diff --git a/agrilink_vocpro/package-lock.json b/agrilink_vocpro/package-lock.json index 7c65fad..353c784 100644 --- a/agrilink_vocpro/package-lock.json +++ b/agrilink_vocpro/package-lock.json @@ -8,17 +8,19 @@ "name": "agrilink-vocpro", "version": "0.0.0", "dependencies": { - "@angular/animations": "^18.2.8", + "@angular/animations": "^18.2.4", "@angular/common": "^18.2.0", "@angular/compiler": "^18.2.0", "@angular/core": "^18.2.0", "@angular/forms": "^18.2.0", + "@angular/material": "^17.3.6", "@angular/platform-browser": "^18.2.0", "@angular/platform-browser-dynamic": "^18.2.0", "@angular/router": "^18.2.0", "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", "chart.js": "^4.4.4", + "date-fns": "^4.1.0", "highcharts-angular": "^4.0.1", "jwt-decode": "^4.0.0", "ngx-toastr": "^19.0.0", @@ -30,6 +32,7 @@ "@angular-devkit/build-angular": "^18.2.4", "@angular/cli": "^18.2.4", "@angular/compiler-cli": "^18.2.0", + "@types/date-fns": "^2.5.3", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.2.0", "karma": "~6.4.0", @@ -274,9 +277,9 @@ } }, "node_modules/@angular/animations": { - "version": "18.2.8", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.8.tgz", - "integrity": "sha512-dMSn2hg70siv3lhP+vqhMbgc923xw6XBUvnpCPEzhZqFHvPXfh/LubmsD5RtqHmjWebXtgVcgS+zg3Gq3jB2lg==", + "version": "18.2.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.4.tgz", + "integrity": "sha512-ajjXpLD+SyxbHnmhj2ZvYpXneviOjcBgU9L2UX4OVS0jVWxCNHLhJrcMqtqFHA6U5fPnhPNR9cmnt6tmqri0rA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -285,7 +288,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.8" + "@angular/core": "18.2.4" } }, "node_modules/@angular/build": { @@ -357,6 +360,24 @@ } } }, + "node_modules/@angular/cdk": { + "version": "17.3.6", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.6.tgz", + "integrity": "sha512-7eKrC61/6pmMAxllU/vYKadZRF7x7GxUYpA5G70fNaQsIUUiZvxx/SJN9AuZEoPGAtF6atKlJD8QVmFoDzv/Lw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^17.0.0 || ^18.0.0", + "@angular/core": "^17.0.0 || ^18.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@angular/cli": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.4.tgz", @@ -490,6 +511,71 @@ "rxjs": "^6.5.3 || ^7.4.0" } }, + "node_modules/@angular/material": { + "version": "17.3.6", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-17.3.6.tgz", + "integrity": "sha512-sttN0JNvd2QvCCFIsxb5noiy7tgQdWrwvmrkJ+3KguHh5X84jDliA/d8N7Xgy2IBLnS/q/Hl9DdRCOiItWG1bw==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/auto-init": "15.0.0-canary.7f224ddd4.0", + "@material/banner": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/button": "15.0.0-canary.7f224ddd4.0", + "@material/card": "15.0.0-canary.7f224ddd4.0", + "@material/checkbox": "15.0.0-canary.7f224ddd4.0", + "@material/chips": "15.0.0-canary.7f224ddd4.0", + "@material/circular-progress": "15.0.0-canary.7f224ddd4.0", + "@material/data-table": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dialog": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/drawer": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/fab": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/floating-label": "15.0.0-canary.7f224ddd4.0", + "@material/form-field": "15.0.0-canary.7f224ddd4.0", + "@material/icon-button": "15.0.0-canary.7f224ddd4.0", + "@material/image-list": "15.0.0-canary.7f224ddd4.0", + "@material/layout-grid": "15.0.0-canary.7f224ddd4.0", + "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", + "@material/linear-progress": "15.0.0-canary.7f224ddd4.0", + "@material/list": "15.0.0-canary.7f224ddd4.0", + "@material/menu": "15.0.0-canary.7f224ddd4.0", + "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", + "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", + "@material/radio": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/segmented-button": "15.0.0-canary.7f224ddd4.0", + "@material/select": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/slider": "15.0.0-canary.7f224ddd4.0", + "@material/snackbar": "15.0.0-canary.7f224ddd4.0", + "@material/switch": "15.0.0-canary.7f224ddd4.0", + "@material/tab": "15.0.0-canary.7f224ddd4.0", + "@material/tab-bar": "15.0.0-canary.7f224ddd4.0", + "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", + "@material/tab-scroller": "15.0.0-canary.7f224ddd4.0", + "@material/textfield": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tooltip": "15.0.0-canary.7f224ddd4.0", + "@material/top-app-bar": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/animations": "^17.0.0 || ^18.0.0", + "@angular/cdk": "17.3.6", + "@angular/common": "^17.0.0 || ^18.0.0", + "@angular/core": "^17.0.0 || ^18.0.0", + "@angular/forms": "^17.0.0 || ^18.0.0", + "@angular/platform-browser": "^17.0.0 || ^18.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@angular/platform-browser": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.4.tgz", @@ -3437,6 +3523,808 @@ "win32" ] }, + "node_modules/@material/animation": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-1GSJaPKef+7HRuV+HusVZHps64cmZuOItDbt40tjJVaikcaZvwmHlcTxRIqzcRoCdt5ZKHh3NoO7GB9Khg4Jnw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/auto-init": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-t7ZGpRJ3ec0QDUO0nJu/SMgLW7qcuG2KqIsEYD1Ej8qhI2xpdR2ydSDQOkVEitXmKoGol1oq4nYSBjTlB65GqA==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/banner": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-g9wBUZzYBizyBcBQXTIafnRUUPi7efU9gPJfzeGgkynXiccP/vh5XMmH+PBxl5v+4MlP/d4cZ2NUYoAN7UTqSA==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/button": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/base": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-I9KQOKXpLfJkP8MqZyr8wZIzdPHrwPjFvGd9zSK91/vPyE4hzHRJc/0njsh9g8Lm9PRYLbifXX+719uTbHxx+A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/button": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-BHB7iyHgRVH+JF16+iscR+Qaic+p7LU1FOLgP8KucRlpF9tTwIxQA6mJwGRi5gUtcG+vyCmzVS+hIQ6DqT/7BA==", + "license": "MIT", + "dependencies": { + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/card": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-kt7y9/IWOtJTr3Z/AoWJT3ZLN7CLlzXhx2udCLP9ootZU2bfGK0lzNwmo80bv/pJfrY9ihQKCtuGTtNxUy+vIw==", + "license": "MIT", + "dependencies": { + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/checkbox": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-rURcrL5O1u6hzWR+dNgiQ/n89vk6tdmdP3mZgnxJx61q4I/k1yijKqNJSLrkXH7Rto3bM5NRKMOlgvMvVd7UMQ==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/chips": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-AYAivV3GSk/T/nRIpH27sOHFPaSMrE3L0WYbnb5Wa93FgY8a0fbsFYtSH2QmtwnzXveg+B1zGTt7/xIIcynKdQ==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/checkbox": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "safevalues": "^0.3.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/circular-progress": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-DJrqCKb+LuGtjNvKl8XigvyK02y36GRkfhMUYTcJEi3PrOE00bwXtyj7ilhzEVshQiXg6AHGWXtf5UqwNrx3Ow==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/progress-indicator": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/data-table": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-/2WZsuBIq9z9RWYF5Jo6b7P6u0fwit+29/mN7rmAZ6akqUR54nXyNfoSNiyydMkzPlZZsep5KrSHododDhBZbA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/checkbox": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/icon-button": "15.0.0-canary.7f224ddd4.0", + "@material/linear-progress": "15.0.0-canary.7f224ddd4.0", + "@material/list": "15.0.0-canary.7f224ddd4.0", + "@material/menu": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/select": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/density": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-o9EXmGKVpiQ6mHhyV3oDDzc78Ow3E7v8dlaOhgaDSXgmqaE8v5sIlLNa/LKSyUga83/fpGk3QViSGXotpQx0jA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dialog": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-u0XpTlv1JqWC/bQ3DavJ1JguofTelLT2wloj59l3/1b60jv42JQ6Am7jU3I8/SIUB1MKaW7dYocXjDWtWJakLA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/button": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/icon-button": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dom": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-mQ1HT186GPQSkRg5S18i70typ5ZytfjL09R0gJ2Qg5/G+MLCGi7TAjZZSH65tuD/QGOjel4rDdWOTmYbPYV6HA==", + "license": "MIT", + "dependencies": { + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/drawer": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-qyO0W0KBftfH8dlLR0gVAgv7ZHNvU8ae11Ao6zJif/YxcvK4+gph1z8AO4H410YmC2kZiwpSKyxM1iQCCzbb4g==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/list": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/elevation": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-tV6s4/pUBECedaI36Yj18KmRCk1vfue/JP/5yYRlFNnLMRVISePbZaKkn/BHXVf+26I3W879+XqIGlDVdmOoMA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/fab": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-4h76QrzfZTcPdd+awDPZ4Q0YdSqsXQnS540TPtyXUJ/5G99V6VwGpjMPIxAsW0y+pmI9UkLL/srrMaJec+7r4Q==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/feature-targeting": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-SAjtxYh6YlKZriU83diDEQ7jNSP2MnxKsER0TvFeyG1vX/DWsUyYDOIJTOEa9K1N+fgJEBkNK8hY55QhQaspew==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/floating-label": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-0KMo5ijjYaEHPiZ2pCVIcbaTS2LycvH9zEhEMKwPPGssBCX7iz5ffYQFk7e5yrQand1r3jnQQgYfHAwtykArnQ==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/focus-ring": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-Jmg1nltq4J6S6A10EGMZnvufrvU3YTi+8R8ZD9lkSbun0Fm2TVdICQt/Auyi6An9zP66oQN6c31eqO6KfIPsDg==", + "license": "MIT", + "dependencies": { + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0" + } + }, + "node_modules/@material/form-field": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-fEPWgDQEPJ6WF7hNnIStxucHR9LE4DoDSMqCsGWS2Yu+NLZYLuCEecgR0UqQsl1EQdNRaFh8VH93KuxGd2hiPg==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/icon-button": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-DcK7IL4ICY/DW+48YQZZs9g0U1kRaW0Wb0BxhvppDMYziHo/CTpFdle4gjyuTyRxPOdHQz5a97ru48Z9O4muTw==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/image-list": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-voMjG2p80XbjL1B2lmF65zO5gEgJOVKClLdqh4wbYzYfwY/SR9c8eLvlYG7DLdFaFBl/7gGxD8TvvZ329HUFPw==", + "license": "MIT", + "dependencies": { + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/layout-grid": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-veDABLxMn2RmvfnUO2RUmC1OFfWr4cU+MrxKPoDD2hl3l3eDYv5fxws6r5T1JoSyXoaN+oEZpheS0+M9Ure8Pg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/line-ripple": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-f60hVJhIU6I3/17Tqqzch1emUKEcfVVgHVqADbU14JD+oEIz429ZX9ksZ3VChoU3+eejFl+jVdZMLE/LrAuwpg==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/linear-progress": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-pRDEwPQielDiC9Sc5XhCXrGxP8wWOnAO8sQlMebfBYHYqy5hhiIzibezS8CSaW4MFQFyXmCmpmqWlbqGYRmiyg==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/progress-indicator": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/list": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-Is0NV91sJlXF5pOebYAtWLF4wU2MJDbYqztML/zQNENkQxDOvEXu3nWNb3YScMIYJJXvARO0Liur5K4yPagS1Q==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/menu": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-D11QU1dXqLbh5X1zKlEhS3QWh0b5BPNXlafc5MXfkdJHhOiieb7LC9hMJhbrHtj24FadJ7evaFW/T2ugJbJNnQ==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/list": "15.0.0-canary.7f224ddd4.0", + "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/menu-surface": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-7RZHvw0gbwppaAJ/Oh5SWmfAKJ62aw1IMB3+3MRwsb5PLoV666wInYa+zJfE4i7qBeOn904xqT2Nko5hY0ssrg==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/notched-outline": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-Yg2usuKB2DKlKIBISbie9BFsOVuffF71xjbxPbybvqemxqUBd+bD5/t6H1fLE+F8/NCu5JMigho4ewUU+0RCiw==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/floating-label": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/progress-indicator": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-UPbDjE5CqT+SqTs0mNFG6uFEw7wBlgYmh+noSkQ6ty/EURm8lF125dmi4dv4kW0+octonMXqkGtAoZwLIHKf/w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/radio": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-wR1X0Sr0KmQLu6+YOFKAI84G3L6psqd7Kys5kfb8WKBM36zxO5HQXC5nJm/Y0rdn22ixzsIz2GBo0MNU4V4k1A==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/ripple": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-JqOsWM1f4aGdotP0rh1vZlPZTg6lZgh39FIYHFMfOwfhR+LAikUJ+37ciqZuewgzXB6iiRO6a8aUH6HR5SJYPg==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/rtl": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-UVf14qAtmPiaaZjuJtmN36HETyoKWmsZM/qn1L5ciR2URb8O035dFWnz4ZWFMmAYBno/L7JiZaCkPurv2ZNrGA==", + "license": "MIT", + "dependencies": { + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/segmented-button": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-LCnVRUSAhELTKI/9hSvyvIvQIpPpqF29BV+O9yM4WoNNmNWqTulvuiv7grHZl6Z+kJuxSg4BGbsPxxb9dXozPg==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/touch-target": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/select": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-WioZtQEXRpglum0cMSzSqocnhsGRr+ZIhvKb3FlaNrTaK8H3Y4QA7rVjv3emRtrLOOjaT6/RiIaUMTo9AGzWQQ==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/floating-label": "15.0.0-canary.7f224ddd4.0", + "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", + "@material/list": "15.0.0-canary.7f224ddd4.0", + "@material/menu": "15.0.0-canary.7f224ddd4.0", + "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", + "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/shape": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-8z8l1W3+cymObunJoRhwFPKZ+FyECfJ4MJykNiaZq7XJFZkV6xNmqAVrrbQj93FtLsECn9g4PjjIomguVn/OEw==", + "license": "MIT", + "dependencies": { + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/slider": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-QU/WSaSWlLKQRqOhJrPgm29wqvvzRusMqwAcrCh1JTrCl+xwJ43q5WLDfjYhubeKtrEEgGu9tekkAiYfMG7EBw==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/snackbar": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-sm7EbVKddaXpT/aXAYBdPoN0k8yeg9+dprgBUkrdqGzWJAeCkxb4fv2B3He88YiCtvkTz2KLY4CThPQBSEsMFQ==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/button": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/icon-button": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/switch": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-lEDJfRvkVyyeHWIBfoxYjJVl+WlEAE2kZ/+6OqB1FW0OV8ftTODZGhHRSzjVBA1/p4FPuhAtKtoK9jTpa4AZjA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "safevalues": "^0.3.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tab": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-E1xGACImyCLurhnizyOTCgOiVezce4HlBFAI6YhJo/AyVwjN2Dtas4ZLQMvvWWqpyhITNkeYdOchwCC1mrz3AQ==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tab-bar": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-p1Asb2NzrcECvAQU3b2SYrpyJGyJLQWR+nXTYzDKE8WOpLIRCXap2audNqD7fvN/A20UJ1J8U01ptrvCkwJ4eA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/tab": "15.0.0-canary.7f224ddd4.0", + "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", + "@material/tab-scroller": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tab-indicator": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-h9Td3MPqbs33spcPS7ecByRHraYgU4tNCZpZzZXw31RypjKvISDv/PS5wcA4RmWqNGih78T7xg4QIGsZg4Pk4w==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tab-scroller": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-LFeYNjQpdXecwECd8UaqHYbhscDCwhGln5Yh+3ctvcEgvmDPNjhKn/DL3sWprWvG8NAhP6sHMrsGhQFVdCWtTg==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/tab": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/textfield": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-AExmFvgE5nNF0UA4l2cSzPghtxSUQeeoyRjFLHLy+oAaE4eKZFrSy0zEpqPeWPQpEMDZk+6Y+6T3cOFYBeSvsw==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/density": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/floating-label": "15.0.0-canary.7f224ddd4.0", + "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", + "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/theme": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-hs45hJoE9yVnoVOcsN1jklyOa51U4lzWsEnQEuJTPOk2+0HqCQ0yv/q0InpSnm2i69fNSyZC60+8HADZGF8ugQ==", + "license": "MIT", + "dependencies": { + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tokens": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-r9TDoicmcT7FhUXC4eYMFnt9TZsz0G8T3wXvkKncLppYvZ517gPyD/1+yhuGfGOxAzxTrM66S/oEc1fFE2q4hw==", + "license": "MIT", + "dependencies": { + "@material/elevation": "15.0.0-canary.7f224ddd4.0" + } + }, + "node_modules/@material/tooltip": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-8qNk3pmPLTnam3XYC1sZuplQXW9xLn4Z4MI3D+U17Q7pfNZfoOugGr+d2cLA9yWAEjVJYB0mj8Yu86+udo4N9w==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/button": "15.0.0-canary.7f224ddd4.0", + "@material/dom": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/tokens": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "safevalues": "^0.3.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/top-app-bar": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-SARR5/ClYT4CLe9qAXakbr0i0cMY0V3V4pe3ElIJPfL2Z2c4wGR1mTR8m2LxU1MfGKK8aRoUdtfKaxWejp+eNA==", + "license": "MIT", + "dependencies": { + "@material/animation": "15.0.0-canary.7f224ddd4.0", + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/elevation": "15.0.0-canary.7f224ddd4.0", + "@material/ripple": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/shape": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "@material/typography": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/touch-target": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-BJo/wFKHPYLGsRaIpd7vsQwKr02LtO2e89Psv0on/p0OephlNIgeB9dD9W+bQmaeZsZ6liKSKRl6wJWDiK71PA==", + "license": "MIT", + "dependencies": { + "@material/base": "15.0.0-canary.7f224ddd4.0", + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/rtl": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/typography": { + "version": "15.0.0-canary.7f224ddd4.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.7f224ddd4.0.tgz", + "integrity": "sha512-kBaZeCGD50iq1DeRRH5OM5Jl7Gdk+/NOfKArkY4ksBZvJiStJ7ACAhpvb8MEGm4s3jvDInQFLsDq3hL+SA79sQ==", + "license": "MIT", + "dependencies": { + "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", + "@material/theme": "15.0.0-canary.7f224ddd4.0", + "tslib": "^2.1.0" + } + }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", @@ -3864,6 +4752,17 @@ "node": ">=14" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.20.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", @@ -4314,6 +5213,13 @@ "@types/node": "*" } }, + "node_modules/@types/date-fns": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@types/date-fns/-/date-fns-2.5.3.tgz", + "integrity": "sha512-4KVPD3g5RjSgZtdOjvI/TDFkLNUHhdoWxmierdQbDeEg17Rov0hbBYtIzNaQA67ORpteOhvR9YEMTb6xeDCang==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -5928,9 +6834,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "license": "MIT", "engines": { @@ -6266,6 +7172,16 @@ "dev": true, "license": "MIT" }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -6585,9 +7501,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "license": "MIT", "dependencies": { @@ -6596,7 +7512,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -6647,7 +7563,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -6959,9 +7875,9 @@ "license": "Apache-2.0" }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6970,7 +7886,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -7002,9 +7918,9 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", "engines": { @@ -7623,6 +8539,13 @@ "node": ">= 0.4" } }, + "node_modules/highcharts": { + "version": "11.4.8", + "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.4.8.tgz", + "integrity": "sha512-5Tke9LuzZszC4osaFisxLIcw7xgNGz4Sy3Jc9pRMV+ydm6sYqsPYdU8ELOgpzGNrbrRNDRBtveoR5xS3SzneEA==", + "license": "https://www.highcharts.com/license", + "peer": true + }, "node_modules/highcharts-angular": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/highcharts-angular/-/highcharts-angular-4.0.1.tgz", @@ -10855,7 +11778,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -11753,6 +12676,12 @@ "dev": true, "license": "MIT" }, + "node_modules/safevalues": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/safevalues/-/safevalues-0.3.4.tgz", + "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==", + "license": "Apache-2.0" + }, "node_modules/sass": { "version": "1.77.6", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", @@ -12245,9 +13174,9 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "license": "MIT", "dependencies": { @@ -12255,7 +13184,7 @@ "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -13990,9 +14919,9 @@ } }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/agrilink_vocpro/package.json b/agrilink_vocpro/package.json index d8d8a65..96794cb 100644 --- a/agrilink_vocpro/package.json +++ b/agrilink_vocpro/package.json @@ -10,17 +10,19 @@ }, "private": true, "dependencies": { - "@angular/animations": "^18.2.8", + "@angular/animations": "^18.2.4", "@angular/common": "^18.2.0", "@angular/compiler": "^18.2.0", "@angular/core": "^18.2.0", "@angular/forms": "^18.2.0", + "@angular/material": "^17.3.6", "@angular/platform-browser": "^18.2.0", "@angular/platform-browser-dynamic": "^18.2.0", "@angular/router": "^18.2.0", "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", "chart.js": "^4.4.4", + "date-fns": "^4.1.0", "highcharts-angular": "^4.0.1", "jwt-decode": "^4.0.0", "ngx-toastr": "^19.0.0", @@ -32,6 +34,7 @@ "@angular-devkit/build-angular": "^18.2.4", "@angular/cli": "^18.2.4", "@angular/compiler-cli": "^18.2.0", + "@types/date-fns": "^2.5.3", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.2.0", "karma": "~6.4.0", diff --git a/agrilink_vocpro/src/app/app.routes.ts b/agrilink_vocpro/src/app/app.routes.ts index c90f077..9306af8 100644 --- a/agrilink_vocpro/src/app/app.routes.ts +++ b/agrilink_vocpro/src/app/app.routes.ts @@ -5,6 +5,7 @@ import { AuthComponent } from './pages/auth/auth.component'; import { AuthGuard } from './cores/guards/auth.guard'; import { RegisterComponent } from './pages/register/register.component'; import { HistorygraphComponent } from './pages/dashboard/page/historygraph/historygraph.component'; +import { ActualgraphComponent } from './pages/dashboard/page/actualgraph/actualgraph.component'; export const routes: Routes = [ { @@ -33,6 +34,11 @@ export const routes: Routes = [ path: 'historygraph', component: HistorygraphComponent, canActivate: [AuthGuard] + }, + { + path: 'actualgraph', + component: ActualgraphComponent, + canActivate: [AuthGuard] } ] } diff --git a/agrilink_vocpro/src/app/cores/interface/sensor-data.ts b/agrilink_vocpro/src/app/cores/interface/sensor-data.ts index 51a219c..23043a8 100644 --- a/agrilink_vocpro/src/app/cores/interface/sensor-data.ts +++ b/agrilink_vocpro/src/app/cores/interface/sensor-data.ts @@ -1,6 +1,7 @@ export interface ParameterSensor { hour: number; day: number; + date: number; //for DHT sensor vicitemperature?: number; diff --git a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.html b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.html index 31c74f1..70fad21 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.html +++ b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.html @@ -3,10 +3,7 @@

{{ greeting }}

Welcome back to your management system

-
-

Latest Update: {{latestUpdate}}

-
- +
@@ -158,10 +155,15 @@ Katup Nutrisi - + Katup Air + + + Pompa Air + + Relay {{ relay.number }} @@ -170,9 +172,7 @@
- - - +
Monitoring Graphs
diff --git a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.scss b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.scss index ad03ede..a33e66b 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.scss +++ b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.scss @@ -16,13 +16,7 @@ .description { color: #49473C; font-size: 15px; - margin-top: 10px; -} - -.update{ - color: #49473C; - font-size: 15px; - margin-top: 18px; + margin: 10px 0px 15px 0px; } .card-container { @@ -102,6 +96,10 @@ margin-top: 20px; justify-content: center; } + + .relay-container{ + justify-content: center; + } } @media (max-width: 344px) { @@ -126,6 +124,10 @@ margin-top: 20px; justify-content: center; } + + .relay-container{ + justify-content: center; + } } button { diff --git a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.ts b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.ts index 82dd575..8d6b696 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.ts +++ b/agrilink_vocpro/src/app/pages/dashboard/dashboard.component.ts @@ -33,7 +33,6 @@ export class DashboardComponent implements OnInit { ngOnInit(): void { this.selectedButton = 'dht'; - this.startClock(); this.updateGreeting(); this.loadData(); } @@ -44,26 +43,6 @@ export class DashboardComponent implements OnInit { } } - startClock(): void { - this.updateLatestTime(); - - this.intervalId = setInterval(() => { - this.updateLatestTime(); - }, 1000); - } - - updateLatestTime(): void { - const now = new Date(); - const options: Intl.DateTimeFormatOptions = { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }; - this.latestUpdate = now.toLocaleString('en-GB', options); - } updateGreeting(): void { const hour = new Date().getHours(); @@ -131,8 +110,6 @@ export class DashboardComponent implements OnInit { }; } } - - this.updateLatestTime(); this.isLoaded = false; }, (error) => { @@ -157,10 +134,10 @@ export class DashboardComponent implements OnInit { created_at: relay.created_at, current_status: relay.current_status })); - this.relayStatus.sort((a, b) => a.number - b.number); - this.noData = false; // Data available + this.relayStatus.sort((a, b) => b.number - a.number); + + this.noData = false; } else { - // Throw an error if relay data is empty this.handleError({ message: 'No available relay data.' }); this.noData = true; } @@ -172,9 +149,8 @@ export class DashboardComponent implements OnInit { this.hasError = true; } ); -} - - + } + handleError(error: any): void { if (this.selectedButton === 'dht') { this.toast.error('Error fetching DHT sensor data. Please try again.', 'Error', { timeOut: 3000 }); diff --git a/agrilink_vocpro/src/app/pages/dashboard/layouts/sidebar/sidebar.component.html b/agrilink_vocpro/src/app/pages/dashboard/layouts/sidebar/sidebar.component.html index 6e2623d..669dde6 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/layouts/sidebar/sidebar.component.html +++ b/agrilink_vocpro/src/app/pages/dashboard/layouts/sidebar/sidebar.component.html @@ -11,6 +11,10 @@ History Graph +
  • + + Actual Graph +

  • diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.html b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.html new file mode 100644 index 0000000..ddca21a --- /dev/null +++ b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.html @@ -0,0 +1,20 @@ +
    +
    +

    {{ greeting }}

    +

    Compare your actual data with the standard data

    +
    +
    + + +
    + +
    +
    Actual Graph Sensor NPK 1
    +
    Actual Graph Sensor NPK 2
    +
    + + +

    No available data

    +
    +
    +
    diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.scss b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.scss new file mode 100644 index 0000000..1231928 --- /dev/null +++ b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.scss @@ -0,0 +1,94 @@ +.container { + font-family: "Onest", sans-serif; +} + +.title { + color: #49473C; + font-size: 30px; + margin-top: 10px; +} + +.description { + color: #49473C; + font-size: 15px; + margin: 10px 0px 15px 0px; +} + +.graph { + width: 100%; + height: 400px; + position: relative; + max-width: 100%; + border-radius: 10px; + border: 1px solid #E5E5E5; + padding: 20px 20px 0px 20px; + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + text-align: center; + margin-top: 20px; +} + +.title-graph { + color: #49473C; + font-size: 20px; + font-weight: 400; + margin-top: 15px; + margin-bottom: 20px; + position: relative; +} + +.graph-content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; +} + +.spinner { + font-size: 30px; + color: #16423C; + position: absolute; +} + +@media (max-width: 768px) { + .graph { + height: 300px; + } + + .title-graph { + margin: auto; + font-size: 15px; + } +} + +@media (max-width: 344px) { + button { + color: #49473C; + margin-right: 20px; + margin-bottom: 20px; + } + + .title-graph { + font-size: 15px; + margin: auto; + } +} + +button { + border: none; + border-radius: 10px; + padding: 5px 10px; + font-size: 15px; + cursor: pointer; + margin-right: 20px; +} + +.active-button { + background-color: #cad849; + color: white; +} diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.spec.ts b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.spec.ts new file mode 100644 index 0000000..4042944 --- /dev/null +++ b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ActualgraphComponent } from './actualgraph.component'; + +describe('ActualgraphComponent', () => { + let component: ActualgraphComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ActualgraphComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ActualgraphComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.ts b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.ts new file mode 100644 index 0000000..8799923 --- /dev/null +++ b/agrilink_vocpro/src/app/pages/dashboard/page/actualgraph/actualgraph.component.ts @@ -0,0 +1,201 @@ +import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core'; +import { Chart, registerables } from 'chart.js'; +import { SensorService } from '../../../../cores/services/sensor.service'; +import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data'; +import { CommonModule } from '@angular/common'; + +Chart.register(...registerables); + +@Component({ + selector: 'app-actualgraph', + standalone: true, + imports: [CommonModule], + templateUrl: './actualgraph.component.html', + styleUrls: ['./actualgraph.component.scss'] +}) +export class ActualgraphComponent implements OnInit { + @ViewChild('chartCanvas', { static: false }) chartCanvas?: ElementRef; + private chart: Chart | undefined; + selectedButton: string = 'npk1'; + isLoading: boolean = true; + isNoData: boolean = false; + greeting = ''; + + constructor( + private sensorService: SensorService, + private cdr: ChangeDetectorRef + ) {} + + ngOnInit(): void { + this.updateGreeting(); + this.loadData('npk1'); + } + + loadData(sensorType: string): void { + console.log('Loading data for sensor:', sensorType); + this.selectedButton = sensorType; + this.isLoading = true; + this.isNoData = false; + + this.sensorService.getLatestData().subscribe( + (response: ApiResponse) => { + console.log('Data received:', response); + if (response.statusCode === 200) { + const selectedData = (response.data as { [key: string]: any[] })[sensorType]; + + if (selectedData && selectedData.length > 0) { + const npkData: ParameterSensor = selectedData[0]; + + if (sensorType === 'npk1' || sensorType === 'npk2') { + const actualData = [ + { x: npkData.soilnitrogen ?? 0, y: 0 }, + { x: npkData.soilphosphorus ?? 0, y: 1 }, + { x: npkData.soilpotassium ?? 0, y: 2 } + ]; + + this.chartData.datasets[0].data = actualData; + this.isLoading = false; + this.cdr.detectChanges(); + + setTimeout(() => { + this.initializeChart(); + }); + } + } else { + this.isNoData = true; + this.isLoading = false; + this.cdr.detectChanges(); + } + } else { + console.error('Error loading data: ', response.message); + this.isLoading = false; + this.cdr.detectChanges(); + } + }, + (error) => { + console.error('Error loading data:', error); + this.isLoading = false; + this.cdr.detectChanges(); + } + ); + } + + // Initialize Chart + private initializeChart(): void { + if (this.chartCanvas?.nativeElement) { + console.log('Initializing chart...'); + const ctx = this.chartCanvas.nativeElement.getContext('2d'); + if (ctx) { + this.chart = new Chart(ctx, { + type: 'bar', + data: this.chartData, + options: this.chartOptions + }); + } + } else { + console.warn('Chart canvas is not available'); + } + } + + updateGreeting(): void { + const hour = new Date().getHours(); + this.greeting = hour < 12 ? 'Good Morning' : hour < 18 ? 'Good Afternoon' : 'Good Evening'; + } + + public chartData = { + labels: ['Nitrogen', 'Phosphor', 'Kalium'], + datasets: [ + { + label: 'Actual Data', + data: [], + backgroundColor: 'rgb(18, 55, 42)', + borderColor: 'rgb(18, 55, 42)', + borderWidth: 1, + type: 'bubble' + }, + { + label: 'Start Data Range', + data: [ + { x: 100, y: 0 }, + { x: 90, y: 1 }, + { x: 220, y: 2 } + ], + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 0, + type: 'bar', + stack: 'range', + }, + { + label: 'Standard Data Range', + data: [ + { x: 100, y: 0 }, + { x: 35, y: 1 }, + { x: 200, y: 2 } + ], + backgroundColor: 'rgb(212, 231, 197)', + borderWidth: 1, + type: 'bar', + stack: 'range' + } + ] + }; + + public chartOptions = { + responsive: true, + maintainAspectRatio: false, + indexAxis: 'y', + scales: { + x: { + title: { + display: true, + text: 'Value (mg/L)', + }, + min: 0, + max: 300, + type: 'linear', + }, + y: { + title: { + display: true, + text: 'Sensor Parameter', + }, + stacked: true, + }, + }, + plugins: { + tooltip: { + callbacks: { + title: function (tooltipItem: any) { + // Display the label (Nitrogen, Phosphorus, or Kalium) + return tooltipItem[0].label; + }, + label: function (tooltipItem: any) { + const dataset = tooltipItem.dataset; + const dataIndex = tooltipItem.dataIndex; + const data = dataset.data[dataIndex]; + + let tooltipText = `Actual Value: ${data.x} mg/L`; + + if (dataset.type === 'bar') { + const startRangeDataset = tooltipItem.chart.data.datasets.find((ds: any) => ds.label === 'Start Data Range'); + const standardRangeDataset = tooltipItem.chart.data.datasets.find((ds: any) => ds.label === 'Standard Data Range'); + + const startRangeValue = startRangeDataset?.data.find((point: any) => point.y === data.y)?.x; + const standardRangeValue = standardRangeDataset?.data.find((point: any) => point.y === data.y)?.x; + + if (startRangeValue !== undefined && standardRangeValue !== undefined) { + const minValue = startRangeValue; + const maxValue = startRangeValue + standardRangeValue; + tooltipText = `(Standard Range: ${minValue} - ${maxValue} mg/L)`; + } + } + + return tooltipText; + }, + }, + }, + }, + }; + + +} diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.html b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.html index a1ef947..70f8098 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.html +++ b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.html @@ -4,6 +4,18 @@ +
    + + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + +
    Sensor BHT
    diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss index 4fa00d6..dd618a1 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss +++ b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.scss @@ -1,9 +1,26 @@ .container-graph { display: flex; flex-direction: column; - justify-content: flex-start; + position: relative; height: max-content; + .date-picker{ + display: flex; + justify-content: flex-end; + padding: 10px 20px; + } + + .mat-form-field{ + font-family: 'Onest', sans-serif; + } + + mat-datepicker-toggle, mat-date-range-input{ + color: #16423C; + } + + .mat-form-field.mat-focused .mat-date-range-input { + color: #16423C; + } .sensor-wrapper { position: relative; @@ -62,6 +79,17 @@ width: 100%; max-width: 100%; } + + .date-picker{ + display: flex; + justify-content: center; + padding: 10px 20px; + } + + mat-hint{ + font-size: 10px; + align-items: center; + } } @media (max-width: 344px) { @@ -70,6 +98,17 @@ width: 100%; max-width: 100%; } + + .date-picker{ + display: flex; + justify-content: center; + padding: 10px 20px; + } + + mat-hint{ + font-size: 10px; + align-items: center; + } } .loading { @@ -88,3 +127,5 @@ height: 100%; font-size: 18px; } + + diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts index 22d18a5..ad65e0a 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts +++ b/agrilink_vocpro/src/app/pages/dashboard/page/graph/graph.component.ts @@ -2,8 +2,13 @@ import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, OnDestroy, OnC import { Chart, registerables } from 'chart.js'; import { SensorService } from '../../../../cores/services/sensor.service'; import { ApiResponse, ParameterSensor } from '../../../../cores/interface/sensor-data'; -import { CommonModule } from '@angular/common'; +import { CommonModule, formatDate } from '@angular/common'; import { FormsModule } from '@angular/forms'; +import { provideNativeDateAdapter} from '@angular/material/core'; +import { MatDatepickerModule} from '@angular/material/datepicker'; +import { MatFormFieldModule} from '@angular/material/form-field'; +import { format } from 'date-fns'; +import { ToastrService } from 'ngx-toastr'; Chart.register(...registerables); @@ -23,7 +28,8 @@ const parameterColors: { [key: string]: string } = { @Component({ selector: 'app-graph', standalone: true, - imports: [CommonModule, FormsModule], + imports: [CommonModule, FormsModule, MatDatepickerModule, MatFormFieldModule], + providers: [provideNativeDateAdapter()], templateUrl: './graph.component.html', styleUrls: ['./graph.component.scss'] }) @@ -34,6 +40,9 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang @Input() interval: string = 'hourly'; selectedInterval: string = 'HOURLY'; + startDate: Date | null = null; + endDate: Date | null = null; + isLoadingDHT: boolean = true; isLoadingNPK1: boolean = true; isLoadingNPK2: boolean = true; @@ -73,14 +82,15 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang selectedNPK2: string = 'npk'; private resizeListener!: () => void; + private updateTimeout: any; - constructor(private sensorService: SensorService, private cdr: ChangeDetectorRef) {} + constructor(private sensorService: SensorService, private toast: ToastrService) {} ngOnInit(): void { this.resizeListener = this.onResize.bind(this); window.addEventListener('resize', this.resizeListener); - this.updateCharts(); } + ngOnChanges(changes: SimpleChanges): void { if (changes['interval'] && changes['interval'].previousValue !== changes['interval'].currentValue) { @@ -92,6 +102,18 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang this.onResize(); } + dateChange(): void { + if(!this.startDate || !this.endDate){ + this.toast.warning('Select both start and end dates'); + return; + } else { + clearTimeout(this.updateTimeout); + this.updateTimeout = setTimeout(() => { + this.updateCharts(); + }, 500); + } + } + ngOnDestroy(): void { window.removeEventListener('resize', this.resizeListener); } @@ -105,13 +127,21 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang this.updateCharts(); } + formatDate(date: Date): string { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + } + getDate(): string { const today = new Date(); const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); const day = String(today.getDate()).padStart(2, '0'); - return `${year}-${month}-${day}`; + const hasil = `${year}-${month}-${day}`; + return hasil; } getDateAgo():string{ @@ -125,13 +155,13 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang return `${year}-${month}-${day}`; } - fetchDHTData(timeRange: string): void { - const hEnd = this.getDate(); - const hStart = this.getDate(); - const dEnd = this.getDate(); - const dStart = this.getDateAgo(); + fetchDHTData(timeRange: string, startDate?: Date, endDate?: Date): void { + const hStart = startDate ? this.formatDate(startDate) : this.getDate(); + const hEnd = endDate ? this.formatDate(endDate) : this.getDate(); + const dStart= startDate ? this.formatDate(startDate) : this.getDateAgo(); + const dEnd = endDate ? this.formatDate(endDate) : this.getDate(); - if(timeRange === 'HOURLY'){ + if (timeRange === 'HOURLY') { this.sensorService.getSensorDataHourly('dht', 'npk', hStart, hEnd, timeRange).subscribe({ next: (response) => { this.isLoadingDHT = false; @@ -147,7 +177,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang this.isNoDataDHT = true; } }); - } else if(timeRange === 'DAILY'){ + } else if (timeRange === 'DAILY') { this.sensorService.getSensorDataDaily('dht', 'npk', dStart, dEnd, timeRange).subscribe({ next: (response) => { this.isLoadingDHT = false; @@ -166,14 +196,14 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang } } - fetchNPK1Data(timeRange: string): void { - const hEnd = this.getDate(); - const hStart = this.getDate(); - const dEnd = this.getDate(); - const dStart = this.getDateAgo(); + fetchNPK1Data(timeRange: string, startDate?: Date, endDate?: Date): void { + const hStart = startDate ? this.formatDate(startDate) : this.getDate(); + const hEnd = endDate ? this.formatDate(endDate) : this.getDate(); + const dStart = startDate ? this.formatDate(startDate) : this.getDateAgo(); + const dEnd= endDate ? this.formatDate(endDate) : this.getDate(); if(timeRange === 'HOURLY'){ - this.sensorService.getSensorDataHourly('npk1', this.selectedNPK1, hEnd, hStart, timeRange).subscribe({ + this.sensorService.getSensorDataHourly('npk1', this.selectedNPK1, hStart, hEnd, timeRange).subscribe({ next: (response) => { this.isLoadingNPK1 = false; if (response.statusCode === 200 && response.data.npk1?.length > 0) { @@ -187,7 +217,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang this.isLoadingNPK1 = false; this.isNoDataNPK1 = true; } - }) + }); }else if(timeRange === 'DAILY'){ this.sensorService.getSensorDataDaily('npk1', this.selectedNPK1, dStart, dEnd, timeRange).subscribe({ next: (response) => { @@ -207,17 +237,18 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang } } - fetchNPK2Data(savedTimeRange: string): void { - const hEnd = this.getDate(); - const hStart = this.getDate(); - const dEnd = this.getDate(); - const dStart = this.getDateAgo(); + fetchNPK2Data(savedTimeRange: string, startDate?: Date, endDate?: Date): void { + const hStart = startDate ? this.formatDate(startDate) : this.getDate(); + const hEnd = endDate ? this.formatDate(endDate) : this.getDate(); + const dStart = startDate ? this.formatDate(startDate) : this.getDateAgo(); + const dEnd = endDate ? this.formatDate(endDate) : this.getDate(); if(savedTimeRange === 'HOURLY'){ this.sensorService.getSensorDataHourly('npk2', this.selectedNPK2, hStart, hEnd, savedTimeRange).subscribe({ next: (response) => { this.isLoadingNPK2 = false; if (response.statusCode === 200 && response.data.npk2?.length > 0) { + console.log('NPK2 Data:', response); this.createChart(this.npk2ChartElement.nativeElement, response, 'npk2', this.selectedNPK2); this.isNoDataNPK2 = false; } else { @@ -254,13 +285,20 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang Object.keys(this.charts).forEach(key => { if (this.charts[key]) { this.charts[key]?.destroy(); + this.charts[key].data.labels = []; + this.charts[key].data.datasets = []; this.charts[key] = undefined; } }); - - this.fetchDHTData(interval); - this.fetchNPK1Data(interval); - this.fetchNPK2Data(interval); + if (this.startDate && this.endDate) { + this.fetchDHTData(interval, this.startDate, this.endDate); + this.fetchNPK1Data(interval, this.startDate, this.endDate); + this.fetchNPK2Data(interval, this.startDate, this.endDate); + } else { + this.fetchDHTData(interval); + this.fetchNPK1Data(interval); + this.fetchNPK2Data(interval); + } } @@ -369,7 +407,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang mode: 'nearest', intersect: false, callbacks: { - label: (tooltipItem) => { + label: (tooltipItem: any) => { const paramLabel = tooltipItem.dataset.label; const value = tooltipItem.formattedValue; return `${paramLabel}: ${value}`; @@ -383,7 +421,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang grid: { display: false }, beginAtZero: true, ticks: { - callback: (value, index, values) => { + callback: (value: string | number, index: number, values: any) => { const labels = this.getLabels(response, sensor); return labels[index] || value; } @@ -406,7 +444,8 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang sensorData.forEach(item => { data.push(item[parameter as keyof ParameterSensor] ?? 0); if(this.interval === 'HOURLY') { - labels.push(`${item.hour}.00`); + labels.push(item.date); + labels.push(item.hour); } else if (this.interval === 'DAILY') { labels.push(item.day); @@ -423,11 +462,14 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang const sensorData = response.data[sensor as keyof typeof response.data]; return sensorData.map(item => { + const formatDate = format(new Date(item.date), 'MMM dd'); + if (this.interval === 'HOURLY' || this.selectedInterval === 'HOURLY') { - return `${item.hour}.00`; + return `${formatDate}, ${item.hour}.00`; } else if (this.interval === 'DAILY') { - const day = item.day; - return this.convertDateToDay(day); + const day = item.date; + const convertDateToDay = this.convertDateToDay(day); + return `${convertDateToDay}, ${formatDate}`; } else { return ''; } @@ -436,7 +478,7 @@ export class GraphComponent implements OnInit, AfterViewInit, OnDestroy, OnChang convertDateToDay(dateString: string): string { const date = new Date(dateString); - const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thrusday', 'Friday', 'Saturday']; + const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat']; return days[date.getDay()]; } diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.html b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.html index d6cec24..39226a9 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.html +++ b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.html @@ -3,10 +3,6 @@

    {{ greeting }}

    View your historical data with customizable time ranges

    -
    -

    Latest Update: {{ latestUpdate }}

    -
    -
    diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.scss b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.scss index ca447bb..40ba899 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.scss +++ b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.scss @@ -11,13 +11,7 @@ .description { color: #49473C; font-size: 15px; - margin-top: 10px; -} - -.update{ - color: #49473C; - font-size: 15px; - margin-top: 18px; + margin: 10px 0px 15px 0px; } .card-container { diff --git a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.ts b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.ts index 0f2846b..14343b5 100644 --- a/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.ts +++ b/agrilink_vocpro/src/app/pages/dashboard/page/historygraph/historygraph.component.ts @@ -13,7 +13,6 @@ import { ChangeDetectorRef } from '@angular/core'; export class HistorygraphComponent implements OnInit, OnDestroy { selectedButton: string = ''; selectedInterval: string = ''; - latestUpdate: string = ''; intervalId: any; greeting: string = ''; @@ -22,7 +21,6 @@ export class HistorygraphComponent implements OnInit, OnDestroy { @ViewChild(GraphComponent) graphComponent!: GraphComponent; ngOnInit(): void { - this.startClock(); this.updateGreeting(); this.selectedButton = 'hourly'; this.selectedInterval = 'HOURLY'; @@ -49,23 +47,6 @@ export class HistorygraphComponent implements OnInit, OnDestroy { } } - startClock(): void { - this.updateLatestTime(); - this.intervalId = setInterval(() => this.updateLatestTime(), 1000); - } - - updateLatestTime(): void { - const now = new Date(); - this.latestUpdate = now.toLocaleString('en-GB', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }); - } - updateGreeting(): void { const hour = new Date().getHours(); if (hour < 12) { diff --git a/agrilink_vocpro/src/index.html b/agrilink_vocpro/src/index.html index 07b7a5c..b8fcee3 100644 --- a/agrilink_vocpro/src/index.html +++ b/agrilink_vocpro/src/index.html @@ -18,6 +18,7 @@ + diff --git a/agrilink_vocpro/src/styles.scss b/agrilink_vocpro/src/styles.scss index 90e18ea..0b134c7 100644 --- a/agrilink_vocpro/src/styles.scss +++ b/agrilink_vocpro/src/styles.scss @@ -1,3 +1,30 @@ +@import '@angular/material/prebuilt-themes/indigo-pink.css'; body{ font-family: "Onest", sans-serif; + +} +.mat-form-field .mat-input-element:focus { + border-color: #16423C !important; + box-shadow: 0 1px 5px rgba(0, 128, 0, 0.3) !important; +} + +.mat-form-field .mat-label.mat-focus-indicator { + color: #16423C !important; +} + +.mat-form-field .mat-input-element:focus { + caret-color: #16423C !important; +} + +.mat-form-field .mat-icon { + color: #16423C !important; +} + + +.mat-datepicker-toggle.mat-accent { + color: #16423C !important; +} + +.mat-calendar .mat-calendar-body-selected { +background-color: #16423C !important; }