From e7dca95e01bd69f12d547deb8cb2859d3d787581 Mon Sep 17 00:00:00 2001 From: Ekaterina Chantsova Date: Fri, 29 Nov 2024 15:08:01 +0200 Subject: [PATCH] Timewindow: take into account default and allowed group intervals when switching between realtime and history --- .../timewindow-config-dialog.component.ts | 123 +++++++++--------- .../time/timewindow-panel.component.ts | 104 ++++++++------- .../src/app/shared/models/time/time.models.ts | 58 +++++++-- 3 files changed, 165 insertions(+), 120 deletions(-) diff --git a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts index 9ba145df4a..7bf7153313 100644 --- a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts +++ b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts @@ -26,7 +26,8 @@ import { realtimeAllowedAggIntervals, RealtimeWindowType, realtimeWindowTypeTranslations, - Timewindow, TimewindowAggIntervalsConfig, + Timewindow, + TimewindowAggIntervalsConfig, TimewindowType, updateFormValuesOnTimewindowTypeChange } from '@shared/models/time/time.models'; @@ -234,62 +235,65 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On hideTimezone: [ isDefinedAndNotNull(this.timewindow.hideTimezone) ? this.timewindow.hideTimezone : false ] }); - - this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((timewindowMs: number) => { - const lastAggIntervalsConfig:TimewindowAggIntervalsConfig = - this.timewindowForm.get('realtime.advancedParams.lastAggIntervalsConfig').value; - if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && - lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { - this.timewindowForm.get('realtime.interval').patchValue( - lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((quickInterval: number) => { - const quickAggIntervalsConfig:TimewindowAggIntervalsConfig = - this.timewindowForm.get('realtime.advancedParams.quickAggIntervalsConfig').value; - if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && - quickAggIntervalsConfig[quickInterval].defaultAggInterval) { - this.timewindowForm.get('realtime.interval').patchValue( - quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('history.timewindowMs').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((timewindowMs: number) => { - const lastAggIntervalsConfig:TimewindowAggIntervalsConfig = - this.timewindowForm.get('history.advancedParams.lastAggIntervalsConfig').value; - if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && - lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { - this.timewindowForm.get('history.interval').patchValue( - lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('history.quickInterval').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((quickInterval: number) => { - const quickAggIntervalsConfig:TimewindowAggIntervalsConfig = - this.timewindowForm.get('history.advancedParams.quickAggIntervalsConfig').value; - if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && - quickAggIntervalsConfig[quickInterval].defaultAggInterval) { - this.timewindowForm.get('history.interval').patchValue( - quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.updateValidators(this.timewindowForm.get('aggregation.type').value); - this.timewindowForm.get('aggregation.type').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((aggregationType: AggregationType) => { - this.updateValidators(aggregationType); - }); + + if (this.aggregation) { + this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((timewindowMs: number) => { + const lastAggIntervalsConfig: TimewindowAggIntervalsConfig = + this.timewindowForm.get('realtime.advancedParams.lastAggIntervalsConfig').value; + if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && + lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { + this.timewindowForm.get('realtime.interval').patchValue( + lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((quickInterval: number) => { + const quickAggIntervalsConfig: TimewindowAggIntervalsConfig = + this.timewindowForm.get('realtime.advancedParams.quickAggIntervalsConfig').value; + if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && + quickAggIntervalsConfig[quickInterval].defaultAggInterval) { + this.timewindowForm.get('realtime.interval').patchValue( + quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('history.timewindowMs').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((timewindowMs: number) => { + const lastAggIntervalsConfig: TimewindowAggIntervalsConfig = + this.timewindowForm.get('history.advancedParams.lastAggIntervalsConfig').value; + if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && + lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { + this.timewindowForm.get('history.interval').patchValue( + lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('history.quickInterval').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((quickInterval: number) => { + const quickAggIntervalsConfig: TimewindowAggIntervalsConfig = + this.timewindowForm.get('history.advancedParams.quickAggIntervalsConfig').value; + if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && + quickAggIntervalsConfig[quickInterval].defaultAggInterval) { + this.timewindowForm.get('history.interval').patchValue( + quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} + ); + } + }); + + this.timewindowForm.get('aggregation.type').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((aggregationType: AggregationType) => { + this.updateValidators(aggregationType); + }); + } + this.timewindowForm.get('selectedTab').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe((selectedTab: TimewindowType) => { @@ -414,13 +418,9 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On const timewindowFormValue = this.timewindowForm.getRawValue(); const realtimeDisableCustomInterval = timewindowFormValue.realtime.disableCustomInterval; const historyDisableCustomInterval = timewindowFormValue.history.disableCustomInterval; - const realtimeAllowedLastIntervals = timewindowFormValue.realtime.advancedParams.allowedLastIntervals; - const realtimeAllowedQuickIntervals = timewindowFormValue.realtime.advancedParams.allowedQuickIntervals; - const historyAllowedLastIntervals = timewindowFormValue.history.advancedParams.allowedLastIntervals; - const historyAllowedQuickIntervals = timewindowFormValue.history.advancedParams.allowedQuickIntervals; updateFormValuesOnTimewindowTypeChange(selectedTab, this.quickIntervalOnly, this.timewindowForm, realtimeDisableCustomInterval, historyDisableCustomInterval, - realtimeAllowedLastIntervals, realtimeAllowedQuickIntervals, historyAllowedLastIntervals, historyAllowedQuickIntervals); + timewindowFormValue.realtime.advancedParams, timewindowFormValue.history.advancedParams); this.timewindowForm.patchValue({ hideAggregation: timewindowFormValue.hideAggregation, hideAggInterval: timewindowFormValue.hideAggInterval, @@ -623,6 +623,7 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On if (result) { this.timewindowForm.get(allowedIntervalsControlName).patchValue(result.allowedIntervals); this.timewindowForm.get(aggIntervalsConfigControlName).patchValue(result.aggIntervalsConfig); + this.timewindowForm.markAsDirty(); } } }, diff --git a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts index 5dec11f619..14247997ac 100644 --- a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts +++ b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts @@ -18,11 +18,13 @@ import { Component, Inject, InjectionToken, OnDestroy, OnInit, ViewContainerRef import { AggregationType, currentHistoryTimewindow, - currentRealtimeTimewindow, historyAllowedAggIntervals, + currentRealtimeTimewindow, + historyAllowedAggIntervals, HistoryWindowType, historyWindowTypeTranslations, Interval, - QuickTimeInterval, realtimeAllowedAggIntervals, + QuickTimeInterval, + realtimeAllowedAggIntervals, RealtimeWindowType, realtimeWindowTypeTranslations, Timewindow, @@ -298,54 +300,56 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit, O disabled: hideTimezone }] }); - - this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((timewindowMs: number) => { - if (this.realtimeAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && - this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { - this.timewindowForm.get('realtime.interval').patchValue( - this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((quickInterval: number) => { - if (this.realtimeAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && - this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) { - this.timewindowForm.get('realtime.interval').patchValue( - this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('history.timewindowMs').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((timewindowMs: number) => { - if (this.historyAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && - this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { - this.timewindowForm.get('history.interval').patchValue( - this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.timewindowForm.get('history.quickInterval').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((quickInterval: number) => { - if (this.historyAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && - this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) { - this.timewindowForm.get('history.interval').patchValue( - this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} - ); - } - }); - this.updateValidators(this.timewindowForm.get('aggregation.type').value); - this.timewindowForm.get('aggregation.type').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((aggregationType: AggregationType) => { - this.updateValidators(aggregationType); - }); + + if (this.aggregation) { + this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((timewindowMs: number) => { + if (this.realtimeAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && + this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { + this.timewindowForm.get('realtime.interval').patchValue( + this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((quickInterval: number) => { + if (this.realtimeAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && + this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) { + this.timewindowForm.get('realtime.interval').patchValue( + this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('history.timewindowMs').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((timewindowMs: number) => { + if (this.historyAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) && + this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) { + this.timewindowForm.get('history.interval').patchValue( + this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false} + ); + } + }); + this.timewindowForm.get('history.quickInterval').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((quickInterval: number) => { + if (this.historyAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) && + this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) { + this.timewindowForm.get('history.interval').patchValue( + this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false} + ); + } + }); + + this.timewindowForm.get('aggregation.type').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((aggregationType: AggregationType) => { + this.updateValidators(aggregationType); + }); + } this.timewindowForm.get('selectedTab').valueChanges.pipe( takeUntil(this.destroy$) @@ -371,7 +375,7 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit, O private onTimewindowTypeChange(selectedTab: TimewindowType) { updateFormValuesOnTimewindowTypeChange(selectedTab, this.quickIntervalOnly, this.timewindowForm, this.realtimeDisableCustomInterval, this.historyDisableCustomInterval, - this.realtimeAllowedLastIntervals, this.realtimeAllowedQuickIntervals, this.historyAllowedLastIntervals, this.historyAllowedQuickIntervals); + this.realtimeAdvancedParams, this.historyAdvancedParams); } update() { diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index 1b9c0c8dba..bf96f9de52 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -528,8 +528,8 @@ export const timewindowTypeChanged = (newTimewindow: Timewindow, oldTimewindow: export const updateFormValuesOnTimewindowTypeChange = (selectedTab: TimewindowType, quickIntervalOnly: boolean, timewindowForm: FormGroup, realtimeDisableCustomInterval: boolean, historyDisableCustomInterval: boolean, - realtimeAllowedLastIntervals?: Array, realtimeAllowedQuickIntervals?: Array, - historyAllowedLastIntervals?: Array, historyAllowedQuickIntervals?: Array) => { + realtimeAdvancedParams?: TimewindowAdvancedParams, + historyAdvancedParams?: TimewindowAdvancedParams) => { const timewindowFormValue = timewindowForm.getRawValue(); if (selectedTab === TimewindowType.REALTIME) { if (timewindowFormValue.history.historyType !== HistoryWindowType.FIXED @@ -538,25 +538,37 @@ export const updateFormValuesOnTimewindowTypeChange = (selectedTab: TimewindowTy timewindowForm.get('realtime.realtimeType').patchValue(RealtimeWindowType[HistoryWindowType[timewindowFormValue.history.historyType]]); } if (!realtimeDisableCustomInterval || - !realtimeAllowedLastIntervals?.length || realtimeAllowedLastIntervals.includes(timewindowFormValue.history.timewindowMs)) { + !realtimeAdvancedParams?.allowedLastIntervals?.length || realtimeAdvancedParams.allowedLastIntervals.includes(timewindowFormValue.history.timewindowMs)) { timewindowForm.get('realtime.timewindowMs').patchValue(timewindowFormValue.history.timewindowMs); } - if (realtimeAllowedQuickIntervals?.includes(timewindowFormValue.history.quickInterval) || - (!realtimeAllowedQuickIntervals?.length && timewindowFormValue.history.quickInterval.startsWith('CURRENT'))) { + if (realtimeAdvancedParams?.allowedQuickIntervals?.includes(timewindowFormValue.history.quickInterval) || + (!realtimeAdvancedParams?.allowedQuickIntervals?.length && timewindowFormValue.history.quickInterval.startsWith('CURRENT'))) { timewindowForm.get('realtime.quickInterval').patchValue(timewindowFormValue.history.quickInterval); } - setTimeout(() => timewindowForm.get('realtime.interval').patchValue(timewindowFormValue.history.interval)); + const defaultAggInterval = realtimeDefaultAggInterval(timewindowForm.getRawValue(), realtimeAdvancedParams); + const allowedAggIntervals = realtimeAllowedAggIntervals(timewindowForm.getRawValue(), realtimeAdvancedParams); + if (defaultAggInterval || !allowedAggIntervals.length || allowedAggIntervals.includes(timewindowFormValue.history.interval)) { + setTimeout(() => timewindowForm.get('realtime.interval').patchValue( + defaultAggInterval ?? timewindowFormValue.history.interval + )); + } } } else { timewindowForm.get('history.historyType').patchValue(HistoryWindowType[RealtimeWindowType[timewindowFormValue.realtime.realtimeType]]); if (!historyDisableCustomInterval || - !historyAllowedLastIntervals?.length || historyAllowedLastIntervals?.includes(timewindowFormValue.realtime.timewindowMs)) { + !historyAdvancedParams?.allowedLastIntervals?.length || historyAdvancedParams.allowedLastIntervals?.includes(timewindowFormValue.realtime.timewindowMs)) { timewindowForm.get('history.timewindowMs').patchValue(timewindowFormValue.realtime.timewindowMs); } - if (!historyAllowedQuickIntervals?.length || historyAllowedQuickIntervals?.includes(timewindowFormValue.realtime.quickInterval)) { + if (!historyAdvancedParams?.allowedQuickIntervals?.length || historyAdvancedParams.allowedQuickIntervals?.includes(timewindowFormValue.realtime.quickInterval)) { timewindowForm.get('history.quickInterval').patchValue(timewindowFormValue.realtime.quickInterval); } - setTimeout(() => timewindowForm.get('history.interval').patchValue(timewindowFormValue.realtime.interval)); + const defaultAggInterval = historyDefaultAggInterval(timewindowForm.getRawValue(), historyAdvancedParams); + const allowedAggIntervals = historyAllowedAggIntervals(timewindowForm.getRawValue(), historyAdvancedParams); + if (defaultAggInterval || !allowedAggIntervals.length || allowedAggIntervals.includes(timewindowFormValue.realtime.interval)) { + setTimeout(() => timewindowForm.get('history.interval').patchValue( + defaultAggInterval ?? timewindowFormValue.realtime.interval + )); + } } timewindowForm.patchValue({ aggregation: { @@ -619,6 +631,34 @@ export const historyAllowedAggIntervals = (timewindow: Timewindow, return []; }; +export const realtimeDefaultAggInterval = (timewindow: Timewindow, + advancedParams: TimewindowAdvancedParams): Interval => { + if (timewindow.realtime.realtimeType === RealtimeWindowType.LAST_INTERVAL && + advancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindow.realtime.timewindowMs) && + advancedParams.lastAggIntervalsConfig[timewindow.realtime.timewindowMs].defaultAggInterval) { + return advancedParams.lastAggIntervalsConfig[timewindow.realtime.timewindowMs].defaultAggInterval; + } else if (timewindow.realtime.realtimeType === RealtimeWindowType.INTERVAL && + advancedParams?.quickAggIntervalsConfig?.hasOwnProperty(timewindow.realtime.quickInterval) && + advancedParams.quickAggIntervalsConfig[timewindow.realtime.quickInterval].defaultAggInterval) { + return advancedParams.quickAggIntervalsConfig[timewindow.realtime.quickInterval].defaultAggInterval; + } + return null; +}; + +export const historyDefaultAggInterval = (timewindow: Timewindow, + advancedParams: TimewindowAdvancedParams): Interval => { + if (timewindow.history.historyType === HistoryWindowType.LAST_INTERVAL && + advancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindow.history.timewindowMs) && + advancedParams.lastAggIntervalsConfig[timewindow.history.timewindowMs].defaultAggInterval) { + return advancedParams.lastAggIntervalsConfig[timewindow.history.timewindowMs].defaultAggInterval; + } else if (timewindow.history.historyType === HistoryWindowType.INTERVAL && + advancedParams?.quickAggIntervalsConfig?.hasOwnProperty(timewindow.history.quickInterval) && + advancedParams.quickAggIntervalsConfig[timewindow.history.quickInterval].defaultAggInterval) { + return advancedParams.quickAggIntervalsConfig[timewindow.history.quickInterval].defaultAggInterval; + } + return null; +}; + export const getTimezone = (tz: string): moment_.Moment => moment.tz(tz); export const calculateTsOffset = (timezone?: string): number => {