@c8y/ngx-components 1023.88.4 → 1023.92.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 (79) hide show
  1. package/auth-configuration/index.d.ts +19 -1
  2. package/auth-configuration/index.d.ts.map +1 -1
  3. package/context-dashboard/index.d.ts +4 -4
  4. package/context-dashboard/index.d.ts.map +1 -1
  5. package/echart/index.d.ts +1 -1
  6. package/echart/models/index.d.ts +1 -1
  7. package/fesm2022/c8y-ngx-components-auth-configuration.mjs +73 -7
  8. package/fesm2022/c8y-ngx-components-auth-configuration.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +21 -7
  10. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -1
  12. package/fesm2022/c8y-ngx-components-echart.mjs +1 -1
  13. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  14. package/fesm2022/c8y-ngx-components-global-context.mjs +494 -359
  15. package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
  16. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +1 -2
  17. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
  18. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs +1 -2
  19. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs.map +1 -1
  20. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs +1 -2
  21. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs.map +1 -1
  22. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +1 -2
  23. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -1
  24. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-list.mjs +0 -1
  25. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-list.mjs.map +1 -1
  26. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +0 -1
  27. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -1
  28. package/fesm2022/c8y-ngx-components-widgets-definitions-event-list.mjs +2 -89
  29. package/fesm2022/c8y-ngx-components-widgets-definitions-event-list.mjs.map +1 -1
  30. package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs +0 -1
  31. package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs.map +1 -1
  32. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +6 -9
  33. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  34. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +2 -2
  35. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  36. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs +2 -2
  37. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs.map +1 -1
  38. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +2 -2
  39. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
  40. package/fesm2022/c8y-ngx-components-widgets-implementations-events.mjs +4 -4
  41. package/fesm2022/c8y-ngx-components-widgets-implementations-events.mjs.map +1 -1
  42. package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs +2 -2
  43. package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs.map +1 -1
  44. package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs +2 -2
  45. package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs.map +1 -1
  46. package/fesm2022/c8y-ngx-components.mjs +39 -16
  47. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  48. package/global-context/index.d.ts +59 -31
  49. package/global-context/index.d.ts.map +1 -1
  50. package/index.d.ts +29 -6
  51. package/index.d.ts.map +1 -1
  52. package/locales/de.po +74 -19
  53. package/locales/es.po +74 -19
  54. package/locales/fr.po +74 -19
  55. package/locales/ja_JP.po +66 -18
  56. package/locales/ko.po +74 -19
  57. package/locales/locales.pot +74 -13
  58. package/locales/nl.po +74 -19
  59. package/locales/pl.po +74 -19
  60. package/locales/pt_BR.po +74 -19
  61. package/locales/zh_CN.po +74 -19
  62. package/locales/zh_TW.po +74 -19
  63. package/package.json +1 -1
  64. package/widgets/definitions/alarms/alarm-list/index.d.ts +0 -1
  65. package/widgets/definitions/alarms/alarm-list/index.d.ts.map +1 -1
  66. package/widgets/definitions/alarms/all-critical-alarms/index.d.ts +0 -1
  67. package/widgets/definitions/alarms/all-critical-alarms/index.d.ts.map +1 -1
  68. package/widgets/definitions/alarms/recent-alarms/index.d.ts +0 -1
  69. package/widgets/definitions/alarms/recent-alarms/index.d.ts.map +1 -1
  70. package/widgets/definitions/datapoints-list/index.d.ts +0 -1
  71. package/widgets/definitions/datapoints-list/index.d.ts.map +1 -1
  72. package/widgets/definitions/datapoints-table/index.d.ts +0 -1
  73. package/widgets/definitions/datapoints-table/index.d.ts.map +1 -1
  74. package/widgets/definitions/kpi/index.d.ts +0 -1
  75. package/widgets/definitions/kpi/index.d.ts.map +1 -1
  76. package/widgets/implementations/alarms/index.d.ts +5 -8
  77. package/widgets/implementations/alarms/index.d.ts.map +1 -1
  78. package/widgets/implementations/html-widget/index.d.ts +4 -6
  79. package/widgets/implementations/html-widget/index.d.ts.map +1 -1
@@ -35,8 +35,11 @@ const GLOBAL_CONTEXT_EVENTS = {
35
35
  };
36
36
  var GLOBAL_CONTEXT_DISPLAY_MODE;
37
37
  (function (GLOBAL_CONTEXT_DISPLAY_MODE) {
38
+ /** Widget is bound to the dashboard-level global context. */
38
39
  GLOBAL_CONTEXT_DISPLAY_MODE["DASHBOARD"] = "dashboard";
40
+ /** Widget owns its context but hides inline time range and aggregation controls. */
39
41
  GLOBAL_CONTEXT_DISPLAY_MODE["CONFIG"] = "config";
42
+ /** Widget owns its context and renders all controls inline (default). */
40
43
  GLOBAL_CONTEXT_DISPLAY_MODE["VIEW_AND_CONFIG"] = "view_and_config";
41
44
  })(GLOBAL_CONTEXT_DISPLAY_MODE || (GLOBAL_CONTEXT_DISPLAY_MODE = {}));
42
45
  var DateContextQueryParamNames;
@@ -109,7 +112,7 @@ const INTERVALS = [
109
112
  { id: 'custom', title: gettext('Custom') }
110
113
  ];
