Przeglądaj źródła

api endpoints consume, token interceptor on each request

onunez 6 lat temu
rodzic
commit
d1a4aa0c86
41 zmienionych plików z 1136 dodań i 270 usunięć
  1. 368 38
      package-lock.json
  2. 5 1
      src/app/app.module.ts
  3. 4 1
      src/app/app.routing.ts
  4. 18 23
      src/app/components/assets/assets.component.html
  5. 50 45
      src/app/components/assets/assets.component.ts
  6. 54 0
      src/app/components/confirm-account/confirm-account.component.html
  7. 84 0
      src/app/components/confirm-account/confirm-account.component.scss
  8. 25 0
      src/app/components/confirm-account/confirm-account.component.spec.ts
  9. 15 0
      src/app/components/confirm-account/confirm-account.component.ts
  10. 1 1
      src/app/components/dashboard/dashboard.component.html
  11. 27 32
      src/app/components/dashboard/dashboard.component.ts
  12. 1 5
      src/app/components/login/login.component.ts
  13. 59 1
      src/app/components/organizations/edit-organization/edit-organization.component.html
  14. 92 1
      src/app/components/organizations/edit-organization/edit-organization.component.ts
  15. 1 1
      src/app/components/organizations/new-organization/new-organization.component.html
  16. 43 2
      src/app/components/organizations/new-organization/new-organization.component.ts
  17. 0 43
      src/app/components/organizations/organizations.component.scss
  18. 1 6
      src/app/components/organizations/organizations.component.ts
  19. 1 1
      src/app/components/plants/edit-plant/edit-plant.component.html
  20. 0 1
      src/app/components/plants/new-plant/new-plant.component.html
  21. 1 1
      src/app/components/plants/plants.component.html
  22. 1 1
      src/app/components/plants/plants.component.ts
  23. 6 5
      src/app/components/plugins/maps/maps.component.ts
  24. 1 1
      src/app/components/plugins/weather-card/weather-card.component.html
  25. 2 0
      src/app/components/plugins/weather-card/weather-card.component.ts
  26. 7 2
      src/app/components/shared/navbar/navbar.component.ts
  27. 1 1
      src/app/components/shared/sidebar/sidebar.component.html
  28. 3 1
      src/app/components/shared/sidebar/sidebar.component.ts
  29. 66 1
      src/app/components/users/new-user/new-user.component.html
  30. 42 1
      src/app/components/users/new-user/new-user.component.ts
  31. 17 11
      src/app/components/users/users.component.html
  32. 12 12
      src/app/components/users/users.component.ts
  33. 0 1
      src/app/services/auth.guard.ts
  34. 6 11
      src/app/services/auth2.service.ts
  35. 12 1
      src/app/services/logs.service.ts
  36. 45 0
      src/app/services/organizations.service.ts
  37. 14 1
      src/app/services/plants.service.ts
  38. 16 8
      src/app/services/token.interceptor.ts
  39. 32 6
      src/app/services/user.service.ts
  40. 1 1
      src/environments/environment.prod.ts
  41. 2 2
      src/environments/environment.ts

+ 368 - 38
package-lock.json

@@ -1673,6 +1673,14 @@
         "through": ">=2.2.7 <3"
       }
     },
+    "abs": {
+      "version": "1.3.13",
+      "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.13.tgz",
+      "integrity": "sha512-VgsJF4AZDoxLwTRx+TlZ6gpHfSaRUcg1Vhyruqxzpr6lTmh3JMO9667AHAVUGHUD3Li9QqjX2WaTXR6pkGFU+Q==",
+      "requires": {
+        "ul": "^5.0.0"
+      }
+    },
     "accepts": {
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -2692,6 +2700,11 @@
       "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
       "dev": true
     },
+    "capture-stack-trace": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
+      "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
+    },
     "caseless": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -3210,6 +3223,14 @@
         "elliptic": "^6.0.0"
       }
     },
+    "create-error-class": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+      "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+      "requires": {
+        "capture-stack-trace": "^1.0.0"
+      }
+    },
     "create-hash": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -3403,6 +3424,11 @@
       "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
       "dev": true
     },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+    },
     "default-gateway": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
@@ -3422,6 +3448,14 @@
         "strip-bom": "^3.0.0"
       }
     },
+    "deffy": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.3.tgz",
+      "integrity": "sha512-c5JD8Z6V1aBWVzn1+aELL97R1pHCwEjXeU3hZXdigkZkxb9vhgFP162kAxGXl992TtAg0btwQyx7d54CqcQaXQ==",
+      "requires": {
+        "typpy": "^2.0.0"
+      }
+    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -3641,10 +3675,13 @@
       "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
       "dev": true
     },
-    "domino": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.3.tgz",
-      "integrity": "sha512-EwjTbUv1Q/RLQOdn9k7ClHutrQcWGsfXaRQNOnM/KgK4xDBoLFEcIRFuBSxAx13Vfa63X029gXYrNFrSy+DOSg=="
+    "duplexer2": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+      "requires": {
+        "readable-stream": "^2.0.2"
+      }
     },
     "duplexify": {
       "version": "3.7.1",
@@ -3824,6 +3861,14 @@
       "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
       "dev": true
     },
+    "err": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz",
+      "integrity": "sha1-65KOLhGjFmSPeCgz0PlyWLpDwvg=",
+      "requires": {
+        "typpy": "^2.2.0"
+      }
+    },
     "err-code": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
@@ -3842,7 +3887,6 @@
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
       "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
-      "dev": true,
       "requires": {
         "is-arrayish": "^0.2.1"
       }
@@ -3973,6 +4017,15 @@
         "safe-buffer": "^5.1.1"
       }
     },
+    "exec-limiter": {
+      "version": "3.2.12",
+      "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.12.tgz",
+      "integrity": "sha512-2Bj2X3UmPQHIPtYkDW5epEHn1aTtGxP30x8Be6IzXzQzyuavlOdKI4wT56iEt9UUfvI421AHAHHnV+lBIvCcVA==",
+      "requires": {
+        "limit-it": "^3.0.0",
+        "typpy": "^2.1.0"
+      }
+    },
     "execa": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@@ -4558,6 +4611,14 @@
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
+    "function.name": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.12.tgz",
+      "integrity": "sha512-C7Tu+rAFrWW5RjXqtKtXp2xOdCujq+4i8ZH3w0uz/xrYHBwXZrPt96x8cDAEHrIjeyEv/Jm6iDGyqupbaVQTlw==",
+      "requires": {
+        "noop6": "^1.0.1"
+      }
+    },
     "genfun": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
@@ -4590,6 +4651,57 @@
         "assert-plus": "^1.0.0"
       }
     },
+    "git-package-json": {
+      "version": "1.4.9",
+      "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.9.tgz",
+      "integrity": "sha512-F88a40RBqCS6S7layrE4LIhX5TIVYyUJRYxZjAPPLfCZu9zf0R5B3l3wIY8A7hFb3xAU6Df/AHVMoBQ9SaR1Jw==",
+      "requires": {
+        "deffy": "^2.2.1",
+        "err": "^1.1.1",
+        "gry": "^5.0.0",
+        "normalize-package-data": "^2.3.5",
+        "oargv": "^3.4.1",
+        "one-by-one": "^3.1.0",
+        "r-json": "^1.2.1",
+        "r-package-json": "^1.0.0",
+        "tmp": "0.0.28"
+      },
+      "dependencies": {
+        "tmp": {
+          "version": "0.0.28",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
+          "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
+          "requires": {
+            "os-tmpdir": "~1.0.1"
+          }
+        }
+      }
+    },
+    "git-source": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.9.tgz",
+      "integrity": "sha512-LRWKxFrt1lIrEAdRMrCk9sGbEYQdf3TwDe9pEwR8DMau+2dljQjqqwITJqhYIbA0TkFaxatOXzLhBWW89ZMO7w==",
+      "requires": {
+        "git-url-parse": "^5.0.1"
+      }
+    },
+    "git-up": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
+      "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
+      "requires": {
+        "is-ssh": "^1.0.0",
+        "parse-url": "^1.0.0"
+      }
+    },
+    "git-url-parse": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
+      "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
+      "requires": {
+        "git-up": "^1.0.0"
+      }
+    },
     "glob": {
       "version": "7.1.4",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
@@ -4684,11 +4796,54 @@
         }
       }
     },
+    "got": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
+      "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
+      "requires": {
+        "create-error-class": "^3.0.1",
+        "duplexer2": "^0.1.4",
+        "is-redirect": "^1.0.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "lowercase-keys": "^1.0.0",
+        "node-status-codes": "^1.0.0",
+        "object-assign": "^4.0.1",
+        "parse-json": "^2.1.0",
+        "pinkie-promise": "^2.0.0",
+        "read-all-stream": "^3.0.0",
+        "readable-stream": "^2.0.5",
+        "timed-out": "^3.0.0",
+        "unzip-response": "^1.0.2",
+        "url-parse-lax": "^1.0.0"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+          "requires": {
+            "error-ex": "^1.2.0"
+          }
+        }
+      }
+    },
     "graceful-fs": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
       "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q=="
     },
