Commit 6417ef7cd0b25f46372706fb7a23e6e714fc3dca
Committed by
GitHub
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
Showing
15 changed files
with
52 additions
and
8 deletions
@@ -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": "Імпортувати тип віджета", |