111
114
  const INTERVAL_TITLES = {
112
- none: gettext('No date filter'),
115
+ none: gettext('All time`interval option`'),
113
116
  minutes: gettext('Last minute'),
114
117
  hours: gettext('Last hour'),
115
118
  days: gettext('Last day'),
@@ -117,6 +120,11 @@ const INTERVAL_TITLES = {
117
120
  months: gettext('Last month'),
118
121
  custom: gettext('Custom')
119
122
  };
123
+ /** Opt-in interval entry covering epoch → now; gated per preset by `supportsLifetime`. */
124
+ const LIFETIME_INTERVAL = {
125
+ id: TIME_INTERVAL.NONE,
126
+ title: gettext('All time`interval option`')
127
+ };
120
128
 
121
129
  /**
122
130
  * Default values for global context configuration
@@ -1510,7 +1518,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1510
1518
  args: [{ providedIn: 'root' }]
1511
1519
  }] });
1512
1520
 
1521
+ /** Returns a shallow copy containing only the keys whose value is defined. */
1522
+ function pickDefined(obj, keys) {
1523
+ const result = {};
1524
+ for (const key of keys) {
1525
+ if (obj[key] !== undefined) {
1526
+ result[key] = obj[key];
1527
+ }
1528
+ }
1529
+ return result;
1530
+ }
1513
1531
  class WidgetConfigMigrationService {
1532
+ static { this.LIFETIME_DATE_FROM = '1970-01-01T00:00:00.000Z'; }
1514
1533
  constructor(dateTimeContextPickerService) {
1515
1534
  this.dateTimeContextPickerService = dateTimeContextPickerService;
1516
1535
  }
@@ -1565,7 +1584,8 @@ class WidgetConfigMigrationService {
1565
1584
  if (!config) {
1566
1585
  return config;
1567
1586
  }
1568
- // Cast to unknown first, then to our working type
1587
+ // Cast to unknown first, then to our working type. The entry point accepts either
1588
+ // legacy or already-migrated shape, so the intersection captures both.
1569
1589
  const rawConfig = config;
1570
1590
  const configObj = options?.legacyTimeContextDefaults && this.hasNoTimeContextFields(rawConfig)
1571
1591
  ? { ...rawConfig, ...options.legacyTimeContextDefaults }
@@ -1649,6 +1669,7 @@ class WidgetConfigMigrationService {
1649
1669
  if (needsDateTimeContext || hasNoGlobalContext) {
1650
1670
  config.dateTimeContext = this.resolveDateTimeContext(mergedSettings);
1651
1671
  }
1672
+ this.upgradeLegacyEpochToNone(config);
1652
1673
  if (needsRefreshSettings || hasNoGlobalContext) {
1653
1674
  this.applyRefreshSettings(config, mergedSettings);
1654
1675
  }
@@ -1674,6 +1695,15 @@ class WidgetConfigMigrationService {
1674
1695
  config.refreshInterval === undefined &&
1675
1696
  config.aggregation === undefined);
1676
1697
  }
1698
+ upgradeLegacyEpochToNone(config) {
1699
+ const ctx = config.dateTimeContext;
1700
+ if (!ctx || ctx.interval === TIME_INTERVAL.NONE)
1701
+ return;
1702
+ const dateFrom = typeof ctx.dateFrom === 'string' ? ctx.dateFrom : ctx.dateFrom?.toISOString();
1703
+ if (dateFrom === WidgetConfigMigrationService.LIFETIME_DATE_FROM) {
1704
+ ctx.interval = TIME_INTERVAL.NONE;
1705
+ }
1706
+ }
1677
1707
  /**
1678
1708
  * Applies refresh settings as a cohesive unit to ensure consistency.
1679
1709
  *
@@ -1724,7 +1754,6 @@ class WidgetConfigMigrationService {
1724
1754
  *
1725
1755
  * @param settings - Merged settings from all config levels
1726
1756
  * @returns The appropriate display mode for the widget
1727
- *
1728
1757
  */
1729
1758
  resolveDisplayMode(settings) {
1730
1759
  // Special case: Display date selection
@@ -1750,12 +1779,10 @@ class WidgetConfigMigrationService {
1750
1779
  if (timeGlobal === undefined && refreshGlobal === true) {
1751
1780
  return GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
1752
1781
  }
1753
- // Both undefined - widget manages itself
1754
1782
  if (timeGlobal === undefined && refreshGlobal === undefined) {
1755
- return GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;
1783
+ return GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG;
1756
1784
  }
1757
- // Default to CONFIG (widget manages itself)
1758
- return GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;
1785
+ return GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG;
1759
1786
  }
1760
1787
  /**
1761
1788
  * Builds date/time context from various legacy configuration formats.
@@ -1765,7 +1792,7 @@ class WidgetConfigMigrationService {
1765
1792
  * ISO date strings and proper interval classification.
1766
1793
  *
1767
1794
  * Resolution priority:
1768
- * 1. interval='none' → Always epoch (1970) to now with CUSTOM interval
1795
+ * 1. interval='none' → epoch (1970) to now, preserving the NONE interval (Lifetime).
1769
1796
  * 2. Predefined intervals (hours, days, etc.) → Calculate fresh dates based on interval
1770
1797
  * 3. Legacy date fields → Use provided dates with calculated/custom interval
1771
1798
  * 4. Widget needs time context → Apply default (last hour)
@@ -1781,14 +1808,15 @@ class WidgetConfigMigrationService {
1781
1808
  *
1782
1809
  */
1783
1810
  resolveDateTimeContext(settings) {
1784
- // Special case: interval "none" always means "all data from 1970 to now"
1811
+ // Legacy "none" preserves the user's "show every record" intent the GC picker
1812
+ // surfaces it as the "Lifetime" entry for widgets opted-in via supportsLifetime.
1785
1813
  if (settings.interval &&
1786
1814
  typeof settings.interval === 'string' &&
1787
1815
  settings.interval.toLowerCase() === 'none') {
1788
1816
  return {
1789
- dateFrom: '1970-01-01T00:00:00.000Z', // Always use epoch start
1790
- dateTo: DateTimeContextUtil.toIso(new Date()), // Always use current time
1791
- interval: TIME_INTERVAL.CUSTOM
1817
+ dateFrom: WidgetConfigMigrationService.LIFETIME_DATE_FROM,
1818
+ dateTo: DateTimeContextUtil.toIso(new Date()),
1819
+ interval: TIME_INTERVAL.NONE
1792
1820
  };
1793
1821
  }
1794
1822
  // Check if we have a predefined interval (not custom or none)
@@ -1901,8 +1929,7 @@ class WidgetConfigMigrationService {
1901
1929
  return true;
1902
1930
  }
1903
1931
  // Also consider display settings if there's a refresh option indicating active refresh
1904
- const displaySettings = settings.displaySettings;
1905
- if (displaySettings?.globalRealtimeContext === true &&
1932
+ if (settings.displaySettings?.globalRealtimeContext === true &&
1906
1933
  typeof settings.refreshOption === 'string' &&
1907
1934
  ['interval', 'global-interval'].includes(settings.refreshOption)) {
1908
1935
  return true;
@@ -1950,7 +1977,7 @@ class WidgetConfigMigrationService {
1950
1977
  * - ≤1 month → MONTHS
1951
1978
  * - >1 month → CUSTOM
1952
1979
  *
1953
- * Special case: interval='none' → CUSTOM
1980
+ * Special case: interval='none' → NONE (Lifetime)
1954
1981
  *
1955
1982
  * @param dateFrom - Start date as ISO string
1956
1983
  * @param dateTo - End date as ISO string
@@ -1959,11 +1986,9 @@ class WidgetConfigMigrationService {
1959
1986
  *
1960
1987
  */
1961
1988
  calculateInterval(dateFrom, dateTo, providedInterval) {
1962
- // Use provided interval if valid
1963
1989
  if (providedInterval) {
1964
- // Handle case-insensitive 'none' variations
1965
1990
  if (providedInterval.toLowerCase() === 'none') {
1966
- return TIME_INTERVAL.CUSTOM;
1991
+ return TIME_INTERVAL.NONE;
1967
1992
  }
1968
1993
  if (Object.values(TIME_INTERVAL).includes(providedInterval)) {
1969
1994
  return providedInterval;
@@ -2049,10 +2074,9 @@ class WidgetConfigMigrationService {
2049
2074
  *
2050
2075
  */
2051
2076
  needsDefaultDateTimeContext(settings) {
2052
- const displaySettings = settings.displaySettings;
2053
2077
  const hasTimeSettings = !!(settings.displayDateSelection ||
2054
2078
  settings.widgetInstanceGlobalTimeContext !== undefined ||
2055
- displaySettings?.globalTimeContext ||
2079
+ settings.displaySettings?.globalTimeContext ||
2056
2080
  settings.interval);
2057
2081
  const hasExplicitDates = !!((settings.dateFrom && settings.dateTo) ||
2058
2082
  settings.dateFilter ||
@@ -2196,7 +2220,7 @@ class WidgetConfigMigrationService {
2196
2220
  *
2197
2221
  */
2198
2222
  extractRelevantSettings(obj) {
2199
- const relevantKeys = [
2223
+ return pickDefined(obj, [
2200
2224
  'displaySettings',
2201
2225
  'widgetInstanceGlobalTimeContext',
2202
2226
  'widgetInstanceGlobalAutoRefreshContext',
@@ -2212,8 +2236,7 @@ class WidgetConfigMigrationService {
2212
2236
  'realtime',
2213
2237
  'interval',
2214
2238
  'aggregation'
2215
- ];
2216
- return Object.fromEntries(relevantKeys.filter(key => obj[key] !== undefined).map(key => [key, obj[key]]));
2239
+ ]);
2217
2240
  }
2218
2241
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: WidgetConfigMigrationService, deps: [{ token: DateTimeContextPickerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2219
2242
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: WidgetConfigMigrationService, providedIn: 'root' }); }
@@ -3222,6 +3245,8 @@ class DateTimeContextPickerComponent {
3222
3245
  showDateFrom: true,
3223
3246
  showDateTo: true
3224
3247
  };
3248
+ /** Override the intervals offered in the picker dropdown. */
3249
+ this.intervalOptions = [...INTERVALS];
3225
3250
  this.service = inject(DateTimeContextPickerService);
3226
3251
  this.formBuilder = inject(FormBuilder);
3227
3252
  this.destroyRef = inject(DestroyRef);
@@ -3473,13 +3498,13 @@ class DateTimeContextPickerComponent {
3473
3498
  }
3474
3499
  }
3475
3500
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DateTimeContextPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3476
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DateTimeContextPickerComponent, isStandalone: true, selector: "c8y-date-time-context-picker", inputs: { disabled: "disabled", shouldDisableInterval: "shouldDisableInterval", config: "config" }, providers: [
3501
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DateTimeContextPickerComponent, isStandalone: true, selector: "c8y-date-time-context-picker", inputs: { disabled: "disabled", shouldDisableInterval: "shouldDisableInterval", config: "config", intervalOptions: "intervalOptions" }, providers: [
3477
3502
  {
3478
3503
  provide: NG_VALUE_ACCESSOR,
3479
3504
  useExisting: forwardRef(() => DateTimeContextPickerComponent),
3480
3505
  multi: true
3481
3506
  }
3482
- ], viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], ngImport: i0, template: "@if (form) {\n @let intervalValue = form.get('interval')?.value;\n @let isIntervalNone = intervalValue === 'none';\n @let dateFromControl = form.get('dateFrom');\n @let dateToControl = form.get('dateTo');\n @let dateRangeLabel = getDateRangeLabel();\n\n <form [formGroup]=\"form\">\n <div\n class=\"dropdown max-width-100\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n [isDisabled]=\"disabled\"\n (onShown)=\"onShownDropdown()\"\n (onHidden)=\"onHiddenDropdown()\"\n >\n <!-- Dropdown toggle button with better accessibility -->\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n [attr.aria-label]=\"dateRangeLabel\"\n [tooltip]=\"dateRangeLabel\"\n placement=\"top\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n data-cy=\"c8y-date-time-context-picker--picker-toggle\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'schedule1'\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"d-col text-left flex-grow min-width-0\">\n @if (isIntervalNone) {\n <span class=\"text-10 text-muted l-h-1\">\n {{ 'No date filter' | translate }}\n </span>\n } @else {\n <span\n class=\"text-10 text-muted l-h-1\"\n data-cy=\"c8y-date-time-context-picker--picker-label\"\n >\n {{ INTERVALS[intervalValue] | translate }}\n </span>\n <span\n class=\"text-12 l-h-1 text-medium text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-time-range\"\n >\n {{ form.get('dateFrom')?.value | c8yDate: DATE_FORMAT }} \u2014\n {{ form.get('dateTo')?.value | c8yDate: DATE_FORMAT }}\n </span>\n }\n </div>\n <span\n class=\"caret m-r-16 m-l-4\"\n aria-hidden=\"true\"\n ></span>\n </button>\n\n <!-- Dropdown menu -->\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n role=\"menu\"\n *dropdownMenu\n >\n @if (dropdown.isOpen) {\n <!-- Interval picker section -->\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"interval\"\n [shouldDisableInterval]=\"shouldDisableInterval\"\n ></c8y-interval-picker>\n\n <!-- Custom date range section -->\n @if (isCustomMode() && (config?.showDateFrom || config?.showDateTo)) {\n <div class=\"p-l-16 p-r-16\">\n @if (config?.showDateFrom) {\n <c8y-form-group [class.has-error]=\"getDateFromErrors()\">\n <label\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]=\"getDateFromErrors()\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToControl?.value\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"tempDateFromControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateFromErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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\n @if (config?.showDateTo) {\n <c8y-form-group [class.has-error]=\"getDateToErrors()\">\n <label\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]=\"getDateToErrors()\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromControl?.value\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"tempDateToControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateToErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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 </div>\n\n <!-- Action buttons -->\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"reset()\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateTimeContext()\"\n [disabled]=\"isApplyDisabled()\"\n translate\n >\n Apply\n </button>\n </div>\n }\n }\n </ul>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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: BsDropdownModule }, { kind: "directive", type: i2$1.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i2$1.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i2$1.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS", "shouldDisableInterval"] }, { 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: "pipe", type: i4.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3507
+ ], viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], ngImport: i0, template: "@if (form) {\n @let intervalValue = form.get('interval')?.value;\n @let isIntervalNone = intervalValue === 'none';\n @let dateFromControl = form.get('dateFrom');\n @let dateToControl = form.get('dateTo');\n @let dateRangeLabel = getDateRangeLabel();\n @let lifetimeTooltip =\n 'No date filter applied \u2014 every record is returned regardless of when it occurred.' | translate;\n @let toggleTooltip = isIntervalNone ? lifetimeTooltip : dateRangeLabel;\n\n <form [formGroup]=\"form\">\n <div\n class=\"dropdown max-width-100\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n [isDisabled]=\"disabled\"\n (onShown)=\"onShownDropdown()\"\n (onHidden)=\"onHiddenDropdown()\"\n >\n <!-- Dropdown toggle button with better accessibility -->\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n [attr.aria-label]=\"toggleTooltip\"\n [tooltip]=\"toggleTooltip\"\n placement=\"top\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n data-cy=\"c8y-date-time-context-picker--picker-toggle\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'schedule1'\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"d-col text-left flex-grow min-width-0\">\n @if (isIntervalNone) {\n <span class=\"text-10 text-muted l-h-1 text-truncate\">\n {{ 'All time`interval option`' | translate }}\n </span>\n } @else {\n <span\n class=\"text-10 text-muted l-h-1 text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-label\"\n >\n {{ INTERVALS[intervalValue] | translate }}\n </span>\n <span\n class=\"text-12 l-h-1 text-medium text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-time-range\"\n >\n {{ form.get('dateFrom')?.value | c8yDate: DATE_FORMAT }} \u2014\n {{ form.get('dateTo')?.value | c8yDate: DATE_FORMAT }}\n </span>\n }\n </div>\n <span\n class=\"caret m-r-16 m-l-4\"\n aria-hidden=\"true\"\n ></span>\n </button>\n\n <!-- Dropdown menu -->\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n role=\"menu\"\n *dropdownMenu\n >\n @if (dropdown.isOpen) {\n <!-- Interval picker section -->\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"interval\"\n [INTERVALS]=\"intervalOptions\"\n [shouldDisableInterval]=\"shouldDisableInterval\"\n ></c8y-interval-picker>\n\n <!-- Custom date range section -->\n @if (isCustomMode() && (config?.showDateFrom || config?.showDateTo)) {\n <div class=\"p-l-16 p-r-16\">\n @if (config?.showDateFrom) {\n <c8y-form-group [class.has-error]=\"getDateFromErrors()\">\n <label\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]=\"getDateFromErrors()\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToControl?.value\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"tempDateFromControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateFromErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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\n @if (config?.showDateTo) {\n <c8y-form-group [class.has-error]=\"getDateToErrors()\">\n <label\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]=\"getDateToErrors()\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromControl?.value\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"tempDateToControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateToErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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 </div>\n\n <!-- Action buttons -->\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"reset()\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateTimeContext()\"\n [disabled]=\"isApplyDisabled()\"\n translate\n >\n Apply\n </button>\n </div>\n }\n }\n </ul>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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: BsDropdownModule }, { kind: "directive", type: i2$1.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i2$1.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i2$1.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS", "shouldDisableInterval"] }, { 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: "pipe", type: i4.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3483
3508
  }
3484
3509
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DateTimeContextPickerComponent, decorators: [{
3485
3510
  type: Component,
@@ -3501,13 +3526,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3501
3526
  useExisting: forwardRef(() => DateTimeContextPickerComponent),
3502
3527
  multi: true
3503
3528
  }
3504
- ], template: "@if (form) {\n @let intervalValue = form.get('interval')?.value;\n @let isIntervalNone = intervalValue === 'none';\n @let dateFromControl = form.get('dateFrom');\n @let dateToControl = form.get('dateTo');\n @let dateRangeLabel = getDateRangeLabel();\n\n <form [formGroup]=\"form\">\n <div\n class=\"dropdown max-width-100\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n [isDisabled]=\"disabled\"\n (onShown)=\"onShownDropdown()\"\n (onHidden)=\"onHiddenDropdown()\"\n >\n <!-- Dropdown toggle button with better accessibility -->\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n [attr.aria-label]=\"dateRangeLabel\"\n [tooltip]=\"dateRangeLabel\"\n placement=\"top\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n data-cy=\"c8y-date-time-context-picker--picker-toggle\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'schedule1'\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"d-col text-left flex-grow min-width-0\">\n @if (isIntervalNone) {\n <span class=\"text-10 text-muted l-h-1\">\n {{ 'No date filter' | translate }}\n </span>\n } @else {\n <span\n class=\"text-10 text-muted l-h-1\"\n data-cy=\"c8y-date-time-context-picker--picker-label\"\n >\n {{ INTERVALS[intervalValue] | translate }}\n </span>\n <span\n class=\"text-12 l-h-1 text-medium text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-time-range\"\n >\n {{ form.get('dateFrom')?.value | c8yDate: DATE_FORMAT }} \u2014\n {{ form.get('dateTo')?.value | c8yDate: DATE_FORMAT }}\n </span>\n }\n </div>\n <span\n class=\"caret m-r-16 m-l-4\"\n aria-hidden=\"true\"\n ></span>\n </button>\n\n <!-- Dropdown menu -->\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n role=\"menu\"\n *dropdownMenu\n >\n @if (dropdown.isOpen) {\n <!-- Interval picker section -->\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"interval\"\n [shouldDisableInterval]=\"shouldDisableInterval\"\n ></c8y-interval-picker>\n\n <!-- Custom date range section -->\n @if (isCustomMode() && (config?.showDateFrom || config?.showDateTo)) {\n <div class=\"p-l-16 p-r-16\">\n @if (config?.showDateFrom) {\n <c8y-form-group [class.has-error]=\"getDateFromErrors()\">\n <label\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]=\"getDateFromErrors()\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToControl?.value\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"tempDateFromControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateFromErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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\n @if (config?.showDateTo) {\n <c8y-form-group [class.has-error]=\"getDateToErrors()\">\n <label\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]=\"getDateToErrors()\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromControl?.value\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"tempDateToControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateToErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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 </div>\n\n <!-- Action buttons -->\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"reset()\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateTimeContext()\"\n [disabled]=\"isApplyDisabled()\"\n translate\n >\n Apply\n </button>\n </div>\n }\n }\n </ul>\n </div>\n </form>\n}\n" }]
3529
+ ], template: "@if (form) {\n @let intervalValue = form.get('interval')?.value;\n @let isIntervalNone = intervalValue === 'none';\n @let dateFromControl = form.get('dateFrom');\n @let dateToControl = form.get('dateTo');\n @let dateRangeLabel = getDateRangeLabel();\n @let lifetimeTooltip =\n 'No date filter applied \u2014 every record is returned regardless of when it occurred.' | translate;\n @let toggleTooltip = isIntervalNone ? lifetimeTooltip : dateRangeLabel;\n\n <form [formGroup]=\"form\">\n <div\n class=\"dropdown max-width-100\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n [isDisabled]=\"disabled\"\n (onShown)=\"onShownDropdown()\"\n (onHidden)=\"onHiddenDropdown()\"\n >\n <!-- Dropdown toggle button with better accessibility -->\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n [attr.aria-label]=\"toggleTooltip\"\n [tooltip]=\"toggleTooltip\"\n placement=\"top\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n data-cy=\"c8y-date-time-context-picker--picker-toggle\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'schedule1'\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"d-col text-left flex-grow min-width-0\">\n @if (isIntervalNone) {\n <span class=\"text-10 text-muted l-h-1 text-truncate\">\n {{ 'All time`interval option`' | translate }}\n </span>\n } @else {\n <span\n class=\"text-10 text-muted l-h-1 text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-label\"\n >\n {{ INTERVALS[intervalValue] | translate }}\n </span>\n <span\n class=\"text-12 l-h-1 text-medium text-truncate\"\n data-cy=\"c8y-date-time-context-picker--picker-time-range\"\n >\n {{ form.get('dateFrom')?.value | c8yDate: DATE_FORMAT }} \u2014\n {{ form.get('dateTo')?.value | c8yDate: DATE_FORMAT }}\n </span>\n }\n </div>\n <span\n class=\"caret m-r-16 m-l-4\"\n aria-hidden=\"true\"\n ></span>\n </button>\n\n <!-- Dropdown menu -->\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n role=\"menu\"\n *dropdownMenu\n >\n @if (dropdown.isOpen) {\n <!-- Interval picker section -->\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"interval\"\n [INTERVALS]=\"intervalOptions\"\n [shouldDisableInterval]=\"shouldDisableInterval\"\n ></c8y-interval-picker>\n\n <!-- Custom date range section -->\n @if (isCustomMode() && (config?.showDateFrom || config?.showDateTo)) {\n <div class=\"p-l-16 p-r-16\">\n @if (config?.showDateFrom) {\n <c8y-form-group [class.has-error]=\"getDateFromErrors()\">\n <label\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]=\"getDateFromErrors()\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToControl?.value\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"tempDateFromControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateFromErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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\n @if (config?.showDateTo) {\n <c8y-form-group [class.has-error]=\"getDateToErrors()\">\n <label\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]=\"getDateToErrors()\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromControl?.value\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"tempDateToControl\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"getDateToErrors()\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\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-message\n name=\"bsDate\"\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 </div>\n\n <!-- Action buttons -->\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"reset()\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateTimeContext()\"\n [disabled]=\"isApplyDisabled()\"\n translate\n >\n Apply\n </button>\n </div>\n }\n }\n </ul>\n </div>\n </form>\n}\n" }]
3505
3530
  }], propDecorators: { disabled: [{
3506
3531
  type: Input
3507
3532
  }], shouldDisableInterval: [{
3508
3533
  type: Input
3509
3534
  }], config: [{
3510
3535
  type: Input
3536
+ }], intervalOptions: [{
3537
+ type: Input
3511
3538
  }], dropdown: [{
3512
3539
  type: ViewChild,
3513
3540
  args: [BsDropdownDirective]
@@ -3552,6 +3579,8 @@ class LiveModeConfigurationControlsComponent {
3552
3579
  }, ...(ngDevMode ? [{ debugName: "settingsSignal" }] : []));
3553
3580
  this.defaultLiveContext = fillMissingDefaults({ refreshOption: REFRESH_OPTION.LIVE });
3554
3581
  this.currentContext = signal(structuredClone(this.defaultLiveContext), ...(ngDevMode ? [{ debugName: "currentContext" }] : []));
3582
+ /** Override the intervals offered in the picker dropdown. */
3583
+ this.intervalOptions = [...INTERVALS];
3555
3584
  this.contextChange = output();
3556
3585
  this.form = this.createForm();
3557
3586
  this.form.valueChanges
@@ -3586,7 +3615,7 @@ class LiveModeConfigurationControlsComponent {
3586
3615
  }, { emitEvent: false });
3587
3616
  }
3588
3617
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LiveModeConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3589
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.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$2.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 }); }
3618
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LiveModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-live-mode-configuration-controls", inputs: { settings: "settings", intervalOptions: "intervalOptions", 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 [intervalOptions]=\"intervalOptions\"\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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.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 }); }
3590
3619
  }
3591
3620
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LiveModeConfigurationControlsComponent, decorators: [{
3592
3621
  type: Component,
@@ -3599,9 +3628,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3599
3628
  FormsModule,
3600
3629
  PopoverModule,
3601
3630
  FormGroupComponent
3602
- ], 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" }]
3631
+ ], 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 [intervalOptions]=\"intervalOptions\"\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" }]
3603
3632
  }], ctorParameters: () => [], propDecorators: { settings: [{
3604
3633
  type: Input
3634
+ }], intervalOptions: [{
3635
+ type: Input
3605
3636
  }], context: [{
3606
3637
  type: Input
3607
3638
  }], contextChange: [{ type: i0.Output, args: ["contextChange"] }] } });
