@c8y/ngx-components 1018.0.115 → 1018.0.125

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 (46) hide show
  1. package/context-dashboard/context-dashboard.model.d.ts +5 -0
  2. package/core/dashboard/dashboard.model.d.ts +5 -0
  3. package/ecosystem/application-plugins/plugin-list.component.d.ts +1 -1
  4. package/esm2020/context-dashboard/context-dashboard.component.mjs +3 -3
  5. package/esm2020/context-dashboard/context-dashboard.model.mjs +1 -1
  6. package/esm2020/context-dashboard/dashboard-detail.component.mjs +1 -1
  7. package/esm2020/core/common/group.service.mjs +2 -11
  8. package/esm2020/core/common/permissions.service.mjs +2 -4
  9. package/esm2020/core/dashboard/dashboard.model.mjs +1 -1
  10. package/esm2020/core/dashboard/widgets-dashboard.component.mjs +5 -4
  11. package/esm2020/core/realtime/measurement-realtime.service.mjs +4 -2
  12. package/esm2020/device-profile/device-profile.component.mjs +4 -2
  13. package/esm2020/ecosystem/application-plugins/plugin-list.component.mjs +15 -7
  14. package/esm2020/sub-assets/add-group/add-group.component.mjs +3 -4
  15. package/esm2020/sub-assets/sub-assets.component.mjs +2 -5
  16. package/esm2020/widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.mjs +2 -2
  17. package/fesm2015/c8y-ngx-components-context-dashboard.mjs +2 -2
  18. package/fesm2015/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  19. package/fesm2015/c8y-ngx-components-device-profile.mjs +3 -1
  20. package/fesm2015/c8y-ngx-components-device-profile.mjs.map +1 -1
  21. package/fesm2015/c8y-ngx-components-ecosystem-application-plugins.mjs +14 -8
  22. package/fesm2015/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  23. package/fesm2015/c8y-ngx-components-ecosystem.mjs +14 -8
  24. package/fesm2015/c8y-ngx-components-ecosystem.mjs.map +1 -1
  25. package/fesm2015/c8y-ngx-components-sub-assets.mjs +3 -7
  26. package/fesm2015/c8y-ngx-components-sub-assets.mjs.map +1 -1
  27. package/fesm2015/c8y-ngx-components-widgets-implementations-kpi.mjs +1 -1
  28. package/fesm2015/c8y-ngx-components-widgets-implementations-kpi.mjs.map +1 -1
  29. package/fesm2015/c8y-ngx-components.mjs +30 -35
  30. package/fesm2015/c8y-ngx-components.mjs.map +1 -1
  31. package/fesm2020/c8y-ngx-components-context-dashboard.mjs +2 -2
  32. package/fesm2020/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  33. package/fesm2020/c8y-ngx-components-device-profile.mjs +3 -1
  34. package/fesm2020/c8y-ngx-components-device-profile.mjs.map +1 -1
  35. package/fesm2020/c8y-ngx-components-ecosystem-application-plugins.mjs +14 -6
  36. package/fesm2020/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  37. package/fesm2020/c8y-ngx-components-ecosystem.mjs +14 -6
  38. package/fesm2020/c8y-ngx-components-ecosystem.mjs.map +1 -1
  39. package/fesm2020/c8y-ngx-components-sub-assets.mjs +3 -7
  40. package/fesm2020/c8y-ngx-components-sub-assets.mjs.map +1 -1
  41. package/fesm2020/c8y-ngx-components-widgets-implementations-kpi.mjs +1 -1
  42. package/fesm2020/c8y-ngx-components-widgets-implementations-kpi.mjs.map +1 -1
  43. package/fesm2020/c8y-ngx-components.mjs +30 -35
  44. package/fesm2020/c8y-ngx-components.mjs.map +1 -1
  45. package/package.json +1 -1
  46. package/widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.d.ts +2 -2