+    "gry": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz",
+      "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==",
+      "requires": {
+        "abs": "^1.2.1",
+        "exec-limiter": "^3.0.0",
+        "one-by-one": "^3.0.0",
+        "ul": "^5.0.0"
+      }
+    },
     "hammerjs": {
       "version": "2.0.8",
       "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
@@ -5240,8 +5395,7 @@
     "is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-      "dev": true
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
     },
     "is-binary-path": {
       "version": "2.1.0",
@@ -5414,6 +5568,11 @@
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
       "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
     },
+    "is-redirect": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+      "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
+    },
     "is-regex": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
@@ -5422,11 +5581,23 @@
         "has": "^1.0.1"
       }
     },
+    "is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
+    },
+    "is-ssh": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz",
+      "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==",
+      "requires": {
+        "protocols": "^1.1.0"
+      }
+    },
     "is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
     },
     "is-symbol": {
       "version": "1.0.2",
@@ -5688,6 +5859,11 @@
         "handlebars": "^4.1.2"
       }
     },
+    "iterate-object": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.3.tgz",
+      "integrity": "sha512-DximWbkke36cnrSfNJv6bgcB2QOMV9PRD2FiowwzCoMsh8RupFLdbNIzWe+cVDWT+NIMNJgGlB1dGxP6kpzGtA=="
+    },
     "jasmine": {
       "version": "2.8.0",
       "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz",
@@ -6737,6 +6913,14 @@
         "immediate": "~3.0.5"
       }
     },
+    "limit-it": {
+      "version": "3.2.9",
+      "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.9.tgz",
+      "integrity": "sha512-3cAf+D47VdMrrzLpV3wIyEHoAACc7FonHMz+I8onocXdnWD2zBeicse851NZ9TUeCEyuBM35Cx82mpdx1WLm2A==",
+      "requires": {
+        "typpy": "^2.0.0"
+      }
+    },
     "loader-runner": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
@@ -6842,6 +7026,11 @@
         "js-tokens": "^3.0.0 || ^4.0.0"
       }
     },
+    "lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+    },
     "lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -8396,6 +8585,16 @@
         }
       }
     },
+    "node-status-codes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
+      "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8="
+    },
+    "noop6": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.8.tgz",
+      "integrity": "sha512-+Al5csMVc40I8xRfJsyBcN1IbpyvebOuQmMfxdw+AL6ECELey12ANgNTRhMfTwNIDU4W9W0g8EHLcsb3+3qPFA=="
+    },
     "normalize-package-data": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -8527,16 +8726,32 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
+    "oargv": {
+      "version": "3.4.9",
+      "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.9.tgz",
+      "integrity": "sha512-24Eatdf7OGezTAU0Yw3HaoO9x+GTFnmBkuFHfWEQtVsIKbD7VMHhyIlDMtxxUxfZKPBPHYsTo8UgGwKr4ySewA==",
+      "requires": {
+        "iterate-object": "^1.1.0",
+        "ul": "^5.0.0"
+      }
+    },
     "oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
       "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
     },
+    "obj-def": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.7.tgz",
+      "integrity": "sha512-ahx1PnGDpovRglgczxsKtoYhPhrhYEG1rs3WklAHMTk29DyStqsrGDVISOIGZLF+ewK4m5CFZNuZXIXRQwZUMg==",
+      "requires": {
+        "deffy": "^2.2.2"
+      }
+    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
     },
     "object-component": {
       "version": "0.0.3",
@@ -8650,6 +8865,15 @@
         "wrappy": "1"
       }
     },
+    "one-by-one": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.7.tgz",
+      "integrity": "sha512-EFE5hyHMGPcesACi1tT6HRmMK23Q74ujX2gjhfGD9qMkz7CxD1AJd5TmBHIEEzuL7h7hKwWh9n9hJ5ClQJnO/Q==",
+      "requires": {
+        "obj-def": "^1.0.0",
+        "sliced": "^1.0.1"
+      }
+    },
     "onetime": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
@@ -8807,6 +9031,42 @@
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
       "dev": true
     },
+    "package-json": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
+      "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
+      "requires": {
+        "got": "^5.0.0",
+        "registry-auth-token": "^3.0.1",
+        "registry-url": "^3.0.3",
+        "semver": "^5.1.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+        }
+      }
+    },
+    "package-json-path": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.8.tgz",
+      "integrity": "sha512-8OCXvm2TmEYoWC7e9AswLC0eoKY3RGbkupbiWa2vaTFaH4vEE3Kr+oeefLVm/7N4me2gYh5SjQYsdwAZLkL87g==",
+      "requires": {
+        "abs": "^1.2.1"
+      }
+    },
+    "package.json": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
+      "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
+      "requires": {
+        "git-package-json": "^1.4.0",
+        "git-source": "^1.1.0",
+        "package-json": "^2.3.1"
+      }
+    },
     "pacote": {
       "version": "9.5.4",
       "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.4.tgz",
@@ -8936,6 +9196,15 @@
         "json-parse-better-errors": "^1.0.1"
       }
     },
+    "parse-url": {
+      "version": "1.3.11",
+      "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
+      "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
+      "requires": {
+        "is-ssh": "^1.3.0",
+        "protocols": "^1.4.0"
+      }
+    },
     "parse5": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
@@ -9117,14 +9386,12 @@
     "pinkie": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-      "dev": true
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
     },
     "pinkie-promise": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
       "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-      "dev": true,
       "requires": {
         "pinkie": "^2.0.0"
       }
@@ -9251,8 +9518,7 @@
     "prepend-http": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
-      "dev": true
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
     },
     "preserve": {
       "version": "0.2.0",
@@ -9307,28 +9573,10 @@
         }
       }
     },
-    "prompt": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.1.12.tgz",
-      "integrity": "sha1-0xFOT7mFrGbqo1WG3Lez+zsnv8Y=",
-      "requires": {
-        "async": "0.1.x",
-        "colors": "0.x.x",
-        "pkginfo": "0.x.x",
-        "winston": "0.5.x"
-      },
-      "dependencies": {
-        "async": {
-          "version": "0.1.22",
-          "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
-          "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE="
-        },
-        "colors": {
-          "version": "0.6.2",
-          "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
-          "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w="
-        }
-      }
+    "protocols": {
+      "version": "1.4.7",
+      "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz",
+      "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg=="
     },
     "protoduck": {
       "version": "5.0.1",
@@ -9680,6 +9928,26 @@
         "schema-utils": "^1.0.0"
       }
     },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "requires": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      }
+    },
+    "read-all-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
+      "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
+      "requires": {
+        "pinkie-promise": "^2.0.0",
+        "readable-stream": "^2.0.0"
+      }
+    },
     "read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -9798,6 +10066,23 @@
         "regjsparser": "^0.1.4"
       }
     },
+    "registry-auth-token": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
+      "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
+      "requires": {
+        "rc": "^1.1.6",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "registry-url": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+      "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+      "requires": {
+        "rc": "^1.0.1"
+      }
+    },
     "regjsgen": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
@@ -10343,6 +10628,11 @@
       "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
       "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
     },
+    "sliced": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
+      "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
+    },
     "smart-buffer": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz",
@@ -11003,6 +11293,11 @@
       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
       "dev": true
     },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+    },
     "style-loader": {
       "version": "0.23.1",
       "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
@@ -11172,6 +11467,11 @@
       "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==",
       "dev": true
     },
+    "timed-out": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz",
+      "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc="
+    },
     "timers-browserify": {
       "version": "2.0.11",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
@@ -11402,6 +11702,14 @@
       "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
       "dev": true
     },
+    "typpy": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.11.tgz",
+      "integrity": "sha512-Jh/fykZSaxeKO0ceMAs6agki9T5TNA9kiIR6fzKbvafKpIw8UlNlHhzuqKyi5lfJJ5VojJOx9tooIbyy7vHV/g==",
+      "requires": {
+        "function.name": "^1.0.3"
+      }
+    },
     "uglify-js": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
@@ -11422,6 +11730,15 @@
         }
       }
     },
+    "ul": {
+      "version": "5.2.14",
+      "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.14.tgz",
+      "integrity": "sha512-VaIRQZ5nkEd8VtI3OYo5qNbhHQuBtPtu5k5GrYaKCmcP1H+FkuWtS+XFTSU1oz5GiuAg2FJL5ka8ufr9zdm8eg==",
+      "requires": {
+        "deffy": "^2.2.2",
+        "typpy": "^2.3.4"
+      }
+    },
     "ultron": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
@@ -11533,6 +11850,11 @@
         }
       }
     },
+    "unzip-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
+      "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
+    },
     "upath": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
@@ -11580,6 +11902,14 @@
         "requires-port": "^1.0.0"
       }
     },
+    "url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "requires": {
+        "prepend-http": "^1.0.1"
+      }
+    },
     "use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",

