From 536b590080b589a807765b69612990d41ae97773 Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Fri, 11 Nov 2022 00:19:51 +0100
Subject: [PATCH 01/13] feat: dynamic line stroke settings
---
.../pkg/database/scrutiny_repository_migrations.go | 6 ++++++
webapp/backend/pkg/models/settings.go | 1 +
webapp/frontend/src/app/core/config/app.config.ts | 6 ++++++
.../dashboard-settings.component.html | 11 +++++++++++
.../dashboard-settings.component.ts | 4 ++++
.../src/app/modules/dashboard/dashboard.component.ts | 2 +-
6 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/webapp/backend/pkg/database/scrutiny_repository_migrations.go b/webapp/backend/pkg/database/scrutiny_repository_migrations.go
index 015428c..1c821be 100644
--- a/webapp/backend/pkg/database/scrutiny_repository_migrations.go
+++ b/webapp/backend/pkg/database/scrutiny_repository_migrations.go
@@ -325,6 +325,12 @@ func (sr *scrutinyRepository) Migrate(ctx context.Context) error {
SettingDataType: "bool",
SettingValueBool: false,
},
+ {
+ SettingKeyName: "line_stroke",
+ SettingKeyDescription: "Temperature chart line stroke ('smooth' | 'straight' | 'stepline')",
+ SettingDataType: "string",
+ SettingValueString: "smooth",
+ },
{
SettingKeyName: "metrics.notify_level",
diff --git a/webapp/backend/pkg/models/settings.go b/webapp/backend/pkg/models/settings.go
index f06db84..f5564ef 100644
--- a/webapp/backend/pkg/models/settings.go
+++ b/webapp/backend/pkg/models/settings.go
@@ -14,6 +14,7 @@ type Settings struct {
DashboardSort string `json:"dashboard_sort" mapstructure:"dashboard_sort"`
TemperatureUnit string `json:"temperature_unit" mapstructure:"temperature_unit"`
FileSizeSIUnits bool `json:"file_size_si_units" mapstructure:"file_size_si_units"`
+ LineStroke string `json:"line_stroke" mapstructure:"line_stroke"`
Metrics struct {
NotifyLevel int `json:"notify_level" mapstructure:"notify_level"`
diff --git a/webapp/frontend/src/app/core/config/app.config.ts b/webapp/frontend/src/app/core/config/app.config.ts
index 92f0451..c48d25a 100644
--- a/webapp/frontend/src/app/core/config/app.config.ts
+++ b/webapp/frontend/src/app/core/config/app.config.ts
@@ -10,6 +10,8 @@ export type DashboardSort = 'status' | 'title' | 'age'
export type TemperatureUnit = 'celsius' | 'fahrenheit'
+export type LineStroke = 'smooth' | 'straight' | 'stepline'
+
export enum MetricsNotifyLevel {
Warn = 1,
@@ -45,6 +47,8 @@ export interface AppConfig {
file_size_si_units?: boolean;
+ line_stroke?: LineStroke;
+
// Settings from Scrutiny API
metrics?: {
@@ -73,6 +77,8 @@ export const appConfig: AppConfig = {
temperature_unit: 'celsius',
file_size_si_units: false,
+ line_stroke: 'smooth',
+
metrics: {
notify_level: MetricsNotifyLevel.Fail,
status_filter_attributes: MetricsStatusFilterAttributes.All,
diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html
index 750d54d..69ebd76 100644
--- a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html
+++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html
@@ -53,6 +53,17 @@
+
+
+ Line stroke
+
+ Smooth
+ Straight
+ Stepline
+
+
+
+
Device Status - Thresholds
diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
index 6bc5f2a..0eef581 100644
--- a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
+++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
@@ -6,6 +6,7 @@ import {
MetricsStatusFilterAttributes,
MetricsStatusThreshold,
TemperatureUnit,
+ LineStroke,
Theme
} from 'app/core/config/app.config';
import {ScrutinyConfigService} from 'app/core/config/scrutiny-config.service';
@@ -23,6 +24,7 @@ export class DashboardSettingsComponent implements OnInit {
dashboardSort: string;
temperatureUnit: string;
fileSizeSIUnits: boolean;
+ lineStroke: string;
theme: string;
statusThreshold: number;
statusFilterAttributes: number;
@@ -48,6 +50,7 @@ export class DashboardSettingsComponent implements OnInit {
this.dashboardSort = config.dashboard_sort;
this.temperatureUnit = config.temperature_unit;
this.fileSizeSIUnits = config.file_size_si_units;
+ this.lineStroke = config.line_stroke;
this.theme = config.theme;
this.statusFilterAttributes = config.metrics.status_filter_attributes;
@@ -63,6 +66,7 @@ export class DashboardSettingsComponent implements OnInit {
dashboard_sort: this.dashboardSort as DashboardSort,
temperature_unit: this.temperatureUnit as TemperatureUnit,
file_size_si_units: this.fileSizeSIUnits,
+ line_stroke: this.lineStroke as LineStroke,
theme: this.theme as Theme,
metrics: {
status_filter_attributes: this.statusFilterAttributes as MetricsStatusFilterAttributes,
diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
index 70b40f6..e49e050 100644
--- a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
+++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
@@ -201,7 +201,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
},
series : this._deviceDataTemperatureSeries(),
stroke : {
- curve: 'straight',
+ curve: this.config.line_stroke,
width: 2
},
tooltip: {
From e18a7e9ce08e9172853f7bd5f6a6388e278ee4e2 Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:23:37 +0100
Subject: [PATCH 02/13] refactor: update dependencies version
---
webapp/frontend/package.json | 107 ++++++++++++++++-------------------
1 file changed, 48 insertions(+), 59 deletions(-)
diff --git a/webapp/frontend/package.json b/webapp/frontend/package.json
index e5e138a..7029231 100644
--- a/webapp/frontend/package.json
+++ b/webapp/frontend/package.json
@@ -20,66 +20,55 @@
},
"private": true,
"dependencies": {
- "@angular/animations": "9.1.4",
- "@angular/cdk": "9.2.2",
- "@angular/common": "9.1.4",
- "@angular/compiler": "9.1.4",
- "@angular/core": "9.1.4",
- "@angular/forms": "9.1.4",
- "@angular/material": "9.2.2",
- "@angular/material-moment-adapter": "9.2.2",
- "@angular/platform-browser": "9.1.4",
- "@angular/platform-browser-dynamic": "9.1.4",
- "@angular/router": "9.1.4",
- "@fullcalendar/angular": "4.4.5-beta",
- "@fullcalendar/core": "4.4.0",
- "@fullcalendar/daygrid": "4.4.0",
- "@fullcalendar/interaction": "4.4.0",
- "@fullcalendar/list": "4.4.0",
- "@fullcalendar/moment": "4.4.0",
- "@fullcalendar/rrule": "4.4.0",
- "@fullcalendar/timegrid": "4.4.0",
- "@types/humanize-duration": "^3.18.1",
- "apexcharts": "3.19.2",
- "crypto-js": "3.3.0",
- "highlight.js": "10.0.1",
- "humanize-duration": "^3.24.0",
- "lodash": "4.17.15",
- "moment": "2.24.0",
- "ng-apexcharts": "1.5.12",
- "ngx-markdown": "9.0.0",
- "ngx-quill": "9.1.0",
- "perfect-scrollbar": "1.5.0",
- "quill": "1.3.7",
- "rrule": "2.6.4",
- "rxjs": "6.5.5",
- "tslib": "1.11.1",
- "web-animations-js": "2.3.2",
- "zone.js": "0.10.3"
+ "@angular/animations": "v13-lts",
+ "@angular/cdk": "v13-lts",
+ "@angular/common": "v13-lts",
+ "@angular/compiler": "v13-lts",
+ "@angular/core": "v13-lts",
+ "@angular/forms": "v13-lts",
+ "@angular/material": "v13-lts",
+ "@angular/material-moment-adapter": "v13-lts",
+ "@angular/platform-browser": "v13-lts",
+ "@angular/platform-browser-dynamic": "v13-lts",
+ "@angular/router": "v13-lts",
+ "@types/humanize-duration": "^3.27.1",
+ "crypto-js": "^4.1.1",
+ "highlight.js": "^11.6.0",
+ "humanize-duration": "^3.27.3",
+ "lodash": "4.17.21",
+ "moment": "^2.29.4",
+ "ng-apexcharts": "^1.7.4",
+ "perfect-scrollbar": "^1.5.5",
+ "quill": "^1.3.7",
+ "rrule": "^2.7.1",
+ "rxjs": "^7.5.7",
+ "tslib": "^2.4.1",
+ "web-animations-js": "^2.3.2",
+ "ngx-markdown": "^13.1.0"
},
"devDependencies": {
- "@angular-devkit/build-angular": "0.901.4",
- "@angular/cli": "9.1.4",
- "@angular/compiler-cli": "9.1.4",
- "@angular/language-service": "9.1.4",
- "@types/crypto-js": "3.1.45",
- "@types/highlight.js": "9.12.3",
- "@types/jasmine": "3.5.10",
- "@types/jasminewd2": "2.0.8",
- "@types/lodash": "4.14.150",
- "@types/node": "12.12.37",
- "codelyzer": "5.2.2",
- "jasmine-core": "3.5.0",
- "jasmine-spec-reporter": "4.2.1",
- "karma": "5.0.4",
- "karma-chrome-launcher": "3.1.0",
- "karma-coverage-istanbul-reporter": "2.1.1",
- "karma-jasmine": "3.0.3",
- "karma-jasmine-html-reporter": "1.5.3",
- "protractor": "5.4.4",
- "tailwindcss": "1.4.4",
- "ts-node": "8.3.0",
- "tslint": "6.1.2",
- "typescript": "3.8.3"
+ "@angular-devkit/build-angular": "v13-lts",
+ "@angular/cli": "v13-lts",
+ "@angular/compiler-cli": "v13-lts",
+ "@angular/language-service": "v13-lts",
+ "@types/crypto-js": "^4.1.1",
+ "@types/highlight.js": "^10.1.0",
+ "@types/jasmine": "^4.3.0",
+ "@types/jasminewd2": "^2.0.10",
+ "@types/lodash": "^4.14.188",
+ "@types/node": "^18.11.9",
+ "codelyzer": "^6.0.2",
+ "jasmine-core": "^4.5.0",
+ "jasmine-spec-reporter": "^7.0.0",
+ "karma": "^6.4.1",
+ "karma-chrome-launcher": "^3.1.1",
+ "karma-coverage-istanbul-reporter": "^3.0.3",
+ "karma-jasmine": "^5.1.0",
+ "karma-jasmine-html-reporter": "^2.0.0",
+ "protractor": "^7.0.0",
+ "tailwindcss": "^3.2.3",
+ "ts-node": "^10.9.1",
+ "tslint": "^6.1.3",
+ "typescript": "^4.6.4"
}
}
From 50321d897a21faa515b142f4b2e285ba16815acd Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:24:02 +0100
Subject: [PATCH 03/13] fix: prod build command
---
webapp/frontend/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/webapp/frontend/package.json b/webapp/frontend/package.json
index 7029231..759f620 100644
--- a/webapp/frontend/package.json
+++ b/webapp/frontend/package.json
@@ -7,7 +7,7 @@
"start": "ng serve --open",
"start:mem": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng serve --open",
"build": "ng build",
- "build:prod": "ng build --prod",
+ "build:prod": "ng build --configuration production",
"build:prod:mem": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
"test": "ng test",
"lint": "ng lint",
From 5518865bc69f0a9906977facfa4be8895a7b12d9 Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:24:38 +0100
Subject: [PATCH 04/13] fix: remove outdated option
---
webapp/frontend/angular.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/webapp/frontend/angular.json b/webapp/frontend/angular.json
index 6ea760f..0acbcca 100644
--- a/webapp/frontend/angular.json
+++ b/webapp/frontend/angular.json
@@ -52,7 +52,6 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
- "extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
From 64ad3536284f67cb4652a9e83a02f0024b7dcde9 Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:26:03 +0100
Subject: [PATCH 05/13] fix: remove fullcalendar
---
webapp/frontend/src/@treo/styles/main.scss | 1 -
.../@treo/styles/overrides/_fullcalendar.scss | 878 ------------------
webapp/frontend/src/styles/vendors.scss | 6 -
3 files changed, 885 deletions(-)
delete mode 100644 webapp/frontend/src/@treo/styles/overrides/_fullcalendar.scss
diff --git a/webapp/frontend/src/@treo/styles/main.scss b/webapp/frontend/src/@treo/styles/main.scss
index b4bf61f..2ebdca4 100644
--- a/webapp/frontend/src/@treo/styles/main.scss
+++ b/webapp/frontend/src/@treo/styles/main.scss
@@ -26,7 +26,6 @@
// 6. Overrides
@import 'overrides/angular-material';
-@import 'overrides/fullcalendar';
@import 'overrides/highlightjs';
@import 'overrides/perfect-scrollbar';
@import 'overrides/quill';
diff --git a/webapp/frontend/src/@treo/styles/overrides/_fullcalendar.scss b/webapp/frontend/src/@treo/styles/overrides/_fullcalendar.scss
deleted file mode 100644
index dba4217..0000000
--- a/webapp/frontend/src/@treo/styles/overrides/_fullcalendar.scss
+++ /dev/null
@@ -1,878 +0,0 @@
-// -----------------------------------------------------------------------------------------------------
-// @ FullCalendar overrides
-// -----------------------------------------------------------------------------------------------------
-
-.fc {
-
- .fc-view-container {
-
- // Day Grid - Month view
- .fc-view.fc-dayGridMonth-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
- border: none;
-
- .fc-row {
-
- .fc-day-header {
-
- span {
- display: flex;
- align-items: center;
- justify-content: center;
- padding-top: 8px;
- font-size: 12px;
- font-weight: 500;
- text-transform: uppercase;
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
- border: none;
-
- .fc-day-grid {
-
- .fc-week {
-
- .fc-content-skeleton {
-
- .fc-day-top {
- text-align: center;
-
- &.fc-other-month {
- opacity: 1;
- }
-
- .fc-day-number {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 22px;
- height: 21px;
- margin: 4px 0;
- font-size: 12px;
- border-radius: 50%;
- float: none;
- }
- }
-
- .fc-event-container {
-
- .fc-day-grid-event {
- display: flex;
- align-items: center;
- height: 22px;
- min-height: 22px;
- max-height: 22px;
- margin: 0 6px 4px 6px;
- padding: 0 8px;
- font-size: 12px;
- border-radius: 4px;
- border: none;
- cursor: pointer;
-
- @include treo-breakpoint('xs') {
- padding: 0 5px;
- }
- }
- }
-
- .fc-more {
- padding: 0 6px;
- font-size: 12px;
- font-weight: 500;
- white-space: nowrap;
-
- @include treo-breakpoint('xs') {
- padding: 0 3px;
- }
- }
- }
-
- .fc-highlight-skeleton {
-
- .fc-highlight {
- position: relative;
- }
- }
- }
- }
- }
- }
-
- .fc-popover {
-
- &.fc-more-popover {
- border: none;
- border-radius: 4px;
- @include treo-elevation('2xl');
-
- .fc-header {
- height: 32px;
- min-height: 32px;
- max-height: 32px;
- padding: 0 8px;
-
- .fc-title {
- margin: 0;
- padding: 0;
- font-size: 12px;
- }
- }
-
- .fc-body {
- max-height: 160px;
- overflow: hidden auto;
-
- .fc-event-container {
- padding: 8px;
-
- .fc-day-grid-event {
- display: flex;
- align-items: center;
- height: 22px;
- min-height: 22px;
- max-height: 22px;
- margin: 0 0 6px 0;
- padding: 0 8px;
- font-size: 12px;
- line-height: 1;
- border-radius: 4px;
- border: none;
- cursor: pointer;
-
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- }
- }
- }
- }
-
- // Time Grid - Week view
- .fc-view.fc-timeGridWeek-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
- border: none;
-
- .fc-row {
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-day-header {
-
- span {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 100%;
-
- &.fc-weekday {
- padding-top: 16px;
- font-size: 12px;
- letter-spacing: 0.055em;
- text-transform: uppercase;
- font-weight: 400;
- }
-
- &.fc-date {
- padding-bottom: 12px;
- font-size: 26px;
- font-weight: 300;
- }
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
- border: none;
-
- .fc-day-grid {
-
- .fc-row {
- min-height: 0;
-
- .fc-bg {
-
- .fc-axis {
- width: 48px !important;
- }
- }
-
- .fc-content-skeleton {
- padding-bottom: 0;
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-event-container {
-
- .fc-day-grid-event {
- display: flex;
- align-items: center;
- height: 22px;
- min-height: 22px;
- max-height: 22px;
- margin: 0 6px 6px 6px;
- padding: 0 8px;
- font-size: 12px;
- line-height: 1;
- border-radius: 4px;
- border: none;
- cursor: pointer;
- }
- }
- }
- }
- }
-
- .fc-divider {
- border: none;
- }
-
- .fc-time-grid {
-
- .fc-bg {
-
- .fc-axis {
- border: none;
- width: 48px !important;
-
- + .fc-day {
- border: none;
- }
- }
- }
-
- .fc-slats {
-
- .fc-axis {
- width: 48px !important;
- height: 48px;
- text-align: center;
-
- span {
- font-size: 12px;
- width: 48px;
- min-width: 48px;
- }
- }
- }
-
- .fc-content-skeleton {
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-event-container {
- margin: 0 12px 0 0;
-
- .fc-time-grid-event {
- display: flex;
- padding: 8px;
- border-radius: 4px;
- border: none;
- cursor: pointer;
-
- .fc-time,
- .fc-title {
- font-size: 12px;
- }
- }
- }
- }
- }
- }
- }
- }
-
- // Time Grid - Day view
- .fc-view.fc-timeGridDay-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
- border: none;
-
- .fc-row {
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-day-header {
-
- span {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 100%;
-
- &.fc-weekday {
- padding-top: 16px;
- font-size: 12px;
- letter-spacing: 0.055em;
- text-transform: uppercase;
- font-weight: 400;
- }
-
- &.fc-date {
- padding-bottom: 12px;
- font-size: 26px;
- font-weight: 300;
- }
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
- border: none;
-
- .fc-day-grid {
-
- .fc-row {
- min-height: 0;
-
- .fc-bg {
-
- .fc-axis {
- width: 48px !important;
- }
- }
-
- .fc-content-skeleton {
- padding-bottom: 0;
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-event-container {
-
- .fc-day-grid-event {
- display: flex;
- align-items: center;
- height: 22px;
- min-height: 22px;
- max-height: 22px;
- margin: 0 6px 6px 6px;
- padding: 0 8px;
- font-size: 12px;
- line-height: 1;
- border-radius: 4px;
- border: none;
- cursor: pointer;
- }
- }
- }
- }
- }
-
- .fc-divider {
- border: none;
- }
-
- .fc-time-grid {
-
- .fc-bg {
-
- .fc-axis {
- border: none;
- width: 48px !important;
-
- + .fc-day {
- border: none;
- }
- }
- }
-
- .fc-slats {
-
- .fc-axis {
- width: 48px !important;
- height: 48px;
- text-align: center;
-
- span {
- font-size: 12px;
- width: 48px;
- min-width: 48px;
- }
- }
- }
-
- .fc-content-skeleton {
-
- .fc-axis {
- width: 48px !important;
- }
-
- .fc-event-container {
- margin: 0 12px 0 0;
-
- .fc-time-grid-event {
- display: flex;
- padding: 8px;
- border-radius: 4px;
- border: none;
- cursor: pointer;
-
- .fc-time,
- .fc-title {
- font-size: 12px;
- }
- }
- }
- }
- }
- }
- }
- }
-
- // List - Year view
- .fc-view.fc-listYear-view {
- border: none;
-
- .fc-list-table {
-
- .fc-list-heading {
- display: none;
- }
-
- .fc-list-item {
- display: flex;
- cursor: pointer;
-
- td {
- display: flex;
- align-items: center;
- width: auto;
- height: 48px;
- min-height: 48px;
- padding: 0 8px;
- border-width: 0 0 1px 0;
-
- &.fc-list-item-date {
- order: 1;
- padding-left: 16px;
- width: 120px;
- min-width: 120px;
- max-width: 120px;
-
- @include treo-breakpoint('xs') {
- width: 100px;
- min-width: 100px;
- max-width: 100px;
- }
-
- > span {
- display: flex;
- align-items: baseline;
-
- span {
-
- &:first-child {
- display: flex;
- justify-content: center;
- padding-right: 8px;
- width: 32px;
- min-width: 32px;
- max-width: 32px;
- font-size: 18px;
-
- @include treo-breakpoint('xs') {
- padding-right: 2px;
- }
-
- + span {
- display: flex;
- font-size: 11px;
- font-weight: 500;
- letter-spacing: 0.055em;
- text-transform: uppercase;
- }
- }
- }
- }
- }
-
- &.fc-list-item-time {
- flex: 0 0 auto;
- order: 3;
- width: 160px;
- min-width: 160px;
- max-width: 160px;
-
- @include treo-breakpoint('xs') {
- width: 120px;
- min-width: 120px;
- max-width: 120px;
- }
- }
-
- &.fc-list-item-marker {
- flex: 0 0 auto;
- order: 2;
-
- .fc-event-dot {
- width: 12px;
- height: 12px;
- border-radius: 50%;
- }
- }
-
- &.fc-list-item-title {
- flex: 1 1 auto;
- order: 4;
- padding-right: 24px;
- font-weight: 500;
- }
- }
- }
- }
- }
- }
-
- // Day grid event - Dragging
- .fc-day-grid-event {
-
- &.fc-dragging,
- &.fc-resizing {
- display: flex;
- align-items: center;
- height: 22px;
- min-height: 22px;
- max-height: 22px;
- margin: 0 6px 4px 6px;
- padding: 0 8px;
- font-size: 12px;
- line-height: 1;
- border-radius: 4px;
- border: none;
- }
- }
-}
-
-// -----------------------------------------------------------------------------------------------------
-// @ Theming
-// -----------------------------------------------------------------------------------------------------
-@include treo-theme {
-
- $background: map-get($theme, background);
- $foreground: map-get($theme, foreground);
- $primary: map-get($theme, primary);
-
- .fc {
-
- .fc-view-container {
-
- // Day Grid - Month view
- .fc-view.fc-dayGridMonth-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
-
- .fc-row {
-
- .fc-day-header {
- border-color: map-get($foreground, divider);
-
- span {
- color: map-get($foreground, secondary-text);
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
-
- .fc-day-grid {
-
- .fc-week {
-
- .fc-bg {
-
- .fc-day {
- border-color: map-get($foreground, divider);
-
- &.fc-today {
- background: none;
- }
- }
- }
-
- .fc-content-skeleton {
-
- .fc-day-top {
-
- &.fc-other-month {
-
- .fc-day-number {
- color: map-get($foreground, hint-text);
- }
- }
-
- &.fc-today {
-
- .fc-day-number {
- background: map-get($primary, default);
- color: map-get($primary, default-contrast);
- }
- }
- }
-
- .fc-more {
- color: map-get($foreground, secondary-text);
- }
- }
-
- .fc-highlight-skeleton {
-
- .fc-highlight {
- background: treo-color('cool-gray', 100);
- opacity: 1;
- }
- }
- }
- }
- }
- }
-
- .fc-popover {
- background: map-get($background, card);
-
- &.fc-more-popover {
-
- .fc-header {
- background: map-get($background, hover);
- }
- }
- }
- }
-
- // Time Grid - Week view
- .fc-view.fc-timeGridWeek-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
-
- .fc-row {
-
- .fc-axis {
- border-color: map-get($foreground, divider);
- }
-
- .fc-day-header {
- border-color: map-get($foreground, divider);
-
- span {
- color: map-get($foreground, secondary-text);
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
- border: none;
-
- .fc-day-grid {
-
- .fc-bg {
-
- .fc-axis {
- border-color: map-get($foreground, divider);
- }
-
- .fc-day {
- border-color: map-get($foreground, divider);
-
- &.fc-today {
- background: none;
- }
- }
- }
- }
-
- .fc-divider {
- background: map-get($foreground, divider);
- }
-
- .fc-time-grid {
-
- .fc-bg {
-
- .fc-day {
- border-color: map-get($foreground, divider);
-
- &.fc-today {
- background: none;
- }
- }
- }
-
- .fc-slats {
-
- .fc-time {
- border-color: map-get($foreground, divider);
- }
-
- .fc-widget-content {
- border-color: map-get($foreground, divider);
- }
- }
- }
- }
- }
- }
-
- // Time Grid - Day view
- .fc-view.fc-timeGridDay-view {
-
- .fc-head {
-
- > tr > .fc-head-container {
-
- .fc-row {
-
- .fc-axis {
- border-color: map-get($foreground, divider);
- }
-
- .fc-day-header {
- border-color: map-get($foreground, divider);
-
- span {
- color: map-get($foreground, secondary-text);
- }
- }
- }
- }
- }
-
- .fc-body {
-
- > tr > .fc-widget-content {
- border: none;
-
- .fc-day-grid {
-
- .fc-bg {
-
- .fc-axis {
- border-color: map-get($foreground, divider);
- }
-
- .fc-day {
- border-color: map-get($foreground, divider);
-
- &.fc-today {
- background: none;
- }
- }
- }
- }
-
- .fc-divider {
- background: map-get($foreground, divider);
- }
-
- .fc-time-grid {
-
- .fc-bg {
-
- .fc-day {
- border-color: map-get($foreground, divider);
-
- &.fc-today {
- background: none;
- }
- }
- }
-
- .fc-slats {
-
- .fc-time {
- border-color: map-get($foreground, divider);
- }
-
- .fc-widget-content {
- border-color: map-get($foreground, divider);
- }
- }
- }
- }
- }
- }
-
- // List - Year view
- .fc-view.fc-listYear-view {
-
- .fc-list-table {
-
- .fc-list-item {
-
- &:hover {
-
- td {
- background-color: map-get($background, hover);
- }
- }
-
- td {
- border-color: map-get($foreground, divider);
-
- &.fc-list-item-date {
-
- > span {
-
- span {
-
- &:first-child {
-
- + span {
- color: map-get($foreground, secondary-text);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/webapp/frontend/src/styles/vendors.scss b/webapp/frontend/src/styles/vendors.scss
index d148122..f38dc52 100644
--- a/webapp/frontend/src/styles/vendors.scss
+++ b/webapp/frontend/src/styles/vendors.scss
@@ -7,12 +7,6 @@
// that Treo doesn't support out-of-the-box visually compatible with your application.
// -----------------------------------------------------------------------------------------------------
-// FullCalendar
-@import '~@fullcalendar/core/main.css';
-@import '~@fullcalendar/daygrid/main.css';
-@import '~@fullcalendar/timegrid/main.css';
-@import '~@fullcalendar/list/main.css';
-
// Perfect scrollbar
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
From e9cf8a9180e5d181f62076bb602888e34596885b Mon Sep 17 00:00:00 2001
From: adripo <26493496+adripo@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:27:07 +0100
Subject: [PATCH 06/13] fix: igeneric types
---
.../@treo/components/date-range/date-range.component.ts | 2 +-
.../src/@treo/components/message/message.component.ts | 2 +-
.../horizontal/components/basic/basic.component.ts | 2 +-
.../horizontal/components/branch/branch.component.ts | 2 +-
.../horizontal/components/divider/divider.component.ts | 2 +-
.../horizontal/components/spacer/spacer.component.ts | 2 +-
.../navigation/horizontal/horizontal.component.ts | 2 +-
.../vertical/components/aside/aside.component.ts | 2 +-
.../vertical/components/basic/basic.component.ts | 2 +-
.../components/collapsable/collapsable.component.ts | 2 +-
.../vertical/components/divider/divider.component.ts | 2 +-
.../vertical/components/group/group.component.ts | 2 +-
.../vertical/components/spacer/spacer.component.ts | 2 +-
.../components/navigation/vertical/vertical.component.ts | 2 +-
.../src/@treo/directives/autogrow/autogrow.directive.ts | 2 +-
.../src/@treo/directives/scrollbar/scrollbar.directive.ts | 2 +-
webapp/frontend/src/@treo/lib/mock-api/mock-api.module.ts | 2 +-
.../src/app/core/config/scrutiny-config.module.ts | 2 +-
.../common/dashboard-device/dashboard-device.component.ts | 2 +-
.../dashboard-settings/dashboard-settings.component.ts | 2 +-
.../src/app/layout/common/search/search.component.ts | 2 +-
webapp/frontend/src/app/layout/layout.component.ts | 2 +-
.../src/app/layout/layouts/empty/empty.component.ts | 2 +-
.../layouts/horizontal/material/material.component.ts | 2 +-
.../src/app/modules/dashboard/dashboard.component.ts | 8 ++++----
.../frontend/src/app/modules/detail/detail.component.ts | 2 +-
26 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/webapp/frontend/src/@treo/components/date-range/date-range.component.ts b/webapp/frontend/src/@treo/components/date-range/date-range.component.ts
index 7690dbe..ac316de 100644
--- a/webapp/frontend/src/@treo/components/date-range/date-range.component.ts
+++ b/webapp/frontend/src/@treo/components/date-range/date-range.component.ts
@@ -56,7 +56,7 @@ export class TreoDateRangeComponent implements ControlValueAccessor, OnInit, OnD
private _timeFormat: string;
private _timeRange: boolean;
private readonly _timeRegExp: RegExp;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/message/message.component.ts b/webapp/frontend/src/@treo/components/message/message.component.ts
index aff4dcc..4295454 100644
--- a/webapp/frontend/src/@treo/components/message/message.component.ts
+++ b/webapp/frontend/src/@treo/components/message/message.component.ts
@@ -31,7 +31,7 @@ export class TreoMessageComponent implements OnInit, OnDestroy
private _dismissed: null | boolean;
private _showIcon: boolean;
private _type: TreoMessageType;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/horizontal/components/basic/basic.component.ts b/webapp/frontend/src/@treo/components/navigation/horizontal/components/basic/basic.component.ts
index 53eef23..1d2c2f3 100644
--- a/webapp/frontend/src/@treo/components/navigation/horizontal/components/basic/basic.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/horizontal/components/basic/basic.component.ts
@@ -23,7 +23,7 @@ export class TreoHorizontalNavigationBasicItemComponent implements OnInit, OnDes
// Private
private _treoHorizontalNavigationComponent: TreoHorizontalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/horizontal/components/branch/branch.component.ts b/webapp/frontend/src/@treo/components/navigation/horizontal/components/branch/branch.component.ts
index 7e2cb3c..4fbe40b 100644
--- a/webapp/frontend/src/@treo/components/navigation/horizontal/components/branch/branch.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/horizontal/components/branch/branch.component.ts
@@ -32,7 +32,7 @@ export class TreoHorizontalNavigationBranchItemComponent implements OnInit, OnDe
// Private
private _treoHorizontalNavigationComponent: TreoHorizontalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/horizontal/components/divider/divider.component.ts b/webapp/frontend/src/@treo/components/navigation/horizontal/components/divider/divider.component.ts
index fa8587b..fd30907 100644
--- a/webapp/frontend/src/@treo/components/navigation/horizontal/components/divider/divider.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/horizontal/components/divider/divider.component.ts
@@ -23,7 +23,7 @@ export class TreoHorizontalNavigationDividerItemComponent implements OnInit, OnD
// Private
private _treoHorizontalNavigationComponent: TreoHorizontalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/horizontal/components/spacer/spacer.component.ts b/webapp/frontend/src/@treo/components/navigation/horizontal/components/spacer/spacer.component.ts
index 7eabfe8..7ca2514 100644
--- a/webapp/frontend/src/@treo/components/navigation/horizontal/components/spacer/spacer.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/horizontal/components/spacer/spacer.component.ts
@@ -23,7 +23,7 @@ export class TreoHorizontalNavigationSpacerItemComponent implements OnInit, OnDe
// Private
private _treoHorizontalNavigationComponent: TreoHorizontalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/horizontal/horizontal.component.ts b/webapp/frontend/src/@treo/components/navigation/horizontal/horizontal.component.ts
index 22b3805..8c4d572 100644
--- a/webapp/frontend/src/@treo/components/navigation/horizontal/horizontal.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/horizontal/horizontal.component.ts
@@ -23,7 +23,7 @@ export class TreoHorizontalNavigationComponent implements OnInit, OnDestroy
// Private
private _navigation: TreoNavigationItem[];
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/aside/aside.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/aside/aside.component.ts
index 8a480b7..ec099b4 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/aside/aside.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/aside/aside.component.ts
@@ -35,7 +35,7 @@ export class TreoVerticalNavigationAsideItemComponent implements OnInit, OnDestr
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/basic/basic.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/basic/basic.component.ts
index 979ee96..f3ac538 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/basic/basic.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/basic/basic.component.ts
@@ -23,7 +23,7 @@ export class TreoVerticalNavigationBasicItemComponent implements OnInit, OnDestr
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/collapsable/collapsable.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/collapsable/collapsable.component.ts
index 8ddeada..32d9910 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/collapsable/collapsable.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/collapsable/collapsable.component.ts
@@ -38,7 +38,7 @@ export class TreoVerticalNavigationCollapsableItemComponent implements OnInit, O
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/divider/divider.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/divider/divider.component.ts
index 90d1c1f..4c1fa07 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/divider/divider.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/divider/divider.component.ts
@@ -23,7 +23,7 @@ export class TreoVerticalNavigationDividerItemComponent implements OnInit, OnDes
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/group/group.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/group/group.component.ts
index d1f4e8d..953ec18 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/group/group.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/group/group.component.ts
@@ -27,7 +27,7 @@ export class TreoVerticalNavigationGroupItemComponent implements OnInit, OnDestr
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/components/spacer/spacer.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/components/spacer/spacer.component.ts
index 287b23e..0557c4e 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/components/spacer/spacer.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/components/spacer/spacer.component.ts
@@ -23,7 +23,7 @@ export class TreoVerticalNavigationSpacerItemComponent implements OnInit, OnDest
// Private
private _treoVerticalNavigationComponent: TreoVerticalNavigationComponent;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/components/navigation/vertical/vertical.component.ts b/webapp/frontend/src/@treo/components/navigation/vertical/vertical.component.ts
index 3b31de0..7c5d82f 100644
--- a/webapp/frontend/src/@treo/components/navigation/vertical/vertical.component.ts
+++ b/webapp/frontend/src/@treo/components/navigation/vertical/vertical.component.ts
@@ -65,7 +65,7 @@ export class TreoVerticalNavigationComponent implements OnInit, AfterViewInit, O
private _position: TreoVerticalNavigationPosition;
private _scrollStrategy: ScrollStrategy;
private _transparentOverlay: boolean | '';
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
@HostBinding('class.treo-vertical-navigation-animations-enabled')
private _animationsEnabled: boolean;
diff --git a/webapp/frontend/src/@treo/directives/autogrow/autogrow.directive.ts b/webapp/frontend/src/@treo/directives/autogrow/autogrow.directive.ts
index be4a295..de5b096 100644
--- a/webapp/frontend/src/@treo/directives/autogrow/autogrow.directive.ts
+++ b/webapp/frontend/src/@treo/directives/autogrow/autogrow.directive.ts
@@ -12,7 +12,7 @@ export class TreoAutogrowDirective implements OnInit, OnDestroy
// Private
private _padding: number;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/directives/scrollbar/scrollbar.directive.ts b/webapp/frontend/src/@treo/directives/scrollbar/scrollbar.directive.ts
index e72d02e..d2efe0e 100644
--- a/webapp/frontend/src/@treo/directives/scrollbar/scrollbar.directive.ts
+++ b/webapp/frontend/src/@treo/directives/scrollbar/scrollbar.directive.ts
@@ -24,7 +24,7 @@ export class TreoScrollbarDirective implements OnInit, OnDestroy
private _animation: number | null;
private _enabled: boolean;
private _options: any;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/@treo/lib/mock-api/mock-api.module.ts b/webapp/frontend/src/@treo/lib/mock-api/mock-api.module.ts
index cf2cabb..15e7a39 100644
--- a/webapp/frontend/src/@treo/lib/mock-api/mock-api.module.ts
+++ b/webapp/frontend/src/@treo/lib/mock-api/mock-api.module.ts
@@ -20,7 +20,7 @@ export class TreoMockApiModule
*
* @param mockDataServices
*/
- static forRoot(mockDataServices: any[]): ModuleWithProviders
+ static forRoot(mockDataServices: any[]): ModuleWithProviders
{
return {
ngModule : TreoMockApiModule,
diff --git a/webapp/frontend/src/app/core/config/scrutiny-config.module.ts b/webapp/frontend/src/app/core/config/scrutiny-config.module.ts
index 3dd5bc8..3b52583 100644
--- a/webapp/frontend/src/app/core/config/scrutiny-config.module.ts
+++ b/webapp/frontend/src/app/core/config/scrutiny-config.module.ts
@@ -19,7 +19,7 @@ export class ScrutinyConfigModule {
*
* @param config
*/
- static forRoot(config: any): ModuleWithProviders {
+ static forRoot(config: any): ModuleWithProviders {
return {
ngModule: ScrutinyConfigModule,
providers: [
diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts
index e29957e..57da104 100644
--- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts
+++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts
@@ -32,7 +32,7 @@ export class DashboardDeviceComponent implements OnInit {
config: AppConfig;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
readonly humanizeDuration = humanizeDuration;
diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
index 0eef581..ea2acce 100644
--- a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
+++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts
@@ -30,7 +30,7 @@ export class DashboardSettingsComponent implements OnInit {
statusFilterAttributes: number;
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
constructor(
private _configService: ScrutinyConfigService,
diff --git a/webapp/frontend/src/app/layout/common/search/search.component.ts b/webapp/frontend/src/app/layout/common/search/search.component.ts
index 3c48651..d74f739 100644
--- a/webapp/frontend/src/app/layout/common/search/search.component.ts
+++ b/webapp/frontend/src/app/layout/common/search/search.component.ts
@@ -35,7 +35,7 @@ export class SearchComponent implements OnInit, OnDestroy
// Private
private _appearance: 'basic' | 'bar';
private _opened: boolean;
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/app/layout/layout.component.ts b/webapp/frontend/src/app/layout/layout.component.ts
index 8e567a6..2872bdd 100644
--- a/webapp/frontend/src/app/layout/layout.component.ts
+++ b/webapp/frontend/src/app/layout/layout.component.ts
@@ -21,7 +21,7 @@ export class LayoutComponent implements OnInit, OnDestroy {
theme: Theme;
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
private systemPrefersDark: boolean;
/**
diff --git a/webapp/frontend/src/app/layout/layouts/empty/empty.component.ts b/webapp/frontend/src/app/layout/layouts/empty/empty.component.ts
index efe4a94..9b6d184 100644
--- a/webapp/frontend/src/app/layout/layouts/empty/empty.component.ts
+++ b/webapp/frontend/src/app/layout/layouts/empty/empty.component.ts
@@ -10,7 +10,7 @@ import { Subject } from 'rxjs';
export class EmptyLayoutComponent implements OnInit, OnDestroy
{
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/app/layout/layouts/horizontal/material/material.component.ts b/webapp/frontend/src/app/layout/layouts/horizontal/material/material.component.ts
index 2e86c2e..5462f33 100644
--- a/webapp/frontend/src/app/layout/layouts/horizontal/material/material.component.ts
+++ b/webapp/frontend/src/app/layout/layouts/horizontal/material/material.component.ts
@@ -25,7 +25,7 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
fixedFooter: boolean;
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
/**
* Constructor
diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
index e49e050..5c7d9c8 100644
--- a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
+++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts
@@ -36,7 +36,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
config: AppConfig;
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
@ViewChild('tempChart', { static: false }) tempChart: ChartComponent;
/**
@@ -193,11 +193,11 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
enabled: true
}
},
- colors : ['#A3BFFA', '#667EEA'],
+ colors : ['#667eea', '#9066ea', '#66c0ea', '#66ead2', '#d266ea', '#66ea90'],
fill : {
- colors : ['#CED9FB', '#AECDFD'],
+ colors : ['#b2bef4', '#c7b2f4', '#b2dff4', '#b2f4e8', '#e8b2f4', '#b2f4c7'],
opacity: 0.5,
- type : 'solid'
+ type : 'gradient'
},
series : this._deviceDataTemperatureSeries(),
stroke : {
diff --git a/webapp/frontend/src/app/modules/detail/detail.component.ts b/webapp/frontend/src/app/modules/detail/detail.component.ts
index e87b75f..d613378 100644
--- a/webapp/frontend/src/app/modules/detail/detail.component.ts
+++ b/webapp/frontend/src/app/modules/detail/detail.component.ts
@@ -85,7 +85,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy {
smartAttributeTableMatSort: MatSort;
// Private
- private _unsubscribeAll: Subject;
+ private _unsubscribeAll: Subject;
private systemPrefersDark: boolean;
readonly humanizeDuration = humanizeDuration;
From 7fd2e2b050fd2f1445fd8ef4953168b69ea46dd1 Mon Sep 17 00:00:00 2001
From: Michael Manganiello
Date: Sun, 19 Feb 2023 21:18:51 -0300
Subject: [PATCH 07/13] Upgrade to Go 1.20
With the release of Go 1.20, version 1.18 is not supported anymore. This
change upgrades the project to Go 1.20.
---
.github/workflows/ci.yaml | 4 ++--
.github/workflows/release.yaml | 2 +-
CONTRIBUTING.md | 20 ++++++++++----------
docker/Dockerfile | 2 +-
docker/Dockerfile.collector | 2 +-
docker/Dockerfile.web | 2 +-
go.mod | 2 +-
7 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 211a579..ed629a5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -101,7 +101,7 @@ jobs:
uses: actions/checkout@v2
- uses: actions/setup-go@v3
with:
- go-version: '^1.18.3'
+ go-version: '^1.20.1'
- name: Build Binaries
run: |
make binary-clean binary-all
@@ -111,4 +111,4 @@ jobs:
name: binaries.zip
path: |
scrutiny-web-*
- scrutiny-collector-metrics-*
\ No newline at end of file
+ scrutiny-collector-metrics-*
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 2a44423..3977818 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -96,7 +96,7 @@ jobs:
name: workspace
- uses: actions/setup-go@v3
with:
- go-version: '1.18.3' # The Go version to download (if necessary) and use.
+ go-version: '1.20.1' # The Go version to download (if necessary) and use.
- name: Build Binaries
run: |
make binary-clean binary-all
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5a6ad71..ea3fbad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,18 +5,18 @@ The Scrutiny repository is a [monorepo](https://en.wikipedia.org/wiki/Monorepo)
- Scrutiny Frontend Angular SPA
- S.M.A.R.T Collector
-Depending on the functionality you are adding, you may need to setup a development environment for 1 or more projects.
+Depending on the functionality you are adding, you may need to setup a development environment for 1 or more projects.
# Modifying the Scrutiny Backend Server (API)
-1. install the [Go runtime](https://go.dev/doc/install) (v1.18+)
+1. install the [Go runtime](https://go.dev/doc/install) (v1.20+)
2. download the `scrutiny-web-frontend.tar.gz` for
the [latest release](https://github.com/AnalogJ/scrutiny/releases/latest). Extract to a folder named `dist`
3. create a `scrutiny.yaml` config file
```yaml
# config file for local development. store as scrutiny.yaml
version: 1
-
+
web:
listen:
port: 8080
@@ -29,13 +29,13 @@ Depending on the functionality you are adding, you may need to setup a developme
path: ./dist
influxdb:
retention_policy: false
-
+
log:
file: 'web.log' #absolute or relative paths allowed, eg. web.log
level: DEBUG
```
-4. start a InfluxDB docker container.
+4. start a InfluxDB docker container.
```bash
docker run -p 8086:8086 --rm influxdb:2.2
```
@@ -60,16 +60,16 @@ The frontend is written in Angular. If you're working on the frontend and can us
3. open your browser and visit [http://localhost:4200/web](http://localhost:4200/web)
# Modifying both Scrutiny Backend and Frontend Applications
-If you're developing a feature that requires changes to the backend and the frontend, or a frontend feature that requires real data,
+If you're developing a feature that requires changes to the backend and the frontend, or a frontend feature that requires real data,
you'll need to follow the steps below:
-1. install the [Go runtime](https://go.dev/doc/install) (v1.18+)
+1. install the [Go runtime](https://go.dev/doc/install) (v1.20+)
2. install [NodeJS](https://nodejs.org/en/download/)
3. create a `scrutiny.yaml` config file
```yaml
# config file for local development. store as scrutiny.yaml
version: 1
-
+
web:
listen:
port: 8080
@@ -82,7 +82,7 @@ you'll need to follow the steps below:
path: ./dist
influxdb:
retention_policy: false
-
+
log:
file: 'web.log' #absolute or relative paths allowed, eg. web.log
level: DEBUG
@@ -185,4 +185,4 @@ docker run -p 8086:8086 -d --rm \
influxdb:2.2
go test ./...
-```
\ No newline at end of file
+```
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 7d35bef..98f1a73 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -5,7 +5,7 @@
########
-FROM golang:1.18-bullseye as backendbuild
+FROM golang:1.20-bullseye as backendbuild
WORKDIR /go/src/github.com/analogj/scrutiny
COPY . /go/src/github.com/analogj/scrutiny
diff --git a/docker/Dockerfile.collector b/docker/Dockerfile.collector
index 2839bdf..0cc9c12 100644
--- a/docker/Dockerfile.collector
+++ b/docker/Dockerfile.collector
@@ -4,7 +4,7 @@
########
-FROM golang:1.18-bullseye as backendbuild
+FROM golang:1.20-bullseye as backendbuild
WORKDIR /go/src/github.com/analogj/scrutiny
diff --git a/docker/Dockerfile.web b/docker/Dockerfile.web
index 8d1192c..5e59986 100644
--- a/docker/Dockerfile.web
+++ b/docker/Dockerfile.web
@@ -5,7 +5,7 @@
########
-FROM golang:1.18-bullseye as backendbuild
+FROM golang:1.20-bullseye as backendbuild
WORKDIR /go/src/github.com/analogj/scrutiny
diff --git a/go.mod b/go.mod
index daa70d2..04a9e91 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/analogj/scrutiny
-go 1.18
+go 1.20
require (
github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14
From 2e8f4a0581f54db0ab3a37a75120b4e4744a43f0 Mon Sep 17 00:00:00 2001
From: Jason Kulatunga
Date: Tue, 4 Apr 2023 21:53:39 -0700
Subject: [PATCH 08/13] update with instructions for adding host id to UI.
- fixes #464
- related #151
---
docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md | 25 ++++++++++++++++++-----
docs/multiple-host-ids.png | Bin 0 -> 80168 bytes
2 files changed, 20 insertions(+), 5 deletions(-)
create mode 100644 docs/multiple-host-ids.png
diff --git a/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md
index 3a9476a..4cf9d16 100644
--- a/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md
+++ b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md
@@ -275,10 +275,12 @@ to disable Scrutiny analysis for them. Both are non-critical, and have low-corre
If this is effecting your drives, you'll need to do the following:
1. Upgrade to v0.4.13+
-2. Reset your drive status using the SQLite script in [#device-failed-but-smart--scrutiny-passed](https://github.com/AnalogJ/scrutiny/blob/master/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md#device-failed-but-smart--scrutiny-passed)
+2. Reset your drive status using the SQLite script
+ in [#device-failed-but-smart--scrutiny-passed](https://github.com/AnalogJ/scrutiny/blob/master/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md#device-failed-but-smart--scrutiny-passed)
3. Wait for (or manually start) the collector.
-If you'd like to learn more about how the Seagate Ironwolf SMART attributes work under the hood, and how they differ from
+If you'd like to learn more about how the Seagate Ironwolf SMART attributes work under the hood, and how they differ
+from
other drives, please read the following:
- http://www.users.on.net/~fzabkar/HDD/Seagate_SER_RRER_HEC.html
@@ -286,10 +288,23 @@ other drives, please read the following:
## Hub & Spoke model, with multiple Hosts.
-When deploying Scrutiny in a hub & spoke model, it can be difficult to determine exactly which node a set of devices are associated with.
-Thankfully the collector has a special `--host-id` flag (or `COLLECTOR_HOST_ID` env variable) that can be used to associate devices with a friendly host name.
+![multiple-host-ids image](multiple-host-ids.png)
-See the [docs/INSTALL_HUB_SPOKE.md](/docs/INSTALL_HUB_SPOKE.md) guide for more information.
+When deploying Scrutiny in a hub & spoke model, it can be difficult to determine exactly which node a set of devices are
+associated with.
+Thankfully the collector has a special `--host-id` flag (or `COLLECTOR_HOST_ID` env variable) that can be used to
+associate devices with a friendly host name.
+
+The host-id is passed from the collector to the web-api when SMART device data is uploaded. There's 3 ways you can set
+the host-id:
+
+- using the collector config
+ file: [master/example.collector.yaml#L19-L22](https://github.com/AnalogJ/scrutiny/blob/master/example.collector.yaml?rgh-link-date=2022-05-25T15%3A08%3A56Z#L19-L22)
+- using the `--host-id` collector CLI
+ argument: [master/collector/cmd/collector-metrics/collector-metrics.go#L180-L185](https://github.com/AnalogJ/scrutiny/blob/master/collector/cmd/collector-metrics/collector-metrics.go?rgh-link-date=2022-05-25T15%3A08%3A56Z#L180-L185)
+- using the `COLLECTOR_HOST_ID` environmental variable.
+
+See the [docs/INSTALL_HUB_SPOKE.md](/docs/INSTALL_HUB_SPOKE.md) guide for more information.
## Collector DEBUG mode
diff --git a/docs/multiple-host-ids.png b/docs/multiple-host-ids.png
new file mode 100644
index 0000000000000000000000000000000000000000..82145eb3ede080ca2fa024c8a407556f2f871be4
GIT binary patch
literal 80168
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