@@ -3627,6 +3658,8 @@ class ConfigurationControlsComponent {
3627
3658
  this.liveContext = input(null, ...(ngDevMode ? [{ debugName: "liveContext" }] : []));
3628
3659
  this.historyContext = input(null, ...(ngDevMode ? [{ debugName: "historyContext" }] : []));
3629
3660
  this.supportedModes = input([REFRESH_OPTION.LIVE, REFRESH_OPTION.HISTORY], ...(ngDevMode ? [{ debugName: "supportedModes" }] : []));
3661
+ /** Override the intervals offered in the picker dropdown. */
3662
+ this.intervalOptions = input([...INTERVALS], ...(ngDevMode ? [{ debugName: "intervalOptions" }] : []));
3630
3663
  this.tabsOutletName = input(null, ...(ngDevMode ? [{ debugName: "tabsOutletName" }] : []));
3631
3664
  this.liveTabSelect = new EventEmitter();
3632
3665
  this.historyTabSelect = new EventEmitter();
@@ -3706,7 +3739,7 @@ class ConfigurationControlsComponent {
3706
3739
  this.validationStatus.emit(isValid);
3707
3740
  }
3708
3741
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3709
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ConfigurationControlsComponent, isStandalone: true, selector: "c8y-configuration-controls", inputs: { controlsDisplayMode: { classPropertyName: "controlsDisplayMode", publicName: "controlsDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null }, activeMode: { classPropertyName: "activeMode", publicName: "activeMode", isSignal: true, isRequired: false, transformFunction: null }, liveContext: { classPropertyName: "liveContext", publicName: "liveContext", isSignal: true, isRequired: false, transformFunction: null }, historyContext: { classPropertyName: "historyContext", publicName: "historyContext", isSignal: true, isRequired: false, transformFunction: null }, supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, tabsOutletName: { classPropertyName: "tabsOutletName", publicName: "tabsOutletName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refreshOptionChange: "refreshOptionChange", contextChange: "contextChange", validationStatus: "validationStatus" }, viewQueries: [{ propertyName: "liveTabTemplate", first: true, predicate: ["LiveTab"], descendants: true, isSignal: true }, { propertyName: "historyTabTemplate", first: true, predicate: ["HistoryTab"], descendants: true, isSignal: true }], ngImport: i0, template: `
3742
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ConfigurationControlsComponent, isStandalone: true, selector: "c8y-configuration-controls", inputs: { controlsDisplayMode: { classPropertyName: "controlsDisplayMode", publicName: "controlsDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null }, activeMode: { classPropertyName: "activeMode", publicName: "activeMode", isSignal: true, isRequired: false, transformFunction: null }, liveContext: { classPropertyName: "liveContext", publicName: "liveContext", isSignal: true, isRequired: false, transformFunction: null }, historyContext: { classPropertyName: "historyContext", publicName: "historyContext", isSignal: true, isRequired: false, transformFunction: null }, supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, intervalOptions: { classPropertyName: "intervalOptions", publicName: "intervalOptions", isSignal: true, isRequired: false, transformFunction: null }, tabsOutletName: { classPropertyName: "tabsOutletName", publicName: "tabsOutletName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refreshOptionChange: "refreshOptionChange", contextChange: "contextChange", validationStatus: "validationStatus" }, viewQueries: [{ propertyName: "liveTabTemplate", first: true, predicate: ["LiveTab"], descendants: true, isSignal: true }, { propertyName: "historyTabTemplate", first: true, predicate: ["HistoryTab"], descendants: true, isSignal: true }], ngImport: i0, template: `
3710
3743
  <div class="p-relative fit-h">
3711
3744
  <div [attr.class]="containerClass()">
3712
3745
  <c8y-tabs-outlet
@@ -3722,6 +3755,7 @@ class ConfigurationControlsComponent {
3722
3755
  <c8y-live-mode-configuration-controls
3723
3756
  [settings]="settings()"
3724
3757
  [context]="liveContext()"
3758
+ [intervalOptions]="intervalOptions()"
3725
3759
  (contextChange)="handleLiveChanges($event)"
3726
3760
  ></c8y-live-mode-configuration-controls>
3727
3761
  </div>
@@ -3758,7 +3792,7 @@ class ConfigurationControlsComponent {
3758
3792
  </div>
3759
3793
  </ng-template>
3760
3794
  </div>
3761
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: HistoryModeConfigurationControlsComponent, selector: "c8y-history-mode-configuration-controls", inputs: ["settings", "context"], outputs: ["contextChange", "validationStatus"] }, { kind: "component", type: LiveModeConfigurationControlsComponent, selector: "c8y-live-mode-configuration-controls", inputs: ["settings", "context"], outputs: ["contextChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3795
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: HistoryModeConfigurationControlsComponent, selector: "c8y-history-mode-configuration-controls", inputs: ["settings", "context"], outputs: ["contextChange", "validationStatus"] }, { kind: "component", type: LiveModeConfigurationControlsComponent, selector: "c8y-live-mode-configuration-controls", inputs: ["settings", "intervalOptions", "context"], outputs: ["contextChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3762
3796
  }
3763
3797
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigurationControlsComponent, decorators: [{
3764
3798
  type: Component,
@@ -3781,6 +3815,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3781
3815
  <c8y-live-mode-configuration-controls
3782
3816
  [settings]="settings()"
3783
3817
  [context]="liveContext()"
3818
+ [intervalOptions]="intervalOptions()"
3784
3819
  (contextChange)="handleLiveChanges($event)"
3785
3820
  ></c8y-live-mode-configuration-controls>
3786
3821
  </div>
@@ -3832,7 +3867,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3832
3867
  IconDirective
3833
3868
  ]
3834
3869
  }]
3835
- }], ctorParameters: () => [], propDecorators: { controlsDisplayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsDisplayMode", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: false }] }], activeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeMode", required: false }] }], liveContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "liveContext", required: false }] }], historyContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "historyContext", required: false }] }], supportedModes: [{ type: i0.Input, args: [{ isSignal: true, alias: "supportedModes", required: false }] }], tabsOutletName: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabsOutletName", required: false }] }], refreshOptionChange: [{ type: i0.Output, args: ["refreshOptionChange"] }], contextChange: [{ type: i0.Output, args: ["contextChange"] }], validationStatus: [{ type: i0.Output, args: ["validationStatus"] }], liveTabTemplate: [{ type: i0.ViewChild, args: ['LiveTab', { isSignal: true }] }], historyTabTemplate: [{ type: i0.ViewChild, args: ['HistoryTab', { isSignal: true }] }] } });
3870
+ }], ctorParameters: () => [], propDecorators: { controlsDisplayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsDisplayMode", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: false }] }], activeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeMode", required: false }] }], liveContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "liveContext", required: false }] }], historyContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "historyContext", required: false }] }], supportedModes: [{ type: i0.Input, args: [{ isSignal: true, alias: "supportedModes", required: false }] }], intervalOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervalOptions", required: false }] }], tabsOutletName: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabsOutletName", required: false }] }], refreshOptionChange: [{ type: i0.Output, args: ["refreshOptionChange"] }], contextChange: [{ type: i0.Output, args: ["contextChange"] }], validationStatus: [{ type: i0.Output, args: ["validationStatus"] }], liveTabTemplate: [{ type: i0.ViewChild, args: ['LiveTab', { isSignal: true }] }], historyTabTemplate: [{ type: i0.ViewChild, args: ['HistoryTab', { isSignal: true }] }] } });
3836
3871
 
3837
3872
  class ConfigurationCollapseComponent {
3838
3873
  constructor() {
@@ -4019,7 +4054,7 @@ class ConfigurationCollapseComponent {
4019
4054
  this.hasPendingChanges.set(!isEqual(snapshot, latest));
4020
4055
  }
4021
4056
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigurationCollapseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4022
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ConfigurationCollapseComponent, isStandalone: true, selector: "c8y-configuration-collapse", inputs: { supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", refreshOptionChange: "refreshOptionChange", savePreferenceChange: "savePreferenceChange" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n class=\"c8y-global-context\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i1$2.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.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: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4057
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ConfigurationCollapseComponent, isStandalone: true, selector: "c8y-configuration-collapse", inputs: { supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", refreshOptionChange: "refreshOptionChange", savePreferenceChange: "savePreferenceChange" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n class=\"c8y-global-context\"\n data-cy=\"global-context--configuration-panel\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n data-cy=\"global-context--Close-button\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i1$2.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.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: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4023
4058
  }
4024
4059
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigurationCollapseComponent, decorators: [{
4025
4060
  type: Component,
@@ -4031,7 +4066,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4031
4066
  PopoverModule,
4032
4067
  ConfigurationControlsComponent,
4033
4068
  C8yTranslatePipe
4034
- ], template: "<div\n class=\"c8y-global-context\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n" }]
4069
+ ], template: "<div\n class=\"c8y-global-context\"\n data-cy=\"global-context--configuration-panel\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n data-cy=\"global-context--Close-button\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n" }]
4035
4070
  }], propDecorators: { supportedModes: [{ type: i0.Input, args: [{ isSignal: true, alias: "supportedModes", required: false }] }], context: [{
4036
4071
  type: Input
4037
4072
  }], contextChange: [{ type: i0.Output, args: ["contextChange"] }], refreshOptionChange: [{ type: i0.Output, args: ["refreshOptionChange"] }], savePreferenceChange: [{ type: i0.Output, args: ["savePreferenceChange"] }] } });
@@ -8603,7 +8638,7 @@ class GlobalContextInlineComponent {
8603
8638
  };
8604
8639
  }
8605
8640
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8606
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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 }, disableRefreshEmits: { classPropertyName: "disableRefreshEmits", publicName: "disableRefreshEmits", 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 inner-scroll\"\n [ngClass]=\"{\n 'p-b-8':\n settings.showTimeContext ||\n settings.showRefresh ||\n settings.showAutoRefresh ||\n settings.showAggregation\n }\"\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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.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: i2.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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8641
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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 }, disableRefreshEmits: { classPropertyName: "disableRefreshEmits", publicName: "disableRefreshEmits", 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 inner-scroll\"\n [ngClass]=\"{\n 'p-b-8':\n settings.showTimeContext ||\n settings.showRefresh ||\n settings.showAutoRefresh ||\n settings.showAggregation\n }\"\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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.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", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8607
8642
  }