@@ -145,7 +145,7 @@ class KpiWidgetViewComponent {
145
145
  this.assignContextFromContextDashboard(datapoint);
146
146
  const latestMeasurement$ = this.getLatestMeasurement$(datapoint);
147
147
  const lastTwoValues$ = this.getLastTwoValuesOfObservable$(latestMeasurement$);
148
- const previousValue$ = lastTwoValues$.pipe(map(res => res[0]), startWith(undefined));
148
+ const previousValue$ = lastTwoValues$.pipe(map(([previousVal]) => previousVal), startWith(undefined));
149
149
  const unit$ = latestMeasurement$.pipe(map(latestMeasurementValue => datapoint.unit || latestMeasurementValue.unit || ''), startWith(''), distinctUntilChanged());
150
150
  return combineLatest([
151
151
  latestMeasurement$,
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-widgets-implementations-kpi.mjs","sources":["../../widgets/implementations/kpi/kpi-widget-config/kpi-widget-config.component.ts","../../widgets/implementations/kpi/kpi-widget-config/kpi-widget-config.component.html","../../widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.ts","../../widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.html","../../widgets/implementations/kpi/kpi-widget.module.ts","../../widgets/implementations/kpi/c8y-ngx-components-widgets-implementations-kpi.ts"],"sourcesContent":["import { Component, Input, OnInit } from '@angular/core';\nimport {\n AbstractControl,\n ControlContainer,\n FormBuilder,\n NgForm,\n ValidationErrors,\n ValidatorFn,\n Validators\n} from '@angular/forms';\nimport { OnBeforeSave } from '@c8y/ngx-components';\nimport { WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';\nimport {\n DatapointAttributesFormConfig,\n DatapointSelectorModalOptions,\n KPIDetails\n} from '@c8y/ngx-components/datapoint-selector';\nimport { IconSelectorService } from '@c8y/ngx-components/icon-selector';\nimport { Observable } from 'rxjs';\nimport { KpiWidgetConfig } from '../kpi-widget.model';\n\nexport function exactlyASingleDatapointActive(): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const datapoints: KPIDetails[] = control.value;\n\n if (!datapoints || !datapoints.length) {\n return null;\n }\n\n const activeDatapoints = datapoints.filter(datapoint => datapoint.__active);\n\n if (activeDatapoints.length === 1) {\n return null;\n }\n\n return { exactlyOneDatapointNeedsToBeActive: true };\n };\n}\n\n@Component({\n selector: 'c8y-kpi-widget-config',\n templateUrl: './kpi-widget-config.component.html',\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]\n})\nexport class KpiWidgetConfigComponent implements OnInit, OnBeforeSave {\n @Input() config: KpiWidgetConfig;\n datapointSelectionConfig: Partial<DatapointSelectorModalOptions> = {};\n defaultFormOptions: Partial<DatapointAttributesFormConfig> = {\n showRedRange: true,\n showYellowRange: true\n };\n formGroup: ReturnType<KpiWidgetConfigComponent['createForm']>;\n availableIcons: string[] = [];\n limits = {\n fontSizeMax: 72,\n fontSizeMin: 18,\n numberOfDecimalPlacesMax: 10,\n numberOfDecimalPlacesMin: 0\n };\n\n constructor(\n private formBuilder: FormBuilder,\n private form: NgForm,\n private iconSelector: IconSelectorService,\n private widgetConfig: WidgetConfigComponent\n ) {}\n\n onBeforeSave(config?: KpiWidgetConfig): boolean | Promise<boolean> | Observable<boolean> {\n if (this.formGroup.valid) {\n Object.assign(config, this.formGroup.value);\n return true;\n }\n return false;\n }\n\n async ngOnInit() {\n if (this.widgetConfig.context?.id) {\n this.datapointSelectionConfig.contextAsset = this.widgetConfig?.context;\n }\n this.initForm();\n if (this.config?.datapoints) {\n this.formGroup.patchValue({ datapoints: this.config.datapoints });\n }\n }\n\n async openIconSelector() {\n try {\n const icon = await this.iconSelector.selectIcon({\n currentSelection: this.formGroup.value.icon\n });\n this.formGroup.patchValue({ icon });\n } catch {\n // nothing to do\n }\n }\n\n private initForm(): void {\n this.formGroup = this.createForm();\n this.form.form.addControl('config', this.formGroup);\n this.formGroup.patchValue(this.config);\n }\n\n private createForm() {\n return this.formBuilder.group({\n numberOfDecimalPlaces: [\n 1,\n [\n Validators.required,\n Validators.min(this.limits.numberOfDecimalPlacesMin),\n Validators.max(this.limits.numberOfDecimalPlacesMax)\n ]\n ],\n showTimestamp: [true, []],\n showTrend: [true, []],\n showIcon: [true, []],\n icon: ['water', [Validators.required, Validators.minLength(1)]],\n fontSize: [\n 36,\n [\n Validators.required,\n Validators.min(this.limits.fontSizeMin),\n Validators.max(this.limits.fontSizeMax)\n ]\n ],\n datapoints: this.formBuilder.control(new Array<KPIDetails>(), [\n Validators.required,\n Validators.minLength(1),\n exactlyASingleDatapointActive()\n ])\n });\n }\n}\n","<div class=\"p-l-24 p-r-24\">\n <form [formGroup]=\"formGroup\" class=\"row no-card-context\">\n <div class=\"col-sm-6 bg-level-0\">\n <c8y-datapoint-selection-list\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"1\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapoints\"\n name=\"datapoints\"\n class=\"bg-inherit\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-sm-6\">\n <div class=\"card-header separator\">\n <div class=\"card-title h4\">{{ 'Layout' | translate }}</div>\n </div>\n <c8y-form-group class=\"p-t-8\">\n <label translate>Icon</label>\n <div class=\"d-flex a-i-center\">\n <div class=\"p-r-8 icon-32 text-muted\">\n <i [c8yIcon]=\"formGroup.value.icon\"></i>\n </div>\n <button\n class=\"btn btn-default btn-xs\"\n type=\"button\"\n title=\"{{ 'Change' | translate }}\"\n (click)=\"openIconSelector()\"\n >\n {{ 'Change' | translate }}\n </button>\n </div>\n </c8y-form-group>\n <c8y-form-group>\n <label [title]=\"'Number of decimal places' | translate\" translate>\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n formControlName=\"numberOfDecimalPlaces\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </c8y-form-group>\n <div>\n <label>{{ 'Display' | translate }}</label>\n <div class=\"d-flex gap-16 flex-wrap\">\n <c8y-form-group>\n <label [title]=\"'Show timestamp' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showTimestamp\" name=\"showTimestamp\" />\n <span></span>\n <span translate>Show timestamp</span>\n </label>\n </c8y-form-group>\n\n <c8y-form-group>\n <label [title]=\"'Show icon' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showIcon\" name=\"showIcon\" />\n <span></span>\n <span translate>Show icon</span>\n </label>\n </c8y-form-group>\n\n <c8y-form-group>\n <label [title]=\"'Show trend icon' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showTrend\" name=\"showTrend\" />\n <span></span>\n <span translate>Show trend icon</span>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'Indicates the trend between the last two measurement values.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n ></button>\n </label>\n </c8y-form-group>\n </div>\n\n <c8y-form-group>\n <label [title]=\"'Font size of measurement value (px)' | translate\" translate>\n Font size of measurement value (px)\n </label>\n <input\n class=\"form-control\"\n formControlName=\"fontSize\"\n name=\"fontSize\"\n type=\"number\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 36 }\"\n />\n <c8y-messages\n [show]=\"formGroup.controls?.fontSize?.touched && formGroup?.controls?.fontSize?.errors\"\n ></c8y-messages>\n </c8y-form-group>\n </div>\n </div>\n </form>\n</div>\n","import { Component, Input, OnInit, Optional } from '@angular/core';\nimport { MeasurementRealtimeService } from '@c8y/ngx-components';\nimport { KPIDetails } from '@c8y/ngx-components/datapoint-selector';\nimport { combineLatest, NEVER, Observable } from 'rxjs';\nimport { distinctUntilChanged, filter, map, pairwise, startWith, tap } from 'rxjs/operators';\nimport { ContextDashboardComponent } from '@c8y/ngx-components/context-dashboard';\nimport { KpiWidgetConfig } from '../kpi-widget.model';\n\ninterface MeasurementValue {\n unit?: string;\n value: number;\n date: string;\n}\n\nenum ColorClass {\n danger = 'text-danger',\n warning = 'text-warning',\n unknown = ''\n}\n\n@Component({\n selector: 'c8y-kpi-widget-view',\n templateUrl: './kpi-widget-view.component.html',\n providers: [MeasurementRealtimeService]\n})\nexport class KpiWidgetViewComponent implements OnInit {\n @Input() config: KpiWidgetConfig = { datapoints: [] };\n state$: Observable<{\n latestMeasurement: MeasurementValue;\n previousValue: MeasurementValue;\n trend: string;\n unit: string;\n colorClass: ColorClass;\n }> = NEVER;\n\n // used to differentiate between loading state and empty state\n noDataInitiallyInDB = false;\n\n constructor(\n private measurementRealtime: MeasurementRealtimeService,\n @Optional() private dashboard: ContextDashboardComponent\n ) {}\n\n async ngOnInit() {\n const datapoints = this.config.datapoints || [];\n const datapoint: KPIDetails = datapoints.find(tmp => tmp.__active);\n if (!datapoint) {\n return;\n }\n\n this.state$ = this.setupObservable(datapoint);\n }\n\n setupObservable(datapoint: KPIDetails): Observable<{\n latestMeasurement: MeasurementValue;\n previousValue: any;\n trend: string;\n unit: string;\n colorClass: ColorClass;\n }> {\n this.assignContextFromContextDashboard(datapoint);\n const latestMeasurement$ = this.getLatestMeasurement$(datapoint);\n const lastTwoValues$ = this.getLastTwoValuesOfObservable$(latestMeasurement$);\n\n const previousValue$ = lastTwoValues$.pipe(\n map(res => res[0]),\n startWith(undefined as any)\n );\n\n const unit$ = latestMeasurement$.pipe(\n map(latestMeasurementValue => datapoint.unit || latestMeasurementValue.unit || ''),\n startWith(''),\n distinctUntilChanged()\n );\n\n return combineLatest([\n latestMeasurement$,\n previousValue$,\n this.getTrendOfLatestMeasurements$(lastTwoValues$),\n unit$,\n this.getColorClass$(latestMeasurement$, datapoint)\n ]).pipe(\n map(([latestMeasurement, previousValue, trend, unit, colorClass]) => {\n return {\n latestMeasurement,\n previousValue,\n trend,\n unit,\n colorClass\n };\n })\n );\n }\n\n private getLatestMeasurement$(datapoint: KPIDetails): Observable<MeasurementValue> {\n return this.measurementRealtime\n .latestValueOfSpecificMeasurement$(\n datapoint.fragment,\n datapoint.series,\n datapoint.__target,\n // we only need the last two values in case we want to show a trend\n this.config.showTrend ? 2 : 1,\n // null will be emitted in case no measurement was found initially\n true\n )\n .pipe(\n tap(measurement => {\n if (!measurement) {\n this.noDataInitiallyInDB = true;\n }\n }),\n filter(measurement => !!measurement),\n map(measurement => {\n return {\n unit: measurement[datapoint.fragment][datapoint.series].unit,\n value: measurement[datapoint.fragment][datapoint.series].value,\n date: measurement.time as string\n };\n })\n );\n }\n\n private getColorClass$(\n measurementAndDatapointCombination$: Observable<MeasurementValue>,\n datapoint: KPIDetails\n ): Observable<ColorClass> {\n return measurementAndDatapointCombination$.pipe(\n map(latestMeasurementValue => {\n if (this.inRangeOf(datapoint, latestMeasurementValue.value, 'redRangeMin', 'redRangeMax')) {\n return ColorClass.danger;\n }\n\n if (\n this.inRangeOf(\n datapoint,\n latestMeasurementValue.value,\n 'yellowRangeMin',\n 'yellowRangeMax'\n )\n ) {\n return ColorClass.warning;\n }\n\n return ColorClass.unknown;\n }),\n startWith(ColorClass.unknown),\n distinctUntilChanged()\n );\n }\n\n private getLastTwoValuesOfObservable$<T>(input$: Observable<T>): Observable<T[]> {\n return input$.pipe(pairwise());\n }\n\n private getTrendOfLatestMeasurements$(latestMeasurement$: Observable<MeasurementValue[]>) {\n return latestMeasurement$.pipe(\n map(res => {\n if (res.length === 2) {\n const oldValue = res[0].value;\n const newValue = res[1].value;\n if (oldValue < newValue) {\n return '45deg';\n }\n if (oldValue > newValue) {\n return '135deg';\n }\n }\n return '90deg';\n }),\n startWith('90deg'),\n distinctUntilChanged()\n );\n }\n\n private inRangeOf(\n datapoint: KPIDetails,\n measurementValue: number,\n minAttribute: string,\n maxAttribute: string\n ): boolean {\n if (\n typeof datapoint[minAttribute] === 'number' &&\n typeof datapoint[maxAttribute] === 'number'\n ) {\n if (\n measurementValue >= datapoint[minAttribute] &&\n measurementValue < datapoint[maxAttribute]\n ) {\n return true;\n }\n }\n return false;\n }\n\n private assignContextFromContextDashboard(datapoint: KPIDetails) {\n if (!this.dashboard?.isDeviceTypeDashboard) {\n return;\n }\n const context = this.dashboard?.context;\n if (context?.id) {\n const { name, id } = context;\n datapoint.__target = { name, id };\n }\n }\n}\n","<div\n class=\"kpi-widget__container d-flex d-col fit-h fit-w a-i-center j-c-center\"\n *ngIf=\"state$ | async as lastState; else noMeasurementFound\"\n>\n <div class=\"d-flex a-i-center j-c-center fit-w\">\n <div\n class=\"m-r-16 flex-no-shrink text-muted\"\n [ngClass]=\"lastState.colorClass\"\n *ngIf=\"config.icon && config.showIcon\"\n >\n <i class=\"icon-32\" [c8yIcon]=\"config.icon\"></i>\n </div>\n <div class=\"text-truncate\">\n <span\n class=\"text-truncate text-medium\"\n [ngClass]=\"lastState.colorClass\"\n [ngStyle]=\"{ 'font-size': (config.fontSize || '36') + 'px' }\"\n title=\"{{\n lastState.colorClass === 'text-danger'\n ? ('Within red range:' | translate)\n : lastState.colorClass === 'text-warning'\n ? ('Within yellow range:' | translate)\n : ''\n }} {{\n lastState.latestMeasurement.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')\n }} {{ lastState.unit || '' }}\"\n >\n {{\n lastState.latestMeasurement.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')\n }}\n <small class=\"text-regular\">{{ lastState.unit || '' }}</small>\n </span>\n </div>\n <div\n class=\"dot dot-info dot-30 m-l-16 flex-no-shrink\"\n *ngIf=\"config?.showTrend && lastState.previousValue as previousValue\"\n >\n <i\n class=\"icon-20\"\n [title]=\"\n ('Previous value' | translate) +\n ': ' +\n (previousValue.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')) +\n ' (' +\n (previousValue.date | date: 'medium') +\n ')'\n \"\n c8yIcon=\"arrow-dotted-up\"\n [ngStyle]=\"{ transform: 'rotate(' + lastState.trend + ')' }\"\n ></i>\n </div>\n </div>\n <div class=\"d-flex j-c-center\">\n <p *ngIf=\"config?.showTimestamp\" class=\"icon-flex text-center text-muted small\">\n <i c8yIcon=\"calendar\"></i>\n {{ lastState.latestMeasurement.date | date: 'medium' }}\n </p>\n </div>\n</div>\n\n<ng-template #noMeasurementFound>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\">\n <c8y-ui-empty-state\n *ngIf=\"noDataInitiallyInDB\"\n class=\"fit-w\"\n [icon]=\"'line-chart'\"\n [title]=\"'No measurement to display.' | translate\"\n [subtitle]=\"'Waiting for measurements to be created.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n <c8y-loading *ngIf=\"!noDataInitiallyInDB\"></c8y-loading>\n </div>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { CoreModule } from '@c8y/ngx-components';\nimport { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';\nimport { IconSelectorModule } from '@c8y/ngx-components/icon-selector';\nimport { PopoverModule } from 'ngx-bootstrap/popover';\nimport { KpiWidgetConfigComponent } from './kpi-widget-config/kpi-widget-config.component';\nimport { KpiWidgetViewComponent } from './kpi-widget-view/kpi-widget-view.component';\n\n@NgModule({\n imports: [CoreModule, DatapointSelectorModule, IconSelectorModule, PopoverModule],\n declarations: [KpiWidgetViewComponent, KpiWidgetConfigComponent]\n})\nexport class KpiWidgetModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-widgets-implementations-kpi.mjs","sources":["../../widgets/implementations/kpi/kpi-widget-config/kpi-widget-config.component.ts","../../widgets/implementations/kpi/kpi-widget-config/kpi-widget-config.component.html","../../widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.ts","../../widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.html","../../widgets/implementations/kpi/kpi-widget.module.ts","../../widgets/implementations/kpi/c8y-ngx-components-widgets-implementations-kpi.ts"],"sourcesContent":["import { Component, Input, OnInit } from '@angular/core';\nimport {\n AbstractControl,\n ControlContainer,\n FormBuilder,\n NgForm,\n ValidationErrors,\n ValidatorFn,\n Validators\n} from '@angular/forms';\nimport { OnBeforeSave } from '@c8y/ngx-components';\nimport { WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';\nimport {\n DatapointAttributesFormConfig,\n DatapointSelectorModalOptions,\n KPIDetails\n} from '@c8y/ngx-components/datapoint-selector';\nimport { IconSelectorService } from '@c8y/ngx-components/icon-selector';\nimport { Observable } from 'rxjs';\nimport { KpiWidgetConfig } from '../kpi-widget.model';\n\nexport function exactlyASingleDatapointActive(): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const datapoints: KPIDetails[] = control.value;\n\n if (!datapoints || !datapoints.length) {\n return null;\n }\n\n const activeDatapoints = datapoints.filter(datapoint => datapoint.__active);\n\n if (activeDatapoints.length === 1) {\n return null;\n }\n\n return { exactlyOneDatapointNeedsToBeActive: true };\n };\n}\n\n@Component({\n selector: 'c8y-kpi-widget-config',\n templateUrl: './kpi-widget-config.component.html',\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]\n})\nexport class KpiWidgetConfigComponent implements OnInit, OnBeforeSave {\n @Input() config: KpiWidgetConfig;\n datapointSelectionConfig: Partial<DatapointSelectorModalOptions> = {};\n defaultFormOptions: Partial<DatapointAttributesFormConfig> = {\n showRedRange: true,\n showYellowRange: true\n };\n formGroup: ReturnType<KpiWidgetConfigComponent['createForm']>;\n availableIcons: string[] = [];\n limits = {\n fontSizeMax: 72,\n fontSizeMin: 18,\n numberOfDecimalPlacesMax: 10,\n numberOfDecimalPlacesMin: 0\n };\n\n constructor(\n private formBuilder: FormBuilder,\n private form: NgForm,\n private iconSelector: IconSelectorService,\n private widgetConfig: WidgetConfigComponent\n ) {}\n\n onBeforeSave(config?: KpiWidgetConfig): boolean | Promise<boolean> | Observable<boolean> {\n if (this.formGroup.valid) {\n Object.assign(config, this.formGroup.value);\n return true;\n }\n return false;\n }\n\n async ngOnInit() {\n if (this.widgetConfig.context?.id) {\n this.datapointSelectionConfig.contextAsset = this.widgetConfig?.context;\n }\n this.initForm();\n if (this.config?.datapoints) {\n this.formGroup.patchValue({ datapoints: this.config.datapoints });\n }\n }\n\n async openIconSelector() {\n try {\n const icon = await this.iconSelector.selectIcon({\n currentSelection: this.formGroup.value.icon\n });\n this.formGroup.patchValue({ icon });\n } catch {\n // nothing to do\n }\n }\n\n private initForm(): void {\n this.formGroup = this.createForm();\n this.form.form.addControl('config', this.formGroup);\n this.formGroup.patchValue(this.config);\n }\n\n private createForm() {\n return this.formBuilder.group({\n numberOfDecimalPlaces: [\n 1,\n [\n Validators.required,\n Validators.min(this.limits.numberOfDecimalPlacesMin),\n Validators.max(this.limits.numberOfDecimalPlacesMax)\n ]\n ],\n showTimestamp: [true, []],\n showTrend: [true, []],\n showIcon: [true, []],\n icon: ['water', [Validators.required, Validators.minLength(1)]],\n fontSize: [\n 36,\n [\n Validators.required,\n Validators.min(this.limits.fontSizeMin),\n Validators.max(this.limits.fontSizeMax)\n ]\n ],\n datapoints: this.formBuilder.control(new Array<KPIDetails>(), [\n Validators.required,\n Validators.minLength(1),\n exactlyASingleDatapointActive()\n ])\n });\n }\n}\n","<div class=\"p-l-24 p-r-24\">\n <form [formGroup]=\"formGroup\" class=\"row no-card-context\">\n <div class=\"col-sm-6 bg-level-0\">\n <c8y-datapoint-selection-list\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"1\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapoints\"\n name=\"datapoints\"\n class=\"bg-inherit\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-sm-6\">\n <div class=\"card-header separator\">\n <div class=\"card-title h4\">{{ 'Layout' | translate }}</div>\n </div>\n <c8y-form-group class=\"p-t-8\">\n <label translate>Icon</label>\n <div class=\"d-flex a-i-center\">\n <div class=\"p-r-8 icon-32 text-muted\">\n <i [c8yIcon]=\"formGroup.value.icon\"></i>\n </div>\n <button\n class=\"btn btn-default btn-xs\"\n type=\"button\"\n title=\"{{ 'Change' | translate }}\"\n (click)=\"openIconSelector()\"\n >\n {{ 'Change' | translate }}\n </button>\n </div>\n </c8y-form-group>\n <c8y-form-group>\n <label [title]=\"'Number of decimal places' | translate\" translate>\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n formControlName=\"numberOfDecimalPlaces\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </c8y-form-group>\n <div>\n <label>{{ 'Display' | translate }}</label>\n <div class=\"d-flex gap-16 flex-wrap\">\n <c8y-form-group>\n <label [title]=\"'Show timestamp' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showTimestamp\" name=\"showTimestamp\" />\n <span></span>\n <span translate>Show timestamp</span>\n </label>\n </c8y-form-group>\n\n <c8y-form-group>\n <label [title]=\"'Show icon' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showIcon\" name=\"showIcon\" />\n <span></span>\n <span translate>Show icon</span>\n </label>\n </c8y-form-group>\n\n <c8y-form-group>\n <label [title]=\"'Show trend icon' | translate\" class=\"c8y-checkbox\">\n <input type=\"checkbox\" formControlName=\"showTrend\" name=\"showTrend\" />\n <span></span>\n <span translate>Show trend icon</span>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'Indicates the trend between the last two measurement values.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n ></button>\n </label>\n </c8y-form-group>\n </div>\n\n <c8y-form-group>\n <label [title]=\"'Font size of measurement value (px)' | translate\" translate>\n Font size of measurement value (px)\n </label>\n <input\n class=\"form-control\"\n formControlName=\"fontSize\"\n name=\"fontSize\"\n type=\"number\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 36 }\"\n />\n <c8y-messages\n [show]=\"formGroup.controls?.fontSize?.touched && formGroup?.controls?.fontSize?.errors\"\n ></c8y-messages>\n </c8y-form-group>\n </div>\n </div>\n </form>\n</div>\n","import { Component, Input, OnInit, Optional } from '@angular/core';\nimport { MeasurementRealtimeService } from '@c8y/ngx-components';\nimport { KPIDetails } from '@c8y/ngx-components/datapoint-selector';\nimport { combineLatest, NEVER, Observable } from 'rxjs';\nimport { distinctUntilChanged, filter, map, pairwise, startWith, tap } from 'rxjs/operators';\nimport { ContextDashboardComponent } from '@c8y/ngx-components/context-dashboard';\nimport { KpiWidgetConfig } from '../kpi-widget.model';\n\ninterface MeasurementValue {\n unit?: string;\n value: number;\n date: string;\n}\n\nenum ColorClass {\n danger = 'text-danger',\n warning = 'text-warning',\n unknown = ''\n}\n\n@Component({\n selector: 'c8y-kpi-widget-view',\n templateUrl: './kpi-widget-view.component.html',\n providers: [MeasurementRealtimeService]\n})\nexport class KpiWidgetViewComponent implements OnInit {\n @Input() config: KpiWidgetConfig = { datapoints: [] };\n state$: Observable<{\n latestMeasurement: MeasurementValue;\n previousValue: MeasurementValue | undefined;\n trend: string;\n unit: string;\n colorClass: ColorClass;\n }> = NEVER;\n\n // used to differentiate between loading state and empty state\n noDataInitiallyInDB = false;\n\n constructor(\n private measurementRealtime: MeasurementRealtimeService,\n @Optional() private dashboard: ContextDashboardComponent\n ) {}\n\n async ngOnInit() {\n const datapoints = this.config.datapoints || [];\n const datapoint: KPIDetails = datapoints.find(tmp => tmp.__active);\n if (!datapoint) {\n return;\n }\n\n this.state$ = this.setupObservable(datapoint);\n }\n\n setupObservable(datapoint: KPIDetails): Observable<{\n latestMeasurement: MeasurementValue;\n previousValue: MeasurementValue | undefined;\n trend: string;\n unit: string;\n colorClass: ColorClass;\n }> {\n this.assignContextFromContextDashboard(datapoint);\n const latestMeasurement$ = this.getLatestMeasurement$(datapoint);\n const lastTwoValues$ = this.getLastTwoValuesOfObservable$(latestMeasurement$);\n\n const previousValue$ = lastTwoValues$.pipe(\n map(([previousVal]) => previousVal),\n startWith(undefined as MeasurementValue | undefined)\n );\n\n const unit$ = latestMeasurement$.pipe(\n map(latestMeasurementValue => datapoint.unit || latestMeasurementValue.unit || ''),\n startWith(''),\n distinctUntilChanged()\n );\n\n return combineLatest([\n latestMeasurement$,\n previousValue$,\n this.getTrendOfLatestMeasurements$(lastTwoValues$),\n unit$,\n this.getColorClass$(latestMeasurement$, datapoint)\n ]).pipe(\n map(([latestMeasurement, previousValue, trend, unit, colorClass]) => {\n return {\n latestMeasurement,\n previousValue,\n trend,\n unit,\n colorClass\n };\n })\n );\n }\n\n private getLatestMeasurement$(datapoint: KPIDetails): Observable<MeasurementValue> {\n return this.measurementRealtime\n .latestValueOfSpecificMeasurement$(\n datapoint.fragment,\n datapoint.series,\n datapoint.__target,\n // we only need the last two values in case we want to show a trend\n this.config.showTrend ? 2 : 1,\n // null will be emitted in case no measurement was found initially\n true\n )\n .pipe(\n tap(measurement => {\n if (!measurement) {\n this.noDataInitiallyInDB = true;\n }\n }),\n filter(measurement => !!measurement),\n map(measurement => {\n return {\n unit: measurement[datapoint.fragment][datapoint.series].unit,\n value: measurement[datapoint.fragment][datapoint.series].value,\n date: measurement.time as string\n };\n })\n );\n }\n\n private getColorClass$(\n measurementAndDatapointCombination$: Observable<MeasurementValue>,\n datapoint: KPIDetails\n ): Observable<ColorClass> {\n return measurementAndDatapointCombination$.pipe(\n map(latestMeasurementValue => {\n if (this.inRangeOf(datapoint, latestMeasurementValue.value, 'redRangeMin', 'redRangeMax')) {\n return ColorClass.danger;\n }\n\n if (\n this.inRangeOf(\n datapoint,\n latestMeasurementValue.value,\n 'yellowRangeMin',\n 'yellowRangeMax'\n )\n ) {\n return ColorClass.warning;\n }\n\n return ColorClass.unknown;\n }),\n startWith(ColorClass.unknown),\n distinctUntilChanged()\n );\n }\n\n private getLastTwoValuesOfObservable$<T>(input$: Observable<T>): Observable<T[]> {\n return input$.pipe(pairwise());\n }\n\n private getTrendOfLatestMeasurements$(latestMeasurement$: Observable<MeasurementValue[]>) {\n return latestMeasurement$.pipe(\n map(res => {\n if (res.length === 2) {\n const oldValue = res[0].value;\n const newValue = res[1].value;\n if (oldValue < newValue) {\n return '45deg';\n }\n if (oldValue > newValue) {\n return '135deg';\n }\n }\n return '90deg';\n }),\n startWith('90deg'),\n distinctUntilChanged()\n );\n }\n\n private inRangeOf(\n datapoint: KPIDetails,\n measurementValue: number,\n minAttribute: string,\n maxAttribute: string\n ): boolean {\n if (\n typeof datapoint[minAttribute] === 'number' &&\n typeof datapoint[maxAttribute] === 'number'\n ) {\n if (\n measurementValue >= datapoint[minAttribute] &&\n measurementValue < datapoint[maxAttribute]\n ) {\n return true;\n }\n }\n return false;\n }\n\n private assignContextFromContextDashboard(datapoint: KPIDetails) {\n if (!this.dashboard?.isDeviceTypeDashboard) {\n return;\n }\n const context = this.dashboard?.context;\n if (context?.id) {\n const { name, id } = context;\n datapoint.__target = { name, id };\n }\n }\n}\n","<div\n class=\"kpi-widget__container d-flex d-col fit-h fit-w a-i-center j-c-center\"\n *ngIf=\"state$ | async as lastState; else noMeasurementFound\"\n>\n <div class=\"d-flex a-i-center j-c-center fit-w\">\n <div\n class=\"m-r-16 flex-no-shrink text-muted\"\n [ngClass]=\"lastState.colorClass\"\n *ngIf=\"config.icon && config.showIcon\"\n >\n <i class=\"icon-32\" [c8yIcon]=\"config.icon\"></i>\n </div>\n <div class=\"text-truncate\">\n <span\n class=\"text-truncate text-medium\"\n [ngClass]=\"lastState.colorClass\"\n [ngStyle]=\"{ 'font-size': (config.fontSize || '36') + 'px' }\"\n title=\"{{\n lastState.colorClass === 'text-danger'\n ? ('Within red range:' | translate)\n : lastState.colorClass === 'text-warning'\n ? ('Within yellow range:' | translate)\n : ''\n }} {{\n lastState.latestMeasurement.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')\n }} {{ lastState.unit || '' }}\"\n >\n {{\n lastState.latestMeasurement.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')\n }}\n <small class=\"text-regular\">{{ lastState.unit || '' }}</small>\n </span>\n </div>\n <div\n class=\"dot dot-info dot-30 m-l-16 flex-no-shrink\"\n *ngIf=\"config?.showTrend && lastState.previousValue as previousValue\"\n >\n <i\n class=\"icon-20\"\n [title]=\"\n ('Previous value' | translate) +\n ': ' +\n (previousValue.value\n | number\n : '1.' +\n (config.numberOfDecimalPlaces || '0') +\n '-' +\n (config.numberOfDecimalPlaces || '0')) +\n ' (' +\n (previousValue.date | date: 'medium') +\n ')'\n \"\n c8yIcon=\"arrow-dotted-up\"\n [ngStyle]=\"{ transform: 'rotate(' + lastState.trend + ')' }\"\n ></i>\n </div>\n </div>\n <div class=\"d-flex j-c-center\">\n <p *ngIf=\"config?.showTimestamp\" class=\"icon-flex text-center text-muted small\">\n <i c8yIcon=\"calendar\"></i>\n {{ lastState.latestMeasurement.date | date: 'medium' }}\n </p>\n </div>\n</div>\n\n<ng-template #noMeasurementFound>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\">\n <c8y-ui-empty-state\n *ngIf=\"noDataInitiallyInDB\"\n class=\"fit-w\"\n [icon]=\"'line-chart'\"\n [title]=\"'No measurement to display.' | translate\"\n [subtitle]=\"'Waiting for measurements to be created.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n <c8y-loading *ngIf=\"!noDataInitiallyInDB\"></c8y-loading>\n </div>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { CoreModule } from '@c8y/ngx-components';\nimport { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';\nimport { IconSelectorModule } from '@c8y/ngx-components/icon-selector';\nimport { PopoverModule } from 'ngx-bootstrap/popover';\nimport { KpiWidgetConfigComponent } from './kpi-widget-config/kpi-widget-config.component';\nimport { KpiWidgetViewComponent } from './kpi-widget-view/kpi-widget-view.component';\n\n@NgModule({\n imports: [CoreModule, DatapointSelectorModule, IconSelectorModule, PopoverModule],\n declarations: [KpiWidgetViewComponent, KpiWidgetConfigComponent]\n})\nexport class KpiWidgetModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3"],"mappings":";;;;;;;;;;;;;;;;;SAqBgB,6BAA6B,GAAA;IAC3C,OAAO,CAAC,OAAwB,KAA6B;AAC3D,QAAA,MAAM,UAAU,GAAiB,OAAO,CAAC,KAAK,CAAC;AAE/C,QAAA,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;AACrC,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AAED,QAAA,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE5E,QAAA,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;AACjC,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AAED,QAAA,OAAO,EAAE,kCAAkC,EAAE,IAAI,EAAE,CAAC;AACtD,KAAC,CAAC;AACJ,CAAC;MAOY,wBAAwB,CAAA;AAgBnC,IAAA,WAAA,CACU,WAAwB,EACxB,IAAY,EACZ,YAAiC,EACjC,YAAmC,EAAA;QAHnC,IAAW,CAAA,WAAA,GAAX,WAAW,CAAa;QACxB,IAAI,CAAA,IAAA,GAAJ,IAAI,CAAQ;QACZ,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAqB;QACjC,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAuB;QAlB7C,IAAwB,CAAA,wBAAA,GAA2C,EAAE,CAAC;AACtE,QAAA,IAAA,CAAA,kBAAkB,GAA2C;AAC3D,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,eAAe,EAAE,IAAI;SACtB,CAAC;QAEF,IAAc,CAAA,cAAA,GAAa,EAAE,CAAC;AAC9B,QAAA,IAAA,CAAA,MAAM,GAAG;AACP,YAAA,WAAW,EAAE,EAAE;AACf,YAAA,WAAW,EAAE,EAAE;AACf,YAAA,wBAAwB,EAAE,EAAE;AAC5B,YAAA,wBAAwB,EAAE,CAAC;SAC5B,CAAC;KAOE;AAEJ,IAAA,YAAY,CAAC,MAAwB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;YACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC5C,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AACD,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE;YACjC,IAAI,CAAC,wBAAwB,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;AACzE,SAAA;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;AAChB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE;AAC3B,YAAA,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;AACnE,SAAA;KACF;AAED,IAAA,MAAM,gBAAgB,GAAA;QACpB,IAAI;YACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;AAC9C,gBAAA,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI;AAC5C,aAAA,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AACrC,SAAA;QAAC,MAAM;;AAEP,SAAA;KACF;IAEO,QAAQ,GAAA;AACd,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AACnC,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;KACxC;IAEO,UAAU,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC5B,YAAA,qBAAqB,EAAE;gBACrB,CAAC;AACD,gBAAA;AACE,oBAAA,UAAU,CAAC,QAAQ;oBACnB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC;oBACpD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC;AACrD,iBAAA;AACF,aAAA;AACD,YAAA,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AACzB,YAAA,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AACrB,YAAA,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AACpB,YAAA,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,YAAA,QAAQ,EAAE;gBACR,EAAE;AACF,gBAAA;AACE,oBAAA,UAAU,CAAC,QAAQ;oBACnB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;oBACvC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;AACxC,iBAAA;AACF,aAAA;YACD,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,EAAc,EAAE;AAC5D,gBAAA,UAAU,CAAC,QAAQ;AACnB,gBAAA,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AACvB,gBAAA,6BAA6B,EAAE;aAChC,CAAC;AACH,SAAA,CAAC,CAAC;KACJ;;qHAtFU,wBAAwB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,WAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAxB,wBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,wBAAwB,EC5CrC,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,shIA6GA,EDnEiB,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iCAAA,EAAA,QAAA,EAAA,yCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,+BAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,mBAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,WAAA,EAAA,cAAA,EAAA,UAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,aAAA,EAAA,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAA,CAAA,CAAA;2FAExD,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBALpC,SAAS;+BACE,uBAAuB,EAAA,aAAA,EAElB,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAA,QAAA,EAAA,shIAAA,EAAA,CAAA;6LAG1D,MAAM,EAAA,CAAA;sBAAd,KAAK;;;AE/BR,IAAK,UAIJ,CAAA;AAJD,CAAA,UAAK,UAAU,EAAA;AACb,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,aAAsB,CAAA;AACtB,IAAA,UAAA,CAAA,SAAA,CAAA,GAAA,cAAwB,CAAA;AACxB,IAAA,UAAA,CAAA,SAAA,CAAA,GAAA,EAAY,CAAA;AACd,CAAC,EAJI,UAAU,KAAV,UAAU,GAId,EAAA,CAAA,CAAA,CAAA;MAOY,sBAAsB,CAAA;IAajC,WACU,CAAA,mBAA+C,EACnC,SAAoC,EAAA;QADhD,IAAmB,CAAA,mBAAA,GAAnB,mBAAmB,CAA4B;QACnC,IAAS,CAAA,SAAA,GAAT,SAAS,CAA2B;AAdjD,QAAA,IAAA,CAAA,MAAM,GAAoB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACtD,IAAM,CAAA,MAAA,GAMD,KAAK,CAAC;;QAGX,IAAmB,CAAA,mBAAA,GAAG,KAAK,CAAC;KAKxB;AAEJ,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;AAChD,QAAA,MAAM,SAAS,GAAe,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,EAAE;YACd,OAAO;AACR,SAAA;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;KAC/C;AAED,IAAA,eAAe,CAAC,SAAqB,EAAA;AAOnC,QAAA,IAAI,CAAC,iCAAiC,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,IAAI,CAAC,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;QAE9E,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CACxC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,WAAW,CAAC,EACnC,SAAS,CAAC,SAAyC,CAAC,CACrD,CAAC;AAEF,QAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CACnC,GAAG,CAAC,sBAAsB,IAAI,SAAS,CAAC,IAAI,IAAI,sBAAsB,CAAC,IAAI,IAAI,EAAE,CAAC,EAClF,SAAS,CAAC,EAAE,CAAC,EACb,oBAAoB,EAAE,CACvB,CAAC;AAEF,QAAA,OAAO,aAAa,CAAC;YACnB,kBAAkB;YAClB,cAAc;AACd,YAAA,IAAI,CAAC,6BAA6B,CAAC,cAAc,CAAC;YAClD,KAAK;AACL,YAAA,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,SAAS,CAAC;AACnD,SAAA,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,CAAC,CAAC,iBAAiB,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,KAAI;YAClE,OAAO;gBACL,iBAAiB;gBACjB,aAAa;gBACb,KAAK;gBACL,IAAI;gBACJ,UAAU;aACX,CAAC;SACH,CAAC,CACH,CAAC;KACH;AAEO,IAAA,qBAAqB,CAAC,SAAqB,EAAA;QACjD,OAAO,IAAI,CAAC,mBAAmB;aAC5B,iCAAiC,CAChC,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,MAAM,EAChB,SAAS,CAAC,QAAQ;;QAElB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC;;AAE7B,QAAA,IAAI,CACL;AACA,aAAA,IAAI,CACH,GAAG,CAAC,WAAW,IAAG;YAChB,IAAI,CAAC,WAAW,EAAE;AAChB,gBAAA,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;AACjC,aAAA;AACH,SAAC,CAAC,EACF,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,EACpC,GAAG,CAAC,WAAW,IAAG;YAChB,OAAO;AACL,gBAAA,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI;AAC5D,gBAAA,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK;gBAC9D,IAAI,EAAE,WAAW,CAAC,IAAc;aACjC,CAAC;SACH,CAAC,CACH,CAAC;KACL;IAEO,cAAc,CACpB,mCAAiE,EACjE,SAAqB,EAAA;QAErB,OAAO,mCAAmC,CAAC,IAAI,CAC7C,GAAG,CAAC,sBAAsB,IAAG;AAC3B,YAAA,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE;gBACzF,OAAO,UAAU,CAAC,MAAM,CAAC;AAC1B,aAAA;AAED,YAAA,IACE,IAAI,CAAC,SAAS,CACZ,SAAS,EACT,sBAAsB,CAAC,KAAK,EAC5B,gBAAgB,EAChB,gBAAgB,CACjB,EACD;gBACA,OAAO,UAAU,CAAC,OAAO,CAAC;AAC3B,aAAA;YAED,OAAO,UAAU,CAAC,OAAO,CAAC;AAC5B,SAAC,CAAC,EACF,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAC7B,oBAAoB,EAAE,CACvB,CAAC;KACH;AAEO,IAAA,6BAA6B,CAAI,MAAqB,EAAA;AAC5D,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;KAChC;AAEO,IAAA,6BAA6B,CAAC,kBAAkD,EAAA;QACtF,OAAO,kBAAkB,CAAC,IAAI,CAC5B,GAAG,CAAC,GAAG,IAAG;AACR,YAAA,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE;gBACpB,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC9B,IAAI,QAAQ,GAAG,QAAQ,EAAE;AACvB,oBAAA,OAAO,OAAO,CAAC;AAChB,iBAAA;gBACD,IAAI,QAAQ,GAAG,QAAQ,EAAE;AACvB,oBAAA,OAAO,QAAQ,CAAC;AACjB,iBAAA;AACF,aAAA;AACD,YAAA,OAAO,OAAO,CAAC;SAChB,CAAC,EACF,SAAS,CAAC,OAAO,CAAC,EAClB,oBAAoB,EAAE,CACvB,CAAC;KACH;AAEO,IAAA,SAAS,CACf,SAAqB,EACrB,gBAAwB,EACxB,YAAoB,EACpB,YAAoB,EAAA;AAEpB,QAAA,IACE,OAAO,SAAS,CAAC,YAAY,CAAC,KAAK,QAAQ;AAC3C,YAAA,OAAO,SAAS,CAAC,YAAY,CAAC,KAAK,QAAQ,EAC3C;AACA,YAAA,IACE,gBAAgB,IAAI,SAAS,CAAC,YAAY,CAAC;AAC3C,gBAAA,gBAAgB,GAAG,SAAS,CAAC,YAAY,CAAC,EAC1C;AACA,gBAAA,OAAO,IAAI,CAAC;AACb,aAAA;AACF,SAAA;AACD,QAAA,OAAO,KAAK,CAAC;KACd;AAEO,IAAA,iCAAiC,CAAC,SAAqB,EAAA;AAC7D,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,EAAE;YAC1C,OAAO;AACR,SAAA;AACD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;QACxC,IAAI,OAAO,EAAE,EAAE,EAAE;AACf,YAAA,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;YAC7B,SAAS,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACnC,SAAA;KACF;;mHAlLU,sBAAsB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,EAAA,CAAA,0BAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,EAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,sBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,EAFtB,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,SAAA,EAAA,CAAC,0BAA0B,CAAC,0BCvBzC,29FAwFA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAF,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,CAAA;2FD/Da,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBALlC,SAAS;+BACE,qBAAqB,EAAA,SAAA,EAEpB,CAAC,0BAA0B,CAAC,EAAA,QAAA,EAAA,29FAAA,EAAA,CAAA;;0BAiBpC,QAAQ;4CAdF,MAAM,EAAA,CAAA;sBAAd,KAAK;;;MEdK,eAAe,CAAA;;4GAAf,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;6GAAf,eAAe,EAAA,YAAA,EAAA,CAFX,sBAAsB,EAAE,wBAAwB,CAAA,EAAA,OAAA,EAAA,CADrD,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,aAAa,CAAA,EAAA,CAAA,CAAA;AAGrE,eAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,YAHhB,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,aAAa,CAAA,EAAA,CAAA,CAAA;2FAGrE,eAAe,EAAA,UAAA,EAAA,CAAA;kBAJ3B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,OAAO,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,aAAa,CAAC;AACjF,oBAAA,YAAY,EAAE,CAAC,sBAAsB,EAAE,wBAAwB,CAAC;AACjE,iBAAA,CAAA;;;ACXD;;AAEG;;;;"}
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Pipe, Injectable, InjectFlags, InjectionToken, Optional, Inject, isDevMode, EventEmitter, Directive, NgModule, LOCALE_ID, HostListener, Input, Component, Output, HostBinding, forwardRef, TemplateRef, SecurityContext, APP_INITIALIZER, Self, SkipSelf, NgModuleRef, createNgModuleRef, ViewChild, ContentChild, Attribute, ViewContainerRef, ContentChildren, ElementRef, Host, ViewChildren, Injector, importProvidersFrom, ChangeDetectionStrategy, SimpleChange, Type } from '@angular/core';
3
- import { isNaN as isNaN$1, isFinite, castArray, flatten, uniq, sortBy, groupBy, camelCase, isUndefined, throttle as throttle$1, keys, get, each, mapValues, mapKeys, isString, forEach, assign, memoize as memoize$1, find, negate, upperFirst, property as property$1, some, entries, omitBy, min, every, first as first$1, map as map$1, orderBy, flatMap, isEmpty, reduce, union, filter as filter$1, isEqual, snakeCase, matches, cloneDeep, uniqBy, clone, toNumber, isEqualWith, escape as escape$1, escapeRegExp, assignWith, set, findIndex, omit, pick, transform, identity, flow, isNil, chunk, without, indexOf, parseInt as parseInt$1, kebabCase, forOwn } from 'lodash-es';
3
+ import { isNaN as isNaN$1, isFinite, castArray, flatten, uniq, sortBy, groupBy, camelCase, isUndefined, throttle as throttle$1, keys, get, each, mapValues, mapKeys, isString, forEach, assign, find, negate, upperFirst, memoize as memoize$1, property, some, entries, omitBy, min, every, first as first$1, map as map$1, orderBy, flatMap, isEmpty, reduce, union, filter as filter$1, isEqual, snakeCase, matches, cloneDeep, uniqBy, clone, toNumber, isEqualWith, escape as escape$1, escapeRegExp, assignWith, set, findIndex, omit, pick, transform, identity, flow, isNil, chunk, without, indexOf, parseInt as parseInt$1, kebabCase, forOwn } from 'lodash-es';
4
4
  import { merge, of, defer, combineLatest, race, isObservable, from, Subject, BehaviorSubject, NEVER, fromEvent, pipe, concat, throwError, Observable, EMPTY, timer, fromEventPattern, empty, forkJoin, ReplaySubject } from 'rxjs';
5
5
  import { map, distinctUntilChanged, filter, startWith, switchMap, scan, take, shareReplay, debounceTime, tap, catchError, takeUntil, mergeMap, first, share, retryWhen, delay, concatMap, debounce, sample, withLatestFrom, every as every$1, toArray, merge as merge$1, expand, finalize } from 'rxjs/operators';
6
6
  import * as i2 from '@angular/cdk/scrolling';
@@ -26,7 +26,6 @@ import * as i6 from 'ngx-bootstrap/datepicker';
26
26
  import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
27
27
  import { defineLocale, enGbLocale, zhCnLocale, ruLocale, ptBrLocale, plLocale, nlLocale, koLocale, jaLocale, frLocale, esLocale, deLocale } from 'ngx-bootstrap/chronos';
28
28
  import { coerceNumberProperty } from '@angular/cdk/coercion';
29
- import { property, sortBy as sortBy$1, isEmpty as isEmpty$1, flatten as flatten$1, get as get$1, set as set$1, pick as pick$1 } from 'lodash';
30
29
  import * as i1$4 from '@angular/platform-browser';
31
30
  import { saveAs } from 'file-saver';
32
31
  import * as i1$5 from 'ngx-bootstrap/dropdown';
@@ -35,6 +34,7 @@ import * as i6$1 from '@angular/cdk/a11y';
35
34
  import { A11yModule } from '@angular/cdk/a11y';
36
35
  import * as i1$a from 'ngx-bootstrap/collapse';
37
36
  import { CollapseModule } from 'ngx-bootstrap/collapse';
37
+ import { sortBy as sortBy$1, isEmpty as isEmpty$1, flatten as flatten$1, get as get$1, set as set$1, pick as pick$1 } from 'lodash';
38
38
  import * as i1$8 from 'ngx-bootstrap/modal';
39
39
  import { ModalModule as ModalModule$1, BsModalRef } from 'ngx-bootstrap/modal';
40
40
  import * as i5 from '@angular/forms';
@@ -4870,23 +4870,6 @@ var GroupFragment;
4870
4870
  GroupFragment["dynamicGroupQueryString"] = "c8y_DeviceQueryString";
4871
4871
  })(GroupFragment || (GroupFragment = {}));
