Merge pull request #8571 from ArtemDzhereleiko/AD/imp/timeseries-table-widget-column-visability

Added columns visibility for Timeseries table
This commit is contained in:
Igor Kulikov 2023-06-06 17:55:29 +03:00 committed by GitHub
commit 7bca490ae7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 175 additions and 9 deletions

View File

@ -66,4 +66,29 @@
</ng-template>
</mat-expansion-panel>
</fieldset>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.table.default-column-visibility</mat-label>
<mat-select formControlName="defaultColumnVisibility">
<mat-option [value]="'visible'">
{{ 'widgets.table.column-visibility-visible' | translate }}
</mat-option>
<mat-option [value]="'hidden'">
{{ 'widgets.table.column-visibility-hidden' | translate }}
</mat-option>
<mat-option [value]="'hidden-mobile'">
{{ 'widgets.table.column-visibility-hidden-mobile' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.table.column-selection-to-display</mat-label>
<mat-select formControlName="columnSelectionToDisplay">
<mat-option [value]="'enabled'">
{{ 'widgets.table.column-selection-to-display-enabled' | translate }}
</mat-option>
<mat-option [value]="'disabled'">
{{ 'widgets.table.column-selection-to-display-disabled' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</section>

View File

@ -43,7 +43,9 @@ export class TimeseriesTableKeySettingsComponent extends WidgetSettingsComponent
useCellStyleFunction: false,
cellStyleFunction: '',
useCellContentFunction: false,
cellContentFunction: ''
cellContentFunction: '',
defaultColumnVisibility: 'visible',
columnSelectionToDisplay: 'enabled'
};
}
@ -53,6 +55,8 @@ export class TimeseriesTableKeySettingsComponent extends WidgetSettingsComponent
cellStyleFunction: [settings.cellStyleFunction, [Validators.required]],
useCellContentFunction: [settings.useCellContentFunction, []],
cellContentFunction: [settings.cellContentFunction, [Validators.required]],
defaultColumnVisibility: [settings.defaultColumnVisibility, []],
columnSelectionToDisplay: [settings.columnSelectionToDisplay, []],
});
}

View File

@ -73,4 +73,29 @@
</ng-template>
</mat-expansion-panel>
</fieldset>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.table.default-column-visibility</mat-label>
<mat-select formControlName="defaultColumnVisibility">
<mat-option [value]="'visible'">
{{ 'widgets.table.column-visibility-visible' | translate }}
</mat-option>
<mat-option [value]="'hidden'">
{{ 'widgets.table.column-visibility-hidden' | translate }}
</mat-option>
<mat-option [value]="'hidden-mobile'">
{{ 'widgets.table.column-visibility-hidden-mobile' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.table.column-selection-to-display</mat-label>
<mat-select formControlName="columnSelectionToDisplay">
<mat-option [value]="'enabled'">
{{ 'widgets.table.column-selection-to-display-enabled' | translate }}
</mat-option>
<mat-option [value]="'disabled'">
{{ 'widgets.table.column-selection-to-display-disabled' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</section>

View File

@ -44,7 +44,9 @@ export class TimeseriesTableLatestKeySettingsComponent extends WidgetSettingsCom
useCellStyleFunction: false,
cellStyleFunction: '',
useCellContentFunction: false,
cellContentFunction: ''
cellContentFunction: '',
defaultColumnVisibility: 'visible',
columnSelectionToDisplay: 'enabled'
};
}
@ -56,6 +58,8 @@ export class TimeseriesTableLatestKeySettingsComponent extends WidgetSettingsCom
cellStyleFunction: [settings.cellStyleFunction, [Validators.required]],
useCellContentFunction: [settings.useCellContentFunction, []],
cellContentFunction: [settings.cellContentFunction, [Validators.required]],
defaultColumnVisibility: [settings.defaultColumnVisibility, []],
columnSelectionToDisplay: [settings.columnSelectionToDisplay, []],
});
}

View File