8608
8643
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextInlineComponent, decorators: [{
8609
8644
  type: Component,
@@ -8657,7 +8692,7 @@ class GlobalContextConfigStoreService {
8657
8692
  /** Currently selected tab (refresh option). Defaults to LIVE. */
8658
8693
  this.refreshOption = signal(REFRESH_OPTION.LIVE, ...(ngDevMode ? [{ debugName: "refreshOption" }] : []));
8659
8694
  /** Current display mode for the widget (config or view_and_config). */
8660
- this.displayMode = signal(GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
8695
+ this.displayMode = signal(GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
8661
8696
  /** Whether the store has processed the first hydrate() call. */
8662
8697
  this.initialized = signal(false, ...(ngDevMode ? [{ debugName: "initialized" }] : []));
8663
8698
  /**
@@ -8746,9 +8781,10 @@ class GlobalContextConfigStoreService {
8746
8781
  this._widgetControls.set(controls);
8747
8782
  }
8748
8783
  /**
8749
- * Sets the display mode and syncs the mode to both modes.
8750
- * Does not change the selected tab.
8751
- * @param mode - Display mode to set (CONFIG or VIEW_AND_CONFIG)
8784
+ * Sets the display mode and propagates it into both live and history state objects.
8785
+ * Does not change the currently selected tab.
8786
+ *
8787
+ * @param mode - Display mode to set (DASHBOARD, CONFIG, or VIEW_AND_CONFIG)
8752
8788
  */
8753
8789
  setDisplayMode(mode) {
8754
8790
  if (this.displayMode() === mode) {
@@ -8901,7 +8937,7 @@ class GlobalContextConfigStoreService {
8901
8937
  }
8902
8938
  if (norm.displayMode !== GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG &&
8903
8939
  norm.displayMode !== GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {
8904
- norm.displayMode = GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;
8940
+ norm.displayMode = GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG;
8905
8941
  }
8906
8942
  if (norm.refreshOption === REFRESH_OPTION.LIVE) {
8907
8943
  norm.aggregation = null;
@@ -9061,7 +9097,7 @@ class GlobalContextConfigComponent {
9061
9097
  changes.refreshOption !== current.refreshOption);
9062
9098
  }
9063
9099
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9064
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.25", type: GlobalContextConfigComponent, isStandalone: true, selector: "c8y-global-context-config", inputs: { configInput: { classPropertyName: "configInput", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, liveSnapshotInput: { classPropertyName: "liveSnapshotInput", publicName: "liveSnapshot", isSignal: true, isRequired: false, transformFunction: null }, historySnapshotInput: { classPropertyName: "historySnapshotInput", publicName: "historySnapshot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextConfigStoreService], ngImport: i0, template: "<c8y-configuration-controls\n [settings]=\"settings()\"\n [controlsDisplayMode]=\"'horizontal'\"\n [tabsOutletName]=\"'verticalTabOutletForConfigurationModes'\"\n [activeMode]=\"refreshOption()\"\n [liveContext]=\"liveConfig()\"\n [historyContext]=\"historyConfig()\"\n [supportedModes]=\"supportedModes()\"\n (contextChange)=\"onConfigurationChanges($event)\"\n (refreshOptionChange)=\"onConfigurationChanges({ refreshOption: $event })\"\n></c8y-configuration-controls>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9100
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.25", type: GlobalContextConfigComponent, isStandalone: true, selector: "c8y-global-context-config", inputs: { configInput: { classPropertyName: "configInput", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, liveSnapshotInput: { classPropertyName: "liveSnapshotInput", publicName: "liveSnapshot", isSignal: true, isRequired: false, transformFunction: null }, historySnapshotInput: { classPropertyName: "historySnapshotInput", publicName: "historySnapshot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextConfigStoreService], ngImport: i0, template: "<c8y-configuration-controls\n [settings]=\"settings()\"\n [controlsDisplayMode]=\"'horizontal'\"\n [tabsOutletName]=\"'verticalTabOutletForConfigurationModes'\"\n [activeMode]=\"refreshOption()\"\n [liveContext]=\"liveConfig()\"\n [historyContext]=\"historyConfig()\"\n [supportedModes]=\"supportedModes()\"\n (contextChange)=\"onConfigurationChanges($event)\"\n (refreshOptionChange)=\"onConfigurationChanges({ refreshOption: $event })\"\n></c8y-configuration-controls>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9065
9101
  }
9066
9102
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextConfigComponent, decorators: [{
9067
9103
  type: Component,
@@ -9083,9 +9119,6 @@ class ConfigContextSelectorComponent {
9083
9119
  // eslint-disable-next-line @typescript-eslint/no-empty-function
9084
9120
  this.onTouched = () => { };
9085
9121
  }
9086
- get isWidgetContext() {
9087
- return this.form?.get('context')?.value === 'widget';
9088
- }
9089
9122
  ngOnInit() {
9090
9123
  this.form = this.initForm();
9091
9124
  this.setupValueChanges();
@@ -9095,7 +9128,7 @@ class ConfigContextSelectorComponent {
9095
9128
  return;
9096
9129
  const formValue = {
9097
9130
  context: value === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD ? 'dashboard' : 'widget',
9098
- showInWidget: value === GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG
9131
+ hideInWidget: value === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG
9099
9132
  };
9100
9133
  this.form?.patchValue(formValue, { emitEvent: false });
9101
9134
  }
@@ -9111,18 +9144,20 @@ class ConfigContextSelectorComponent {
9111
9144
  initForm() {
9112
9145
  return this.fb.group({
9113
9146
  context: 'widget',
9114
- showInWidget: false
9147
+ hideInWidget: false
9115
9148
  });
9116
9149
  }
9117
9150
  setupValueChanges() {
9118
9151
  this.form.valueChanges
9119
- .pipe(map$1(({ context, showInWidget }) => context === 'dashboard'
9120
- ? GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD
9121
- : showInWidget
9122
- ? GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG
9123
- : GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG), takeUntilDestroyed(this.destroyRef))
9124
- .subscribe(dateSelection => {
9125
- this.onChange(dateSelection);
9152
+ .pipe(map$1(({ context, hideInWidget }) => {
9153
+ if (context === 'dashboard')
9154
+ return GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
9155
+ return hideInWidget
9156
+ ? GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG
9157
+ : GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG;
9158
+ }), takeUntilDestroyed(this.destroyRef))
9159
+ .subscribe(displayMode => {
9160
+ this.onChange(displayMode);
9126
9161
  this.onTouched();
9127
9162
  });
9128
9163
  }
@@ -9135,9 +9170,6 @@ class ConfigContextSelectorComponent {
9135
9170
  }
9136
9171
  ], ngImport: i0, template: `
9137
9172
  @if (form) {
9138
- @let isWidgetContext = form.get('context')?.value === 'widget';
9139
- @let helpText = 'Show controls directly in the widget view for easier access.' | translate;
9140
-
9141
9173
  <form class="form-group m-b-8" [formGroup]="form">
9142
9174
  <div class="d-flex gap-8 a-i-center">
9143
9175
  <label class="c8y-radio">
@@ -9161,33 +9193,20 @@ class ConfigContextSelectorComponent {
9161
9193
  <span translate>Widget</span>
9162
9194
  </label>
9163
9195
  </div>
9164
-
9165
- @if (isWidgetContext) {
9166
- <div class="m-t-8">
9167
- <label class="c8y-checkbox">
9168
- <input
9169
- type="checkbox"
9170
- data-cy="c8y-config-context-selector--view-and-config-mode"
9171
- formControlName="showInWidget"
9172
- />
9173
- <span class="a-s-center"></span>
9174
- <span translate>Show in widget</span>
9175
- <button
9176
- class="btn-help btn-help--sm"
9177
- [attr.aria-label]="'Help' | translate"
9178
- [popover]="helpText"
9179
- placement="right"
9180
- triggers="focus"
9181
- container="body"
9182
- type="button"
9183
- [adaptivePosition]="true"
9184
- ></button>
9185
- </label>
9186
- </div>
9196
+ @if (form.controls.context.value === 'widget') {
9197
+ <label class="c8y-checkbox m-t-8">
9198
+ <input
9199
+ type="checkbox"
9200
+ data-cy="c8y-config-context-selector--hide-in-widget"
9201
+ formControlName="hideInWidget"
9202
+ />
9203
+ <span></span>
9204
+ <span translate>Hide in widget</span>
9205
+ </label>
9187
9206
  }
9188
9207
  </form>
9189
9208
  }
9190
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9209
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9191
9210
  }
9192
9211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigContextSelectorComponent, decorators: [{
9193
9212
  type: Component,
@@ -9197,9 +9216,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
9197
9216
  changeDetection: ChangeDetectionStrategy.OnPush,
9198
9217
  template: `
9199
9218
  @if (form) {
9200
- @let isWidgetContext = form.get('context')?.value === 'widget';
9201
- @let helpText = 'Show controls directly in the widget view for easier access.' | translate;
9202
-
9203
9219
  <form class="form-group m-b-8" [formGroup]="form">
9204
9220
  <div class="d-flex gap-8 a-i-center">
9205
9221
  <label class="c8y-radio">
@@ -9223,29 +9239,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
9223
9239
  <span translate>Widget</span>
9224
9240
  </label>
9225
9241
  </div>
9226
-
9227
- @if (isWidgetContext) {
9228
- <div class="m-t-8">
9229
- <label class="c8y-checkbox">
9230
- <input
9231
- type="checkbox"
9232
- data-cy="c8y-config-context-selector--view-and-config-mode"
9233
- formControlName="showInWidget"
9234
- />
9235
- <span class="a-s-center"></span>
9236
- <span translate>Show in widget</span>
9237
- <button
9238
- class="btn-help btn-help--sm"
9239
- [attr.aria-label]="'Help' | translate"
9240
- [popover]="helpText"
9241
- placement="right"
9242
- triggers="focus"
9243
- container="body"
9244
- type="button"
9245
- [adaptivePosition]="true"
9246
- ></button>
9247
- </label>
9248
- </div>
9242
+ @if (form.controls.context.value === 'widget') {
9243
+ <label class="c8y-checkbox m-t-8">
9244
+ <input
9245
+ type="checkbox"
9246
+ data-cy="c8y-config-context-selector--hide-in-widget"
9247
+ formControlName="hideInWidget"
9248
+ />
9249
+ <span></span>
9250
+ <span translate>Hide in widget</span>
9251
+ </label>
9249
9252
  }
9250
9253
  </form>
9251
9254
  }
@@ -9257,7 +9260,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
9257
9260
  multi: true
9258
9261
  }
9259
9262
  ],
9260
- imports: [C8yTranslatePipe, FormsModule, ReactiveFormsModule, PopoverModule]
9263
+ imports: [C8yTranslatePipe, FormsModule, ReactiveFormsModule]
9261
9264
  }]
9262
9265
  }] });
9263
9266
 
@@ -9740,7 +9743,7 @@ class PreviewControlsComponent {
9740
9743
  this.config.displayMode = GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
9741
9744
  }
9742
9745
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PreviewControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9743
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.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: i2.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 }); }
9746
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { 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: i2.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 }); }
9744
9747
  }
