From ad8cf203ed3e4b03e22924bde1d956ffe14c358a Mon Sep 17 00:00:00 2001 From: Ekaterina Chantsova Date: Wed, 6 Aug 2025 19:40:16 +0300 Subject: [PATCH] Timewindow: clear timewindow config for new map widgets --- .../core/services/dashboard-utils.service.ts | 28 +++++--- .../widget/maps/map-model.definition.ts | 67 ++++++++++++++++++- .../models/widget/widget-model.definition.ts | 1 + 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/ui-ngx/src/app/core/services/dashboard-utils.service.ts b/ui-ngx/src/app/core/services/dashboard-utils.service.ts index 7101aa0a2e..9c7c5d28d6 100644 --- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts +++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts @@ -236,6 +236,7 @@ export class DashboardUtilsService { public validateAndUpdateWidget(widget: Widget): Widget { widget.config = this.validateAndUpdateWidgetConfig(widget.config, widget.type); widget = this.validateAndUpdateWidgetTypeFqn(widget); + this.removeTimewindowConfigIfUnused(widget); if (isDefined((widget as any).title)) { delete (widget as any).title; } @@ -350,26 +351,33 @@ export class DashboardUtilsService { } } } - - this.removeTimewindowConfigIfUnused(widgetConfig, type); return widgetConfig; } - private 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; + private removeTimewindowConfigIfUnused(widget: Widget) { + const widgetHasTimewindow = this.widgetHasTimewindow(widget); + if (!widgetHasTimewindow || widget.config.useDashboardTimewindow) { + delete widget.config.displayTimewindow; + delete widget.config.timewindow; + delete widget.config.timewindowStyle; if (!widgetHasTimewindow) { - delete widgetConfig.useDashboardTimewindow; + delete widget.config.useDashboardTimewindow; } } } + private widgetHasTimewindow(widget: Widget): boolean { + const widgetDefinition = findWidgetModelDefinition(widget); + if (widgetDefinition) { + return widgetDefinition.hasTimewindow(widget); + } + return widgetTypeHasTimewindow(widget.type) + || (widget.type === widgetType.latest && datasourcesHasAggregation(widget.config.datasources)); + } + public prepareWidgetForSaving(widget: Widget): Widget { - this.removeTimewindowConfigIfUnused(widget.config, widget.type); + this.removeTimewindowConfigIfUnused(widget); return widget; } diff --git a/ui-ngx/src/app/shared/models/widget/maps/map-model.definition.ts b/ui-ngx/src/app/shared/models/widget/maps/map-model.definition.ts index 1dcd6890d8..8013889017 100644 --- a/ui-ngx/src/app/shared/models/widget/maps/map-model.definition.ts +++ b/ui-ngx/src/app/shared/models/widget/maps/map-model.definition.ts @@ -17,13 +17,18 @@ import { EntityAliases, EntityAliasInfo, getEntityAliasId } from '@shared/models/alias.models'; import { FilterInfo, Filters, getFilterId } from '@shared/models/query/query.models'; import { Dashboard } from '@shared/models/dashboard.models'; -import { Datasource, DatasourceType, Widget } from '@shared/models/widget.models'; +import { DataKey, Datasource, datasourcesHasAggregation, DatasourceType, Widget } from '@shared/models/widget.models'; import { + additionalMapDataSourcesToDatasources, BaseMapSettings, + CirclesDataLayerSettings, MapDataLayerSettings, + MapDataLayerType, MapDataSourceSettings, mapDataSourceSettingsToDatasource, - MapType + MapType, + MarkersDataLayerSettings, + PolygonsDataLayerSettings } from '@shared/models/widget/maps/map.models'; import { WidgetModelDefinition } from '@shared/models/widget/widget-model.definition'; @@ -124,6 +129,27 @@ export const MapModelDefinition: WidgetModelDefinition = { datasources.push(...getMapDataLayersDatasources(settings.additionalDataSources)); } return datasources; + }, + hasTimewindow(widget: Widget): boolean { + const settings: BaseMapSettings = widget.config.settings as BaseMapSettings; + if (settings.trips?.length) { + return true; + } else { + const datasources: Datasource[] = []; + if (settings.markers?.length) { + datasources.push(...getMapLatestDataLayersDatasources(settings.markers, 'markers')); + } + if (settings.polygons?.length) { + datasources.push(...getMapLatestDataLayersDatasources(settings.polygons, 'polygons')); + } + if (settings.circles?.length) { + datasources.push(...getMapLatestDataLayersDatasources(settings.circles, 'circles')); + } + if (settings.additionalDataSources?.length) { + datasources.push(...additionalMapDataSourcesToDatasources(settings.additionalDataSources)); + } + return datasourcesHasAggregation(datasources); + } } }; @@ -223,3 +249,40 @@ const getMapDataLayersDatasources = (settings: MapDataLayerSettings[] | MapDataS }); return datasources; }; + +const getMapLatestDataLayersDatasources = (settings: MapDataLayerSettings[], + dataLayerType: MapDataLayerType): Datasource[] => { + const datasources: Datasource[] = []; + settings.forEach((dsSettings) => { + const dataKeys: DataKey[] = getMapLatestDataLayerDatasourceDataKeys(dsSettings, dataLayerType); + const datasource: Datasource = mapDataSourceSettingsToDatasource(dsSettings); + datasource.dataKeys.push(...dataKeys); + datasources.push(datasource); + if ((dsSettings).additionalDataSources?.length) { + (dsSettings).additionalDataSources.forEach((ds) => { + const additionalDatasource: Datasource = mapDataSourceSettingsToDatasource(ds); + additionalDatasource.dataKeys.push(...dataKeys); + datasources.push(additionalDatasource); + }); + } + }); + return datasources; +}; + +const getMapLatestDataLayerDatasourceDataKeys = (settings: MapDataLayerSettings, + dataLayerType: MapDataLayerType): DataKey[] => { + const dataKeys = settings.additionalDataKeys || []; + switch (dataLayerType) { + case 'markers': + const markersSettings = settings as MarkersDataLayerSettings; + dataKeys.push(markersSettings.xKey, markersSettings.yKey); + break; + case 'polygons': + dataKeys.push((settings as PolygonsDataLayerSettings).polygonKey); + break; + case 'circles': + dataKeys.push((settings as CirclesDataLayerSettings).circleKey); + break; + } + return dataKeys; +}; diff --git a/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts b/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts index 1b54240c09..21dc801b3f 100644 --- a/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts +++ b/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts @@ -25,6 +25,7 @@ export interface WidgetModelDefinition { prepareExportInfo(dashboard: Dashboard, widget: Widget): T; updateFromExportInfo(widget: Widget, entityAliases: EntityAliases, filters: Filters, info: T): void; datasources(widget: Widget): Datasource[]; + hasTimewindow(widget: Widget): boolean; } const widgetModelRegistry: WidgetModelDefinition[] = [