Commit 6417ef7cd0b25f46372706fb7a23e6e714fc3dca

Authored by Igor Kulikov
Committed by GitHub
2 parents c7652824 d53d4362

Merge pull request #5486 from ArtemDzhereleiko/imp/widget-settings/no-data-message

[3.2.2] UI: New widget settings with input field no data message
@@ -136,7 +136,7 @@ @@ -136,7 +136,7 @@
136 </table> 136 </table>
137 <span [fxShow]="(alarmsDatasource.isEmpty() | async) && !alarmsDatasource.dataLoading" 137 <span [fxShow]="(alarmsDatasource.isEmpty() | async) && !alarmsDatasource.dataLoading"
138 fxLayoutAlign="center center" 138 fxLayoutAlign="center center"
139 - class="no-data-found" translate>alarm.no-alarms-prompt</span> 139 + class="no-data-found">{{ noDataDisplayMessageText }}</span>
140 <span [fxShow]="alarmsDatasource.dataLoading" 140 <span [fxShow]="alarmsDatasource.dataLoading"
141 fxLayoutAlign="center center" 141 fxLayoutAlign="center center"
142 class="no-data-found">{{ 'common.loading' | translate }}</span> 142 class="no-data-found">{{ 'common.loading' | translate }}</span>
@@ -74,6 +74,7 @@ import { @@ -74,6 +74,7 @@ import {
74 getColumnWidth, 74 getColumnWidth,
75 getRowStyleInfo, 75 getRowStyleInfo,
76 getTableCellButtonActions, 76 getTableCellButtonActions,
  77 + noDataMessage,
77 prepareTableCellButtonActions, 78 prepareTableCellButtonActions,
78 RowStyleInfo, 79 RowStyleInfo,
79 TableCellButtonActionDescriptor, 80 TableCellButtonActionDescriptor,
@@ -166,6 +167,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -166,6 +167,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
166 public columns: Array<EntityColumn> = []; 167 public columns: Array<EntityColumn> = [];
167 public displayedColumns: string[] = []; 168 public displayedColumns: string[] = [];
168 public alarmsDatasource: AlarmsDatasource; 169 public alarmsDatasource: AlarmsDatasource;
  170 + public noDataDisplayMessageText: string;
169 private setCellButtonAction: boolean; 171 private setCellButtonAction: boolean;
170 172
171 private cellContentCache: Array<any> = []; 173 private cellContentCache: Array<any> = [];
@@ -357,6 +359,9 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -357,6 +359,9 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
357 this.pageLink.severityList = isDefined(this.widgetConfig.alarmSeverityList) ? this.widgetConfig.alarmSeverityList : []; 359 this.pageLink.severityList = isDefined(this.widgetConfig.alarmSeverityList) ? this.widgetConfig.alarmSeverityList : [];
358 this.pageLink.typeList = isDefined(this.widgetConfig.alarmTypeList) ? this.widgetConfig.alarmTypeList : []; 360 this.pageLink.typeList = isDefined(this.widgetConfig.alarmTypeList) ? this.widgetConfig.alarmTypeList : [];
359 361
  362 + this.noDataDisplayMessageText =
  363 + noDataMessage(this.widgetConfig.noDataDisplayMessage, 'alarm.no-alarms-prompt', this.utils, this.translate);
  364 +
360 const cssString = constructTableCssString(this.widgetConfig); 365 const cssString = constructTableCssString(this.widgetConfig);
361 const cssParser = new cssjs(); 366 const cssParser = new cssjs();
362 cssParser.testMode = false; 367 cssParser.testMode = false;
@@ -95,7 +95,7 @@ @@ -95,7 +95,7 @@
95 </table> 95 </table>
96 <span [fxShow]="(entityDatasource.isEmpty() | async) && !entityDatasource.dataLoading" 96 <span [fxShow]="(entityDatasource.isEmpty() | async) && !entityDatasource.dataLoading"
97 fxLayoutAlign="center center" 97 fxLayoutAlign="center center"
98 - class="no-data-found" translate>entity.no-entities-prompt</span> 98 + class="no-data-found">{{ noDataDisplayMessageText }}</span>
99 <span [fxShow]="entityDatasource.dataLoading" 99 <span [fxShow]="entityDatasource.dataLoading"
100 fxLayoutAlign="center center" 100 fxLayoutAlign="center center"
101 class="no-data-found">{{ 'common.loading' | translate }}</span> 101 class="no-data-found">{{ 'common.loading' | translate }}</span>
@@ -80,6 +80,7 @@ import { @@ -80,6 +80,7 @@ import {
80 getEntityValue, 80 getEntityValue,
81 getRowStyleInfo, 81 getRowStyleInfo,
82 getTableCellButtonActions, 82 getTableCellButtonActions,
  83 + noDataMessage,
83 prepareTableCellButtonActions, 84 prepareTableCellButtonActions,
84 RowStyleInfo, 85 RowStyleInfo,
85 TableCellButtonActionDescriptor, 86 TableCellButtonActionDescriptor,
@@ -142,6 +143,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -142,6 +143,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
142 public columns: Array<EntityColumn> = []; 143 public columns: Array<EntityColumn> = [];
143 public displayedColumns: string[] = []; 144 public displayedColumns: string[] = [];
144 public entityDatasource: EntityDatasource; 145 public entityDatasource: EntityDatasource;
  146 + public noDataDisplayMessageText: string;
145 private setCellButtonAction: boolean; 147 private setCellButtonAction: boolean;
146 148
147 private cellContentCache: Array<any> = []; 149 private cellContentCache: Array<any> = [];
@@ -275,6 +277,9 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -275,6 +277,9 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
275 this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3]; 277 this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
276 this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : 1024; 278 this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : 1024;
277 279
  280 + this.noDataDisplayMessageText =
  281 + noDataMessage(this.widgetConfig.noDataDisplayMessage, 'entity.no-entities-prompt', this.utils, this.translate);
  282 +
278 const cssString = constructTableCssString(this.widgetConfig); 283 const cssString = constructTableCssString(this.widgetConfig);
279 const cssParser = new cssjs(); 284 const cssParser = new cssjs();
280 cssParser.testMode = false; 285 cssParser.testMode = false;
@@ -23,6 +23,8 @@ import { Direction, EntityDataSortOrder, EntityKey } from '@shared/models/query/ @@ -23,6 +23,8 @@ import { Direction, EntityDataSortOrder, EntityKey } from '@shared/models/query/
23 import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; 23 import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
24 import { WidgetContext } from '@home/models/widget-component.models'; 24 import { WidgetContext } from '@home/models/widget-component.models';
25 import { FormattedData } from '@home/components/widget/lib/maps/map-models'; 25 import { FormattedData } from '@home/components/widget/lib/maps/map-models';
  26 +import { UtilsService } from '@core/services/utils.service';
  27 +import { TranslateService } from '@ngx-translate/core';
26 28
27 const tinycolor = tinycolor_; 29 const tinycolor = tinycolor_;
28 30
@@ -352,6 +354,14 @@ function filterTableCellButtonAction(widgetContext: WidgetContext, @@ -352,6 +354,14 @@ function filterTableCellButtonAction(widgetContext: WidgetContext,
352 } 354 }
353 } 355 }
354 356
  357 +export function noDataMessage(noDataDisplayMessage: string, defaultMessage: string,
  358 + utils: UtilsService, translate: TranslateService): string {
  359 + if (isNotEmptyStr(noDataDisplayMessage)) {
  360 + return utils.customTranslation(noDataDisplayMessage, noDataDisplayMessage);
  361 + }
  362 + return translate.instant(defaultMessage);
  363 +}
  364 +
355 export function constructTableCssString(widgetConfig: WidgetConfig): string { 365 export function constructTableCssString(widgetConfig: WidgetConfig): string {
356 const origColor = widgetConfig.color || 'rgba(0, 0, 0, 0.87)'; 366 const origColor = widgetConfig.color || 'rgba(0, 0, 0, 0.87)';
357 const origBackgroundColor = widgetConfig.backgroundColor || 'rgb(255, 255, 255)'; 367 const origBackgroundColor = widgetConfig.backgroundColor || 'rgb(255, 255, 255)';
@@ -104,7 +104,7 @@ @@ -104,7 +104,7 @@
104 </table> 104 </table>
105 <span [fxShow]="source.timeseriesDatasource.isEmpty() | async" 105 <span [fxShow]="source.timeseriesDatasource.isEmpty() | async"
106 fxLayoutAlign="center center" 106 fxLayoutAlign="center center"
107 - class="no-data-found" translate>widget.no-data-found</span> 107 + class="no-data-found">{{ noDataDisplayMessageText }}</span>
108 </div> 108 </div>
109 <mat-divider *ngIf="displayPagination"></mat-divider> 109 <mat-divider *ngIf="displayPagination"></mat-divider>
110 <mat-paginator *ngIf="displayPagination" 110 <mat-paginator *ngIf="displayPagination"
@@ -59,6 +59,7 @@ import { @@ -59,6 +59,7 @@ import {
59 getCellStyleInfo, 59 getCellStyleInfo,
60 getRowStyleInfo, 60 getRowStyleInfo,
61 getTableCellButtonActions, 61 getTableCellButtonActions,
  62 + noDataMessage,
62 prepareTableCellButtonActions, 63 prepareTableCellButtonActions,
63 RowStyleInfo, 64 RowStyleInfo,
64 TableCellButtonActionDescriptor, 65 TableCellButtonActionDescriptor,
@@ -126,6 +127,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI @@ -126,6 +127,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
126 public textSearch: string = null; 127 public textSearch: string = null;
127 public sources: TimeseriesTableSource[]; 128 public sources: TimeseriesTableSource[];
128 public sourceIndex: number; 129 public sourceIndex: number;
  130 + public noDataDisplayMessageText: string;
129 private setCellButtonAction: boolean; 131 private setCellButtonAction: boolean;
130 132
131 private cellContentCache: Array<any> = []; 133 private cellContentCache: Array<any> = [];
@@ -251,6 +253,9 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI @@ -251,6 +253,9 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
251 } 253 }
252 this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3]; 254 this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
253 255
  256 + this.noDataDisplayMessageText =
  257 + noDataMessage(this.widgetConfig.noDataDisplayMessage, 'widget.no-data-found', this.utils, this.translate);
  258 +
254 let cssString = constructTableCssString(this.widgetConfig); 259 let cssString = constructTableCssString(this.widgetConfig);
255 260
256 const origBackgroundColor = this.widgetConfig.backgroundColor || 'rgb(255, 255, 255)'; 261 const origBackgroundColor = this.widgetConfig.backgroundColor || 'rgb(255, 255, 255)';
@@ -306,6 +306,12 @@ @@ -306,6 +306,12 @@
306 <input matInput formControlName="decimals" type="number" min="0" max="15" step="1"> 306 <input matInput formControlName="decimals" type="number" min="0" max="15" step="1">
307 </mat-form-field> 307 </mat-form-field>
308 </div> 308 </div>
  309 + <div fxLayout="row">
  310 + <mat-form-field fxFlex>
  311 + <mat-label translate>widget-config.no-data-display-message</mat-label>
  312 + <input matInput formControlName="noDataDisplayMessage">
  313 + </mat-form-field>
  314 + </div>
309 </ng-template> 315 </ng-template>
310 </mat-expansion-panel> 316 </mat-expansion-panel>
311 </mat-accordion> 317 </mat-accordion>
@@ -209,6 +209,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont @@ -209,6 +209,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
209 titleStyle: [null, []], 209 titleStyle: [null, []],
210 units: [null, []], 210 units: [null, []],
211 decimals: [null, [Validators.min(0), Validators.max(15), Validators.pattern(/^\d*$/)]], 211 decimals: [null, [Validators.min(0), Validators.max(15), Validators.pattern(/^\d*$/)]],
  212 + noDataDisplayMessage: [null, []],
212 showLegend: [null, []], 213 showLegend: [null, []],
213 legendConfig: [null, []] 214 legendConfig: [null, []]
214 }); 215 });
@@ -411,6 +412,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont @@ -411,6 +412,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
411 }, 412 },
412 units: config.units, 413 units: config.units,
413 decimals: config.decimals, 414 decimals: config.decimals,
  415 + noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '',
