@c8y/ngx-components 1023.7.3 → 1023.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/context-dashboard/index.d.ts.map +1 -1
  2. package/context-dashboard-state/index.d.ts.map +1 -1
  3. package/fesm2022/c8y-ngx-components-context-dashboard-state.mjs +0 -1
  4. package/fesm2022/c8y-ngx-components-context-dashboard-state.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +0 -6
  6. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-global-context.mjs +296 -283
  8. package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-map.mjs +11 -4
  10. package/fesm2022/c8y-ngx-components-map.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +2 -8
  12. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +2 -1
  14. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +4 -16
  16. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components.mjs +2 -2
  18. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  19. package/global-context/index.d.ts +68 -57
  20. package/global-context/index.d.ts.map +1 -1
  21. package/locales/locales.pot +40 -31
  22. package/map/index.d.ts +8 -0
  23. package/map/index.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/widgets/implementations/alarms/index.d.ts.map +1 -1
  26. package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -1
  27. package/widgets/implementations/datapoints-table/index.d.ts.map +1 -1
@@ -23,6 +23,7 @@ import * as i2 from 'ngx-bootstrap/dropdown';
23
23
  import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
24
24
  import { A11yModule } from '@angular/cdk/a11y';
25
25
  import { withLatestFrom, filter as filter$1, tap, distinctUntilChanged as distinctUntilChanged$1, map as map$1 } from 'rxjs/operators';
26
+ import { TranslateService } from '@ngx-translate/core';
26
27
 
