Browse Source

UI: Optimize deepClean

pull/13690/head
Vladyslav_Prykhodko 9 months ago
parent
commit
05971f1076
  1. 13
      ui-ngx/src/app/core/services/dashboard-utils.service.ts
  2. 83
      ui-ngx/src/app/core/utils.ts
  3. 4
      ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts

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

@ -35,7 +35,15 @@ import {
LayoutType, LayoutType,
WidgetLayout WidgetLayout
} from '@shared/models/dashboard.models'; } from '@shared/models/dashboard.models';
import { deepClone, isDefined, isDefinedAndNotNull, isNotEmptyStr, isString, isUndefined } from '@core/utils'; import {
deepClean,
deepClone,
isDefined,
isDefinedAndNotNull,
isNotEmptyStr,
isString,
isUndefined
} from '@core/utils';
import { import {
Datasource, Datasource,
datasourcesHasAggregation, datasourcesHasAggregation,
@ -353,7 +361,7 @@ export class DashboardUtilsService {
} }
} }
} }
return widgetConfig; return deepClean(widgetConfig, {cleanKeys: ['_hash'], cleanOnlyKey: true});
} }
private removeTimewindowConfigIfUnused(widget: Widget) { private removeTimewindowConfigIfUnused(widget: Widget) {
@ -380,6 +388,7 @@ export class DashboardUtilsService {
public prepareWidgetForSaving(widget: Widget): Widget { public prepareWidgetForSaving(widget: Widget): Widget {
this.removeTimewindowConfigIfUnused(widget); this.removeTimewindowConfigIfUnused(widget);
widget = deepClean(widget, {cleanKeys: ['_hash'], cleanOnlyKey: true});
return widget; return widget;
} }

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

@ -34,7 +34,7 @@ import {
} from '@shared/models/js-function.models'; } from '@shared/models/js-function.models';
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { SecurityContext } from '@angular/core'; import { SecurityContext } from '@angular/core';
import { AbstractControl, ValidationErrors, Validators } from '@angular/forms'; import { AbstractControl, ValidationErrors } from '@angular/forms';
const varsRegex = /\${([^}]*)}/g; const varsRegex = /\${([^}]*)}/g;
const emailRegex = /^[A-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i; const emailRegex = /^[A-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
@ -795,31 +795,72 @@ export function deepTrim<T>(obj: T): T {
}, (Array.isArray(obj) ? [] : {}) as T); }, (Array.isArray(obj) ? [] : {}) as T);
} }
const isValidValue = (value: any): boolean => {
return (
value !== undefined &&
value !== null &&
value !== '' &&
!Number.isNaN(value)
);
};
export function deepClean<T extends Record<string, any> | any[]>(obj: T, { export function deepClean<T extends Record<string, any> | any[]>(obj: T, {
cleanKeys = [] cleanKeys = [],
cleanOnlyKey = false
} = {}): T { } = {}): T {
return _.transform(obj, (result, value, key) => { const keysToRemove = new Set(cleanKeys);
if (cleanKeys.includes(key)) {
return; const clean = (input: any): any => {
} if (Array.isArray(input)) {
if (Array.isArray(value) || isLiteralObject(value)) { const result: any[] = [];
value = deepClean(value, {cleanKeys}); for (const item of input) {
} const value = clean(item);
if(isLiteralObject(value) && isEmpty(value)) {
return; if (cleanOnlyKey) {
} result.push(value);
if (Array.isArray(value) && !value.length) { continue;
return; }
}
if (value === undefined || value === null || value === '' || Number.isNaN(value)) { if (isValidValue(value)) {
return; const isEmptyArray = Array.isArray(value) && value.length === 0;
const isEmptyObj = isLiteralObject(value) && Object.keys(value).length === 0;
if (!isEmptyArray && !isEmptyObj) {
result.push(value);
}
}
}
return result;
} }
if (Array.isArray(result)) { if (isLiteralObject(input)) {
return result.push(value); const result: Record<string, any> = {};
for (const key in input) {
if (keysToRemove.has(key)) continue;
const value = clean(input[key]);
if (cleanOnlyKey) {
result[key] = value;
continue;
}
if (isValidValue(value)) {
const isEmptyArray = Array.isArray(value) && value.length === 0;
const isEmptyObj = isLiteralObject(value) && Object.keys(value).length === 0;
if (!isEmptyArray && !isEmptyObj) {
result[key] = value;
}
}
}
return result;
} }
result[key] = value; return input;
}); };
return clean(obj);
} }
export function generateSecret(length?: number): string { export function generateSecret(length?: number): string {

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 { deepClean, deepClone, isUndefined } from '@core/utils'; import { 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(deepClean(entityAliases)); this.dialogRef.close(entityAliases);
} else { } else {
this.store.dispatch(new ActionNotificationShow( this.store.dispatch(new ActionNotificationShow(
{ {

Loading…
Cancel
Save