Browse Source

Merge pull request #12749 from Terny22/feature/table-pagination-improvments

Pagination settings improvements
pull/12883/head
Igor Kulikov 1 year ago
committed by GitHub
parent
commit
c28ef74b7c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 21
      ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts
  2. 23
      ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.ts
  3. 24
      ui-ngx/src/app/modules/home/components/widget/lib/rpc/persistent-table.component.ts
  4. 46
      ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html
  5. 34
      ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.ts
  6. 46
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html
  7. 34
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts
  8. 59
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html
  9. 30
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.ts
  10. 46
      ui-ngx/src/app/modules/home/components/widget/lib/settings/entity/entities-table-widget-settings.component.html
  11. 45
      ui-ngx/src/app/modules/home/components/widget/lib/settings/entity/entities-table-widget-settings.component.ts
  12. 15
      ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts
  13. 21
      ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts
  14. 5
      ui-ngx/src/assets/locale/locale.constant-en_US.json

21
ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts

@ -185,7 +185,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
public enableStickyHeader = true;
public enableStickyAction = false;
public showCellActionsMenu = true;
public pageSizeOptions;
public pageSizeOptions = [];
public pageLink: AlarmDataPageLink;
public sortOrderProperty: string;
public textSearchMode = false;
@ -213,7 +213,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
private allowClear = true;
public allowAssign = true;
private defaultPageSize = 10;
private defaultPageSize;
private defaultSortOrder = '-' + alarmFields.createdTime.value;
private contentsInfo: {[key: string]: CellContentInfo} = {};
@ -392,10 +392,25 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
this.rowStylesInfo = getRowStyleInfo(this.ctx, this.settings, 'alarm, ctx');
const pageSize = this.settings.defaultPageSize;
let pageStepIncrement = this.settings.pageStepIncrement;
let pageStepCount = this.settings.pageStepCount;
if (isDefined(pageSize) && isNumber(pageSize) && pageSize > 0) {
this.defaultPageSize = pageSize;
}
this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
if (!this.defaultPageSize) {
this.defaultPageSize = pageStepIncrement ?? 10;
}
if (!isDefinedAndNotNull(pageStepIncrement) || !isDefinedAndNotNull(pageStepCount)) {
pageStepIncrement = this.defaultPageSize;
pageStepCount = 3;
}
for (let i = 1; i <= pageStepCount; i++) {
this.pageSizeOptions.push(pageStepIncrement * i);
}
this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : 1024;
const alarmFilter = this.entityService.resolveAlarmFilter(this.widgetConfig.alarmFilterConfig, false);

23
ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.ts

