@c8y/ngx-components 1021.21.0 → 1021.22.26

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 (185) hide show
  1. package/alarms/alarm-details.component.d.ts +1 -3
  2. package/alarms/alarm-details.component.d.ts.map +1 -1
  3. package/alarms/alarm-info.component.d.ts +9 -14
  4. package/alarms/alarm-info.component.d.ts.map +1 -1
  5. package/alarms/alarms-date-filter.component.d.ts +23 -10
  6. package/alarms/alarms-date-filter.component.d.ts.map +1 -1
  7. package/alarms/alarms-type-filter.component.d.ts +21 -14
  8. package/alarms/alarms-type-filter.component.d.ts.map +1 -1
  9. package/alarms/alarms-view.service.d.ts +7 -0
  10. package/alarms/alarms-view.service.d.ts.map +1 -1
  11. package/alarms/alarms.component.d.ts.map +1 -1
  12. package/alarms/alarms.helper.d.ts +5 -0
  13. package/alarms/alarms.helper.d.ts.map +1 -0
  14. package/alarms/alarms.model.d.ts +1 -6
  15. package/alarms/alarms.model.d.ts.map +1 -1
  16. package/alarms/alarms.module.d.ts +1 -1
  17. package/alarms/alarms.module.d.ts.map +1 -1
  18. package/alarms/cockpit/index.d.ts.map +1 -1
  19. package/alarms/devicemanagement/index.d.ts.map +1 -1
  20. package/alarms/index.d.ts +6 -4
  21. package/alarms/index.d.ts.map +1 -1
  22. package/branding/shared/data/branding-tracking.service.d.ts +20 -0
  23. package/branding/shared/data/branding-tracking.service.d.ts.map +1 -0
  24. package/branding/shared/data/branding-version.service.d.ts.map +1 -1
  25. package/branding/shared/data/index.d.ts +1 -0
  26. package/branding/shared/data/index.d.ts.map +1 -1
  27. package/branding/shared/data/store-branding.service.d.ts +8 -1
  28. package/branding/shared/data/store-branding.service.d.ts.map +1 -1
  29. package/branding/shared/lazy/branding/branding.component.d.ts +3 -2
  30. package/branding/shared/lazy/branding/branding.component.d.ts.map +1 -1
  31. package/branding/shared/lazy/branding-theme-form/branding-theme-form.component.d.ts.map +1 -1
  32. package/branding/shared/lazy/edit-branding-router-outlet/edit-branding-router-outlet.component.d.ts.map +1 -1
  33. package/cockpit-config/cockpit-config.module.d.ts +1 -1
  34. package/cockpit-config/cockpit-config.module.d.ts.map +1 -1
  35. package/context-dashboard/context-dashboard.service.d.ts +1 -1
  36. package/context-dashboard/context-dashboard.service.d.ts.map +1 -1
  37. package/core/bootstrap/bootstrap.component.d.ts.map +1 -1
  38. package/core/common/service-registry.model.d.ts +2 -1
  39. package/core/common/service-registry.model.d.ts.map +1 -1
  40. package/core/common/ui-state.service.d.ts +0 -1
  41. package/core/common/ui-state.service.d.ts.map +1 -1
  42. package/core/i18n/missing-translation-custom.handler.d.ts +1 -0
  43. package/core/i18n/missing-translation-custom.handler.d.ts.map +1 -1
  44. package/core/plugins/index.d.ts +1 -0
  45. package/core/plugins/index.d.ts.map +1 -1
  46. package/core/plugins/plugin-loaded.pipe.d.ts +12 -0
  47. package/core/plugins/plugin-loaded.pipe.d.ts.map +1 -0
  48. package/core/plugins/plugins-resolve.service.d.ts +4 -2
  49. package/core/plugins/plugins-resolve.service.d.ts.map +1 -1
  50. package/core/plugins/plugins.model.d.ts +3 -1
  51. package/core/plugins/plugins.model.d.ts.map +1 -1
  52. package/core/plugins/plugins.service.d.ts +3 -0
  53. package/core/plugins/plugins.service.d.ts.map +1 -1
  54. package/core/router/context-route.component.d.ts +8 -3
  55. package/core/router/context-route.component.d.ts.map +1 -1
  56. package/core/router/context-route.service.d.ts +29 -3
  57. package/core/router/context-route.service.d.ts.map +1 -1
  58. package/core/router/router-tabs.resolver.d.ts +6 -3
  59. package/core/router/router-tabs.resolver.d.ts.map +1 -1
  60. package/core/router/router.model.d.ts +40 -3
  61. package/core/router/router.model.d.ts.map +1 -1
  62. package/core/router/router.module.d.ts +2 -1
  63. package/core/router/router.module.d.ts.map +1 -1
  64. package/core/router/router.service.d.ts +5 -4
  65. package/core/router/router.service.d.ts.map +1 -1
  66. package/core/router/scoped-context-route.service.d.ts +57 -0
  67. package/core/router/scoped-context-route.service.d.ts.map +1 -0
  68. package/core/router/view-context.service.d.ts +8 -18
  69. package/core/router/view-context.service.d.ts.map +1 -1
  70. package/ecosystem/application-plugins/application-plugins.component.d.ts.map +1 -1
  71. package/ecosystem/application-plugins/application-plugins.guard.d.ts.map +1 -1
  72. package/ecosystem/application-plugins/orphaned-status-cell-renderer.component.d.ts.map +1 -1
  73. package/esm2022/alarms/alarm-details.component.mjs +7 -9
  74. package/esm2022/alarms/alarm-info.component.mjs +23 -33
  75. package/esm2022/alarms/alarm-severity-to-label.pipe.mjs +2 -2
  76. package/esm2022/alarms/alarms-date-filter.component.mjs +94 -42
  77. package/esm2022/alarms/alarms-type-filter.component.mjs +102 -72
  78. package/esm2022/alarms/alarms-view.service.mjs +17 -3
  79. package/esm2022/alarms/alarms.component.mjs +12 -5
  80. package/esm2022/alarms/alarms.helper.mjs +32 -0
  81. package/esm2022/alarms/alarms.model.mjs +1 -1
  82. package/esm2022/alarms/alarms.module.mjs +7 -7
  83. package/esm2022/alarms/cockpit/index.mjs +13 -17
  84. package/esm2022/alarms/devicemanagement/index.mjs +15 -18
  85. package/esm2022/alarms/index.mjs +7 -5
  86. package/esm2022/branding/shared/data/branding-tracking.service.mjs +58 -0
  87. package/esm2022/branding/shared/data/branding-version.service.mjs +9 -5
  88. package/esm2022/branding/shared/data/index.mjs +2 -1
  89. package/esm2022/branding/shared/data/store-branding.service.mjs +15 -4
  90. package/esm2022/branding/shared/lazy/branding/branding.component.mjs +16 -12
  91. package/esm2022/branding/shared/lazy/branding-theme-form/branding-theme-form.component.mjs +5 -2
  92. package/esm2022/branding/shared/lazy/edit-branding-router-outlet/edit-branding-router-outlet.component.mjs +2 -2
  93. package/esm2022/cockpit-config/cockpit-config.module.mjs +6 -3
  94. package/esm2022/cockpit-config/feature-config.component.mjs +5 -4
  95. package/esm2022/context-dashboard/context-dashboard.service.mjs +47 -13
  96. package/esm2022/core/bootstrap/bootstrap.component.mjs +4 -3
  97. package/esm2022/core/common/service-registry.model.mjs +1 -1
  98. package/esm2022/core/common/ui-state.service.mjs +1 -19
  99. package/esm2022/core/i18n/missing-translation-custom.handler.mjs +5 -1
  100. package/esm2022/core/i18n/translation-loader.service.mjs +2 -2
  101. package/esm2022/core/plugins/index.mjs +2 -1
  102. package/esm2022/core/plugins/plugin-loaded.pipe.mjs +26 -0
  103. package/esm2022/core/plugins/plugins-resolve.service.mjs +5 -1
  104. package/esm2022/core/plugins/plugins.model.mjs +2 -1
  105. package/esm2022/core/plugins/plugins.service.mjs +13 -5
  106. package/esm2022/core/router/context-route.component.mjs +23 -13
  107. package/esm2022/core/router/context-route.service.mjs +37 -5
  108. package/esm2022/core/router/router-tabs.resolver.mjs +66 -21
  109. package/esm2022/core/router/router.model.mjs +6 -1
  110. package/esm2022/core/router/router.module.mjs +20 -13
  111. package/esm2022/core/router/router.service.mjs +24 -10
  112. package/esm2022/core/router/scoped-context-route.service.mjs +157 -0
  113. package/esm2022/core/router/view-context.service.mjs +59 -16
  114. package/esm2022/core/tabs/tabs-outlet.component.mjs +3 -3
  115. package/esm2022/core/version/websdk-plugin-version.factory.mjs +2 -2
  116. package/esm2022/datapoint-selector/datapoint-selection-list/datapoint-selection-list.component.mjs +3 -3
  117. package/esm2022/ecosystem/activity-log/activity-log.component.mjs +3 -3
  118. package/esm2022/ecosystem/application-plugins/application-plugins.component.mjs +67 -23
  119. package/esm2022/ecosystem/application-plugins/application-plugins.guard.mjs +8 -2
  120. package/esm2022/ecosystem/application-plugins/orphaned-status-cell-renderer.component.mjs +7 -1
  121. package/esm2022/interval-picker/interval-picker.component.mjs +1 -1
  122. package/esm2022/interval-picker/interval-picker.model.mjs +1 -1
  123. package/esm2022/protocol-lwm2m/ng1/plugin-checker.service.mjs +5 -1
  124. package/esm2022/widgets/definitions/alarms/alarm-list/index.mjs +2 -1
  125. package/esm2022/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.mjs +73 -4
  126. package/esm2022/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.mjs +29 -5
  127. package/esm2022/widgets/implementations/alarms/alarm-list-widget.model.mjs +7 -1
  128. package/esm2022/widgets/implementations/alarms/alarm-widget.service.mjs +12 -2
  129. package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs +12 -16
  130. package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs.map +1 -1
  131. package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs +14 -17
  132. package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs.map +1 -1
  133. package/fesm2022/c8y-ngx-components-alarms.mjs +389 -268
  134. package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
  135. package/fesm2022/c8y-ngx-components-branding-shared-data.mjs +76 -9
  136. package/fesm2022/c8y-ngx-components-branding-shared-data.mjs.map +1 -1
  137. package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs +19 -12
  138. package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs.map +1 -1
  139. package/fesm2022/c8y-ngx-components-cockpit-config.mjs +7 -5
  140. package/fesm2022/c8y-ngx-components-cockpit-config.mjs.map +1 -1
  141. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +46 -12
  142. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  143. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +2 -2
  144. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  145. package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs +79 -23
  146. package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  147. package/fesm2022/c8y-ngx-components-ecosystem.mjs +81 -25
  148. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  149. package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
  150. package/fesm2022/c8y-ngx-components-protocol-lwm2m.mjs +4 -0
  151. package/fesm2022/c8y-ngx-components-protocol-lwm2m.mjs.map +1 -1
  152. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +1 -0
  153. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
  154. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +124 -15
  155. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  156. package/fesm2022/c8y-ngx-components.mjs +489 -176
  157. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  158. package/interval-picker/interval-picker.component.d.ts +2 -2
  159. package/interval-picker/interval-picker.component.d.ts.map +1 -1
  160. package/interval-picker/interval-picker.model.d.ts +5 -0
  161. package/interval-picker/interval-picker.model.d.ts.map +1 -1
  162. package/locales/de.po +431 -538
  163. package/locales/en.po +2 -889
  164. package/locales/en_US.po +2 -880
  165. package/locales/es.po +462 -540
  166. package/locales/fr.po +470 -549
  167. package/locales/ja_JP.po +405 -598
  168. package/locales/ko.po +649 -502
  169. package/locales/locales.pot +27 -12
  170. package/locales/nl.po +463 -541
  171. package/locales/pl.po +504 -554
  172. package/locales/pt_BR.po +466 -543
  173. package/locales/zh_CN.po +650 -498
  174. package/locales/zh_TW.po +650 -498
  175. package/package.json +1 -1
  176. package/protocol-lwm2m/ng1/plugin-checker.service.d.ts +4 -0
  177. package/protocol-lwm2m/ng1/plugin-checker.service.d.ts.map +1 -1
  178. package/widgets/definitions/alarms/alarm-list/index.d.ts.map +1 -1
  179. package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts +12 -1
  180. package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts.map +1 -1
  181. package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts +12 -1
  182. package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts.map +1 -1
  183. package/widgets/implementations/alarms/alarm-list-widget.model.d.ts +11 -1
  184. package/widgets/implementations/alarms/alarm-list-widget.model.d.ts.map +1 -1
  185. package/widgets/implementations/alarms/alarm-widget.service.d.ts.map +1 -1
@@ -1,32 +1,89 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, InjectionToken, Pipe, Component, Optional, Input, EventEmitter, Output, ViewChild, NgModule } from '@angular/core';
2
+ import { Injectable, Pipe, InjectionToken, Component, Optional, Input, EventEmitter, Output, ViewChild, forwardRef, NgModule } from '@angular/core';
3
+ import { combineLatest, firstValueFrom, map as map$1, shareReplay, Subject, BehaviorSubject, of, from, forkJoin, EMPTY, Observable, pipe, fromEvent, take, takeUntil as takeUntil$1 } from 'rxjs';
4
+ import { filter, map, switchMap, startWith, takeUntil, catchError, finalize, tap, debounceTime, distinctUntilChanged, shareReplay as shareReplay$1, throttleTime } from 'rxjs/operators';
5
+ import * as i3 from '@c8y/ngx-components';
6
+ import { Permissions, gettext, ViewContext, CountdownIntervalComponent, DynamicComponentAlertAggregator, DynamicComponentAlert, AlarmWithChildrenRealtimeService, ContextRouteComponent, ContextRouteGuard, RouterTabsResolver, hookNavigator, hookRoute, CommonModule, CoreModule, HeaderModule, DynamicComponentModule, RelativeTimePipe } from '@c8y/ngx-components';
7
+ import { sortBy, cloneDeep } from 'lodash-es';
3
8
  import * as i2 from '@c8y/client';
4
9
  import { AlarmStatus, Severity, ALARM_STATUS_LABELS, SEVERITY_LABELS } from '@c8y/client';
5
- import * as i3 from '@c8y/ngx-components';
6
- import { Permissions, gettext, ViewContext, CountdownIntervalComponent, DynamicComponentAlertAggregator, DynamicComponentAlert, AlarmWithChildrenRealtimeService, hookNavigator, hookRoute, CommonModule, CoreModule, HeaderModule, DynamicComponentModule, RelativeTimePipe } from '@c8y/ngx-components';
7
10
  import * as i1 from '@ngx-translate/core';
8
11
  import { TranslateModule } from '@ngx-translate/core';
9
- import { sortBy, cloneDeep } from 'lodash-es';
10
- import { firstValueFrom, map, shareReplay, Subject, BehaviorSubject, combineLatest, tap, switchMap as switchMap$1, takeUntil, from, forkJoin, EMPTY, Observable, pipe, fromEvent } from 'rxjs';
11
- import * as i8 from '@c8y/ngx-components/interval-picker';
12
+ import * as i9 from '@c8y/ngx-components/interval-picker';
12
13
  import { INTERVAL_TITLES, INTERVALS, IntervalPickerComponent } from '@c8y/ngx-components/interval-picker';