4872
4872
 
4873
- /**
4874
- * Decorator to memoize function results.
4875
- * @param resolver Cache key resolver function, used by memoize from lodash.
4876
- */
4877
- function memoize(resolver) {
4878
- return (target, fnName, descriptor) => {
4879
- const fn = descriptor.value;
4880
- descriptor.value = function (...args) {
4881
- const memoizedFnName = `_${fnName}Memoized`;
4882
- if (!this[memoizedFnName]) {
4883
- this[memoizedFnName] = memoize$1(fn, resolver);
4884
- }
4885
- return this[memoizedFnName](...args);
4886
- };
4887
- };
4888
- }
4889
-
4890
4873
  const MO_TYPES = [
4891
4874
  'asset',
4892
4875
  'dynamicGroup',
@@ -5024,18 +5007,12 @@ class GroupService {
5024
5007
  }
5025
5008
  GroupService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GroupService, deps: [{ token: AssetTypesService }], target: i0.ɵɵFactoryTarget.Injectable });
5026
5009
  GroupService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GroupService, providedIn: 'root' });
5027
- __decorate([
5028
- memoize(property('id')),
5029
- __metadata("design:type", Function),
5030
- __metadata("design:paramtypes", [Object, Object]),
5031
- __metadata("design:returntype", Promise)
5032
- ], GroupService.prototype, "getIcon", null);
5033
5010
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GroupService, decorators: [{
5034
5011
  type: Injectable,
5035
5012
  args: [{
5036
5013
  providedIn: 'root'
5037
5014
  }]
5038
- }], ctorParameters: function () { return [{ type: AssetTypesService }]; }, propDecorators: { getIcon: [] } });
5015
+ }], ctorParameters: function () { return [{ type: AssetTypesService }]; } });
5039
5016
 