@ -42,7 +42,7 @@ import {
import { IWidgetSubscription } from '@core/api/widget-api.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { deepClone, hashCode, isDefined, isNumber, isObject, isUndefined } from '@core/utils';
import { deepClone, hashCode, isDefined, isDefinedAndNotNull, isNumber, isObject, isUndefined } from '@core/utils';
import cssjs from '@core/css/css';
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
@ -139,7 +139,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
public enableStickyHeader = true;
public enableStickyAction = true;
public showCellActionsMenu = true;
public pageSizeOptions;
public pageSizeOptions = [];
public pageLink: EntityDataPageLink;
public sortOrderProperty: string;
public textSearchMode = false;
@ -161,7 +161,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
private widgetResize$: ResizeObserver;
private destroy$ = new Subject<void>();
private defaultPageSize = 10;
private defaultPageSize;
private defaultSortOrder = 'entityName';
private contentsInfo: {[key: string]: CellContentInfo} = {};
@ -311,10 +311,25 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
this.rowStylesInfo = getRowStyleInfo(this.ctx, this.settings, 'entity, ctx');
const pageSize = this.settings.defaultPageSize;
let pageStepIncrement = this.settings.pageStepIncrement;
let pageStepCount = this.settings.pageStepCount;
if (isDefined(pageSize) && isNumber(pageSize) && pageSize > 0) {
this.defaultPageSize = pageSize;
}
this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
if (!this.defaultPageSize) {
this.defaultPageSize = pageStepIncrement ?? 10;
}
if (!isDefinedAndNotNull(pageStepIncrement) || !isDefinedAndNotNull(pageStepCount)) {
pageStepIncrement = this.defaultPageSize;
pageStepCount = 3;
}
for (let i = 1; i <= pageStepCount; i++) {
this.pageSizeOptions.push(pageStepIncrement * i);
}
this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : 1024;
this.noDataDisplayMessageText =

24
ui-ngx/src/app/modules/home/components/widget/lib/rpc/persistent-table.component.ts

@ -43,7 +43,7 @@ import {
import cssjs from '@core/css/css';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { hashCode, isDefined, isNumber, parseHttpErrorMessage } from '@core/utils';
import { hashCode, isDefined, isDefinedAndNotNull, isNumber, parseHttpErrorMessage } from '@core/utils';
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { emptyPageData, PageData } from '@shared/models/page/page-data';
import {
@ -114,7 +114,7 @@ export class PersistentTableComponent extends PageComponent implements OnInit, O
private subscription: IWidgetSubscription;
private enableFilterAction = true;
private allowSendRequest = true;
private defaultPageSize = 10;
private defaultPageSize;
private defaultSortOrder = '-createdTime';
private rpcStatusFilter: RpcStatus;
private displayDetails = true;
@ -130,7 +130,7 @@ export class PersistentTableComponent extends PageComponent implements OnInit, O
public enableStickyHeader = true;
public enableStickyAction = true;
public pageLink: PageLink;
public pageSizeOptions;
public pageSizeOptions = [];
public actionCellButtonAction: PersistentTableWidgetActionDescriptor[] = [];
public displayedColumns: string[];
public hidePageSize = false;
@ -207,10 +207,26 @@ export class PersistentTableComponent extends PageComponent implements OnInit, O
this.displayedColumns = [...this.displayTableColumns];
const pageSize = this.settings.defaultPageSize;
let pageStepIncrement = this.settings.pageStepIncrement;
let pageStepCount = this.settings.pageStepCount;
if (isDefined(pageSize) && isNumber(pageSize) && pageSize > 0) {
this.defaultPageSize = pageSize;
}
this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
if (!this.defaultPageSize) {
this.defaultPageSize = pageStepIncrement ?? 10;
}
if (!isDefinedAndNotNull(pageStepIncrement) || !isDefinedAndNotNull(pageStepCount)) {
pageStepIncrement = this.defaultPageSize;
pageStepCount = 3;
}
for (let i = 1; i <= pageStepCount; i++) {
this.pageSizeOptions.push(pageStepIncrement * i);
}
if (this.settings.defaultSortOrder && this.settings.defaultSortOrder.length) {
this.defaultSortOrder = this.settings.defaultSortOrder;
}

46
ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html

@ -94,10 +94,52 @@
<mat-slide-toggle class="mat-slide" formControlName="displayPagination">
{{ 'widgets.table.display-pagination' | translate }}
</mat-slide-toggle>
<div class="tb-form-row space-between column-xs">
<div class="fixed-title-width">{{ 'widgets.table.page-step-settings' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2">
<div class="tb-small-label" translate>widgets.table.page-step-increment</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepIncrement" type="number" min="1" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(alarmsTableWidgetSettingsForm.get('pageStepIncrement').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-increment-format-message') | translate"
*ngIf="alarmsTableWidgetSettingsForm.get('pageStepIncrement').invalid
&& alarmsTableWidgetSettingsForm.get('pageStepIncrement').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
<mat-divider vertical></mat-divider>
<div class="tb-small-label" translate>widgets.table.page-step-count</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepCount" type="number" min="1" max="100" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(alarmsTableWidgetSettingsForm.get('pageStepCount').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-count-format-message') | translate"
*ngIf="alarmsTableWidgetSettingsForm.get('pageStepCount').invalid
&& alarmsTableWidgetSettingsForm.get('pageStepCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.table.default-page-size</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="defaultPageSize" type="number" min="1" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="defaultPageSize" placeholder="{{ 'widget-config.set' | translate }}">
<mat-option *ngFor="let size of pageStepSizeValues" [value]="size">
{{ size }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>

34
ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.ts

@ -19,6 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { buildPageStepSizeValues } from '@home/components/widget/lib/table-widget.models';
@Component({
selector: 'tb-alarms-table-widget-settings',
@ -28,6 +29,7 @@ import { AppState } from '@core/core.state';
export class AlarmsTableWidgetSettingsComponent extends WidgetSettingsComponent {
alarmsTableWidgetSettingsForm: UntypedFormGroup;
pageStepSizeValues = [];
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
@ -56,6 +58,8 @@ export class AlarmsTableWidgetSettingsComponent extends WidgetSettingsComponent
displayActivity: true,
displayPagination: true,
defaultPageSize: 10,
pageStepIncrement: null,
pageStepCount: 3,
defaultSortOrder: '-createdTime',
useRowStyleFunction: false,
rowStyleFunction: ''
@ -80,31 +84,45 @@ export class AlarmsTableWidgetSettingsComponent extends WidgetSettingsComponent
displayActivity: [settings.displayActivity, []],
displayPagination: [settings.displayPagination, []],
defaultPageSize: [settings.defaultPageSize, [Validators.min(1)]],
pageStepCount: [settings.pageStepCount ?? 3, [Validators.min(1), Validators.max(100),
Validators.required, Validators.pattern(/^\d*$/)]],
pageStepIncrement: [settings.pageStepIncrement ?? settings.defaultPageSize,
[Validators.min(1), Validators.required, Validators.pattern(/^\d*$/)]],
defaultSortOrder: [settings.defaultSortOrder, []],
useRowStyleFunction: [settings.useRowStyleFunction, []],
rowStyleFunction: [settings.rowStyleFunction, [Validators.required]]
});
this.pageStepSizeValues = buildPageStepSizeValues(this.alarmsTableWidgetSettingsForm.get('pageStepCount').value,
this.alarmsTableWidgetSettingsForm.get('pageStepIncrement').value);
}
protected validatorTriggers(): string[] {
return ['useRowStyleFunction', 'displayPagination'];
return ['useRowStyleFunction', 'displayPagination', 'pageStepCount', 'pageStepIncrement'];
}
protected updateValidators(emitEvent: boolean) {
protected updateValidators(emitEvent: boolean, trigger: string) {
if (trigger === 'pageStepCount' || trigger === 'pageStepIncrement') {
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').reset();
this.pageStepSizeValues = buildPageStepSizeValues(this.alarmsTableWidgetSettingsForm.get('pageStepCount').value,
this.alarmsTableWidgetSettingsForm.get('pageStepIncrement').value);
return;
}
const useRowStyleFunction: boolean = this.alarmsTableWidgetSettingsForm.get('useRowStyleFunction').value;
const displayPagination: boolean = this.alarmsTableWidgetSettingsForm.get('displayPagination').value;
if (useRowStyleFunction) {
this.alarmsTableWidgetSettingsForm.get('rowStyleFunction').enable();
this.alarmsTableWidgetSettingsForm.get('rowStyleFunction').enable({emitEvent});
} else {
this.alarmsTableWidgetSettingsForm.get('rowStyleFunction').disable();
this.alarmsTableWidgetSettingsForm.get('rowStyleFunction').disable({emitEvent});
}
if (displayPagination) {
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').enable();
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').enable({emitEvent});
this.alarmsTableWidgetSettingsForm.get('pageStepCount').enable({emitEvent: false});
this.alarmsTableWidgetSettingsForm.get('pageStepIncrement').enable({emitEvent: false});
} else {
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').disable();
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').disable({emitEvent});
this.alarmsTableWidgetSettingsForm.get('pageStepCount').disable({emitEvent: false});
this.alarmsTableWidgetSettingsForm.get('pageStepIncrement').disable({emitEvent: false});
}
this.alarmsTableWidgetSettingsForm.get('rowStyleFunction').updateValueAndValidity({emitEvent});
this.alarmsTableWidgetSettingsForm.get('defaultPageSize').updateValueAndValidity({emitEvent});
}
}

46
ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html

@ -61,10 +61,52 @@
<mat-slide-toggle class="mat-slide" formControlName="displayPagination">
{{ 'widgets.table.display-pagination' | translate }}
</mat-slide-toggle>
<div class="tb-form-row space-between column-xs">
<div class="fixed-title-width">{{ 'widgets.table.page-step-settings' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2">
<div class="tb-small-label" translate>widgets.table.page-step-increment</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepIncrement" type="number" min="1" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(timeseriesTableWidgetSettingsForm.get('pageStepIncrement').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-increment-format-message') | translate"
*ngIf="timeseriesTableWidgetSettingsForm.get('pageStepIncrement').invalid
&& timeseriesTableWidgetSettingsForm.get('pageStepIncrement').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
<mat-divider vertical></mat-divider>
<div class="tb-small-label" translate>widgets.table.page-step-count</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepCount" type="number" min="1" max="100" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(timeseriesTableWidgetSettingsForm.get('pageStepCount').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-count-format-message') | translate"
*ngIf="timeseriesTableWidgetSettingsForm.get('pageStepCount').invalid
&& timeseriesTableWidgetSettingsForm.get('pageStepCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.table.default-page-size</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="defaultPageSize" type="number" min="1" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="defaultPageSize" placeholder="{{ 'widget-config.set' | translate }}">
<mat-option *ngFor="let size of pageStepSizeValues" [value]="size">
{{ size }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>

34
ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts

@ -19,6 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { buildPageStepSizeValues } from '@home/components/widget/lib/table-widget.models';
@Component({
selector: 'tb-timeseries-table-widget-settings',
@ -28,6 +29,7 @@ import { AppState } from '@core/core.state';
export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsComponent {
timeseriesTableWidgetSettingsForm: UntypedFormGroup;
pageStepSizeValues = [];
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
@ -51,6 +53,8 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
displayPagination: true,
useEntityLabel: false,
defaultPageSize: 10,
pageStepIncrement: null,
pageStepCount: 3,
hideEmptyLines: false,
disableStickyHeader: false,
useRowStyleFunction: false,
@ -77,32 +81,46 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
displayPagination: [settings.displayPagination, []],
useEntityLabel: [settings.useEntityLabel, []],
defaultPageSize: [settings.defaultPageSize, [Validators.min(1)]],
pageStepCount: [settings.pageStepCount ?? 3, [Validators.min(1), Validators.max(100),
Validators.required, Validators.pattern(/^\d*$/)]],
pageStepIncrement: [settings.pageStepIncrement ?? settings.defaultPageSize,
[Validators.min(1), Validators.required, Validators.pattern(/^\d*$/)]],
hideEmptyLines: [settings.hideEmptyLines, []],
disableStickyHeader: [settings.disableStickyHeader, []],
useRowStyleFunction: [settings.useRowStyleFunction, []],
rowStyleFunction: [settings.rowStyleFunction, [Validators.required]]
});
this.pageStepSizeValues = buildPageStepSizeValues(this.timeseriesTableWidgetSettingsForm.get('pageStepCount').value,
this.timeseriesTableWidgetSettingsForm.get('pageStepIncrement').value);
}
protected validatorTriggers(): string[] {
return ['useRowStyleFunction', 'displayPagination'];
return ['useRowStyleFunction', 'displayPagination', 'pageStepCount', 'pageStepIncrement'];
}
protected updateValidators(emitEvent: boolean) {
protected updateValidators(emitEvent: boolean, trigger: string) {
if (trigger === 'pageStepCount' || trigger === 'pageStepIncrement') {
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').reset();
this.pageStepSizeValues = buildPageStepSizeValues(this.timeseriesTableWidgetSettingsForm.get('pageStepCount').value,
this.timeseriesTableWidgetSettingsForm.get('pageStepIncrement').value);
return;
}
const useRowStyleFunction: boolean = this.timeseriesTableWidgetSettingsForm.get('useRowStyleFunction').value;
const displayPagination: boolean = this.timeseriesTableWidgetSettingsForm.get('displayPagination').value;
if (useRowStyleFunction) {
this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').enable();
this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').enable({emitEvent});
} else {
this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').disable();
this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').disable({emitEvent});
}
if (displayPagination) {
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').enable();
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').enable({emitEvent});
this.timeseriesTableWidgetSettingsForm.get('pageStepCount').enable({emitEvent: false});
this.timeseriesTableWidgetSettingsForm.get('pageStepIncrement').enable({emitEvent: false});
} else {
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').disable();
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').disable({emitEvent});
this.timeseriesTableWidgetSettingsForm.get('pageStepCount').disable({emitEvent: false});
this.timeseriesTableWidgetSettingsForm.get('pageStepIncrement').disable({emitEvent: false});
}
this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').updateValueAndValidity({emitEvent});
this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').updateValueAndValidity({emitEvent});
}
}

59
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html

@ -43,15 +43,60 @@
<mat-slide-toggle formControlName="allowDelete">
{{ 'widgets.persistent-table.allow-delete-request' | translate }}
</mat-slide-toggle>
<section class="flex flex-col gap-2 gt-xs:flex-row gt-xs:items-center gt-xs:justify-start">
<mat-slide-toggle class="flex-1" formControlName="displayPagination">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>widgets.table.pagination</div>
<mat-slide-toggle class="mat-slide" formControlName="displayPagination">
{{ 'widgets.table.display-pagination' | translate }}
</mat-slide-toggle>
<mat-form-field class="mat-block flex-1">
<mat-label translate>widgets.table.default-page-size</mat-label>
<input matInput type="number" min="1" step="1" formControlName="defaultPageSize">
</mat-form-field>
</section>
<div class="tb-form-row space-between column-xs">
<div class="fixed-title-width">{{ 'widgets.table.page-step-settings' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2">
<div class="tb-small-label" translate>widgets.table.page-step-increment</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepIncrement" type="number" min="1" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(persistentTableWidgetSettingsForm.get('pageStepIncrement').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-increment-format-message') | translate"
*ngIf="persistentTableWidgetSettingsForm.get('pageStepIncrement').invalid
&& persistentTableWidgetSettingsForm.get('pageStepIncrement').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
<mat-divider vertical></mat-divider>
<div class="tb-small-label" translate>widgets.table.page-step-count</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepCount" type="number" min="1" max="100" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(persistentTableWidgetSettingsForm.get('pageStepCount').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-count-format-message') | translate"
*ngIf="persistentTableWidgetSettingsForm.get('pageStepCount').invalid
&& persistentTableWidgetSettingsForm.get('pageStepCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.table.default-page-size</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="defaultPageSize" placeholder="{{ 'widget-config.set' | translate }}">
<mat-option *ngFor="let size of pageStepSizeValues" [value]="size">
{{ size }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<mat-form-field class="mat-block flex-1">
<mat-label translate>widgets.table.default-sort-order</mat-label>
<input matInput formControlName="defaultSortOrder">

30
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.ts

@ -27,6 +27,7 @@ import { MatChipInputEvent, MatChipGrid } from '@angular/material/chips';
import { MatAutocomplete, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
import { map, mergeMap, share, startWith } from 'rxjs/operators';
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
import { buildPageStepSizeValues } from '@home/components/widget/lib/table-widget.models';
interface DisplayColumn {
name: string;
@ -57,6 +58,8 @@ export class PersistentTableWidgetSettingsComponent extends WidgetSettingsCompon
persistentTableWidgetSettingsForm: UntypedFormGroup;
pageStepSizeValues = [];
filteredDisplayColumns: Observable<Array<DisplayColumn>>;
columnSearchText = '';
@ -94,6 +97,8 @@ export class PersistentTableWidgetSettingsComponent extends WidgetSettingsCompon
displayPagination: true,
defaultPageSize: 10,
pageStepIncrement: null,
pageStepCount: 3,
defaultSortOrder: '-createdTime',
displayColumns: ['rpcId', 'messageType', 'status', 'method', 'createdTime', 'expirationTime']
@ -110,9 +115,15 @@ export class PersistentTableWidgetSettingsComponent extends WidgetSettingsCompon
displayDetails: [settings.displayDetails, []],
displayPagination: [settings.displayPagination, []],
defaultPageSize: [settings.defaultPageSize, [Validators.min(1)]],
pageStepCount: [settings.pageStepCount ?? 3, [Validators.min(1), Validators.max(100),
Validators.required, Validators.pattern(/^\d*$/)]],
pageStepIncrement: [settings.pageStepIncrement ?? settings.defaultPageSize,
[Validators.min(1), Validators.required, Validators.pattern(/^\d*$/)]],
defaultSortOrder: [settings.defaultSortOrder, []],
displayColumns: [settings.displayColumns, [Validators.required]]
});
this.pageStepSizeValues = buildPageStepSizeValues(this.persistentTableWidgetSettingsForm.get('pageStepCount').value,
this.persistentTableWidgetSettingsForm.get('pageStepIncrement').value);
}
public validateSettings(): boolean {
@ -122,17 +133,26 @@ export class PersistentTableWidgetSettingsComponent extends WidgetSettingsCompon
}
protected validatorTriggers(): string[] {
return ['displayPagination'];
return ['displayPagination', 'pageStepCount', 'pageStepIncrement'];
}
protected updateValidators(emitEvent: boolean) {
protected updateValidators(emitEvent: boolean, trigger: string) {
if (trigger === 'pageStepCount' || trigger === 'pageStepIncrement') {
this.persistentTableWidgetSettingsForm.get('defaultPageSize').reset();
this.pageStepSizeValues = buildPageStepSizeValues(this.persistentTableWidgetSettingsForm.get('pageStepCount').value,
this.persistentTableWidgetSettingsForm.get('pageStepIncrement').value);
return;
}
const displayPagination: boolean = this.persistentTableWidgetSettingsForm.get('displayPagination').value;
if (displayPagination) {
this.persistentTableWidgetSettingsForm.get('defaultPageSize').enable();
this.persistentTableWidgetSettingsForm.get('defaultPageSize').enable({emitEvent});
this.persistentTableWidgetSettingsForm.get('pageStepCount').enable({emitEvent: false});
this.persistentTableWidgetSettingsForm.get('pageStepIncrement').enable({emitEvent: false});
} else {
this.persistentTableWidgetSettingsForm.get('defaultPageSize').disable();
this.persistentTableWidgetSettingsForm.get('defaultPageSize').disable({emitEvent});
this.persistentTableWidgetSettingsForm.get('pageStepCount').disable({emitEvent: false});
this.persistentTableWidgetSettingsForm.get('pageStepIncrement').disable({emitEvent: false});
}
this.persistentTableWidgetSettingsForm.get('defaultPageSize').updateValueAndValidity({emitEvent});
}
private fetchColumns(searchText?: string): Observable<Array<DisplayColumn>> {

46
ui-ngx/src/app/modules/home/components/widget/lib/settings/entity/entities-table-widget-settings.component.html

@ -91,10 +91,52 @@
<mat-slide-toggle class="mat-slide" formControlName="displayPagination">
{{ 'widgets.table.display-pagination' | translate }}
</mat-slide-toggle>
<div class="tb-form-row space-between column-xs">
<div class="fixed-title-width">{{ 'widgets.table.page-step-settings' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2">
<div class="tb-small-label" translate>widgets.table.page-step-increment</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepIncrement" type="number" min="1" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(entitiesTableWidgetSettingsForm.get('pageStepIncrement').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-increment-format-message') | translate"
*ngIf="entitiesTableWidgetSettingsForm.get('pageStepIncrement').invalid
&& entitiesTableWidgetSettingsForm.get('pageStepIncrement').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
<mat-divider vertical></mat-divider>
<div class="tb-small-label" translate>widgets.table.page-step-count</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="pageStepCount" type="number" min="1" max="100" step="1" required
placeholder="{{ 'widget-config.set' | translate }}">
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="(entitiesTableWidgetSettingsForm.get('pageStepCount').hasError('required')
? 'widgets.value-source.value-required'
: 'widgets.table.page-step-count-format-message') | translate"
*ngIf="entitiesTableWidgetSettingsForm.get('pageStepCount').invalid
&& entitiesTableWidgetSettingsForm.get('pageStepCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.table.default-page-size</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="defaultPageSize" type="number" min="1" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="defaultPageSize" placeholder="{{ 'widget-config.set' | translate }}">
<mat-option *ngFor="let size of pageStepSizeValues" [value]="size">
{{ size }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>

45
ui-ngx/src/app/modules/home/components/widget/lib/settings/entity/entities-table-widget-settings.component.ts

@ -19,6 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { buildPageStepSizeValues } from '@home/components/widget/lib/table-widget.models';
@Component({
selector: 'tb-entities-table-widget-settings',
@ -28,6 +29,7 @@ import { AppState } from '@core/core.state';
export class EntitiesTableWidgetSettingsComponent extends WidgetSettingsComponent {
entitiesTableWidgetSettingsForm: UntypedFormGroup;
pageStepSizeValues = [];
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
@ -54,6 +56,8 @@ export class EntitiesTableWidgetSettingsComponent extends WidgetSettingsComponen
displayEntityType: true,
displayPagination: true,
defaultPageSize: 10,
pageStepIncrement: null,
pageStepCount: 3,
defaultSortOrder: 'entityName',
useRowStyleFunction: false,
rowStyleFunction: ''
@ -76,45 +80,58 @@ export class EntitiesTableWidgetSettingsComponent extends WidgetSettingsComponen
displayEntityType: [settings.displayEntityType, []],
displayPagination: [settings.displayPagination, []],
defaultPageSize: [settings.defaultPageSize, [Validators.min(1)]],
pageStepCount: [settings.pageStepCount ?? 3, [Validators.min(1), Validators.max(100),
Validators.required, Validators.pattern(/^\d*$/)]],
pageStepIncrement: [settings.pageStepIncrement ?? settings.defaultPageSize,
[Validators.min(1), Validators.required, Validators.pattern(/^\d*$/)]],
defaultSortOrder: [settings.defaultSortOrder, []],
useRowStyleFunction: [settings.useRowStyleFunction, []],
rowStyleFunction: [settings.rowStyleFunction, [Validators.required]]
});
this.pageStepSizeValues = buildPageStepSizeValues(this.entitiesTableWidgetSettingsForm.get('pageStepCount').value,
this.entitiesTableWidgetSettingsForm.get('pageStepIncrement').value);
}
protected validatorTriggers(): string[] {
return ['useRowStyleFunction', 'displayPagination', 'displayEntityName', 'displayEntityLabel'];
return ['useRowStyleFunction', 'displayPagination', 'displayEntityName', 'displayEntityLabel', 'pageStepCount',
'pageStepIncrement'];
}
protected updateValidators(emitEvent: boolean) {
protected updateValidators(emitEvent: boolean, trigger: string) {
if (trigger === 'pageStepCount' || trigger === 'pageStepIncrement') {
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').reset();
this.pageStepSizeValues = buildPageStepSizeValues(this.entitiesTableWidgetSettingsForm.get('pageStepCount').value,
this.entitiesTableWidgetSettingsForm.get('pageStepIncrement').value);
return;
}
const useRowStyleFunction: boolean = this.entitiesTableWidgetSettingsForm.get('useRowStyleFunction').value;
const displayPagination: boolean = this.entitiesTableWidgetSettingsForm.get('displayPagination').value;
const displayEntityName: boolean = this.entitiesTableWidgetSettingsForm.get('displayEntityName').value;
const displayEntityLabel: boolean = this.entitiesTableWidgetSettingsForm.get('displayEntityLabel').value;
if (useRowStyleFunction) {
this.entitiesTableWidgetSettingsForm.get('rowStyleFunction').enable();
this.entitiesTableWidgetSettingsForm.get('rowStyleFunction').enable({emitEvent});
} else {
this.entitiesTableWidgetSettingsForm.get('rowStyleFunction').disable();
this.entitiesTableWidgetSettingsForm.get('rowStyleFunction').disable({emitEvent});
}
if (displayPagination) {
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').enable();
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').enable({emitEvent});
this.entitiesTableWidgetSettingsForm.get('pageStepCount').enable({emitEvent: false});
this.entitiesTableWidgetSettingsForm.get('pageStepIncrement').enable({emitEvent: false});
} else {
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').disable();
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').disable({emitEvent});
this.entitiesTableWidgetSettingsForm.get('pageStepCount').disable({emitEvent: false});
this.entitiesTableWidgetSettingsForm.get('pageStepIncrement').disable({emitEvent: false});
}
if (displayEntityName) {
this.entitiesTableWidgetSettingsForm.get('entityNameColumnTitle').enable();
this.entitiesTableWidgetSettingsForm.get('entityNameColumnTitle').enable({emitEvent});
} else {
this.entitiesTableWidgetSettingsForm.get('entityNameColumnTitle').disable();
this.entitiesTableWidgetSettingsForm.get('entityNameColumnTitle').disable({emitEvent});
}
if (displayEntityLabel) {
this.entitiesTableWidgetSettingsForm.get('entityLabelColumnTitle').enable();
this.entitiesTableWidgetSettingsForm.get('entityLabelColumnTitle').enable({emitEvent});
} else {
this.entitiesTableWidgetSettingsForm.get('entityLabelColumnTitle').disable();
this.entitiesTableWidgetSettingsForm.get('entityLabelColumnTitle').disable({emitEvent});
}
this.entitiesTableWidgetSettingsForm.get('rowStyleFunction').updateValueAndValidity({emitEvent});
this.entitiesTableWidgetSettingsForm.get('defaultPageSize').updateValueAndValidity({emitEvent});
this.entitiesTableWidgetSettingsForm.get('entityNameColumnTitle').updateValueAndValidity({emitEvent});
this.entitiesTableWidgetSettingsForm.get('entityLabelColumnTitle').updateValueAndValidity({emitEvent});
}
}

15
ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts

@ -16,7 +16,7 @@
import { EntityId } from '@shared/models/id/entity-id';
import { DataKey, FormattedData, WidgetActionDescriptor, WidgetConfig } from '@shared/models/widget.models';
import { getDescendantProp, isDefined, isNotEmptyStr } from '@core/utils';
import { getDescendantProp, isDefined, isDefinedAndNotNull, isNotEmptyStr } from '@core/utils';
import { AlarmDataInfo, alarmFields } from '@shared/models/alarm.models';
import tinycolor from 'tinycolor2';
import { Direction } from '@shared/models/page/sort-order';
@ -47,6 +47,8 @@ export interface TableWidgetSettings {
enableStickyHeader: boolean;
displayPagination: boolean;
defaultPageSize: number;
pageStepIncrement: number;
pageStepCount: number;
useRowStyleFunction: boolean;
rowStyleFunction?: TbFunction;
reserveSpaceForHiddenAction?: boolean;
@ -558,3 +560,14 @@ export function getHeaderTitle(dataKey: DataKey, keySettings: TableWidgetDataKey
}
return dataKey.label;
}
export function buildPageStepSizeValues(pageStepCount: number, pageStepIncrement: number): Array<number> {
const pageSteps: Array<number> = [];
if (isDefinedAndNotNull(pageStepCount) && pageStepCount > 0 && pageStepCount <= 100 &&
isDefinedAndNotNull(pageStepIncrement) && pageStepIncrement > 0) {
for (let i = 1; i <= pageStepCount; i++) {
pageSteps.push(pageStepIncrement * i);
}
}
return pageSteps;
}

21
ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts

@ -173,7 +173,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
public enableStickyHeader = true;
public enableStickyAction = true;
public showCellActionsMenu = true;
public pageSizeOptions;
public pageSizeOptions = [];
public textSearchMode = false;
public hidePageSize = false;
public sources: TimeseriesTableSource[];
@ -192,7 +192,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
private latestData: Array<DatasourceData>;
private datasources: Array<Datasource>;
private defaultPageSize = 10;
private defaultPageSize;
private defaultSortOrder = '-0';
private hideEmptyLines = false;
public showTimestamp = true;
@ -352,10 +352,25 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
this.rowStylesInfo = getRowStyleInfo(this.ctx, this.settings, 'rowData, ctx');
const pageSize = this.settings.defaultPageSize;
let pageStepIncrement = this.settings.pageStepIncrement;
let pageStepCount = this.settings.pageStepCount;
if (isDefined(pageSize) && isNumber(pageSize) && pageSize > 0) {
this.defaultPageSize = pageSize;
}
this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
if (!this.defaultPageSize) {
this.defaultPageSize = pageStepIncrement ?? 10;
}
if (!isDefinedAndNotNull(pageStepIncrement) || !isDefinedAndNotNull(pageStepCount)) {
pageStepIncrement = this.defaultPageSize;
pageStepCount = 3;
}
for (let i = 1; i <= pageStepCount; i++) {
this.pageSizeOptions.push(pageStepIncrement * i);
}
this.noDataDisplayMessageText =
noDataMessage(this.widgetConfig.noDataDisplayMessage, 'widget.no-data-found', this.utils, this.translate);

5
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -8550,6 +8550,11 @@
"display-timestamp": "Timestamp",
"display-pagination": "Display pagination",
"default-page-size": "Default page size",
"page-step-settings": "Page step settings",
"page-step-count": "Number of steps",
"page-step-increment": "Step increment",
"page-step-count-format-message": "Should be an integer value, in the range from 1 to 100.",
"page-step-increment-format-message": "Should be an integer value, greater or equal to 1.",
"use-entity-label-tab-name": "Use entity label in tab name",
"hide-empty-lines": "Hide empty lines",
"row-style": "Row style",

Loading…
Cancel
Save