Timewindow: remove timewindow config from widget if unused
This commit is contained in:
		
							parent
							
								
									35b349bd6e
								
							
						
					
					
						commit
						f1c80e4379
					
				@ -38,6 +38,7 @@ import {
 | 
			
		||||
import { deepClone, isDefined, isDefinedAndNotNull, isNotEmptyStr, isString, isUndefined } from '@core/utils';
 | 
			
		||||
import {
 | 
			
		||||
  Datasource,
 | 
			
		||||
  datasourcesHasAggregation,
 | 
			
		||||
  datasourcesHasOnlyComparisonAggregation,
 | 
			
		||||
  DatasourceType,
 | 
			
		||||
  defaultLegendConfig,
 | 
			
		||||
@ -49,7 +50,8 @@ import {
 | 
			
		||||
  WidgetConfigMode,
 | 
			
		||||
  WidgetSize,
 | 
			
		||||
  widgetType,
 | 
			
		||||
  WidgetTypeDescriptor
 | 
			
		||||
  WidgetTypeDescriptor,
 | 
			
		||||
  widgetTypeHasTimewindow
 | 
			
		||||
} from '@app/shared/models/widget.models';
 | 
			
		||||
import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
import { AliasFilterType, EntityAlias, EntityAliasFilter } from '@app/shared/models/alias.models';
 | 
			
		||||
@ -295,8 +297,11 @@ export class DashboardUtilsService {
 | 
			
		||||
    widgetConfig.datasources = this.validateAndUpdateDatasources(widgetConfig.datasources);
 | 
			
		||||
    if (type === widgetType.latest) {
 | 
			
		||||
      const onlyHistoryTimewindow = datasourcesHasOnlyComparisonAggregation(widgetConfig.datasources);
 | 
			
		||||
      widgetConfig.timewindow = initModelFromDefaultTimewindow(widgetConfig.timewindow, true,
 | 
			
		||||
        onlyHistoryTimewindow, this.timeService, false);
 | 
			
		||||
      const aggregationEnabledForKeys = datasourcesHasAggregation(widgetConfig.datasources);
 | 
			
		||||
      if (aggregationEnabledForKeys) {
 | 
			
		||||
        widgetConfig.timewindow = initModelFromDefaultTimewindow(widgetConfig.timewindow, true,
 | 
			
		||||
          onlyHistoryTimewindow, this.timeService, false);
 | 
			
		||||
      }
 | 
			
		||||
    } else if (type === widgetType.rpc) {
 | 
			
		||||
      if (widgetConfig.targetDeviceAliasIds && widgetConfig.targetDeviceAliasIds.length) {
 | 
			
		||||
        widgetConfig.targetDevice = {
 | 
			
		||||
@ -346,9 +351,29 @@ export class DashboardUtilsService {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.removeTimewindowConfigIfUnused(widgetConfig, type);
 | 
			
		||||
    return widgetConfig;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public removeTimewindowConfigIfUnused(widgetConfig: WidgetConfig, type: widgetType) {
 | 
			
		||||
    const widgetHasTimewindow = widgetTypeHasTimewindow(type) || (type === widgetType.latest && datasourcesHasAggregation(widgetConfig.datasources));
 | 
			
		||||
    if (!widgetHasTimewindow || widgetConfig.useDashboardTimewindow) {
 | 
			
		||||
      delete widgetConfig.displayTimewindow;
 | 
			
		||||
      delete widgetConfig.timewindow;
 | 
			
		||||
      delete widgetConfig.timewindowStyle;
 | 
			
		||||
 | 
			
		||||
      if (!widgetHasTimewindow) {
 | 
			
		||||
        delete widgetConfig.useDashboardTimewindow;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public prepareWidgetForSaving(widget: Widget): Widget {
 | 
			
		||||
    this.removeTimewindowConfigIfUnused(widget.config, widget.type);
 | 
			
		||||
    return widget;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public prepareWidgetForScadaLayout(widget: Widget, isScada: boolean): Widget {
 | 
			
		||||
    const config = widget.config;
 | 
			
		||||
    config.showTitle = false;
 | 
			
		||||
 | 
			
		||||
@ -1322,6 +1322,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private addWidgetToDashboard(widget: Widget) {
 | 
			
		||||
    this.dashboardUtils.prepareWidgetForSaving(widget);
 | 
			
		||||
    if (this.addingLayoutCtx) {
 | 
			
		||||
      this.addWidgetToLayout(widget, this.addingLayoutCtx.id);
 | 
			
		||||
      this.addingLayoutCtx = null;
 | 
			
		||||
@ -1409,7 +1410,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
 | 
			
		||||
  saveWidget() {
 | 
			
		||||
    this.editWidgetComponent.widgetFormGroup.markAsPristine();
 | 
			
		||||
    const widget = deepClone(this.editingWidget);
 | 
			
		||||
    const widget = this.dashboardUtils.prepareWidgetForSaving(deepClone(this.editingWidget));
 | 
			
		||||
    const widgetLayout = deepClone(this.editingWidgetLayout);
 | 
			
		||||
    const id = this.editingWidgetOriginal.id;
 | 
			
		||||
    this.dashboardConfiguration.widgets[id] = widget;
 | 
			
		||||
 | 
			
		||||
@ -23,11 +23,19 @@ import { PageComponent } from '@shared/components/page.component';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { AbstractControl, UntypedFormGroup } from '@angular/forms';
 | 
			
		||||
import { DataKey, DatasourceType, Widget, WidgetConfigMode, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
import {
 | 
			
		||||
  DataKey,
 | 
			
		||||
  DatasourceType,
 | 
			
		||||
  Widget,
 | 
			
		||||
  widgetTypeCanHaveTimewindow,
 | 
			
		||||
  WidgetConfigMode,
 | 
			
		||||
  widgetType
 | 
			
		||||
} from '@shared/models/widget.models';
 | 
			
		||||
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
 | 
			
		||||
import { isDefinedAndNotNull } from '@core/utils';
 | 
			
		||||
import { isDefinedAndNotNull, isUndefinedOrNull } from '@core/utils';
 | 
			
		||||
import { IAliasController } from '@core/api/widget-api.models';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { initModelFromDefaultTimewindow } from '@shared/models/time/time.models';
 | 
			
		||||
 | 
			
		||||
export type WidgetConfigCallbacks = DatasourceCallbacks & WidgetActionCallbacks;
 | 
			
		||||
 | 
			
		||||
@ -107,6 +115,11 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement
 | 
			
		||||
    if (this.isAdd) {
 | 
			
		||||
      this.setupDefaults(widgetConfig);
 | 
			
		||||
    }
 | 
			
		||||
    if (widgetTypeCanHaveTimewindow(widgetConfig.widgetType) && isUndefinedOrNull(widgetConfig.config.timewindow)) {
 | 
			
		||||
      widgetConfig.config.timewindow = initModelFromDefaultTimewindow(null,
 | 
			
		||||
        widgetConfig.widgetType === widgetType.latest, false, this.widgetConfigComponent.timeService,
 | 
			
		||||
        widgetConfig.widgetType === widgetType.timeseries);
 | 
			
		||||
    }
 | 
			
		||||
    this.onConfigSet(widgetConfig);
 | 
			
		||||
    this.updateValidators(false);
 | 
			
		||||
    for (const trigger of this.validatorTriggers()) {
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ import {
 | 
			
		||||
  TargetDevice,
 | 
			
		||||
  targetDeviceValid,
 | 
			
		||||
  Widget,
 | 
			
		||||
  widgetTypeCanHaveTimewindow,
 | 
			
		||||
  WidgetConfigMode,
 | 
			
		||||
  widgetType
 | 
			
		||||
} from '@shared/models/widget.models';
 | 
			
		||||
@ -53,7 +54,7 @@ import {
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
 | 
			
		||||
import { deepClone, genNextLabel, isDefined, isObject } from '@app/core/utils';
 | 
			
		||||
import { deepClone, genNextLabel, isDefined, isDefinedAndNotNull, isObject } from '@app/core/utils';
 | 
			
		||||
import { alarmFields, AlarmSearchStatus } from '@shared/models/alarm.models';
 | 
			
		||||
import { IAliasController } from '@core/api/widget-api.models';
 | 
			
		||||
import { EntityAlias } from '@shared/models/alias.models';
 | 
			
		||||
@ -84,6 +85,8 @@ import { DataKeySettingsFunction } from '@home/components/widget/lib/settings/co
 | 
			
		||||
import { defaultFormProperties, FormProperty } from '@shared/models/dynamic-form.models';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { WidgetService } from '@core/http/widget.service';
 | 
			
		||||
import { TimeService } from '@core/services/time.service';
 | 
			
		||||
import { initModelFromDefaultTimewindow } from '@shared/models/time/time.models';
 | 
			
		||||
import Timeout = NodeJS.Timeout;
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@ -201,6 +204,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
 | 
			
		||||
  constructor(protected store: Store<AppState>,
 | 
			
		||||
              private utils: UtilsService,
 | 
			
		||||
              private entityService: EntityService,
 | 
			
		||||
              public timeService: TimeService,
 | 
			
		||||
              private dialog: MatDialog,
 | 
			
		||||
              public translate: TranslateService,
 | 
			
		||||
              private fb: UntypedFormBuilder,
 | 
			
		||||
@ -366,16 +370,16 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
 | 
			
		||||
    this.dataSettings = this.fb.group({});
 | 
			
		||||
    this.targetDeviceSettings = this.fb.group({});
 | 
			
		||||
    this.advancedSettings = this.fb.group({});
 | 
			
		||||
    if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) {
 | 
			
		||||
    if (widgetTypeCanHaveTimewindow(this.widgetType)) {
 | 
			
		||||
      this.dataSettings.addControl('timewindowConfig', this.fb.control({
 | 
			
		||||
        useDashboardTimewindow: true,
 | 
			
		||||
        displayTimewindow: true,
 | 
			
		||||
        useDashboardTimewindow: this.widgetType !== widgetType.latest,
 | 
			
		||||
        displayTimewindow: this.widgetType !== widgetType.latest,
 | 
			
		||||
        timewindow: null,
 | 
			
		||||
        timewindowStyle: null
 | 
			
		||||
      }));
 | 
			
		||||
      if (this.widgetType === widgetType.alarm) {
 | 
			
		||||
        this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (this.widgetType === widgetType.alarm) {
 | 
			
		||||
      this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null));
 | 
			
		||||
    }
 | 
			
		||||
    if (this.modelValue.isDataEnabled) {
 | 
			
		||||
      if (this.widgetType !== widgetType.rpc &&
 | 
			
		||||
@ -529,14 +533,17 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
 | 
			
		||||
        },
 | 
			
		||||
        {emitEvent: false}
 | 
			
		||||
      );
 | 
			
		||||
      if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) {
 | 
			
		||||
      if (widgetTypeCanHaveTimewindow(this.widgetType)) {
 | 
			
		||||
        const useDashboardTimewindow = isDefined(config.useDashboardTimewindow) ?
 | 
			
		||||
          config.useDashboardTimewindow : true;
 | 
			
		||||
          config.useDashboardTimewindow : this.widgetType !== widgetType.latest;
 | 
			
		||||
        this.dataSettings.get('timewindowConfig').patchValue({
 | 
			
		||||
          useDashboardTimewindow,
 | 
			
		||||
          displayTimewindow: isDefined(config.displayTimewindow) ?
 | 
			
		||||
            config.displayTimewindow : true,
 | 
			
		||||
          timewindow: config.timewindow,
 | 
			
		||||
            config.displayTimewindow : this.widgetType !== widgetType.latest,
 | 
			
		||||
          timewindow: isDefinedAndNotNull(config.timewindow)
 | 
			
		||||
            ? config.timewindow
 | 
			
		||||
            : initModelFromDefaultTimewindow(null, this.widgetType === widgetType.latest, this.onlyHistoryTimewindow(),
 | 
			
		||||
              this.timeService, this.widgetType === widgetType.timeseries),
 | 
			
		||||
          timewindowStyle: config.timewindowStyle
 | 
			
		||||
        }, {emitEvent: false});
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -489,6 +489,14 @@ export const targetDeviceValid = (targetDevice?: TargetDevice): boolean =>
 | 
			
		||||
    ((targetDevice.type === TargetDeviceType.device && !!targetDevice.deviceId) ||
 | 
			
		||||
      (targetDevice.type === TargetDeviceType.entity && !!targetDevice.entityAliasId));
 | 
			
		||||
 | 
			
		||||
export const widgetTypeHasTimewindow = (type: widgetType): boolean => {
 | 
			
		||||
  return type === widgetType.timeseries || type === widgetType.alarm;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const widgetTypeCanHaveTimewindow = (type: widgetType): boolean => {
 | 
			
		||||
  return widgetTypeHasTimewindow(type) || type === widgetType.latest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const datasourcesHasAggregation = (datasources?: Array<Datasource>): boolean => {
 | 
			
		||||
  if (datasources) {
 | 
			
		||||
    const foundDatasource = datasources.find(datasource => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user