27
28
  const GLOBAL_CONTEXT_EVENTS = {
28
29
  STATE_CHANGE: 'GLOBAL_CONTEXT_STATE_CHANGE',
@@ -127,8 +128,8 @@ const GLOBAL_CONTEXT_DEFAULTS = {
127
128
  REFRESH_OPTION: REFRESH_OPTION.LIVE,
128
129
  /** Default auto-refresh state */
129
130
  IS_AUTO_REFRESH_ENABLED: true,
130
- /** Default refresh interval in milliseconds (30 seconds) */
131
- REFRESH_INTERVAL: 30000,
131
+ /** Default refresh interval in milliseconds (5 seconds) */
132
+ REFRESH_INTERVAL: 5000,
132
133
  /** Default aggregation type */
133
134
  AGGREGATION: null,
134
135
  /** Default display mode */
@@ -146,28 +147,22 @@ const LINK_BTNS_CONFIG = {
146
147
  dateTimeContext: {
147
148
  formControlName: 'dateTimeContext',
148
149
  settingKey: 'showTimeContext',
149
- label: 'time context',
150
+ label: gettext('date/time'),
150
151
  cssClass: 'time-context',
151
- linkTooltip: gettext('Link time context to global context'),
152
- unlinkTooltip: gettext('Unlink time context from global context'),
153
152
  icon: 'calendar'
154
153
  },
155
154
  isAutoRefreshEnabled: {
156
155
  formControlName: 'isAutoRefreshEnabled',
157
156
  settingKey: 'showAutoRefresh',
158
- label: 'auto-refresh',
157
+ label: gettext('auto refresh'),
159
158
  cssClass: 'auto-refresh',
160
- linkTooltip: gettext('Link auto-refresh to global context'),
161
- unlinkTooltip: gettext('Unlink auto-refresh from global context'),
162
159
  icon: 'refresh'
163
160
  },
164
161
  aggregation: {
165
162
  formControlName: 'aggregation',
166
163
  settingKey: 'showAggregation',
167
- label: 'aggregation',
164
+ label: gettext('aggregation'),
168
165
  cssClass: 'aggregation',
169
- linkTooltip: gettext('Link aggregation to global context'),
170
- unlinkTooltip: gettext('Unlink aggregation from global context'),
171
166
  icon: 'input'
172
167
  }
173
168
  };
@@ -524,7 +519,10 @@ function fillMissingDefaults(state) {
524
519
  return {
525
520
  ...defaults,
526
521
  ...state,
527
- dateTimeContext
522
+ dateTimeContext,
523
+ // Always override refreshInterval to use the fixed 5s default
524
+ // This ensures old dashboards with custom intervals are migrated to the new fixed interval
525
+ refreshInterval: GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL
528
526
  };
529
527
  }
530
528
  /**
@@ -893,7 +891,8 @@ class GlobalContextFormService {
893
891
  dateTimeContext: formValue.dateTimeContext,
894
892
  aggregation: formValue.aggregation,
895
893
  isAutoRefreshEnabled: formValue.isAutoRefreshEnabled,
896
- refreshInterval: formValue.refreshInterval,
894
+ // Always use fixed 5s interval, ignore any form value
895
+ refreshInterval: GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL,
897
896
  refreshOption: formValue.refreshOption
898
897
  };
899
898
  }
@@ -1515,7 +1514,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1515
1514
  class WidgetConfigMigrationService {
1516
1515
  constructor(dateTimeContextPickerService) {
1517
1516
  this.dateTimeContextPickerService = dateTimeContextPickerService;
1518
- this.REALTIME_INTERVAL = 5000; // 5 seconds for realtime
1519
1517
  }
1520
1518
  /**
1521
1519
  * Transforms legacy widget configurations into the standardized GlobalContextState format.
@@ -1686,16 +1684,9 @@ class WidgetConfigMigrationService {
1686
1684
  if (config.isAutoRefreshEnabled === undefined) {
1687
1685
  config.isAutoRefreshEnabled = this.resolveAutoRefreshEnabled(isRealtime, typeof legacyRefreshOption === 'string' ? legacyRefreshOption : undefined);
1688
1686
  }
1689
- // Refresh Interval - always use from mergedSettings if available (to honor nested configs)
1690
- if (mergedSettings.refreshInterval !== undefined) {
1691
- config.refreshInterval =
1692
- typeof mergedSettings.refreshInterval === 'number'
1693
- ? mergedSettings.refreshInterval
1694
- : GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
1695
- }
1696
- else if (config.refreshInterval === undefined) {
1697
- config.refreshInterval = this.resolveRefreshInterval(isRealtime, mergedSettings);
1698
- }
1687
+ // Refresh Interval - always use default 5s interval (ignore stored values)
1688
+ // This ensures old dashboards with custom intervals are migrated to the fixed 5s interval
1689
+ config.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
1699
1690
  }
1700
1691
  /**
1701
1692
  * Determines the appropriate display mode based on legacy widget configuration.
@@ -1871,28 +1862,6 @@ class WidgetConfigMigrationService {
1871
1862
  }
1872
1863
  return true; // Default to enabled (including interval='none')
1873
1864
  }
1874
- /**
1875
- * Resolves the refresh interval in milliseconds.
1876
- *
1877
- * Priority:
1878
- * 1. Realtime widgets → 5000ms (5 seconds)
1879
- * 2. Explicit refreshInterval in settings → use as-is
1880
- * 3. Default → GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL
1881
- *
1882
- * @param isRealtime - Whether the widget is in realtime mode
1883
- * @param settings - Widget settings potentially containing refreshInterval
1884
- * @returns Refresh interval in milliseconds
1885
- *
1886
- */
1887
- resolveRefreshInterval(isRealtime, settings) {
1888
- if (isRealtime) {
1889
- return this.REALTIME_INTERVAL;
1890
- }
1891
- if (typeof settings.refreshInterval === 'number') {
1892
- return settings.refreshInterval;
1893
- }
1894
- return GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
1895
- }
1896
1865
  /**
1897
1866
  * Detects if a widget is configured for realtime operation.
1898
1867
  *
@@ -2945,7 +2914,6 @@ class HistoryModeConfigurationControlsComponent {
2945
2914
  }
2946
2915
  }
2947
2916
  constructor() {
2948
- this.DEFAULT_INTERVAL_VALUES = DEFAULT_INTERVAL_VALUES;
2949
2917
  this.AGGREGATION_TEXTS = AGGREGATION_TEXTS;
2950
2918
  this.DATE_FORMAT = 'medium';
2951
2919
  this.errorMessages = {
@@ -2955,7 +2923,7 @@ class HistoryModeConfigurationControlsComponent {
2955
2923
  invalidDateRange: gettext('Start date must be before end date.')
2956
2924
  };
2957
2925
  // Popover messages for translation extraction
2958
- this.TIME_RANGE_PICKER_POPOVER = gettext('Sets a rolling time window relative to the current time. As time progresses, the window automatically shifts to maintain the selected duration, always showing the most recent data.');
2926
+ this.TIME_RANGE_PICKER_POPOVER = gettext('Specify the exact start and end date/time of the time period to analyse. This provides a static view of historical data within the selected timeframe.');
2959
2927
  this.AGGREGATION_POPOVER = gettext("Groups data points into larger time intervals to simplify visualization and improve performance. 'None' shows raw data, while other options combine data points into minute, hour, or day groupings.");
2960
2928
  this.destroyRef = inject(DestroyRef);
2961
2929
  this.formBuilder = inject(FormBuilder);
@@ -3130,7 +3098,7 @@ class HistoryModeConfigurationControlsComponent {
3130
3098
  };
3131
3099
  }
3132
3100
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HistoryModeConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3133
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: HistoryModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-history-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", validationStatus: "validationStatus" }, ngImport: i0, template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date filter' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-6 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex flex-wrap col-6 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-\">\n @if (SHOW_AGGREGATION) {\n @let selectedAggregation = currentForm.get('aggregation')?.value;\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"p-t-16 p-b-16 m-b-4\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n [disabledAggregations]=\"disabledAggregations()\"\n [layout]=\"'radio'\"\n ></c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3101
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: HistoryModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-history-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", validationStatus: "validationStatus" }, ngImport: i0, template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date & time range' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-6 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex flex-wrap col-6 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-\">\n @if (SHOW_AGGREGATION) {\n @let selectedAggregation = currentForm.get('aggregation')?.value;\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"p-t-16 p-b-16 m-b-4\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n [disabledAggregations]=\"disabledAggregations()\"\n [layout]=\"'radio'\"\n ></c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3134
3102
  }
3135
3103
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HistoryModeConfigurationControlsComponent, decorators: [{
3136
3104
  type: Component,
@@ -3148,57 +3116,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3148
3116
  MessageDirective,
3149
3117
  DateTimePickerModule,
3150
3118
  NgClass
3151
- ], template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date filter' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-6 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex flex-wrap col-6 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-\">\n @if (SHOW_AGGREGATION) {\n @let selectedAggregation = currentForm.get('aggregation')?.value;\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"p-t-16 p-b-16 m-b-4\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n [disabledAggregations]=\"disabledAggregations()\"\n [layout]=\"'radio'\"\n ></c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n" }]
3119
+ ], template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date & time range' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-6 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex flex-wrap col-6 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-\">\n @if (SHOW_AGGREGATION) {\n @let selectedAggregation = currentForm.get('aggregation')?.value;\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"p-t-16 p-b-16 m-b-4\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n [disabledAggregations]=\"disabledAggregations()\"\n [layout]=\"'radio'\"\n ></c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n" }]
3152
3120
  }], ctorParameters: () => [], propDecorators: { settings: [{
3153
3121
  type: Input
3154
3122
  }], context: [{
3155
3123
  type: Input
3156
3124
  }], contextChange: [{ type: i0.Output, args: ["contextChange"] }], validationStatus: [{ type: i0.Output, args: ["validationStatus"] }] } });
3157
3125
 
3158
- class AutoRefreshSelectControlComponent {
3159
- constructor() {
3160
- this.DEFAULT_INTERVAL_VALUES = DEFAULT_INTERVAL_VALUES;
3161
- this.START_INTERVAL_VALUE = 30_000;
3162
- this.SECONDS_UNTIL_REFRESH = gettext('{{ seconds }} s`until refresh`');
3163
- this.intervalValueChange = output();
3164
- this.autoRefreshSeconds = signal(undefined, ...(ngDevMode ? [{ debugName: "autoRefreshSeconds" }] : []));
3165
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3166
- this.onTouched = () => { };
3167
- }
3168
- registerOnChange(fn) {
3169
- this.onChange = fn;
3170
- }
3171
- registerOnTouched(fn) {
3172
- this.onTouched = fn;
3173
- }
3174
- writeValue(autoRefreshSeconds) {
3175
- this.autoRefreshSeconds.set(autoRefreshSeconds);
3176
- }
3177
- onIntervalChange(autoRefreshSeconds) {
3178
- this.onChange(autoRefreshSeconds);
3179
- this.autoRefreshSeconds.set(autoRefreshSeconds);
3180
- this.intervalValueChange.emit();
3181
- }
3182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoRefreshSelectControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AutoRefreshSelectControlComponent, isStandalone: true, selector: "c8y-auto-refresh-select-control", outputs: { intervalValueChange: "intervalValueChange" }, providers: [
3184
- {
3185
- provide: NG_VALUE_ACCESSOR,
3186
- useExisting: forwardRef(() => AutoRefreshSelectControlComponent),
3187
- multi: true
3188
- }
3189
- ], ngImport: i0, template: "@let refreshIntervalLabel = 'Refresh interval in seconds' | translate;\n@let secondsTranslation = SECONDS_UNTIL_REFRESH | translate;\n\n<div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [attr.aria-label]=\"refreshIntervalLabel\"\n [tooltip]=\"refreshIntervalLabel\"\n placement=\"bottom\"\n data-cy=\"global-context--refresh-interval-select\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [container]=\"'body'\"\n mode\n [ngModel]=\"autoRefreshSeconds()\"\n (ngModelChange)=\"onIntervalChange($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n @for (refreshInterval of DEFAULT_INTERVAL_VALUES; track refreshInterval) {\n @let isSelected = refreshInterval === START_INTERVAL_VALUE;\n @let secondsValue = refreshInterval / 1000;\n\n <option\n [ngValue]=\"refreshInterval\"\n [attr.selected]=\"isSelected ? '' : null\"\n >\n @if (secondsValue === 5) {\n {{ 'Auto' | translate }}\n } @else {\n {{ '{{ seconds }}s' | translate: { seconds: secondsValue } }}\n }\n </option>\n }\n </select>\n <span></span>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3190
- }
3191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoRefreshSelectControlComponent, decorators: [{
3192
- type: Component,
3193
- args: [{ selector: 'c8y-auto-refresh-select-control', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3194
- {
3195
- provide: NG_VALUE_ACCESSOR,
3196
- useExisting: forwardRef(() => AutoRefreshSelectControlComponent),
3197
- multi: true
3198
- }
3199
- ], standalone: true, imports: [C8yTranslatePipe, TooltipModule, FormsModule], template: "@let refreshIntervalLabel = 'Refresh interval in seconds' | translate;\n@let secondsTranslation = SECONDS_UNTIL_REFRESH | translate;\n\n<div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [attr.aria-label]=\"refreshIntervalLabel\"\n [tooltip]=\"refreshIntervalLabel\"\n placement=\"bottom\"\n data-cy=\"global-context--refresh-interval-select\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [container]=\"'body'\"\n mode\n [ngModel]=\"autoRefreshSeconds()\"\n (ngModelChange)=\"onIntervalChange($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n @for (refreshInterval of DEFAULT_INTERVAL_VALUES; track refreshInterval) {\n @let isSelected = refreshInterval === START_INTERVAL_VALUE;\n @let secondsValue = refreshInterval / 1000;\n\n <option\n [ngValue]=\"refreshInterval\"\n [attr.selected]=\"isSelected ? '' : null\"\n >\n @if (secondsValue === 5) {\n {{ 'Auto' | translate }}\n } @else {\n {{ '{{ seconds }}s' | translate: { seconds: secondsValue } }}\n }\n </option>\n }\n </select>\n <span></span>\n</div>\n" }]
3200
- }], propDecorators: { intervalValueChange: [{ type: i0.Output, args: ["intervalValueChange"] }] } });
3201
-
3202
3126
  class IntervalPickerComponent {
3203
3127
  constructor() {
3204
3128
  this.INTERVALS = [...INTERVALS];
@@ -3591,9 +3515,8 @@ class LiveModeConfigurationControlsComponent {
3591
3515
  this.patchFormFromContext(cloned);
3592
3516
  }
3593
3517
  constructor() {
3594
- this.DEFAULT_INTERVAL_VALUES = DEFAULT_INTERVAL_VALUES;
3595
3518
  // Popover messages for translation extraction
3596
- this.REFRESH_INTERVAL_POPOVER_MESSAGE = gettext('The update method is determined by the widget type. Some widgets support real-time updates via WebSocket connection, while others use periodic refreshes at predefined intervals.');
3519
+ this.REFRESH_POPOVER_MESSAGE = gettext('The update method is determined by the widget type. Some widgets support real-time updates via WebSocket connection, while others use periodic refreshes.');
3597
3520
  this.TIME_RANGE_PICKER_POPOVER = gettext('Sets a rolling time window relative to the current time. As time progresses, the window automatically shifts to maintain the selected duration, always showing the most recent data.');
3598
3521
  this.destroyRef = inject(DestroyRef);
3599
3522
  this.formBuilder = inject(FormBuilder);
@@ -3610,7 +3533,7 @@ class LiveModeConfigurationControlsComponent {
3610
3533
  .subscribe(value => {
3611
3534
  this.contextChange.emit({
3612
3535
  dateTimeContext: value.dateTimeContext ?? null,
3613
- refreshInterval: value.refreshInterval ?? null,
3536
+ refreshInterval: GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL,
3614
3537
  isAutoRefreshEnabled: value.isAutoRefreshEnabled ?? null,
3615
3538
  aggregation: null
3616
3539
  });
@@ -3620,8 +3543,8 @@ class LiveModeConfigurationControlsComponent {
3620
3543
  createForm() {
3621
3544
  return this.formBuilder.group({
3622
3545
  dateTimeContext: this.formBuilder.control(null),
3623
- refreshInterval: this.formBuilder.control(null),
3624
- isAutoRefreshEnabled: this.formBuilder.control(null)
3546
+ refreshInterval: this.formBuilder.control(GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL),
3547
+ isAutoRefreshEnabled: this.formBuilder.control(true)
3625
3548
  });
3626
3549
  }
3627
3550
  patchFormFromContext(context) {
@@ -3629,15 +3552,15 @@ class LiveModeConfigurationControlsComponent {
3629
3552
  return;
3630
3553
  }
3631
3554
  const ctx = context ?? this.currentContext();
3632
- const { dateTimeContext, refreshInterval, isAutoRefreshEnabled } = ctx;
3555
+ const { dateTimeContext, isAutoRefreshEnabled } = ctx;
3633
3556
  this.form.patchValue({
3634
3557
  dateTimeContext: dateTimeContext ? structuredClone(dateTimeContext) : null,
3635
- refreshInterval: refreshInterval ?? null,
3558
+ refreshInterval: GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL,
3636
3559
  isAutoRefreshEnabled: isAutoRefreshEnabled ?? null
3637
3560
  }, { emitEvent: false });
3638
3561
  }
3639
3562
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LiveModeConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3640
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: LiveModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-live-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"btn-icon-dot auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_INTERVAL_POPOVER_MESSAGE | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <ng-container>\n <label\n class=\"m-b-0 text-12 text-nowrap\"\n for=\"refreshInterval\"\n >\n {{ 'Refresh interval' | translate }}\n </label>\n <c8y-auto-refresh-select-control\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n </ng-container>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date filter' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: AutoRefreshSelectControlComponent, selector: "c8y-auto-refresh-select-control", outputs: ["intervalValueChange"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3563
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: LiveModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-live-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date & time' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"standalone btn-icon-dot__item auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_POPOVER_MESSAGE | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <label class=\"c8y-switch c8y-switch--inline\">\n <input\n type=\"checkbox\"\n #arInput\n formControlName=\"isAutoRefreshEnabled\"\n />\n <span></span>\n <span>\n {{ 'Auto refresh enabled' | translate }}\n </span>\n </label>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3641
3564
  }
3642
3565
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LiveModeConfigurationControlsComponent, decorators: [{
3643
3566
  type: Component,
@@ -3649,9 +3572,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3649
3572
  IconDirective,
3650
3573
  FormsModule,
3651
3574
  PopoverModule,
3652
- FormGroupComponent,
3653
- AutoRefreshSelectControlComponent
3654
- ], template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"btn-icon-dot auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_INTERVAL_POPOVER_MESSAGE | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <ng-container>\n <label\n class=\"m-b-0 text-12 text-nowrap\"\n for=\"refreshInterval\"\n >\n {{ 'Refresh interval' | translate }}\n </label>\n <c8y-auto-refresh-select-control\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n </ng-container>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"btn-icon-dot time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date filter' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n" }]
3575
+ FormGroupComponent
3576
+ ], template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date & time' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"standalone btn-icon-dot__item auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_POPOVER_MESSAGE | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <label class=\"c8y-switch c8y-switch--inline\">\n <input\n type=\"checkbox\"\n #arInput\n formControlName=\"isAutoRefreshEnabled\"\n />\n <span></span>\n <span>\n {{ 'Auto refresh enabled' | translate }}\n </span>\n </label>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n" }]
3655
3577
  }], ctorParameters: () => [], propDecorators: { settings: [{
3656
3578
  type: Input
3657
3579
  }], context: [{
@@ -3795,7 +3717,7 @@ class ConfigurationControlsComponent {
3795
3717
  <i [c8yIcon]="'process'"></i>
3796
3718
  <div>
3797
3719
  <p class="text-bold">{{ MODE_LABELS.LIVE | translate }}</p>
3798
- <p class="text-12 l-h-tight">
3720
+ <p class="tab-description text-12 l-h-tight">
3799
3721
  {{ MODE_DESCRIPTIONS.LIVE | translate }}
3800
3722
  </p>
3801
3723
  </div>
@@ -3804,7 +3726,7 @@ class ConfigurationControlsComponent {
3804
3726
  <i [c8yIcon]="'schedule1'"></i>
3805
3727
  <div>
3806
3728
  <p class="text-bold">{{ MODE_LABELS.HISTORY | translate }}</p>
3807
- <p class="text-12 l-h-tight">
3729
+ <p class="tab-description text-12 l-h-tight">
3808
3730
  {{ MODE_DESCRIPTIONS.HISTORY | translate }}
3809
3731
  </p>
3810
3732
  </div>
@@ -3854,7 +3776,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3854
3776
  <i [c8yIcon]="'process'"></i>
3855
3777
  <div>
3856
3778
  <p class="text-bold">{{ MODE_LABELS.LIVE | translate }}</p>
3857
- <p class="text-12 l-h-tight">
3779
+ <p class="tab-description text-12 l-h-tight">
3858
3780
  {{ MODE_DESCRIPTIONS.LIVE | translate }}
3859
3781
  </p>
3860
3782
  </div>
@@ -3863,7 +3785,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3863
3785
  <i [c8yIcon]="'schedule1'"></i>
3864
3786
  <div>
3865
3787
  <p class="text-bold">{{ MODE_LABELS.HISTORY | translate }}</p>
3866
- <p class="text-12 l-h-tight">
3788
+ <p class="tab-description text-12 l-h-tight">
3867
3789
  {{ MODE_DESCRIPTIONS.HISTORY | translate }}
3868
3790
  </p>
3869
3791
  </div>
@@ -4650,9 +4572,9 @@ class AutoRefreshControlComponent {
4650
4572
  };
4651
4573
  this.isAutoRefreshConnected = false;
4652
4574
  this.disableCounter = false;
4653
- this.DISABLE_AUTO_REFRESH = gettext('Disable auto refresh');
4654
- this.ENABLE_AUTO_REFRESH = gettext('Enable auto refresh');
4655
- this.DEFAULT_INTERVAL_VALUE = 30_000;
4575
+ this.DISABLE_AUTO_REFRESH = gettext('Auto refresh enabled');
4576
+ this.ENABLE_AUTO_REFRESH = gettext('Auto refresh paused');
4577
+ this.DEFAULT_INTERVAL_VALUE = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
4656
4578
  this.countdownComponentReady$ = new BehaviorSubject(null);
4657
4579
  this.loading$ = new BehaviorSubject(false);
4658
4580
  this.destroyRef = inject(DestroyRef);
@@ -4664,18 +4586,14 @@ class AutoRefreshControlComponent {
4664
4586
  // eslint-disable-next-line @typescript-eslint/no-empty-function
4665
4587
  this.onTouched = () => { };
4666
4588
  }
4667
- set autoRefreshSeconds(value) {
4668
- this.autoRefreshSeconds$ = new BehaviorSubject(value);
4669
- if (value === 5000) {
4670
- this.countdownIntervalConfig = {
4671
- enforcePulseIcon: true
4672
- };
4673
- }
4674
- else {
4675
- this.countdownIntervalConfig = {
4676
- enforcePulseIcon: false
4677
- };
4678
- }
4589
+ set autoRefreshSeconds(_value) {
4590
+ // Value hardcoded to 5000ms for now, as per requirements
4591
+ // It will be adjusted later when dynamic intervals are supported (based on the request execution time)
4592
+ this.autoRefreshSeconds$ = new BehaviorSubject(GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL);
4593
+ // Always show pulse icon, never show countdown timer
4594
+ this.countdownIntervalConfig = {
4595
+ enforcePulseIcon: true
4596
+ };
4679
4597
  }
4680
4598
  set isLoading(value) {
4681
4599
  const wasLoading = this._isLoading;
@@ -4850,7 +4768,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
4850
4768
  class ContextControlsComponent {
4851
4769
  constructor() {
4852
4770
  // Static properties
4853
- this.DEFAULT_INTERVAL_VALUES = DEFAULT_INTERVAL_VALUES;
4854
4771
  this.REFRESH_OPTION = REFRESH_OPTION;
4855
4772
  // Inputs
4856
4773
  this.showDisplayModeLabel = false;
@@ -4931,7 +4848,7 @@ class ContextControlsComponent {
4931
4848
  return pick(settings, requiredKeys);
4932
4849
  }
4933
4850
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ContextControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4934
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ContextControlsComponent, isStandalone: true, selector: "c8y-context-controls", inputs: { showDisplayModeLabel: "showDisplayModeLabel", isLoading: "isLoading", settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", refresh: "refresh", contextClick: "contextClick" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-start form-control\">\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No linked widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-center form-control\">\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No linked widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: TimeRangeDisplayComponent, selector: "c8y-time-range-display", inputs: ["dateTimeContext", "mode"] }, { kind: "component", type: AggregationDisplayComponent, selector: "c8y-aggregation-display", inputs: ["aggregation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4851
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ContextControlsComponent, isStandalone: true, selector: "c8y-context-controls", inputs: { showDisplayModeLabel: "showDisplayModeLabel", isLoading: "isLoading", settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", refresh: "refresh", contextClick: "contextClick" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-start form-control\">\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-center form-control\">\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: TimeRangeDisplayComponent, selector: "c8y-time-range-display", inputs: ["dateTimeContext", "mode"] }, { kind: "component", type: AggregationDisplayComponent, selector: "c8y-aggregation-display", inputs: ["aggregation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4935
4852
  }
4936
4853
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ContextControlsComponent, decorators: [{
4937
4854
  type: Component,
@@ -4947,7 +4864,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
4947
4864
  TimeRangeDisplayComponent,
4948
4865
  AggregationDisplayComponent,
4949
4866
  AsyncPipe
4950
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-start form-control\">\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No linked widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-center form-control\">\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No linked widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n" }]
4867
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-start form-control\">\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event); $event.stopPropagation()\"\n >\n <div class=\"d-col a-i-center form-control\">\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n" }]
4951
4868
  }], propDecorators: { showDisplayModeLabel: [{
4952
4869
  type: Input
4953
4870
  }], isLoading: [{
@@ -5314,6 +5231,9 @@ class GlobalContextComponent {
5314
5231
  dateTimeContext: normalized
5315
5232
  };
5316
5233
  }
5234
+ // Always enforce the fixed 5s refresh interval
5235
+ // This ensures old dashboards with custom intervals stored in dashboardState are migrated
5236
+ currentState.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
5317
5237
  return currentState;
5318
5238
  }
5319
5239
  setupDashboardSubscription() {
@@ -5875,8 +5795,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
5875
5795
  */
5876
5796
  class GlobalContextLinkControlsComponent {
5877
5797
  constructor() {
5878
- this.linkToggled = new EventEmitter();
5798
+ // Single output event - all controls toggle together (v2 pattern)
5879
5799
  this.allLinksToggled = new EventEmitter();
5800
+ this.translateService = inject(TranslateService);
5880
5801
  this._linkStates = {};
5881
5802
  this.linkStatesSignal = signal({}, ...(ngDevMode ? [{ debugName: "linkStatesSignal" }] : []));
5882
5803
  this.controlConfigsSignal = signal({}, ...(ngDevMode ? [{ debugName: "controlConfigsSignal" }] : []));
@@ -5893,8 +5814,6 @@ class GlobalContextLinkControlsComponent {
5893
5814
  key,
5894
5815
  isLinked,
5895
5816
  cssClass: (controlConfigs[key]?.cssClass || 'default').trim(),
5896
- unlinkedTooltip: controlConfigs[key]?.unlinkTooltip || '',
5897
- linkedTooltip: controlConfigs[key]?.linkTooltip || '',
5898
5817
  icon: controlConfigs[key]?.icon || '',
5899
5818
  disabled: !!controlConfigs[key]?.disabled,
5900
5819
  disabledTooltip: controlConfigs[key]?.disabledTooltip,
@@ -5910,9 +5829,22 @@ class GlobalContextLinkControlsComponent {
5910
5829
  return controls.length > 0 && controls.some(control => control.isLinked);
5911
5830
  }, ...(ngDevMode ? [{ debugName: "someControlsLinked" }] : []));
5912
5831
  this.masterTooltipText = computed(() => {
5913
- return this.allControlsLinked()
5914
- ? gettext('Unlink all from global context')
5915
- : gettext('Link all to global context');
5832
+ const controls = this.visibleControls();
5833
+ const linkedControls = controls.filter(control => control.isLinked);
5834
+ const controlConfigs = this.controlConfigsSignal();
5835
+ const clickToToggleLabel = this.translateService.instant(gettext('(click to toggle)'));
5836
+ if (linkedControls.length === 0) {
5837
+ const usingWidgetCustomTimeSettingsLabel = this.translateService.instant(gettext('Using widget custom time settings'));
5838
+ return `${usingWidgetCustomTimeSettingsLabel}\n${clickToToggleLabel}`;
5839
+ }
5840
+ const linkedNames = linkedControls.map(control => {
5841
+ const config = controlConfigs[control.key];
5842
+ return this.translateService.instant(config?.label);
5843
+ });
5844
+ const formatter = new Intl.ListFormat(this.translateService.getCurrentLang()?.replace('_', '-'), { type: 'conjunction' });
5845
+ const linkedNamesList = formatter.format(linkedNames);
5846
+ const linkedToDashboardLabel = this.translateService.instant(gettext('Synced to dashboard:'));
5847
+ return `${linkedToDashboardLabel}\n${linkedNamesList}\n${clickToToggleLabel}`;
5916
5848
  }, ...(ngDevMode ? [{ debugName: "masterTooltipText" }] : []));
5917
5849
  }
5918
5850
  set linkStates(value) {
@@ -5928,18 +5860,6 @@ class GlobalContextLinkControlsComponent {
5928
5860
  ngOnInit() {
5929
5861
  this.linkStatesSignal.set(this._linkStates);
5930
5862
  }
5931
- toggle(key) {
5932
- if (!(key in this._linkStates))
5933
- return;
5934
- const config = this.controlConfigsSignal();
5935
- if (config[key]?.disabled) {
5936
- return;
5937
- }
5938
- const newLinkState = !this._linkStates[key];
5939
- this._linkStates = { ...this._linkStates, [key]: newLinkState };
5940
- this.linkStatesSignal.set(this._linkStates);
5941
- this.linkToggled.emit({ key, isLinked: newLinkState });
5942
- }
5943
5863
  toggleAll() {
5944
5864
  const newLinkState = !this.allControlsLinked();
5945
5865
  const updatedLinkStates = { ...this._linkStates };
@@ -5955,56 +5875,35 @@ class GlobalContextLinkControlsComponent {
5955
5875
  this.allLinksToggled.emit(newLinkState);
5956
5876
  }
5957
5877
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GlobalContextLinkControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5958
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GlobalContextLinkControlsComponent, isStandalone: true, selector: "c8y-global-context-link-controls", inputs: { linkStates: "linkStates", controlConfigs: "controlConfigs" }, outputs: { linkToggled: "linkToggled", allLinksToggled: "allLinksToggled" }, ngImport: i0, template: `
5878
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GlobalContextLinkControlsComponent, isStandalone: true, selector: "c8y-global-context-link-controls", inputs: { linkStates: "linkStates", controlConfigs: "controlConfigs" }, outputs: { allLinksToggled: "allLinksToggled" }, ngImport: i0, template: `
5959
5879
  @if (showLinks()) {
5960
- <div class="input-group input-group--dots" role="group">
5961
- <!-- Master Link Toggle -->
5962
- <button
5963
- class="btn-icon-dot "
5964
- [class.active]="allControlsLinked()"
5965
- [class.partial-active]="someControlsLinked() && !allControlsLinked()"
5966
- [tooltip]="masterTooltipTemplate"
5967
- [attr.data-cy]="'global-context-link--all'"
5968
- [delay]="500"
5969
- [container]="'body'"
5970
- [placement]="'top'"
5971
- (click)="toggleAll()"
5972
- >
5880
+ <button
5881
+ class="btn-icon-dot-set"
5882
+ [class.active]="someControlsLinked()"
5883
+ [attr.aria-label]="'Global context sync controls' | translate"
5884
+ [tooltip]="masterTooltipTemplate"
5885
+ delay="500"
5886
+ container="body"
5887
+ (click)="toggleAll()"
5888
+ data-cy="global-context-link--all"
5889
+ >
5890
+ <span class="btn-icon-dot__item default" [class.active]="allControlsLinked()">
5973
5891
  <i [c8yIcon]="someControlsLinked() ? 'link' : 'unlink'"></i>
5974
- </button>
5975
- <ng-template #masterTooltipTemplate>
5976
- {{ masterTooltipText() | translate }}
5977
- </ng-template>
5978
- <!-- Individual Link Toggles -->
5892
+ </span>
5893
+ <!-- Individual Link icons -->
5979
5894
  @for (control of visibleControls(); track control.key) {
5980
- <button
5981
- [class]="control.cssClass + ' btn-icon-dot'"
5895
+ <span
5896
+ [class]="control.cssClass + ' btn-icon-dot__item'"
5982
5897
  [class.active]="control.isLinked"
5983
5898
  [class.link-disabled]="control.disabled"
5984
5899
  [class.link-auto-unlinked]="control.autoUnlinked"
5985
- [tooltip]="tooltipTemplate"
5986
5900
  [attr.data-cy]="'global-context-link--' + control.key"
5987
- [delay]="500"
5988
- [container]="'body'"
5989
- [placement]="'top'"
5990
- [disabled]="control.disabled"
5991
- (click)="toggle(control.key)"
5992
5901
  >
5993
5902
  <i [c8yIcon]="control.icon"></i>
5994
- </button>
5995
-
5996
- <ng-template #tooltipTemplate>
5997
- {{
5998
- (control.disabled
5999
- ? control.disabledTooltip
6000
- : control.isLinked
6001
- ? control.unlinkedTooltip
6002
- : control.linkedTooltip
6003
- ) | translate
6004
- }}
6005
- </ng-template>
5903
+ </span>
6006
5904
  }
6007
- </div>
5905
+ </button>
5906
+ <ng-template #masterTooltipTemplate>{{ masterTooltipText() | translate }}</ng-template>
6008
5907
  }
6009
5908
  `, isInline: true, styles: [".btn-icon-dot[disabled]{cursor:not-allowed;opacity:.75}.btn-icon-dot.link-auto-unlinked,.btn-icon-dot.link-auto-unlinked:focus{box-shadow:0 0 0 2px var(--c8y-palette-status-danger);border-color:var(--c8y-palette-status-danger)}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6010
5909
  }
@@ -6012,59 +5911,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
6012
5911
  type: Component,
6013
5912
  args: [{ selector: 'c8y-global-context-link-controls', standalone: true, imports: [IconDirective, TooltipModule, C8yTranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
6014
5913
  @if (showLinks()) {
6015
- <div class="input-group input-group--dots" role="group">
6016
- <!-- Master Link Toggle -->
6017
- <button
6018
- class="btn-icon-dot "
6019
- [class.active]="allControlsLinked()"
6020
- [class.partial-active]="someControlsLinked() && !allControlsLinked()"
6021
- [tooltip]="masterTooltipTemplate"
6022
- [attr.data-cy]="'global-context-link--all'"
6023
- [delay]="500"
6024
- [container]="'body'"
6025
- [placement]="'top'"
6026
- (click)="toggleAll()"
6027
- >
5914
+ <button
5915
+ class="btn-icon-dot-set"
5916
+ [class.active]="someControlsLinked()"
5917
+ [attr.aria-label]="'Global context sync controls' | translate"
5918
+ [tooltip]="masterTooltipTemplate"
5919
+ delay="500"
5920
+ container="body"
5921
+ (click)="toggleAll()"
5922
+ data-cy="global-context-link--all"
5923
+ >
5924
+ <span class="btn-icon-dot__item default" [class.active]="allControlsLinked()">
6028
5925
  <i [c8yIcon]="someControlsLinked() ? 'link' : 'unlink'"></i>
6029
- </button>
6030
- <ng-template #masterTooltipTemplate>
6031
- {{ masterTooltipText() | translate }}
6032
- </ng-template>
6033
- <!-- Individual Link Toggles -->
5926
+ </span>
5927
+ <!-- Individual Link icons -->
6034
5928
  @for (control of visibleControls(); track control.key) {
6035
- <button
6036
- [class]="control.cssClass + ' btn-icon-dot'"
5929
+ <span
5930
+ [class]="control.cssClass + ' btn-icon-dot__item'"
6037
5931
  [class.active]="control.isLinked"
6038
5932
  [class.link-disabled]="control.disabled"
6039
5933
  [class.link-auto-unlinked]="control.autoUnlinked"
6040
- [tooltip]="tooltipTemplate"
6041
5934
  [attr.data-cy]="'global-context-link--' + control.key"
6042
- [delay]="500"
6043
- [container]="'body'"
6044
- [placement]="'top'"
6045
- [disabled]="control.disabled"
6046
- (click)="toggle(control.key)"
6047
5935
  >
6048
5936
  <i [c8yIcon]="control.icon"></i>
6049
- </button>
6050
-
6051
- <ng-template #tooltipTemplate>
6052
- {{
6053
- (control.disabled
6054
- ? control.disabledTooltip
6055
- : control.isLinked
6056
- ? control.unlinkedTooltip
6057
- : control.linkedTooltip
6058
- ) | translate
6059
- }}
6060
- </ng-template>
5937
+ </span>
6061
5938
  }
6062
- </div>
5939
+ </button>
5940
+ <ng-template #masterTooltipTemplate>{{ masterTooltipText() | translate }}</ng-template>
6063
5941
  }
6064
5942
  `, styles: [".btn-icon-dot[disabled]{cursor:not-allowed;opacity:.75}.btn-icon-dot.link-auto-unlinked,.btn-icon-dot.link-auto-unlinked:focus{box-shadow:0 0 0 2px var(--c8y-palette-status-danger);border-color:var(--c8y-palette-status-danger)}\n"] }]
6065
- }], propDecorators: { linkToggled: [{
6066
- type: Output
6067
- }], allLinksToggled: [{
5943
+ }], propDecorators: { allLinksToggled: [{
6068
5944
  type: Output
6069
5945
  }], linkStates: [{
6070
5946
  type: Input
@@ -6159,8 +6035,12 @@ function toggleAllLinks(ctx, args) {
6159
6035
  if (outcome.recalcGlobalAggregation) {
6160
6036
  ctx.recalcGlobalAggregation();
6161
6037
  }
6162
- ctx.emitBasedOnFieldSources();
6163
- if (outcome.shouldEmitRefresh) {
6038
+ // Only emit configuration updates if not suppressed
6039
+ if (!args.suppressEmit) {
6040
+ ctx.emitBasedOnFieldSources();
6041
+ }
6042
+ // Only emit refresh if not suppressed (when unlinking, data is already loaded)
6043
+ if (outcome.shouldEmitRefresh && !args.suppressRefresh) {
6164
6044
  ctx.emitRefresh(null);
6165
6045
  }
6166
6046
  syncWithEffectiveConfig(ctx, outcome.snapshotKeys);
@@ -6277,7 +6157,7 @@ function buildControlLinkConfig(ctx, settings, linkStates) {
6277
6157
  ...baseConfig,
6278
6158
  cssClass: baseCssClass || 'default',
6279
6159
  disabled: !!disableReason,
6280
- disabledTooltip: disableReason ?? baseConfig.linkTooltip,
6160
+ disabledTooltip: disableReason ?? baseConfig.label,
6281
6161
  ...(baseAutoUnlinked !== undefined ? { autoUnlinked: baseAutoUnlinked } : {})
6282
6162
  };
6283
6163
  filteredStates[key] = linkStates?.[key] ?? false;
@@ -6953,6 +6833,10 @@ function sanitizeLocalState(state, configSignal, ensureDateTimeContext) {
6953
6833
  delete snapshot.dateTimeContext;
6954
6834
  else if (snapshot.dateTimeContext !== undefined)
6955
6835
  snapshot.dateTimeContext = ensureDateTimeContext(snapshot.dateTimeContext);
6836
+ // Always enforce the fixed 5s refresh interval
6837
+ if (snapshot.refreshInterval !== undefined) {
6838
+ snapshot.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
6839
+ }
6956
6840
  return snapshot;
6957
6841
  }
6958
6842
  function sanitizeGlobalState(state, configSignal, normalizeRefreshOption, getDefaultRefreshOption, ensureDateTimeContext) {
@@ -6960,6 +6844,10 @@ function sanitizeGlobalState(state, configSignal, normalizeRefreshOption, getDef
6960
6844
  if (snapshot.dateTimeContext !== undefined)
6961
6845
  snapshot.dateTimeContext = ensureDateTimeContext(snapshot.dateTimeContext);
6962
6846
  snapshot.refreshOption = normalizeRefreshOption(snapshot.refreshOption ?? getDefaultRefreshOption());
6847
+ // Always enforce the fixed 5s refresh interval
6848
+ if (snapshot.refreshInterval !== undefined) {
6849
+ snapshot.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
6850
+ }
6963
6851
  return snapshot;
6964
6852
  }
6965
6853
  function ensureDateTimeContext(context, configSignal) {
@@ -7156,6 +7044,8 @@ class SharedModeOrchestrator {
7156
7044
  }
7157
7045
  initConfig(config) {
7158
7046
  const cloned = structuredClone(config ?? createDefaultGlobalContextState());
7047
+ // Always enforce the fixed 5s refresh interval
7048
+ cloned.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
7159
7049
  this.configSignal.set(cloned);
7160
7050
  }
7161
7051
  initWidgetControls(controls) {
@@ -7211,36 +7101,24 @@ class SharedModeOrchestrator {
7211
7101
  this.setGlobalState(normalizedGlobalState);
7212
7102
  this.initWidgetControls(widgetControls);
7213
7103
  const widgetDisplayMode = resolveWidgetDisplayMode(initialConfig, normalizedGlobalState);
7214
- const contextDisplayMode = mapToContextDisplayMode(widgetDisplayMode);
7215
7104
  const controls = widgetControls ?? this.widgetControlsSignal();
7216
- const refreshOption = forcedRefreshOption ??
7217
- normalizedGlobalState.refreshOption ??
7218
- initialConfig?.refreshOption ??
7219
- this.getDefaultRefreshOption();
7220
- const baseLinks = isDashboard && controls
7221
- ? (this.widgetControlService.getDefaultLinksFromControls(controls, contextDisplayMode, refreshOption) ?? {})
7222
- : {};
7223
7105
  const localState = initialConfig ? { ...initialConfig } : {};
7224
7106
  const fieldSources = {};
7225
7107
  const globalSnapshot = structuredClone(normalizedGlobalState ?? {});
7226
- const resolvedLinks = baseLinks ?? {};
7108
+ // Simple rule: Dashboard mode → ALL sources global, Non-dashboard → ALL sources local
7109
+ const defaultSource = isDashboard ? FIELD_SOURCE_GLOBAL : FIELD_SOURCE_LOCAL;
7227
7110
  Object.keys(localState).forEach(key => {
7228
- fieldSources[key] = resolvedLinks[key] ? FIELD_SOURCE_GLOBAL : FIELD_SOURCE_LOCAL;
7111
+ fieldSources[key] = defaultSource;
7229
7112
  });
7230
- if (isDashboard && controls?.supports?.includes('aggregation')) {
7231
- fieldSources.aggregation = FIELD_SOURCE_GLOBAL;
7232
- }
7233
- if (fieldSources.isAutoRefreshEnabled) {
7234
- fieldSources.refreshInterval = fieldSources.isAutoRefreshEnabled;
7235
- fieldSources.refreshOption = fieldSources.isAutoRefreshEnabled;
7236
- }
7237
- if (!fieldSources.refreshOption) {
7238
- fieldSources.refreshOption = FIELD_SOURCE_GLOBAL;
7239
- }
7240
- if (fieldSources.dateTimeContext === FIELD_SOURCE_LOCAL) {
7241
- fieldSources.refreshOption = FIELD_SOURCE_LOCAL;
7113
+ // Ensure all supported controls have field sources
7114
+ if (controls?.supports) {
7115
+ controls.supports.forEach(field => {
7116
+ if (!fieldSources[field]) {
7117
+ fieldSources[field] = defaultSource;
7118
+ }
7119
+ });
7242
7120
  }
7243
- // ALWAYS GLOBAL
7121
+ // Source is ALWAYS global (tracks event origin)
7244
7122
  fieldSources.source = FIELD_SOURCE_GLOBAL;
7245
7123
  this.applyInitialModeAdjustments({
7246
7124
  isDashboard,
@@ -7262,8 +7140,15 @@ class SharedModeOrchestrator {
7262
7140
  const localState = this.localStateSignal();
7263
7141
  const globalState = this.globalStateSignal();
7264
7142
  const fieldSources = this.fieldSourcesSignal();
7143
+ // Normalize baseConfig to enforce fixed 5s refresh interval
7144
+ const normalizedBaseConfig = baseConfig
7145
+ ? {
7146
+ ...baseConfig,
7147
+ refreshInterval: GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL
7148
+ }
7149
+ : baseConfig;
7265
7150
  const composed = composeEffectiveConfig({
7266
- baseConfig,
7151
+ baseConfig: normalizedBaseConfig,
7267
7152
  localState,
7268
7153
  globalState,
7269
7154
  fieldSources
@@ -7832,10 +7717,21 @@ class GlobalContextInlineOrchestratorService {
7832
7717
  };
7833
7718
  this.live.initializeStateAndSources(liveParams);
7834
7719
  this.history.initializeStateAndSources(historyParams);
7835
- const desiredMode = params.forcedRefreshOption ??
7836
- baseGlobalState.refreshOption ??
7837
- params.initialConfig?.refreshOption ??
7838
- this.activeMode;
7720
+ // After initialization, sync the fresh states back to snapshots
7721
+ // (applyInitialModeAdjustments may have generated fresh dates in local state)
7722
+ // Use computeEffectiveConfig to merge local+global states
7723
+ const liveEffective = this.live.computeEffectiveConfig(params.initialConfig);
7724
+ const historyEffective = this.history.computeEffectiveConfig(params.initialConfig);
7725
+ this.updateModeSnapshot(REFRESH_OPTION.LIVE, liveEffective);
7726
+ this.updateModeSnapshot(REFRESH_OPTION.HISTORY, historyEffective);
7727
+ // For standalone mode, use widget's refreshOption, not global state
7728
+ // For dashboard mode, use global state's refreshOption
7729
+ const desiredMode = params.isDashboard
7730
+ ? (params.forcedRefreshOption ??
7731
+ baseGlobalState.refreshOption ??
7732
+ params.initialConfig?.refreshOption ??
7733
+ this.activeMode)
7734
+ : (params.forcedRefreshOption ?? params.initialConfig?.refreshOption ?? this.activeMode);
7839
7735
  this.ensureMode(desiredMode);
7840
7736
  }
7841
7737
  handleFormChange(context) {
@@ -7861,6 +7757,15 @@ class GlobalContextInlineOrchestratorService {
7861
7757
  this.getActive().executeHandler(context);
7862
7758
  }
7863
7759
  processRefresh(params) {
7760
+ // Choose orchestrator based on mode:
7761
+ // - Dashboard mode: use global state's refreshOption
7762
+ // - Standalone mode: use effective config's refreshOption (local state)
7763
+ const isDashboard = this.initSnapshot?.isDashboard ?? false;
7764
+ const effectiveRefreshOption = isDashboard
7765
+ ? (this.getGlobalState().refreshOption ?? this.activeMode)
7766
+ : (this.getActive().computeEffectiveConfig(this.initSnapshot?.initialConfig ?? null)
7767
+ .refreshOption ?? this.activeMode);
7768
+ this.ensureMode(effectiveRefreshOption);
7864
7769
  return this.getActive().processRefresh(params);
7865
7770
  }
7866
7771
  applyRefreshOptionChange(params) {
@@ -7942,10 +7847,17 @@ class GlobalContextInlineOrchestratorService {
7942
7847
  if (!this.initSnapshot) {
7943
7848
  return;
7944
7849
  }
7850
+ const isDashboard = this.initSnapshot.isDashboard;
7851
+ const snapshot = this.modeSnapshots[this.activeMode] ?? {};
7852
+ // For standalone mode, use the snapshot as initialConfig so fresh dates are preserved
7853
+ // For dashboard mode, use original initialConfig and snapshot goes to globalState
7854
+ const effectiveInitialConfig = isDashboard
7855
+ ? this.initSnapshot.initialConfig
7856
+ : snapshot;
7945
7857
  const params = {
7946
- initialConfig: this.initSnapshot.initialConfig,
7947
- globalState: structuredClone(this.modeSnapshots[this.activeMode] ?? {}),
7948
- isDashboard: this.initSnapshot.isDashboard,
7858
+ initialConfig: effectiveInitialConfig,
7859
+ globalState: structuredClone(snapshot),
7860
+ isDashboard,
7949
7861
  widgetControls: this.initSnapshot.widgetControls,
7950
7862
  generateFreshDateTime: this.initSnapshot.generateFreshDateTime,
7951
7863
  forcedRefreshOption: this.activeMode
@@ -8136,16 +8048,59 @@ class GlobalContextInlineComponent {
8136
8048
  handleLinkToggle(event, options) {
8137
8049
  return handleLinkToggle(this.getLinkContext(), event, options);
8138
8050
  }
8139
- toggleAllLinks(isLinked) {
8051
+ toggleAllLinks(isLinked, suppressRefresh, suppressEmit) {
8140
8052
  const supportedLinks = Object.keys(this.controlLinkStatus() || {});
8141
8053
  if (!supportedLinks.length) {
8142
8054
  return;
8143
8055
  }
8056
+ // When unlinking: suppress both refresh and emit (data is already loaded)
8057
+ // When linking: allow both refresh and emit unless explicitly suppressed
8058
+ const shouldSuppressRefresh = suppressRefresh ?? !isLinked;
8059
+ const shouldSuppressEmit = suppressEmit ?? !isLinked;
8144
8060
  toggleAllLinks(this.getLinkContext(), {
8145
8061
  keys: supportedLinks,
8146
- isLinked
8062
+ isLinked,
8063
+ suppressRefresh: shouldSuppressRefresh,
8064
+ suppressEmit: shouldSuppressEmit
8147
8065
  });
8148
8066
  }
8067
+ updateDateTimeContext(dateTimeContext) {
8068
+ this.orchestrator.updateLocalState(state => ({
8069
+ ...state,
8070
+ dateTimeContext: structuredClone(dateTimeContext)
8071
+ }));
8072
+ const dateTimeControl = this.form?.get('dateTimeContext');
8073
+ if (dateTimeControl) {
8074
+ dateTimeControl.setValue(structuredClone(dateTimeContext), { emitEvent: false });
8075
+ }
8076
+ }
8077
+ /**
8078
+ * Pause auto-refresh: sets isAutoRefreshEnabled to false and unlinks all controls.
8079
+ * This stops the auto-refresh timer and prevents the widget from receiving
8080
+ * updates from the global context.
8081
+ *
8082
+ * NOTE: Does NOT trigger any refresh or emit - data is already loaded, no updates needed.
8083
+ */
8084
+ pauseAutoRefresh() {
8085
+ // Step 1: Unlink all controls without any emissions (data already loaded)
8086
+ this.toggleAllLinks(false, // isLinked = false
8087
+ true, // suppressRefresh = true
8088
+ true // suppressEmit = true
8089
+ );
8090
+ // Step 2: Set isAutoRefreshEnabled to false without emitting events
8091
+ this.setAutoRefreshEnabled(false);
8092
+ }
8093
+ /**
8094
+ * Resume auto-refresh: sets isAutoRefreshEnabled to true and links all controls.
8095
+ * This starts the auto-refresh timer and allows the widget to receive
8096
+ * updates from the global context.
8097
+ *
8098
+ * NOTE: Triggers emissions and refresh to sync with the current global context state.
8099
+ */
8100
+ resumeAutoRefresh() {
8101
+ this.toggleAllLinks(true, false, false);
8102
+ this.setAutoRefreshEnabled(true);
8103
+ }
8149
8104
  triggerHandler(handlerName, configOverride) {
8150
8105
  const handler = this.widgetControls()?.stateHandlers?.[handlerName];
8151
8106
  const previousRefresh = this.effectiveConfig().refreshOption;
@@ -8173,6 +8128,12 @@ class GlobalContextInlineComponent {
8173
8128
  this.refresh.emit(null);
8174
8129
  }
8175
8130
  }
8131
+ setAutoRefreshEnabled(enabled) {
8132
+ const autoRefreshControl = this.form?.get('isAutoRefreshEnabled');
8133
+ if (autoRefreshControl && autoRefreshControl.value !== enabled) {
8134
+ autoRefreshControl.setValue(enabled, { emitEvent: false });
8135
+ }
8136
+ }
8176
8137
  mapToWidgetDisplayMode(mode) {
8177
8138
  switch (mode) {
8178
8139
  case GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG:
@@ -8499,7 +8460,7 @@ class GlobalContextInlineComponent {
8499
8460
  };
8500
8461
  }
8501
8462
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GlobalContextInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8502
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GlobalContextInlineComponent, isStandalone: true, selector: "c8y-global-context-inline", inputs: { widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildForLegacy: { classPropertyName: "dashboardChildForLegacy", publicName: "dashboardChildForLegacy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextInlineOrchestratorService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, static: true }], exportAs: ["globalContextInline"], ngImport: i0, template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (linkToggled)=\"handleLinkToggle($event)\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n\n @if (settings.showRefreshInterval) {\n <c8y-auto-refresh-select-control\n style=\"margin-left: -1px\"\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n }\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: GlobalContextLinkControlsComponent, selector: "c8y-global-context-link-controls", inputs: ["linkStates", "controlConfigs"], outputs: ["linkToggled", "allLinksToggled"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: AutoRefreshSelectControlComponent, selector: "c8y-auto-refresh-select-control", outputs: ["intervalValueChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8463
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GlobalContextInlineComponent, isStandalone: true, selector: "c8y-global-context-inline", inputs: { widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildForLegacy: { classPropertyName: "dashboardChildForLegacy", publicName: "dashboardChildForLegacy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextInlineOrchestratorService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, static: true }], exportAs: ["globalContextInline"], ngImport: i0, template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: GlobalContextLinkControlsComponent, selector: "c8y-global-context-link-controls", inputs: ["linkStates", "controlConfigs"], outputs: ["allLinksToggled"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8503
8464
  }
8504
8465
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GlobalContextInlineComponent, decorators: [{
8505
8466
  type: Component,
@@ -8508,13 +8469,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
8508
8469
  GlobalContextLinkControlsComponent,
8509
8470
  AggregationPickerComponent,
8510
8471
  AutoRefreshControlComponent,
8511
- AutoRefreshSelectControlComponent,
8512
8472
  DateTimeContextPickerComponent,
8513
8473
  IconDirective,
8514
8474
  C8yTranslatePipe,
8515
8475
  TooltipModule,
8516
8476
  NgTemplateOutlet
8517
- ], selector: 'c8y-global-context-inline', exportAs: 'globalContextInline', providers: [GlobalContextInlineOrchestratorService], template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (linkToggled)=\"handleLinkToggle($event)\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n\n @if (settings.showRefreshInterval) {\n <c8y-auto-refresh-select-control\n style=\"margin-left: -1px\"\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n }\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n" }]
8477
+ ], selector: 'c8y-global-context-inline', exportAs: 'globalContextInline', providers: [GlobalContextInlineOrchestratorService], template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n" }]
8518
8478
  }], ctorParameters: () => [], propDecorators: { widgetControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "widgetControls", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], dashboardChildForLegacy: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChildForLegacy", required: false }] }], refresh: [{ type: i0.Output, args: ["refresh"] }], globalContextChange: [{ type: i0.Output, args: ["globalContextChange"] }], headerTemplateRef: [{
8519
8479
  type: ViewChild,
8520
8480
  args: ['headerContent', { static: true, read: TemplateRef }]
@@ -8715,7 +8675,9 @@ class GlobalContextConfigStoreService {
8715
8675
  if (!prev) {
8716
8676
  return;
8717
8677
  }
8718
- let next = { ...prev, ...changes };
8678
+ // Filter out refreshInterval from changes - it's fixed at 5s and should not be user-modifiable
8679
+ const { refreshInterval: _, ...allowedChanges } = changes;
8680
+ let next = { ...prev, ...allowedChanges };
8719
8681
  if (!isLive) {
8720
8682
  next = this.enforceHistory(next);
8721
8683
  }
@@ -8723,6 +8685,8 @@ class GlobalContextConfigStoreService {
8723
8685
  // Live must not carry aggregation
8724
8686
  next.aggregation = null;
8725
8687
  }
8688
+ // Always enforce the fixed refresh interval
8689
+ next.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
8726
8690
  this.setIfChanged(target, next);
8727
8691
  }
8728
8692
  /**
@@ -8798,6 +8762,8 @@ class GlobalContextConfigStoreService {
8798
8762
  if (norm.refreshOption === REFRESH_OPTION.LIVE) {
8799
8763
  norm.aggregation = null;
8800
8764
  }
8765
+ // Always enforce the fixed 5s refresh interval
8766
+ norm.refreshInterval = GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL;
8801
8767
  if (norm.refreshOption === REFRESH_OPTION.HISTORY) {
8802
8768
  return this.enforceHistory(norm);
8803
8769
  }
@@ -9185,7 +9151,6 @@ class GlobalContextWidgetConfigComponent {
9185
9151
  effect(() => {
9186
9152
  const cfg = this.configInput();
9187
9153
  // Always ensure auto-refresh is enabled in the widget config
9188
- cfg.isAutoRefreshEnabled = true;
9189
9154
  const next = cfg?.displayMode ?? GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
9190
9155
  const current = this.form?.get('displayMode')?.value;
9191
9156
  if (current !== next && this.form) {
@@ -9631,7 +9596,7 @@ class PreviewControlsComponent {
9631
9596
  this.config.displayMode = GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
9632
9597
  }
9633
9598
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PreviewControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: PreviewControlsComponent, isStandalone: true, selector: "c8y-preview-controls", inputs: { widgetControls: "widgetControls", config: "config" }, ngImport: i0, template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n\n <!-- Refresh Interval Selector -->\n @if (settings.showRefreshInterval) {\n <c8y-auto-refresh-select-control\n style=\"margin-left: -1px\"\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n }\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: AutoRefreshSelectControlComponent, selector: "c8y-auto-refresh-select-control", outputs: ["intervalValueChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9599
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: PreviewControlsComponent, isStandalone: true, selector: "c8y-preview-controls", inputs: { widgetControls: "widgetControls", config: "config" }, ngImport: i0, template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9635
9600
  }
9636
9601
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PreviewControlsComponent, decorators: [{
9637
9602
  type: Component,
@@ -9642,10 +9607,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
9642
9607
  DateTimeContextPickerComponent,
9643
9608
  AggregationPickerComponent,
9644
9609
  AutoRefreshControlComponent,
9645
- AutoRefreshSelectControlComponent,
9646
9610
  TooltipModule,
9647
9611
  C8yTranslatePipe
9648
- ], selector: 'c8y-preview-controls', template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n\n <!-- Refresh Interval Selector -->\n @if (settings.showRefreshInterval) {\n <c8y-auto-refresh-select-control\n style=\"margin-left: -1px\"\n formControlName=\"refreshInterval\"\n ></c8y-auto-refresh-select-control>\n }\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"] }]
9612
+ ], selector: 'c8y-preview-controls', template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"] }]
9649
9613
  }], propDecorators: { widgetControls: [{
9650
9614
  type: Input
9651
9615
  }], config: [{
@@ -10461,6 +10425,8 @@ class GlobalContextWidgetWrapperComponent {
10461
10425
  this.internalConfig = signal({}, ...(ngDevMode ? [{ debugName: "internalConfig" }] : []));
10462
10426
  // Latest global snapshot cached for child config updates on mode change
10463
10427
  this.widgetInitialConfig = null;
10428
+ // Last emitted state - used for diff calculation to avoid race conditions
10429
+ this.lastEmittedState = signal({}, ...(ngDevMode ? [{ debugName: "lastEmittedState" }] : []));
10464
10430
  // --- Outputs ---
10465
10431
  this.globalContextChange = new EventEmitter();
10466
10432
  this.contextChangeSubject = new Subject();
@@ -10482,25 +10448,72 @@ class GlobalContextWidgetWrapperComponent {
10482
10448
  this.globalContextChange.emit(structuredClone({ context, diff }));
10483
10449
  });
10484
10450
  }
10485
- triggerHandler(handler, config) {
10486
- this.globalContextInlineComponent?.triggerHandler(handler, config);
10451
+ /**
10452
+ * Update dateTimeContext for internal widget interactions (e.g., slider drag).
10453
+ * This bypasses the config propagation logic and directly updates the inline component state.
10454
+ */
10455
+ updateDateTimeContext(dateTimeContext) {
10456
+ this.globalContextInlineComponent?.updateDateTimeContext(dateTimeContext);
10457
+ }
10458
+ /**
10459
+ * Directly toggle all link controls to linked or unlinked state.
10460
+ * All controls are always toggled together as a unified group.
10461
+ *
10462
+ * @param isLinked - True to link all controls, false to unlink all controls
10463
+ * @param suppressRefresh - True to prevent refresh emission (data already loaded)
10464
+ * @param suppressEmit - True to prevent configuration change emission
10465
+ */
10466
+ toggleAllLinks(isLinked, suppressRefresh, suppressEmit) {
10467
+ this.globalContextInlineComponent?.toggleAllLinks(isLinked, suppressRefresh, suppressEmit);
10468
+ }
10469
+ /**
10470
+ * Pause auto-refresh and unlink all controls from global context.
10471
+ * Useful when user is interacting with the widget (e.g., scrolling through a list)
10472
+ * and you want to prevent automatic updates.
10473
+ *
10474
+ * This does two things:
10475
+ * 1. Sets isAutoRefreshEnabled to false (stops the auto-refresh timer)
10476
+ * 2. Unlinks all controls (dateTimeContext, aggregation, isAutoRefreshEnabled)
10477
+ * from global context as they work as a unified group
10478
+ */
10479
+ pauseAutoRefresh() {
10480
+ this.globalContextInlineComponent?.pauseAutoRefresh();
10481
+ }
10482
+ /**
10483
+ * Resume auto-refresh and re-link all controls to global context.
10484
+ * Useful when user has finished interacting with the widget (e.g., scrolled back to top)
10485
+ * and you want to re-enable automatic updates.
10486
+ *
10487
+ * This does two things:
10488
+ * 1. Sets isAutoRefreshEnabled to true (starts the auto-refresh timer)
10489
+ * 2. Links all controls (dateTimeContext, aggregation, isAutoRefreshEnabled)
10490
+ * to global context as they work as a unified group
10491
+ */
10492
+ resumeAutoRefresh() {
10493
+ this.globalContextInlineComponent?.resumeAutoRefresh();
10487
10494
  }
10488
10495
  onGlobalContextChange(context) {
10489
- const currentConfig = this.internalConfig();
10490
- const diff = this.globalContextUtilsService.getChangedFields(currentConfig, context);
10491
10496
  const template = this.widgetControls();
10492
- const filteredContext = pick(context, template.supports);
10493
- const filteredDiff = pick(diff, template.supports);
10494
- const formattedContext = formatDateTimeContextForEmission(filteredContext, template.supports);
10495
10497
  // OVERRIDE CONTROLS BASED ON WIDGET MODE
10496
- // Ensure aggregation is null in live mode
10498
+ // Ensure aggregation is null in live mode BEFORE calculating diff
10497
10499
  // TODO: consider updating inline component to handle this logic.
10498
10500
  // Edge case: widget supports aggregation. In history mode, user selects aggregation different than null.
10499
10501
  // Then switches to live mode.
10500
10502
  // Second scenario: legacy widget migration where aggregation was set in config.
10501
- if (formattedContext.refreshOption === REFRESH_OPTION.LIVE) {
10502
- formattedContext.aggregation = null;
10503
- }
10503
+ const normalizedContext = { ...context };
10504
+ if (normalizedContext.refreshOption === REFRESH_OPTION.LIVE) {
10505
+ normalizedContext.aggregation = null;
10506
+ }
10507
+ // Use lastEmittedState instead of internalConfig to avoid race conditions
10508
+ // where handleConfigChange updates internalConfig before the inline component emits
10509
+ const previousState = this.lastEmittedState();
10510
+ const diff = this.globalContextUtilsService.getChangedFields(previousState, normalizedContext);
10511
+ const filteredContext = pick(normalizedContext, template.supports);
10512
+ const filteredDiff = pick(diff, template.supports);
10513
+ const formattedContext = formatDateTimeContextForEmission(filteredContext, template.supports);
10514
+ // Update lastEmittedState to track what we just emitted
10515
+ this.lastEmittedState.set(formattedContext);
10516
+ // Also update internalConfig to keep it in sync (for backward compatibility)
10504
10517
  this.internalConfig.update(cfg => ({ ...cfg, ...formattedContext }));
10505
10518
  this.contextChangeSubject.next({ context: formattedContext, diff: filteredDiff });
10506
10519
  }
@@ -10700,5 +10713,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
10700
10713
  * Generated bundle index. Do not edit.
10701
10714
  */
10702
10715
 
10703
- export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, AutoRefreshSelectControlComponent, ConfigContextSelectorComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent, DEFAULT_INTERVAL_VALUES, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LINK_BTNS_CONFIG, LiveModeConfigurationControlsComponent, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, createAutoRefreshHandlers, createResult, defineWidgetControls, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
10716
+ export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, ConfigContextSelectorComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent, DEFAULT_INTERVAL_VALUES, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LINK_BTNS_CONFIG, LiveModeConfigurationControlsComponent, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, createAutoRefreshHandlers, createResult, defineWidgetControls, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
10704
10717
  //# sourceMappingURL=c8y-ngx-components-global-context.mjs.map