13
14
  import * as i7 from '@angular/common';
14
15
  import { DatePipe, TitleCasePipe } from '@angular/common';
15
16
  import * as i1$1 from '@angular/router';
16
17
  import { NavigationEnd, RouterModule } from '@angular/router';
17
- import { filter, map as map$1, switchMap, startWith, takeUntil as takeUntil$1, catchError, finalize, tap as tap$1, debounceTime, distinctUntilChanged, shareReplay as shareReplay$1, throttleTime } from 'rxjs/operators';
18
18
  import * as i1$2 from '@angular/forms';
19
- import { FormControl } from '@angular/forms';
19
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
20
20
  import * as i6 from 'ngx-bootstrap/dropdown';
21
21
  import { BsDropdownDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';
22
22
  import * as i5 from '@angular/cdk/a11y';
23
23
  import { A11yModule } from '@angular/cdk/a11y';
24
24
  import * as i5$1 from 'ngx-bootstrap/tooltip';
25
25
  import { TooltipModule } from 'ngx-bootstrap/tooltip';
26
- import * as i2$1 from '@c8y/ngx-components/alarm-event-selector';
26
+ import * as i1$3 from '@c8y/ngx-components/alarm-event-selector';
27
27
  import { AlarmEventSelectorModule } from '@c8y/ngx-components/alarm-event-selector';
28
28
  import { PopoverModule } from 'ngx-bootstrap/popover';
29
29
 
30
+ /**
31
+ * A service to retrieve custom buttons for the alarm details view.
32
+ */
33
+ class AlarmDetailsButtonService {
34
+ constructor(serviceRegistry, pluginsResolver) {
35
+ this.serviceRegistry = serviceRegistry;
36
+ this.pluginsResolver = pluginsResolver;
37
+ }
38
+ get$(alarm, source) {
39
+ const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map(() => {
40
+ return this.serviceRegistry.get('alarmDetailsButton');
41
+ }));
42
+ return providers$.pipe(switchMap(providers => {
43
+ const observables$ = providers.map(provider => provider.getAlarmDetailsButton$(alarm, source).pipe(startWith(false)));
44
+ return combineLatest(observables$);
45
+ }), map(indicators => {
46
+ return indicators.filter(Boolean);
47
+ }), map(indicators => sortBy(indicators, this.byPriority)));
48
+ }
49
+ byPriority(item) {
50
+ if (item.priority === undefined) {
51
+ return 0;
52
+ }
53
+ return -item.priority;
54
+ }
55
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
56
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, providedIn: 'root' }); }
57
+ }
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, decorators: [{
59
+ type: Injectable,
60
+ args: [{ providedIn: 'root' }]
61
+ }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });
62
+
63
+ /**
64
+ * A pipe to provide custom buttons for the alarm details view.
65
+ *
66
+ * Will call `get$()` method of `AlarmDetailsButtonService` to get the custom buttons for the provided alarm.
67
+ */
68
+ class AlarmDetailsButtonPipe {
69
+ constructor(alarmDetailsButtonService) {
70
+ this.alarmDetailsButtonService = alarmDetailsButtonService;
71
+ }
72
+ transform(alarm, source) {
73
+ return this.alarmDetailsButtonService.get$(alarm, source);
74
+ }
75
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, deps: [{ token: AlarmDetailsButtonService }], target: i0.ɵɵFactoryTarget.Pipe }); }
76
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, isStandalone: true, name: "alarmDetailsButton" }); }
77
+ }
78
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, decorators: [{
79
+ type: Pipe,
80
+ args: [{
81
+ standalone: true,
82
+ name: 'alarmDetailsButton',
83
+ pure: true
84
+ }]
85
+ }], ctorParameters: () => [{ type: AlarmDetailsButtonService }] });
86
+
30
87
  class AlarmDetailsService {
31
88
  constructor(stateService, permissions) {
32
89
  this.stateService = stateService;
@@ -149,7 +206,7 @@ class AlarmDetailsService {
149
206
  * @returns A promise that resolves to the requested application or undefined if the application is not found.
150
207
  */
151
208
  async getApplication(applicationKey) {
152
- return await firstValueFrom(this.stateService.currentAppsOfUser.pipe(map(apps => apps.find(app => app.key === applicationKey)), shareReplay(1)));
209
+ return await firstValueFrom(this.stateService.currentAppsOfUser.pipe(map$1(apps => apps.find(app => app.key === applicationKey)), shareReplay(1)));
153
210
  }
154
211
  checkIfHasAnyRoleAllowingToCreateSmartRule() {
155
212
  const ROLES_ALLOWING_SMART_RULE_CREATION = [
@@ -465,6 +522,20 @@ class AlarmsViewService {
465
522
  getRouterNavigationArray(contextData, alarm) {
466
523
  return this.getRouterLink(contextData, alarm).split('/').filter(Boolean);
467
524
  }
525
+ /**
526
+ * Returns the correct from and to dates based on the selected interval
527
+ * @param intervalId the selected interval. E.g. 'none', 'hours', 'custom' ...
528
+ * @returns The calculated date context based on the selected interval.
529
+ */
530
+ getDateTimeContextByInterval(intervalId) {
531
+ const interval = INTERVALS_EXTENDED.find(({ id }) => id === intervalId);
532
+ if (interval.id === 'none') {
533
+ return [new Date(0), new Date()];
534
+ }
535
+ const dateTo = new Date();
536
+ const dateFrom = new Date(dateTo.valueOf() - interval.timespanInMs);
537
+ return [dateFrom, dateTo];
538
+ }
468
539
  /**
469
540
  * Creates a value for query parameter for filtering alarms by severity based on array of selected severities.
470
541
  *
@@ -508,63 +579,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
508
579
  }]
509
580
  }], ctorParameters: () => [{ type: i2.AlarmService }, { type: i3.OptionsService }] });
510
581
 
511
- /**
512
- * A service to retrieve custom buttons for the alarm details view.
513
- */
514
- class AlarmDetailsButtonService {
515
- constructor(serviceRegistry, pluginsResolver) {
516
- this.serviceRegistry = serviceRegistry;
517
- this.pluginsResolver = pluginsResolver;
518
- }
519
- get$(alarm, source) {
520
- const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map$1(() => {
521
- return this.serviceRegistry.get('alarmDetailsButton');
522
- }));
523
- return providers$.pipe(switchMap(providers => {
524
- const observables$ = providers.map(provider => provider.getAlarmDetailsButton$(alarm, source).pipe(startWith(false)));
525
- return combineLatest(observables$);
526
- }), map$1(indicators => {
527
- return indicators.filter(Boolean);
528
- }), map$1(indicators => sortBy(indicators, this.byPriority)));
529
- }
530
- byPriority(item) {
531
- if (item.priority === undefined) {
532
- return 0;
533
- }
534
- return -item.priority;
535
- }
536
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
537
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, providedIn: 'root' }); }
538
- }
539
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonService, decorators: [{
540
- type: Injectable,
541
- args: [{ providedIn: 'root' }]
542
- }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });
543
-
544
- /**
545
- * A pipe to provide custom buttons for the alarm details view.
546
- *
547
- * Will call `get$()` method of `AlarmDetailsButtonService` to get the custom buttons for the provided alarm.
548
- */
549
- class AlarmDetailsButtonPipe {
550
- constructor(alarmDetailsButtonService) {
551
- this.alarmDetailsButtonService = alarmDetailsButtonService;
552
- }
553
- transform(alarm, source) {
554
- return this.alarmDetailsButtonService.get$(alarm, source);
555
- }
556
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, deps: [{ token: AlarmDetailsButtonService }], target: i0.ɵɵFactoryTarget.Pipe }); }
557
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, isStandalone: true, name: "alarmDetailsButton" }); }
558
- }
559
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsButtonPipe, decorators: [{
560
- type: Pipe,
561
- args: [{
562
- standalone: true,
563
- name: 'alarmDetailsButton',
564
- pure: true
565
- }]
566
- }], ctorParameters: () => [{ type: AlarmDetailsButtonService }] });
567
-
568
582
  /**
569
583
  * Pipe for transforming alarm severity types into corresponding icons.
570
584
  *
@@ -703,10 +717,12 @@ class AlarmDetailsComponent {
703
717
  this.customFragments = null;
704
718
  }
705
719
  async ngOnInit() {
720
+ const isSmartRulesServiceSubscribed = !!(await this.alarmDetailsService.getApplication(this.alarmDetailsService.SMART_RULES_APPLICATION_KEY));
721
+ const hasAnyRoleAllowingToCreateSmartRule = this.alarmDetailsService.checkIfHasAnyRoleAllowingToCreateSmartRule();
706
722
  this.isCreateSmartRulesButtonAvailable =
707
723
  !!this.ng1SmartRulesUpgradeService &&
708
- this.isSmartRulesServiceSubscribed &&
709
- this.hasAnyRoleAllowingToCreateSmartRule;
724
+ isSmartRulesServiceSubscribed &&
725
+ hasAnyRoleAllowingToCreateSmartRule;
710
726
  this.userDeviceManagementApp = await this.alarmDetailsService.getApplication(this.alarmDetailsService.DEVICE_MANAGEMENT_APPLICATION_KEY);
711
727
  this.showSourceNavigationLink =
712
728
  !!this.userDeviceManagementApp && !this.isDeviceManagementView();
@@ -981,19 +997,15 @@ class AlarmDetailsComponent {
981
997
  return customProperties;
982
998
  }
983
999
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsComponent, deps: [{ token: AlarmDetailsService }, { token: i2.AlarmService }, { token: i3.AlertService }, { token: i3.AppStateService }, { token: i2.AuditService }, { token: i3.RelativeTimePipe }, { token: Ng1SmartRulesUpgradeService, optional: true }, { token: i1.TranslateService }, { token: i2.InventoryService }, { token: AlarmsViewService }, { token: i3.ColorService }], target: i0.ɵɵFactoryTarget.Component }); }
984
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmDetailsComponent, selector: "c8y-alarm-details", inputs: { selectedAlarm: "selectedAlarm", hasAnyRoleAllowingToCreateSmartRule: "hasAnyRoleAllowingToCreateSmartRule", isSmartRulesServiceSubscribed: "isSmartRulesServiceSubscribed" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n <p class=\"small\">{{ statusMessage }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n c8yIcon=\"contactless-payment\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n <p class=\"small\">\n <button\n class=\"btn-link text-muted p-0 m-r-8\"\n title=\"{{ selectedAlarm.source.name }}\"\n type=\"button\"\n routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n >\n <small class=\"icon-flex\">\n <i c8yIcon=\"exchange\"></i>\n {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n </small>\n </button>\n <ng-container *ngIf=\"showSourceNavigationLink\">\n <button\n class=\"btn-link p-0\"\n title=\"{{\n linkTitle\n | translate: { appName: userDeviceManagementApp | humanizeAppName | async }\n }}\"\n type=\"button\"\n (click)=\"goToAlarmSource(selectedAlarm.id)\"\n data-cy=\"alarm-details-device-management-link\"\n >\n {{ userDeviceManagementApp | humanizeAppName | async }}\n <i c8yIcon=\"external-link\"></i>\n </button>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': typeColor }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n <p\n class=\"small text-truncate\"\n title=\"{{ selectedAlarm.type }}\"\n >\n <code>{{ selectedAlarm.type }}</code>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"col-xs-12 col-md-12 p-b-16\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"calendar\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n <div class=\"content-flex-50\">\n <div class=\"col-4 p-b-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last updated' | translate }}</p>\n <p class=\"small\">\n {{ lastUpdated | c8yDate: 'medium' }}\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n <p>\n <span class=\"badge badge-info\">{{ selectedAlarm.count }}</span>\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n <p class=\"small\">\n {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"col-xs-12 col-md-12 p-b-16\"\n *ngIf=\"customFragments\"\n >\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"outgoing-data\"\n ></i>\n </div>\n <div\n class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n data-cy=\"alarm-details-custom-data\"\n >\n <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n <pre><code>{{ customFragments | json }}</code></pre>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Reload audit logs' | translate\"\n type=\"submit\"\n (click)=\"reloadAuditLog(true, true)\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading }\"\n ></i>\n {{ 'Reload audit logs' | translate }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n \"\n type=\"submit\"\n (click)=\"\n onUpdateDetails(\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? ACKNOWLEDGED_STATUS_VALUE\n : ACTIVE_STATUS_VALUE\n )\n \"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n >\n <i\n [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n ></i>\n {{\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Create smart rule' | translate\"\n type=\"submit\"\n *ngIf=\"isCreateSmartRulesButtonAvailable\"\n (click)=\"createSmartRule()\"\n >\n <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n {{ 'Create smart rule' | translate }}\n </button>\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Clear`alarm`' | translate\"\n type=\"submit\"\n (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear`alarm`' | translate }}\n </button>\n\n <button\n *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n class=\"btn btn-default btn-sm\"\n [ngClass]=\"button.additionalButtonClasses\"\n [title]=\"button.title | translate\"\n type=\"button\"\n (click)=\"detailsButtonAction(button, selectedAlarm)\"\n [disabled]=\"button.disabled\"\n >\n <i [ngClass]=\"button.additionalIconClasses\" [c8yIcon]=\"button.icon\"></i>\n <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"'archive'\"\n [title]=\"'No audit logs found.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n <c8y-list-group\n data-cy=\"c8y-alarms-details--audit-logs\"\n *ngIf=\"!isLoading\"\n >\n <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n {{ log.creationTime | date: 'mediumDate' }}\n {{ log.creationTime | date: 'mediumTime' }}\n <c8y-li>\n <c8y-li-body>\n <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n {{ log | auditChangesMessage }}\n </p>\n <div class=\"c8y-list__item__footer\">\n <span\n class=\"m-r-16 small\"\n *ngIf=\"log.user\"\n >\n <span class=\"text-label-small\">\n {{ 'by`user`' | translate }}\n </span>\n {{ log.user }}\n </span>\n <span class=\"small\">\n <span class=\"text-label-small\">\n {{ 'device time' | translate }}\n </span>\n {{ log.time | c8yDate: 'medium' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n</ng-container>\n", dependencies: [{ kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.LowerCasePipe, name: "lowercase" }, { kind: "pipe", type: i7.JsonPipe, name: "json" }, { kind: "pipe", type: i7.DatePipe, name: "date" }, { kind: "pipe", type: i3.HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i3.AssetLinkPipe, name: "assetLink" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: AlarmDetailsButtonPipe, name: "alarmDetailsButton" }, { kind: "pipe", type: AlarmSeverityToIconPipe, name: "AlarmSeverityToIcon" }, { kind: "pipe", type: AlarmStatusToIconPipe, name: "AlarmStatusToIcon" }, { kind: "pipe", type: AuditChangesMessagePipe, name: "auditChangesMessage" }] }); }
1000
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmDetailsComponent, selector: "c8y-alarm-details", inputs: { selectedAlarm: "selectedAlarm" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n <p class=\"small\">{{ statusMessage }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n c8yIcon=\"contactless-payment\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n <p class=\"small\">\n <button\n class=\"btn-link text-muted p-0 m-r-8 text-left\"\n title=\"{{ selectedAlarm.source.name }}\"\n type=\"button\"\n routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n >\n <small class=\"icon-flex\">\n <i c8yIcon=\"exchange\"></i>\n {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n </small>\n </button>\n <ng-container *ngIf=\"showSourceNavigationLink\">\n <button\n class=\"btn-link p-0 text-left\"\n title=\"{{\n linkTitle\n | translate: { appName: userDeviceManagementApp | humanizeAppName | async }\n }}\"\n type=\"button\"\n (click)=\"goToAlarmSource(selectedAlarm.id)\"\n data-cy=\"alarm-details-device-management-link\"\n >\n {{ userDeviceManagementApp | humanizeAppName | async }}\n <i c8yIcon=\"external-link\"></i>\n </button>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': typeColor }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n <p\n class=\"small text-truncate\"\n title=\"{{ selectedAlarm.type }}\"\n >\n <code>{{ selectedAlarm.type }}</code>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"col-xs-12 col-md-12 p-b-16\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"calendar\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n <div class=\"content-flex-50\">\n <div class=\"col-4 p-b-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last updated' | translate }}</p>\n <p class=\"small\">\n {{ lastUpdated | c8yDate: 'medium' }}\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n <p>\n <span class=\"badge badge-info\">{{ selectedAlarm.count }}</span>\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n <p class=\"small\">\n {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"col-xs-12 col-md-12 p-b-16\"\n *ngIf=\"customFragments\"\n >\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"outgoing-data\"\n ></i>\n </div>\n <div\n class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n data-cy=\"alarm-details-custom-data\"\n >\n <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n <pre><code>{{ customFragments | json }}</code></pre>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Reload audit logs' | translate\"\n type=\"submit\"\n (click)=\"reloadAuditLog(true, true)\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading }\"\n ></i>\n {{ 'Reload audit logs' | translate }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n \"\n type=\"submit\"\n (click)=\"\n onUpdateDetails(\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? ACKNOWLEDGED_STATUS_VALUE\n : ACTIVE_STATUS_VALUE\n )\n \"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n >\n <i\n [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n ></i>\n {{\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Create smart rule' | translate\"\n type=\"submit\"\n *ngIf=\"isCreateSmartRulesButtonAvailable\"\n (click)=\"createSmartRule()\"\n >\n <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n {{ 'Create smart rule' | translate }}\n </button>\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Clear`alarm`' | translate\"\n type=\"submit\"\n (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear`alarm`' | translate }}\n </button>\n\n <button\n *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n class=\"btn btn-default btn-sm\"\n [ngClass]=\"button.additionalButtonClasses\"\n [title]=\"button.title | translate\"\n type=\"button\"\n (click)=\"detailsButtonAction(button, selectedAlarm)\"\n [disabled]=\"button.disabled\"\n >\n <i [ngClass]=\"button.additionalIconClasses\" [c8yIcon]=\"button.icon\"></i>\n <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"'archive'\"\n [title]=\"'No audit logs found.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n <c8y-list-group\n data-cy=\"c8y-alarms-details--audit-logs\"\n *ngIf=\"!isLoading\"\n >\n <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n {{ log.creationTime | date: 'mediumDate' }}\n {{ log.creationTime | date: 'mediumTime' }}\n <c8y-li>\n <c8y-li-body>\n <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n {{ log | auditChangesMessage }}\n </p>\n <div class=\"c8y-list__item__footer\">\n <span\n class=\"m-r-16 small\"\n *ngIf=\"log.user\"\n >\n <span class=\"text-label-small\">\n {{ 'by`user`' | translate }}\n </span>\n {{ log.user }}\n </span>\n <span class=\"small\">\n <span class=\"text-label-small\">\n {{ 'device time' | translate }}\n </span>\n {{ log.time | c8yDate: 'medium' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n</ng-container>\n", dependencies: [{ kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.LowerCasePipe, name: "lowercase" }, { kind: "pipe", type: i7.JsonPipe, name: "json" }, { kind: "pipe", type: i7.DatePipe, name: "date" }, { kind: "pipe", type: i3.HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i3.AssetLinkPipe, name: "assetLink" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: AlarmDetailsButtonPipe, name: "alarmDetailsButton" }, { kind: "pipe", type: AlarmSeverityToIconPipe, name: "AlarmSeverityToIcon" }, { kind: "pipe", type: AlarmStatusToIconPipe, name: "AlarmStatusToIcon" }, { kind: "pipe", type: AuditChangesMessagePipe, name: "auditChangesMessage" }] }); }
985
1001
  }
986
1002
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmDetailsComponent, decorators: [{
987
1003
  type: Component,
988
- args: [{ selector: 'c8y-alarm-details', template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n <p class=\"small\">{{ statusMessage }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n c8yIcon=\"contactless-payment\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n <p class=\"small\">\n <button\n class=\"btn-link text-muted p-0 m-r-8\"\n title=\"{{ selectedAlarm.source.name }}\"\n type=\"button\"\n routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n >\n <small class=\"icon-flex\">\n <i c8yIcon=\"exchange\"></i>\n {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n </small>\n </button>\n <ng-container *ngIf=\"showSourceNavigationLink\">\n <button\n class=\"btn-link p-0\"\n title=\"{{\n linkTitle\n | translate: { appName: userDeviceManagementApp | humanizeAppName | async }\n }}\"\n type=\"button\"\n (click)=\"goToAlarmSource(selectedAlarm.id)\"\n data-cy=\"alarm-details-device-management-link\"\n >\n {{ userDeviceManagementApp | humanizeAppName | async }}\n <i c8yIcon=\"external-link\"></i>\n </button>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': typeColor }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n <p\n class=\"small text-truncate\"\n title=\"{{ selectedAlarm.type }}\"\n >\n <code>{{ selectedAlarm.type }}</code>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"col-xs-12 col-md-12 p-b-16\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"calendar\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n <div class=\"content-flex-50\">\n <div class=\"col-4 p-b-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last updated' | translate }}</p>\n <p class=\"small\">\n {{ lastUpdated | c8yDate: 'medium' }}\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n <p>\n <span class=\"badge badge-info\">{{ selectedAlarm.count }}</span>\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n <p class=\"small\">\n {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"col-xs-12 col-md-12 p-b-16\"\n *ngIf=\"customFragments\"\n >\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"outgoing-data\"\n ></i>\n </div>\n <div\n class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n data-cy=\"alarm-details-custom-data\"\n >\n <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n <pre><code>{{ customFragments | json }}</code></pre>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Reload audit logs' | translate\"\n type=\"submit\"\n (click)=\"reloadAuditLog(true, true)\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading }\"\n ></i>\n {{ 'Reload audit logs' | translate }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n \"\n type=\"submit\"\n (click)=\"\n onUpdateDetails(\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? ACKNOWLEDGED_STATUS_VALUE\n : ACTIVE_STATUS_VALUE\n )\n \"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n >\n <i\n [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n ></i>\n {{\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Create smart rule' | translate\"\n type=\"submit\"\n *ngIf=\"isCreateSmartRulesButtonAvailable\"\n (click)=\"createSmartRule()\"\n >\n <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n {{ 'Create smart rule' | translate }}\n </button>\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Clear`alarm`' | translate\"\n type=\"submit\"\n (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear`alarm`' | translate }}\n </button>\n\n <button\n *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n class=\"btn btn-default btn-sm\"\n [ngClass]=\"button.additionalButtonClasses\"\n [title]=\"button.title | translate\"\n type=\"button\"\n (click)=\"detailsButtonAction(button, selectedAlarm)\"\n [disabled]=\"button.disabled\"\n >\n <i [ngClass]=\"button.additionalIconClasses\" [c8yIcon]=\"button.icon\"></i>\n <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"'archive'\"\n [title]=\"'No audit logs found.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n <c8y-list-group\n data-cy=\"c8y-alarms-details--audit-logs\"\n *ngIf=\"!isLoading\"\n >\n <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n {{ log.creationTime | date: 'mediumDate' }}\n {{ log.creationTime | date: 'mediumTime' }}\n <c8y-li>\n <c8y-li-body>\n <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n {{ log | auditChangesMessage }}\n </p>\n <div class=\"c8y-list__item__footer\">\n <span\n class=\"m-r-16 small\"\n *ngIf=\"log.user\"\n >\n <span class=\"text-label-small\">\n {{ 'by`user`' | translate }}\n </span>\n {{ log.user }}\n </span>\n <span class=\"small\">\n <span class=\"text-label-small\">\n {{ 'device time' | translate }}\n </span>\n {{ log.time | c8yDate: 'medium' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n</ng-container>\n" }]
1004
+ args: [{ selector: 'c8y-alarm-details', template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n <p class=\"small\">{{ statusMessage }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n c8yIcon=\"contactless-payment\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n <p class=\"small\">\n <button\n class=\"btn-link text-muted p-0 m-r-8 text-left\"\n title=\"{{ selectedAlarm.source.name }}\"\n type=\"button\"\n routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n >\n <small class=\"icon-flex\">\n <i c8yIcon=\"exchange\"></i>\n {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n </small>\n </button>\n <ng-container *ngIf=\"showSourceNavigationLink\">\n <button\n class=\"btn-link p-0 text-left\"\n title=\"{{\n linkTitle\n | translate: { appName: userDeviceManagementApp | humanizeAppName | async }\n }}\"\n type=\"button\"\n (click)=\"goToAlarmSource(selectedAlarm.id)\"\n data-cy=\"alarm-details-device-management-link\"\n >\n {{ userDeviceManagementApp | humanizeAppName | async }}\n <i c8yIcon=\"external-link\"></i>\n </button>\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': typeColor }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n <p\n class=\"small text-truncate\"\n title=\"{{ selectedAlarm.type }}\"\n >\n <code>{{ selectedAlarm.type }}</code>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"col-xs-12 col-md-12 p-b-16\">\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"calendar\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n <div class=\"content-flex-50\">\n <div class=\"col-4 p-b-8\">\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last updated' | translate }}</p>\n <p class=\"small\">\n {{ lastUpdated | c8yDate: 'medium' }}\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n <p>\n <span class=\"badge badge-info\">{{ selectedAlarm.count }}</span>\n </p>\n </div>\n <div\n class=\"col-4 p-b-8\"\n *ngIf=\"selectedAlarm.count > 1\"\n >\n <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n <p class=\"small\">\n {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"col-xs-12 col-md-12 p-b-16\"\n *ngIf=\"customFragments\"\n >\n <div class=\"border-all fit-w d-flex\">\n <div class=\"p-8\">\n <i\n class=\"icon-24 text-gray-dark m-t-4\"\n c8yIcon=\"outgoing-data\"\n ></i>\n </div>\n <div\n class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n data-cy=\"alarm-details-custom-data\"\n >\n <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n <pre><code>{{ customFragments | json }}</code></pre>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Reload audit logs' | translate\"\n type=\"submit\"\n (click)=\"reloadAuditLog(true, true)\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading }\"\n ></i>\n {{ 'Reload audit logs' | translate }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n \"\n type=\"submit\"\n (click)=\"\n onUpdateDetails(\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? ACKNOWLEDGED_STATUS_VALUE\n : ACTIVE_STATUS_VALUE\n )\n \"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n >\n <i\n [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n ></i>\n {{\n selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n ? (ACKNOWLEDGE_LABEL | translate)\n : (REACTIVATE_LABEL | translate)\n }}\n </button>\n\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Create smart rule' | translate\"\n type=\"submit\"\n *ngIf=\"isCreateSmartRulesButtonAvailable\"\n (click)=\"createSmartRule()\"\n >\n <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n {{ 'Create smart rule' | translate }}\n </button>\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Clear`alarm`' | translate\"\n type=\"submit\"\n (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear`alarm`' | translate }}\n </button>\n\n <button\n *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n class=\"btn btn-default btn-sm\"\n [ngClass]=\"button.additionalButtonClasses\"\n [title]=\"button.title | translate\"\n type=\"button\"\n (click)=\"detailsButtonAction(button, selectedAlarm)\"\n [disabled]=\"button.disabled\"\n >\n <i [ngClass]=\"button.additionalIconClasses\" [c8yIcon]=\"button.icon\"></i>\n <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"'archive'\"\n [title]=\"'No audit logs found.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n <c8y-list-group\n data-cy=\"c8y-alarms-details--audit-logs\"\n *ngIf=\"!isLoading\"\n >\n <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n {{ log.creationTime | date: 'mediumDate' }}\n {{ log.creationTime | date: 'mediumTime' }}\n <c8y-li>\n <c8y-li-body>\n <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n {{ log | auditChangesMessage }}\n </p>\n <div class=\"c8y-list__item__footer\">\n <span\n class=\"m-r-16 small\"\n *ngIf=\"log.user\"\n >\n <span class=\"text-label-small\">\n {{ 'by`user`' | translate }}\n </span>\n {{ log.user }}\n </span>\n <span class=\"small\">\n <span class=\"text-label-small\">\n {{ 'device time' | translate }}\n </span>\n {{ log.time | c8yDate: 'medium' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n</ng-container>\n" }]
989
1005
  }], ctorParameters: () => [{ type: AlarmDetailsService }, { type: i2.AlarmService }, { type: i3.AlertService }, { type: i3.AppStateService }, { type: i2.AuditService }, { type: i3.RelativeTimePipe }, { type: Ng1SmartRulesUpgradeService, decorators: [{
990
1006
  type: Optional
991
1007
  }] }, { type: i1.TranslateService }, { type: i2.InventoryService }, { type: AlarmsViewService }, { type: i3.ColorService }], propDecorators: { selectedAlarm: [{
992
1008
  type: Input
993
- }], hasAnyRoleAllowingToCreateSmartRule: [{
994
- type: Input
995
- }], isSmartRulesServiceSubscribed: [{
996
- type: Input
997
1009
  }] } });
998
1010
 
999
1011
  class AlarmEmptyComponent {
@@ -1006,40 +1018,91 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
1006
1018
  }] });
1007
1019
 
1008
1020
  class AlarmInfoComponent {
1009
- constructor(alarmDetailsService, activatedRoute, alarmsService, router, contextRouteService, alarmsViewService) {
1010
- this.alarmDetailsService = alarmDetailsService;
1021
+ constructor(activatedRoute, router, contextRouteService, alarmsViewService) {
1011
1022
  this.activatedRoute = activatedRoute;
1012
- this.alarmsService = alarmsService;
1013
1023
  this.router = router;
1014
1024
  this.contextRouteService = contextRouteService;
1015
1025
  this.alarmsViewService = alarmsViewService;
1016
- this.destroy$ = new Subject();
1017
- }
1018
- ngOnInit() {
1019
- this.selectedAlarm$ = this.activatedRoute.params.pipe(tap(() => (this.isLoading = true)), switchMap$1(params => this.alarmsService.detail(params.id)), map(alarmResult => alarmResult.data), tap(() => this.loadingDone()), shareReplay(), takeUntil(this.destroy$));
1020
- }
1021
- ngOnDestroy() {
1022
- this.destroy$.next();
1023
- this.destroy$.complete();
1026
+ this.isContextRoute = false;
1027
+ this.TITLE = gettext('Alarms');
1024
1028
  }
1025
- async loadingDone() {
1026
- this.isSmartRulesServiceSubscribed = !!(await this.alarmDetailsService.getApplication(this.alarmDetailsService.SMART_RULES_APPLICATION_KEY));
1027
- this.hasAnyRoleAllowingToCreateSmartRule =
1028
- this.alarmDetailsService.checkIfHasAnyRoleAllowingToCreateSmartRule();
1029
- this.isLoading = false;
1029
+ async ngOnInit() {
1030
+ const contextData = this.contextRouteService.getContextData(this.activatedRoute);
1031
+ this.selectedAlarm$ = of(contextData.contextData);
1032
+ this.isContextRoute = this.contextRouteService.isContextRoute(this.router.url, [
1033
+ ViewContext.Device,
1034
+ ViewContext.Group
1035
+ ]);
1030
1036
  }
1031
1037
  back() {
1032
1038
  const contextData = this.contextRouteService.getContextData(this.activatedRoute);
1033
1039
  const backLink = this.alarmsViewService.getRouterNavigationArray(contextData);
1034
1040
  this.router.navigate(backLink, { queryParamsHandling: 'preserve' });
1035
1041
  }
1036
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmInfoComponent, deps: [{ token: AlarmDetailsService }, { token: i1$1.ActivatedRoute }, { token: i2.AlarmService }, { token: i1$1.Router }, { token: i3.ContextRouteService }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
1037
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmInfoComponent, selector: "c8y-alarm-info", ngImport: i0, template: "<div\n class=\"inner-scroll split-view__detail split-view__detail--selected\"\n *ngIf=\"selectedAlarm$ | async\"\n>\n <div\n class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator sticky-top bg-component\"\n >\n <button\n class=\"btn btn-clean text-primary visible-sm visible-xs\"\n [title]=\"'Back' | translate\"\n (click)=\"back()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n\n <div class=\"flex-no-shrink a-s-start\"></div>\n <div class=\"flex-grow d-col\">\n <div class=\"text-break-word flex-grow text-16\">\n {{ (selectedAlarm$ | async)?.text | translate }}\n </div>\n </div>\n </div>\n <div\n class=\"card-block overflow-visible p-l-24 p-r-24\"\n *ngIf=\"!isLoading; else loading\"\n >\n <c8y-alarm-details\n [isSmartRulesServiceSubscribed]=\"isSmartRulesServiceSubscribed\"\n [hasAnyRoleAllowingToCreateSmartRule]=\"hasAnyRoleAllowingToCreateSmartRule\"\n [selectedAlarm]=\"selectedAlarm$ | async\"\n ></c8y-alarm-details>\n </div>\n <ng-template #loading>\n <div class=\"d-flex d-col a-i-center j-c-center fit-h\">\n <c8y-loading></c8y-loading>\n </div>\n </ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: AlarmDetailsComponent, selector: "c8y-alarm-details", inputs: ["selectedAlarm", "hasAnyRoleAllowingToCreateSmartRule", "isSmartRulesServiceSubscribed"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1042
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmInfoComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: i1$1.Router }, { token: i3.ContextRouteService }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
1043
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmInfoComponent, selector: "c8y-alarm-info", ngImport: i0, template: "<ng-container *ngIf=\"!isContextRoute\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<div\n class=\"inner-scroll split-view__detail split-view__detail--selected\"\n *ngIf=\"selectedAlarm$ | async\"\n>\n <div class=\"sticky-top bg-component\">\n <div class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator\">\n <button\n class=\"btn btn-clean text-primary visible-sm visible-xs\"\n [title]=\"'Back' | translate\"\n (click)=\"back()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n\n <div class=\"flex-no-shrink a-s-start\"></div>\n <div class=\"flex-grow d-col\">\n <div\n class=\"text-break-word flex-grow text-16\"\n data-cy=\"c8y-alarms-info--title\"\n >\n {{ (selectedAlarm$ | async)?.text | translate }}\n </div>\n </div>\n </div>\n <div class=\"p-relative\">\n <c8y-tabs-outlet\n outletName=\"alarms\"\n orientation=\"horizontal\"\n ></c8y-tabs-outlet>\n </div>\n <div class=\"card-block overflow-visible p-l-24 p-r-24\">\n <c8y-alarm-details [selectedAlarm]=\"selectedAlarm$ | async\"></c8y-alarm-details>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3.TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "hasHeader"] }, { kind: "component", type: AlarmDetailsComponent, selector: "c8y-alarm-details", inputs: ["selectedAlarm"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1038
1044
  }
1039
1045
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmInfoComponent, decorators: [{
1040
1046
  type: Component,
1041
- args: [{ selector: 'c8y-alarm-info', template: "<div\n class=\"inner-scroll split-view__detail split-view__detail--selected\"\n *ngIf=\"selectedAlarm$ | async\"\n>\n <div\n class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator sticky-top bg-component\"\n >\n <button\n class=\"btn btn-clean text-primary visible-sm visible-xs\"\n [title]=\"'Back' | translate\"\n (click)=\"back()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n\n <div class=\"flex-no-shrink a-s-start\"></div>\n <div class=\"flex-grow d-col\">\n <div class=\"text-break-word flex-grow text-16\">\n {{ (selectedAlarm$ | async)?.text | translate }}\n </div>\n </div>\n </div>\n <div\n class=\"card-block overflow-visible p-l-24 p-r-24\"\n *ngIf=\"!isLoading; else loading\"\n >\n <c8y-alarm-details\n [isSmartRulesServiceSubscribed]=\"isSmartRulesServiceSubscribed\"\n [hasAnyRoleAllowingToCreateSmartRule]=\"hasAnyRoleAllowingToCreateSmartRule\"\n [selectedAlarm]=\"selectedAlarm$ | async\"\n ></c8y-alarm-details>\n </div>\n <ng-template #loading>\n <div class=\"d-flex d-col a-i-center j-c-center fit-h\">\n <c8y-loading></c8y-loading>\n </div>\n </ng-template>\n</div>\n" }]
1042
- }], ctorParameters: () => [{ type: AlarmDetailsService }, { type: i1$1.ActivatedRoute }, { type: i2.AlarmService }, { type: i1$1.Router }, { type: i3.ContextRouteService }, { type: AlarmsViewService }] });
1047
+ args: [{ selector: 'c8y-alarm-info', template: "<ng-container *ngIf=\"!isContextRoute\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<div\n class=\"inner-scroll split-view__detail split-view__detail--selected\"\n *ngIf=\"selectedAlarm$ | async\"\n>\n <div class=\"sticky-top bg-component\">\n <div class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator\">\n <button\n class=\"btn btn-clean text-primary visible-sm visible-xs\"\n [title]=\"'Back' | translate\"\n (click)=\"back()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n\n <div class=\"flex-no-shrink a-s-start\"></div>\n <div class=\"flex-grow d-col\">\n <div\n class=\"text-break-word flex-grow text-16\"\n data-cy=\"c8y-alarms-info--title\"\n >\n {{ (selectedAlarm$ | async)?.text | translate }}\n </div>\n </div>\n </div>\n <div class=\"p-relative\">\n <c8y-tabs-outlet\n outletName=\"alarms\"\n orientation=\"horizontal\"\n ></c8y-tabs-outlet>\n </div>\n <div class=\"card-block overflow-visible p-l-24 p-r-24\">\n <c8y-alarm-details [selectedAlarm]=\"selectedAlarm$ | async\"></c8y-alarm-details>\n </div>\n </div>\n</div>\n" }]
1048
+ }], ctorParameters: () => [{ type: i1$1.ActivatedRoute }, { type: i1$1.Router }, { type: i3.ContextRouteService }, { type: AlarmsViewService }] });
1049
+
1050
+ /**
1051
+ * A service to retrieve custom indicators for the alarm list view.
1052
+ */
1053
+ class AlarmListIndicatorService {
1054
+ constructor(serviceRegistry, pluginsResolver) {
1055
+ this.serviceRegistry = serviceRegistry;
1056
+ this.pluginsResolver = pluginsResolver;
1057
+ }
1058
+ get$(alarm) {
1059
+ const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map(() => {
1060
+ return this.serviceRegistry.get('alarmListIndicator');
1061
+ }));
1062
+ return providers$.pipe(switchMap(providers => {
1063
+ const observables$ = providers.map(provider => provider.getAlarmListIndicator$(alarm).pipe(startWith(false)));
1064
+ return combineLatest(observables$);
1065
+ }), map(indicators => {
1066
+ return indicators.filter(Boolean);
1067
+ }), map(indicators => sortBy(indicators, this.byPriority)));
1068
+ }
1069
+ byPriority(item) {
1070
+ if (item.priority === undefined) {
1071
+ return 0;
1072
+ }
1073
+ return -item.priority;
1074
+ }
1075
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1076
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, providedIn: 'root' }); }
1077
+ }
1078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, decorators: [{
1079
+ type: Injectable,
1080
+ args: [{ providedIn: 'root' }]
1081
+ }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });
1082
+
1083
+ /**
1084
+ * A pipe to provide custom indicators for the alarm list view.
1085
+ *
1086
+ * Will call `get$()` method of `AlarmListIndicatorService` to get the custom indicators for the provided alarm.
1087
+ */
1088
+ class AlarmListIndicatorPipe {
1089
+ constructor(alarmListIndicatorService) {
1090
+ this.alarmListIndicatorService = alarmListIndicatorService;
1091
+ }
1092
+ transform(alarm) {
1093
+ return this.alarmListIndicatorService.get$(alarm);
1094
+ }
1095
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, deps: [{ token: AlarmListIndicatorService }], target: i0.ɵɵFactoryTarget.Pipe }); }
1096
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, isStandalone: true, name: "alarmListIndicator" }); }
1097
+ }
1098
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, decorators: [{
1099
+ type: Pipe,
1100
+ args: [{
1101
+ standalone: true,
1102
+ name: 'alarmListIndicator',
1103
+ pure: true
1104
+ }]
1105
+ }], ctorParameters: () => [{ type: AlarmListIndicatorService }] });
1043
1106
 