@ -23,6 +23,9 @@
<mat-checkbox formControlName="enableSearch">
{{ 'widgets.table.enable-search' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="enableSelectColumnDisplay">
{{ 'widgets.table.enable-select-column-display' | translate }}
</mat-checkbox>
</section>
<section fxLayout="column" fxFlex>
<mat-checkbox formControlName="enableStickyHeader">

View File

@ -41,6 +41,7 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
protected defaultSettings(): WidgetSettings {
return {
enableSearch: true,
enableSelectColumnDisplay: true,
enableStickyHeader: true,
enableStickyAction: true,
reserveSpaceForHiddenAction: 'true',
@ -59,6 +60,7 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
protected onSettingsSet(settings: WidgetSettings) {
this.timeseriesTableWidgetSettingsForm = this.fb.group({
enableSearch: [settings.enableSearch, []],
enableSelectColumnDisplay: [settings.enableSelectColumnDisplay, []],
enableStickyHeader: [settings.enableStickyHeader, []],
enableStickyAction: [settings.enableStickyAction, []],
reserveSpaceForHiddenAction: [settings.reserveSpaceForHiddenAction, []],

View File

@ -31,6 +31,7 @@ type ColumnSelectionOptions = 'enabled' | 'disabled';
export interface TableWidgetSettings {
enableSearch: boolean;
enableSelectColumnDisplay: boolean;
enableStickyAction: boolean;
enableStickyHeader: boolean;
displayPagination: boolean;

View File

@ -19,9 +19,12 @@ import {
ChangeDetectorRef,
Component,
ElementRef,
Injector,
Input,
OnDestroy,
OnInit,
QueryList,
StaticProvider,
ViewChild,
ViewChildren,
ViewContainerRef
@ -64,8 +67,9 @@ import {
CellStyleInfo,
checkHasActions,
constructTableCssString,
DisplayColumn,
getCellContentInfo,
getCellStyleInfo,
getCellStyleInfo, getColumnDefaultVisibility, getColumnSelectionAvailability,
getRowStyleInfo,
getTableCellButtonActions,
noDataMessage,
@ -75,12 +79,17 @@ import {
TableWidgetDataKeySettings,
TableWidgetSettings
} from '@home/components/widget/lib/table-widget.models';
import { Overlay } from '@angular/cdk/overlay';
import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { SubscriptionEntityInfo } from '@core/api/widget-api.models';
import { DatePipe } from '@angular/common';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ResizeObserver } from '@juggle/resize-observer';
import { hidePageSizePixelValue } from '@shared/models/constants';
import {
DISPLAY_COLUMNS_PANEL_DATA,
DisplayColumnsPanelComponent
} from '@home/components/widget/lib/display-columns-panel.component';
import { ComponentPortal } from '@angular/cdk/portal';
export interface TimeseriesTableWidgetSettings extends TableWidgetSettings {
showTimestamp: boolean;
@ -105,6 +114,8 @@ interface TimeseriesHeader {
dataKey: DataKey;
sortable: boolean;
show: boolean;
columnDefaultVisibility?: boolean;
columnSelectionAvailability?: boolean;
styleInfo: CellStyleInfo;
contentInfo: CellContentInfo;
order?: number;
@ -131,7 +142,7 @@ interface TimeseriesTableSource {
templateUrl: './timeseries-table-widget.component.html',
styleUrls: ['./timeseries-table-widget.component.scss', './table-widget.scss']
})
export class TimeseriesTableWidgetComponent extends PageComponent implements OnInit, AfterViewInit {
export class TimeseriesTableWidgetComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy {
@Input()
ctx: WidgetContext;
@ -169,6 +180,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
private useEntityLabel = false;
private dateFormatFilter: string;
private displayedColumns: Array<DisplayColumn[]> = [];
private rowStylesInfo: RowStyleInfo;
private subscriptions: Subscription[] = [];
@ -184,6 +197,15 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
}
};
private columnDisplayAction: WidgetAction = {
name: 'entity.columns-to-display',
show: true,
icon: 'view_column',
onAction: ($event) => {
this.editColumnsToDisplay($event);
}
};
constructor(protected store: Store<AppState>,
private elementRef: ElementRef,
private overlay: Overlay,
@ -275,11 +297,12 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
}
private initialize() {
this.ctx.widgetActions = [this.searchAction ];
this.ctx.widgetActions = [this.searchAction, this.columnDisplayAction];
this.setCellButtonAction = !!this.ctx.actionsApi.getActionDescriptors('actionCellButton').length;
this.searchAction.show = isDefined(this.settings.enableSearch) ? this.settings.enableSearch : true;
this.columnDisplayAction.show = isDefined(this.settings.enableSelectColumnDisplay) ? this.settings.enableSelectColumnDisplay : true;
this.displayPagination = isDefined(this.settings.displayPagination) ? this.settings.displayPagination : true;
this.enableStickyHeader = isDefined(this.settings.enableStickyHeader) ? this.settings.enableStickyHeader : true;
this.enableStickyAction = isDefined(this.settings.enableStickyAction) ? this.settings.enableStickyAction : true;
@ -365,9 +388,82 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
this.sources.push(source);
}
}
this.prepareDisplayedColumn();
this.sources[this.sourceIndex].displayedColumns =
this.displayedColumns[this.sourceIndex].filter(value => value.display).map(value => value.def);
this.updateActiveEntityInfo();
}
private editColumnsToDisplay($event: Event) {
if ($event) {
$event.stopPropagation();
}
const target = $event.target || $event.currentTarget;
const config = new OverlayConfig();
config.backdropClass = 'cdk-overlay-transparent-backdrop';
config.hasBackdrop = true;
const connectedPosition: ConnectedPosition = {
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top'
};
config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
.withPositions([connectedPosition]);
const overlayRef = this.overlay.create(config);
overlayRef.backdropClick().subscribe(() => {
overlayRef.dispose();
});
const source = this.sources[this.sourceIndex];
this.prepareDisplayedColumn();
const providers: StaticProvider[] = [
{
provide: DISPLAY_COLUMNS_PANEL_DATA,
useValue: {
columns: this.displayedColumns[this.sourceIndex],
columnsUpdated: (newColumns) => {
source.displayedColumns = newColumns.filter(value => value.display).map(value => value.def);
this.clearCache();
}
}
},
{
provide: OverlayRef,
useValue: overlayRef
}
];
const injector = Injector.create({parent: this.viewContainerRef.injector, providers});
overlayRef.attach(new ComponentPortal(DisplayColumnsPanelComponent,
this.viewContainerRef, injector));
this.ctx.detectChanges();
}
private prepareDisplayedColumn() {
if (!this.displayedColumns[this.sourceIndex]) {
this.displayedColumns[this.sourceIndex] = this.sources[this.sourceIndex].displayedColumns.map(value => {
let title = '';
const header = this.sources[this.sourceIndex].header.find(column => column.index.toString() === value);
if (value === '0') {
title = 'Timestamp';
} else if (value === 'actions') {
title = 'Actions';
} else {
title = header.dataKey.name;
}
return {
title,
def: value,
display: header?.columnDefaultVisibility ?? true,
selectable: header?.columnSelectionAvailability ?? true
};
});
}
}
private prepareHeader(datasource: Datasource): TimeseriesHeader[] {
const dataKeys = datasource.dataKeys;
const latestDataKeys = datasource.latestDataKeys;
@ -377,6 +473,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
const keySettings: TableWidgetDataKeySettings = dataKey.settings;
const styleInfo = getCellStyleInfo(keySettings, 'value, rowData, ctx');
const contentInfo = getCellContentInfo(keySettings, 'value, rowData, ctx');
const columnDefaultVisibility = getColumnDefaultVisibility(keySettings, this.ctx);
const columnSelectionAvailability = getColumnSelectionAvailability(keySettings);
contentInfo.units = dataKey.units;
contentInfo.decimals = dataKey.decimals;
header.push({
@ -386,6 +484,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
styleInfo,
contentInfo,
show: true,
columnDefaultVisibility,
columnSelectionAvailability,
order: index + 2
});
});
@ -396,6 +496,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
const keySettings: TimeseriesWidgetLatestDataKeySettings = dataKey.settings;
const styleInfo = getCellStyleInfo(keySettings, 'value, rowData, ctx');
const contentInfo = getCellContentInfo(keySettings, 'value, rowData, ctx');
const columnDefaultVisibility = getColumnDefaultVisibility(keySettings, this.ctx);
const columnSelectionAvailability = getColumnSelectionAvailability(keySettings);
contentInfo.units = dataKey.units;
contentInfo.decimals = dataKey.decimals;
header.push({
@ -405,13 +507,13 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
styleInfo,
contentInfo,
show: isDefinedAndNotNull(keySettings.show) ? keySettings.show : true,
columnDefaultVisibility,
columnSelectionAvailability,
order: isDefinedAndNotNull(keySettings.order) ? keySettings.order : (index + 2)
});
});
}
header = header.sort((a, b) => {
return a.order - b.order;
});
header = header.sort((a, b) => a.order - b.order);
return header;
}