From ddfe3858e29871e338dd41640ed615e8624b9457 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 2 Dec 2020 19:46:52 +0200 Subject: [PATCH 1/7] UI: Added translation for dashboard api usage; Added support translation on widget title and widget title tooltip --- ui-ngx/src/app/core/api/widget-api.models.ts | 2 +- .../dashboard/dashboard.component.html | 2 +- .../dashboard/dashboard.component.ts | 2 + .../home/models/dashboard-component.models.ts | 5 + .../home/pages/api-usage/api_usage_json.raw | 166 +++++++++--------- .../assets/locale/locale.constant-en_US.json | 52 +++++- 6 files changed, 143 insertions(+), 86 deletions(-) diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index e4b9deae89..d7dfdc29b4 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -198,7 +198,7 @@ export class WidgetSubscriptionContext { export type SubscriptionMessageSeverity = 'info' | 'warn' | 'error' | 'success'; export interface SubscriptionMessage { - severity: SubscriptionMessageSeverity, + severity: SubscriptionMessageSeverity; message: string; } diff --git a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html index 653e7f841f..063bd0a63d 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html @@ -90,7 +90,7 @@ matTooltipPosition="above" class="mat-subheading-2 title"> {{widget.titleIcon}} - {{widget.title}} + {{widget.customTranslatedTitle}} , + public utils: UtilsService, private timeService: TimeService, private dialogService: DialogService, private breakpointObserver: BreakpointObserver, diff --git a/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts b/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts index 3709b08b28..94a50540f9 100644 --- a/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts @@ -24,6 +24,7 @@ import { guid, isDefined, isEqual, isUndefined } from '@app/core/utils'; import { IterableDiffer, KeyValueDiffer } from '@angular/core'; import { IAliasController, IStateController } from '@app/core/api/widget-api.models'; import { enumerable } from '@shared/decorators/enumerable'; +import { UtilsService } from '@core/services/utils.service'; export interface WidgetsData { widgets: Array; @@ -56,6 +57,7 @@ export interface DashboardCallbacks { } export interface IDashboardComponent { + utils: UtilsService; gridsterOpts: GridsterConfig; gridster: GridsterComponent; dashboardWidgets: DashboardWidgets; @@ -295,6 +297,7 @@ export class DashboardWidget implements GridsterItem, IDashboardWidget { margin: string; title: string; + customTranslatedTitle: string; titleTooltip: string; showTitle: boolean; titleStyle: {[klass: string]: any}; @@ -358,8 +361,10 @@ export class DashboardWidget implements GridsterItem, IDashboardWidget { this.title = isDefined(this.widgetContext.widgetTitle) && this.widgetContext.widgetTitle.length ? this.widgetContext.widgetTitle : this.widget.config.title; + this.customTranslatedTitle = this.dashboard.utils.customTranslation(this.title, this.title); this.titleTooltip = isDefined(this.widgetContext.widgetTitleTooltip) && this.widgetContext.widgetTitleTooltip.length ? this.widgetContext.widgetTitleTooltip : this.widget.config.titleTooltip; + this.titleTooltip = this.dashboard.utils.customTranslation(this.titleTooltip, this.titleTooltip); this.showTitle = isDefined(this.widget.config.showTitle) ? this.widget.config.showTitle : true; this.titleStyle = this.widget.config.titleStyle ? this.widget.config.titleStyle : {}; diff --git a/ui-ngx/src/app/modules/home/pages/api-usage/api_usage_json.raw b/ui-ngx/src/app/modules/home/pages/api-usage/api_usage_json.raw index ab61bd331d..b54ce8ea99 100644 --- a/ui-ngx/src/app/modules/home/pages/api-usage/api_usage_json.raw +++ b/ui-ngx/src/app/modules/home/pages/api-usage/api_usage_json.raw @@ -95,7 +95,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"JavaScript\";" + "postFuncBody": "return \"{i18n:api-usage.javascript}\";" }, { "name": "jsExecutionApiState", @@ -108,7 +108,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Executions\";" + "postFuncBody": "return \"{i18n:api-usage.executions}\";" } ] } @@ -123,8 +123,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" + "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" }, "title": "JavaScript functions", "dropShadow": true, @@ -253,7 +253,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Telemetry\";" + "postFuncBody": "return \"{i18n:api-usage.telemetry}\";" }, { "name": "dbApiState", @@ -266,7 +266,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Data points storage days\";" + "postFuncBody": "return \"{i18n:api-usage.data-points-storage-days}\";" } ] } @@ -281,8 +281,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" + "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" }, "title": "Telemetry persistence", "dropShadow": true, @@ -411,7 +411,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Rule Engine\";" + "postFuncBody": "return \"{i18n:api-usage.rule-engine}\";" }, { "name": "ruleEngineApiState", @@ -424,7 +424,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Executions\";" + "postFuncBody": "return \"{i18n:api-usage.executions}\";" } ] } @@ -439,8 +439,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n", - "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n
\n
" + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n", + "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n
\n
" }, "title": "Rule Engine execution", "dropShadow": true, @@ -605,7 +605,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Transport\";" + "postFuncBody": "return \"{i18n:api-usage.transport}\";" } ] } @@ -620,8 +620,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardHtml": "
\n \n \n
\n
\n
\n
\n ${title}\n
\n
${apiState}
\n
\n
\n
\n
\n
Messages
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Data points
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bars-row {\n flex: 1;\n display: flex;\n flex-direction: row;\n}\n\n.card .bar-column {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 6px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n" + "cardHtml": "
\n \n \n
\n
\n
\n
\n ${title}\n
\n
${apiState}
\n
\n
\n
\n
\n
{i18n:api-usage.messages}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
{i18n:api-usage.data-points}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bars-row {\n flex: 1;\n display: flex;\n flex-direction: row;\n}\n\n.card .bar-column {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 6px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n" }, "title": "Transport", "dropShadow": true, @@ -750,7 +750,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Email\";" + "postFuncBody": "return \"{i18n:api-usage.email}\";" }, { "name": "emailApiState", @@ -763,7 +763,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Messages\";" + "postFuncBody": "return \"{i18n:api-usage.messages}\";" } ] } @@ -778,8 +778,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" + "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" }, "title": "Email messages", "dropShadow": true, @@ -908,7 +908,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"SMS\";" + "postFuncBody": "return \"{i18n:api-usage.sms}\";" }, { "name": "smsApiState", @@ -921,7 +921,7 @@ "decimals": null, "funcBody": null, "usePostProcessing": true, - "postFuncBody": "return \"Messages\";" + "postFuncBody": "return \"{i18n:api-usage.messages}\";" } ] } @@ -936,8 +936,8 @@ "color": "#666666", "padding": "0", "settings": { - "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", - "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" + "cardHtml": "
\n \n \n
\n
\n
\n
${title}
\n
${apiState}
\n
\n
\n
${unit}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
", + "cardCss": ".card {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n}\n\n.card > img {\n height: 0;\n}\n\n.card .content {\n flex: 1; \n padding: 13px 13px 0;\n display: flex;\n box-sizing: border-box;\n}\n\n.card .content .column {\n display: flex;\n flex-direction: column; \n justify-content: space-around;\n flex: 1;\n}\n\n.card .content .title-row {\n display: flex;\n flex-direction: row;\n padding-bottom: 10px;\n}\n\n.card .title {\n flex: 1;\n font-size: 20px;\n font-weight: 400;\n color: #666666;\n}\n\n.card .state {\n text-transform: uppercase;\n font-size: 20px;\n font-weight: bold;\n}\n\n.card.enabled .state {\n color: #00B260;\n}\n\n.card.warning .state {\n color: #FFAD6F;\n}\n\n.card.disabled .state {\n color: #F73243;\n}\n\n.card .bar-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.card .bar {\n flex: 1;\n max-height: 30px;\n margin-top: 3.5px;\n margin-bottom: 4px;\n background-color: #F0F0F0;\n border: 1px solid #DADCDB;\n border-radius: 2px;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);\n}\n\n.card.enabled .bar {\n border-color: #00B260;\n background-color: #F0FBF7;\n}\n\n.card.warning .bar {\n border-color: #FFAD6F;\n background-color: #FFFAF6;\n}\n\n.card.disabled .bar {\n border-color: #F73243;\n background-color: #FFF0F0;\n}\n\n.card .bar .bar-fill {\n background-color: #F0F0F0;\n border-radius: 2px;\n height: 100%;\n width: 0%;\n}\n\n.card.enabled .bar-fill {\n background-color: #00C46C;\n}\n\n.card.warning .bar-fill {\n background-color: #FFD099;\n}\n\n.card.disabled .bar-fill {\n background-color: #FF9494;\n}\n\n.card .bar-labels {\n height: 20px;\n font-size: 16px;\n color: #666;\n display: flex;\n flex-direction: row;\n}\n\n\n.card .mat-button {\n text-transform: uppercase;\n}\n\n.card .mat-button-wrapper {\n pointer-events: none;\n}\n\n.card .action-row {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n padding: 8px 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .card .title {\n font-size: 12px;\n }\n .card .state {\n font-size: 12px;\n }\n .card .unit {\n font-size: 8px;\n }\n .card .bar-labels {\n font-size: 8px;\n }\n .card .mat-button {\n font-size: 8px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1280px) and (max-width: 1599px) {\n .card .title {\n font-size: 14px;\n }\n .card .state {\n font-size: 14px;\n }\n .card .unit {\n font-size: 10px;\n }\n .card .bar-labels {\n font-size: 10px;\n }\n .card .mat-button {\n font-size: 10px;\n }\n .card .action-row {\n padding: 0;\n }\n}\n\n@media screen and (min-width: 1600px) and (max-width: 1919px) {\n .card .title {\n font-size: 16px;\n }\n .card .state {\n font-size: 16px;\n }\n .card .unit {\n font-size: 12px;\n }\n .card .bar-labels {\n font-size: 12px;\n }\n .card .mat-button {\n font-size: 12px;\n }\n .card .action-row {\n padding: 0;\n }\n} \n\n\n" }, "title": "SMS messages", "dropShadow": true, @@ -993,7 +993,7 @@ { "name": "ruleEngineExecutionCountHourly", "type": "timeseries", - "label": "Rule Engine executions", + "label": "{i18n:api-usage.rule-engine-executions}", "color": "#ab00ff", "settings": { "excludeFromStacking": false, @@ -1078,7 +1078,7 @@ "showLabels": true } }, - "title": "Rule Engine hourly activity", + "title": "{i18n:api-usage.rule-engine-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1091,7 +1091,7 @@ "actions": { "headerButton": [ { - "name": "View statistics", + "name": "{i18n:api-usage.view-statistics}", "icon": "show_chart", "type": "openDashboardState", "targetDashboardStateId": "rule_engine_statistics", @@ -1101,7 +1101,7 @@ "id": "f9f08190-9ed9-d802-5b7a-c57ff84b5648" }, { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "rule_engine_execution", @@ -1150,7 +1150,7 @@ { "name": "transportMsgCountHourly", "type": "timeseries", - "label": "Transport messages", + "label": "{i18n:api-usage.transport-messages}", "color": "#2196f3", "settings": { "excludeFromStacking": false, @@ -1185,7 +1185,7 @@ { "name": "transportDataPointsCountHourly", "type": "timeseries", - "label": "Transport data points", + "label": "{i18n:api-usage.transport-data-points}", "color": "#4caf50", "settings": { "excludeFromStacking": false, @@ -1271,7 +1271,7 @@ }, "tooltipCumulative": false }, - "title": "Transport hourly activity", + "title": "{i18n:api-usage.transport-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1284,7 +1284,7 @@ "actions": { "headerButton": [ { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "transport", @@ -1333,7 +1333,7 @@ { "name": "jsExecutionCountHourly", "type": "timeseries", - "label": "JavaScript executions", + "label": "{i18n:api-usage.javascript-executions}", "color": "#ff9900", "settings": { "excludeFromStacking": false, @@ -1418,7 +1418,7 @@ "showLabels": true } }, - "title": "JavaScript functions hourly activity", + "title": "{i18n:api-usage.javascript-functions-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1431,7 +1431,7 @@ "actions": { "headerButton": [ { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "javascript_functions", @@ -1480,7 +1480,7 @@ { "name": "storageDataPointsCountHourly", "type": "timeseries", - "label": "Data points storage days", + "label": "{i18n:api-usage.data-points-storage-days}", "color": "#1039ee", "settings": { "excludeFromStacking": false, @@ -1565,7 +1565,7 @@ "showLabels": true } }, - "title": "Telemetry persistence hourly activity", + "title": "{i18n:api-usage.telemetry-persistence-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1578,7 +1578,7 @@ "actions": { "headerButton": [ { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "telemetry_persistence", @@ -1627,7 +1627,7 @@ { "name": "emailCountHourly", "type": "timeseries", - "label": "Email messages", + "label": "{i18n:api-usage.email-messages}", "color": "#d35a00", "settings": { "excludeFromStacking": false, @@ -1712,7 +1712,7 @@ "showLabels": true } }, - "title": "Email messages hourly activity", + "title": "{i18n:api-usage.email-messages-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1725,7 +1725,7 @@ "actions": { "headerButton": [ { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "email_messages", @@ -1774,7 +1774,7 @@ { "name": "smsCountHourly", "type": "timeseries", - "label": "SMS messages", + "label": "{i18n:api-usage.sms-messages}", "color": "#f36021", "settings": { "excludeFromStacking": false, @@ -1859,7 +1859,7 @@ "showLabels": true } }, - "title": "SMS messages hourly activity", + "title": "{i18n:api-usage.sms-messages-hourly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -1872,7 +1872,7 @@ "actions": { "headerButton": [ { - "name": "View details", + "name": "{i18n:api-usage.view-details}", "icon": "insert_chart", "type": "openDashboardState", "targetDashboardStateId": "sms_messages", @@ -1921,7 +1921,7 @@ { "name": "ruleEngineExecutionCountHourly", "type": "timeseries", - "label": "Rule Engine executions", + "label": "{i18n:api-usage.rule-engine-executions}", "color": "#ab00ff", "settings": { "excludeFromStacking": false, @@ -2007,7 +2007,7 @@ "showLabels": true } }, - "title": "Rule Engine daily activity", + "title": "{i18n:api-usage.rule-engine-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2056,7 +2056,7 @@ { "name": "ruleEngineExecutionCount", "type": "timeseries", - "label": "Rule Engine executions", + "label": "{i18n:api-usage.rule-engine-executions}", "color": "#ab00ff", "settings": { "excludeFromStacking": false, @@ -2142,7 +2142,7 @@ "showLabels": true } }, - "title": "Rule Engine monthly activity", + "title": "{i18n:api-usage.rule-engine-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2191,7 +2191,7 @@ { "name": "jsExecutionCountHourly", "type": "timeseries", - "label": "JavaScript executions", + "label": "{i18n:api-usage.javascript-executions}", "color": "#ff9900", "settings": { "excludeFromStacking": false, @@ -2277,7 +2277,7 @@ "showLabels": true } }, - "title": "JavaScript functions daily activity", + "title": "{i18n:api-usage.javascript-functions-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2326,7 +2326,7 @@ { "name": "jsExecutionCount", "type": "timeseries", - "label": "JavaScript executions", + "label": "{i18n:api-usage.javascript-executions}", "color": "#ff9900", "settings": { "excludeFromStacking": false, @@ -2412,7 +2412,7 @@ "showLabels": true } }, - "title": "JavaScript functions monthly activity", + "title": "{i18n:api-usage.javascript-functions-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2461,7 +2461,7 @@ { "name": "transportMsgCountHourly", "type": "timeseries", - "label": "Transport messages", + "label": "{i18n:api-usage.transport-messages}", "color": "#2196f3", "settings": { "excludeFromStacking": false, @@ -2496,7 +2496,7 @@ { "name": "transportDataPointsCountHourly", "type": "timeseries", - "label": "Transport data points", + "label": "{i18n:api-usage.transport-data-points}", "color": "#4caf50", "settings": { "excludeFromStacking": false, @@ -2583,7 +2583,7 @@ }, "tooltipCumulative": false }, - "title": "Transport daily activity", + "title": "{i18n:api-usage.transport-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2632,7 +2632,7 @@ { "name": "transportMsgCount", "type": "timeseries", - "label": "Transport messages", + "label": "{i18n:api-usage.transport-messages}", "color": "#2196f3", "settings": { "excludeFromStacking": false, @@ -2667,7 +2667,7 @@ { "name": "transportDataPointsCount", "type": "timeseries", - "label": "Transport data points", + "label": "{i18n:api-usage.transport-data-points}", "color": "#4caf50", "settings": { "excludeFromStacking": false, @@ -2754,7 +2754,7 @@ }, "tooltipCumulative": false }, - "title": "Transport monthly activity", + "title": "{i18n:api-usage.transport-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2803,7 +2803,7 @@ { "name": "storageDataPointsCountHourly", "type": "timeseries", - "label": "Data points storage days", + "label": "{i18n:api-usage.data-points-storage-days}", "color": "#1039ee", "settings": { "excludeFromStacking": false, @@ -2889,7 +2889,7 @@ "showLabels": true } }, - "title": "Telemetry persistence daily activity", + "title": "{i18n:api-usage.telemetry-persistence-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -2938,7 +2938,7 @@ { "name": "storageDataPointsCount", "type": "timeseries", - "label": "Data points storage days", + "label": "{i18n:api-usage.data-points-storage-days}", "color": "#1039ee", "settings": { "excludeFromStacking": false, @@ -3024,7 +3024,7 @@ "showLabels": true } }, - "title": "Telemetry persistence monthly activity", + "title": "{i18n:api-usage.telemetry-persistence-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -3073,7 +3073,7 @@ { "name": "emailCountHourly", "type": "timeseries", - "label": "Email messages", + "label": "{i18n:api-usage.email-messages}", "color": "#d35a00", "settings": { "excludeFromStacking": false, @@ -3159,7 +3159,7 @@ "showLabels": true } }, - "title": "Email messages daily activity", + "title": "{i18n:api-usage.email-messages-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -3208,7 +3208,7 @@ { "name": "emailCount", "type": "timeseries", - "label": "Email messages", + "label": "{i18n:api-usage.email-messages}", "color": "#d35a00", "settings": { "excludeFromStacking": false, @@ -3294,7 +3294,7 @@ "showLabels": true } }, - "title": "Email messages monthly activity", + "title": "{i18n:api-usage.sms-messages-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -3343,7 +3343,7 @@ { "name": "smsCountHourly", "type": "timeseries", - "label": "SMS messages", + "label": "{i18n:api-usage.sms-messages}", "color": "#f36021", "settings": { "excludeFromStacking": false, @@ -3429,7 +3429,7 @@ "showLabels": true } }, - "title": "SMS messages daily activity", + "title": "{i18n:api-usage.sms-messages-daily-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -3478,7 +3478,7 @@ { "name": "smsCount", "type": "timeseries", - "label": "SMS messages", + "label": "{i18n:api-usage.sms-messages}", "color": "#f36021", "settings": { "excludeFromStacking": false, @@ -3564,7 +3564,7 @@ "showLabels": true } }, - "title": "SMS messages monthly activity", + "title": "{i18n:api-usage.sms-messages-monthly-activity}", "dropShadow": true, "enableFullscreen": true, "titleStyle": { @@ -3610,7 +3610,7 @@ { "name": "successfulMsgs", "type": "timeseries", - "label": "${entityName} Successful", + "label": "{i18n:api-usage.successful}", "color": "#4caf50", "settings": { "excludeFromStacking": false, @@ -3640,7 +3640,7 @@ { "name": "failedMsgs", "type": "timeseries", - "label": "${entityName} Permanent Failures", + "label": "{i18n:api-usage.permanent-failures}", "color": "#ef5350", "settings": { "excludeFromStacking": false, @@ -3670,7 +3670,7 @@ { "name": "tmpFailed", "type": "timeseries", - "label": "${entityName} Processing Failures", + "label": "{i18n:api-usage.processing-failures}", "color": "#ffc107", "settings": { "excludeFromStacking": false, @@ -3794,7 +3794,7 @@ { "name": "timeoutMsgs", "type": "timeseries", - "label": "${entityName} Permanent Timeouts", + "label": "{i18n:api-usage.permanent-timeouts}", "color": "#4caf50", "settings": { "excludeFromStacking": false, @@ -3824,7 +3824,7 @@ { "name": "tmpTimeout", "type": "timeseries", - "label": "${entityName} Processing Timeouts", + "label": "{i18n:api-usage.processing-timeouts}", "color": "#9c27b0", "settings": { "excludeFromStacking": false, @@ -4031,7 +4031,7 @@ }, "states": { "default": { - "name": "Api Usage", + "name": "{i18n:api-usage.api-usage}", "root": true, "layouts": { "main": { @@ -4130,7 +4130,7 @@ } }, "transport": { - "name": "Transport", + "name": "{i18n:api-usage.transport}", "root": false, "layouts": { "main": { @@ -4163,7 +4163,7 @@ } }, "rule_engine_execution": { - "name": "Rule Engine execution", + "name": "{i18n:api-usage.rule-engine-executions}", "root": false, "layouts": { "main": { @@ -4196,7 +4196,7 @@ } }, "javascript_functions": { - "name": "JavaScript functions", + "name": "{i18n:api-usage.javascript-functions}", "root": false, "layouts": { "main": { @@ -4229,7 +4229,7 @@ } }, "telemetry_persistence": { - "name": "Telemetry persistence", + "name": "{i18n:api-usage.telemetry-persistence}", "root": false, "layouts": { "main": { @@ -4262,7 +4262,7 @@ } }, "email_messages": { - "name": "Email messages", + "name": "{i18n:api-usage.email-messages}", "root": false, "layouts": { "main": { @@ -4295,7 +4295,7 @@ } }, "sms_messages": { - "name": "SMS messages", + "name": "{i18n:api-usage.sms-messages}", "root": false, "layouts": { "main": { @@ -4328,7 +4328,7 @@ } }, "rule_engine_statistics": { - "name": "Rule Engine Statistics", + "name": "{i18n:api-usage.rule-engine-statistics}", "root": false, "layouts": { "main": { @@ -4417,4 +4417,4 @@ } }, "name": "Api Usage" -} \ No newline at end of file +} diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 2c8cc0641a..86ac20bf35 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -433,7 +433,57 @@ "no-telemetry-text": "No telemetry found" }, "api-usage": { - "api-usage": "Api Usage" + "api-usage": "Api Usage", + "data-points": "Data points", + "data-points-storage-days": "Data points storage days", + "email": "Email", + "email-messages": "Email messages", + "email-messages-daily-activity": "Email messages daily activity", + "email-messages-hourly-activity": "Email messages hourly activity", + "email-messages-monthly-activity": "Email messages monthly activity", + "exceptions": "Exceptions", + "executions": "Executions", + "javascript": "JavaScript", + "javascript-executions": "JavaScript executions", + "javascript-functions": "JavaScript functions", + "javascript-functions-daily-activity": "JavaScript functions daily activity", + "javascript-functions-hourly-activity": "JavaScript functions hourly activity", + "javascript-functions-monthly-activity": "JavaScript functions monthly activity", + "latest-error": "Latest Error", + "messages": "Messages", + "permanent-failures": "${entityName} Permanent Failures", + "permanent-timeouts": "${entityName} Permanent Timeouts", + "processing-failures": "${entityName} Processing Failures", + "processing-failures-and-timeouts": "Processing Failures and Timeouts", + "processing-timeouts": "${entityName} Processing Timeouts", + "queue-stats": "Queue Stats", + "rule-chain": "Rule Chain", + "rule-engine": "Rule Engine", + "rule-engine-daily-activity": "Rule Engine daily activity", + "rule-engine-executions": "Rule Engine executions", + "rule-engine-hourly-activity": "Rule Engine hourly activity", + "rule-engine-monthly-activity": "Rule Engine monthly activity", + "rule-engine-statistics": "Rule Engine Statistics", + "rule-node": "Rule Node", + "sms": "SMS", + "sms-messages": "SMS messages", + "sms-messages-daily-activity": "SMS messages daily activity", + "sms-messages-hourly-activity": "SMS messages hourly activity", + "sms-messages-monthly-activity": "SMS messages monthly activity", + "successful": "${entityName} Successful", + "telemetry": "Telemetry", + "telemetry-persistence": "Telemetry persistence", + "telemetry-persistence-daily-activity": "Telemetry persistence daily activity", + "telemetry-persistence-hourly-activity": "Telemetry persistence hourly activity", + "telemetry-persistence-monthly-activity": "Telemetry persistence monthly activity", + "transport": "Transport", + "transport-daily-activity": "Transport daily activity", + "transport-data-points": "Transport data points", + "transport-hourly-activity": "Transport hourly activity", + "transport-messages": "Transport messages", + "transport-monthly-activity": "Transport monthly activity", + "view-details": "View details", + "view-statistics": "View statistics" }, "audit-log": { "audit": "Audit", From c9598a23ea3e8170f872b2c0c13a6964059076e5 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 3 Dec 2020 14:09:48 +0200 Subject: [PATCH 2/7] UI: Introduce initial page loading spinner --- ui-ngx/src/app/app.component.html | 2 +- ui-ngx/src/app/app.component.ts | 10 +++- ui-ngx/src/index.html | 76 ++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/app.component.html b/ui-ngx/src/app/app.component.html index 6521e99533..7330d0c1c1 100644 --- a/ui-ngx/src/app/app.component.html +++ b/ui-ngx/src/app/app.component.html @@ -17,4 +17,4 @@ --> - + diff --git a/ui-ngx/src/app/app.component.ts b/ui-ngx/src/app/app.component.ts index f7d290c5ca..ac3512694e 100644 --- a/ui-ngx/src/app/app.component.ts +++ b/ui-ngx/src/app/app.component.ts @@ -62,7 +62,7 @@ export class AppComponent implements OnInit { this.matIconRegistry.addSvgIconLiteral( 'alpha-e-circle-outline', this.domSanitizer.bypassSecurityTrustHtml( - '' ) @@ -124,5 +124,11 @@ export class AppComponent implements OnInit { ngOnInit() { } -} + onActivateComponent($event: any) { + const loadingElement = $('div#tb-loading-spinner'); + if (loadingElement.length) { + loadingElement.remove(); + } + } +} diff --git a/ui-ngx/src/index.html b/ui-ngx/src/index.html index af49c0c938..f569c054e4 100644 --- a/ui-ngx/src/index.html +++ b/ui-ngx/src/index.html @@ -16,7 +16,7 @@ --> - + ThingsBoard @@ -24,8 +24,82 @@ + +
+
+
+
+
From 30bca76585eed149420e57397099f758e309261d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 3 Dec 2020 14:47:28 +0200 Subject: [PATCH 3/7] UI: set default background color --- ui-ngx/src/app/modules/login/pages/login/login.component.scss | 2 +- ui-ngx/src/index.html | 2 +- ui-ngx/src/styles.scss | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/login/pages/login/login.component.scss b/ui-ngx/src/app/modules/login/pages/login/login.component.scss index b8fa052e75..28150044c3 100644 --- a/ui-ngx/src/app/modules/login/pages/login/login.component.scss +++ b/ui-ngx/src/app/modules/login/pages/login/login.component.scss @@ -21,7 +21,7 @@ .tb-login-content { margin-top: 36px; margin-bottom: 76px; - background-color: rgb(250, 250, 250); + background-color: #eee; .tb-login-form { @media #{$mat-gt-xs} { width: 550px !important; diff --git a/ui-ngx/src/index.html b/ui-ngx/src/index.html index f569c054e4..4f2672a518 100644 --- a/ui-ngx/src/index.html +++ b/ui-ngx/src/index.html @@ -29,7 +29,7 @@ body, html { height: 100%; overflow: hidden; - background-color: rgb(250,250,250); + background-color: #eee; } .tb-loading-spinner { diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index 190fbb1ba7..600121b66d 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -41,7 +41,7 @@ body, html { body { margin: 0; padding: 0; - background-color: rgb(250,250,250); + background-color: #eee; overflow: hidden; } From 6f2f9c54dcd7c32f0511807a66c3ec8497aa42dd Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 1 Jan 2021 02:03:02 +0200 Subject: [PATCH 4/7] fixed zones in SchedulerUtils and ApiUsageStateService improvements --- .../DefaultTbApiUsageStateService.java | 31 +++++++++++++------ .../common/msg/tools/SchedulerUtils.java | 13 +++----- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 50a273223d..12e8e6017d 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -61,6 +61,7 @@ import org.thingsboard.server.service.telemetry.InternalTelemetryService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -73,6 +74,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; @Slf4j @Service @@ -347,16 +349,11 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { try { long now = System.currentTimeMillis(); myTenantStates.values().forEach(state -> { - if ((state.getNextCycleTs() > now) && (state.getNextCycleTs() - now < TimeUnit.HOURS.toMillis(1))) { + if ((state.getNextCycleTs() < now) && (now - state.getNextCycleTs() < TimeUnit.HOURS.toMillis(1))) { TenantId tenantId = state.getTenantId(); state.setCycles(state.getNextCycleTs(), SchedulerUtils.getStartOfNextNextMonth()); - ToUsageStatsServiceMsg.Builder msg = ToUsageStatsServiceMsg.newBuilder(); - msg.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); - msg.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); - for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) { - msg.addValues(UsageStatsKVProto.newBuilder().setKey(key.name()).setValue(0).build()); - } - process(new TbProtoQueueMsg<>(UUID.randomUUID(), msg.build()), TbCallback.EMPTY); + saveNewCounts(state, Arrays.asList(ApiUsageRecordKey.values())); + updateTenantState(state, tenantProfileCache.get(tenantId)); } }); } finally { @@ -364,6 +361,14 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { } } + private void saveNewCounts(TenantApiUsageState state, List keys) { + List counts = keys.stream() + .map(key -> new BasicTsKvEntry(state.getCurrentCycleTs(), new LongDataEntry(key.getApiCountKey(), 0L))) + .collect(Collectors.toList()); + + tsWsService.saveAndNotifyInternal(state.getTenantId(), state.getApiUsageState().getId(), counts, VOID_CALLBACK); + } + private TenantApiUsageState getOrFetchState(TenantId tenantId) { TenantApiUsageState tenantState = myTenantStates.get(tenantId); if (tenantState == null) { @@ -377,6 +382,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { } TenantProfile tenantProfile = tenantProfileCache.get(tenantId); tenantState = new TenantApiUsageState(tenantProfile, dbStateEntity); + List newCounts = new ArrayList<>(); try { List dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getId()).get(); for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) { @@ -385,7 +391,13 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { for (TsKvEntry tsKvEntry : dbValues) { if (tsKvEntry.getKey().equals(key.getApiCountKey())) { cycleEntryFound = true; - tenantState.put(key, tsKvEntry.getTs() == tenantState.getCurrentCycleTs() ? tsKvEntry.getLongValue().get() : 0L); + + boolean oldCount = tsKvEntry.getTs() == tenantState.getCurrentCycleTs(); + tenantState.put(key, oldCount ? tsKvEntry.getLongValue().get() : 0L); + + if (!oldCount) { + newCounts.add(key); + } } else if (tsKvEntry.getKey().equals(key.getApiCountKey() + HOURLY)) { hourlyEntryFound = true; tenantState.putHourly(key, tsKvEntry.getTs() == tenantState.getCurrentHourTs() ? tsKvEntry.getLongValue().get() : 0L); @@ -397,6 +409,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { } log.debug("[{}] Initialized state: {}", tenantId, dbStateEntity); myTenantStates.put(tenantId, tenantState); + saveNewCounts(tenantState, newCounts); } catch (InterruptedException | ExecutionException e) { log.warn("[{}] Failed to fetch api usage state from db.", tenantId, e); } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/tools/SchedulerUtils.java b/common/message/src/main/java/org/thingsboard/server/common/msg/tools/SchedulerUtils.java index 421066b30b..57cc578f2c 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/tools/SchedulerUtils.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/tools/SchedulerUtils.java @@ -17,22 +17,19 @@ package org.thingsboard.server.common.msg.tools; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; import java.time.ZoneId; -import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; -import java.time.temporal.TemporalUnit; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import static java.time.ZoneOffset.UTC; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoUnit.MONTHS; public class SchedulerUtils { - private final static ZoneId UTC = ZoneId.of("UTC"); private static final ConcurrentMap tzMap = new ConcurrentHashMap<>(); public static ZoneId getZoneId(String tz) { @@ -44,7 +41,7 @@ public class SchedulerUtils { } public static long getStartOfCurrentHour(ZoneId zoneId) { - return LocalDateTime.now(ZoneOffset.UTC).atZone(zoneId).truncatedTo(ChronoUnit.HOURS).toInstant().toEpochMilli(); + return LocalDateTime.now(UTC).atZone(zoneId).truncatedTo(ChronoUnit.HOURS).toInstant().toEpochMilli(); } public static long getStartOfCurrentMonth() { @@ -52,7 +49,7 @@ public class SchedulerUtils { } public static long getStartOfCurrentMonth(ZoneId zoneId) { - return LocalDate.now().withDayOfMonth(1).atStartOfDay(zoneId).toInstant().toEpochMilli(); + return LocalDate.now(UTC).withDayOfMonth(1).atStartOfDay(zoneId).toInstant().toEpochMilli(); } public static long getStartOfNextMonth() { @@ -60,7 +57,7 @@ public class SchedulerUtils { } public static long getStartOfNextMonth(ZoneId zoneId) { - return LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()).atStartOfDay(zoneId).toInstant().toEpochMilli(); + return LocalDate.now(UTC).with(TemporalAdjusters.firstDayOfNextMonth()).atStartOfDay(zoneId).toInstant().toEpochMilli(); } public static long getStartOfNextNextMonth() { @@ -68,7 +65,7 @@ public class SchedulerUtils { } public static long getStartOfNextNextMonth(ZoneId zoneId) { - return LocalDate.now().with(firstDayOfNextNextMonth()).atStartOfDay(zoneId).toInstant().toEpochMilli(); + return LocalDate.now(UTC).with(firstDayOfNextNextMonth()).atStartOfDay(zoneId).toInstant().toEpochMilli(); } public static TemporalAdjuster firstDayOfNextNextMonth() { From 2ca3ce47f40256b56d15434bc6fc99823fa778a8 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 3 Dec 2020 16:27:27 +0200 Subject: [PATCH 5/7] UI: Fixed show in Safari browser profile; Fixed show ui-rule-node --- .../filter-predicate-value.component.html | 16 ++-- .../filter/key-filter-list.component.html | 2 +- .../alarm/create-alarm-rules.component.html | 2 +- .../alarm/device-profile-alarm.component.html | 7 +- .../device-profile-alarms.component.html | 3 +- .../profile/device-profile.component.html | 2 +- .../rule-node-details.component.html | 86 +++++++++---------- 7 files changed, 57 insertions(+), 61 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html b/ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html index 524285ea3f..01106137b9 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html @@ -17,28 +17,28 @@ -->
-
+
- + - + - - + {{ (filterPredicateValueFormGroup.get('defaultValue').value ? 'value.true' : 'value.false') | translate }} @@ -46,9 +46,9 @@
filter.default-value
-
+
- + @@ -62,7 +62,7 @@
filter.dynamic-source-type
- + diff --git a/ui-ngx/src/app/modules/home/components/filter/key-filter-list.component.html b/ui-ngx/src/app/modules/home/components/filter/key-filter-list.component.html index 26dbaaec4a..cf670d7b27 100644 --- a/ui-ngx/src/app/modules/home/components/filter/key-filter-list.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/key-filter-list.component.html @@ -41,7 +41,7 @@ filter.operation.and
-
+
{{ keyFilterControl.value.key.key }}
{{ entityKeyTypeTranslations.get(keyFilterControl.value.key.type) }}
-
+
-
+
-
+
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html index fd4efddf5a..880e7586df 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html @@ -21,48 +21,46 @@ {{'rulechain.open-rulechain' | translate }}
-
- -
-
-
- - rulenode.name - - - {{ 'rulenode.name-required' | translate }} - - - - {{ 'rulenode.debug-mode' | translate }} - -
- - -
- - rulenode.description - - -
+ +
+
+
+ + rulenode.name + + + {{ 'rulenode.name-required' | translate }} + + + + {{ 'rulenode.debug-mode' | translate }} +
-
- - -
- - rulenode.description - - -
-
-
- -
+ + +
+ + rulenode.description + + +
+ +
+ + +
+ + rulenode.description + + +
+
+ + From 41006bf3fcaf88af20d6385607030dea6a57bd24 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 3 Dec 2020 18:20:45 +0200 Subject: [PATCH 6/7] UI: Fixed show in Safari browser dashboard filter --- .../filter-user-info-dialog.component.html | 6 +- .../filter/filters-edit-panel.component.html | 4 +- .../filter/user-filter-dialog.component.html | 58 +++++++++---------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html index 587504da45..9be0838fb8 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html @@ -27,10 +27,10 @@
- + {{ 'filter.editable' | translate }} -
+
filter.display-label @@ -39,7 +39,7 @@ {{ 'filter.autogenerated-label' | translate }}
- + filter.order-priority diff --git a/ui-ngx/src/app/modules/home/components/filter/filters-edit-panel.component.html b/ui-ngx/src/app/modules/home/components/filter/filters-edit-panel.component.html index 3de6b75bc4..775bfddaaa 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filters-edit-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filters-edit-panel.component.html @@ -16,8 +16,8 @@ -->
-
-
+
+
{{filter.value.filter}}