1044
1107
  /**
1045
1108
  * Pipe for transforming an array of alarm severity types into a comma-separated string.
@@ -1104,7 +1167,7 @@ class AlarmSeverityToLabelPipe {
1104
1167
  */
1105
1168
  transform(alarmSeverity) {
1106
1169
  const alarmStatusMapped = SEVERITY_LABELS[alarmSeverity?.toUpperCase()];
1107
- return this.translateService.instant(alarmStatusMapped);
1170
+ return this.translateService.instant(alarmStatusMapped ?? alarmSeverity);
1108
1171
  }
1109
1172
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmSeverityToLabelPipe, deps: [{ token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
1110
1173
  static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: AlarmSeverityToLabelPipe, name: "AlarmSeverityToLabel" }); }
@@ -1165,7 +1228,7 @@ class AlarmsFilterComponent {
1165
1228
  this.destroy$ = new Subject();
1166
1229
  }
1167
1230
  ngOnInit() {
1168
- this.activatedRoute.queryParams.pipe(takeUntil$1(this.destroy$)).subscribe(params => {
1231
+ this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe(params => {
1169
1232
  this.showCleared = params.showCleared === 'true';
1170
1233
  this.formGroup.setValue({
1171
1234
  [Severity.CRITICAL]: params[Severity.CRITICAL] === 'true',
@@ -1184,7 +1247,7 @@ class AlarmsFilterComponent {
1184
1247
  }
1185
1248
  ngAfterViewInit() {
1186
1249
  this.filtersDropdown.isOpenChange
1187
- .pipe(takeUntil$1(this.destroy$), filter(Boolean))
1250
+ .pipe(takeUntil(this.destroy$), filter(Boolean))
1188
1251
  .subscribe(() => this.updateAlarmsCount());
1189
1252
  }
1190
1253
  ngOnDestroy() {
@@ -1290,19 +1353,19 @@ class AlarmsFilterComponent {
1290
1353
  this.shouldDisableApplyButton$ = this.createDisableApplyButtonStream();
1291
1354
  }
1292
1355
  createAllSelectedStream(formValue$) {
1293
- return formValue$.pipe(map$1(severities => Object.values(severities).every(Boolean)));
1356
+ return formValue$.pipe(map(severities => Object.values(severities).every(Boolean)));
1294
1357
  }
1295
1358
  createIndeterminateStream(formValue$) {
1296
- return formValue$.pipe(map$1(severities => Object.values(severities).some(Boolean) && !Object.values(severities).every(Boolean)));
1359
+ return formValue$.pipe(map(severities => Object.values(severities).some(Boolean) && !Object.values(severities).every(Boolean)));
1297
1360
  }
1298
1361
  trackAllCheckboxesDisabled(formValue$) {
1299
- formValue$.pipe(takeUntil$1(this.destroy$)).subscribe(severities => {
1362
+ formValue$.pipe(takeUntil(this.destroy$)).subscribe(severities => {
1300
1363
  const areAllDisabled = Object.values(severities).every(value => !value);
1301
1364
  this.isNoneCheckboxSelected$.next(areAllDisabled);
1302
1365
  });
1303
1366
  }
1304
1367
  createDisableApplyButtonStream() {
1305
- return combineLatest([this.isNoneCheckboxSelected$, this.severitiesTouched$]).pipe(map$1(([allCheckboxesAreDisabled, severitiesTouched]) => allCheckboxesAreDisabled || !severitiesTouched));
1368
+ return combineLatest([this.isNoneCheckboxSelected$, this.severitiesTouched$]).pipe(map(([allCheckboxesAreDisabled, severitiesTouched]) => allCheckboxesAreDisabled || !severitiesTouched));
1306
1369
  }
1307
1370
  updateChipsAndDefaultValues() {
1308
1371
  const severityFilter = this.formGroup;
@@ -1444,7 +1507,7 @@ class AlarmsIntervalRefreshComponent {
1444
1507
  onIntervalToggleChange() {
1445
1508
  this.toggleIntervalForm
1446
1509
  .get('intervalToggle')
1447
- .valueChanges.pipe(takeUntil$1(this.destroy$), filter(Boolean))
1510
+ .valueChanges.pipe(takeUntil(this.destroy$), filter(Boolean))
1448
1511
  .subscribe(() => setTimeout(() => this.startCountdown()));
1449
1512
  }
1450
1513
  initForm() {
@@ -1456,12 +1519,12 @@ class AlarmsIntervalRefreshComponent {
1456
1519
  listenToRefreshIntervalChange() {
1457
1520
  this.toggleIntervalForm
1458
1521
  .get('refreshInterval')
1459
- .valueChanges.pipe(takeUntil$1(this.destroy$))
1522
+ .valueChanges.pipe(takeUntil(this.destroy$))
1460
1523
  .subscribe(() => this.resetCountdown());
1461
1524
  }
1462
1525
  listenOnLoadingChanges() {
1463
1526
  this.alarmsListLoading$
1464
- .pipe(tap$1(() => this.countdownIntervalComponent?.stop()))
1527
+ .pipe(tap(() => this.countdownIntervalComponent?.stop()))
1465
1528
  .subscribe(state => {
1466
1529
  !state && this.countdownIntervalComponent?.reset();
1467
1530
  });
@@ -1485,63 +1548,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
1485
1548
  args: [CountdownIntervalComponent]
1486
1549
  }] } });
1487
1550
 
1488
- /**
1489
- * A service to retrieve custom indicators for the alarm list view.
1490
- */
1491
- class AlarmListIndicatorService {
1492
- constructor(serviceRegistry, pluginsResolver) {
1493
- this.serviceRegistry = serviceRegistry;
1494
- this.pluginsResolver = pluginsResolver;
1495
- }
1496
- get$(alarm) {
1497
- const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map$1(() => {
1498
- return this.serviceRegistry.get('alarmListIndicator');
1499
- }));
1500
- return providers$.pipe(switchMap(providers => {
1501
- const observables$ = providers.map(provider => provider.getAlarmListIndicator$(alarm).pipe(startWith(false)));
1502
- return combineLatest(observables$);
1503
- }), map$1(indicators => {
1504
- return indicators.filter(Boolean);
1505
- }), map$1(indicators => sortBy(indicators, this.byPriority)));
1506
- }
1507
- byPriority(item) {
1508
- if (item.priority === undefined) {
1509
- return 0;
1510
- }
1511
- return -item.priority;
1512
- }
1513
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1514
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, providedIn: 'root' }); }
1515
- }
1516
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorService, decorators: [{
1517
- type: Injectable,
1518
- args: [{ providedIn: 'root' }]
1519
- }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });
1520
-
1521
- /**
1522
- * A pipe to provide custom indicators for the alarm list view.
1523
- *
1524
- * Will call `get$()` method of `AlarmListIndicatorService` to get the custom indicators for the provided alarm.
1525
- */
1526
- class AlarmListIndicatorPipe {
1527
- constructor(alarmListIndicatorService) {
1528
- this.alarmListIndicatorService = alarmListIndicatorService;
1529
- }
1530
- transform(alarm) {
1531
- return this.alarmListIndicatorService.get$(alarm);
1532
- }
1533
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, deps: [{ token: AlarmListIndicatorService }], target: i0.ɵɵFactoryTarget.Pipe }); }
1534
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, isStandalone: true, name: "alarmListIndicator" }); }
1535
- }
1536
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmListIndicatorPipe, decorators: [{
1537
- type: Pipe,
1538
- args: [{
1539
- standalone: true,
1540
- name: 'alarmListIndicator',
1541
- pure: true
1542
- }]
1543
- }], ctorParameters: () => [{ type: AlarmListIndicatorService }] });
1544
-
1545
1551
  class AlarmsListComponent {
1546
1552
  constructor(activatedRoute, alarmsViewService, contextRouteService, router) {
1547
1553
  this.activatedRoute = activatedRoute;
@@ -1604,7 +1610,7 @@ class AlarmsListComponent {
1604
1610
  */
1605
1611
  this.isEmptyListLoading = true;
1606
1612
  this.alertAggregator = new DynamicComponentAlertAggregator();
1607
- this.mapAlarmLink = pipe(map$1((alarms) => alarms.map((alarm) => {
1613
+ this.mapAlarmLink = pipe(map((alarms) => alarms.map((alarm) => {
1608
1614
  alarm.link = this.getRouterLink(alarm);
1609
1615
  return alarm;
1610
1616
  })));
@@ -1644,7 +1650,7 @@ class AlarmsListComponent {
1644
1650
  if (this.alarmsViewService.isIntervalRefresh()) {
1645
1651
  const scrollElement = this.innerScrollWrapper.nativeElement;
1646
1652
  fromEvent(scrollElement, 'scroll')
1647
- .pipe(takeUntil$1(this.destroy$), debounceTime(300))
1653
+ .pipe(takeUntil(this.destroy$), debounceTime(300))
1648
1654
  .subscribe((event) => {
1649
1655
  const target = event.target;
1650
1656
  this.isScrolling = this.shouldCountdownIntervalBeHidden(target);
@@ -1671,7 +1677,7 @@ class AlarmsListComponent {
1671
1677
  return scrollTopPixels > this.HIDE_INTERVAL_COUNTDOWN_SCROLL;
1672
1678
  }
1673
1679
  verifyIfFiltersMatchingAlarm() {
1674
- this.activeChildParam$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd && this.activatedRoute.children.length > 0), switchMap(() => this.activatedRoute.children[0].params), map$1(params => params.id), distinctUntilChanged(), shareReplay$1(), takeUntil$1(this.destroy$));
1680
+ this.activeChildParam$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd && this.activatedRoute.children.length > 0), switchMap(() => this.activatedRoute.children[0].params), map(params => params.id), distinctUntilChanged(), shareReplay$1(), takeUntil(this.destroy$));
1675
1681
  // done to get the first navigation
1676
1682
  this.activeChildParam$.subscribe();
1677
1683
  }
@@ -1705,16 +1711,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
1705
1711
  }] } });
1706
1712
 
1707
1713
  class AlarmsDateFilterComponent {
1708
- constructor(formBuilder, router, activatedRoute) {
1714
+ constructor(formBuilder, router, activatedRoute, alarmsViewService) {
1709
1715
  this.formBuilder = formBuilder;
1710
1716
  this.router = router;
1711
1717
  this.activatedRoute = activatedRoute;
1712
- this.DEFAULT_INTERVAL = 'none';
1718
+ this.alarmsViewService = alarmsViewService;
1713
1719
  this.INTERVALS = INTERVALS_EXTENDED;
1714
1720
  this.INTERVAL_TITLES = INTERVAL_TITLES_EXTENDED;
1715
1721
  this.DATE_FORMAT = 'short';
1722
+ this.DEFAULT_INTERVAL = 'none';
1723
+ this.updateQueryParams = true;
1724
+ this.noFilterLabel = gettext('No date filter');
1716
1725
  this.destroy$ = new Subject();
1717
1726
  this.dateFilterChange = new EventEmitter();
1727
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1728
+ this.onTouched = () => { };
1718
1729
  }
1719
1730
  ngOnInit() {
1720
1731
  const context = this.getDefaultContext();
@@ -1723,7 +1734,7 @@ class AlarmsDateFilterComponent {
1723
1734
  this.form.value.currentDateContextFromDate,
1724
1735
  this.form.value.currentDateContextToDate
1725
1736
  ];
1726
- this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe(params => {
1737
+ this.activatedRoute.queryParams.pipe(take(1), takeUntil$1(this.destroy$)).subscribe(params => {
1727
1738
  this.showCleared = params.showCleared === 'true';
1728
1739
  this.severityOptions = {
1729
1740
  [Severity.CRITICAL]: params.critical === 'true',
@@ -1734,6 +1745,20 @@ class AlarmsDateFilterComponent {
1734
1745
  if (params.typeFilters) {
1735
1746
  this.typeFilters = params.typeFilters;
1736
1747
  }
1748
+ if (!params.interval) {
1749
+ return;
1750
+ }
1751
+ if (params.interval !== 'custom') {
1752
+ this.updateDateTime(params.interval);
1753
+ }
1754
+ else {
1755
+ this.form.patchValue({
1756
+ currentDateContextInterval: params.interval,
1757
+ temporaryUserSelectedFromDate: params.lastUpdatedFrom,
1758
+ temporaryUserSelectedToDate: params.createdTo
1759
+ });
1760
+ this.date = [params.lastUpdatedFrom, params.createdTo];
1761
+ }
1737
1762
  });
1738
1763
  this.subscribeToIntervalChange();
1739
1764
  }
@@ -1746,6 +1771,7 @@ class AlarmsDateFilterComponent {
1746
1771
  showCleared: this.showCleared,
1747
1772
  severityOptions: this.severityOptions,
1748
1773
  typeFilters: this.typeFilters,
1774
+ interval: this.form.value.currentDateContextInterval,
1749
1775
  selectedDates: [
1750
1776
  new Date(this.form.value.temporaryUserSelectedFromDate),
1751
1777
  new Date(this.form.value.temporaryUserSelectedToDate)
@@ -1759,50 +1785,61 @@ class AlarmsDateFilterComponent {
1759
1785
  this.router.navigate([], {
1760
1786
  relativeTo: this.activatedRoute,
1761
1787
  queryParams: {
1762
- showCleared: combinedFormEvent.showCleared,
1763
- ...combinedFormEvent.severityOptions,
1764
- typeFilters: this.typeFilters,
1788
+ interval: this.form.value.currentDateContextInterval,
1765
1789
  lastUpdatedFrom: combinedFormEvent.selectedDates[0].toISOString(),
1766
1790
  createdTo: combinedFormEvent.selectedDates[1].toISOString()
1767
- }
1791
+ },
1792
+ queryParamsHandling: 'merge'
1768
1793
  });
1769
1794
  this.dateFilterChange.emit(combinedFormEvent);
1770
1795
  }
1796
+ writeValue(value) {
1797
+ if (value) {
1798
+ this.form.patchValue({
1799
+ currentDateContextFromDate: typeof value[0] === 'string' ? value[0] : value[0].toISOString(),
1800
+ currentDateContextToDate: typeof value[1] === 'string' ? value[1] : value[1].toISOString()
1801
+ });
1802
+ }
1803
+ }
1804
+ registerOnChange(fn) {
1805
+ this.onChange = fn;
1806
+ }
1807
+ registerOnTouched(onTouched) {
1808
+ this.onTouched = onTouched;
1809
+ }
1810
+ updateDateTime(interval) {
1811
+ const date = this.alarmsViewService.getDateTimeContextByInterval(interval);
1812
+ if (this.dropdown) {
1813
+ this.dropdown.isOpen = false;
1814
+ }
1815
+ this.date = date.map(d => d.toISOString());
1816
+ this.form.patchValue({
1817
+ temporaryUserSelectedFromDate: date[0].toISOString(),
1818
+ temporaryUserSelectedToDate: date[1].toISOString(),
1819
+ currentDateContextInterval: interval
1820
+ }, { emitEvent: false });
1821
+ this.applyDateFilter();
1822
+ }
1771
1823
  getDefaultContext() {
1772
- const defaultStartDate = 'months';
1773
1824
  return {
1774
- date: this.getDateTimeContextByInterval(defaultStartDate),
1825
+ date: this.alarmsViewService.getDateTimeContextByInterval(this.DEFAULT_INTERVAL),
1775
1826
  interval: this.DEFAULT_INTERVAL
1776
1827
  };
1777
1828
  }
1778
- getDateTimeContextByInterval(intervalId) {
1779
- const interval = INTERVALS_EXTENDED.find(({ id }) => id === intervalId);
1780
- if (interval.id === 'none') {
1781
- return [new Date(0), new Date()];
1782
- }
1783
- const dateTo = new Date();
1784
- const dateFrom = new Date(dateTo.valueOf() - interval.timespanInMs);
1785
- return [dateFrom, dateTo];
1786
- }
1787
1829
  subscribeToIntervalChange() {
1788
1830
  this.form.controls.currentDateContextInterval.valueChanges
1789
- .pipe(takeUntil(this.destroy$))
1831
+ .pipe(takeUntil$1(this.destroy$))
1790
1832
  .subscribe(interval => {
1791
1833
  if (interval === 'custom') {
1792
1834
  this.form.patchValue({
1793
- temporaryUserSelectedFromDate: this.form.controls.currentDateContextFromDate.value
1835
+ temporaryUserSelectedFromDate: this.form.controls.temporaryUserSelectedFromDate.value === new Date(0).toISOString()
1836
+ ? this.form.controls.currentDateContextToDate.value
1837
+ : this.form.controls.temporaryUserSelectedFromDate.value,
1838
+ currentDateContextInterval: interval
1794
1839
  }, { emitEvent: false });
1795
1840
  return;
1796
1841
  }
1797
- const date = this.getDateTimeContextByInterval(interval);
1798
- this.dropdown.isOpen = false;
1799
- this.date = date.map(d => d.toISOString());
1800
- this.form.patchValue({
1801
- temporaryUserSelectedFromDate: date[0].toISOString(),
1802
- temporaryUserSelectedToDate: date[1].toISOString(),
1803
- currentDateContextInterval: interval
1804
- }, { emitEvent: false });
1805
- this.applyDateFilter();
1842
+ this.updateDateTime(interval);
1806
1843
  });
1807
1844
  }
1808
1845
  createForm(context) {
@@ -1814,13 +1851,31 @@ class AlarmsDateFilterComponent {
1814
1851
  currentDateContextInterval: context.interval || 'custom'
1815
1852
  });
1816
1853
  }
1817
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsDateFilterComponent, deps: [{ token: i1$2.FormBuilder }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
1818
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsDateFilterComponent, selector: "c8y-alarms-date-filter", outputs: { dateFilterChange: "dateFilterChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], ngImport: i0, template: "<form\n class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n>\n <div>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{\n form.value.currentDateContextInterval === 'none'\n ? 'No date filter'\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span class=\"text-12 text-truncate\">\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"alarms-date-filter--selected-time-range\"\n *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n [INTERVALS]=\"INTERVALS\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n [disabled]=\"(form.pristine && form.untouched) || form.invalid || form.value.realtime\"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i3.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: i5$1.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: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i8.IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1854
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsDateFilterComponent, deps: [{ token: i1$2.FormBuilder }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
1855
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsDateFilterComponent, selector: "c8y-alarms-date-filter", inputs: { DEFAULT_INTERVAL: "DEFAULT_INTERVAL", updateQueryParams: "updateQueryParams", date: "date" }, outputs: { dateFilterChange: "dateFilterChange" }, providers: [
1856
+ {
1857
+ provide: NG_VALUE_ACCESSOR,
1858
+ useExisting: forwardRef(() => AlarmsDateFilterComponent),
1859
+ multi: true
1860
+ }
1861
+ ], viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], ngImport: i0, template: "<form\n class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n>\n <div\n class=\"dropdown flex-grow\"\n c8yDropdownDirection\n #dropDirection=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{\n (form.value.currentDateContextInterval === 'none'\n ? noFilterLabel\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n ) | translate\n }}\"\n tooltip=\"{{\n (form.value.currentDateContextInterval === 'none'\n ? noFilterLabel\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n ) | translate\n }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"alarms-date-filter--selected-time-range\"\n *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n [INTERVALS]=\"INTERVALS\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n [disabled]=\"(form.pristine && form.untouched) || form.invalid\"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DropdownDirectionDirective, selector: "[dropdown][c8yBsDropdownDirection],[dropdown][c8yDropdownDirection]" }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i3.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: i5$1.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: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i9.IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1819
1862
  }
1820
1863
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsDateFilterComponent, decorators: [{
1821
1864
  type: Component,
1822
- args: [{ selector: 'c8y-alarms-date-filter', template: "<form\n class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n>\n <div>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{\n form.value.currentDateContextInterval === 'none'\n ? 'No date filter'\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span class=\"text-12 text-truncate\">\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"alarms-date-filter--selected-time-range\"\n *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n [INTERVALS]=\"INTERVALS\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n [disabled]=\"(form.pristine && form.untouched) || form.invalid || form.value.realtime\"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </div>\n</form>\n" }]
1823
- }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }], propDecorators: { dateFilterChange: [{
1865
+ args: [{ selector: 'c8y-alarms-date-filter', providers: [
1866
+ {
1867
+ provide: NG_VALUE_ACCESSOR,
1868
+ useExisting: forwardRef(() => AlarmsDateFilterComponent),
1869
+ multi: true
1870
+ }
1871
+ ], template: "<form\n class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n>\n <div\n class=\"dropdown flex-grow\"\n c8yDropdownDirection\n #dropDirection=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{\n (form.value.currentDateContextInterval === 'none'\n ? noFilterLabel\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n ) | translate\n }}\"\n tooltip=\"{{\n (form.value.currentDateContextInterval === 'none'\n ? noFilterLabel\n : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n ) | translate\n }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"alarms-date-filter--selected-time-range\"\n *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n [INTERVALS]=\"INTERVALS\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n class=\"m-b-8\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n [disabled]=\"(form.pristine && form.untouched) || form.invalid\"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n</form>\n" }]
1872
+ }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: AlarmsViewService }], propDecorators: { DEFAULT_INTERVAL: [{
1873
+ type: Input
1874
+ }], updateQueryParams: [{
1875
+ type: Input
1876
+ }], date: [{
1877
+ type: Input
1878
+ }], dateFilterChange: [{
1824
1879
  type: Output
1825
1880
  }], dropdown: [{
1826
1881
  type: ViewChild,
@@ -1828,72 +1883,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
1828
1883
  }] } });
1829
1884
 
1830
1885
  class AlarmsTypeFilterComponent {
1831
- constructor(formBuilder, alarmEventSelectorService, activatedRoute, router) {
1832
- this.formBuilder = formBuilder;
1886
+ constructor(alarmEventSelectorService, activatedRoute, router, colorService) {
1833
1887
  this.alarmEventSelectorService = alarmEventSelectorService;
1834
1888
  this.activatedRoute = activatedRoute;
1835
1889
  this.router = router;
1890
+ this.colorService = colorService;
1891
+ this.possibleFilters = [];
1836
1892
  this.activeFilters = [];
1837
1893
  this.onFilterChanged = new EventEmitter();
1838
- this.formControlName = 'alarms';
1894
+ this.customAlarmTypes = [];
1895
+ this.customAlarmTypeInput = '';
1839
1896
  this.queryParamName = 'typeFilter';
1840
- this.formGroup = this.formBuilder.group({
1841
- [this.formControlName]: new FormControl([])
1842
- });
1897
+ this.STORAGE_ACCESS_KEY = 'customAlarmTypes';
1843
1898
  this.destroy$ = new Subject();
1844
- this.queryParam = '';
1899
+ this.currentQueryParam = '';
1845
1900
  }
1846
1901
  ngOnInit() {
1847
- this.activatedRoute.queryParams
1848
- .pipe(map$1(params => {
1849
- const alarms = this.formGroup.get(this.formControlName).value;
1850
- return this.getActiveAlarmFiltersFromQueryParameter(alarms, params[this.queryParamName]);
1851
- }), takeUntil$1(this.destroy$))
1852
- .subscribe((alarmFilters) => this.formGroup.get(this.formControlName).patchValue(alarmFilters));
1853
- this.formGroup
1854
- .get(this.formControlName)
1855
- .valueChanges.pipe(takeUntil$1(this.destroy$))
1856
- .subscribe((alarmFilters) => this.applyFilterChange(alarmFilters));
1902
+ this.setQueryParameterObservable();
1857
1903
  }
1858
- ngOnChanges(changes) {
1904
+ async ngOnChanges(changes) {
1859
1905
  if (changes.alarms && changes.alarms.currentValue && this.activeFilters.length === 0) {
1860
- this.setAlarms();
1906
+ await this.setPossibleFilters();
1907
+ this.applyFilterChange();
1861
1908
  }
1862
1909
  }
1910
+ setQueryParameterObservable() {
1911
+ this.activatedRoute.queryParams
1912
+ .pipe(map$1(params => {
1913
+ const alarms = this.possibleFilters;
1914
+ const possibleFilters = this.setActiveAlarmFiltersFromQueryParameter(alarms, params[this.queryParamName]);
1915
+ return possibleFilters;
1916
+ }), takeUntil$1(this.destroy$))
1917
+ .subscribe((possibleFilters) => {
1918
+ this.possibleFilters = possibleFilters;
1919
+ this.applyFilterChange();
1920
+ });
1921
+ }
1863
1922
  ngOnDestroy() {
1864
1923
  this.destroy$.next();
1865
1924
  this.destroy$.complete();
1866
1925
  }
1926
+ toggleAlarmType(alarmType) {
1927
+ alarmType.__active = !alarmType.__active;
1928
+ }
1867
1929
  deselect(type) {
1868
- const alarms = this.formGroup.get(this.formControlName).value;
1869
- const alarmFilter = alarms.find(alarm => alarm.filters.type === type.filters.type);
1930
+ const alarmFilter = this.possibleFilters.find(alarm => alarm.filters.type === type.filters.type);
1870
1931
  alarmFilter.__active = false;
1871
- this.formGroup.get(this.formControlName).patchValue(alarms);
1932
+ this.applyFilterChange();
1872
1933
  }
1873
1934
  deselectAll() {
1874
- const alarms = this.formGroup.get(this.formControlName).value;
1875
- const allFilters = alarms.map(alarm => {
1935
+ this.possibleFilters = this.possibleFilters.map(alarm => {
1876
1936
  return {
1877
1937
  ...alarm,
1878
1938
  __active: false
1879
1939
  };
1880
1940
  });
1881
- this.formGroup.get(this.formControlName).patchValue(allFilters);
1882
- }
1883
- getActiveAlarmFiltersFromQueryParameter(alarmFilters, filterTypesQuery) {
1884
- if (!filterTypesQuery) {
1885
- return alarmFilters;
1886
- }
1887
- const types = filterTypesQuery.split(',');
1888
- return alarmFilters.map((alarm) => ({
1889
- ...alarm,
1890
- __active: types.includes(alarm.filters.type)
1891
- }));
1941
+ this.applyFilterChange();
1892
1942
  }
1893
- applyFilterChange(alarmFilters) {
1894
- const actives = alarmFilters.filter((alarmFilter) => alarmFilter.__active);
1943
+ applyFilterChange() {
1944
+ const actives = this.possibleFilters.filter((alarmFilter) => alarmFilter.__active);
1895
1945
  const newQueryParam = this.getQueryParams(actives);
1896
- const hasChanged = newQueryParam !== this.queryParam;
1946
+ const hasChanged = newQueryParam !== this.currentQueryParam;
1897
1947
  if (hasChanged) {
1898
1948
  this.activeFilters = actives;
1899
1949
  this.onFilterChanged.emit(this.activeFilters);
@@ -1903,41 +1953,76 @@ class AlarmsTypeFilterComponent {
1903
1953
  },
1904
1954
  queryParamsHandling: 'merge'
1905
1955
  });
1906
- this.queryParam = newQueryParam;
1956
+ this.currentQueryParam = newQueryParam;
1907
1957
  }
1908
1958
  }
1909
- getQueryParams(activeFilters) {
1910
- return activeFilters.map(filter => filter.filters.type).join(',');
1959
+ resetFilters() {
1960
+ this.possibleFilters.forEach(possibleFilter => {
1961
+ possibleFilter.__active = this.activeFilters.some((activeFilter) => activeFilter === possibleFilter);
1962
+ });
1963
+ }
1964
+ removeCustomAlarm(alarmDetails) {
1965
+ this.possibleFilters = this.possibleFilters.filter(filter => filter !== alarmDetails);
1966
+ this.storeCustomAlarmTypes();
1967
+ }
1968
+ confirmWithEnter(event) {
1969
+ if (event.key === 'Enter') {
1970
+ this.addCustomAlarmType();
1971
+ }
1972
+ }
1973
+ async addCustomAlarmType() {
1974
+ if (!this.customAlarmTypeInput) {
1975
+ return;
1976
+ }
1977
+ this.possibleFilters.unshift({
1978
+ label: this.customAlarmTypeInput,
1979
+ color: await this.colorService.generateColor(this.customAlarmTypeInput),
1980
+ filters: {
1981
+ type: this.customAlarmTypeInput
1982
+ },
1983
+ timelineType: 'ALARM',
1984
+ __active: true,
1985
+ __target: null
1986
+ });
1987
+ this.customAlarmTypeInput = '';
1988
+ this.storeCustomAlarmTypes();
1911
1989
  }
1912
- async setAlarms() {
1990
+ storeCustomAlarmTypes() {
1991
+ const customTypes = this.possibleFilters.filter((filter) => !filter.__target);
1992
+ window.localStorage.setItem(this.STORAGE_ACCESS_KEY, JSON.stringify(customTypes));
1993
+ }
1994
+ getCustomAlarmTypeFromStorage() {
1995
+ const types = window.localStorage.getItem(this.STORAGE_ACCESS_KEY);
1996
+ return types ? JSON.parse(types) : [];
1997
+ }
1998
+ async setPossibleFilters() {
1913
1999
  const queryParameters = this.activatedRoute.snapshot.queryParamMap.get(this.queryParamName);
1914
2000
  const alarmTypesFromCurrentlyShownAlarms = await this.alarmEventSelectorService.getUniqueAlarmsOnly(this.alarms.data);
1915
- const alarmTypesWithMissingAndCustom = await this.addMissingAlarmTypesFromQueryParams(alarmTypesFromCurrentlyShownAlarms, queryParameters);
1916
- const selectableAlarmTypes = this.getActiveAlarmFiltersFromQueryParameter(alarmTypesWithMissingAndCustom, queryParameters);
1917
- this.formGroup.get(this.formControlName).patchValue(selectableAlarmTypes);
2001
+ const customAlarmTypesFromLocalStorage = this.getCustomAlarmTypeFromStorage();
2002
+ const selectableAlarmTypes = this.setActiveAlarmFiltersFromQueryParameter([...customAlarmTypesFromLocalStorage, ...alarmTypesFromCurrentlyShownAlarms], queryParameters);
2003
+ this.possibleFilters = selectableAlarmTypes;
1918
2004
  }
1919
- async addMissingAlarmTypesFromQueryParams(alarmFilters, queryParameters) {
1920
- if (!queryParameters) {
1921
- return alarmFilters;
1922
- }
1923
- const types = queryParameters.split(',');
1924
- const missingFilters = await Promise.all(types
1925
- .filter(type => !alarmFilters.find(alarmFilter => alarmFilter.filters.type === type))
1926
- .map(type => {
1927
- return this.alarmEventSelectorService.createItem('ALARM', {
1928
- type,
1929
- source: null
1930
- });
2005
+ setActiveAlarmFiltersFromQueryParameter(alarmFilters, filterTypesQuery = '') {
2006
+ const types = (filterTypesQuery ?? '').split(',');
2007
+ return alarmFilters.map((alarm) => ({
2008
+ ...alarm,
2009
+ __active: types.includes(alarm.filters.type)
1931
2010
  }));
1932
- return [...alarmFilters, ...missingFilters];
1933
2011
  }
1934
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsTypeFilterComponent, deps: [{ token: i1$2.FormBuilder }, { token: i2$1.AlarmEventSelectorService }, { token: i1$1.ActivatedRoute }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
1935
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsTypeFilterComponent, selector: "c8y-alarms-type-filter", inputs: { alarms: "alarms" }, outputs: { onFilterChanged: "onFilterChanged" }, usesOnChanges: true, ngImport: i0, template: "<form\n class=\"d-flex a-i-center\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"dropdown\"\n title=\"{{ 'Filter by Alarm types' | translate }}\"\n dropdown\n #filtersDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <div class=\"input-group fit-w\">\n <div class=\"form-control d-flex a-i-center inner-scroll\">\n <ng-container *ngIf=\"activeFilters.length > 0; else allTypes\">\n <span\n class=\"tag tag--info chip\"\n *ngFor=\"let filter of activeFilters\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ 'Remove' | translate }}\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); deselect(filter)\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': filter.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n {{ filter.filters.type }}\n </span>\n </ng-container>\n <ng-template #allTypes>\n <span class=\"text-nowrap\">\n {{ 'All alarm types' | translate }}\n </span>\n </ng-template>\n </div>\n <div class=\"input-group-btn input-group-btn--last text-center\">\n <button\n class=\"btn-default btn\"\n [title]=\"'Clear filters' | translate\"\n *ngIf=\"activeFilters.length\"\n (click)=\"deselectAll()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <button\n class=\"btn-default btn btn--caret\"\n [title]=\"'Alarm types' | translate\"\n data-cy=\"c8y-alarm-type-filter\"\n dropdownToggle\n >\n <i class=\"caret\"></i>\n </button>\n </div>\n </div>\n <div\n class=\"dropdown-menu dropdown-menu-action-bar\"\n style=\"max-width:unset; min-width: 250px\"\n *dropdownMenu\n >\n <c8y-alarm-event-selection-list\n [title]=\"'Alarm type filter' | translate\"\n [attr.name]=\"formControlName\"\n [config]=\"{\n title: 'Alarm type filter' | translate,\n allowChangingContext: false\n }\"\n [inline]=\"true\"\n [hideSource]=\"true\"\n [addButtonLabel]=\"'Manage alarm types' | translate\"\n [canEdit]=\"false\"\n [canDragAndDrop]=\"false\"\n [canRemove]=\"false\"\n [timelineType]=\"'ALARM'\"\n [activeToggleAsSwitch]=\"false\"\n [formControlName]=\"formControlName\"\n >\n <c8y-ui-empty-state\n class=\"p-t-8\"\n icon=\"c8y-alarm\"\n [title]=\"'No alarm found' | translate\"\n [subtitle]=\"'There is no alarm to filter. You can still add a custom alarm.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-alarm-event-selection-list>\n </div>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i5.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2$1.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "config"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
2012
+ getQueryParams(activeFilters) {
2013
+ return activeFilters.map(filter => filter.filters.type).join(',');
2014
+ }
2015
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsTypeFilterComponent, deps: [{ token: i1$3.AlarmEventSelectorService }, { token: i1$1.ActivatedRoute }, { token: i1$1.Router }, { token: i3.ColorService }], target: i0.ɵɵFactoryTarget.Component }); }
2016
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsTypeFilterComponent, selector: "c8y-alarms-type-filter", inputs: { alarms: "alarms", possibleFilters: "possibleFilters", activeFilters: "activeFilters" }, outputs: { onFilterChanged: "onFilterChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex a-i-center\">\n <div\n class=\"dropdown\"\n title=\"{{ 'Filter by Alarm types' | translate }}\"\n dropdown\n #filtersDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n (onHidden)=\"resetFilters()\"\n [insideClick]=\"true\"\n >\n <div class=\"input-group fit-w\">\n <div class=\"form-control d-flex a-i-center inner-scroll\">\n <ng-container *ngIf=\"activeFilters.length > 0; else allTypes\">\n <span\n class=\"tag tag--info chip\"\n *ngFor=\"let filter of activeFilters\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ 'Remove' | translate }}\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); deselect(filter)\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': filter.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n {{ filter.filters.type }}\n </span>\n </ng-container>\n <ng-template #allTypes>\n <span class=\"text-nowrap\">\n {{ 'All alarm types' | translate }}\n </span>\n </ng-template>\n </div>\n <div class=\"input-group-btn input-group-btn--last text-center\">\n <button\n class=\"btn-default btn\"\n [title]=\"'Clear filters' | translate\"\n *ngIf=\"activeFilters.length\"\n (click)=\"deselectAll()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <button\n class=\"btn-default btn btn--caret\"\n [title]=\"'Alarm types' | translate\"\n data-cy=\"c8y-alarm-type-filter\"\n dropdownToggle\n >\n <i class=\"caret\"></i>\n </button>\n </div>\n </div>\n <div\n class=\"dropdown-menu dropdown-menu-action-bar\"\n style=\"max-width: unset; min-width: 250px\"\n *dropdownMenu\n >\n <div class=\"p-16 bg-level-2\">\n <div>\n <p>\n <i\n class=\"text-info m-r-4\"\n [c8yIcon]=\"'info-circle'\"\n ></i>\n <strong tanslate>The list below may not be complete.</strong>\n </p>\n <p tanslate>\n Recent alarms are displayed below. Past alarms might not be shown. Optionally you can\n add a custom alarm.\n </p>\n </div>\n </div>\n <c8y-list-group>\n <div class=\"input-group p-t-16 p-b-16 p-r-32 p-l-32 separator-bottom\">\n <input\n class=\"form-control\"\n placeholder=\"'Custom alarm type' | translate\"\n type=\"text\"\n [(ngModel)]=\"customAlarmTypeInput\"\n (keydown)=\"confirmWithEnter($event)\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn-dot text-primary\"\n [attr.aria-label]=\"'Add custom alarm' | translate\"\n tooltip=\"'Add' | translate\"\n placement=\"top\"\n [delay]=\"500\"\n (click)=\"addCustomAlarmType()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n </button>\n </div>\n </div>\n\n <c8y-li\n class=\"c8y-list__item__collapse--container-small cdk-drag\"\n style=\"cursor: pointer\"\n *ngFor=\"let alarmType of possibleFilters\"\n (click)=\"toggleAlarmType(alarmType)\"\n >\n <c8y-li-checkbox\n class=\"a-s-center m-t-4 p-r-0 p-l-0\"\n [selected]=\"alarmType.__active\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleAlarmType(alarmType); $event.stopPropagation()\"\n ></c8y-li-checkbox>\n <div class=\"d-flex a-i-center p-l-4\">\n <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-0\">\n <div class=\"c8y-colorpicker c8y-colorpicker--alarm\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': alarmType.color }\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"'bell'\"\n ></i>\n </span>\n </div>\n </div>\n <span class=\"text-truncate text-12 flex-grow\">\n {{ alarmType.label }}\n </span>\n <button\n class=\"btn-dot btn-dot--danger\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"'Remove' | translate\"\n placement=\"top\"\n *ngIf=\"alarmType.__target === null\"\n [delay]=\"500\"\n (click)=\"removeCustomAlarm(alarmType); $event.stopPropagation()\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </c8y-li>\n <c8y-li *ngIf=\"possibleFilters.length === 0\">\n <c8y-ui-empty-state\n class=\"p-t-8\"\n icon=\"c8y-alarm\"\n [title]=\"'No alarm found' | translate\"\n [subtitle]=\"\n 'There is no alarm to filter. You can still add a custom alarm.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-li>\n <div class=\"sticky-bottom p-16\">\n <button\n class=\"btn btn-block btn-primary\"\n [disabled]=\"possibleFilters.length === 0\"\n (click)=\"applyFilterChange(); $event.stopPropagation(); filtersDropdown.hide()\"\n translate\n >\n Apply\n </button>\n </div>\n </c8y-list-group>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemCheckboxComponent, selector: "c8y-list-item-checkbox, c8y-li-checkbox", inputs: ["selected", "indeterminate", "disabled", "displayAsSwitch"], outputs: ["onSelect"] }, { kind: "directive", type: i5$1.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: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1936
2017
  }
1937
2018
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsTypeFilterComponent, decorators: [{
1938
2019
  type: Component,
1939
- args: [{ selector: 'c8y-alarms-type-filter', template: "<form\n class=\"d-flex a-i-center\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"dropdown\"\n title=\"{{ 'Filter by Alarm types' | translate }}\"\n dropdown\n #filtersDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <div class=\"input-group fit-w\">\n <div class=\"form-control d-flex a-i-center inner-scroll\">\n <ng-container *ngIf=\"activeFilters.length > 0; else allTypes\">\n <span\n class=\"tag tag--info chip\"\n *ngFor=\"let filter of activeFilters\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ 'Remove' | translate }}\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); deselect(filter)\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': filter.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n {{ filter.filters.type }}\n </span>\n </ng-container>\n <ng-template #allTypes>\n <span class=\"text-nowrap\">\n {{ 'All alarm types' | translate }}\n </span>\n </ng-template>\n </div>\n <div class=\"input-group-btn input-group-btn--last text-center\">\n <button\n class=\"btn-default btn\"\n [title]=\"'Clear filters' | translate\"\n *ngIf=\"activeFilters.length\"\n (click)=\"deselectAll()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <button\n class=\"btn-default btn btn--caret\"\n [title]=\"'Alarm types' | translate\"\n data-cy=\"c8y-alarm-type-filter\"\n dropdownToggle\n >\n <i class=\"caret\"></i>\n </button>\n </div>\n </div>\n <div\n class=\"dropdown-menu dropdown-menu-action-bar\"\n style=\"max-width:unset; min-width: 250px\"\n *dropdownMenu\n >\n <c8y-alarm-event-selection-list\n [title]=\"'Alarm type filter' | translate\"\n [attr.name]=\"formControlName\"\n [config]=\"{\n title: 'Alarm type filter' | translate,\n allowChangingContext: false\n }\"\n [inline]=\"true\"\n [hideSource]=\"true\"\n [addButtonLabel]=\"'Manage alarm types' | translate\"\n [canEdit]=\"false\"\n [canDragAndDrop]=\"false\"\n [canRemove]=\"false\"\n [timelineType]=\"'ALARM'\"\n [activeToggleAsSwitch]=\"false\"\n [formControlName]=\"formControlName\"\n >\n <c8y-ui-empty-state\n class=\"p-t-8\"\n icon=\"c8y-alarm\"\n [title]=\"'No alarm found' | translate\"\n [subtitle]=\"'There is no alarm to filter. You can still add a custom alarm.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-alarm-event-selection-list>\n </div>\n </div>\n</form>\n" }]
1940
- }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: i2$1.AlarmEventSelectorService }, { type: i1$1.ActivatedRoute }, { type: i1$1.Router }], propDecorators: { alarms: [{
2020
+ args: [{ selector: 'c8y-alarms-type-filter', template: "<div class=\"d-flex a-i-center\">\n <div\n class=\"dropdown\"\n title=\"{{ 'Filter by Alarm types' | translate }}\"\n dropdown\n #filtersDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n (onHidden)=\"resetFilters()\"\n [insideClick]=\"true\"\n >\n <div class=\"input-group fit-w\">\n <div class=\"form-control d-flex a-i-center inner-scroll\">\n <ng-container *ngIf=\"activeFilters.length > 0; else allTypes\">\n <span\n class=\"tag tag--info chip\"\n *ngFor=\"let filter of activeFilters\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ 'Remove' | translate }}\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); deselect(filter)\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': filter.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n {{ filter.filters.type }}\n </span>\n </ng-container>\n <ng-template #allTypes>\n <span class=\"text-nowrap\">\n {{ 'All alarm types' | translate }}\n </span>\n </ng-template>\n </div>\n <div class=\"input-group-btn input-group-btn--last text-center\">\n <button\n class=\"btn-default btn\"\n [title]=\"'Clear filters' | translate\"\n *ngIf=\"activeFilters.length\"\n (click)=\"deselectAll()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n <button\n class=\"btn-default btn btn--caret\"\n [title]=\"'Alarm types' | translate\"\n data-cy=\"c8y-alarm-type-filter\"\n dropdownToggle\n >\n <i class=\"caret\"></i>\n </button>\n </div>\n </div>\n <div\n class=\"dropdown-menu dropdown-menu-action-bar\"\n style=\"max-width: unset; min-width: 250px\"\n *dropdownMenu\n >\n <div class=\"p-16 bg-level-2\">\n <div>\n <p>\n <i\n class=\"text-info m-r-4\"\n [c8yIcon]=\"'info-circle'\"\n ></i>\n <strong tanslate>The list below may not be complete.</strong>\n </p>\n <p tanslate>\n Recent alarms are displayed below. Past alarms might not be shown. Optionally you can\n add a custom alarm.\n </p>\n </div>\n </div>\n <c8y-list-group>\n <div class=\"input-group p-t-16 p-b-16 p-r-32 p-l-32 separator-bottom\">\n <input\n class=\"form-control\"\n placeholder=\"'Custom alarm type' | translate\"\n type=\"text\"\n [(ngModel)]=\"customAlarmTypeInput\"\n (keydown)=\"confirmWithEnter($event)\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn-dot text-primary\"\n [attr.aria-label]=\"'Add custom alarm' | translate\"\n tooltip=\"'Add' | translate\"\n placement=\"top\"\n [delay]=\"500\"\n (click)=\"addCustomAlarmType()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n </button>\n </div>\n </div>\n\n <c8y-li\n class=\"c8y-list__item__collapse--container-small cdk-drag\"\n style=\"cursor: pointer\"\n *ngFor=\"let alarmType of possibleFilters\"\n (click)=\"toggleAlarmType(alarmType)\"\n >\n <c8y-li-checkbox\n class=\"a-s-center m-t-4 p-r-0 p-l-0\"\n [selected]=\"alarmType.__active\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleAlarmType(alarmType); $event.stopPropagation()\"\n ></c8y-li-checkbox>\n <div class=\"d-flex a-i-center p-l-4\">\n <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-0\">\n <div class=\"c8y-colorpicker c8y-colorpicker--alarm\">\n <span\n class=\"circle-icon-wrapper\"\n [ngStyle]=\"{ 'background-color': alarmType.color }\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"'bell'\"\n ></i>\n </span>\n </div>\n </div>\n <span class=\"text-truncate text-12 flex-grow\">\n {{ alarmType.label }}\n </span>\n <button\n class=\"btn-dot btn-dot--danger\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"'Remove' | translate\"\n placement=\"top\"\n *ngIf=\"alarmType.__target === null\"\n [delay]=\"500\"\n (click)=\"removeCustomAlarm(alarmType); $event.stopPropagation()\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </c8y-li>\n <c8y-li *ngIf=\"possibleFilters.length === 0\">\n <c8y-ui-empty-state\n class=\"p-t-8\"\n icon=\"c8y-alarm\"\n [title]=\"'No alarm found' | translate\"\n [subtitle]=\"\n 'There is no alarm to filter. You can still add a custom alarm.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-li>\n <div class=\"sticky-bottom p-16\">\n <button\n class=\"btn btn-block btn-primary\"\n [disabled]=\"possibleFilters.length === 0\"\n (click)=\"applyFilterChange(); $event.stopPropagation(); filtersDropdown.hide()\"\n translate\n >\n Apply\n </button>\n </div>\n </c8y-list-group>\n </div>\n </div>\n</div>\n" }]
2021
+ }], ctorParameters: () => [{ type: i1$3.AlarmEventSelectorService }, { type: i1$1.ActivatedRoute }, { type: i1$1.Router }, { type: i3.ColorService }], propDecorators: { alarms: [{
2022
+ type: Input
2023
+ }], possibleFilters: [{
2024
+ type: Input
2025
+ }], activeFilters: [{
1941
2026
  type: Input
1942
2027
  }], onFilterChanged: [{
1943
2028
  type: Output
@@ -1980,7 +2065,7 @@ class AlarmsComponent {
1980
2065
  this.handleLegacyRealtime();
1981
2066
  }
1982
2067
  this.alarmsViewService.reloadAlarmsList$
1983
- .pipe(debounceTime(this.WAIT_TIME_AVOID_MULTIPLE_REQUEST_BY_PARAM_CHANGE), takeUntil$1(this.destroy$))
2068
+ .pipe(debounceTime(this.WAIT_TIME_AVOID_MULTIPLE_REQUEST_BY_PARAM_CHANGE), takeUntil(this.destroy$))
1984
2069
  .subscribe(() => {
1985
2070
  this.updateAlarms();
1986
2071
  });
@@ -2087,7 +2172,7 @@ class AlarmsComponent {
2087
2172
  subscribeToRealtimeUpdates() {
2088
2173
  this.alarmWithChildrenRealtimeService
2089
2174
  .onAll$(this.contextSourceId)
2090
- .pipe(takeUntil$1(this.destroy$), throttleTime(THROTTLE_REALTIME_REFRESH, undefined, { trailing: true }))
2175
+ .pipe(takeUntil(this.destroy$), throttleTime(THROTTLE_REALTIME_REFRESH, undefined, { trailing: true }))
2091
2176
  .subscribe(() => {
2092
2177
  if (this.isRealtimeToggleOn) {
2093
2178
  this.refresh();
@@ -2098,19 +2183,55 @@ class AlarmsComponent {
2098
2183
  });
2099
2184
  }
2100
2185
  initializeContextSourceId() {
2101
- this.contextSourceId = this.contextRouteService.getContextData(this.activatedRoute)?.contextData?.id;
2186
+ const routeContext = this.contextRouteService.getContextData(this.activatedRoute);
2187
+ if (!routeContext) {
2188
+ return;
2189
+ }
2190
+ const { context, contextData } = routeContext;
2191
+ if ([ViewContext.Device, ViewContext.Group].includes(context)) {
2192
+ this.contextSourceId = contextData?.id;
2193
+ }
2102
2194
  }
2103
2195
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: AlarmsViewService }, { token: i3.AlarmWithChildrenRealtimeService }, { token: i3.AlertService }, { token: i3.ContextRouteService }, { token: i3.ModalService }, { token: i1.TranslateService }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
2104
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsComponent, selector: "c8y-alarms", providers: [AlarmWithChildrenRealtimeService], viewQueries: [{ propertyName: "alarmIntervalRefreshComponent", first: true, predicate: AlarmsIntervalRefreshComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-filter\n [contextSourceId]=\"contextSourceId\"\n (onFilterApplied)=\"applyFormFilters($event)\"\n class=\"d-block fit-w\"\n ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item \n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n>\n <c8y-alarms-type-filter\n [alarms]=\"alarms$ | async\"\n (onFilterChanged)=\"applyTypeFilters($event)\"\n class=\"d-block fit-w\"\n ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"0\"\n>\n <button\n class=\"btn btn-link\"\n [title]=\"'Clear all alarms' | translate\"\n type=\"button\"\n (click)=\"clearAll()\"\n data-cy=\"c8y-alarms-view--clear-all-button\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear all`alarms`' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"\n (isRealtimeActive | async)\n ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n : (REFRESH_LABEL | translate)\n \"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading$ | async\"\n (click)=\"refresh()\"\n >\n <span\n class=\"tag tag--info m-r-8\"\n *ngIf=\"isRealtimeActive | async\"\n >\n {{ 'New alarms' | translate }}\n </span>\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n ></i>\n </button>\n <button\n class=\"c8y-realtime btn btn-default btn-sm\"\n [attr.aria-label]=\"realtimeIconTitle\"\n [tooltip]=\"realtimeIconTitle\"\n placement=\"bottom\"\n type=\"button\"\n [container]=\"'body'\"\n (click)=\"toggleRealtimeState()\"\n >\n <span\n class=\"c8y-pulse m-0\"\n [ngClass]=\"{\n active: isRealtimeToggleOn,\n inactive: !isRealtimeToggleOn\n }\"\n ></span>\n </button>\n </div>\n</ng-template>\n\n<c8y-help\n src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n <c8y-alarms-list\n class=\"d-contents\"\n [isInitialLoading]=\"isLoading$ | async\"\n [alarms]=\"alarms$ | async\"\n [typeFilters]=\"typeFilters\"\n (onScrollingStateChange)=\"changeInterval(!$event)\"\n (onSelectedAlarm)=\"changeInterval(false)\"\n [splitView]=\"true\"\n [hasPermissions]=\"!isDisabled\"\n >\n <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n <c8y-alarms-interval-refresh\n [alarmsListLoading$]=\"isLoading$\"\n [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n (onCountdownEnded)=\"refresh()\"\n [isDisabled]=\"isDisabled\"\n ></c8y-alarms-interval-refresh>\n </ng-container>\n </c8y-alarms-list>\n\n <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: i5$1.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: i1$1.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: AlarmsIntervalRefreshComponent, selector: "c8y-alarms-interval-refresh", inputs: ["isDisabled", "alarmsListLoading$", "isIntervalToggleEnabled"], outputs: ["onCountdownEnded"] }, { kind: "component", type: AlarmsListComponent, selector: "c8y-alarms-list", inputs: ["alarms", "hasPermissions", "typeFilters", "loadMoreMode", "navigationOptions", "isInitialLoading", "splitView"], outputs: ["onSelectedAlarm", "onScrollingStateChange"] }, { kind: "component", type: AlarmsDateFilterComponent, selector: "c8y-alarms-date-filter", outputs: ["dateFilterChange"] }, { kind: "component", type: AlarmsTypeFilterComponent, selector: "c8y-alarms-type-filter", inputs: ["alarms"], outputs: ["onFilterChanged"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
2196
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: AlarmsComponent, selector: "c8y-alarms", providers: [AlarmWithChildrenRealtimeService], viewQueries: [{ propertyName: "alarmIntervalRefreshComponent", first: true, predicate: AlarmsIntervalRefreshComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-filter\n class=\"d-block fit-w\"\n [contextSourceId]=\"contextSourceId\"\n (onFilterApplied)=\"applyFormFilters($event)\"\n ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n>\n <c8y-alarms-type-filter\n class=\"d-block fit-w\"\n [alarms]=\"alarms$ | async\"\n (onFilterChanged)=\"applyTypeFilters($event)\"\n ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"0\"\n>\n <button\n class=\"btn btn-link\"\n [title]=\"'Clear all alarms' | translate\"\n type=\"button\"\n (click)=\"clearAll()\"\n data-cy=\"c8y-alarms-view--clear-all-button\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear all`alarms`' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"\n (isRealtimeActive | async)\n ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n : (REFRESH_LABEL | translate)\n \"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading$ | async\"\n (click)=\"refresh()\"\n >\n <span\n class=\"tag tag--info m-r-8\"\n *ngIf=\"isRealtimeActive | async\"\n >\n {{ 'New alarms' | translate }}\n </span>\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n ></i>\n </button>\n <button\n class=\"c8y-realtime btn btn-default btn-sm\"\n [attr.aria-label]=\"realtimeIconTitle\"\n [tooltip]=\"realtimeIconTitle\"\n placement=\"bottom\"\n type=\"button\"\n data-cy=\"c8y-alarms--realtime-button\"\n [container]=\"'body'\"\n (click)=\"toggleRealtimeState()\"\n >\n <span\n class=\"c8y-pulse m-0\"\n [ngClass]=\"{\n active: isRealtimeToggleOn,\n inactive: !isRealtimeToggleOn\n }\"\n ></span>\n </button>\n </div>\n</ng-template>\n\n<c8y-help\n src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n <c8y-alarms-list\n class=\"d-contents\"\n [isInitialLoading]=\"isLoading$ | async\"\n [alarms]=\"alarms$ | async\"\n [typeFilters]=\"typeFilters\"\n (onScrollingStateChange)=\"changeInterval(!$event)\"\n (onSelectedAlarm)=\"changeInterval(false)\"\n [splitView]=\"true\"\n [hasPermissions]=\"!isDisabled\"\n >\n <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n <c8y-alarms-interval-refresh\n [alarmsListLoading$]=\"isLoading$\"\n [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n (onCountdownEnded)=\"refresh()\"\n [isDisabled]=\"isDisabled\"\n ></c8y-alarms-interval-refresh>\n </ng-container>\n </c8y-alarms-list>\n\n <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: i5$1.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: i1$1.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: AlarmsIntervalRefreshComponent, selector: "c8y-alarms-interval-refresh", inputs: ["isDisabled", "alarmsListLoading$", "isIntervalToggleEnabled"], outputs: ["onCountdownEnded"] }, { kind: "component", type: AlarmsListComponent, selector: "c8y-alarms-list", inputs: ["alarms", "hasPermissions", "typeFilters", "loadMoreMode", "navigationOptions", "isInitialLoading", "splitView"], outputs: ["onSelectedAlarm", "onScrollingStateChange"] }, { kind: "component", type: AlarmsDateFilterComponent, selector: "c8y-alarms-date-filter", inputs: ["DEFAULT_INTERVAL", "updateQueryParams", "date"], outputs: ["dateFilterChange"] }, { kind: "component", type: AlarmsTypeFilterComponent, selector: "c8y-alarms-type-filter", inputs: ["alarms", "possibleFilters", "activeFilters"], outputs: ["onFilterChanged"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
2105
2197
  }
2106
2198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsComponent, decorators: [{
2107
2199
  type: Component,
2108
- args: [{ selector: 'c8y-alarms', providers: [AlarmWithChildrenRealtimeService], template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-filter\n [contextSourceId]=\"contextSourceId\"\n (onFilterApplied)=\"applyFormFilters($event)\"\n class=\"d-block fit-w\"\n ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item \n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n>\n <c8y-alarms-type-filter\n [alarms]=\"alarms$ | async\"\n (onFilterChanged)=\"applyTypeFilters($event)\"\n class=\"d-block fit-w\"\n ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"0\"\n>\n <button\n class=\"btn btn-link\"\n [title]=\"'Clear all alarms' | translate\"\n type=\"button\"\n (click)=\"clearAll()\"\n data-cy=\"c8y-alarms-view--clear-all-button\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear all`alarms`' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"\n (isRealtimeActive | async)\n ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n : (REFRESH_LABEL | translate)\n \"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading$ | async\"\n (click)=\"refresh()\"\n >\n <span\n class=\"tag tag--info m-r-8\"\n *ngIf=\"isRealtimeActive | async\"\n >\n {{ 'New alarms' | translate }}\n </span>\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n ></i>\n </button>\n <button\n class=\"c8y-realtime btn btn-default btn-sm\"\n [attr.aria-label]=\"realtimeIconTitle\"\n [tooltip]=\"realtimeIconTitle\"\n placement=\"bottom\"\n type=\"button\"\n [container]=\"'body'\"\n (click)=\"toggleRealtimeState()\"\n >\n <span\n class=\"c8y-pulse m-0\"\n [ngClass]=\"{\n active: isRealtimeToggleOn,\n inactive: !isRealtimeToggleOn\n }\"\n ></span>\n </button>\n </div>\n</ng-template>\n\n<c8y-help\n src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n <c8y-alarms-list\n class=\"d-contents\"\n [isInitialLoading]=\"isLoading$ | async\"\n [alarms]=\"alarms$ | async\"\n [typeFilters]=\"typeFilters\"\n (onScrollingStateChange)=\"changeInterval(!$event)\"\n (onSelectedAlarm)=\"changeInterval(false)\"\n [splitView]=\"true\"\n [hasPermissions]=\"!isDisabled\"\n >\n <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n <c8y-alarms-interval-refresh\n [alarmsListLoading$]=\"isLoading$\"\n [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n (onCountdownEnded)=\"refresh()\"\n [isDisabled]=\"isDisabled\"\n ></c8y-alarms-interval-refresh>\n </ng-container>\n </c8y-alarms-list>\n\n <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n" }]
2200
+ args: [{ selector: 'c8y-alarms', providers: [AlarmWithChildrenRealtimeService], template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-filter\n class=\"d-block fit-w\"\n [contextSourceId]=\"contextSourceId\"\n (onFilterApplied)=\"applyFormFilters($event)\"\n ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form min-width-fit\"\n>\n <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n>\n <c8y-alarms-type-filter\n class=\"d-block fit-w\"\n [alarms]=\"alarms$ | async\"\n (onFilterChanged)=\"applyTypeFilters($event)\"\n ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"0\"\n>\n <button\n class=\"btn btn-link\"\n [title]=\"'Clear all alarms' | translate\"\n type=\"button\"\n (click)=\"clearAll()\"\n data-cy=\"c8y-alarms-view--clear-all-button\"\n >\n <i c8yIcon=\"c8y-alert-idle\"></i>\n {{ 'Clear all`alarms`' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"\n (isRealtimeActive | async)\n ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n : (REFRESH_LABEL | translate)\n \"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading$ | async\"\n (click)=\"refresh()\"\n >\n <span\n class=\"tag tag--info m-r-8\"\n *ngIf=\"isRealtimeActive | async\"\n >\n {{ 'New alarms' | translate }}\n </span>\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n ></i>\n </button>\n <button\n class=\"c8y-realtime btn btn-default btn-sm\"\n [attr.aria-label]=\"realtimeIconTitle\"\n [tooltip]=\"realtimeIconTitle\"\n placement=\"bottom\"\n type=\"button\"\n data-cy=\"c8y-alarms--realtime-button\"\n [container]=\"'body'\"\n (click)=\"toggleRealtimeState()\"\n >\n <span\n class=\"c8y-pulse m-0\"\n [ngClass]=\"{\n active: isRealtimeToggleOn,\n inactive: !isRealtimeToggleOn\n }\"\n ></span>\n </button>\n </div>\n</ng-template>\n\n<c8y-help\n src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n <c8y-alarms-list\n class=\"d-contents\"\n [isInitialLoading]=\"isLoading$ | async\"\n [alarms]=\"alarms$ | async\"\n [typeFilters]=\"typeFilters\"\n (onScrollingStateChange)=\"changeInterval(!$event)\"\n (onSelectedAlarm)=\"changeInterval(false)\"\n [splitView]=\"true\"\n [hasPermissions]=\"!isDisabled\"\n >\n <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n <c8y-alarms-interval-refresh\n [alarmsListLoading$]=\"isLoading$\"\n [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n (onCountdownEnded)=\"refresh()\"\n [isDisabled]=\"isDisabled\"\n ></c8y-alarms-interval-refresh>\n </ng-container>\n </c8y-alarms-list>\n\n <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n" }]
2109
2201
  }], ctorParameters: () => [{ type: i1$1.ActivatedRoute }, { type: AlarmsViewService }, { type: i3.AlarmWithChildrenRealtimeService }, { type: i3.AlertService }, { type: i3.ContextRouteService }, { type: i3.ModalService }, { type: i1.TranslateService }, { type: i1$1.Router }], propDecorators: { alarmIntervalRefreshComponent: [{
2110
2202
  type: ViewChild,
2111
2203
  args: [AlarmsIntervalRefreshComponent]
2112
2204
  }] } });
2113
2205
 
2206
+ function getViewContextRoutes(contexts) {
2207
+ return contexts.map(context => ({
2208
+ context,
2209
+ path: 'details',
2210
+ icon: 'bell',
2211
+ label: gettext('Details'),
2212
+ component: AlarmInfoComponent,
2213
+ tabsOutlet: 'alarms'
2214
+ }));
2215
+ }
2216
+ function getChildrenForViewContext(context) {
2217
+ return [
2218
+ {
2219
+ path: '',
2220
+ component: AlarmEmptyComponent
2221
+ },
2222
+ {
2223
+ path: ':id',
2224
+ rootContext: context,
2225
+ component: ContextRouteComponent,
2226
+ canActivate: [ContextRouteGuard],
2227
+ data: { context, contextData: {} },
2228
+ resolve: {
2229
+ tabs: RouterTabsResolver
2230
+ }
2231
+ }
2232
+ ];
2233
+ }
2234
+
2114
2235
  const defaultAlarmsConfig = {
2115
2236
  hybrid: true
2116
2237
  };
@@ -2158,7 +2279,7 @@ class AlarmsModule {
2158
2279
  AlarmDetailsButtonPipe,
2159
2280
  AlarmSeverityToIconPipe,
2160
2281
  DynamicComponentModule,
2161
- IntervalPickerComponent], exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent] }); }
2282
+ IntervalPickerComponent], exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent, AlarmsDateFilterComponent] }); }
2162
2283
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: AlarmsModule, providers: [
2163
2284
  DatePipe,
2164
2285
  TitleCasePipe,
@@ -2201,7 +2322,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
2201
2322
  AlarmsDateFilterComponent,
2202
2323
  AlarmsTypeFilterComponent
2203
2324
  ],
2204
- exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent],
2325
+ exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent, AlarmsDateFilterComponent],
2205
2326
  providers: [
2206
2327
  DatePipe,
2207
2328
  TitleCasePipe,
@@ -2236,5 +2357,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
2236
2357
  * Generated bundle index. Do not edit.
2237
2358
  */
2238
2359
 
2239
- export { ALARMS_MODULE_CONFIG, ALARMS_PATH, ALARM_DEFAULT_PROPERTIES, ALARM_SEVERITY_ICON, ALARM_SEVERITY_ICON_MAP, ALARM_STATUS_ICON, AlarmDetailsButtonPipe, AlarmDetailsButtonService, AlarmDetailsComponent, AlarmDetailsService, AlarmEmptyComponent, AlarmIconMap, AlarmInfoComponent, AlarmListIndicatorPipe, AlarmListIndicatorService, AlarmSeveritiesToTitlePipe, AlarmSeverityToIconPipe, AlarmSeverityToLabelPipe, AlarmStatusToIconPipe, AlarmStatusToLabelPipe, AlarmsComponent, AlarmsFilterComponent, AlarmsIconComponent, AlarmsIntervalRefreshComponent, AlarmsListComponent, AlarmsModule, AlarmsViewService, AuditChangesMessagePipe, DEFAULT_ALARM_COUNTS, DEFAULT_SEVERITY_VALUES, DEFAULT_STATUS_VALUES, HELP_ICON, INTERVALS_EXTENDED, INTERVAL_TITLES_EXTENDED, Ng1SmartRulesUpgradeService, SmartRulesUpgradeServiceFactory, THROTTLE_REALTIME_REFRESH, smartRulesUpgradeServiceProvider };
2360
+ export { ALARMS_MODULE_CONFIG, ALARMS_PATH, ALARM_DEFAULT_PROPERTIES, ALARM_SEVERITY_ICON, ALARM_SEVERITY_ICON_MAP, ALARM_STATUS_ICON, AlarmDetailsButtonPipe, AlarmDetailsButtonService, AlarmDetailsComponent, AlarmDetailsService, AlarmEmptyComponent, AlarmIconMap, AlarmInfoComponent, AlarmListIndicatorPipe, AlarmListIndicatorService, AlarmSeveritiesToTitlePipe, AlarmSeverityToIconPipe, AlarmSeverityToLabelPipe, AlarmStatusToIconPipe, AlarmStatusToLabelPipe, AlarmsComponent, AlarmsDateFilterComponent, AlarmsFilterComponent, AlarmsIconComponent, AlarmsIntervalRefreshComponent, AlarmsListComponent, AlarmsModule, AlarmsViewService, AuditChangesMessagePipe, DEFAULT_ALARM_COUNTS, DEFAULT_SEVERITY_VALUES, DEFAULT_STATUS_VALUES, HELP_ICON, INTERVALS_EXTENDED, INTERVAL_TITLES_EXTENDED, Ng1SmartRulesUpgradeService, SmartRulesUpgradeServiceFactory, THROTTLE_REALTIME_REFRESH, getChildrenForViewContext, getViewContextRoutes, smartRulesUpgradeServiceProvider };
2240
2361
  //# sourceMappingURL=c8y-ngx-components-alarms.mjs.map