414 showLegend: isDefined(config.showLegend) ? config.showLegend : 416 showLegend: isDefined(config.showLegend) ? config.showLegend :
415 this.widgetType === widgetType.timeseries, 417 this.widgetType === widgetType.timeseries,
416 legendConfig: config.legendConfig || defaultLegendConfig(this.widgetType) 418 legendConfig: config.legendConfig || defaultLegendConfig(this.widgetType)
@@ -39,8 +39,7 @@ @@ -39,8 +39,7 @@
39 <div class="tb-absolute-fill tb-widget-no-data" *ngIf="displayNoData"> 39 <div class="tb-absolute-fill tb-widget-no-data" *ngIf="displayNoData">
40 <span fxLayoutAlign="center center" 40 <span fxLayoutAlign="center center"
41 style="display: flex;" 41 style="display: flex;"
42 - class="tb-absolute-fill"  
43 - translate>widget.no-data</span> 42 + class="tb-absolute-fill">{{ noDataDisplayMessageText }}</span>
44 </div> 43 </div>
45 <div class="tb-absolute-fill tb-widget-loading" [fxShow]="loadingData" fxLayout="column" fxLayoutAlign="center center"> 44 <div class="tb-absolute-fill tb-widget-loading" [fxShow]="loadingData" fxLayout="column" fxLayoutAlign="center center">
46 <mat-spinner color="accent" md-mode="indeterminate" diameter="40"></mat-spinner> 45 <mat-spinner color="accent" md-mode="indeterminate" diameter="40"></mat-spinner>
@@ -141,6 +141,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI @@ -141,6 +141,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
141 widgetErrorData: ExceptionData; 141 widgetErrorData: ExceptionData;
142 loadingData: boolean; 142 loadingData: boolean;
143 displayNoData = false; 143 displayNoData = false;
  144 + noDataDisplayMessageText: string;
