Browse Source

UI: Add deepClean widget config

pull/13690/head
Vladyslav_Prykhodko 1 year ago
parent
commit
d1e7f48c4c
  1. 6
      ui-ngx/src/app/core/api/widget-subscription.ts
  2. 5
      ui-ngx/src/app/core/services/dashboard-utils.service.ts
  3. 30
      ui-ngx/src/app/core/utils.ts
  4. 4
      ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts
  5. 8
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts
  6. 8
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-settings-dialog.component.ts
  7. 12
      ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts
  8. 2
      ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.ts
  9. 4
      ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts
  10. 4
      ui-ngx/src/app/shared/models/dashboard.models.ts

6
ui-ngx/src/app/core/api/widget-subscription.ts

@ -1497,9 +1497,9 @@ export class WidgetSubscription implements IWidgetSubscription {
private entityDataToDatasourceData(datasource: Datasource, data: Array<DataSetHolder>): Array<DatasourceData> { private entityDataToDatasourceData(datasource: Datasource, data: Array<DataSetHolder>): Array<DatasourceData> {
let datasourceDataArray: Array<DatasourceData> = []; let datasourceDataArray: Array<DatasourceData> = [];
datasourceDataArray = datasourceDataArray.concat(datasource.dataKeys.map((dataKey, keyIndex) => { datasourceDataArray = datasourceDataArray.concat(datasource.dataKeys.map((dataKey, keyIndex) => {
dataKey.hidden = !!dataKey.settings.hideDataByDefault; dataKey.hidden = !!dataKey.settings?.hideDataByDefault;
dataKey.inLegend = dataKey.settings.showInLegend || dataKey.inLegend = dataKey.settings?.showInLegend ||
(isUndefined(dataKey.settings.showInLegend) && !dataKey.settings.removeFromLegend); (isUndefined(dataKey.settings?.showInLegend) && !dataKey.settings?.removeFromLegend);
dataKey.label = this.ctx.utils.customTranslation(dataKey.label, dataKey.label); dataKey.label = this.ctx.utils.customTranslation(dataKey.label, dataKey.label);
const datasourceData: DatasourceData = { const datasourceData: DatasourceData = {
datasource, datasource,

5
ui-ngx/src/app/core/services/dashboard-utils.service.ts

@ -78,7 +78,10 @@ export class DashboardUtilsService {
public validateAndUpdateDashboard(dashboard: Dashboard): Dashboard { public validateAndUpdateDashboard(dashboard: Dashboard): Dashboard {
if (!dashboard.configuration) { if (!dashboard.configuration) {
dashboard.configuration = {}; dashboard.configuration = {
entityAliases: {},
filters: {},
};
} }
if (isUndefined(dashboard.configuration.widgets)) { if (isUndefined(dashboard.configuration.widgets)) {
dashboard.configuration.widgets = {}; dashboard.configuration.widgets = {};

30
ui-ngx/src/app/core/utils.ts

@ -27,7 +27,8 @@ import { serverErrorCodesTranslations } from '@shared/models/constants';
import { SubscriptionEntityInfo } from '@core/api/widget-api.models'; import { SubscriptionEntityInfo } from '@core/api/widget-api.models';
import { import {
CompiledTbFunction, CompiledTbFunction,
compileTbFunction, GenericFunction, compileTbFunction,
GenericFunction,
isNotEmptyTbFunction, isNotEmptyTbFunction,
TbFunction TbFunction
} from '@shared/models/js-function.models'; } from '@shared/models/js-function.models';
@ -773,6 +774,33 @@ export function deepTrim<T>(obj: T): T {
}, (Array.isArray(obj) ? [] : {}) as T); }, (Array.isArray(obj) ? [] : {}) as T);
} }
export function deepClean<T extends Record<string, any> | any[]>(obj: T, {
cleanKeys = []
} = {}): T {
return _.transform(obj, (result, value, key) => {
if (cleanKeys.includes(key)) {
return;
}
if (Array.isArray(value) || isLiteralObject(value)) {
value = deepClean(value, {cleanKeys});
}
if(isLiteralObject(value) && isEmpty(value)) {
return;
}
if (Array.isArray(value) && !value.length) {
return;
}
if (value === undefined || value === null || value === '' || Number.isNaN(value)) {
return;
}
if (Array.isArray(result)) {
return result.push(value);
}
result[key] = value;
});
}
export function generateSecret(length?: number): string { export function generateSecret(length?: number): string {
if (isUndefined(length) || length == null) { if (isUndefined(length) || length == null) {
length = 1; length = 1;

4
ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts

@ -37,7 +37,7 @@ import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ActionNotificationShow } from '@core/notification/notification.actions'; import { ActionNotificationShow } from '@core/notification/notification.actions';
import { DialogService } from '@core/services/dialog.service'; import { DialogService } from '@core/services/dialog.service';
import { deepClone, isUndefined } from '@core/utils'; import { deepClean, deepClone, isUndefined } from '@core/utils';
import { EntityAliasDialogComponent, EntityAliasDialogData } from './entity-alias-dialog.component'; import { EntityAliasDialogComponent, EntityAliasDialogData } from './entity-alias-dialog.component';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@ -263,7 +263,7 @@ export class EntityAliasesDialogComponent extends DialogComponent<EntityAliasesD
} }
} }
if (valid) { if (valid) {
this.dialogRef.close(entityAliases); this.dialogRef.close(deepClean(entityAliases));
} else { } else {
this.store.dispatch(new ActionNotificationShow( this.store.dispatch(new ActionNotificationShow(
{ {

8
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts

@ -58,7 +58,7 @@ import {
} from '@app/shared/models/dashboard.models'; } from '@app/shared/models/dashboard.models';
import { WINDOW } from '@core/services/window.service'; import { WINDOW } from '@core/services/window.service';
import { WindowMessage } from '@shared/models/window-message.model'; import { WindowMessage } from '@shared/models/window-message.model';
import { deepClone, guid, isDefined, isDefinedAndNotNull, isEqual, isNotEmptyStr } from '@app/core/utils'; import { deepClean, deepClone, guid, isDefined, isDefinedAndNotNull, isEqual, isNotEmptyStr } from '@app/core/utils';
import { import {
DashboardContext, DashboardContext,
DashboardPageInitData, DashboardPageInitData,
@ -1222,7 +1222,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
this.setEditMode(false, false); this.setEditMode(false, false);
} else { } else {
let reInitDashboard = false; let reInitDashboard = false;
this.dashboard.configuration.timewindow = this.dashboardCtx.dashboardTimewindow; this.dashboard.configuration.timewindow = deepClean(this.dashboardCtx.dashboardTimewindow);
this.dashboardService.saveDashboard(this.dashboard).pipe( this.dashboardService.saveDashboard(this.dashboard).pipe(
catchError((err) => { catchError((err) => {
if (err.status === HttpStatusCode.Conflict) { if (err.status === HttpStatusCode.Conflict) {
@ -1409,8 +1409,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
saveWidget() { saveWidget() {
this.editWidgetComponent.widgetFormGroup.markAsPristine(); this.editWidgetComponent.widgetFormGroup.markAsPristine();
const widget = deepClone(this.editingWidget); const widget = deepClean(deepClone(this.editingWidget), {cleanKeys: ['_hash']});
const widgetLayout = deepClone(this.editingWidgetLayout); const widgetLayout = deepClean(deepClone(this.editingWidgetLayout));
const id = this.editingWidgetOriginal.id; const id = this.editingWidgetOriginal.id;
this.dashboardConfiguration.widgets[id] = widget; this.dashboardConfiguration.widgets[id] = widget;
this.editingWidgetOriginal = widget; this.editingWidgetOriginal = widget;

8
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-settings-dialog.component.ts

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, Inject, OnDestroy, OnInit, SkipSelf } from '@angular/core'; import { Component, Inject, OnDestroy, SkipSelf } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core'; import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -33,7 +33,7 @@ import {
viewFormatTypes, viewFormatTypes,
viewFormatTypeTranslationMap viewFormatTypeTranslationMap
} from '@app/shared/models/dashboard.models'; } from '@app/shared/models/dashboard.models';
import { isDefined, isUndefined } from '@core/utils'; import { deepClean, deepTrim, isDefined, isUndefined } from '@core/utils';
import { StatesControllerService } from './states/states-controller.service'; import { StatesControllerService } from './states/states-controller.service';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import { merge, Subject } from 'rxjs'; import { merge, Subject } from 'rxjs';
@ -295,10 +295,10 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS
let settings: DashboardSettings = null; let settings: DashboardSettings = null;
let gridSettings: GridSettings = null; let gridSettings: GridSettings = null;
if (this.settings) { if (this.settings) {
settings = {...this.settings, ...this.settingsFormGroup.getRawValue()}; settings = deepClean(deepTrim({...this.settings, ...this.settingsFormGroup.getRawValue()}));
} }
if (this.gridSettings) { if (this.gridSettings) {
gridSettings = {...this.gridSettings, ...this.gridSettingsFormGroup.getRawValue()}; gridSettings = deepClean(deepTrim({...this.gridSettings, ...this.gridSettingsFormGroup.getRawValue()}));
} }
this.dialogRef.close({settings, gridSettings}); this.dialogRef.close({settings, gridSettings});
} }

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

@ -37,15 +37,7 @@ import { DataKey, WidgetActionDescriptor, WidgetConfig } from '@shared/models/wi
import { IWidgetSubscription } from '@core/api/widget-api.models'; import { IWidgetSubscription } from '@core/api/widget-api.models';
import { UtilsService } from '@core/services/utils.service'; import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { import { deepClone, hashCode, isDefined, isDefinedAndNotNull, isNotEmptyStr, isObject, isUndefined } from '@core/utils';
deepClone,
hashCode,
isDefined,
isDefinedAndNotNull,
isNotEmptyStr,
isObject,
isUndefined
} from '@core/utils';
import cssjs from '@core/css/css'; import cssjs from '@core/css/css';
import { sortItems } from '@shared/models/page/page-link'; import { sortItems } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
@ -440,7 +432,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
if (this.subscription.alarmSource) { if (this.subscription.alarmSource) {
this.subscription.alarmSource.dataKeys.forEach((alarmDataKey) => { this.subscription.alarmSource.dataKeys.forEach((alarmDataKey) => {
const dataKey: EntityColumn = deepClone(alarmDataKey) as EntityColumn; const dataKey: EntityColumn = deepClone(alarmDataKey) as EntityColumn;
const keySettings: TableWidgetDataKeySettings = dataKey.settings; const keySettings: TableWidgetDataKeySettings = dataKey.settings ?? {};
dataKey.entityKey = dataKeyToEntityKey(alarmDataKey); dataKey.entityKey = dataKeyToEntityKey(alarmDataKey);
dataKey.label = this.utils.customTranslation(dataKey.label, dataKey.label); dataKey.label = this.utils.customTranslation(dataKey.label, dataKey.label);
dataKey.title = getHeaderTitle(dataKey, keySettings, this.utils); dataKey.title = getHeaderTitle(dataKey, keySettings, this.utils);

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

@ -461,7 +461,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
} }
dataKeys.push(dataKey); dataKeys.push(dataKey);
const keySettings: TableWidgetDataKeySettings = dataKey.settings; const keySettings: TableWidgetDataKeySettings = dataKey.settings ?? {};
dataKey.label = this.utils.customTranslation(dataKey.label, dataKey.label); dataKey.label = this.utils.customTranslation(dataKey.label, dataKey.label);
dataKey.title = getHeaderTitle(dataKey, keySettings, this.utils); dataKey.title = getHeaderTitle(dataKey, keySettings, this.utils);
dataKey.def = 'def' + this.columns.length; dataKey.def = 'def' + this.columns.length;

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

@ -555,8 +555,8 @@ export function constructTableCssString(widgetConfig: WidgetConfig): string {
return cssString; return cssString;
} }
export function getHeaderTitle(dataKey: DataKey, keySettings: TableWidgetDataKeySettings, utils: UtilsService) { export function getHeaderTitle(dataKey: DataKey, keySettings: TableWidgetDataKeySettings | undefined, utils: UtilsService) {
if (isDefined(keySettings.customTitle) && isNotEmptyStr(keySettings.customTitle)) { if (isNotEmptyStr(keySettings?.customTitle)) {
return utils.customTranslation(keySettings.customTitle, keySettings.customTitle); return utils.customTranslation(keySettings.customTitle, keySettings.customTitle);
} }
return dataKey.label; return dataKey.label;

4
ui-ngx/src/app/shared/models/dashboard.models.ts

@ -186,8 +186,8 @@ export interface DashboardConfiguration {
settings?: DashboardSettings; settings?: DashboardSettings;
widgets?: {[id: string]: Widget } | Widget[]; widgets?: {[id: string]: Widget } | Widget[];
states?: {[id: string]: DashboardState }; states?: {[id: string]: DashboardState };
entityAliases?: EntityAliases; entityAliases: EntityAliases;
filters?: Filters; filters: Filters;
[key: string]: any; [key: string]: any;
} }

Loading…
Cancel
Save