Browse Source

moved sorting of datasources

pull/14412/head
Maksym Tsymbarov 10 months ago
parent
commit
0e8b99c067
  1. 2
      application/src/main/data/json/system/widget_types/timeseries_table.json
  2. 6
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html
  3. 13
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts
  4. 64
      ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts
  5. 6
      ui-ngx/src/assets/locale/locale.constant-en_US.json

2
application/src/main/data/json/system/widget_types/timeseries_table.json

@ -17,7 +17,7 @@
"latestDataKeySettingsDirective": "tb-timeseries-table-latest-key-settings", "latestDataKeySettingsDirective": "tb-timeseries-table-latest-key-settings",
"hasBasicMode": true, "hasBasicMode": true,
"basicModeDirective": "tb-timeseries-table-basic-config", "basicModeDirective": "tb-timeseries-table-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}],\"latestDataKeys\":[]}],\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"enableSearch\":true,\"enableSelectColumnDisplay\":true,\"enableStickyHeader\":true,\"enableStickyAction\":true,\"showCellActionsMenu\":true,\"reserveSpaceForHiddenAction\":\"true\",\"showTimestamp\":true,\"dateFormat\":{\"format\":\"yyyy-MM-dd HH:mm:ss\"},\"displayPagination\":true,\"useEntityLabel\":false,\"defaultPageSize\":10,\"pageStepCount\":3,\"pageStepIncrement\":10,\"hideEmptyLines\":false,\"disableStickyHeader\":false,\"useRowStyleFunction\":false,\"rowStyleFunction\":\"\",\"sortOrder\":{\"property\":\"createdTime\",\"direction\":\"ASC\"}},\"title\":\"Time series table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"configMode\":\"basic\",\"titleFont\":null,\"titleColor\":null,\"titleIcon\":null}" "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}],\"latestDataKeys\":null}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"enableSearch\":true,\"enableSelectColumnDisplay\":true,\"enableStickyHeader\":true,\"enableStickyAction\":true,\"showCellActionsMenu\":true,\"reserveSpaceForHiddenAction\":\"true\",\"showTimestamp\":true,\"dateFormat\":{\"format\":\"yyyy-MM-dd HH:mm:ss\"},\"displayPagination\":true,\"useEntityLabel\":false,\"defaultPageSize\":10,\"pageStepCount\":3,\"pageStepIncrement\":10,\"hideEmptyLines\":false,\"disableStickyHeader\":false,\"useRowStyleFunction\":false,\"rowStyleFunction\":\"\",\"sortOrder\":{\"property\":\"createdTime\",\"direction\":\"DESC\"}},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"displayTimewindow\":true,\"configMode\":\"advanced\"}"
}, },
"resources": [ "resources": [
{ {

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

@ -113,7 +113,7 @@
<div class="tb-form-panel"> <div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.table.table-tabs</div> <div class="tb-form-panel-title" translate>widgets.table.table-tabs</div>
<mat-slide-toggle class="mat-slide" formControlName="useEntityLabel"> <mat-slide-toggle class="mat-slide" formControlName="useEntityLabel">
{{ 'widgets.table.use-entity-label-header-title' | translate }} {{ 'widgets.table.use-entity-label-tab-name' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
<div class="tb-form-row justify-between column-xs" formGroupName="sortOrder"> <div class="tb-form-row justify-between column-xs" formGroupName="sortOrder">
<div class="fixed-title-width" translate>widgets.table.sort-by</div> <div class="fixed-title-width" translate>widgets.table.sort-by</div>
@ -126,8 +126,8 @@
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-lt-lg medium-width" appearance="outline" subscriptSizing="dynamic"> <mat-form-field class="flex-lt-lg medium-width" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="direction" placeholder="{{ 'widget-config.set' | translate }}"> <mat-select formControlName="direction" placeholder="{{ 'widget-config.set' | translate }}">
<mat-option [value]="Direction.ASC">{{ 'widgets.table.sort-asc' | translate }}</mat-option> <mat-option [value]="Direction.ASC">{{ 'common.sort-asc' | translate }}</mat-option>
<mat-option [value]="Direction.DESC">{{ 'widgets.table.sort-desc' | translate }}</mat-option> <mat-option [value]="Direction.DESC">{{ 'common.sort-desc' | translate }}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>

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

@ -46,7 +46,6 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
} }
protected defaultSettings(): WidgetSettings { protected defaultSettings(): WidgetSettings {
console.log("default")
return { return {
enableSearch: true, enableSearch: true,
enableSelectColumnDisplay: true, enableSelectColumnDisplay: true,
@ -67,7 +66,7 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
rowStyleFunction: '', rowStyleFunction: '',
sortOrder: { sortOrder: {
property: this.entityFields.name.keyName, property: this.entityFields.name.keyName,
direction: Direction.ASC direction: Direction.DESC
} }
}; };
} }
@ -75,11 +74,10 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
protected prepareInputSettings(settings: WidgetSettings): WidgetSettings { protected prepareInputSettings(settings: WidgetSettings): WidgetSettings {
settings.pageStepIncrement = settings.pageStepIncrement ?? settings.defaultPageSize; settings.pageStepIncrement = settings.pageStepIncrement ?? settings.defaultPageSize;
settings.sortOrder = { settings.sortOrder = {
property: settings.sortOrder?.property || this.entityFields.name.keyName, property: settings.sortOrder?.property || this.entityFields.createdTime.keyName,
direction: settings.sortOrder?.direction || Direction.ASC direction: settings.sortOrder?.direction || Direction.DESC
}; };
this.pageStepSizeValues = buildPageStepSizeValues(settings.pageStepCount, settings.pageStepIncrement); this.pageStepSizeValues = buildPageStepSizeValues(settings.pageStepCount, settings.pageStepIncrement);
console.log("input",settings)
return settings; return settings;
} }
@ -128,10 +126,9 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon
protected prepareOutputSettings(settings: WidgetSettings): WidgetSettings { protected prepareOutputSettings(settings: WidgetSettings): WidgetSettings {
settings.sortOrder = { settings.sortOrder = {
property: settings.sortOrder?.property || this.entityFields.name.keyName, property: settings.sortOrder?.property || this.entityFields.createdTime.keyName,
direction: settings.sortOrder?.direction || Direction.ASC direction: settings.sortOrder?.direction || Direction.DESC
}; };
console.log("output",settings)
return settings; return settings;
} }

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

@ -409,13 +409,10 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
return translated; return translated;
} }
private sortDatasources(source: Datasource[], entityLabelCache: Map<string, string>): Datasource[] { private sortDatasources(source: TimeseriesTableSource[], entityLabelCache: Map<string, string>) {
const property = this.settings?.sortOrder?.property; const property = this.settings?.sortOrder?.property;
const direction = this.settings?.sortOrder?.direction; const direction = this.settings?.sortOrder?.direction;
const isAsc = direction === Direction.ASC; const isAsc = direction === Direction.ASC;
let sortedSource = [...source];
source.forEach(ds => this.getTabLabel(ds, entityLabelCache));
if (property === entityFields.name.keyName) { if (property === entityFields.name.keyName) {
const collator = new Intl.Collator(undefined, { const collator = new Intl.Collator(undefined, {
@ -424,63 +421,19 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
ignorePunctuation: false ignorePunctuation: false
}); });
sortedSource.sort((a, b) => { source.sort((a, b) => {
const valueA = entityLabelCache.get(a.entityId) || ''; const valueA = entityLabelCache.get(a.datasource.entityId) || '';
const valueB = entityLabelCache.get(b.entityId) || ''; const valueB = entityLabelCache.get(a.datasource.entityId) || '';
return isAsc return isAsc
? collator.compare(valueA, valueB) ? collator.compare(valueA, valueB)
: collator.compare(valueB, valueA); : collator.compare(valueB, valueA);
}); });
} else if (property === entityFields.createdTime.keyName) { } else if (property === entityFields.createdTime.keyName) {
if (!isAsc) { if (isAsc) {
sortedSource.reverse(); source.reverse();
} }
} }
this.reorderDataArrays(source, sortedSource);
return sortedSource;
}
private reorderDataArrays(originalOrder: Datasource[], newOrder: Datasource[]): void {
const indexMap = new Map<number, number>();
originalOrder.forEach((ds, oldIndex) => {
const newIndex = newOrder.findIndex(newDs => newDs.entityId === ds.entityId);
indexMap.set(oldIndex, newIndex);
});
const newData: Array<DatasourceData> = [];
originalOrder.forEach((ds, oldIndex) => {
const dataKeys = ds.dataKeys;
const startIdx = oldIndex * dataKeys.length;
const endIdx = startIdx + dataKeys.length;
const datasourceData = this.data.slice(startIdx, endIdx);
const newIndex = indexMap.get(oldIndex);
const newStartIdx = newIndex * dataKeys.length;
datasourceData.forEach((data, i) => {
newData[newStartIdx + i] = data;
});
});
this.data = newData;
if (this.latestData && this.latestData.length > 0) {
const newLatestData: Array<DatasourceData> = [];
originalOrder.forEach((ds, oldIndex) => {
const latestDataKeys = ds.latestDataKeys || [];
const startIdx = oldIndex * latestDataKeys.length;
const endIdx = startIdx + latestDataKeys.length;
const datasourceLatestData = this.latestData.slice(startIdx, endIdx);
const newIndex = indexMap.get(oldIndex);
const newStartIdx = newIndex * latestDataKeys.length;
datasourceLatestData.forEach((data, i) => {
newLatestData[newStartIdx + i] = data;
});
});
this.latestData = newLatestData;
}
} }
private updateDatasources() { private updateDatasources() {
@ -491,8 +444,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
const entityLabelCache = new Map<string,string>(); const entityLabelCache = new Map<string,string>();
const pageSize = this.displayPagination ? this.defaultPageSize : Number.POSITIVE_INFINITY; const pageSize = this.displayPagination ? this.defaultPageSize : Number.POSITIVE_INFINITY;
if (this.datasources) { if (this.datasources) {
const sortedDatasources = this.sortDatasources(this.datasources, entityLabelCache); this.datasources.forEach(ds => this.getTabLabel(ds, entityLabelCache));
for (const datasource of sortedDatasources) { for (const datasource of this.datasources) {
const sortOrder: SortOrder = sortOrderFromString(this.defaultSortOrder); const sortOrder: SortOrder = sortOrderFromString(this.defaultSortOrder);
const source = {} as TimeseriesTableSource; const source = {} as TimeseriesTableSource;
source.header = this.prepareHeader(datasource); source.header = this.prepareHeader(datasource);
@ -529,6 +482,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
} }
} }
if (this.sources.length) { if (this.sources.length) {
this.sortDatasources(this.sources, entityLabelCache);
this.sources.forEach((source, index) => { this.sources.forEach((source, index) => {
this.prepareDisplayedColumn(index); this.prepareDisplayedColumn(index);
source.displayedColumns = this.displayedColumns[index].filter(value => value.display).map(value => value.def); source.displayedColumns = this.displayedColumns[index].filter(value => value.display).map(value => value.def);

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

@ -1639,6 +1639,8 @@
"documentation": "Documentation", "documentation": "Documentation",
"time-left": "{{time}} left", "time-left": "{{time}} left",
"output": "Output", "output": "Output",
"sort-asc": "Ascending",
"sort-desc": "Descending",
"suffix": { "suffix": {
"s": "s", "s": "s",
"ms": "ms" "ms": "ms"
@ -9482,7 +9484,7 @@
"page-step-increment": "Step increment", "page-step-increment": "Step increment",
"page-step-count-format-message": "Should be an integer value, in the range from 1 to 100.", "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.", "page-step-increment-format-message": "Should be an integer value, greater or equal to 1.",
"use-entity-label-header-title": "Use entity label in header title", "use-entity-label-tab-name": "Use entity label in tab name",
"hide-empty-lines": "Hide empty lines", "hide-empty-lines": "Hide empty lines",
"row-style": "Row style", "row-style": "Row style",
"use-row-style-function": "Use row style function", "use-row-style-function": "Use row style function",
@ -9538,8 +9540,6 @@
"show-cell-actions-menu-mobile": "Show cell actions dropdown menu in mobile mode", "show-cell-actions-menu-mobile": "Show cell actions dropdown menu in mobile mode",
"disable-sorting": "Disable sorting", "disable-sorting": "Disable sorting",
"sort-by": "Sort tabs by", "sort-by": "Sort tabs by",
"sort-asc": "Ascending",
"sort-desc": "Descending",
"sort-timestamp-option": "Created time" "sort-timestamp-option": "Created time"
}, },
"latest-chart": { "latest-chart": {

Loading…
Cancel
Save