+ 5 - 1
src/app/app.module.ts

@@ -34,12 +34,16 @@ import { AngularMyDatePickerModule } from 'angular-mydatepicker';
 import { PluginsModule } from './components/plugins/plugins.module';
 import { LoginComponent } from './components/login/login.component';
 
+import { TokenInterceptor } from '@app/services/token.interceptor';
+import { ConfirmAccountComponent } from './components/confirm-account/confirm-account.component';
+
 
 @NgModule({
   declarations: [
     AppComponent,
     AdminComponent,
     LoginComponent,
+    ConfirmAccountComponent,
   ],
   imports: [
     BrowserModule,
@@ -58,7 +62,7 @@ import { LoginComponent } from './components/login/login.component';
     AngularMyDatePickerModule
   ],
   providers: [
-    //{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
+    { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
     //{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
     //AuthenticationService,
     // provider used to create fake backend

+ 4 - 1
src/app/app.routing.ts

@@ -9,6 +9,7 @@ import { LoginComponent } from './components/login/login.component';
 //import { AuthGuard } from './services/authentication.service';
 import { AuthGuard } from './services/auth.guard';
 import { Role } from './models/role';
+import { ConfirmAccountComponent } from './components/confirm-account/confirm-account.component';
 
 const routes: Routes =[
   {
@@ -24,7 +25,9 @@ const routes: Routes =[
       path: '',
       loadChildren : './layouts/admin/admin.module#AdminModule' //() => AdminModule
     }]
-  }, { path: 'login', component: LoginComponent },
+  }, 
+  { path: 'login', component: LoginComponent },
+  { path: 'confirm-account', component: ConfirmAccountComponent },
   { path: '**', redirectTo: '' }
 ];
 

+ 18 - 23
src/app/components/assets/assets.component.html

@@ -9,26 +9,26 @@
     <div class="col-lg-6 col-sm-4 p-1">
       <div class="row">
         <div class="col-lg-12 col-sm-12">
-          <select class="custom-select"(onChange)="onChangeObj($event)" name="sel3">
+          <select class="custom-select" (change)="onChangeObj($event)" name="sel3">
             <option *ngFor="let item of listAssets" [selected]="item.id===organizationId" [value]="item.id" >{{item.name}}</option>
           </select>
         
         </div>
       </div>
-      <div class="row">
+      <!--<div class="row">
         <div class="col-lg-12">
             <div class="widget environment-meters">
                 <div class="mini-stats">
                   <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
-                  <h5 *ngIf="listEnergyProduced">
-                    {{listEnergyProduced.thisWeek.total_energy_kWh/1000 | number}}
+                  <h5 *ngIf="eProduced">
+                    {{eProduced.thisWeek.total_energy_kWh/1000 | number}}
                     <small>MWh</small>
                   </h5>
                 </div>
               </div>
           </div>
       </div>
-      
+    -->  
     </div>
 
     <!-- Weather card -->
@@ -49,8 +49,8 @@
       <div class="widget energy-stats">
         <div class="mini-stats ">
           <span class="sky-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="listEnergyProduced">
-            {{listEnergyProduced.today.total_energy_kWh}}
+          <h3 *ngIf="eProduced">
+            {{energyDay}}
             <small>kW</small>
           </h3>
           <p>Ultimo dia</p>
@@ -62,8 +62,8 @@
       <div class="widget energy-stats">
         <div class="mini-stats ">
           <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="listEnergyProduced">
-            {{listEnergyProduced.thisWeek.total_energy_kWh/1000 | number}}
+          <h3 *ngIf="eProduced">
+            {{energyWeek}}
             <small>MWh</small>
           </h3>
           <p>Ultima semana</p>
@@ -75,8 +75,8 @@
       <div class="widget energy-stats">
         <div class="mini-stats ">
           <span class="yellow-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="listEnergyProduced">
-            {{listEnergyProduced.thisMonth.total_energy_kWh/1000 | number}}
+          <h3 *ngIf="eProduced">
+            {{energyMonth}}
             <small>MWh</small>
           </h3>
           <p>Ultimos 30 días</p>
@@ -88,8 +88,8 @@
       <div class="widget energy-stats">
         <div class="mini-stats ">
           <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="listEnergyProduced">
-            {{listEnergyProduced.lifeTime.total_energy_kWh/1000 | number}}
+          <h3 *ngIf="eProduced">
+            {{energyYear}}
             <small>MWh</small>
           </h3>
           <p>Total</p>
@@ -104,14 +104,8 @@
     <div class="col-lg-12 col-md-12 col-sm-12">
       <div class="widget">
         <div class="mini-stats">
-          <!--
-          <div class="chart-container" style="display:none;">
-            <canvas baseChart #baseChart="base-chart" [datasets]="barChartData" [labels]="barChartLabels" [options]="barChartOptions"
-              [legend]="barChartLegend" [chartType]="barChartType"></canvas>
-          </div>
-          -->
 
-          <div class="chart-container" >
+          <div class="chart-container">
             <canvas id="canvas">{{ chart1 }}</canvas>
           </div>
 
@@ -129,13 +123,14 @@
           </div>
         </div>
       </div>
+
     </div>
   </div>
   
   <!-- Enviromental cool stats cards -->
   <div class="row align-container">
 
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6">
+    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
       <div class="widget">
         <div class="enviroment-stats">
           <div class="enviromental-icon">
@@ -150,7 +145,7 @@
       </div>
     </div>
     
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6">
+    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
       <div class="widget">
         <div class="enviroment-stats">
           <div class="enviromental-icon">
@@ -165,7 +160,7 @@
       </div>
     </div>
     
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6">
+    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
       <div class="widget">
         <div class="enviroment-stats">
           <div class="enviromental-icon">

+ 50 - 45
src/app/components/assets/assets.component.ts

@@ -36,7 +36,8 @@ export class AssetsComponent implements OnInit {
 
   organizationId:string;
   listAssets:any;
-  listEnergyProduced:any;
+
+  eProduced:any;
   error:boolean;
   errorMessage:string;
   errortest:any;
@@ -45,7 +46,10 @@ export class AssetsComponent implements OnInit {
   metersKeys:any;
   metersValues:any;
   view:string;
-
+  energyDay:any;
+  energyWeek:any;
+  energyMonth:any;
+  energyYear:any;
 
   //For daterange
   daysLabels:any = {su: 'Dom', mo: 'Lun', tu: 'Mar', we: 'Mie', th: 'Jue', fr: 'Vie', sa: 'Sab'};
@@ -86,6 +90,13 @@ export class AssetsComponent implements OnInit {
     private logsService: LogsService,
     private measService: MeasuresService) {
       
+      this.route.queryParams.subscribe(params => {
+        this.organizationId = params['id'];
+        console.log("organization");
+        console.log(this.organizationId); 
+      });
+
+      
       Swal.fire({
         allowOutsideClick: false,
         type: 'info',
@@ -98,15 +109,12 @@ export class AssetsComponent implements OnInit {
   @ViewChild("baseChart",null) chart: BaseChartDirective;
 
   ngOnInit() {
-    
-    let plants = this.plantsService.getAllAssets();
-    let energy_produced = this.plantsService.getAssetsProducedEnergy();
 
     // Default date is today and set it on a string var and initialize dateRange plugin
-    this.initialDate = new Date("2019-09-15").toISOString().slice(0, 10);
+    this.initialDate = new Date("2019-09-30").toISOString().slice(0, 10);
     console.log(this.initialDate);
     if (this.myDateInit) {
-      let begin: Date = new Date("2019-09-15");
+      let begin: Date = new Date("2019-09-30");
       this.model = {
         isRange: false, 
         singleDate: {
@@ -116,46 +124,38 @@ export class AssetsComponent implements OnInit {
         }
       };
     }
-    
-    // Observable of two objects
-    forkJoin([plants, energy_produced]).subscribe(results => {
-      console.log(results[0]["data"]);
-      if (localStorage.getItem("email") == "inverlec@grupomerelec.com"){
-        this.listAssets = [
-          {
-            name: "Inversiones MERELEC S.A de C.V",
-            id: '5d70330cb288f25b679c68a8'
-          },
-          {
-            name: "Inversiones MERELEC 2 S.A de C.V",
-            id: '5d70330cb288f25b679c68n8'
-          },          
-        ]
-
-        this.view = "month";
-        this.onMeasureClickRange(this.view, this.initialDate);
-
-        console.log(this.listAssets[0]["id"]);
-      }
-      else {
-        this.listAssets = results[0]["data"];
-        console.log(this.listAssets[0]["id"]);
-        this.view = "month";
-        this.onMeasureClickRange(this.view, this.initialDate);
+    // Initialize on load
+    this.isActive = [false, false, false, false];
+
+    let plants = this.plantsService.getAllAssets().subscribe(res => {
+      this.listAssets = res["data"]["assets"];
+      this.view = "month";
+      if (this.organizationId == undefined){
+        this.organizationId = this.listAssets[0].id;
       }
-      
-      // Energy produced given an assetID
-      this.listEnergyProduced = results[1];      
-    },
-    (err) => {
+      this.onMeasureClickRange(this.view, this.initialDate);
+
+      let energy_produced = this.logsService.getEnergySummaryByAsset(this.organizationId).subscribe(resp => {
+        console.log(resp);
+        this.eProduced = resp["data"]["energy"];//results[1];
+        this.energyDay = this.eProduced.today.total_energy_kWh;
+        this.energyWeek = this.eProduced.thisWeek.total_energy_kWh > 0 ? this.eProduced.thisWeek.total_energy_kWh/1000 : this.eProduced.thisWeek.total_energy_kWh
+        this.energyMonth = this.eProduced.thisMonth.total_energy_kWh > 0 ? this.eProduced.thisMonth.total_energy_kWh/1000 : this.eProduced.thisMonth.total_energy_kWh
+        this.energyYear = this.eProduced.lifeTime.total_energy_kWh > 0 ? this.eProduced.lifeTime.total_energy_kWh/1000 : this.eProduced.lifeTime.total_energy_kWh
+        console.log(this.energyYear);
+      });
+
+    }, (err) => {
       Swal.fire({
         type: 'error',
         title: 'Error en el servidor',
         text: "No su pudo obtener la informacion"
       });
-    });    
+    });
+
 
-    this.chartjs = true;
+
+    //this.chartjs = true;
     setTimeout(()=>{
       Swal.close();
     }, 2700);
@@ -173,8 +173,10 @@ export class AssetsComponent implements OnInit {
 
   // Trigger again the chart with the selected assetID
   onChangeObj(event:any) {
-    this.onMeasureClickRange(this.view, this.initialDate, event.target.value);
+    this.organizationId = event.target.value;
+    this.onMeasureClickRange(this.view, this.initialDate, this.organizationId);
   }
+  
 
   // Change the date range of the chart, according to the selected view (daily, weekly, ...)
   onDateChanged(event: IMyDateModel) {
@@ -209,7 +211,7 @@ export class AssetsComponent implements OnInit {
     Swal.showLoading();
     this.view = view;
 
-    // Chart (re)initialize, to prevent double load on changing range or views
+    // Chart (re)initialize, to prevent double load on changing date range or views
     if (this.chart1 != undefined){
       this.chart1.destroy();
     }
@@ -261,17 +263,20 @@ export class AssetsComponent implements OnInit {
 
     this.logsService.getEnergyProducedByParams(assetId,interval,dateRange).toPromise()
     .then((data: any) => {
+      console.log("meters");
+      console.log(data);
       this.metersData = [];      
-      this.metersKeys = Object.keys(data["data"][0]["dataset"]);
+      this.metersKeys = Object.keys(data["data"]["dataset"]);
 
       // Get all the values according to each index (meter) 
-      this.metersValues = Object.values(data["data"][0]["dataset"]);
+      this.metersValues = Object.values(data["data"]["dataset"]);
 
       // Get the keys of those values
       let meterKeys2 = Object.keys(this.metersValues);
 
       for (let prop in meterKeys2) { 
-        let label = localStorage.getItem("email") == "inverlec@grupomerelec.com" ? `INVERLEC ${prop}` : this.metersValues[prop]["label"];
+        //let label = localStorage.getItem("email") == "inverlec@grupomerelec.com" ? `INVERLEC ${prop}` : this.metersValues[prop]["label"];
+        let label = this.metersValues[prop]["label"];
         let measure_values = Object.values(this.metersValues[prop]["data"].map(obj => obj.total_energy_kWh).reverse())
         this.metersData.push({"label": label, backgroundColor: this.barChartColors[prop], data: measure_values });
       }

+ 54 - 0
src/app/components/confirm-account/confirm-account.component.html

@@ -0,0 +1,54 @@
+<div id="wrapper">
+  <div class="vertical-align-wrap">
+    <div class="vertical-align-middle auth-main">
+      <div class="auth-box">
+        <div class="top">
+          <img alt="Inverlec" src="./assets/img/inverlec_logo.png">
+        </div>
+
+        <div class="card">
+          <div class="header">
+            <h1 class="lead">Confirmación de cuenta</h1>
+          </div>
+          <div class="body">
+            <form [formGroup]="loginForm" (ngSubmit)="login()">
+
+              <div class="form-group">
+                <label for="email">Correo electrónico</label>
+                <input type="text" name="email" class="form-control"
+                formControlName="email" required email readonly />
+              </div>
+
+              <div class="form-group">
+                <label for="name">Nombre</label>
+                <input type="text" name="name" class="form-control"
+                formControlName="name" required />
+              </div>
+
+              <div class="form-group">
+                <label for="password">Contraseña</label>
+                <input type="password" name="password"  class="form-control"
+                formControlName="password" required minlength="6" />
+              </div>
+
+              <div class="form-group">
+                <label for="confirm_password">Confirmar contraseña</label>
+                <input type="password" name="confirm_password"  class="form-control"
+                formControlName="confirm_password" required minlength="6" />
+              </div>
+
+              <br>
+
+              <div class="div-center">
+                <button class="btn btn-primary" type="submit" [disabled]="!loginForm.valid"> 
+                  Confirmar cuenta
+                </button>
+              </div>
+
+            </form>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 84 - 0
src/app/components/confirm-account/confirm-account.component.scss

@@ -0,0 +1,84 @@
+.vertical-align-wrap {
+  //position: absolute;
+  width: 100%;
+  height: 100%;
+  //display: table;
+}
+
+.vertical-align-middle {
+  //display: table-cell;
+  vertical-align: middle;
+}
+
+.auth-box {
+  width: 800px;
+  height: auto;
+  margin: 20px auto;
+
+  .top {
+    margin: 0 auto;
+    text-align: center;
+  }
+
+  .card {
+    padding: 25px;
+
+    .lead {
+      text-align: center;
+      font-size: 1.5rem;
+      color: #223d7d;
+    }
+  }
+
+  .div-center {
+    text-align: center;
+    margin: 0 auto;
+  }
+}
+
+.auth-main::before {
+  content: '';
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200px;
+  height: 100%;
+  z-index: -1;
+  background: #223d7d; //#f0f0f0;
+}
+
+.auth-main:after {
+  content: '';
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: -2;
+  //background: #223d7d;
+  //background: url(../../assets/images/auth_bg.jpg) no-repeat top left fixed;
+}
+
+.card {
+  background: #fff;
+  transition: .5s;
+  border: 0;
+  margin-bottom: 30px;
+  border-radius: .55rem;
+  position: relative;
+  width: 100%;
+  box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1);
+}
+
+@media screen and (max-width: 640px) {
+  .auth-box {
+      width: 90%;
+  }
+}
+
+@media screen and (max-width: 992px) {
+  .auth-box {
+      width: 80%;
+      margin: 0 auto;
+  }
+}

+ 25 - 0
src/app/components/confirm-account/confirm-account.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConfirmAccountComponent } from './confirm-account.component';
+
+describe('ConfirmAccountComponent', () => {
+  let component: ConfirmAccountComponent;
+  let fixture: ComponentFixture<ConfirmAccountComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ConfirmAccountComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ConfirmAccountComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
src/app/components/confirm-account/confirm-account.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-confirm-account',
+  templateUrl: './confirm-account.component.html',
+  styleUrls: ['./confirm-account.component.scss']
+})
+export class ConfirmAccountComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 1 - 1
src/app/components/dashboard/dashboard.component.html

@@ -11,7 +11,7 @@
             <h4 class="font-weight-normal mb-3">Total de plantas instaladas
               <i class="mdi mdi-chart-line mdi-24px float-right"></i>
             </h4>
-            <h2 class="mb-3" *ngIf="listData">{{listData.length}}</h2>
+            <h2 class="mb-3" *ngIf="listAssets">{{listAssets.length}}</h2>
           </div>
         </div>
       </div>

+ 27 - 32
src/app/components/dashboard/dashboard.component.ts

@@ -22,15 +22,16 @@ export class DashboardComponent implements OnInit {
 
 
   listData:any;
-  
   rows = [];
   markers: Layer[] = [];
   points: LatLng[] = [];
 
+
   listAssets: any;
   error:boolean;
+  listOrganizations: any;
   plantId: string;
-  plant:any;
+  plant: any;
   sub: any;
   plantNotFound: boolean;
   selectedPlant: any;
@@ -40,7 +41,7 @@ export class DashboardComponent implements OnInit {
 
   sumarize:number = 0;
 
-  totalMetersInstalled:string;
+  totalMetersInstalled: string;
 
   lastUpdate = new Date().toLocaleString();
   i: number;
@@ -55,15 +56,16 @@ export class DashboardComponent implements OnInit {
 
   // Open Street Map definitions
   LAYER_OSM = tileLayer(
-    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
-    { maxZoom: 18,
+    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+    {
+      maxZoom: 18,
       attribution: '&copy; OpenStreetMap contributors'
     }
   );
 
   // Values to bind to Leaflet Directive
   options = {
-    layers: [ this.LAYER_OSM ],
+    layers: [this.LAYER_OSM],
     zoom: 10,
     center: latLng([13.661714, -89.251530])
   };
@@ -81,22 +83,12 @@ export class DashboardComponent implements OnInit {
       text: 'Espere por favor...'
     });
     Swal.showLoading();
-
-
-    this.plantsService.getAssets().subscribe(res => {
-      this.listData = res["assets"];
-    }, (err) => {
-      Swal.fire({
-        type: 'error',
-        title: 'Error en el servidor',
-        text: "No su pudo obtener la informacion"
-      });
-    });
     
     this.plantsService.getAllAssets().subscribe(res => {
-      this.listAssets = res["data"];
+      this.listAssets = res["data"]["assets"];
+      console.log(this.listAssets);
       this.assetKeys = Object.keys(this.listAssets);
-
+      console.log("assetKeys");
       for (let prop in this.assetKeys){
         this.meterKeys2 = Object.keys(this.listAssets.map(item => item["meters_installed"])[prop]);
         for (let prop2 in this.meterKeys2){
@@ -140,42 +132,45 @@ export class DashboardComponent implements OnInit {
       }]
     ];
 
-    setTimeout(()=>{
+    setTimeout(() => {
 
-      if (this.listData != undefined){
+      if (this.listAssets != undefined) {
         this.addMarkers();
       }
 
       Swal.close();
-    }, 2500);
+    }, 2700);
 
   }
 
-  getAsset(id:string){
-    return observableOf(this.listData.find(e => e.id === id));
+  getAsset(id: string) {
+    return observableOf(this.listAssets.find(e => e.id === id));
   }
 
 
   addMarkers() {
     let lat, long, address, name2;
 
-    for (const plant of this.listData) {
-      if (localStorage.getItem("email") == "inverlec@grupomerelec.com"){
+    for (const plant of this.listAssets) {
+      console.log(plant.meters_installed[0]);
+
+      console.log("assets");
+      if (localStorage.getItem("email") == "inverlec@grupomerelec.com") {
         lat = "13.6613819";
         long = "-89.2514334";
         address = "Urbanización Madre Selva Calle Llama del Bosque, Edificio Avante, Local 4-5/4-6, Antiguo Cuscatlán";
         name2 = "Inversiones MERELEC S.A de C.V";
       }
       else {
-        lat = plant.latitud;
-        long = plant.longitud;
+        lat = plant["meters_installed"][0].gpsLat;
+        long = plant["meters_installed"][0].gpsLong;
         address = plant.address;
         name2 = plant.name;
       }
 
       const newMarker = marker(
         [lat, long],
-        {icon: this.icon})
+        { icon: this.icon })
         .bindPopup('<b>' + name2 + '</b><br>Dirección: ' + address)
         .on('click', () => {
           this.zone.run(() => {
@@ -189,7 +184,7 @@ export class DashboardComponent implements OnInit {
 
   sendPlantId(id: string) {
     this.plantId = id;
-    if (localStorage.getItem("email") == "inverlec@grupomerelec.com"){
+    if (localStorage.getItem("email") == "inverlec@grupomerelec.com") {
       this.selectedPlant = {
         name: "Inversiones MERELEC S.A de C.V",
         country: "El Salvador",
@@ -199,7 +194,7 @@ export class DashboardComponent implements OnInit {
       }
     }
     else {
-      this.selectedPlant = this.listData.find(e => e.id === this.plantId);
+      this.selectedPlant = this.listAssets.find(e => e.id === this.plantId);
     }
   }
 
@@ -216,7 +211,7 @@ export class DashboardComponent implements OnInit {
     //});
   }
 
-  goToAsset(id: string){
+  goToAsset(id: string) {
     this.router.navigate(['/assets'], { queryParams: { id: id } });
   }
 

+ 1 - 5
src/app/components/login/login.component.ts

@@ -24,7 +24,6 @@ export class LoginComponent implements OnInit {
   get f() { return this.loginForm.controls; }
 
   login() {
-    console.log("enter login");
     this.authService.login(
       {
         email: this.f.email.value,
@@ -33,10 +32,7 @@ export class LoginComponent implements OnInit {
     )
     .subscribe(success => {
       if (success) {
-        console.log(success);
-        console.log("success");
-        //window.location.href="";
-        //this.router.navigate(['/secret-random-number']);
+        window.location.href="#/dashboard";
       }
     });
   }

+ 59 - 1
src/app/components/organizations/edit-organization/edit-organization.component.html

@@ -17,6 +17,64 @@
 
       </div>
 
-    </div>          
+    </div>
+    <br>
+    <div class="row justify-content-center">
+      
+      <div class="col-8">
+        <div class="align-container">
+
+          <div class="card" *ngIf="organizationExists">
+            <div class="card-header card-header-icon card-header-rose">
+              <div class="card-icon"><i class="material-icons">map</i></div>
+              <h4 class="card-title">Editar organización - <small class="category">Complete la información básica</small></h4>
+            </div>
+            <div class="card-body">              
+              <div class="align-container">
+                <form class="form-auth-small ng-untouched ng-pristine ng-valid" [formGroup]="organizationForm" (ngSubmit)="editOrganization()">
+                  <div class="form-group">
+                    <label for="name">Nombre de la organización: </label>
+                    <input type="text" name="name" class="form-control" required formControlName="name" />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="country">País: </label>
+                    <input type="text" name="country" class="form-control" required formControlName="country" />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="city">Ciudad: </label>
+                    <input type="text" name="city" class="form-control" required formControlName="city" />
+                  </div>      
+                  
+                  <div class="form-group">
+                    <label for="contactName">Nombre contacto: </label>
+                    <input type="text" name="contactName" class="form-control" required formControlName="contactName" />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="contactNumber">Teléfono contacto: </label>
+                    <input type="text" name="contactNumber" class="form-control" required formControlName="contactNumber" />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="address">Dirección: </label>
+                    <textarea name="address" class="form-control" rows="2" required formControlName="address"></textarea>
+                  </div>
+                  <br>
+                  <button class="btn btn-primary">
+                    Editar organización
+                  </button>
+                  <!--<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>-->
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+
+    </div>         
+    
   </div>
 </div>

+ 92 - 1
src/app/components/organizations/edit-organization/edit-organization.component.ts

@@ -1,4 +1,9 @@
 import { Component, OnInit } from '@angular/core';
+import { OrganizationsService } from '@app/services/organizations.service';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-edit-organization',
@@ -6,10 +11,96 @@ import { Component, OnInit } from '@angular/core';
   styleUrls: ['./edit-organization.component.scss']
 })
 export class EditOrganizationComponent implements OnInit {
+  [x: string]: any;
   title:string = "Editar organización"; 
-  constructor() { }
+  listOrganization: any;
+  organizationExists:boolean;
+  organizationForm: FormGroup;
+
+  constructor(private orgService: OrganizationsService, private formBuilder: FormBuilder, private route: ActivatedRoute) {
+    this.route.params.subscribe(params => {
+      console.log(params);
+      this.organizationId = params['id'];
+      console.log("organization");
+      console.log(this.organizationId); 
+    });
+
+    this.orgService.getOrganization(this.organizationId).subscribe(res => {
+      this.listOrganization = res["data"]["organization"];
+      this.organizationExists = true;
+      console.log(this.listOrganization["name"]);
+      console.log(this.organizationExists);
+
+      this.organizationForm = this.formBuilder.group({
+        name: [this.listOrganization.name],
+        address: [this.listOrganization.address],
+        city: [this.listOrganization.city],
+        country: [this.listOrganization.country],
+        contactName: [this.listOrganization.contactName],
+        contactNumber: [this.listOrganization.contactNumber],
+      });
+
+
+    }, (err) => {
+      Swal.fire({
+        type: 'error',
+        title: 'Error en el servidor',
+        text: "No su pudo obtener la informacion"
+      });
+    });
+
+  }
 
   ngOnInit() {
+    /*
+    this.organizationForm = this.formBuilder.group({
+      name: [this.listOrganization.name],
+      address: [this.listOrganization.address],
+      city: [this.listOrganization.city],
+      country: [this.listOrganization.country],
+      contactName: [this.listOrganization.contactName],
+      contactNumber: [this.listOrganization.contactNumber],
+    });
+
+    this.organizationForm = this.formBuilder.group({
+      name: [""], //this.listOrganization.name
+      address: [""], //this.listOrganization.address
+      city: [""], //this.listOrganization.city
+      country: [""], //this.listOrganization.country
+      contactName: [""], //this.listOrganization.contactName
+      contactNumber: [""], //this.listOrganization.contactNumber
+    });
+    */
   }
 
+  get f() { return this.organizationForm.controls; }
+
+  editOrganization() {
+    /*
+      this.orgService.editOrganization(
+        {
+          name: this.f.name.value
+          address: this.f.address.value
+          city: this.f.city.value
+          country: this.f.country.value
+          contactName: this.f.contactName.value
+          contactNumber: this.f.contactNumber.value
+        }
+      )
+    .subscribe(success => {
+      if (success) {
+        Swal.fire({
+          allowOutsideClick: false,
+          type: 'info',
+          text: 'Espere por favor...'
+        });
+        window.location.href="#/dashboard";
+
+      }
+      
+    });*/
+  }
+
+
+
 }

+ 1 - 1
src/app/components/organizations/new-organization/new-organization.component.html

@@ -28,7 +28,7 @@
             </div>
             <div class="card-body">              
               <div class="align-container">
-                <form class="form-auth-small ng-untouched ng-pristine ng-valid" >
+                <form class="form-auth-small ng-untouched ng-pristine ng-valid" [formGroup]="organizationForm" (ngSubmit)="createOrganization()">
                   <div class="form-group">
                     <label for="name">Nombre de la organización: </label>
                     <input type="text" name="name" class="form-control" required />

+ 43 - 2
src/app/components/organizations/new-organization/new-organization.component.ts

@@ -1,4 +1,7 @@
 import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder } from '@angular/forms';
+import { OrganizationsService } from '@app/services/organizations.service';
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-new-organization',
@@ -7,12 +10,50 @@ import { Component, OnInit } from '@angular/core';
 })
 export class NewOrganizationComponent implements OnInit {
   title:string = "Nueva organización"; 
+  organizationForm: FormGroup;
 
-  constructor() {
-    console.log("new");
+
+  constructor(private orgService: OrganizationsService, private formBuilder: FormBuilder) {
   }
 
   ngOnInit() {
+    this.organizationForm = this.formBuilder.group({
+      name: [''],
+      address: [''],
+      city: [''],
+      country: [''],
+      contactName: [''],
+      contactNumber: [''],
+    });
+  }
+
+  get f() { return this.organizationForm.controls; }
+
+  createOrganization() {
+    
+      this.orgService.createOrganization(
+        {
+          name: this.f.name.value,
+          address: this.f.address.value,
+          city: this.f.city.value,
+          country: this.f.country.value,
+          contactName: this.f.contactName.value,
+          contactNumber: this.f.contactNumber.value
+        }
+      )
+    .subscribe(success => {
+      if (success) {
+        Swal.fire({
+          allowOutsideClick: false,
+          type: 'info',
+          text: 'Espere por favor...'
+        });
+        //window.location.href="#/dashboard";
+
+      }
+      
+    });
   }
 
+
 }

+ 0 - 43
src/app/components/organizations/organizations.component.scss

@@ -1,43 +0,0 @@
-table {
-  width: 100%;
-}
-
-.mat-form-field {
-  font-size: 14px;
-  width: 100%;
-}
-
-.example-loading-shade {
-  position: absolute;
-  top: 0;
-  left: 0;
-  bottom: 56px;
-  right: 0;
-  background: rgba(0, 0, 0, 0.15);
-  z-index: 1;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.example-rate-limit-reached {
-  color: #980000;
-  max-width: 360px;
-  text-align: center;
-}
-
-/* Structure */
-.example-container {
-  position: relative;
-  min-height: 200px;
-}
-
-.example-table-container {
-  position: relative;
-  //max-height: 400px;
-  overflow: auto;
-}
-
-.align-right {
-  text-align: right;
-}

+ 1 - 6
src/app/components/organizations/organizations.component.ts

@@ -50,18 +50,13 @@ export class OrganizationsComponent implements OnInit {
     console.log(this.listData);
     
     this.orgService.getAllOrganizations().subscribe(ans => {
-      this.listOrganization = ans["data"];
+      this.listOrganization = ans["data"]["organizations"];
       console.log(this.listOrganization);
       this.dataSource.data = this.listOrganization;
       this.dataSource.paginator = this.paginator;
       this.dataSource.sort = this.sort;
       
     });
-
-      
-    
-    
-    
   }
 
   applyFilter(filterValue: string) {

+ 1 - 1
src/app/components/plants/edit-plant/edit-plant.component.html

@@ -9,7 +9,7 @@
           <nav aria-label="breadcrumb">
             <ol class="breadcrumb">
               <li class="breadcrumb-item"><a [routerLink]="['/']">Dashboard</a></li>
-              <li class="breadcrumb-item"><a [routerLink]="['/organizations']">Plantas</a></li>
+              <li class="breadcrumb-item"><a [routerLink]="['/plants']">Plantas</a></li>
               <li class="breadcrumb-item">Editar planta</li>
             </ol>
           </nav>

+ 0 - 1
src/app/components/plants/new-plant/new-plant.component.html

@@ -1,4 +1,3 @@
-<p>new-plant works!</p>
 <h2 class="floating-title">{{title}}</h2>
 
 <div class="main-content">

+ 1 - 1
src/app/components/plants/plants.component.html

@@ -23,7 +23,7 @@
       <div class="col-12">
           <div class="align-container">
 
-            <h4><b>Listado de organizaciones</b></h4>
+            <h4><b>Listado de plantas</b></h4>
             <div class="example-container mat-elevation-z8">
               <div class="example-table-container">
           

+ 1 - 1
src/app/components/plants/plants.component.ts

@@ -38,7 +38,7 @@ export class PlantsComponent implements OnInit {
 
   ngOnInit() {
     this.orgService.getAllAssets().subscribe(ans => {
-      this.listPlant = ans["data"];
+      this.listPlant = ans["data"]["assets"];
       console.log(this.listPlant);
       this.dataSource.data = this.listPlant;
       this.dataSource.paginator = this.paginator;

+ 6 - 5
src/app/components/plugins/maps/maps.component.ts

@@ -10,7 +10,7 @@ import { PlantsService } from 'src/app/services/plants.service';
 })
 export class MapsComponent implements OnInit {
 
-  listData:any;
+  listData: any;
   markers: Layer[] = [];
   points: LatLng[] = [];
   plantId: number;
@@ -28,14 +28,15 @@ export class MapsComponent implements OnInit {
 
   // Open Street Map definitions
   LAYER_OSM = tileLayer(
-    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
-    { maxZoom: 18,
+    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+    {
+      maxZoom: 18,
       attribution: '&copy; OpenStreetMap contributors'
     });
 
   // Values to bind to Leaflet Directive
   options = {
-    layers: [ this.LAYER_OSM ],
+    layers: [this.LAYER_OSM],
     zoom: 8,
     center: latLng([13.661714, -89.251530])
   };
@@ -54,7 +55,7 @@ export class MapsComponent implements OnInit {
       const long = plant.longitud;
       const newMarker = marker(
         [lat, long],
-        {icon: this.icon})
+        { icon: this.icon })
         .bindPopup('<b>' + plant.name + '</b><br>Dirección: ' + plant.address)
         .on('click', () => {
           this.zone.run(() => {

+ 1 - 1
src/app/components/plugins/weather-card/weather-card.component.html

@@ -13,7 +13,7 @@
     </div>
     <div class="col-lg-6 col-md-6 col-xs-12">
       <div class="temp">
-         <img src="assets/img/{{icon}}.png" alt="" width="60">
+         <img src="assets/img/{{icon}}.png" alt="" width="60" *ngIf="icon_exists">
          <span>{{temp}}°</span>
       </div>
     </div>

+ 2 - 0
src/app/components/plugins/weather-card/weather-card.component.ts

@@ -25,6 +25,7 @@ export class WeatherCardComponent implements OnInit {
   cityName: string;
   cityAdded = false;
   icon: string;
+  icon_exists: boolean;
   pipe = new DatePipe('es-ES')
   newDate = Date.now();
   currentDate = this.pipe.transform(this.newDate, 'fullDate')
@@ -40,6 +41,7 @@ export class WeatherCardComponent implements OnInit {
         this.cityName = payload.name
         this.state = payload.weather[0].description;
         this.temp = Math.ceil(payload.main.temp);
+        this.icon_exists = true;
         this.icon = payload.weather[0].icon;
       }, (err) => {
         this.errorMessage = err.error.message;

+ 7 - 2
src/app/components/shared/navbar/navbar.component.ts

@@ -1,3 +1,5 @@
+import { Observable } from 'rxjs';
+
 import { Component, OnInit, ElementRef } from '@angular/core';
 import { ROUTES } from '../sidebar/sidebar.component';
 import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
@@ -144,8 +146,11 @@ export class NavbarComponent implements OnInit {
     };
 
     logout() {
-      console.log("i clicked logout");
-      this.auth.logout();
+      this.auth.logout().subscribe(success => {
+        if (success) {
+          window.location.href="";
+        }
+      });
       //window.location.href="";
 
       //this.router.navigateByUrl("login");

+ 1 - 1
src/app/components/shared/sidebar/sidebar.component.html

@@ -40,7 +40,7 @@
         </a>
       </li>
       <li routerLinkActive="active" *ngFor="let menuItem of adminMenuItems" class="{{menuItem.class}} nav-item">
-        <a class="nav-link" [routerLink]="[menuItem.path]"> <!--*ngIf="menuItem.role.includes(admin_role)"-->
+        <a class="nav-link" [routerLink]="[menuItem.path]" *ngIf="menuItem.allowed_roles.indexOf(+role_number)>-1"> 
           <i class="material-icons">{{menuItem.icon}}</i>
           <p>{{menuItem.title}}</p>
         </a>

+ 3 - 1
src/app/components/shared/sidebar/sidebar.component.ts

@@ -43,9 +43,11 @@ export class SidebarComponent implements OnInit {
   role_number:any;
 
   constructor(private auth: AuthService, private router: Router) {
+    console.log("encryted user menu");
     console.log(localStorage.getItem("USER_MENU"));
     var bytes  = CryptoJS.AES.decrypt(localStorage.getItem("USER_MENU"), 'soma-inverlec-2019');
     this.role_number = bytes.toString(CryptoJS.enc.Utf8);
+    console.log(this.role_number);
   }
 
   ngOnInit() {
@@ -53,7 +55,7 @@ export class SidebarComponent implements OnInit {
     this.adminMenuItems = ADMIN_ROUTES.filter(menuItem => menuItem);
 
     // must be changed for the method that returns if it is an admin
-    if (this.auth.isLoggedIn() == true) {
+    if (this.auth.isLoggedIn() == true && this.role_number > 1) {
       this.adminMenu = true;
     }
 

+ 66 - 1
src/app/components/users/new-user/new-user.component.html

@@ -1 +1,66 @@
-<p>new-user works!</p>
+<h2 class="floating-title">{{title}}</h2>
+
+<div class="main-content">
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-12">
+
+        <nav aria-label="breadcrumb">
+          <ol class="breadcrumb">
+            <li class="breadcrumb-item"><a [routerLink]="['/']">Dashboard</a></li>
+            <li class="breadcrumb-item"><a [routerLink]="['/users']">Usuarios</a></li>
+            <li class="breadcrumb-item">Nuevo Usuario</li>
+          </ol>
+        </nav>
+      </div>
+    </div>
+    <br>
+    <div class="row justify-content-center">
+      
+      <div class="col-8">
+        <div class="align-container">
+
+          <div class="card">
+            <div class="card-header card-header-icon card-header-rose">
+              <div class="card-icon"><i class="material-icons">map</i></div>
+              <h4 class="card-title">Nuevo Usuario - <small class="category">Complete la información básica</small></h4>
+            </div>
+            <div class="card-body">              
+              <div class="align-container">
+                <form class="form-auth-small ng-untouched ng-pristine ng-valid" [formGroup]="userForm" (ngSubmit)="createUser()">
+                  <div class="form-group">
+                    <label for="first_name">Nombre: </label>
+                    <input type="text" name="first_name" class="form-control" required />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="last_name">Apellido: </label>
+                    <input type="text" name="last_name" class="form-control" required />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="email">Email: </label>
+                    <input type="text" name="email" class="form-control" required />
+                  </div>      
+                  
+                  <div class="form-group">
+                    <label for="role">Rol: </label>
+                    <input type="text" name="role" class="form-control" required />
+                  </div>
+                  <br>
+                  <button class="btn btn-primary">
+                    Crear usuario
+                  </button>
+                  <!--<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>-->
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+
+    </div>          
+  </div>
+</div>

+ 42 - 1
src/app/components/users/new-user/new-user.component.ts

@@ -1,4 +1,7 @@
 import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder } from '@angular/forms';
+import { UserService } from '@app/services/user.service';
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-new-user',
@@ -6,10 +9,48 @@ import { Component, OnInit } from '@angular/core';
   styleUrls: ['./new-user.component.scss']
 })
 export class NewUserComponent implements OnInit {
+  title:string = "Nuevo usuario"; 
+  organizationForm: FormGroup;
 
-  constructor() { }
+
+  constructor(private userService: UserService, private formBuilder: FormBuilder) {
+  }
 
   ngOnInit() {
+    this.organizationForm = this.formBuilder.group({
+      first_name: [''],
+      last_name: [''],
+      email: [''],
+      role: [''],
+    });
+  }
+
+  get f() { return this.organizationForm.controls; }
+
+  createOrganization() {
+    
+      this.userService.createUser(
+        {
+          first_name: this.f.first_name.value,
+          last_name: this.f.last_name.value,
+          email: this.f.email.value,
+          role: this.f.role.value,
+
+        }
+      )
+    .subscribe(success => {
+      if (success) {
+        Swal.fire({
+          allowOutsideClick: false,
+          type: 'info',
+          text: 'Espere por favor...'
+        });
+        //window.location.href="#/dashboard";
+
+      }
+      
+    });
   }
 
+
 }

+ 17 - 11
src/app/components/users/users.component.html

@@ -30,24 +30,30 @@
                 <table mat-table [dataSource]="dataSource" class="example-table">
           
                   <!-- Name Column -->
-                  <ng-container matColumnDef="name">
-                    <th mat-header-cell *matHeaderCellDef>Planta</th>
-                    <td mat-cell *matCellDef="let row">{{row.name}}</td>
+                  <ng-container matColumnDef="email">
+                    <th mat-header-cell *matHeaderCellDef>Correo</th>
+                    <td mat-cell *matCellDef="let row">{{row.email}}</td>
                   </ng-container>
 
                   <!-- Country Column -->
-                  <ng-container matColumnDef="country">
-                    <th mat-header-cell *matHeaderCellDef>País</th>
-                    <td mat-cell *matCellDef="let row">{{row.country}}</td>
+                  <ng-container matColumnDef="first_name">
+                    <th mat-header-cell *matHeaderCellDef>Nombre</th>
+                    <td mat-cell *matCellDef="let row">{{row.first_name}}</td>
                   </ng-container>
 
                   <!-- Country Column -->
-                  <ng-container matColumnDef="city">
-                    <th mat-header-cell *matHeaderCellDef>Ciudad</th>
-                    <td mat-cell *matCellDef="let row">{{row.city}}</td>
+                  <ng-container matColumnDef="last_name">
+                    <th mat-header-cell *matHeaderCellDef>Apellido</th>
+                    <td mat-cell *matCellDef="let row">{{row.last_name}}</td>
                   </ng-container>
                   
-                  <!--  Column -->
+                  <!-- Country Column -->
+                  <ng-container matColumnDef="role">
+                    <th mat-header-cell *matHeaderCellDef>Rol</th>
+                    <td mat-cell *matCellDef="let row">{{row.role}}</td>
+                  </ng-container>
+
+                  <!--  Column 
                   <ng-container matColumnDef="id">
                     <th mat-header-cell *matHeaderCellDef>&nbsp;</th>
                     <td mat-cell *matCellDef="let row">
@@ -56,7 +62,7 @@
                       </a>
                     </td>
                   </ng-container>
-          
+          -->
           
                   <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
                   <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

+ 12 - 12
src/app/components/users/users.component.ts

@@ -1,8 +1,8 @@
 import { Component, ViewChild, OnInit } from '@angular/core';
 
 import {HttpClient} from '@angular/common/http';
-import { Plant } from 'src/app/models/plant';
-import { PlantsService } from 'src/app/services/plants.service';
+import { User } from 'src/app/models/user';
+import { UserService } from 'src/app/services/user.service';
 import {MatPaginator} from '@angular/material/paginator';
 import {MatSort} from '@angular/material/sort';
 import {MatTableDataSource} from '@angular/material/table';
@@ -16,14 +16,14 @@ import {MatTableDataSource} from '@angular/material/table';
 })
 export class UsersComponent implements OnInit {
 
-  title:string = "Plantas";
+  title:string = "Usuarios";
  
-  displayedColumns: string[] = ['name', 'country', 'city', 'id'];
+  displayedColumns: string[] = ['email', 'first_name', 'last_name', 'role'];
   //displayedColumns: string[] = ['state'];
 
-  listData: Plant[] = [];
-  listPlant:any;
-  dataSource = new MatTableDataSource(this.listPlant);
+  listData: User[] = [];
+  listUsers:any;
+  dataSource = new MatTableDataSource(this.listUsers);
 
   resultsLength = 0;
   isLoadingResults = true;
@@ -34,13 +34,13 @@ export class UsersComponent implements OnInit {
 
 
   constructor(
-    private orgService: PlantsService) {}
+    private userService: UserService) {}
 
   ngOnInit() {
-    this.orgService.getAllAssets().subscribe(ans => {
-      this.listPlant = ans["data"];
-      console.log(this.listPlant);
-      this.dataSource.data = this.listPlant;
+    this.userService.getAllUsers().subscribe(ans => {
+      this.listUsers = ans["data"]["users"];
+      console.log(this.listUsers);
+      this.dataSource.data = this.listUsers;
       this.dataSource.paginator = this.paginator;
       this.dataSource.sort = this.sort;
     });

+ 0 - 1
src/app/services/auth.guard.ts

@@ -10,7 +10,6 @@ export class AuthGuard implements CanActivate {
   constructor(private authService: AuthService, private router: Router) { }
 
   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
-    
     if (this.authService.isLoggedIn()) {
       return true
     }

+ 6 - 11
src/app/services/auth2.service.ts

@@ -1,7 +1,7 @@
 import { Injectable } from '@angular/core';
 import { HttpClient } from '@angular/common/http';
 import { of, Observable } from 'rxjs';
-import { catchError, mapTo, tap } from 'rxjs/operators';
+import { catchError, mapTo, tap, map } from 'rxjs/operators';
 import { Token } from '@app/models/token';
 import { environment } from '@environments/environment';
 import * as CryptoJS from 'crypto-js';
@@ -31,27 +31,25 @@ export class AuthService {
   }
 
   logout() {
-    console.log("enter function");
     return this.http.post<any>(`${environment.productionApiUrl}/auth/logout`, {
-      'refreshToken': this.getRefreshToken()
     }).pipe(
       tap(() => this.doLogoutUser()),
       mapTo(true),
       catchError(error => {
-        console.log(error.error);
         return of(false);
       }));
-  }
+    }
 
   isLoggedIn() {
     return !!this.getJwtToken();
   }
 
   refreshToken() {
+    let refreshToken:string = this.getRefreshToken();
     return this.http.post<any>(`${environment.productionApiUrl}/auth/refresh`, {
-      'refreshToken': this.getRefreshToken()
+      'Authorization': `Bearer ${refreshToken}`
     }).pipe(tap((tokens: Token) => {
-      this.storeJwtToken(tokens["data"]["user"].token);
+      this.storeJwtToken(tokens["data"]["access_token"]);
     }));
   }
 
@@ -60,19 +58,16 @@ export class AuthService {
   }
 
   private doLoginUser(email: string, tokens: Token) {
-    console.log("tokens");
-    console.log(tokens["data"]["user"].role);
     this.loggedUser = email;
     this.storeTokens(tokens);
   }
 
   private doLogoutUser() {
-    console.log("loggin out");
     this.loggedUser = null;
     this.removeTokens();
   }
 
-  private getRefreshToken() {
+  getRefreshToken() {
     return localStorage.getItem(this.REFRESH_TOKEN);
   }
 

+ 12 - 1
src/app/services/logs.service.ts

@@ -19,7 +19,18 @@ export class LogsService {
   }
 
   getEnergyProducedByParams(id:string, interval:string, date:string) {
-    return this.http.get(`${environment.productionApiUrl}/asset/energyProducedByInterval/${id}/${interval}/${date}`)
+    return this.http.get(`${environment.productionApiUrl}/asset/${id}/energy-produced/${interval}/${date}`)
+    .pipe(
+      timeout(this.time),
+      map(response =>{
+        return response;
+      }),
+      catchError(this.errorHandl)
+    )
+  }
+
+  getEnergySummaryByAsset(id:string){
+    return this.http.get(`${environment.productionApiUrl}/asset/${id}/energy-stats`)
     .pipe(
       timeout(this.time),
       map(response =>{

+ 45 - 0
src/app/services/organizations.service.ts

@@ -39,6 +39,51 @@ export class OrganizationsService {
     )
   }
 
+
+  getOrganization(id: string){
+    return this.http.get<any>(`${environment.productionApiUrl}/organization/${id}`)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
+
+  createOrganization(organization: { name :string, address :string, 
+    city :string, country :string, contactName :string,
+    contactNumber: string}): Observable<boolean> {
+      return this.http.post<any>(`${environment.productionApiUrl}/organizations`, organization)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
+  
+  updateOrganization(id:string, organization: { name :string, address :string, 
+    city :string, country :string, contactName :string,
+    contactNumber: string}): Observable<boolean> {
+      return this.http.put<any>(`${environment.productionApiUrl}/organization/${id}`, organization)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
+  
+  deleteOrganization(id:string): Observable<boolean> {
+    return this.http.delete<any>(`${environment.productionApiUrl}/organization/${id}`)
+    .pipe(
+      map(response => {
+        return response;
+      }),
+      catchError(this.errorHandl)
+    )  
+  }
+
   getAllOrganizations() {
     return this.http.get(`${environment.productionApiUrl}/organizations`)
     .pipe(

+ 14 - 1
src/app/services/plants.service.ts

@@ -35,7 +35,8 @@ export class PlantsService extends PlantData {
   }
 
   getAllAssets(){
-    return this.http.get(`${environment.productionApiUrl}/assets`)
+    console.log("get assetss");
+    return this.http.get<any>(`${environment.productionApiUrl}/assets`, {})
     .pipe(
       map(response => {
         return response;
@@ -44,6 +45,18 @@ export class PlantsService extends PlantData {
     )
   }
 
+  getAssetById(assetId:string){
+    console.log("get asset by id");
+    return this.http.get<any>(`${environment.productionApiUrl}/asset/${assetId}`, {})
+    .pipe(
+      map(response => {
+        return response;
+      }),
+      catchError(this.errorHandl)
+    )
+  }
+
+
   getAssets() {
     return this.http.get(`${environment.apiUrl}/assets`)
     .pipe(

+ 16 - 8
src/app/services/token.interceptor.ts

@@ -13,18 +13,26 @@ export class TokenInterceptor implements HttpInterceptor {
   constructor(public authService: AuthService) { }
 
   intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
-
-    if (this.authService.getJwtToken()) {
-      request = this.addToken(request, this.authService.getJwtToken());
+    if (request.url.indexOf("auth/refresh")!= -1){
+      request = this.addToken(request, this.authService.getRefreshToken());
     }
-
+    else if (request.url.indexOf("openweather")!= -1){
+      request;
+    }
+    else {
+      if (this.authService.getJwtToken()) {
+        request = this.addToken(request, this.authService.getJwtToken());
+      }
+    }
+    
     return next.handle(request).pipe(catchError(error => {
       if (error instanceof HttpErrorResponse && error.status === 401) {
         return this.handle401Error(request, next);
       } else {
         return throwError(error);
       }
-    }));
+    }));      
+
   }
 
   private addToken(request: HttpRequest<any>, token: string) {
@@ -43,8 +51,8 @@ export class TokenInterceptor implements HttpInterceptor {
       return this.authService.refreshToken().pipe(
         switchMap((token: any) => {
           this.isRefreshing = false;
-          this.refreshTokenSubject.next(token.jwt);
-          return next.handle(this.addToken(request, token.jwt));
+          this.refreshTokenSubject.next(token["data"]["access_token"]);
+          return next.handle(this.addToken(request, token["data"]["access_token"]));
         }));
 
     } else {
@@ -56,4 +64,4 @@ export class TokenInterceptor implements HttpInterceptor {
         }));
     }
   }
-}
+}

+ 32 - 6
src/app/services/user.service.ts

@@ -3,16 +3,42 @@ import { HttpClient } from '@angular/common/http';
 
 import { environment } from '@environments/environment';
 import { User } from '@app/models';
+import { Observable } from 'rxjs/internal/Observable';
+import { throwError } from 'rxjs/internal/observable/throwError';
+import { map, catchError } from 'rxjs/operators';
 
 @Injectable({ providedIn: 'root' })
 export class UserService {
-    constructor(private http: HttpClient) { }
+  constructor(private http: HttpClient) { }
 
-    getAll() {
-        return this.http.get<User[]>(`${environment.apiUrl}/users`);
-    }
+  getAllUsers() {
+      return this.http.get<User[]>(`${environment.productionApiUrl}/users`);
+  }
+
+  getById(id: number) {
+      return this.http.get<User>(`${environment.apiUrl}/users/${id}`);
+  }
+
+  createUser(user: { first_name :string, last_name :string, 
+    email :string, role :string }): Observable<boolean> {
+      return this.http.post<any>(`${environment.productionApiUrl}/organizations`, user)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
 
-    getById(id: number) {
-        return this.http.get<User>(`${environment.apiUrl}/users/${id}`);
+  errorHandl(error) {
+    let errorMessage = '';
+    if(error.error instanceof ErrorEvent) {
+      // Get client-side error
+      errorMessage = error.error.message;
+    } else {
+      // Get server-side error
+      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
     }
+    return throwError(errorMessage);
+  }
 }

+ 1 - 1
src/environments/environment.prod.ts

@@ -1,5 +1,5 @@
 export const environment = {
   production: true,
-  apiUrl: 'http://192.168.98.140:8000',
+  apiUrl: 'https://192.168.98.140:8000',
   appID: '55899b9ea53834f2736b65a3582b734b',
 };

+ 2 - 2
src/environments/environment.ts

@@ -4,8 +4,8 @@
 
 export const environment = {
     production: false,
-    apiUrl: 'https://192.168.98.140:8000',
-    productionApiUrl: 'http://192.168.98.10:8888',
+    apiUrl: 'https://api.inverlec.solar',
+    productionApiUrl: 'http://192.168.98.10:8888/api/v1',
     appID: '55899b9ea53834f2736b65a3582b734b',
     gKey: '',
     config: {