144 145
145 displayLegend: boolean; 146 displayLegend: boolean;
146 legendConfig: LegendConfig; 147 legendConfig: LegendConfig;
@@ -360,6 +361,13 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI @@ -360,6 +361,13 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
360 setTimeout(() => { 361 setTimeout(() => {
361 this.dashboardWidget.updateWidgetParams(); 362 this.dashboardWidget.updateWidgetParams();
362 }, 0); 363 }, 0);
  364 +
  365 + const noDataDisplayMessage = this.widget.config.noDataDisplayMessage;
  366 + if (isNotEmptyStr(noDataDisplayMessage)) {
  367 + this.noDataDisplayMessageText = this.utils.customTranslation(noDataDisplayMessage, noDataDisplayMessage);
  368 + } else {
  369 + this.noDataDisplayMessageText = this.translate.instant('widget.no-data');
  370 + }
363 } 371 }
364 372
365 ngAfterViewInit(): void { 373 ngAfterViewInit(): void {
@@ -509,6 +509,7 @@ export interface WidgetConfig { @@ -509,6 +509,7 @@ export interface WidgetConfig {
509 titleStyle?: {[klass: string]: any}; 509 titleStyle?: {[klass: string]: any};
510 units?: string; 510 units?: string;
511 decimals?: number; 511 decimals?: number;
  512 + noDataDisplayMessage?: string;
512 actions?: {[actionSourceId: string]: Array<WidgetActionDescriptor>}; 513 actions?: {[actionSourceId: string]: Array<WidgetActionDescriptor>};
513 settings?: any; 514 settings?: any;
514 alarmSource?: Datasource; 515 alarmSource?: Datasource;
@@ -3081,7 +3081,8 @@ @@ -3081,7 +3081,8 @@
3081 "icon-color": "Icon color", 3081 "icon-color": "Icon color",
3082 "icon-size": "Icon size", 3082 "icon-size": "Icon size",
3083 "advanced-settings": "Advanced settings", 3083 "advanced-settings": "Advanced settings",
3084 - "data-settings": "Data settings" 3084 + "data-settings": "Data settings",
  3085 + "no-data-display-message": "\"No data to display\" alternative message"
3085 }, 3086 },
3086 "widget-type": { 3087 "widget-type": {
3087 "import": "Import widget type", 3088 "import": "Import widget type",
@@ -1679,7 +1679,8 @@ @@ -1679,7 +1679,8 @@
1679 "icon-color": "Цвет иконки", 1679 "icon-color": "Цвет иконки",
1680 "icon-size": "Размер иконки", 1680 "icon-size": "Размер иконки",
1681 "advanced-settings": "Расширенные настройки", 1681 "advanced-settings": "Расширенные настройки",
1682 - "data-settings": "Настройки данных" 1682 + "data-settings": "Настройки данных",
  1683 + "no-data-display-message": "\"Нет данных для отображения\" альтернативный текст"
1683 }, 1684 },
1684 "widget-type": { 1685 "widget-type": {
1685 "import": "Импортировать тип виджета", 1686 "import": "Импортировать тип виджета",
@@ -2251,7 +2251,8 @@ @@ -2251,7 +2251,8 @@
2251 "icon-color": "Колір іконки", 2251 "icon-color": "Колір іконки",
2252 "icon-size": "Розмір іконки", 2252 "icon-size": "Розмір іконки",
2253 "advanced-settings": "Розширені налаштування", 2253 "advanced-settings": "Розширені налаштування",
2254 - "data-settings": "Налаштування даних" 2254 + "data-settings": "Налаштування даних",
  2255 + "no-data-display-message": "\"Немає данних для відображення\" альтернативний текст"
2255 }, 2256 },
2256 "widget-type": { 2257 "widget-type": {
2257 "import": "Імпортувати тип віджета", 2258 "import": "Імпортувати тип віджета",