5040
5017
  class GetGroupIconPipe {
5041
5018
  constructor(groupService) {
@@ -5141,6 +5118,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
5141
5118
  args: [{ name: 'humanize' }]
5142
5119
  }] });
5143
5120
 
5121
+ /**
5122
+ * Decorator to memoize function results.
5123
+ * @param resolver Cache key resolver function, used by memoize from lodash.
5124
+ */
5125
+ function memoize(resolver) {
5126
+ return (target, fnName, descriptor) => {
5127
+ const fn = descriptor.value;
5128
+ descriptor.value = function (...args) {
5129
+ const memoizedFnName = `_${fnName}Memoized`;
5130
+ if (!this[memoizedFnName]) {
5131
+ this[memoizedFnName] = memoize$1(fn, resolver);
5132
+ }
5133
+ return this[memoizedFnName](...args);
5134
+ };
5135
+ };
5136
+ }
5137
+
5144
5138
  class Permissions {
5145
5139
  constructor(appState, inventory, user) {
5146
5140
  this.appState = appState;
@@ -5201,11 +5195,9 @@ class Permissions {
5201
5195
  return currentUserName === data.owner;
5202
5196
  }
5203
5197
  checkWithRequest(mo) {
5204
- const moName = mo.name;
5205
5198
  const moId = mo.id;
5206
5199
  const partialUpdateObject = {
5207
- id: moId,
5208
- name: moName
5200
+ id: moId
5209
5201
  };
5210
5202
  return this.inventory
5211
5203
  .update(partialUpdateObject)
@@ -5232,13 +5224,13 @@ class Permissions {
5232
5224
  Permissions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: Permissions, deps: [{ token: AppStateService }, { token: i1$1.InventoryService }, { token: i1$1.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
5233
5225
  Permissions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: Permissions, providedIn: 'root' });
5234
5226
  __decorate([
5235
- memoize(property$1('id')),
5227
+ memoize(property('id')),
5236
5228
  __metadata("design:type", Function),
5237
5229
  __metadata("design:paramtypes", [Object]),
5238
5230
  __metadata("design:returntype", Promise)
5239
5231
  ], Permissions.prototype, "checkIfOwner", null);
5240
5232
  __decorate([
5241
- memoize(property$1('id')),
5233
+ memoize(property('id')),
5242
5234
  __metadata("design:type", Function),
5243
5235
  __metadata("design:paramtypes", [Object]),
5244
5236
  __metadata("design:returntype", void 0)
@@ -24461,7 +24453,8 @@ class WidgetsDashboardComponent {
24461
24453
  allowFullscreen: false,
24462
24454
  canCopy: true,
24463
24455
  canDelete: true,
24464
- isLoading: false
24456
+ isLoading: false,
24457
+ columns: 12
24465
24458
  };
24466
24459
  this.onAddWidget = new EventEmitter();
24467
24460
  this.onEditWidget = new EventEmitter();
@@ -24553,7 +24546,7 @@ class WidgetsDashboardComponent {
24553
24546
  }
24554
24547
  }
24555
24548
  WidgetsDashboardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: WidgetsDashboardComponent, deps: [{ token: DynamicComponentService }], target: i0.ɵɵFactoryTarget.Component });
24556
- WidgetsDashboardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: WidgetsDashboardComponent, selector: "c8y-widgets-dashboard", inputs: { widgets: "widgets", context: "context", contextDashboard: "contextDashboard", _settings: ["settings", "_settings"], breadcrumb: "breadcrumb" }, outputs: { onAddWidget: "onAddWidget", onEditWidget: "onEditWidget", onDeleteWidget: "onDeleteWidget", onChangeDashboard: "onChangeDashboard", onEditDashboard: "onEditDashboard", onCopyDashboard: "onCopyDashboard", onDeleteDashboard: "onDeleteDashboard", onFreeze: "onFreeze", onChangeStart: "onChangeStart", onChangeEnd: "onChangeEnd" }, host: { styleAttribute: "\n display: block;\n ", classAttribute: "dashboard c8y-grid-dashboard" }, providers: [WidgetsDashboardEventService], ngImport: i0, template: "<c8y-title *ngIf=\"!!settings.title\">\n {{ settings.title | translate }}\n</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!!breadcrumb\">\n <c8y-breadcrumb-item\n [icon]=\"breadcrumb.icon\"\n [label]=\"breadcrumb.label\"\n [path]=\"breadcrumb.path\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onAddWidget.observers.length\">\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n data-cy=\"widget-dashboard--Add-widget\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add widget' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onEditDashboard.observers.length\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onEditDashboard.emit()\"\n data-cy=\"widgets-dashboard--edit-widget\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"settings.allowFullscreen\">\n <button\n title=\"{{ 'Full screen' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"fullScreen() ? 'compress' : 'expand'\"></i>\n {{ 'Full screen' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"navbar-form\"\n *ngIf=\"onFreeze.observers.length\"\n>\n <button\n title=\"{{ 'Lock/unlock this dashboard' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n [ngClass]=\"{ active: settings.isFrozen }\"\n (click)=\"onFreeze.emit(settings)\"\n [disabled]=\"settings.isDisabled\"\n uib-btn-checkbox\n data-cy=\"widgets-dashboard--button-lock-toggle\"\n >\n <i [c8yIcon]=\"settings.isFrozen ? 'lock' : 'unlock'\"></i>\n </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'more'\" [priority]=\"-2000\" *ngIf=\"settings.canCopy\">\n <button title=\"{{ 'Copy dashboard' | translate }}\" type=\"button\" (click)=\"onCopyDashboard.emit()\" class=\"btn btn-link\">\n <i c8yIcon=\"clone\"></i>\n <span class=\"m-l-4\" translate>Copy dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-3000\"\n *ngIf=\"settings.canDelete && onDeleteDashboard.observers.length\"\n>\n <button\n title=\"{{ 'Delete dashboard' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteDashboard.emit()\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Delete dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<ng-template #loadingIndicator>\n <c8y-loading class=\"col-xs-12 text-center\" *ngIf=\"isLoadingWidgets$ | async\"></c8y-loading>\n</ng-template>\n\n<ng-container *ngIf=\"!(isLoadingWidgets$ | async); else loadingIndicator\">\n <ng-container *ngIf=\"resolvedWidgets$ | async as widgetsToDisplay\">\n <!-- empty state -->\n <c8y-ui-empty-state\n *ngIf=\"widgetsToDisplay?.length === 0\"\n [icon]=\"'c8y-device'\"\n [title]=\"'No widgets to display.' | translate\"\n >\n <div *ngIf=\"!settings.isFrozen && onAddWidget.observers.length\">\n <p translate>Add widgets to this dashboard.</p>\n <div>\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n class=\"btn btn-primary m-t-16\"\n translate\n >\n Add widget\n </button>\n </div>\n <p c8y-guide-docs>\n <small translate ngNonBindable>\n Find out more in the\n <a c8y-guide-href=\"users-guide/cockpit/#dashboards\">User guide`KEEP_ORIGINAL`</a>\n .\n </small>\n </p>\n </div>\n </c8y-ui-empty-state>\n\n <c8y-dashboard\n (dashboardChange)=\"onChangeDashboard.emit($event)\"\n #dashboard\n >\n <c8y-dashboard-child\n *ngFor=\"let widget of widgetsToDisplay\"\n [x]=\"widget._x\"\n [y]=\"widget._y\"\n [width]=\"widget._width || settings.defaultWidth\"\n [height]=\"widget._height || settings.defaultHeight\"\n [margin]=\"settings.widgetMargin\"\n [isFrozen]=\"settings.isFrozen || settings.isDisabled\"\n [class]=\"widget.classes\"\n [data]=\"widget\"\n [useIntersection]=\"true\"\n (changeStart)=\"onChangeStart.emit({ widget: widget, source: child, dashboard: dashboard })\"\n (changeEnd)=\"onChangeEnd.emit({ widget: widget, source: child, dashboard: dashboard })\"\n #child\n >\n <c8y-dashboard-child-title>\n <span \n data-cy=\"c8y-dashboard-list--device-widget\"\n *ngIf=\"settings.translateWidgetTitle\">\n {{ widget.title | translate }}\n </span>\n <span *ngIf=\"!settings.translateWidgetTitle\">\n {{ widget.title }}\n </span>\n </c8y-dashboard-child-title>\n <c8y-dashboard-child-action *ngIf=\"onEditWidget.observers.length\">\n <button\n title=\"{{ 'Edit widget' | translate }}\"\n type=\"button\"\n (click)=\"onEditWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"pencil\"></i>\n <span class=\"m-l-4\" translate>Edit</span>\n </button>\n </c8y-dashboard-child-action>\n <c8y-dashboard-child-action *ngIf=\"onDeleteWidget.observers.length\">\n <button\n title=\"{{ 'Remove widget' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Remove</span>\n </button>\n </c8y-dashboard-child-action>\n\n <c8y-widget-time-context\n *ngIf=\"\n widget.config?.displaySettings?.globalTimeContext &&\n widget.config.widgetInstanceGlobalTimeContext\n \"\n (dateContextChange)=\"updateWidgetConfig({ date: $event }, widget)\"\n [canDecouple]=\"widget.config.canDecoupleGlobalTimeContext\"\n ></c8y-widget-time-context>\n\n <c8y-dynamic-component\n [componentId]=\"widget.componentId || widget.name\"\n [config]=\"\n widget.templateUrl || widget.widgetComponent\n ? { child: widget, dashboard: contextDashboard, context: context }\n : widget.config\n \"\n *ngIf=\"child.intersected\"\n (updateWidgetClasses)=\"updateWidgetClasses(widget, $event)\"\n ></c8y-dynamic-component>\n </c8y-dashboard-child>\n </c8y-dashboard>\n </ng-container>\n</ng-container>\n\n", dependencies: [{ kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId"] }, { kind: "component", type: DynamicComponentComponent, selector: "c8y-dynamic-component", inputs: ["componentId", "config", "mode", "notFoundError", "executeResolvers"], outputs: ["updateWidgetClasses"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: DashboardChildComponent, selector: "c8y-dashboard-child", inputs: ["x", "y", "width", "height", "data", "margin", "isFrozen", "useIntersection", "class"], outputs: ["changeStart", "changeEnd"] }, { kind: "component", type: DashboardComponent, selector: "c8y-dashboard", inputs: ["columns", "gap", "rows"], outputs: ["dashboardChange"] }, { kind: "component", type: DashboardChildTitleComponent, selector: "c8y-dashboard-child-title" }, { kind: "component", type: DashboardChildActionComponent, selector: "c8y-dashboard-child-action" }, { kind: "component", type: WidgetTimeContextComponent, selector: "c8y-widget-time-context", inputs: ["canDecouple"], outputs: ["dateContextChange"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
24549
+ WidgetsDashboardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: WidgetsDashboardComponent, selector: "c8y-widgets-dashboard", inputs: { widgets: "widgets", context: "context", contextDashboard: "contextDashboard", _settings: ["settings", "_settings"], breadcrumb: "breadcrumb" }, outputs: { onAddWidget: "onAddWidget", onEditWidget: "onEditWidget", onDeleteWidget: "onDeleteWidget", onChangeDashboard: "onChangeDashboard", onEditDashboard: "onEditDashboard", onCopyDashboard: "onCopyDashboard", onDeleteDashboard: "onDeleteDashboard", onFreeze: "onFreeze", onChangeStart: "onChangeStart", onChangeEnd: "onChangeEnd" }, host: { styleAttribute: "\n display: block;\n ", classAttribute: "dashboard c8y-grid-dashboard" }, providers: [WidgetsDashboardEventService], ngImport: i0, template: "<c8y-title *ngIf=\"!!settings.title\">\n {{ settings.title | translate }}\n</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!!breadcrumb\">\n <c8y-breadcrumb-item\n [icon]=\"breadcrumb.icon\"\n [label]=\"breadcrumb.label\"\n [path]=\"breadcrumb.path\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onAddWidget.observers.length\">\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n data-cy=\"widget-dashboard--Add-widget\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add widget' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onEditDashboard.observers.length\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onEditDashboard.emit()\"\n data-cy=\"widgets-dashboard--edit-widget\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"settings.allowFullscreen\">\n <button\n title=\"{{ 'Full screen' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"fullScreen() ? 'compress' : 'expand'\"></i>\n {{ 'Full screen' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"navbar-form\"\n *ngIf=\"onFreeze.observers.length\"\n>\n <button\n title=\"{{ 'Lock/unlock this dashboard' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n [ngClass]=\"{ active: settings.isFrozen }\"\n (click)=\"onFreeze.emit(settings)\"\n [disabled]=\"settings.isDisabled\"\n uib-btn-checkbox\n data-cy=\"widgets-dashboard--button-lock-toggle\"\n >\n <i [c8yIcon]=\"settings.isFrozen ? 'lock' : 'unlock'\"></i>\n </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'more'\" [priority]=\"-2000\" *ngIf=\"settings.canCopy\">\n <button title=\"{{ 'Copy dashboard' | translate }}\" type=\"button\" (click)=\"onCopyDashboard.emit()\" class=\"btn btn-link\">\n <i c8yIcon=\"clone\"></i>\n <span class=\"m-l-4\" translate>Copy dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-3000\"\n *ngIf=\"settings.canDelete && onDeleteDashboard.observers.length\"\n>\n <button\n title=\"{{ 'Delete dashboard' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteDashboard.emit()\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Delete dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<ng-template #loadingIndicator>\n <c8y-loading class=\"col-xs-12 text-center\" *ngIf=\"isLoadingWidgets$ | async\"></c8y-loading>\n</ng-template>\n\n<ng-container *ngIf=\"!(isLoadingWidgets$ | async); else loadingIndicator\">\n <ng-container *ngIf=\"resolvedWidgets$ | async as widgetsToDisplay\">\n <!-- empty state -->\n <c8y-ui-empty-state\n *ngIf=\"widgetsToDisplay?.length === 0\"\n [icon]=\"'c8y-device'\"\n [title]=\"'No widgets to display.' | translate\"\n >\n <div *ngIf=\"!settings.isFrozen && onAddWidget.observers.length\">\n <p translate>Add widgets to this dashboard.</p>\n <div>\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n class=\"btn btn-primary m-t-16\"\n translate\n >\n Add widget\n </button>\n </div>\n <p c8y-guide-docs>\n <small translate ngNonBindable>\n Find out more in the\n <a c8y-guide-href=\"users-guide/cockpit/#dashboards\">User guide`KEEP_ORIGINAL`</a>\n .\n </small>\n </p>\n </div>\n </c8y-ui-empty-state>\n\n <c8y-dashboard\n [columns]=\"settings.columns\"\n (dashboardChange)=\"onChangeDashboard.emit($event)\"\n #dashboard\n >\n <c8y-dashboard-child\n *ngFor=\"let widget of widgetsToDisplay\"\n [x]=\"widget._x\"\n [y]=\"widget._y\"\n [width]=\"widget._width || settings.defaultWidth\"\n [height]=\"widget._height || settings.defaultHeight\"\n [margin]=\"settings.widgetMargin\"\n [isFrozen]=\"settings.isFrozen || settings.isDisabled\"\n [class]=\"widget.classes\"\n [data]=\"widget\"\n [useIntersection]=\"true\"\n (changeStart)=\"onChangeStart.emit({ widget: widget, source: child, dashboard: dashboard })\"\n (changeEnd)=\"onChangeEnd.emit({ widget: widget, source: child, dashboard: dashboard })\"\n #child\n >\n <c8y-dashboard-child-title>\n <span \n data-cy=\"c8y-dashboard-list--device-widget\"\n *ngIf=\"settings.translateWidgetTitle\">\n {{ widget.title | translate }}\n </span>\n <span *ngIf=\"!settings.translateWidgetTitle\">\n {{ widget.title }}\n </span>\n </c8y-dashboard-child-title>\n <c8y-dashboard-child-action *ngIf=\"onEditWidget.observers.length\">\n <button\n title=\"{{ 'Edit widget' | translate }}\"\n type=\"button\"\n (click)=\"onEditWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"pencil\"></i>\n <span class=\"m-l-4\" translate>Edit</span>\n </button>\n </c8y-dashboard-child-action>\n <c8y-dashboard-child-action *ngIf=\"onDeleteWidget.observers.length\">\n <button\n title=\"{{ 'Remove widget' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Remove</span>\n </button>\n </c8y-dashboard-child-action>\n\n <c8y-widget-time-context\n *ngIf=\"\n widget.config?.displaySettings?.globalTimeContext &&\n widget.config.widgetInstanceGlobalTimeContext\n \"\n (dateContextChange)=\"updateWidgetConfig({ date: $event }, widget)\"\n [canDecouple]=\"widget.config.canDecoupleGlobalTimeContext\"\n ></c8y-widget-time-context>\n\n <c8y-dynamic-component\n [componentId]=\"widget.componentId || widget.name\"\n [config]=\"\n widget.templateUrl || widget.widgetComponent\n ? { child: widget, dashboard: contextDashboard, context: context }\n : widget.config\n \"\n *ngIf=\"child.intersected\"\n (updateWidgetClasses)=\"updateWidgetClasses(widget, $event)\"\n ></c8y-dynamic-component>\n </c8y-dashboard-child>\n </c8y-dashboard>\n </ng-container>\n</ng-container>\n\n", dependencies: [{ kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId"] }, { kind: "component", type: DynamicComponentComponent, selector: "c8y-dynamic-component", inputs: ["componentId", "config", "mode", "notFoundError", "executeResolvers"], outputs: ["updateWidgetClasses"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: DashboardChildComponent, selector: "c8y-dashboard-child", inputs: ["x", "y", "width", "height", "data", "margin", "isFrozen", "useIntersection", "class"], outputs: ["changeStart", "changeEnd"] }, { kind: "component", type: DashboardComponent, selector: "c8y-dashboard", inputs: ["columns", "gap", "rows"], outputs: ["dashboardChange"] }, { kind: "component", type: DashboardChildTitleComponent, selector: "c8y-dashboard-child-title" }, { kind: "component", type: DashboardChildActionComponent, selector: "c8y-dashboard-child-action" }, { kind: "component", type: WidgetTimeContextComponent, selector: "c8y-widget-time-context", inputs: ["canDecouple"], outputs: ["dateContextChange"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
24557
24550
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: WidgetsDashboardComponent, decorators: [{
24558
24551
  type: Component,
24559
24552
  args: [{ selector: 'c8y-widgets-dashboard', host: {
@@ -24561,7 +24554,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
24561
24554
  display: block;
24562
24555
  `,
24563
24556
  class: 'dashboard c8y-grid-dashboard'
24564
- }, providers: [WidgetsDashboardEventService], template: "<c8y-title *ngIf=\"!!settings.title\">\n {{ settings.title | translate }}\n</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!!breadcrumb\">\n <c8y-breadcrumb-item\n [icon]=\"breadcrumb.icon\"\n [label]=\"breadcrumb.label\"\n [path]=\"breadcrumb.path\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onAddWidget.observers.length\">\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n data-cy=\"widget-dashboard--Add-widget\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add widget' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onEditDashboard.observers.length\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onEditDashboard.emit()\"\n data-cy=\"widgets-dashboard--edit-widget\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"settings.allowFullscreen\">\n <button\n title=\"{{ 'Full screen' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"fullScreen() ? 'compress' : 'expand'\"></i>\n {{ 'Full screen' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"navbar-form\"\n *ngIf=\"onFreeze.observers.length\"\n>\n <button\n title=\"{{ 'Lock/unlock this dashboard' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n [ngClass]=\"{ active: settings.isFrozen }\"\n (click)=\"onFreeze.emit(settings)\"\n [disabled]=\"settings.isDisabled\"\n uib-btn-checkbox\n data-cy=\"widgets-dashboard--button-lock-toggle\"\n >\n <i [c8yIcon]=\"settings.isFrozen ? 'lock' : 'unlock'\"></i>\n </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'more'\" [priority]=\"-2000\" *ngIf=\"settings.canCopy\">\n <button title=\"{{ 'Copy dashboard' | translate }}\" type=\"button\" (click)=\"onCopyDashboard.emit()\" class=\"btn btn-link\">\n <i c8yIcon=\"clone\"></i>\n <span class=\"m-l-4\" translate>Copy dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-3000\"\n *ngIf=\"settings.canDelete && onDeleteDashboard.observers.length\"\n>\n <button\n title=\"{{ 'Delete dashboard' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteDashboard.emit()\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Delete dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<ng-template #loadingIndicator>\n <c8y-loading class=\"col-xs-12 text-center\" *ngIf=\"isLoadingWidgets$ | async\"></c8y-loading>\n</ng-template>\n\n<ng-container *ngIf=\"!(isLoadingWidgets$ | async); else loadingIndicator\">\n <ng-container *ngIf=\"resolvedWidgets$ | async as widgetsToDisplay\">\n <!-- empty state -->\n <c8y-ui-empty-state\n *ngIf=\"widgetsToDisplay?.length === 0\"\n [icon]=\"'c8y-device'\"\n [title]=\"'No widgets to display.' | translate\"\n >\n <div *ngIf=\"!settings.isFrozen && onAddWidget.observers.length\">\n <p translate>Add widgets to this dashboard.</p>\n <div>\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n class=\"btn btn-primary m-t-16\"\n translate\n >\n Add widget\n </button>\n </div>\n <p c8y-guide-docs>\n <small translate ngNonBindable>\n Find out more in the\n <a c8y-guide-href=\"users-guide/cockpit/#dashboards\">User guide`KEEP_ORIGINAL`</a>\n .\n </small>\n </p>\n </div>\n </c8y-ui-empty-state>\n\n <c8y-dashboard\n (dashboardChange)=\"onChangeDashboard.emit($event)\"\n #dashboard\n >\n <c8y-dashboard-child\n *ngFor=\"let widget of widgetsToDisplay\"\n [x]=\"widget._x\"\n [y]=\"widget._y\"\n [width]=\"widget._width || settings.defaultWidth\"\n [height]=\"widget._height || settings.defaultHeight\"\n [margin]=\"settings.widgetMargin\"\n [isFrozen]=\"settings.isFrozen || settings.isDisabled\"\n [class]=\"widget.classes\"\n [data]=\"widget\"\n [useIntersection]=\"true\"\n (changeStart)=\"onChangeStart.emit({ widget: widget, source: child, dashboard: dashboard })\"\n (changeEnd)=\"onChangeEnd.emit({ widget: widget, source: child, dashboard: dashboard })\"\n #child\n >\n <c8y-dashboard-child-title>\n <span \n data-cy=\"c8y-dashboard-list--device-widget\"\n *ngIf=\"settings.translateWidgetTitle\">\n {{ widget.title | translate }}\n </span>\n <span *ngIf=\"!settings.translateWidgetTitle\">\n {{ widget.title }}\n </span>\n </c8y-dashboard-child-title>\n <c8y-dashboard-child-action *ngIf=\"onEditWidget.observers.length\">\n <button\n title=\"{{ 'Edit widget' | translate }}\"\n type=\"button\"\n (click)=\"onEditWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"pencil\"></i>\n <span class=\"m-l-4\" translate>Edit</span>\n </button>\n </c8y-dashboard-child-action>\n <c8y-dashboard-child-action *ngIf=\"onDeleteWidget.observers.length\">\n <button\n title=\"{{ 'Remove widget' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Remove</span>\n </button>\n </c8y-dashboard-child-action>\n\n <c8y-widget-time-context\n *ngIf=\"\n widget.config?.displaySettings?.globalTimeContext &&\n widget.config.widgetInstanceGlobalTimeContext\n \"\n (dateContextChange)=\"updateWidgetConfig({ date: $event }, widget)\"\n [canDecouple]=\"widget.config.canDecoupleGlobalTimeContext\"\n ></c8y-widget-time-context>\n\n <c8y-dynamic-component\n [componentId]=\"widget.componentId || widget.name\"\n [config]=\"\n widget.templateUrl || widget.widgetComponent\n ? { child: widget, dashboard: contextDashboard, context: context }\n : widget.config\n \"\n *ngIf=\"child.intersected\"\n (updateWidgetClasses)=\"updateWidgetClasses(widget, $event)\"\n ></c8y-dynamic-component>\n </c8y-dashboard-child>\n </c8y-dashboard>\n </ng-container>\n</ng-container>\n\n" }]
24557
+ }, providers: [WidgetsDashboardEventService], template: "<c8y-title *ngIf=\"!!settings.title\">\n {{ settings.title | translate }}\n</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!!breadcrumb\">\n <c8y-breadcrumb-item\n [icon]=\"breadcrumb.icon\"\n [label]=\"breadcrumb.label\"\n [path]=\"breadcrumb.path\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onAddWidget.observers.length\">\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n data-cy=\"widget-dashboard--Add-widget\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add widget' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"onEditDashboard.observers.length\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onEditDashboard.emit()\"\n data-cy=\"widgets-dashboard--edit-widget\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"settings.allowFullscreen\">\n <button\n title=\"{{ 'Full screen' | translate }}\"\n type=\"button\"\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"fullScreen() ? 'compress' : 'expand'\"></i>\n {{ 'Full screen' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'right'\"\n itemClass=\"navbar-form\"\n *ngIf=\"onFreeze.observers.length\"\n>\n <button\n title=\"{{ 'Lock/unlock this dashboard' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n [ngClass]=\"{ active: settings.isFrozen }\"\n (click)=\"onFreeze.emit(settings)\"\n [disabled]=\"settings.isDisabled\"\n uib-btn-checkbox\n data-cy=\"widgets-dashboard--button-lock-toggle\"\n >\n <i [c8yIcon]=\"settings.isFrozen ? 'lock' : 'unlock'\"></i>\n </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'more'\" [priority]=\"-2000\" *ngIf=\"settings.canCopy\">\n <button title=\"{{ 'Copy dashboard' | translate }}\" type=\"button\" (click)=\"onCopyDashboard.emit()\" class=\"btn btn-link\">\n <i c8yIcon=\"clone\"></i>\n <span class=\"m-l-4\" translate>Copy dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-3000\"\n *ngIf=\"settings.canDelete && onDeleteDashboard.observers.length\"\n>\n <button\n title=\"{{ 'Delete dashboard' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteDashboard.emit()\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Delete dashboard</span>\n </button>\n</c8y-action-bar-item>\n\n<ng-template #loadingIndicator>\n <c8y-loading class=\"col-xs-12 text-center\" *ngIf=\"isLoadingWidgets$ | async\"></c8y-loading>\n</ng-template>\n\n<ng-container *ngIf=\"!(isLoadingWidgets$ | async); else loadingIndicator\">\n <ng-container *ngIf=\"resolvedWidgets$ | async as widgetsToDisplay\">\n <!-- empty state -->\n <c8y-ui-empty-state\n *ngIf=\"widgetsToDisplay?.length === 0\"\n [icon]=\"'c8y-device'\"\n [title]=\"'No widgets to display.' | translate\"\n >\n <div *ngIf=\"!settings.isFrozen && onAddWidget.observers.length\">\n <p translate>Add widgets to this dashboard.</p>\n <div>\n <button\n title=\"{{ 'Add widget' | translate }}\"\n type=\"button\"\n [disabled]=\"settings.isFrozen || settings.isDisabled\"\n (click)=\"onAddWidget.emit()\"\n class=\"btn btn-primary m-t-16\"\n translate\n >\n Add widget\n </button>\n </div>\n <p c8y-guide-docs>\n <small translate ngNonBindable>\n Find out more in the\n <a c8y-guide-href=\"users-guide/cockpit/#dashboards\">User guide`KEEP_ORIGINAL`</a>\n .\n </small>\n </p>\n </div>\n </c8y-ui-empty-state>\n\n <c8y-dashboard\n [columns]=\"settings.columns\"\n (dashboardChange)=\"onChangeDashboard.emit($event)\"\n #dashboard\n >\n <c8y-dashboard-child\n *ngFor=\"let widget of widgetsToDisplay\"\n [x]=\"widget._x\"\n [y]=\"widget._y\"\n [width]=\"widget._width || settings.defaultWidth\"\n [height]=\"widget._height || settings.defaultHeight\"\n [margin]=\"settings.widgetMargin\"\n [isFrozen]=\"settings.isFrozen || settings.isDisabled\"\n [class]=\"widget.classes\"\n [data]=\"widget\"\n [useIntersection]=\"true\"\n (changeStart)=\"onChangeStart.emit({ widget: widget, source: child, dashboard: dashboard })\"\n (changeEnd)=\"onChangeEnd.emit({ widget: widget, source: child, dashboard: dashboard })\"\n #child\n >\n <c8y-dashboard-child-title>\n <span \n data-cy=\"c8y-dashboard-list--device-widget\"\n *ngIf=\"settings.translateWidgetTitle\">\n {{ widget.title | translate }}\n </span>\n <span *ngIf=\"!settings.translateWidgetTitle\">\n {{ widget.title }}\n </span>\n </c8y-dashboard-child-title>\n <c8y-dashboard-child-action *ngIf=\"onEditWidget.observers.length\">\n <button\n title=\"{{ 'Edit widget' | translate }}\"\n type=\"button\"\n (click)=\"onEditWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"pencil\"></i>\n <span class=\"m-l-4\" translate>Edit</span>\n </button>\n </c8y-dashboard-child-action>\n <c8y-dashboard-child-action *ngIf=\"onDeleteWidget.observers.length\">\n <button\n title=\"{{ 'Remove widget' | translate }}\"\n type=\"button\"\n (click)=\"onDeleteWidget.emit({ widget: widget, source: child, dashboard: dashboard })\"\n >\n <i c8yIcon=\"delete\"></i>\n <span class=\"m-l-4\" translate>Remove</span>\n </button>\n </c8y-dashboard-child-action>\n\n <c8y-widget-time-context\n *ngIf=\"\n widget.config?.displaySettings?.globalTimeContext &&\n widget.config.widgetInstanceGlobalTimeContext\n \"\n (dateContextChange)=\"updateWidgetConfig({ date: $event }, widget)\"\n [canDecouple]=\"widget.config.canDecoupleGlobalTimeContext\"\n ></c8y-widget-time-context>\n\n <c8y-dynamic-component\n [componentId]=\"widget.componentId || widget.name\"\n [config]=\"\n widget.templateUrl || widget.widgetComponent\n ? { child: widget, dashboard: contextDashboard, context: context }\n : widget.config\n \"\n *ngIf=\"child.intersected\"\n (updateWidgetClasses)=\"updateWidgetClasses(widget, $event)\"\n ></c8y-dynamic-component>\n </c8y-dashboard-child>\n </c8y-dashboard>\n </ng-container>\n</ng-container>\n\n" }]
24565
24558
  }], ctorParameters: function () { return [{ type: DynamicComponentService }]; }, propDecorators: { widgets: [{
24566
24559
  type: Input
24567
24560
  }], context: [{
@@ -28561,7 +28554,9 @@ class MeasurementRealtimeService extends RealtimeService {
28561
28554
  map(result => !emitNullIfInitialValuesWereNotFound || result.data.length ? result.data : [null]),
28562
28555
  // reverse required, so that measurements are received ordered by time (ascending).
28563
28556
  // from ensures values are sent as single measurements and not a measurement array.
28564
- switchMap(result => from(result.reverse())));
28557
+ // TODO: replace `[...result].reverse()` with `result.toReversed()` once es2023 is available.
28558
+ // Had to clone the result array as otherwise reverse may alternate the array multiple times if the observable is subscribed multiple times.
28559
+ switchMap(result => from([...result].reverse())));
28565
28560
  }
28566
28561
  channel() {
28567
28562
  return '/measurements/*';