@c8y/ngx-components 1023.14.212 → 1023.14.216
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.
- package/echart/index.d.ts +24 -2
- package/echart/index.d.ts.map +1 -1
- package/echart/models/index.d.ts +9 -0
- package/echart/models/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +43 -4
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-notes.mjs +30 -8
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-notes.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +18 -3
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/package.json +1 -1
- package/widgets/implementations/asset-notes/index.d.ts +7 -0
- package/widgets/implementations/asset-notes/index.d.ts.map +1 -1
- package/widgets/implementations/datapoints-graph/index.d.ts +6 -0
- package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as i3 from '@angular/common';
|
|
2
2
|
import { CommonModule as CommonModule$1 } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { inject, input, signal, computed, Component } from '@angular/core';
|
|
5
|
-
import * as
|
|
5
|
+
import * as i2 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
7
|
import { InventoryService } from '@c8y/client';
|
|
8
|
-
import { gettext } from '@c8y/ngx-components/gettext';
|
|
9
8
|
import * as i1 from '@c8y/ngx-components';
|
|
10
|
-
import { AppStateService, AlertService, DatePipe, CommonModule, CoreModule, FormsModule as FormsModule$1 } from '@c8y/ngx-components';
|
|
9
|
+
import { AppStateService, AlertService, DatePipe, ContextRouteService, CommonModule, CoreModule, FormsModule as FormsModule$1 } from '@c8y/ngx-components';
|
|
10
|
+
import { gettext } from '@c8y/ngx-components/gettext';
|
|
11
11
|
|
|
12
12
|
class AssetNotesWidgetComponent {
|
|
13
13
|
constructor() {
|
|
@@ -15,6 +15,7 @@ class AssetNotesWidgetComponent {
|
|
|
15
15
|
this.appState = inject(AppStateService);
|
|
16
16
|
this.alertService = inject(AlertService);
|
|
17
17
|
this.datePipe = inject(DatePipe);
|
|
18
|
+
this.contextRoute = inject(ContextRouteService);
|
|
18
19
|
this.config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : []));
|
|
19
20
|
this.notes = signal(null, ...(ngDevMode ? [{ debugName: "notes" }] : []));
|
|
20
21
|
this.editable = signal(false, ...(ngDevMode ? [{ debugName: "editable" }] : []));
|
|
@@ -32,6 +33,10 @@ class AssetNotesWidgetComponent {
|
|
|
32
33
|
this.editable.set(!this.editable());
|
|
33
34
|
}
|
|
34
35
|
async save() {
|
|
36
|
+
const id = this.deviceId();
|
|
37
|
+
if (!id) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
35
40
|
try {
|
|
36
41
|
const updatedNotes = {
|
|
37
42
|
...this.notes(),
|
|
@@ -39,7 +44,7 @@ class AssetNotesWidgetComponent {
|
|
|
39
44
|
lastUpdated: new Date().toISOString()
|
|
40
45
|
};
|
|
41
46
|
await this.inventory.update({
|
|
42
|
-
id
|
|
47
|
+
id,
|
|
43
48
|
[this.FRAGMENT]: updatedNotes
|
|
44
49
|
});
|
|
45
50
|
this.notes.set(updatedNotes);
|
|
@@ -51,20 +56,37 @@ class AssetNotesWidgetComponent {
|
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
async loadNotes() {
|
|
59
|
+
const id = this.deviceId();
|
|
60
|
+
if (!id) {
|
|
61
|
+
// No device resolved — stay read-only (Edit is hidden while loading) instead of
|
|
62
|
+
// presenting an editable empty state.
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
54
65
|
try {
|
|
55
|
-
const device = await this.inventory.detail(
|
|
66
|
+
const device = await this.inventory.detail(id);
|
|
56
67
|
this.notes.set(device.data[this.FRAGMENT] || { htmlContent: '' });
|
|
57
68
|
}
|
|
58
69
|
catch (error) {
|
|
70
|
+
// Leave the widget read-only on failure: a transient error must not let the user save
|
|
71
|
+
// over notes that are still on the device.
|
|
59
72
|
this.alertService.addServerFailure(error);
|
|
60
73
|
}
|
|
61
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Id of the device whose notes are shown. Prefers the widget's own `config.device`, and
|
|
77
|
+
* falls back to the dashboard context device — pre-migration (AngularJS) Asset Notes
|
|
78
|
+
* dashboards saved no `config.device` and relied on the surrounding dashboard context.
|
|
79
|
+
*/
|
|
80
|
+
deviceId() {
|
|
81
|
+
const id = this.config()?.device?.id ?? this.contextRoute.activatedContextData?.contextData?.id;
|
|
82
|
+
return id == null ? undefined : `${id}`;
|
|
83
|
+
}
|
|
62
84
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AssetNotesWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
63
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AssetNotesWidgetComponent, isStandalone: true, selector: "c8y-asset-notes", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n
|
|
85
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AssetNotesWidgetComponent, isStandalone: true, selector: "c8y-asset-notes", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n @if (isLoading()) {\n <c8y-loading></c8y-loading>\n }\n <div class=\"text-break-word asset-notes-body\">\n @if (notes()?.htmlContent && !isLoading()) {\n <span\n class=\"markdown-content d-inline-block\"\n [innerHTML]=\"notes()?.htmlContent | markdownToHtml | async\"\n ></span>\n } @else if (!notes()?.htmlContent) {\n <span>\n {{ 'No notes yet.' | translate }}\n </span>\n }\n\n @if (!isLoading()) {\n <button\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"asset-notes-footer m-t-8\">\n <small class=\"text-muted\">\n @if (notes()?.lastUpdated) {\n <em\n ngNonBindable\n translate\n [translateParams]=\"ngNonBindableTranslate()\"\n >\n {{ lastUpdated }} by {{ user }}\n </em>\n }\n </small>\n </div>\n } @else {\n <div class=\"fit-h flex-grow\">\n <div class=\"d-flex a-i-stretch fit-h\">\n <textarea\n class=\"form-control fit-h text-monospace\"\n [attr.aria-label]=\"'Notes' | translate\"\n rows=\"5\"\n [(ngModel)]=\"notes().htmlContent\"\n c8y-code-editor\n ></textarea>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n >\n <i c8yIcon=\"check\"></i>\n </button>\n </div>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i1.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.MarkdownToHtmlPipe, name: "markdownToHtml" }] }); }
|
|
64
86
|
}
|
|
65
87
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AssetNotesWidgetComponent, decorators: [{
|
|
66
88
|
type: Component,
|
|
67
|
-
args: [{ selector: 'c8y-asset-notes', standalone: true, imports: [CommonModule, CommonModule$1, CoreModule, FormsModule, FormsModule$1, DatePipe], template: "<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n
|
|
89
|
+
args: [{ selector: 'c8y-asset-notes', standalone: true, imports: [CommonModule, CommonModule$1, CoreModule, FormsModule, FormsModule$1, DatePipe], template: "<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n @if (isLoading()) {\n <c8y-loading></c8y-loading>\n }\n <div class=\"text-break-word asset-notes-body\">\n @if (notes()?.htmlContent && !isLoading()) {\n <span\n class=\"markdown-content d-inline-block\"\n [innerHTML]=\"notes()?.htmlContent | markdownToHtml | async\"\n ></span>\n } @else if (!notes()?.htmlContent) {\n <span>\n {{ 'No notes yet.' | translate }}\n </span>\n }\n\n @if (!isLoading()) {\n <button\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"asset-notes-footer m-t-8\">\n <small class=\"text-muted\">\n @if (notes()?.lastUpdated) {\n <em\n ngNonBindable\n translate\n [translateParams]=\"ngNonBindableTranslate()\"\n >\n {{ lastUpdated }} by {{ user }}\n </em>\n }\n </small>\n </div>\n } @else {\n <div class=\"fit-h flex-grow\">\n <div class=\"d-flex a-i-stretch fit-h\">\n <textarea\n class=\"form-control fit-h text-monospace\"\n [attr.aria-label]=\"'Notes' | translate\"\n rows=\"5\"\n [(ngModel)]=\"notes().htmlContent\"\n c8y-code-editor\n ></textarea>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n >\n <i c8yIcon=\"check\"></i>\n </button>\n </div>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n" }]
|
|
68
90
|
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }] } });
|
|
69
91
|
|
|
70
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c8y-ngx-components-widgets-implementations-asset-notes.mjs","sources":["../../widgets/implementations/asset-notes/asset-notes-widget.component.ts","../../widgets/implementations/asset-notes/asset-notes-widget.component.html","../../widgets/implementations/asset-notes/c8y-ngx-components-widgets-implementations-asset-notes.ts"],"sourcesContent":["import { CommonModule as NgCommonModule } from '@angular/common';\nimport { Component, computed, inject, input, InputSignal, OnInit, signal } from '@angular/core';\nimport { FormsModule as NgFormsModule } from '@angular/forms';\nimport { IManagedObject, InventoryService } from '@c8y/client';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n AlertService,\n AppStateService,\n CommonModule,\n CoreModule,\n DatePipe,\n FormsModule\n} from '@c8y/ngx-components';\n\ninterface AssetNotes {\n user: string;\n lastUpdated: string;\n htmlContent: string;\n}\n\nexport type AssetNotesConfig = { device: Partial<IManagedObject> };\n\n@Component({\n selector: 'c8y-asset-notes',\n templateUrl: './asset-notes-widget.component.html',\n standalone: true,\n imports: [CommonModule, NgCommonModule, CoreModule, NgFormsModule, FormsModule, DatePipe]\n})\nexport class AssetNotesWidgetComponent implements OnInit {\n private inventory = inject(InventoryService);\n private appState = inject(AppStateService);\n private alertService = inject(AlertService);\n private datePipe = inject(DatePipe);\n\n config: InputSignal<AssetNotesConfig> = input();\n\n notes = signal<AssetNotes | null>(null);\n editable = signal(false);\n isLoading = computed(() => this.notes()?.htmlContent === undefined);\n\n private readonly FRAGMENT = 'c8y_ComponentConfig!assetNotes';\n ngNonBindableTranslate = computed(() => ({\n lastUpdated: this.datePipe.transform(this.notes()?.lastUpdated),\n user: this.notes()?.user\n }));\n\n async ngOnInit() {\n await this.loadNotes();\n }\n\n toggleEdit() {\n this.editable.set(!this.editable());\n }\n\n async save() {\n try {\n const updatedNotes = {\n ...this.notes(),\n user: this.appState.currentUser.value.id,\n lastUpdated: new Date().toISOString()\n };\n\n await this.inventory.update({\n id: this.config().device.id,\n [this.FRAGMENT]: updatedNotes\n });\n\n this.notes.set(updatedNotes);\n this.editable.set(false);\n this.alertService.success(gettext('Notes saved.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n\n private async loadNotes() {\n try {\n const device = await this.inventory.detail(this.config().device.id);\n this.notes.set(device.data[this.FRAGMENT] || { htmlContent: '' });\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n}\n","<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n <c8y-loading *ngIf=\"isLoading()\"></c8y-loading>\n <div class=\"text-break-word asset-notes-body\">\n @if (notes()?.htmlContent && !isLoading()) {\n <span\n class=\"markdown-content d-inline-block\"\n [innerHTML]=\"notes()?.htmlContent | markdownToHtml | async\"\n ></span>\n } @else if (!notes()?.htmlContent) {\n <span>\n {{ 'No notes yet.' | translate }}\n </span>\n }\n\n <button\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n </div>\n </div>\n <div class=\"asset-notes-footer m-t-8\">\n <small class=\"text-muted\">\n <em\n *ngIf=\"notes()?.lastUpdated\"\n ngNonBindable\n translate\n [translateParams]=\"ngNonBindableTranslate()\"\n >\n {{ lastUpdated }} by {{ user }}\n </em>\n </small>\n </div>\n } @else {\n <div class=\"fit-h flex-grow\">\n <div class=\"d-flex a-i-stretch fit-h\">\n <textarea\n class=\"form-control fit-h text-monospace\"\n [attr.aria-label]=\"'Notes' | translate\"\n rows=\"5\"\n [(ngModel)]=\"notes().htmlContent\"\n c8y-code-editor\n ></textarea>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n >\n <i c8yIcon=\"check\"></i>\n </button>\n </div>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NgCommonModule","NgFormsModule","FormsModule"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-widgets-implementations-asset-notes.mjs","sources":["../../widgets/implementations/asset-notes/asset-notes-widget.component.ts","../../widgets/implementations/asset-notes/asset-notes-widget.component.html","../../widgets/implementations/asset-notes/c8y-ngx-components-widgets-implementations-asset-notes.ts"],"sourcesContent":["import { CommonModule as NgCommonModule } from '@angular/common';\nimport { Component, computed, inject, input, InputSignal, OnInit, signal } from '@angular/core';\nimport { FormsModule as NgFormsModule } from '@angular/forms';\nimport { IManagedObject, InventoryService } from '@c8y/client';\nimport {\n AlertService,\n AppStateService,\n CommonModule,\n ContextRouteService,\n CoreModule,\n DatePipe,\n FormsModule\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\ninterface AssetNotes {\n user: string;\n lastUpdated: string;\n htmlContent: string;\n}\n\nexport type AssetNotesConfig = { device: Partial<IManagedObject> };\n\n@Component({\n selector: 'c8y-asset-notes',\n templateUrl: './asset-notes-widget.component.html',\n standalone: true,\n imports: [CommonModule, NgCommonModule, CoreModule, NgFormsModule, FormsModule, DatePipe]\n})\nexport class AssetNotesWidgetComponent implements OnInit {\n private inventory = inject(InventoryService);\n private appState = inject(AppStateService);\n private alertService = inject(AlertService);\n private datePipe = inject(DatePipe);\n private contextRoute = inject(ContextRouteService);\n\n config: InputSignal<AssetNotesConfig> = input();\n\n notes = signal<AssetNotes | null>(null);\n editable = signal(false);\n isLoading = computed(() => this.notes()?.htmlContent === undefined);\n\n private readonly FRAGMENT = 'c8y_ComponentConfig!assetNotes';\n ngNonBindableTranslate = computed(() => ({\n lastUpdated: this.datePipe.transform(this.notes()?.lastUpdated),\n user: this.notes()?.user\n }));\n\n async ngOnInit() {\n await this.loadNotes();\n }\n\n toggleEdit() {\n this.editable.set(!this.editable());\n }\n\n async save() {\n const id = this.deviceId();\n if (!id) {\n return;\n }\n try {\n const updatedNotes = {\n ...this.notes(),\n user: this.appState.currentUser.value.id,\n lastUpdated: new Date().toISOString()\n };\n\n await this.inventory.update({\n id,\n [this.FRAGMENT]: updatedNotes\n });\n\n this.notes.set(updatedNotes);\n this.editable.set(false);\n this.alertService.success(gettext('Notes saved.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n\n private async loadNotes() {\n const id = this.deviceId();\n if (!id) {\n // No device resolved — stay read-only (Edit is hidden while loading) instead of\n // presenting an editable empty state.\n return;\n }\n try {\n const device = await this.inventory.detail(id);\n this.notes.set(device.data[this.FRAGMENT] || { htmlContent: '' });\n } catch (error) {\n // Leave the widget read-only on failure: a transient error must not let the user save\n // over notes that are still on the device.\n this.alertService.addServerFailure(error);\n }\n }\n\n /**\n * Id of the device whose notes are shown. Prefers the widget's own `config.device`, and\n * falls back to the dashboard context device — pre-migration (AngularJS) Asset Notes\n * dashboards saved no `config.device` and relied on the surrounding dashboard context.\n */\n private deviceId(): string | undefined {\n const id = this.config()?.device?.id ?? this.contextRoute.activatedContextData?.contextData?.id;\n return id == null ? undefined : `${id}`;\n }\n}\n","<div class=\"fit-h d-flex flex-wrap a-i-stretch\">\n <i\n class=\"c8y-icon c8y-icon-duocolor asset-notes-icon\"\n [c8yIcon]=\"'c8y-notification'\"\n ></i>\n\n @if (!editable()) {\n <div class=\"asset-notes-content\">\n @if (isLoading()) {\n <c8y-loading></c8y-loading>\n }\n <div class=\"text-break-word asset-notes-body\">\n @if (notes()?.htmlContent && !isLoading()) {\n <span\n class=\"markdown-content d-inline-block\"\n [innerHTML]=\"notes()?.htmlContent | markdownToHtml | async\"\n ></span>\n } @else if (!notes()?.htmlContent) {\n <span>\n {{ 'No notes yet.' | translate }}\n </span>\n }\n\n @if (!isLoading()) {\n <button\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n </div>\n </div>\n <div class=\"asset-notes-footer m-t-8\">\n <small class=\"text-muted\">\n @if (notes()?.lastUpdated) {\n <em\n ngNonBindable\n translate\n [translateParams]=\"ngNonBindableTranslate()\"\n >\n {{ lastUpdated }} by {{ user }}\n </em>\n }\n </small>\n </div>\n } @else {\n <div class=\"fit-h flex-grow\">\n <div class=\"d-flex a-i-stretch fit-h\">\n <textarea\n class=\"form-control fit-h text-monospace\"\n [attr.aria-label]=\"'Notes' | translate\"\n rows=\"5\"\n [(ngModel)]=\"notes().htmlContent\"\n c8y-code-editor\n ></textarea>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n >\n <i c8yIcon=\"check\"></i>\n </button>\n </div>\n <div class=\"input-group-btn a-s-center\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"toggleEdit()\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NgCommonModule","NgFormsModule","FormsModule"],"mappings":"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"}
|
|
@@ -275,7 +275,7 @@ class DatapointsGraphWidgetConfigComponent {
|
|
|
275
275
|
ChartAlarmsService,
|
|
276
276
|
ChartHelpersService,
|
|
277
277
|
WidgetTimeContextDateRangeService
|
|
278
|
-
], viewQueries: [{ propertyName: "previewMapSet", first: true, predicate: ["dataPointsGraphPreview"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\">\n <c8y-datapoint-selection-list\n class=\"bg-component separator-bottom d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"1\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-component separator-bottom d-block\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <div class=\"form-group form-group-sm\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\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 </div>\n <c8y-form-group class=\"form-group-sm\">\n <label>\n {{ 'Data point legend display' | translate }}\n </label>\n <div\n class=\"c8y-select-wrapper\"\n [formGroup]=\"formGroup\"\n >\n <select\n class=\"form-control\"\n [title]=\"'Data point legend display' | translate\"\n id=\"dataPointLegendDisplay\"\n formControlName=\"dataPointLegendDisplay\"\n >\n @for (option of legendDisplayOptions; track option) {\n <option [ngValue]=\"option.value\">\n {{ option.label | translate }}\n </option>\n }\n </select>\n </div>\n </c8y-form-group>\n</form>\n\n<form\n class=\"d-block p-t-8\"\n [formGroup]=\"formGroup\"\n>\n <label>{{ 'Display options' | translate }}</label>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into a single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [popover]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into a single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [popover]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line on every occurrence' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when triggered' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span translate>Show icon when triggered</span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n }\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n </c8y-form-group>\n </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n @if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [config]=\"config\"\n [displayMode]=\"'preview'\"\n [widgetControls]=\"widgetControls\"\n ></c8y-global-context-widget-wrapper>\n }\n\n @if (activeDatapointsExists) {\n <c8y-charts\n class=\"d-block p-relative\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n }\n\n @if (!activeDatapointsExists) {\n <c8y-ui-empty-state\n class=\"d-block m-t-24\"\n [icon]=\"'search'\"\n [title]=\"'No data points selected' | translate\"\n [subtitle]=\"'Select data point to render content' | translate\"\n data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i2.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i5.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i6.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: i7.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "datapoints", "config"] }, { kind: "component", type: GlobalContextWidgetWrapperComponent, selector: "c8y-global-context-widget-wrapper", inputs: ["isLoading", "displayMode", "widgetControls", "controlLinks", "dashboardChildForLegacy", "config", "disableRefreshEmits"], outputs: ["globalContextChange"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
|
|
278
|
+
], viewQueries: [{ propertyName: "previewMapSet", first: true, predicate: ["dataPointsGraphPreview"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\">\n <c8y-datapoint-selection-list\n class=\"bg-component separator-bottom d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"1\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-component separator-bottom d-block\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <div class=\"form-group form-group-sm\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\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 </div>\n <c8y-form-group class=\"form-group-sm\">\n <label>\n {{ 'Data point legend display' | translate }}\n </label>\n <div\n class=\"c8y-select-wrapper\"\n [formGroup]=\"formGroup\"\n >\n <select\n class=\"form-control\"\n [title]=\"'Data point legend display' | translate\"\n id=\"dataPointLegendDisplay\"\n formControlName=\"dataPointLegendDisplay\"\n >\n @for (option of legendDisplayOptions; track option) {\n <option [ngValue]=\"option.value\">\n {{ option.label | translate }}\n </option>\n }\n </select>\n </div>\n </c8y-form-group>\n</form>\n\n<form\n class=\"d-block p-t-8\"\n [formGroup]=\"formGroup\"\n>\n <label>{{ 'Display options' | translate }}</label>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into a single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [popover]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into a single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [popover]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line on every occurrence' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when triggered' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span translate>Show icon when triggered</span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n }\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n </c8y-form-group>\n </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n @if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [config]=\"config\"\n [displayMode]=\"'preview'\"\n [widgetControls]=\"widgetControls\"\n ></c8y-global-context-widget-wrapper>\n }\n\n @if (activeDatapointsExists) {\n <c8y-charts\n class=\"d-block p-relative\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n }\n\n @if (!activeDatapointsExists) {\n <c8y-ui-empty-state\n class=\"d-block m-t-24\"\n [icon]=\"'search'\"\n [title]=\"'No data points selected' | translate\"\n [subtitle]=\"'Select data point to render content' | translate\"\n data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i2.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i5.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint", "selectedChange"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i6.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: i7.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "datapoints", "config"] }, { kind: "component", type: GlobalContextWidgetWrapperComponent, selector: "c8y-global-context-widget-wrapper", inputs: ["isLoading", "displayMode", "widgetControls", "controlLinks", "dashboardChildForLegacy", "config", "disableRefreshEmits"], outputs: ["globalContextChange"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
|
|
279
279
|
}
|
|
280
280
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetConfigComponent, decorators: [{
|
|
281
281
|
type: Component,
|
|
@@ -312,6 +312,9 @@ class DatapointsGraphWidgetViewComponent {
|
|
|
312
312
|
// This is needed to reflect migrated states in the widget config.
|
|
313
313
|
const migratedConfig = this.widgetConfigMigrationService.migrateWidgetConfig(value);
|
|
314
314
|
const newConfig = merge(value, migratedConfig);
|
|
315
|
+
// Keep the original input reference so the clicked data point can be mirrored
|
|
316
|
+
// back onto it.
|
|
317
|
+
this.originalConfig = value;
|
|
315
318
|
this.displayConfig = cloneDeep(newConfig);
|
|
316
319
|
}
|
|
317
320
|
get config() {
|
|
@@ -385,6 +388,18 @@ class DatapointsGraphWidgetViewComponent {
|
|
|
385
388
|
(await this.dynamicComponentService.getById(defaultWidgetIds.DATAPOINTS_GRAPH_NEW)).data
|
|
386
389
|
?.widgetControls || {};
|
|
387
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Mirrors the data point clicked on the chart back onto the original widget config
|
|
393
|
+
* so `config.selected` stays observable from outside the widget.
|
|
394
|
+
*/
|
|
395
|
+
onSelectedChange(selected) {
|
|
396
|
+
if (this.originalConfig) {
|
|
397
|
+
this.originalConfig.selected = selected;
|
|
398
|
+
}
|
|
399
|
+
if (this.displayConfig) {
|
|
400
|
+
this.displayConfig.selected = selected;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
388
403
|
onGlobalContextChange(event) {
|
|
389
404
|
this.invalidateHiddenItemsCache();
|
|
390
405
|
const { context, diff } = event;
|
|
@@ -734,7 +749,7 @@ class DatapointsGraphWidgetViewComponent {
|
|
|
734
749
|
this.loadedAlarmsOrEvents = this.loadedAlarmsOrEvents.filter(aOrE => aOrE.__active && !aOrE.__hidden);
|
|
735
750
|
}
|
|
736
751
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetViewComponent, deps: [{ token: i1$1.TranslateService }, { token: i1.ContextDashboardComponent, optional: true }, { token: i2.DynamicComponentService }, { token: i4$1.WidgetConfigMigrationService }, { token: i2.WidgetTimeContextDateRangeService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
737
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DatapointsGraphWidgetViewComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-view", inputs: { config: "config" }, providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], viewQueries: [{ propertyName: "wrapper", first: true, predicate: GlobalContextWidgetWrapperComponent, descendants: true }, { propertyName: "chartComponent", first: true, predicate: ChartsComponent, descendants: true }], ngImport: i0, template: "@if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [widgetControls]=\"widgetControls\"\n [isLoading]=\"isLoading$ | async\"\n [config]=\"displayConfig\"\n [disableRefreshEmits]=\"true\"\n (globalContextChange)=\"onGlobalContextChange($event)\"\n ></c8y-global-context-widget-wrapper>\n}\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n <div\n class=\"d-flex a-i-center gap-4\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n item.value.original.__active\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n <button\n class=\"btn btn-default btn-sm flex-no-shrink m-l-auto\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i5$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i2.SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: i2.SelectItemDirective, selector: "[c8ySelectItem]", inputs: ["c8ySelectItem", "c8ySelectItemLabel"] }, { kind: "directive", type: i2.SelectedItemsDirective, selector: "[c8ySelectedItems]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i5.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: AlarmsModule }, { kind: "component", type: i9.AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: GlobalContextWidgetWrapperComponent, selector: "c8y-global-context-widget-wrapper", inputs: ["isLoading", "displayMode", "widgetControls", "controlLinks", "dashboardChildForLegacy", "config", "disableRefreshEmits"], outputs: ["globalContextChange"] }, { kind: "pipe", type: i5$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
|
|
752
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DatapointsGraphWidgetViewComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-view", inputs: { config: "config" }, providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], viewQueries: [{ propertyName: "wrapper", first: true, predicate: GlobalContextWidgetWrapperComponent, descendants: true }, { propertyName: "chartComponent", first: true, predicate: ChartsComponent, descendants: true }], ngImport: i0, template: "@if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [widgetControls]=\"widgetControls\"\n [isLoading]=\"isLoading$ | async\"\n [config]=\"displayConfig\"\n [disableRefreshEmits]=\"true\"\n (globalContextChange)=\"onGlobalContextChange($event)\"\n ></c8y-global-context-widget-wrapper>\n}\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n <div\n class=\"d-flex a-i-center gap-4\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n item.value.original.__active\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n <button\n class=\"btn btn-default btn-sm flex-no-shrink m-l-auto\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (selectedChange)=\"onSelectedChange($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i5$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint", "selectedChange"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i2.SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: i2.SelectItemDirective, selector: "[c8ySelectItem]", inputs: ["c8ySelectItem", "c8ySelectItemLabel"] }, { kind: "directive", type: i2.SelectedItemsDirective, selector: "[c8ySelectedItems]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i5.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: AlarmsModule }, { kind: "component", type: i9.AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: GlobalContextWidgetWrapperComponent, selector: "c8y-global-context-widget-wrapper", inputs: ["isLoading", "displayMode", "widgetControls", "controlLinks", "dashboardChildForLegacy", "config", "disableRefreshEmits"], outputs: ["globalContextChange"] }, { kind: "pipe", type: i5$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
|
|
738
753
|
}
|
|
739
754
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetViewComponent, decorators: [{
|
|
740
755
|
type: Component,
|
|
@@ -751,7 +766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
751
766
|
SelectComponent,
|
|
752
767
|
SelectItemDirective,
|
|
753
768
|
SelectedItemsDirective
|
|
754
|
-
], providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], template: "@if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [widgetControls]=\"widgetControls\"\n [isLoading]=\"isLoading$ | async\"\n [config]=\"displayConfig\"\n [disableRefreshEmits]=\"true\"\n (globalContextChange)=\"onGlobalContextChange($event)\"\n ></c8y-global-context-widget-wrapper>\n}\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n <div\n class=\"d-flex a-i-center gap-4\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n item.value.original.__active\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n <button\n class=\"btn btn-default btn-sm flex-no-shrink m-l-auto\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n" }]
|
|
769
|
+
], providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], template: "@if (widgetControls) {\n <c8y-global-context-widget-wrapper\n [widgetControls]=\"widgetControls\"\n [isLoading]=\"isLoading$ | async\"\n [config]=\"displayConfig\"\n [disableRefreshEmits]=\"true\"\n (globalContextChange)=\"onGlobalContextChange($event)\"\n ></c8y-global-context-widget-wrapper>\n}\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n <div\n class=\"d-flex a-i-center gap-4\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n item.value.original.__active\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n <button\n class=\"btn btn-default btn-sm flex-no-shrink m-l-auto\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (selectedChange)=\"onSelectedChange($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n" }]
|
|
755
770
|
}], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i1.ContextDashboardComponent, decorators: [{
|
|
756
771
|
type: Optional
|
|
757
772
|
}] }, { type: i2.DynamicComponentService }, { type: i4$1.WidgetConfigMigrationService }, { type: i2.WidgetTimeContextDateRangeService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
|