9745
9748
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PreviewControlsComponent, decorators: [{
9746
9749
  type: Component,
@@ -10867,22 +10870,20 @@ const CONTEXT_FEATURE = {
10867
10870
  /** Preset name constants for type-safe access */
10868
10871
  const PRESET_NAME = {
10869
10872
  DEFAULT: 'default',
10870
- ALARM_LIST: 'alarmList',
10871
- CHART: 'chart',
10873
+ LIFETIME_LIST: 'lifetimeList',
10872
10874
  DATA_TABLE: 'dataTable',
10873
10875
  DATA_TABLE_CONFIG: 'dataTableConfig',
10874
10876
  LIVE_ONLY: 'liveOnly',
10875
10877
  AUTO_REFRESH_ONLY: 'autoRefreshOnly',
10876
10878
  AUTO_REFRESH_ONLY_CONFIG: 'autoRefreshOnlyConfig',
10877
10879
  HISTORY_ONLY: 'historyOnly',
10878
- ALARM_LIST_CONFIG: 'alarmListConfig',
10879
- ALARM_LIST_LEGACY: 'alarmListLegacy',
10880
+ LIFETIME_LIST_CONFIG: 'lifetimeListConfig',
10881
+ DATAPOINTS_GRAPH: 'datapointsGraph',
10882
+ DATAPOINTS_GRAPH_CONFIG: 'datapointsGraphConfig',
10880
10883
  KPI: 'kpi',
10881
10884
  KPI_CONFIG: 'kpiConfig',
10882
10885
  DATA_POINTS_LIST: 'dataPointsList',
10883
- DATA_POINTS_LIST_CONFIG: 'dataPointsListConfig',
10884
- DATAPOINTS_GRAPH: 'datapointsGraph',
10885
- DATAPOINTS_GRAPH_CONFIG: 'datapointsGraphConfig'
10886
+ DATA_POINTS_LIST_CONFIG: 'dataPointsListConfig'
10886
10887
  };
10887
10888
  /** Control presets for different widget types (mode constraints applied by applyModeConstraints) */
10888
10889
  const CONTROL_PRESETS = {
@@ -10891,9 +10892,15 @@ const CONTROL_PRESETS = {
10891
10892
  dashboard: [
10892
10893
  CONTEXT_FEATURE.LIVE_TIME,
10893
10894
  CONTEXT_FEATURE.HISTORY_TIME,
10894
- CONTEXT_FEATURE.AUTO_REFRESH
10895
+ CONTEXT_FEATURE.AUTO_REFRESH,
10896
+ CONTEXT_FEATURE.REFRESH
10897
+ ],
10898
+ config: [
10899
+ CONTEXT_FEATURE.LIVE_TIME,
10900
+ CONTEXT_FEATURE.HISTORY_TIME,
10901
+ CONTEXT_FEATURE.AUTO_REFRESH,
10902
+ CONTEXT_FEATURE.REFRESH
10895
10903
  ],
10896
- config: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
10897
10904
  view_and_config: [
10898
10905
  CONTEXT_FEATURE.LIVE_TIME,
10899
10906
  CONTEXT_FEATURE.HISTORY_TIME,
@@ -10902,33 +10909,52 @@ const CONTROL_PRESETS = {
10902
10909
  CONTEXT_FEATURE.REFRESH
10903
10910
  ]
10904
10911
  },
10905
- /** For alarm/event lists (supports both live and history modes) */
10906
- [PRESET_NAME.ALARM_LIST]: {
10912
+ /**
10913
+ * Same controls as `DATA_POINTS_LIST` (time hidden in config mode), but adds the
10914
+ * "Lifetime" (epoch → now) entry to the interval picker — for widgets whose data has
10915
+ * a queryable origin (alarms, events).
10916
+ */
10917
+ [PRESET_NAME.LIFETIME_LIST]: {
10907
10918
  dashboard: [
10908
10919
  CONTEXT_FEATURE.LIVE_TIME,
10909
10920
  CONTEXT_FEATURE.HISTORY_TIME,
10910
- CONTEXT_FEATURE.AUTO_REFRESH
10921
+ CONTEXT_FEATURE.AUTO_REFRESH,
10922
+ CONTEXT_FEATURE.REFRESH
10911
10923
  ],
10912
- config: [CONTEXT_FEATURE.AUTO_REFRESH],
10924
+ config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
10913
10925
  view_and_config: [
10914
10926
  CONTEXT_FEATURE.LIVE_TIME,
10915
10927
  CONTEXT_FEATURE.HISTORY_TIME,
10916
- CONTEXT_FEATURE.AUTO_REFRESH
10917
- ]
10928
+ CONTEXT_FEATURE.AUTO_REFRESH,
10929
+ CONTEXT_FEATURE.REFRESH
10930
+ ],
10931
+ supportsLifetime: true
10918
10932
  },
10919
- /** For alarm/event lists in config mode (supports both live and history modes with time in config) */
10920
- [PRESET_NAME.ALARM_LIST_CONFIG]: {
10933
+ /**
10934
+ * Same controls as `DATA_POINTS_LIST_CONFIG` (LT/HT/AR/RF in all modes), but adds the
10935
+ * "Lifetime" (epoch → now) entry to the interval picker — for widgets whose data has
10936
+ * a queryable origin (alarms, events).
10937
+ */
10938
+ [PRESET_NAME.LIFETIME_LIST_CONFIG]: {
10921
10939
  dashboard: [
10922
10940
  CONTEXT_FEATURE.LIVE_TIME,
10923
10941
  CONTEXT_FEATURE.HISTORY_TIME,
10924
- CONTEXT_FEATURE.AUTO_REFRESH
10942
+ CONTEXT_FEATURE.AUTO_REFRESH,
10943
+ CONTEXT_FEATURE.REFRESH
10944
+ ],
10945
+ config: [
10946
+ CONTEXT_FEATURE.LIVE_TIME,
10947
+ CONTEXT_FEATURE.HISTORY_TIME,
10948
+ CONTEXT_FEATURE.AUTO_REFRESH,
10949
+ CONTEXT_FEATURE.REFRESH
10925
10950
  ],
10926
- config: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
10927
10951
  view_and_config: [
10928
10952
  CONTEXT_FEATURE.LIVE_TIME,
10929
10953
  CONTEXT_FEATURE.HISTORY_TIME,
10930
- CONTEXT_FEATURE.AUTO_REFRESH
10931
- ]
10954
+ CONTEXT_FEATURE.AUTO_REFRESH,
10955
+ CONTEXT_FEATURE.REFRESH
10956
+ ],
10957
+ supportsLifetime: true
10932
10958
  },
10933
10959
  /** For data tables in view/preview mode (aggregation support, no manual refresh) */
10934
10960
  [PRESET_NAME.DATA_TABLE]: {
@@ -10936,14 +10962,16 @@ const CONTROL_PRESETS = {
10936
10962
  CONTEXT_FEATURE.LIVE_TIME,
10937
10963
  CONTEXT_FEATURE.HISTORY_TIME,
10938
10964
  CONTEXT_FEATURE.AGGREGATION,
10939
- CONTEXT_FEATURE.AUTO_REFRESH
10965
+ CONTEXT_FEATURE.AUTO_REFRESH,
10966
+ CONTEXT_FEATURE.REFRESH
10940
10967
  ],
10941
- config: [CONTEXT_FEATURE.AGGREGATION, CONTEXT_FEATURE.AUTO_REFRESH],
10968
+ config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
10942
10969
  view_and_config: [
10943
10970
  CONTEXT_FEATURE.LIVE_TIME,
10944
10971
  CONTEXT_FEATURE.HISTORY_TIME,
10945
10972
  CONTEXT_FEATURE.AGGREGATION,
10946
- CONTEXT_FEATURE.AUTO_REFRESH
10973
+ CONTEXT_FEATURE.AUTO_REFRESH,
10974
+ CONTEXT_FEATURE.REFRESH
10947
10975
  ]
10948
10976
  },
10949
10977
  /** For data tables in config mode (full time controls with aggregation) */
@@ -10951,29 +10979,16 @@ const CONTROL_PRESETS = {
10951
10979
  dashboard: [
10952
10980
  CONTEXT_FEATURE.LIVE_TIME,
10953
10981
  CONTEXT_FEATURE.HISTORY_TIME,
10954
- CONTEXT_FEATURE.AUTO_REFRESH
10982
+ CONTEXT_FEATURE.AUTO_REFRESH,
10983
+ CONTEXT_FEATURE.REFRESH
10955
10984
  ],
10956
10985
  config: [
10957
10986
  CONTEXT_FEATURE.LIVE_TIME,
10958
10987
  CONTEXT_FEATURE.HISTORY_TIME,
10959
10988
  CONTEXT_FEATURE.AGGREGATION,
10960
- CONTEXT_FEATURE.AUTO_REFRESH
10961
- ],
10962
- view_and_config: [
10963
- CONTEXT_FEATURE.LIVE_TIME,
10964
- CONTEXT_FEATURE.HISTORY_TIME,
10965
- CONTEXT_FEATURE.AGGREGATION,
10966
- CONTEXT_FEATURE.AUTO_REFRESH
10967
- ]
10968
- },
10969
- /** For charts with aggregation support (supports both live and history modes) */
10970
- [PRESET_NAME.CHART]: {
10971
- dashboard: [
10972
- CONTEXT_FEATURE.LIVE_TIME,
10973
- CONTEXT_FEATURE.HISTORY_TIME,
10974
- CONTEXT_FEATURE.AUTO_REFRESH
10989
+ CONTEXT_FEATURE.AUTO_REFRESH,
10990
+ CONTEXT_FEATURE.REFRESH
10975
10991
  ],
10976
- config: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
10977
10992
  view_and_config: [
10978
10993
  CONTEXT_FEATURE.LIVE_TIME,
10979
10994
  CONTEXT_FEATURE.HISTORY_TIME,
@@ -10984,129 +10999,143 @@ const CONTROL_PRESETS = {
10984
10999
  },
10985
11000
  /** For live-only widgets (no history mode support) */
10986
11001
  [PRESET_NAME.LIVE_ONLY]: {
10987
- dashboard: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
10988
- config: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
11002
+ dashboard: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11003
+ config: [CONTEXT_FEATURE.LIVE_TIME, CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
10989
11004
  view_and_config: [
10990
11005
  CONTEXT_FEATURE.LIVE_TIME,
10991
11006
  CONTEXT_FEATURE.AUTO_REFRESH,
10992
11007
  CONTEXT_FEATURE.REFRESH
10993
11008
  ]
10994
11009
  },
10995
- /** For auto-refresh-only widgets (no history mode, no live time range support) — preview shows no controls in config mode */
11010
+ /**
11011
+ * For auto-refresh-only widgets (no history mode, no live time range support).
11012
+ * The `config` mode is intentionally empty so the widget renders no controls in
11013
+ * the configuration sidebar (used by the HTML widget).
11014
+ */
10996
11015
  [PRESET_NAME.AUTO_REFRESH_ONLY]: {
10997
- dashboard: [CONTEXT_FEATURE.AUTO_REFRESH],
11016
+ dashboard: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
10998
11017
  config: [],
10999
- view_and_config: [CONTEXT_FEATURE.AUTO_REFRESH]
11018
+ view_and_config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH]
11000
11019
  },
11001
11020
  /** For auto-refresh-only widget config section (shows auto-refresh toggle in all modes) */
11002
11021
  [PRESET_NAME.AUTO_REFRESH_ONLY_CONFIG]: {
11003
- dashboard: [CONTEXT_FEATURE.AUTO_REFRESH],
11004
- config: [CONTEXT_FEATURE.AUTO_REFRESH],
11005
- view_and_config: [CONTEXT_FEATURE.AUTO_REFRESH]
11022
+ dashboard: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11023
+ config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11024
+ view_and_config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH]
11006
11025
  },
11007
11026
  /** For history-only widgets (no live mode support) */
11008
11027
  [PRESET_NAME.HISTORY_ONLY]: {
11009
- dashboard: [CONTEXT_FEATURE.HISTORY_TIME],
11010
- config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AGGREGATION],
11028
+ dashboard: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.REFRESH],
11029
+ config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AGGREGATION, CONTEXT_FEATURE.REFRESH],
11011
11030
  view_and_config: [
11012
11031
  CONTEXT_FEATURE.HISTORY_TIME,
11013
11032
  CONTEXT_FEATURE.AGGREGATION,
11014
11033
  CONTEXT_FEATURE.REFRESH
11015
11034
  ]
11016
11035
  },
11017
- [PRESET_NAME.ALARM_LIST_LEGACY]: {
11036
+ /** For data points graph widget inline controls (supports aggregation in dashboard mode) */
11037
+ [PRESET_NAME.DATAPOINTS_GRAPH]: {
11018
11038
  dashboard: [
11019
11039
  CONTEXT_FEATURE.LIVE_TIME,
11020
11040
  CONTEXT_FEATURE.HISTORY_TIME,
11021
- CONTEXT_FEATURE.AUTO_REFRESH
11041
+ CONTEXT_FEATURE.AUTO_REFRESH,
11042
+ CONTEXT_FEATURE.AGGREGATION,
11043
+ CONTEXT_FEATURE.REFRESH
11022
11044
  ],
11023
11045
  config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11024
11046
  view_and_config: [
11025
11047
  CONTEXT_FEATURE.LIVE_TIME,
11026
11048
  CONTEXT_FEATURE.HISTORY_TIME,
11027
- CONTEXT_FEATURE.AUTO_REFRESH
11049
+ CONTEXT_FEATURE.AGGREGATION,
11050
+ CONTEXT_FEATURE.AUTO_REFRESH,
11051
+ CONTEXT_FEATURE.REFRESH
11028
11052
  ]
11029
11053
  },
11030
- /** For KPI widget in view mode (live/history, no aggregation) */
11031
- [PRESET_NAME.KPI]: {
11032
- dashboard: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
11033
- config: [CONTEXT_FEATURE.AUTO_REFRESH],
11034
- view_and_config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH]
11035
- },
11036
- /** For KPI widget in config mode (full time controls, no aggregation) */
11037
- [PRESET_NAME.KPI_CONFIG]: {
11038
- dashboard: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
11039
- config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH],
11040
- view_and_config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH]
11041
- },
11042
- /** For data points list (supports both live and history modes) */
11043
- [PRESET_NAME.DATA_POINTS_LIST]: {
11054
+ /** For data points graph widget config section (full controls including time range) */
11055
+ [PRESET_NAME.DATAPOINTS_GRAPH_CONFIG]: {
11044
11056
  dashboard: [
11045
11057
  CONTEXT_FEATURE.LIVE_TIME,
11046
11058
  CONTEXT_FEATURE.HISTORY_TIME,
11047
- CONTEXT_FEATURE.AUTO_REFRESH
11059
+ CONTEXT_FEATURE.AUTO_REFRESH,
11060
+ CONTEXT_FEATURE.AGGREGATION,
11061
+ CONTEXT_FEATURE.REFRESH
11062
+ ],
11063
+ config: [
11064
+ CONTEXT_FEATURE.LIVE_TIME,
11065
+ CONTEXT_FEATURE.HISTORY_TIME,
11066
+ CONTEXT_FEATURE.AUTO_REFRESH,
11067
+ CONTEXT_FEATURE.AGGREGATION,
11068
+ CONTEXT_FEATURE.REFRESH
11048
11069
  ],
11049
- config: [CONTEXT_FEATURE.AUTO_REFRESH],
11050
11070
  view_and_config: [
11051
11071
  CONTEXT_FEATURE.LIVE_TIME,
11052
11072
  CONTEXT_FEATURE.HISTORY_TIME,
11053
- CONTEXT_FEATURE.AUTO_REFRESH
11073
+ CONTEXT_FEATURE.AGGREGATION,
11074
+ CONTEXT_FEATURE.AUTO_REFRESH,
11075
+ CONTEXT_FEATURE.REFRESH
11054
11076
  ]
11055
11077
  },
11056
- /** For data points list in config mode (supports both live and history modes with time in config) */
11057
- [PRESET_NAME.DATA_POINTS_LIST_CONFIG]: {
11078
+ /** For KPI widget in view mode (live/history, no aggregation) */
11079
+ [PRESET_NAME.KPI]: {
11058
11080
  dashboard: [
11059
- CONTEXT_FEATURE.LIVE_TIME,
11060
11081
  CONTEXT_FEATURE.HISTORY_TIME,
11061
- CONTEXT_FEATURE.AUTO_REFRESH
11082
+ CONTEXT_FEATURE.AUTO_REFRESH,
11083
+ CONTEXT_FEATURE.REFRESH
11062
11084
  ],
11063
- config: [
11085
+ config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11086
+ view_and_config: [
11087
+ CONTEXT_FEATURE.HISTORY_TIME,
11064
11088
  CONTEXT_FEATURE.AUTO_REFRESH,
11065
- CONTEXT_FEATURE.LIVE_TIME,
11089
+ CONTEXT_FEATURE.REFRESH
11090
+ ]
11091
+ },
11092
+ /** For KPI widget in config mode (full time controls, no aggregation) */
11093
+ [PRESET_NAME.KPI_CONFIG]: {
11094
+ dashboard: [
11066
11095
  CONTEXT_FEATURE.HISTORY_TIME,
11067
- CONTEXT_FEATURE.AUTO_REFRESH
11096
+ CONTEXT_FEATURE.AUTO_REFRESH,
11097
+ CONTEXT_FEATURE.REFRESH
11068
11098
  ],
11099
+ config: [CONTEXT_FEATURE.HISTORY_TIME, CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11069
11100
  view_and_config: [
11070
- CONTEXT_FEATURE.LIVE_TIME,
11071
11101
  CONTEXT_FEATURE.HISTORY_TIME,
11072
- CONTEXT_FEATURE.AUTO_REFRESH
11102
+ CONTEXT_FEATURE.AUTO_REFRESH,
11103
+ CONTEXT_FEATURE.REFRESH
11073
11104
  ]
11074
11105
  },
11075
- /** For data points graph widget inline controls (supports aggregation in dashboard mode) */
11076
- [PRESET_NAME.DATAPOINTS_GRAPH]: {
11106
+ /** For data points list (supports both live and history modes) */
11107
+ [PRESET_NAME.DATA_POINTS_LIST]: {
11077
11108
  dashboard: [
11078
11109
  CONTEXT_FEATURE.LIVE_TIME,
11079
11110
  CONTEXT_FEATURE.HISTORY_TIME,
11080
11111
  CONTEXT_FEATURE.AUTO_REFRESH,
11081
- CONTEXT_FEATURE.AGGREGATION
11112
+ CONTEXT_FEATURE.REFRESH
11082
11113
  ],
11083
- config: [CONTEXT_FEATURE.AUTO_REFRESH],
11114
+ config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
11084
11115
  view_and_config: [
11085
11116
  CONTEXT_FEATURE.LIVE_TIME,
11086
11117
  CONTEXT_FEATURE.HISTORY_TIME,
11087
- CONTEXT_FEATURE.AGGREGATION,
11088
11118
  CONTEXT_FEATURE.AUTO_REFRESH,
11089
- CONTEXT_FEATURE.REFRESH_HISTORY
11119
+ CONTEXT_FEATURE.REFRESH
11090
11120
  ]
11091
11121
  },
11092
- /** For data points graph widget config section (full controls including time range) */
11093
- [PRESET_NAME.DATAPOINTS_GRAPH_CONFIG]: {
11122
+ /** For data points list in config mode (supports both live and history modes with time in config) */
11123
+ [PRESET_NAME.DATA_POINTS_LIST_CONFIG]: {
11094
11124
  dashboard: [
11095
11125
  CONTEXT_FEATURE.LIVE_TIME,
11096
11126
  CONTEXT_FEATURE.HISTORY_TIME,
11097
11127
  CONTEXT_FEATURE.AUTO_REFRESH,
11098
- CONTEXT_FEATURE.AGGREGATION
11128
+ CONTEXT_FEATURE.REFRESH
11099
11129
  ],
11100
11130
  config: [
11101
11131
  CONTEXT_FEATURE.LIVE_TIME,
11102
11132
  CONTEXT_FEATURE.HISTORY_TIME,
11103
11133
  CONTEXT_FEATURE.AUTO_REFRESH,
11104
- CONTEXT_FEATURE.AGGREGATION
11134
+ CONTEXT_FEATURE.REFRESH
11105
11135
  ],
11106
11136
  view_and_config: [
11107
11137
  CONTEXT_FEATURE.LIVE_TIME,
11108
11138
  CONTEXT_FEATURE.HISTORY_TIME,
11109
- CONTEXT_FEATURE.AGGREGATION,
11110
11139
  CONTEXT_FEATURE.AUTO_REFRESH,
11111
11140
  CONTEXT_FEATURE.REFRESH
11112
11141
  ]
@@ -11159,6 +11188,11 @@ function getSupportedModes(controls, displayMode) {
11159
11188
  // Fallback to LIVE if no mode features detected
11160
11189
  return modes.length > 0 ? modes : [REFRESH_OPTION.LIVE];
11161
11190
  }
11191
+ /** Standard intervals, optionally prepended with "Lifetime" when the preset opts in. */
11192
+ function resolveIntervalOptions(controls) {
11193
+ const presetDef = typeof controls === 'string' ? CONTROL_PRESETS[controls] : controls;
11194
+ return presetDef?.supportsLifetime ? [LIFETIME_INTERVAL, ...INTERVALS] : [...INTERVALS];
11195
+ }
11162
11196
  /**
11163
11197
  * Convert controls preset to GlobalContextSettings for registration.
11164
11198
  */
@@ -11194,6 +11228,7 @@ class ConfigModeControls {
11194
11228
  this.lastEmittedContext = signal({}, ...(ngDevMode ? [{ debugName: "lastEmittedContext" }] : []));
11195
11229
  this.settings = computed(() => controlsToSettings(this.controls(), this.displayMode(), this.refreshOption()), ...(ngDevMode ? [{ debugName: "settings" }] : []));
11196
11230
  this.supportedModes = computed(() => getSupportedModes(this.controls(), this.displayMode()), ...(ngDevMode ? [{ debugName: "supportedModes" }] : []));
11231
+ this.intervalOptions = computed(() => resolveIntervalOptions(this.controls()), ...(ngDevMode ? [{ debugName: "intervalOptions" }] : []));
11197
11232
  // Sync with incoming config
11198
11233
  effect(() => {
11199
11234
  const cfg = this.config();
@@ -11343,12 +11378,13 @@ class ConfigModeControls {
11343
11378
  [liveContext]="liveState()"
11344
11379
  [historyContext]="historyState()"
11345
11380
  [supportedModes]="supportedModes()"
11381
+ [intervalOptions]="intervalOptions()"
11346
11382
  (contextChange)="onConfigurationChange($event)"
11347
11383
  (refreshOptionChange)="onRefreshOptionChange($event)"
11348
11384
  ></c8y-configuration-controls>
11349
11385
  </fieldset>
11350
11386
  }
11351
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11387
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11352
11388
  }
11353
11389
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ConfigModeControls, decorators: [{
11354
11390
  type: Component,
@@ -11399,6 +11435,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
11399
11435
  [liveContext]="liveState()"
11400
11436
  [historyContext]="historyState()"
11401
11437
  [supportedModes]="supportedModes()"
11438
+ [intervalOptions]="intervalOptions()"
11402
11439
  (contextChange)="onConfigurationChange($event)"
11403
11440
  (refreshOptionChange)="onRefreshOptionChange($event)"
11404
11441
  ></c8y-configuration-controls>
@@ -11421,42 +11458,46 @@ class ContextControlsComponent {
11421
11458
  this.configChange = output();
11422
11459
  this.refresh = output();
11423
11460
  this.lastEmittedState = signal({}, ...(ngDevMode ? [{ debugName: "lastEmittedState" }] : []));
11424
- /**
11425
- * Visible controls for the template.
11426
- * LIVE_TIME and HISTORY_TIME are normalized to 'time' for template simplicity.
11427
- */
11428
11461
  this.visibleControls = computed(() => {
11462
+ const cfg = this.config();
11463
+ if (!cfg)
11464
+ return null;
11429
11465
  const controlsInput = this.controls();
11430
11466
  const presetDef = typeof controlsInput === 'string' ? CONTROL_PRESETS[controlsInput] : controlsInput;
11431
11467
  const baseControls = presetDef?.[this.displayMode()];
11432
11468
  if (!baseControls) {
11433
11469
  return [];
11434
11470
  }
11435
- const refreshOption = this.config()?.refreshOption || REFRESH_OPTION.LIVE;
11471
+ const refreshOption = cfg.refreshOption || REFRESH_OPTION.LIVE;
11436
11472
  const filteredControls = applyModeConstraints(baseControls, refreshOption);
11437
- // Normalize LIVE_TIME/HISTORY_TIME to 'time' and REFRESH_*/REFRESH to 'refresh' for template
11438
- return filteredControls.map(c => {
11473
+ const normalized = filteredControls.map(c => {
11439
11474
  if (c === CONTEXT_FEATURE.LIVE_TIME || c === CONTEXT_FEATURE.HISTORY_TIME)
11440
11475
  return 'time';
11441
11476
  if (c === CONTEXT_FEATURE.REFRESH_LIVE || c === CONTEXT_FEATURE.REFRESH_HISTORY)
11442
11477
  return CONTEXT_FEATURE.REFRESH;
11443
11478
  return c;
11444
11479
  });
11480
+ // Manual refresh is redundant while auto-refresh is rendered and running.
11481
+ if (cfg.isAutoRefreshEnabled && normalized.includes(CONTEXT_FEATURE.AUTO_REFRESH)) {
11482
+ return normalized.filter(c => c !== CONTEXT_FEATURE.REFRESH);
11483
+ }
11484
+ return normalized;
11445
11485
  }, ...(ngDevMode ? [{ debugName: "visibleControls" }] : []));
11446
11486
  this.disabledAggregations = computed(() => {
11447
- const dateCtx = this.config().dateTimeContext;
11487
+ const dateCtx = this.config()?.dateTimeContext;
11448
11488
  if (!dateCtx)
11449
11489
  return {};
11450
11490
  const [from, to] = this.parseDateRange(dateCtx);
11451
11491
  return this.aggregationValidationService.getDisabledAggregations([from, to]);
11452
11492
  }, ...(ngDevMode ? [{ debugName: "disabledAggregations" }] : []));
11453
11493
  this.dateTimePickerConfig = computed(() => {
11454
- const refreshOption = this.config().refreshOption;
11494
+ const refreshOption = this.config()?.refreshOption;
11455
11495
  return refreshOption === REFRESH_OPTION.HISTORY
11456
11496
  ? { showDateFrom: true, showDateTo: true }
11457
11497
  : { showDateFrom: true, showDateTo: false };
11458
11498
  }, ...(ngDevMode ? [{ debugName: "dateTimePickerConfig" }] : []));
11459
- this.autoRefreshSeconds = computed(() => this.config().refreshInterval || GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL, ...(ngDevMode ? [{ debugName: "autoRefreshSeconds" }] : []));
11499
+ this.autoRefreshSeconds = computed(() => this.config()?.refreshInterval || GLOBAL_CONTEXT_DEFAULTS.REFRESH_INTERVAL, ...(ngDevMode ? [{ debugName: "autoRefreshSeconds" }] : []));
11500
+ this.intervalOptions = computed(() => resolveIntervalOptions(this.controls()), ...(ngDevMode ? [{ debugName: "intervalOptions" }] : []));
11460
11501
  this.form = this.fb.group({
11461
11502
  dateTimeContext: [null],
11462
11503
  aggregation: [null],
@@ -11503,6 +11544,8 @@ class ContextControlsComponent {
11503
11544
  syncConfigToForm() {
11504
11545
  effect(() => {
11505
11546
  const cfg = this.config();
11547
+ if (!cfg)
11548
+ return;
11506
11549
  this.form.patchValue(cfg, { emitEvent: false });
11507
11550
  });
11508
11551
  }
@@ -11511,6 +11554,8 @@ class ContextControlsComponent {
11511
11554
  if (this.displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD)
11512
11555
  return;
11513
11556
  const cfg = this.config();
11557
+ if (!cfg)
11558
+ return;
11514
11559
  const isLive = cfg.refreshOption !== REFRESH_OPTION.HISTORY && !!cfg.dateTimeContext;
11515
11560
  const normalized = isLive
11516
11561
  ? { ...cfg, dateTimeContext: DateTimeContextUtil.normalizeForLive(cfg.dateTimeContext) }
@@ -11552,12 +11597,9 @@ class ContextControlsComponent {
11552
11597
  }
11553
11598
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ContextControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11554
11599
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ContextControlsComponent, isStandalone: true, selector: "c8y-context-controls", inputs: { controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", refresh: "refresh" }, ngImport: i0, template: `
11555
- <form
11556
- class="d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll h-auto min-width-0 widget-controls"
11557
- [formGroup]="form"
11558
- >
11559
- <div class="input-group w-auto">
11560
- @if (visibleControls().includes('aggregation')) {
11600
+ <form class="d-flex gap-16 h-auto min-width-0 widget-controls" [formGroup]="form">
11601
+ <div class="input-group w-auto min-width-0">
11602
+ @if (visibleControls()?.includes('aggregation')) {
11561
11603
  <c8y-aggregation-picker
11562
11604
  data-cy="global-inline-date-context--Aggregation-display"
11563
11605
  formControlName="aggregation"
@@ -11567,7 +11609,7 @@ class ContextControlsComponent {
11567
11609
  </c8y-aggregation-picker>
11568
11610
  }
11569
11611
 
11570
- @if (visibleControls().includes('autoRefresh')) {
11612
+ @if (visibleControls()?.includes('autoRefresh')) {
11571
11613
  <c8y-auto-refresh-control
11572
11614
  formControlName="isAutoRefreshEnabled"
11573
11615
  [autoRefreshSeconds]="autoRefreshSeconds()"
@@ -11577,16 +11619,18 @@ class ContextControlsComponent {
11577
11619
  </c8y-auto-refresh-control>
11578
11620
  }
11579
11621
 
11580
- @if (visibleControls().includes('time')) {
11622
+ @if (visibleControls()?.includes('time')) {
11581
11623
  <c8y-date-time-context-picker
11624
+ class="min-width-0"
11582
11625
  style="margin-left: -1px"
11583
11626
  formControlName="dateTimeContext"
11584
11627
  [config]="dateTimePickerConfig()"
11628
+ [intervalOptions]="intervalOptions()"
11585
11629
  >
11586
11630
  </c8y-date-time-context-picker>
11587
11631
  }
11588
11632
 
11589
- @if (visibleControls().includes('refresh')) {
11633
+ @if (visibleControls()?.includes('refresh')) {
11590
11634
  <div class="input-group-btn">
11591
11635
  <button
11592
11636
  class="btn btn-default"
@@ -11606,7 +11650,7 @@ class ContextControlsComponent {
11606
11650
  }
11607
11651
  </div>
11608
11652
  </form>
11609
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.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: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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" }] }); }
11653
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { 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: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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" }] }); }
11610
11654
  }
11611
11655
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ContextControlsComponent, decorators: [{
11612
11656
  type: Component,
@@ -11623,12 +11667,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
11623
11667
  TooltipModule
11624
11668
  ],
11625
11669
  template: `
11626
- <form
11627
- class="d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll h-auto min-width-0 widget-controls"
11628
- [formGroup]="form"
11629
- >
11630
- <div class="input-group w-auto">
11631
- @if (visibleControls().includes('aggregation')) {
11670
+ <form class="d-flex gap-16 h-auto min-width-0 widget-controls" [formGroup]="form">
11671
+ <div class="input-group w-auto min-width-0">
11672
+ @if (visibleControls()?.includes('aggregation')) {
11632
11673
  <c8y-aggregation-picker
11633
11674
  data-cy="global-inline-date-context--Aggregation-display"
11634
11675
  formControlName="aggregation"
@@ -11638,7 +11679,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
11638
11679
  </c8y-aggregation-picker>
11639
11680
  }
11640
11681
 
11641
- @if (visibleControls().includes('autoRefresh')) {
11682
+ @if (visibleControls()?.includes('autoRefresh')) {
11642
11683
  <c8y-auto-refresh-control
11643
11684
  formControlName="isAutoRefreshEnabled"
11644
11685
  [autoRefreshSeconds]="autoRefreshSeconds()"
@@ -11648,16 +11689,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
11648
11689
  </c8y-auto-refresh-control>
11649
11690
  }
11650
11691
 
11651
- @if (visibleControls().includes('time')) {
11692
+ @if (visibleControls()?.includes('time')) {
11652
11693
  <c8y-date-time-context-picker
11694
+ class="min-width-0"
11653
11695
  style="margin-left: -1px"
11654
11696
  formControlName="dateTimeContext"
11655
11697
  [config]="dateTimePickerConfig()"
11698
+ [intervalOptions]="intervalOptions()"
11656
11699
  >
11657
11700
  </c8y-date-time-context-picker>
11658
11701
  }
11659
11702
 
11660
- @if (visibleControls().includes('refresh')) {
11703
+ @if (visibleControls()?.includes('refresh')) {
11661
11704
  <div class="input-group-btn">
11662
11705
  <button
11663
11706
  class="btn btn-default"
@@ -11681,6 +11724,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
11681
11724
  }]
11682
11725
  }], ctorParameters: () => [], propDecorators: { controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }] } });
11683
11726
 
11727
+ class HeaderTemplateService {
11728
+ /**
11729
+ * Registers a header template on the host dashboard child.
11730
+ *
11731
+ * Call from an injection context (e.g. constructor). Pass signal-reading getters
11732
+ * in `opts` for reactive updates; cleanup is automatic on destroy/change.
11733
+ *
11734
+ * @param opts Getters resolving the host dashboard child and template ref, plus
11735
+ * the display priority. Read signals inside the getters to drive re-registration.
11736
+ */
11737
+ register(opts) {
11738
+ const { getDashboardChild, getTemplateRef, priority } = opts;
11739
+ effect(onCleanup => {
11740
+ const dashChild = getDashboardChild();
11741
+ const templateRef = getTemplateRef();
11742
+ if (!dashChild || !templateRef)
11743
+ return;
11744
+ const templates = dashChild._additionalHeaderTemplates.value;
11745
+ if (templates.some(t => t.template === templateRef))
11746
+ return;
11747
+ dashChild._additionalHeaderTemplates.next([
11748
+ ...templates,
11749
+ { template: templateRef, priority }
11750
+ ]);
11751
+ onCleanup(() => {
11752
+ const current = dashChild._additionalHeaderTemplates.value;
11753
+ dashChild._additionalHeaderTemplates.next(current.filter(t => t.template !== templateRef));
11754
+ });
11755
+ });
11756
+ }
11757
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: HeaderTemplateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11758
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: HeaderTemplateService }); }
11759
+ }
11760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: HeaderTemplateService, decorators: [{
11761
+ type: Injectable
11762
+ }] });
11763
+
11684
11764
  // Map preset controls to state keys
11685
11765
  const CONTROL_DISPLAY_CONFIG = {
11686
11766
  liveTime: {
@@ -11716,11 +11796,18 @@ class LinkButtonsComponent {
11716
11796
  constructor() {
11717
11797
  this.injectedDashboardChild = inject(DashboardChildComponent, { optional: true });
11718
11798
  this.translateService = inject(TranslateService);
11799
+ this.headerTemplate = inject(HeaderTemplateService);
11800
+ this.headerTemplateRef = viewChild('headerContent', ...(ngDevMode ? [{ debugName: "headerTemplateRef", read: TemplateRef }] : [{ read: TemplateRef }]));
11719
11801
  this.dashboardChild = input(...(ngDevMode ? [undefined, { debugName: "dashboardChild" }] : []));
11720
11802
  this.isLinked = input.required(...(ngDevMode ? [{ debugName: "isLinked" }] : []));
11721
11803
  this.controls = input(PRESET_NAME.DEFAULT, ...(ngDevMode ? [{ debugName: "controls" }] : []));
11722
11804
  this.config = input({}, ...(ngDevMode ? [{ debugName: "config" }] : []));
11805
+ this.displayMode = input(GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
11806
+ this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
11807
+ this.emitRefresh = input(true, ...(ngDevMode ? [{ debugName: "emitRefresh" }] : []));
11723
11808
  this.toggle = output();
11809
+ this.configChange = output();
11810
+ this.refresh = output();
11724
11811
  this.visibleControls = computed(() => {
11725
11812
  const controlsInput = this.controls();
11726
11813
  const presetDef = typeof controlsInput === 'string' ? CONTROL_PRESETS[controlsInput] : controlsInput;
@@ -11744,106 +11831,123 @@ class LinkButtonsComponent {
11744
11831
  const linkedToDashboardLabel = this.translateService.instant(gettext('Synced to dashboard:'));
11745
11832
  return `${linkedToDashboardLabel}\n${linkedNamesList}\n${clickToToggleLabel}`;
11746
11833
  }, ...(ngDevMode ? [{ debugName: "masterTooltipText" }] : []));
11747
- }
11748
- ngAfterViewInit() {
11749
- const dashChild = this.getDashboardChild();
11750
- if (!dashChild || !this.headerTemplateRef) {
11751
- return;
11752
- }
11753
- const templates = dashChild._additionalHeaderTemplates.value;
11754
- if (!templates.some(t => t.template === this.headerTemplateRef)) {
11755
- dashChild._additionalHeaderTemplates.next([
11756
- ...templates,
11757
- {
11758
- template: this.headerTemplateRef,
11759
- priority: 100
11760
- }
11761
- ]);
11762
- }
11763
- }
11764
- ngOnDestroy() {
11765
- const dashChild = this.getDashboardChild();
11766
- if (!dashChild || !this.headerTemplateRef) {
11767
- return;
11768
- }
11769
- const templates = dashChild._additionalHeaderTemplates.value;
11770
- dashChild._additionalHeaderTemplates.next(templates.filter(t => t.template !== this.headerTemplateRef));
11834
+ this.headerTemplate.register({
11835
+ getDashboardChild: () => this.getDashboardChild(),
11836
+ getTemplateRef: () => this.headerTemplateRef(),
11837
+ priority: 100
11838
+ });
11771
11839
  }
11772
11840
  getDashboardChild() {
11773
11841
  return this.dashboardChild() ?? this.injectedDashboardChild ?? null;
11774
11842
  }
11775
11843
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LinkButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11776
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LinkButtonsComponent, isStandalone: true, selector: "c8y-link-buttons", inputs: { dashboardChild: { classPropertyName: "dashboardChild", publicName: "dashboardChild", isSignal: true, isRequired: false, transformFunction: null }, isLinked: { classPropertyName: "isLinked", publicName: "isLinked", isSignal: true, isRequired: true, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggle: "toggle" }, viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: `
11844
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LinkButtonsComponent, isStandalone: true, selector: "c8y-link-buttons", inputs: { dashboardChild: { classPropertyName: "dashboardChild", publicName: "dashboardChild", isSignal: true, isRequired: false, transformFunction: null }, isLinked: { classPropertyName: "isLinked", publicName: "isLinked", isSignal: true, isRequired: true, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggle: "toggle", configChange: "configChange", refresh: "refresh" }, providers: [HeaderTemplateService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: `
11777
11845
  <ng-template #headerContent>
11778
- <button
11779
- class="btn-icon-dot-set"
11780
- [class.active]="isLinked()"
11781
- [attr.aria-label]="'Global context sync controls' | translate"
11782
- [tooltip]="masterTooltipTemplate"
11783
- delay="500"
11784
- container="body"
11785
- (click)="toggle.emit(!isLinked())"
11786
- data-cy="global-context-link--all"
11846
+ <div
11847
+ class="c8y-header-controls-group"
11848
+ [class.c8y-header-controls-group--has-summary]="!isLinked()"
11787
11849
  >
11788
- <span class="btn-icon-dot__item default" [class.active]="isLinked()">
11789
- <i [c8yIcon]="isLinked() ? 'link' : 'unlink'"></i>
11790
- </span>
11791
- @for (control of visibleControls(); track control.stateKey) {
11792
- <span
11793
- [class]="control.cssClass + ' btn-icon-dot__item'"
11794
- [class.active]="isLinked()"
11795
- [attr.data-cy]="'global-context-link--' + control.stateKey"
11796
- >
11797
- <i [c8yIcon]="control.icon"></i>
11850
+ <button
11851
+ class="btn-icon-dot-set"
11852
+ [class.active]="isLinked()"
11853
+ [attr.aria-label]="'Global context sync controls' | translate"
11854
+ [tooltip]="masterTooltipTemplate"
11855
+ delay="500"
11856
+ container="body"
11857
+ (click)="toggle.emit(!isLinked())"
11858
+ data-cy="global-context-link--all"
11859
+ >
11860
+ <span class="btn-icon-dot__item default" [class.active]="isLinked()">
11861
+ <i [c8yIcon]="isLinked() ? 'link' : 'unlink'"></i>
11798
11862
  </span>
11863
+ @for (control of visibleControls(); track control.stateKey) {
11864
+ @if (isLinked()) {
11865
+ <span
11866
+ [class]="control.cssClass + ' btn-icon-dot__item active'"
11867
+ [attr.data-cy]="'global-context-link--' + control.stateKey"
11868
+ >
11869
+ <i [c8yIcon]="control.icon"></i>
11870
+ </span>
11871
+ }
11872
+ }
11873
+ </button>
11874
+ @if (!isLinked()) {
11875
+ <c8y-context-controls
11876
+ class="c8y-header-controls-group__summary"
11877
+ [controls]="controls()"
11878
+ [displayMode]="displayMode()"
11879
+ [config]="config()"
11880
+ [isLoading]="isLoading()"
11881
+ [emitRefresh]="emitRefresh()"
11882
+ (configChange)="configChange.emit($event)"
11883
+ (refresh)="refresh.emit()"
11884
+ ></c8y-context-controls>
11799
11885
  }
11800
- </button>
11886
+ </div>
11801
11887
  <ng-template #masterTooltipTemplate>{{ masterTooltipText() }}</ng-template>
11802
11888
  </ng-template>
11803
- `, isInline: true, dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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" }] }); }
11889
+ `, isInline: true, dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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: "component", type: ContextControlsComponent, selector: "c8y-context-controls", inputs: ["controls", "displayMode", "config", "isLoading", "emitRefresh"], outputs: ["configChange", "refresh"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11804
11890
  }
11805
11891
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LinkButtonsComponent, decorators: [{
11806
11892
  type: Component,
11807
11893
  args: [{
11808
11894
  selector: 'c8y-link-buttons',
11809
11895
  standalone: true,
11810
- imports: [IconDirective, TooltipModule, C8yTranslatePipe],
11896
+ changeDetection: ChangeDetectionStrategy.OnPush,
11897
+ imports: [IconDirective, TooltipModule, C8yTranslatePipe, ContextControlsComponent],
11898
+ providers: [HeaderTemplateService],
11811
11899
  template: `
11812
11900
  <ng-template #headerContent>
11813
- <button
11814
- class="btn-icon-dot-set"
11815
- [class.active]="isLinked()"
11816
- [attr.aria-label]="'Global context sync controls' | translate"
11817
- [tooltip]="masterTooltipTemplate"
11818
- delay="500"
11819
- container="body"
11820
- (click)="toggle.emit(!isLinked())"
11821
- data-cy="global-context-link--all"
11901
+ <div
11902
+ class="c8y-header-controls-group"
11903
+ [class.c8y-header-controls-group--has-summary]="!isLinked()"
11822
11904
  >
11823
- <span class="btn-icon-dot__item default" [class.active]="isLinked()">
11824
- <i [c8yIcon]="isLinked() ? 'link' : 'unlink'"></i>
11825
- </span>
11826
- @for (control of visibleControls(); track control.stateKey) {
11827
- <span
11828
- [class]="control.cssClass + ' btn-icon-dot__item'"
11829
- [class.active]="isLinked()"
11830
- [attr.data-cy]="'global-context-link--' + control.stateKey"
11831
- >
11832
- <i [c8yIcon]="control.icon"></i>
11905
+ <button
11906
+ class="btn-icon-dot-set"
11907
+ [class.active]="isLinked()"
11908
+ [attr.aria-label]="'Global context sync controls' | translate"
11909
+ [tooltip]="masterTooltipTemplate"
11910
+ delay="500"
11911
+ container="body"
11912
+ (click)="toggle.emit(!isLinked())"
11913
+ data-cy="global-context-link--all"
11914
+ >
11915
+ <span class="btn-icon-dot__item default" [class.active]="isLinked()">
11916
+ <i [c8yIcon]="isLinked() ? 'link' : 'unlink'"></i>
11833
11917
  </span>
11918
+ @for (control of visibleControls(); track control.stateKey) {
11919
+ @if (isLinked()) {
11920
+ <span
11921
+ [class]="control.cssClass + ' btn-icon-dot__item active'"
11922
+ [attr.data-cy]="'global-context-link--' + control.stateKey"
11923
+ >
11924
+ <i [c8yIcon]="control.icon"></i>
11925
+ </span>
11926
+ }
11927
+ }
11928
+ </button>
11929
+ @if (!isLinked()) {
11930
+ <c8y-context-controls
11931
+ class="c8y-header-controls-group__summary"
11932
+ [controls]="controls()"
11933
+ [displayMode]="displayMode()"
11934
+ [config]="config()"
11935
+ [isLoading]="isLoading()"
11936
+ [emitRefresh]="emitRefresh()"
11937
+ (configChange)="configChange.emit($event)"
11938
+ (refresh)="refresh.emit()"
11939
+ ></c8y-context-controls>
11834
11940
  }
11835
- </button>
11941
+ </div>
11836
11942
  <ng-template #masterTooltipTemplate>{{ masterTooltipText() }}</ng-template>
11837
11943
  </ng-template>
11838
11944
  `
11839
11945
  }]
11840
- }], propDecorators: { headerTemplateRef: [{
11841
- type: ViewChild,
11842
- args: ['headerContent', { static: true, read: TemplateRef }]
11843
- }], dashboardChild: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChild", required: false }] }], isLinked: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLinked", required: true }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], toggle: [{ type: i0.Output, args: ["toggle"] }] } });
11946
+ }], ctorParameters: () => [], propDecorators: { headerTemplateRef: [{ type: i0.ViewChild, args: ['headerContent', { ...{ read: TemplateRef }, isSignal: true }] }], dashboardChild: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChild", required: false }] }], isLinked: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLinked", required: true }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], toggle: [{ type: i0.Output, args: ["toggle"] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }] } });
11844
11947
 
11845
11948
  class GlobalContextConnectorComponent {
11846
11949
  constructor() {
11950
+ this.injectedDashboardChild = inject(DashboardChildComponent, { optional: true });
11847
11951
  this.eventService = inject(GlobalContextEventService);
11848
11952
  this.globalContextService = inject(GlobalContextService);
11849
11953
  this.globalContextUtils = inject(GlobalContextUtilsService);
@@ -11852,7 +11956,8 @@ class GlobalContextConnectorComponent {
11852
11956
  this.controls = input(PRESET_NAME.DEFAULT, ...(ngDevMode ? [{ debugName: "controls" }] : []));
11853
11957
  this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
11854
11958
  this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
11855
- this.dashboardChild = input.required(...(ngDevMode ? [{ debugName: "dashboardChild" }] : []));
11959
+ this.dashboardChildInput = input(undefined, ...(ngDevMode ? [{ debugName: "dashboardChildInput", alias: 'dashboardChild' }] : [{ alias: 'dashboardChild' }]));
11960
+ this.dashboardChild = computed(() => this.dashboardChildInput() ?? this.injectedDashboardChild, ...(ngDevMode ? [{ debugName: "dashboardChild" }] : []));
11856
11961
  this.linked = input(undefined, ...(ngDevMode ? [{ debugName: "linked" }] : []));
11857
11962
  /** When false, refresh events are not emitted as configChange - only user-initiated state changes */
11858
11963
  this.emitRefresh = input(true, ...(ngDevMode ? [{ debugName: "emitRefresh" }] : []));
@@ -11896,13 +12001,14 @@ class GlobalContextConnectorComponent {
11896
12001
  this.configChange.emit(event);
11897
12002
  }
11898
12003
  onLocalRefresh() {
11899
- const { dateTimeContext } = this.config();
12004
+ const currentConfig = this.config();
12005
+ const { dateTimeContext } = currentConfig;
11900
12006
  if (!dateTimeContext) {
11901
12007
  this.refresh.emit();
11902
12008
  return;
11903
12009
  }
11904
12010
  const context = {
11905
- ...this.config(),
12011
+ ...currentConfig,
11906
12012
  dateTimeContext: DateTimeContextUtil.normalizeForLive(dateTimeContext)
11907
12013
  };
11908
12014
  if (!this.emitIfChanged(context)) {
@@ -11925,8 +12031,9 @@ class GlobalContextConnectorComponent {
11925
12031
  syncExternalLinkState() {
11926
12032
  effect(() => {
11927
12033
  const external = this.linked();
11928
- if (external !== undefined)
11929
- this.isLinked.set(external);
12034
+ if (external === undefined)
12035
+ return;
12036
+ this.isLinked.set(external);
11930
12037
  });
11931
12038
  }
11932
12039
  subscribeToGlobalContext() {
@@ -11939,7 +12046,6 @@ class GlobalContextConnectorComponent {
11939
12046
  if (cached)
11940
12047
  this.emitIfChanged(cached);
11941
12048
  const stateChanges$ = this.eventService.on(GLOBAL_CONTEXT_EVENTS.STATE_CHANGE);
11942
- // Only include refresh events if emitRefresh is true
11943
12049
  let source$ = stateChanges$;
11944
12050
  if (this.emitRefresh()) {
11945
12051
  const refresh$ = this.eventService.on(GLOBAL_CONTEXT_EVENTS.REFRESH).pipe(map$1(data => ({
@@ -11990,35 +12096,28 @@ class GlobalContextConnectorComponent {
11990
12096
  });
11991
12097
  }
11992
12098
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextConnectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: GlobalContextConnectorComponent, isStandalone: true, selector: "c8y-global-context-connector", inputs: { controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChild: { classPropertyName: "dashboardChild", publicName: "dashboardChild", isSignal: true, isRequired: true, transformFunction: null }, linked: { classPropertyName: "linked", publicName: "linked", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", refresh: "refresh", linkedChange: "linkedChange" }, ngImport: i0, template: `
12099
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: GlobalContextConnectorComponent, isStandalone: true, selector: "c8y-global-context-connector", inputs: { controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildInput: { classPropertyName: "dashboardChildInput", publicName: "dashboardChild", isSignal: true, isRequired: false, transformFunction: null }, linked: { classPropertyName: "linked", publicName: "linked", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", refresh: "refresh", linkedChange: "linkedChange" }, ngImport: i0, template: `
11994
12100
  @if (hasActiveControls()) {
11995
12101
  <c8y-link-buttons
11996
12102
  [dashboardChild]="dashboardChild()"
11997
12103
  [isLinked]="isLinked()"
11998
12104
  [controls]="controls()"
11999
12105
  [config]="config()"
12106
+ [isLoading]="isLoading()"
12107
+ [emitRefresh]="emitRefresh()"
12000
12108
  (toggle)="onLinkToggle($event)"
12109
+ (configChange)="onLocalChange($event)"
12110
+ (refresh)="onLocalRefresh()"
12001
12111
  ></c8y-link-buttons>
12002
-
12003
- @if (!isLinked()) {
12004
- <c8y-context-controls
12005
- [controls]="controls()"
12006
- displayMode="dashboard"
12007
- [config]="config()"
12008
- [isLoading]="isLoading()"
12009
- (configChange)="onLocalChange($event)"
12010
- (refresh)="onLocalRefresh()"
12011
- ></c8y-context-controls>
12012
- }
12013
12112
  }
12014
- `, isInline: true, dependencies: [{ kind: "component", type: ContextControlsComponent, selector: "c8y-context-controls", inputs: ["controls", "displayMode", "config", "isLoading", "emitRefresh"], outputs: ["configChange", "refresh"] }, { kind: "component", type: LinkButtonsComponent, selector: "c8y-link-buttons", inputs: ["dashboardChild", "isLinked", "controls", "config"], outputs: ["toggle"] }] }); }
12113
+ `, isInline: true, dependencies: [{ kind: "component", type: LinkButtonsComponent, selector: "c8y-link-buttons", inputs: ["dashboardChild", "isLinked", "controls", "config", "displayMode", "isLoading", "emitRefresh"], outputs: ["toggle", "configChange", "refresh"] }] }); }
12015
12114
  }
12016
12115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: GlobalContextConnectorComponent, decorators: [{
12017
12116
  type: Component,
12018
12117
  args: [{
12019
12118
  selector: 'c8y-global-context-connector',
12020
12119
  standalone: true,
12021
- imports: [ContextControlsComponent, LinkButtonsComponent],
12120
+ imports: [LinkButtonsComponent],
12022
12121
  template: `
12023
12122
  @if (hasActiveControls()) {
12024
12123
  <c8y-link-buttons
@@ -12026,69 +12125,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
12026
12125
  [isLinked]="isLinked()"
12027
12126
  [controls]="controls()"
12028
12127
  [config]="config()"
12128
+ [isLoading]="isLoading()"
12129
+ [emitRefresh]="emitRefresh()"
12029
12130
  (toggle)="onLinkToggle($event)"
12131
+ (configChange)="onLocalChange($event)"
12132
+ (refresh)="onLocalRefresh()"
12030
12133
  ></c8y-link-buttons>
12031
-
12032
- @if (!isLinked()) {
12033
- <c8y-context-controls
12034
- [controls]="controls()"
12035
- displayMode="dashboard"
12036
- [config]="config()"
12037
- [isLoading]="isLoading()"
12038
- (configChange)="onLocalChange($event)"
12039
- (refresh)="onLocalRefresh()"
12040
- ></c8y-context-controls>
12041
- }
12042
12134
  }
12043
12135
  `
12044
12136
  }]
12045
- }], ctorParameters: () => [], propDecorators: { controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], dashboardChild: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChild", required: true }] }], linked: [{ type: i0.Input, args: [{ isSignal: true, alias: "linked", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], linkedChange: [{ type: i0.Output, args: ["linkedChange"] }] } });
12137
+ }], ctorParameters: () => [], propDecorators: { controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], dashboardChildInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChild", required: false }] }], linked: [{ type: i0.Input, args: [{ isSignal: true, alias: "linked", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], linkedChange: [{ type: i0.Output, args: ["linkedChange"] }] } });
12046
12138
 
12047
12139
  class LocalControlsComponent {
12048
12140
  constructor() {
12141
+ this.injectedDashboardChild = inject(DashboardChildComponent, { optional: true });
12142
+ this.headerTemplate = inject(HeaderTemplateService);
12143
+ this.headerTemplateRef = viewChild('headerContent', ...(ngDevMode ? [{ debugName: "headerTemplateRef", read: TemplateRef }] : [{ read: TemplateRef }]));
12049
12144
  this.controls = input(PRESET_NAME.DEFAULT, ...(ngDevMode ? [{ debugName: "controls" }] : []));
12050
- this.displayMode = input(GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
12145
+ this.displayMode = input(GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
12051
12146
  this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
12052
12147
  this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
12053
12148
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
12054
12149
  this.emitRefresh = input(true, ...(ngDevMode ? [{ debugName: "emitRefresh" }] : []));
12150
+ /** Explicit override; falls back to DI-injected DashboardChildComponent. */
12151
+ this.dashboardChildInput = input(undefined, ...(ngDevMode ? [{ debugName: "dashboardChildInput", alias: 'dashboardChild' }] : [{ alias: 'dashboardChild' }]));
12152
+ this.resolvedDashboardChild = computed(() => this.dashboardChildInput() ?? this.injectedDashboardChild ?? null, ...(ngDevMode ? [{ debugName: "resolvedDashboardChild" }] : []));
12055
12153
  this.configChange = output();
12056
12154
  this.refresh = output();
12155
+ this.headerTemplate.register({
12156
+ getDashboardChild: () => this.resolvedDashboardChild(),
12157
+ getTemplateRef: () => this.headerTemplateRef(),
12158
+ priority: 50
12159
+ });
12057
12160
  }
12058
12161
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LocalControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12059
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.25", type: LocalControlsComponent, isStandalone: true, selector: "c8y-local-controls", inputs: { controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", refresh: "refresh" }, host: { attributes: { "data-local-controls": "true" }, properties: { "class.disabled": "disabled()" } }, ngImport: i0, template: `
12060
- <div [class.disabled-overlay]="disabled()">
12061
- <c8y-context-controls
12062
- [controls]="controls()"
12063
- [displayMode]="displayMode()"
12064
- [config]="config()"
12065
- [isLoading]="isLoading()"
12066
- [emitRefresh]="emitRefresh()"
12067
- (configChange)="configChange.emit($event)"
12068
- (refresh)="refresh.emit()"
12069
- ></c8y-context-controls>
12070
- </div>
12071
- `, isInline: true, styles: [".disabled-overlay{position:relative;cursor:not-allowed}.disabled-overlay:after{content:\"\";position:absolute;inset:0;z-index:10}\n"], dependencies: [{ kind: "component", type: ContextControlsComponent, selector: "c8y-context-controls", inputs: ["controls", "displayMode", "config", "isLoading", "emitRefresh"], outputs: ["configChange", "refresh"] }] }); }
12162
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LocalControlsComponent, isStandalone: true, selector: "c8y-local-controls", inputs: { controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, emitRefresh: { classPropertyName: "emitRefresh", publicName: "emitRefresh", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildInput: { classPropertyName: "dashboardChildInput", publicName: "dashboardChild", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", refresh: "refresh" }, host: { attributes: { "data-local-controls": "true" }, properties: { "class.disabled": "disabled()" } }, providers: [HeaderTemplateService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: `
12163
+ <ng-template #headerContent>
12164
+ <div class="c8y-header-controls-group">
12165
+ <c8y-context-controls
12166
+ [controls]="controls()"
12167
+ [displayMode]="displayMode()"
12168
+ [config]="config()"
12169
+ [isLoading]="isLoading()"
12170
+ [emitRefresh]="emitRefresh()"
12171
+ (configChange)="configChange.emit($event)"
12172
+ (refresh)="refresh.emit()"
12173
+ ></c8y-context-controls>
12174
+ </div>
12175
+ </ng-template>
12176
+
12177
+ @if (!resolvedDashboardChild() || disabled()) {
12178
+ <div [class.disabled-overlay]="disabled()">
12179
+ <c8y-context-controls
12180
+ [controls]="controls()"
12181
+ [displayMode]="displayMode()"
12182
+ [config]="config()"
12183
+ [isLoading]="isLoading()"
12184
+ [emitRefresh]="emitRefresh()"
12185
+ (configChange)="configChange.emit($event)"
12186
+ (refresh)="refresh.emit()"
12187
+ ></c8y-context-controls>
12188
+ </div>
12189
+ }
12190
+ `, isInline: true, styles: [".disabled-overlay{position:relative;cursor:not-allowed}.disabled-overlay:after{content:\"\";position:absolute;inset:0;z-index:10}\n"], dependencies: [{ kind: "component", type: ContextControlsComponent, selector: "c8y-context-controls", inputs: ["controls", "displayMode", "config", "isLoading", "emitRefresh"], outputs: ["configChange", "refresh"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12072
12191
  }
12073
12192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LocalControlsComponent, decorators: [{
12074
12193
  type: Component,
12075
- args: [{ selector: 'c8y-local-controls', standalone: true, imports: [ContextControlsComponent], host: {
12194
+ args: [{ selector: 'c8y-local-controls', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ContextControlsComponent], providers: [HeaderTemplateService], host: {
12076
12195
  'data-local-controls': 'true',
12077
12196
  '[class.disabled]': 'disabled()'
12078
12197
  }, template: `
12079
- <div [class.disabled-overlay]="disabled()">
12080
- <c8y-context-controls
12081
- [controls]="controls()"
12082
- [displayMode]="displayMode()"
12083
- [config]="config()"
12084
- [isLoading]="isLoading()"
12085
- [emitRefresh]="emitRefresh()"
12086
- (configChange)="configChange.emit($event)"
12087
- (refresh)="refresh.emit()"
12088
- ></c8y-context-controls>
12089
- </div>
12198
+ <ng-template #headerContent>
12199
+ <div class="c8y-header-controls-group">
12200
+ <c8y-context-controls
12201
+ [controls]="controls()"
12202
+ [displayMode]="displayMode()"
12203
+ [config]="config()"
12204
+ [isLoading]="isLoading()"
12205
+ [emitRefresh]="emitRefresh()"
12206
+ (configChange)="configChange.emit($event)"
12207
+ (refresh)="refresh.emit()"
12208
+ ></c8y-context-controls>
12209
+ </div>
12210
+ </ng-template>
12211
+
12212
+ @if (!resolvedDashboardChild() || disabled()) {
12213
+ <div [class.disabled-overlay]="disabled()">
12214
+ <c8y-context-controls
12215
+ [controls]="controls()"
12216
+ [displayMode]="displayMode()"
12217
+ [config]="config()"
12218
+ [isLoading]="isLoading()"
12219
+ [emitRefresh]="emitRefresh()"
12220
+ (configChange)="configChange.emit($event)"
12221
+ (refresh)="refresh.emit()"
12222
+ ></c8y-context-controls>
12223
+ </div>
12224
+ }
12090
12225
  `, styles: [".disabled-overlay{position:relative;cursor:not-allowed}.disabled-overlay:after{content:\"\";position:absolute;inset:0;z-index:10}\n"] }]
12091
- }], propDecorators: { controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }] } });
12226
+ }], ctorParameters: () => [], propDecorators: { headerTemplateRef: [{ type: i0.ViewChild, args: ['headerContent', { ...{ read: TemplateRef }, isSignal: true }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], emitRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitRefresh", required: false }] }], dashboardChildInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardChild", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }] } });
12092
12227
 
12093
12228
  /** @deprecated Use LocalControlsComponent or GlobalContextConnectorComponent instead */
12094
12229
 
@@ -12111,5 +12246,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
12111
12246
  * Generated bundle index. Do not edit.
12112
12247
  */
12113
12248
 
12114
- export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, DateTimeContextUtil, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, 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, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
12249
+ export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, DateTimeContextUtil, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LIFETIME_INTERVAL, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, 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, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
12115
12250
  //# sourceMappingURL=c8y-ngx-components-global-context.mjs.map