@openremote/or-attribute-card 1.8.0-snapshot.20250725120002 → 1.8.0-snapshot.20250728102340

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/lib/index.js CHANGED
@@ -1,865 +1,209 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
- return new (P || (P = Promise))(function (resolve, reject) {
10
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
- step((generator = generator.apply(thisArg, _arguments || [])).next());
14
- });
15
- };
16
- import { css, html, LitElement, unsafeCSS } from "lit";
17
- import { customElement, property, state, query } from "lit/decorators.js";
18
- import i18next from "i18next";
19
- import { AssetModelUtil } from "@openremote/model";
20
- import { DefaultColor3, DefaultColor4, manager, Util } from "@openremote/core";
21
- import { isAxiosError } from "@openremote/rest";
22
- import { Chart, LineController, LineElement, PointElement, LinearScale, TimeSeriesScale, Title } from "chart.js";
23
- import "chartjs-adapter-moment";
24
- import { InputType } from "@openremote/or-mwc-components/or-mwc-input";
25
- import { getAssetDescriptorIconTemplate } from "@openremote/or-icon";
26
- import "@openremote/or-mwc-components/or-mwc-dialog";
27
- import "@openremote/or-attribute-picker";
28
- import moment from "moment";
29
- import { OrAssetTreeSelectionEvent } from "@openremote/or-asset-tree";
30
- import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog";
31
- import { OrAssetAttributePicker, OrAssetAttributePickerPickedEvent } from "@openremote/or-attribute-picker";
32
- import { getContentWithMenuTemplate } from "@openremote/or-mwc-components/or-mwc-menu";
33
- import { when } from "lit/directives/when.js";
34
- import { debounce } from "lodash";
35
- Chart.register(LineController, LineElement, PointElement, LinearScale, Title, TimeSeriesScale);
36
- // language=CSS
37
- const style = css `
38
-
39
- :host {
40
- --internal-or-attribute-history-graph-line-color: var(--or-attribute-history-graph-line-color, var(--or-app-color4, ${unsafeCSS(DefaultColor4)}));
41
- width: 100%;
42
- }
43
-
44
- :host([hidden]) {
45
- display: none;
46
- }
47
-
48
- .panel {
49
- position: relative;
50
- height: 100%;
51
- }
52
- .panel.panel-empty {
53
- display: flex;
54
- }
55
- .panel.panel-empty .panel-content-wrapper {
56
- align-items: center;
57
- width: 100%;
58
- }
59
- .panel.panel-empty .panel-content {
60
- align-items: center;
61
- justify-content: center;
62
- flex-direction: column;
63
- }
64
-
65
- .panel-content-wrapper {
66
- height: 100%;
67
- display: flex;
68
- flex-direction: column;
69
- }
70
-
71
- .panel-title {
72
- display: flex;
73
- align-items: center;
74
- /*margin: -15px -15px 0 0;*/ /* compensate for the click-space of the plusminus button */
75
- font-weight: bolder;
76
- line-height: 1em;
77
- color: var(--internal-or-asset-viewer-title-text-color);
78
- flex: 0 0 auto;
79
- }
80
-
81
- .panel-title-text {
82
- flex: 1;
83
- text-transform: uppercase;
84
- white-space: nowrap;
85
- text-overflow: ellipsis;
86
- overflow: hidden;
87
- }
88
-
89
- .panel-content {
90
- display: flex;
91
- flex-direction: column;
92
- width: 100%;
93
- flex: 1;
94
- }
95
-
96
- .mainvalue-wrapper {
97
- width: 100%;
98
- display: flex;
99
- flex: 0 0 60px;
100
- align-items: center;
101
- justify-content: center;
102
- }
103
-
104
- .graph-wrapper {
105
- width: 100%;
106
- display: flex;
107
- flex: 1;
108
- align-items: center;
109
- }
110
-
111
- .main-number {
112
- color: var(--internal-or-asset-viewer-title-text-color);
113
- font-size: 42px;
114
- }
115
-
116
- .main-number-icon {
117
- font-size: 24px;
118
- margin-right: 10px;
119
- display: flex;
120
- }
121
-
122
- .main-number-unit {
123
- font-size: 42px;
124
- color: var(--internal-or-asset-viewer-title-text-color);
125
- font-weight: 200;
126
- margin-left: 5px;
127
- }
128
-
129
- .main-number.xs, .main-number-unit.xs {
130
- font-size: 18px;
131
- }
132
- .main-number.s, .main-number-unit.s {
133
- font-size: 24px;
134
- }
135
- .main-number.m, .main-number-unit.m {
136
- font-size: 30px;
137
- }
138
- .main-number.l, .main-number-unit.l {
139
- font-size: 36px;
140
- }
141
- .main-number.xl, .main-number-unit.xl {
142
- font-size: 42px;
143
- }
144
-
145
- .chart-wrapper {
146
- flex: 1 1 auto;
147
- width: 65%;
148
- height: 75%;
149
- }
150
- .controls-wrapper {
151
- flex: 0 0 80px;
152
- height: 100%;
153
- display: flex;
154
- flex-direction: column;
155
- align-items: end;
156
- place-content: space-between;
157
- }
158
-
159
- .delta-wrapper {
160
- /*flex: 0 0 50px;*/
161
- text-align: right;
162
-
163
- /*position: absolute;*/
164
- /*right: var(--internal-or-asset-viewer-panel-padding);*/
165
- }
166
-
167
- .date-range-wrapper {
168
- flex: 1;
169
- display: flex;
170
- justify-content: space-between;
171
- }
172
-
173
- .period-selector {
174
-
175
- }
176
-
177
- .delta {
178
- color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)});
179
- font-weight: bold;
180
- }
181
- `;
182
- let OrAttributeCard = class OrAttributeCard extends LitElement {
183
- static get styles() {
184
- return [
185
- style
186
- ];
187
- }
188
- constructor() {
189
- super();
190
- this.assets = [];
191
- this.assetAttributes = [];
192
- this.data = undefined;
193
- this.mainValueDecimals = 2;
194
- this.mainValueSize = "m";
195
- this.delta = undefined;
196
- this.deltaPlus = "";
197
- this.deltaFormat = "absolute";
198
- this.showControls = true;
199
- this.hideAttributePicker = false;
200
- this.showTitle = true;
201
- this._loading = false;
202
- this.period = "day";
203
- }
204
- connectedCallback() {
205
- super.connectedCallback();
206
- this._style = window.getComputedStyle(this);
207
- }
208
- disconnectedCallback() {
209
- super.disconnectedCallback();
210
- this._cleanup();
211
- }
212
- firstUpdated() {
213
- this.loadSettings();
214
- }
215
- updated(changedProperties) {
216
- if (changedProperties.has("realm") && changedProperties.get("realm") != undefined) {
217
- this.assets = [];
218
- this.loadSettings();
219
- }
220
- const reloadData = changedProperties.has("period") || changedProperties.has("compareTimestamp")
221
- || changedProperties.has("timestamp") || changedProperties.has("assetAttributes") || changedProperties.has("realm");
222
- if (reloadData) {
223
- this.data = undefined;
224
- if (this._chart) {
225
- this._chart.destroy();
226
- this._chart = undefined;
227
- }
228
- this.loadData();
229
- }
230
- if (!this.data || this.data.length === 0) {
231
- return;
232
- }
233
- if (!this._chart) {
234
- this._chart = new Chart(this._chartElem.getContext("2d"), {
235
- type: "line",
236
- data: {
237
- datasets: [
238
- {
239
- data: this.data.filter(value => value.y != null),
240
- tension: 0.1,
241
- spanGaps: true,
242
- backgroundColor: "transparent",
243
- borderColor: this._style.getPropertyValue("--internal-or-attribute-history-graph-line-color"),
244
- pointBorderColor: "transparent",
245
- }
246
- ]
247
- },
248
- options: {
249
- responsive: true,
250
- maintainAspectRatio: false,
251
- plugins: {
252
- legend: {
253
- display: false
254
- },
255
- tooltip: {
256
- displayColors: false,
257
- callbacks: {
258
- title: (context) => {
259
- return "";
260
- },
261
- // label: (context) => {
262
- // return context.parsed.y; // Removes the colon before the label
263
- // },
264
- footer: () => {
265
- return ""; // Hack the broken vertical alignment of body with footerFontSize: 0
266
- }
267
- }
268
- }
269
- },
270
- scales: {
271
- y: {
272
- display: false
273
- },
274
- x: {
275
- type: "time",
276
- min: this._startOfPeriod,
277
- max: this._endOfPeriod,
278
- display: false,
279
- }
280
- }
281
- }
282
- });
283
- }
284
- else {
285
- if (changedProperties.has("data")) {
286
- this._chart.data.datasets[0].data = this.data.filter(value => value.y != null);
287
- this._chart.update();
288
- this.delta = this.getFormattedDelta(this.getFirstKnownMeasurement(this.data), this.getLastKnownMeasurement(this.data));
289
- }
290
- }
291
- if (changedProperties.has("mainValue") || changedProperties.has("mainValueDecimals")) {
292
- this.formattedMainValue = this.getFormattedValue(this.mainValue);
293
- }
294
- if (changedProperties.has("delta")) {
295
- this.deltaPlus = this.delta && this.delta.val > 0 ? "+" : "";
296
- }
297
- }
298
- shouldHideAttributePicker() {
299
- return (this.hideAttributePicker && this.hideAttributePicker.toString() == "true");
300
- }
301
- shouldShowControls() {
302
- return (this.showControls && this.showControls.toString() == "true");
303
- }
304
- shouldShowTitle() {
305
- return (this.showTitle && this.showTitle.toString() == "true");
306
- }
307
- render() {
308
- if (!this._error && (!this.assets || !this.assetAttributes || this.assetAttributes.length === 0)) {
309
- return html `
310
- <div class="panel panel-empty">
311
- <div class="panel-content-wrapper">
312
- <div class="panel-content">
313
- ${!this.shouldHideAttributePicker() ? html `
314
- <or-mwc-input class="button" .type="${InputType.BUTTON}" label="selectAttribute" icon="plus" @or-mwc-input-changed="${() => this._openDialog("editAttribute")}"></or-mwc-input>
315
- ` : html `
316
- <span style="text-align: center;">${i18next.t('noAttributeConnected')}</span>
317
- `}
318
- </div>
319
- </div>
320
- </div>
321
- `;
322
- }
323
- this.updateComplete.then(() => {
324
- this.resizeObserver = new ResizeObserver(debounce((entries) => {
325
- const elemSize = entries[0].devicePixelContentBoxSize[0].inlineSize;
326
- this.setLabelSizeByWidth(elemSize);
327
- }, 200));
328
- this.resizeObserver.observe(this.shadowRoot.querySelector(".graph-wrapper"));
329
- });
330
- return html `
331
- <div class="panel" id="attribute-card">
332
- <div class="panel-content-wrapper">
333
- <div class="panel-title">
334
- ${this.shouldShowTitle() ? html `<span class="panel-title-text">${this.assets[0].name + " - " + i18next.t(this.assetAttributes[0][1].name)}</span>` : undefined}
335
- ${this.shouldShowTitle() ? getContentWithMenuTemplate(html `
336
- <or-mwc-input icon="dots-vertical" type="button"></or-mwc-input>
337
- `, [
338
- {
339
- text: i18next.t("editAttribute"),
340
- value: "editAttribute"
341
- },
342
- {
343
- text: i18next.t("editDelta"),
344
- value: "editDelta"
345
- },
346
- {
347
- text: i18next.t("editCurrentValue"),
348
- value: "editCurrentValue"
349
- },
350
- {
351
- text: i18next.t("delete"),
352
- value: "delete"
353
- }
354
- ], undefined, (option) => this.handleMenuSelect(option)) : undefined}
355
- </div>
356
- <div class="panel-content">
357
- <div class="mainvalue-wrapper">
358
- ${when(!this._loading, () => html `
359
- <span class="main-number-icon">${this.assets && this.assets.length === 1 ? getAssetDescriptorIconTemplate(AssetModelUtil.getAssetDescriptor(this.assets[0].type)) : ""}</span>
360
- <span class="main-number ${this.mainValueSize}">${this.formattedMainValue ? this.formattedMainValue.value : ""}</span>
361
- <span class="main-number-unit ${this.mainValueSize}">${this.formattedMainValue ? this.formattedMainValue.unit : ""}</span>
362
- `)}
363
- </div>
364
- <div class="graph-wrapper">
365
-
366
- ${when(this._error, () => html `
367
- <div style="flex: 0 0 80px;"></div>
368
- <or-translate .value="${this._error}" style="flex: 1; text-align: center;"></or-translate>
369
- `, () => html `
370
- <div class="chart-wrapper">
371
- ${when(this._loading, () => html `
372
- <or-loading-indicator></or-loading-indicator>
373
- `, () => html `
374
- <canvas id="chart"></canvas>
375
- `)}
376
- </div>
377
- `)}
378
-
379
- <div class="controls-wrapper">
380
- <div class="delta-wrapper">
381
- <span class="delta">${this.delta ? this.deltaPlus + (this.delta.val !== undefined && this.delta.val !== null ? this.delta.val : "") + (this.delta.unit || "") : ""}</span>
382
- </div>
383
- ${this.shouldShowControls() ? html `
384
- <div class="period-selector-wrapper">
385
- ${getContentWithMenuTemplate(html `<or-mwc-input class="period-selector" .type="${InputType.BUTTON}" label="${this.period ? this.period : '-'}"></or-mwc-input>`, [{ value: "hour", text: "hour" }, { value: "day", text: "day" }, { value: "week", text: "week" }, { value: "month", text: "month" }, { value: "year", text: "year" }].map((option) => {
386
- option.text = i18next.t(option.value);
387
- return option;
388
- }), this.period, (value) => this._setPeriodOption(value), undefined, // closedCallback
389
- false, // multiSelect
390
- true, // translateValues
391
- false, // midHeight
392
- false, // fullWidth
393
- "kpi-menu-id", // Menu Id
394
- true // fixToHost
395
- )}
396
- </div>
397
- ` : html `
398
- <or-mwc-input class="period-selector" .type="${InputType.BUTTON}" disabled .label="${i18next.t(this.period ? this.period : "-")}"></or-mwc-input>
399
- `}
400
- </div>
401
- </div>
402
- </div>
403
- </div>
404
- </div>
405
- `;
406
- }
407
- _openDialog(dialogContent) {
408
- let dialog;
409
- switch (dialogContent) {
410
- case "editDelta":
411
- case "editCurrentValue":
412
- dialog = new OrMwcDialog()
413
- .setHeading(i18next.t(dialogContent))
414
- .setDismissAction(null)
415
- .setContent(dialogContent === "editDelta"
416
- ? html `
417
- <or-mwc-input id="delta-mode-picker" value="${this.deltaFormat}" @or-mwc-input-changed="${(evt) => { this.deltaFormat = evt.detail.value; this.saveSettings(); }}" .type="${InputType.LIST}" .options="${[
418
- ["percentage", "Percentage"],
419
- ["absolute", "Absolute"]
420
- ]}"></or-mwc-input>
421
- `
422
- : html `
423
- <or-mwc-input id="current-value-decimals" .label="${i18next.t("decimals")}" value="${this.mainValueDecimals}" .type="${InputType.TEXT}"></or-mwc-input>
424
- `)
425
- .setActions([
426
- {
427
- actionName: "cancel",
428
- content: html `<or-mwc-input class="button" .type="${InputType.BUTTON}" label="cancel"></or-mwc-input>`,
429
- action: () => {
430
- // Nothing to do here
431
- }
432
- },
433
- {
434
- actionName: "yes",
435
- default: true,
436
- content: html `<or-mwc-input class="button" .type="${InputType.BUTTON}" label="ok" data-mdc-dialog-action="yes"></or-mwc-input>`,
437
- action: () => {
438
- if (dialogContent === "editDelta") {
439
- this.delta = this.data ? this.getFormattedDelta(this.getFirstKnownMeasurement(this.data), this.getLastKnownMeasurement(this.data)) : undefined;
440
- }
441
- else {
442
- if (dialog && dialog.shadowRoot && dialog.shadowRoot.getElementById("current-value-decimals")) {
443
- const elm = dialog.shadowRoot.getElementById("current-value-decimals");
444
- const input = parseInt(elm.value, 10);
445
- if (input < 0) {
446
- this.mainValueDecimals = 0;
447
- }
448
- else if (input > 10) {
449
- this.mainValueDecimals = 10;
450
- }
451
- else {
452
- this.mainValueDecimals = input;
453
- }
454
- this.formattedMainValue = this.getFormattedValue(this.mainValue);
455
- this.saveSettings();
456
- }
457
- }
458
- }
459
- }
460
- ]);
461
- dialog.addEventListener(OrAssetTreeSelectionEvent.NAME, (ev) => __awaiter(this, void 0, void 0, function* () {
462
- const selectedNode = ev.detail && ev.detail.newNodes.length > 0 ? ev.detail.newNodes[0] : undefined;
463
- if (!selectedNode) {
464
- this.asset = undefined;
465
- }
466
- else {
467
- // fully load the asset
468
- const assetEvent = yield manager.events.sendEventWithReply({
469
- eventType: "read-asset",
470
- assetId: selectedNode.asset.id
471
- });
472
- this.asset = assetEvent.asset;
473
- }
474
- }));
475
- break;
476
- default:
477
- dialog = new OrAssetAttributePicker()
478
- .setHeading(i18next.t("selectAttribute"));
479
- dialog.addEventListener(OrAssetAttributePickerPickedEvent.NAME, (ev) => __awaiter(this, void 0, void 0, function* () {
480
- // handle selected attrs
481
- const attrRef = ev.detail[0];
482
- try {
483
- const response = yield manager.rest.api.AssetResource.get(attrRef.id);
484
- this.asset = response.data;
485
- this._setAttribute(attrRef.name);
486
- }
487
- catch (e) {
488
- console.error("Failed to get assets requested in settings", e);
489
- }
490
- }));
491
- break;
492
- }
493
- if (dialog) {
494
- showDialog(dialog);
495
- }
496
- }
497
- _setAttribute(attributeName) {
498
- if (this.asset && attributeName) {
499
- const attr = this.asset.attributes ? this.asset.attributes[attributeName] : undefined;
500
- this.assets = [this.asset];
501
- this.assetAttributes = attr ? [[0, attr]] : [];
502
- this.saveSettings();
503
- }
504
- }
505
- _cleanup() {
506
- if (this._chart) {
507
- this._chart.destroy();
508
- this._chart = undefined;
509
- }
510
- }
511
- loadSettings() {
512
- return __awaiter(this, arguments, void 0, function* (reset = false) {
513
- this.assetAttributes = [];
514
- if (!this.period || reset) {
515
- this.period = "day";
516
- }
517
- if (!this.deltaFormat || reset) {
518
- this.deltaFormat = "absolute";
519
- }
520
- if (!this.mainValueDecimals || reset) {
521
- this.mainValueDecimals = 0;
522
- }
523
- if (!this.realm) {
524
- this.realm = manager.getRealm();
525
- }
526
- let allConfigs = (yield manager.console.retrieveData("OrChartConfig")) || [];
527
- if (!Array.isArray(allConfigs)) {
528
- allConfigs = [allConfigs];
529
- }
530
- if (allConfigs.length === 0 || !this.panelName) {
531
- return;
532
- }
533
- const viewSelector = window.location.hash;
534
- let config = allConfigs.find(e => e.realm === this.realm);
535
- const view = config && config.views && config.views[viewSelector] ? config.views[viewSelector][this.panelName] : undefined;
536
- if (!view) {
537
- return;
538
- }
539
- if (!view.attributeRefs) {
540
- // Old/invalid config format remove it
541
- delete config.views[viewSelector][this.panelName];
542
- const cleanData = [...allConfigs.filter(e => e.realm !== this.realm), config];
543
- manager.console.storeData("OrChartConfig", cleanData);
544
- return;
545
- }
546
- const assetIds = view.attributeRefs.map((attrRef) => attrRef.id);
547
- if (assetIds.length === 0) {
548
- return;
549
- }
550
- this._loading = true;
551
- if (!assetIds.every(id => !!this.assets.find(asset => asset.id === id))) {
552
- const query = {
553
- ids: assetIds
554
- };
555
- try {
556
- const response = yield manager.rest.api.AssetResource.queryAssets(query);
557
- const assets = response.data || [];
558
- view.attributeRefs = view.attributeRefs.filter((attrRef) => !!assets.find((asset) => asset.id === attrRef.id && asset.attributes && asset.attributes.hasOwnProperty(attrRef.name)));
559
- allConfigs = [...allConfigs.filter(e => e.realm !== this.realm), config];
560
- manager.console.storeData("OrChartConfig", allConfigs);
561
- this.assets = assets.filter((asset) => view.attributeRefs.find((attrRef) => attrRef.id === asset.id));
562
- }
563
- catch (e) {
564
- console.error("Failed to get assets requested in settings", e);
565
- }
566
- this._loading = false;
567
- if (this.assets && this.assets.length > 0) {
568
- this.assetAttributes = view.attributeRefs.map((attrRef) => {
569
- const assetIndex = this.assets.findIndex((asset) => asset.id === attrRef.id);
570
- const asset = assetIndex >= 0 ? this.assets[assetIndex] : undefined;
571
- return asset && asset.attributes ? [assetIndex, asset.attributes[attrRef.name]] : undefined;
572
- }).filter((indexAndAttr) => !!indexAndAttr);
573
- this.period = view.period || "day";
574
- this.mainValueDecimals = view.decimals || 0;
575
- this.deltaFormat = view.deltaFormat || "absolute";
576
- }
577
- }
578
- });
579
- }
580
- saveSettings() {
581
- return __awaiter(this, void 0, void 0, function* () {
582
- if (!this.panelName) {
583
- return;
584
- }
585
- const viewSelector = window.location.hash;
586
- let allConfigs = (yield manager.console.retrieveData("OrChartConfig")) || [];
587
- let config = allConfigs.find(e => e.realm === this.realm);
588
- if (!config) {
589
- config = {
590
- realm: this.realm,
591
- views: {}
592
- };
593
- }
594
- if (!config.views[viewSelector]) {
595
- config.views[viewSelector] = {};
596
- }
597
- if (!this.assets || !this.assetAttributes || this.assets.length === 0 || this.assetAttributes.length === 0) {
598
- delete config.views[viewSelector][this.panelName];
599
- }
600
- else {
601
- config.realm = this.realm;
602
- config.views[viewSelector][this.panelName] = {
603
- attributeRefs: this.assetAttributes.map(([index, attr]) => {
604
- const asset = this.assets[index];
605
- return !!asset ? { id: asset.id, name: attr.name } : undefined;
606
- }).filter((attrRef) => !!attrRef),
607
- period: this.period,
608
- deltaFormat: this.deltaFormat,
609
- decimals: this.mainValueDecimals
610
- };
611
- }
612
- allConfigs = [...allConfigs.filter(e => e.realm !== this.realm), config];
613
- manager.console.storeData("OrChartConfig", allConfigs);
614
- });
615
- }
616
- loadData() {
617
- return __awaiter(this, void 0, void 0, function* () {
618
- var _a;
619
- if (this.data || !this.assetAttributes || !this.assets || this.assets.length === 0 || this.assetAttributes.length === 0 || !this.period) {
620
- return;
621
- }
622
- // If a new requests comes in, we override it with this one using AbortController.
623
- if (this._dataAbortController) {
624
- this._dataAbortController.abort("Data request overridden");
625
- delete this._dataAbortController;
626
- }
627
- this._loading = true;
628
- let interval = "HOUR" /* DatapointInterval.HOUR */;
629
- let stepSize = 1;
630
- switch (this.period) {
631
- case "hour":
632
- interval = "MINUTE" /* DatapointInterval.MINUTE */;
633
- stepSize = 5;
634
- break;
635
- case "day":
636
- interval = "HOUR" /* DatapointInterval.HOUR */;
637
- stepSize = 1;
638
- break;
639
- case "week":
640
- interval = "HOUR" /* DatapointInterval.HOUR */;
641
- stepSize = 6;
642
- break;
643
- case "month":
644
- interval = "DAY" /* DatapointInterval.DAY */;
645
- stepSize = 1;
646
- break;
647
- case "year":
648
- interval = "MONTH" /* DatapointInterval.MONTH */;
649
- stepSize = 1;
650
- break;
651
- }
652
- const lowerCaseInterval = interval.toLowerCase();
653
- this._startOfPeriod = moment().subtract(1, this.period).toDate().getTime();
654
- this._endOfPeriod = moment().toDate().getTime();
655
- const assetId = this.assets[0].id;
656
- const attributeName = this.assetAttributes[0][1].name;
657
- this._dataAbortController = new AbortController();
658
- try {
659
- const response = yield manager.rest.api.AssetDatapointResource.getDatapoints(assetId, attributeName, { type: "lttb", fromTimestamp: this._startOfPeriod, toTimestamp: this._endOfPeriod, amountOfPoints: 20 }, { signal: this._dataAbortController.signal });
660
- this._loading = false;
661
- if (response.status === 200) {
662
- this.data = response.data;
663
- this.delta = this.getFormattedDelta(this.getFirstKnownMeasurement(this.data), this.getLastKnownMeasurement(this.data));
664
- this.deltaPlus = this.delta && this.delta.val > 0 ? "+" : "";
665
- this._error = undefined;
666
- }
667
- }
668
- catch (ex) {
669
- console.error(ex);
670
- if ((ex === null || ex === void 0 ? void 0 : ex.message) === "canceled") {
671
- return; // If request has been canceled (using AbortController); return, and prevent _loading is set to false.
672
- }
673
- this._loading = false;
674
- if (isAxiosError(ex)) {
675
- if (ex.message.includes("timeout")) {
676
- this._error = "noAttributeDataTimeout";
677
- return;
678
- }
679
- else if (((_a = ex.response) === null || _a === void 0 ? void 0 : _a.status) === 413) {
680
- this._error = "datapointRequestTooLarge";
681
- return;
682
- }
683
- }
684
- this._error = "couldNotRetrieveAttribute";
685
- }
686
- finally {
687
- // Finally, request the current value through WS request/response
688
- this.mainValue = undefined;
689
- this.formattedMainValue = undefined;
690
- const currentValue = yield manager.events.sendEventWithReply({
691
- eventType: "read-asset-attribute",
692
- ref: {
693
- id: assetId,
694
- name: attributeName
695
- }
696
- });
697
- this.mainValue = currentValue.value;
698
- this.formattedMainValue = this.getFormattedValue(this.mainValue);
699
- }
700
- });
701
- }
702
- getTotalValue(data) {
703
- return data.reduce((acc, val) => {
704
- return val.y ? acc + Math.round(val.y) : acc;
705
- }, 0);
706
- }
707
- getHighestValue(data) {
708
- return Math.max.apply(Math, data.map((e) => e.y || false));
709
- }
710
- getFormattedValue(value) {
711
- if (value === undefined || !this.assets || !this.assetAttributes || this.assets.length === 0 || this.assetAttributes.length === 0) {
712
- return;
713
- }
714
- const attr = this.assetAttributes[0][1];
715
- const roundedVal = +(value === null || value === void 0 ? void 0 : value.toFixed(this.mainValueDecimals)); // + operator prevents str return
716
- const attributeDescriptor = AssetModelUtil.getAttributeDescriptor(attr.name, this.assets[0].type);
717
- const units = Util.resolveUnits(Util.getAttributeUnits(attr, attributeDescriptor, this.assets[0].type));
718
- this.setLabelSizeByLength(roundedVal.toString());
719
- if (!units) {
720
- return { value: roundedVal, unit: "" };
721
- }
722
- return {
723
- value: roundedVal,
724
- unit: units
725
- };
726
- }
727
- getFirstKnownMeasurement(data) {
728
- for (let i = 0; i <= data.length; i++) {
729
- if (data[i] && data[i].y !== undefined)
730
- return data[i].y;
731
- }
732
- return 0;
733
- }
734
- getLastKnownMeasurement(data) {
735
- for (let i = data.length - 1; i >= 0; i--) {
736
- if (data[i] && data[i].y !== undefined)
737
- return data[i].y;
738
- }
739
- return 0;
740
- }
741
- getFormattedDelta(firstVal, lastVal) {
742
- if (this.deltaFormat === "percentage") {
743
- if (firstVal && lastVal) {
744
- if (lastVal === 0 && firstVal === 0) {
745
- return { val: 0, unit: "%" };
746
- }
747
- else if (lastVal === 0 && firstVal !== 0) {
748
- return { val: 100, unit: "%" };
749
- }
750
- else {
751
- const math = Math.round((lastVal - firstVal) / firstVal * 100);
752
- return { val: math, unit: "%" };
753
- }
754
- }
755
- else {
756
- return { val: 0, unit: "%" };
757
- }
758
- }
759
- return { val: Math.round(lastVal - firstVal), unit: "" };
760
- }
761
- handleMenuSelect(value) {
762
- if (value === "delete") {
763
- this.assets = [];
764
- this.assetAttributes = [];
765
- this.saveSettings();
766
- }
767
- else {
768
- this._openDialog(value);
769
- }
770
- }
771
- setLabelSizeByLength(value) {
772
- if (value.length >= 20) {
773
- this.mainValueSize = "xs";
774
- }
775
- if (value.length < 20) {
776
- this.mainValueSize = "s";
777
- }
778
- if (value.length < 15) {
779
- this.mainValueSize = "m";
780
- }
781
- if (value.length < 10) {
782
- this.mainValueSize = "l";
783
- }
784
- if (value.length < 5) {
785
- this.mainValueSize = "xl";
786
- }
787
- }
788
- setLabelSizeByWidth(inlineSize) {
789
- if (inlineSize < 60) {
790
- this.mainValueSize = "s";
791
- }
792
- else if (inlineSize < 100) {
793
- this.mainValueSize = "m";
794
- }
795
- else if (inlineSize < 200) {
796
- this.mainValueSize = "l";
797
- }
798
- else {
799
- this.mainValueSize = "xl";
800
- }
801
- }
802
- _setPeriodOption(value) {
803
- this.period = value;
804
- this.saveSettings();
805
- }
806
- };
807
- __decorate([
808
- property()
809
- ], OrAttributeCard.prototype, "panelName", void 0);
810
- __decorate([
811
- property({ type: Object })
812
- ], OrAttributeCard.prototype, "assets", void 0);
813
- __decorate([
814
- property({ type: Object })
815
- ], OrAttributeCard.prototype, "assetAttributes", void 0);
816
- __decorate([
817
- property()
818
- ], OrAttributeCard.prototype, "data", void 0);
819
- __decorate([
820
- property({ type: String })
821
- ], OrAttributeCard.prototype, "realm", void 0);
822
- __decorate([
823
- property()
824
- ], OrAttributeCard.prototype, "mainValue", void 0);
825
- __decorate([
826
- property()
827
- ], OrAttributeCard.prototype, "mainValueDecimals", void 0);
828
- __decorate([
829
- property()
830
- ], OrAttributeCard.prototype, "mainValueSize", void 0);
831
- __decorate([
832
- property()
833
- ], OrAttributeCard.prototype, "delta", void 0);
834
- __decorate([
835
- property()
836
- ], OrAttributeCard.prototype, "deltaPlus", void 0);
837
- __decorate([
838
- property()
839
- ], OrAttributeCard.prototype, "deltaFormat", void 0);
840
- __decorate([
841
- property()
842
- ], OrAttributeCard.prototype, "showControls", void 0);
843
- __decorate([
844
- property()
845
- ], OrAttributeCard.prototype, "hideAttributePicker", void 0);
846
- __decorate([
847
- property()
848
- ], OrAttributeCard.prototype, "showTitle", void 0);
849
- __decorate([
850
- property()
851
- ], OrAttributeCard.prototype, "_loading", void 0);
852
- __decorate([
853
- property()
854
- ], OrAttributeCard.prototype, "period", void 0);
855
- __decorate([
856
- state()
857
- ], OrAttributeCard.prototype, "_error", void 0);
858
- __decorate([
859
- query("#chart")
860
- ], OrAttributeCard.prototype, "_chartElem", void 0);
861
- OrAttributeCard = __decorate([
862
- customElement("or-attribute-card")
863
- ], OrAttributeCard);
864
- export { OrAttributeCard };
865
- //# sourceMappingURL=index.js.map
1
+ var __decorate=this&&this.__decorate||function(t,e,i,a){var s,r=arguments.length,o=r<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,a);else for(var n=t.length-1;n>=0;n--)(s=t[n])&&(o=(r<3?s(o):r>3?s(e,i,o):s(e,i))||o);return r>3&&o&&Object.defineProperty(e,i,o),o},__awaiter=this&&this.__awaiter||function(t,e,i,a){return new(i||(i=Promise))(function(s,r){function o(t){try{l(a.next(t))}catch(t){r(t)}}function n(t){try{l(a.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):((e=t.value)instanceof i?e:new i(function(t){t(e)})).then(o,n)}l((a=a.apply(t,e||[])).next())})};import{css as t,html as e,LitElement as i,unsafeCSS as a}from"lit";import{customElement as s,property as r,state as o,query as n}from"lit/decorators.js";import l from"i18next";import{AssetModelUtil as d}from"@openremote/model";import{DefaultColor3 as h,DefaultColor4 as u,manager as p,Util as c}from"@openremote/core";import{isAxiosError as m}from"@openremote/rest";import{Chart as v,LineController as f,LineElement as b,PointElement as g,LinearScale as w,TimeSeriesScale as y,Title as _}from"chart.js";import"chartjs-adapter-moment";import{InputType as x}from"@openremote/or-mwc-components/or-mwc-input";import{getAssetDescriptorIconTemplate as A}from"@openremote/or-icon";import"@openremote/or-mwc-components/or-mwc-dialog";import"@openremote/or-attribute-picker";import C from"moment";import{OrAssetTreeSelectionEvent as O}from"@openremote/or-asset-tree";import{OrMwcDialog as V,showDialog as S}from"@openremote/or-mwc-components/or-mwc-dialog";import{OrAssetAttributePicker as D,OrAssetAttributePickerPickedEvent as $}from"@openremote/or-attribute-picker";import{getContentWithMenuTemplate as T}from"@openremote/or-mwc-components/or-mwc-menu";import{when as z}from"lit/directives/when.js";import{debounce as M}from"lodash";v.register(f,b,g,w,_,y);let style=t`
2
+
3
+ :host {
4
+ --internal-or-attribute-history-graph-line-color: var(--or-attribute-history-graph-line-color, var(--or-app-color4, ${a(u)}));
5
+ width: 100%;
6
+ }
7
+
8
+ :host([hidden]) {
9
+ display: none;
10
+ }
11
+
12
+ .panel {
13
+ position: relative;
14
+ height: 100%;
15
+ }
16
+ .panel.panel-empty {
17
+ display: flex;
18
+ }
19
+ .panel.panel-empty .panel-content-wrapper {
20
+ align-items: center;
21
+ width: 100%;
22
+ }
23
+ .panel.panel-empty .panel-content {
24
+ align-items: center;
25
+ justify-content: center;
26
+ flex-direction: column;
27
+ }
28
+
29
+ .panel-content-wrapper {
30
+ height: 100%;
31
+ display: flex;
32
+ flex-direction: column;
33
+ }
34
+
35
+ .panel-title {
36
+ display: flex;
37
+ align-items: center;
38
+ /*margin: -15px -15px 0 0;*/ /* compensate for the click-space of the plusminus button */
39
+ font-weight: bolder;
40
+ line-height: 1em;
41
+ color: var(--internal-or-asset-viewer-title-text-color);
42
+ flex: 0 0 auto;
43
+ }
44
+
45
+ .panel-title-text {
46
+ flex: 1;
47
+ text-transform: uppercase;
48
+ white-space: nowrap;
49
+ text-overflow: ellipsis;
50
+ overflow: hidden;
51
+ }
52
+
53
+ .panel-content {
54
+ display: flex;
55
+ flex-direction: column;
56
+ width: 100%;
57
+ flex: 1;
58
+ }
59
+
60
+ .mainvalue-wrapper {
61
+ width: 100%;
62
+ display: flex;
63
+ flex: 0 0 60px;
64
+ align-items: center;
65
+ justify-content: center;
66
+ }
67
+
68
+ .graph-wrapper {
69
+ width: 100%;
70
+ display: flex;
71
+ flex: 1;
72
+ align-items: center;
73
+ }
74
+
75
+ .main-number {
76
+ color: var(--internal-or-asset-viewer-title-text-color);
77
+ font-size: 42px;
78
+ }
79
+
80
+ .main-number-icon {
81
+ font-size: 24px;
82
+ margin-right: 10px;
83
+ display: flex;
84
+ }
85
+
86
+ .main-number-unit {
87
+ font-size: 42px;
88
+ color: var(--internal-or-asset-viewer-title-text-color);
89
+ font-weight: 200;
90
+ margin-left: 5px;
91
+ }
92
+
93
+ .main-number.xs, .main-number-unit.xs {
94
+ font-size: 18px;
95
+ }
96
+ .main-number.s, .main-number-unit.s {
97
+ font-size: 24px;
98
+ }
99
+ .main-number.m, .main-number-unit.m {
100
+ font-size: 30px;
101
+ }
102
+ .main-number.l, .main-number-unit.l {
103
+ font-size: 36px;
104
+ }
105
+ .main-number.xl, .main-number-unit.xl {
106
+ font-size: 42px;
107
+ }
108
+
109
+ .chart-wrapper {
110
+ flex: 1 1 auto;
111
+ width: 65%;
112
+ height: 75%;
113
+ }
114
+ .controls-wrapper {
115
+ flex: 0 0 80px;
116
+ height: 100%;
117
+ display: flex;
118
+ flex-direction: column;
119
+ align-items: end;
120
+ place-content: space-between;
121
+ }
122
+
123
+ .delta-wrapper {
124
+ /*flex: 0 0 50px;*/
125
+ text-align: right;
126
+
127
+ /*position: absolute;*/
128
+ /*right: var(--internal-or-asset-viewer-panel-padding);*/
129
+ }
130
+
131
+ .date-range-wrapper {
132
+ flex: 1;
133
+ display: flex;
134
+ justify-content: space-between;
135
+ }
136
+
137
+ .period-selector {
138
+
139
+ }
140
+
141
+ .delta {
142
+ color: var(--or-app-color3, ${a(h)});
143
+ font-weight: bold;
144
+ }
145
+ `,OrAttributeCard=class extends i{static get styles(){return[style]}constructor(){super(),this.assets=[],this.assetAttributes=[],this.data=void 0,this.mainValueDecimals=2,this.mainValueSize="m",this.delta=void 0,this.deltaPlus="",this.deltaFormat="absolute",this.showControls=!0,this.hideAttributePicker=!1,this.showTitle=!0,this._loading=!1,this.period="day"}connectedCallback(){super.connectedCallback(),this._style=window.getComputedStyle(this)}disconnectedCallback(){super.disconnectedCallback(),this._cleanup()}firstUpdated(){this.loadSettings()}updated(t){t.has("realm")&&void 0!=t.get("realm")&&(this.assets=[],this.loadSettings()),(t.has("period")||t.has("compareTimestamp")||t.has("timestamp")||t.has("assetAttributes")||t.has("realm"))&&(this.data=void 0,this._chart&&(this._chart.destroy(),this._chart=void 0),this.loadData()),this.data&&0!==this.data.length&&(this._chart?t.has("data")&&(this._chart.data.datasets[0].data=this.data.filter(t=>null!=t.y),this._chart.update(),this.delta=this.getFormattedDelta(this.getFirstKnownMeasurement(this.data),this.getLastKnownMeasurement(this.data))):this._chart=new v(this._chartElem.getContext("2d"),{type:"line",data:{datasets:[{data:this.data.filter(t=>null!=t.y),tension:.1,spanGaps:!0,backgroundColor:"transparent",borderColor:this._style.getPropertyValue("--internal-or-attribute-history-graph-line-color"),pointBorderColor:"transparent"}]},options:{responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{displayColors:!1,callbacks:{title:t=>"",footer:()=>""}}},scales:{y:{display:!1},x:{type:"time",min:this._startOfPeriod,max:this._endOfPeriod,display:!1}}}}),(t.has("mainValue")||t.has("mainValueDecimals"))&&(this.formattedMainValue=this.getFormattedValue(this.mainValue)),t.has("delta")&&(this.deltaPlus=this.delta&&this.delta.val>0?"+":""))}shouldHideAttributePicker(){return this.hideAttributePicker&&"true"==this.hideAttributePicker.toString()}shouldShowControls(){return this.showControls&&"true"==this.showControls.toString()}shouldShowTitle(){return this.showTitle&&"true"==this.showTitle.toString()}render(){return this._error||this.assets&&this.assetAttributes&&0!==this.assetAttributes.length?(this.updateComplete.then(()=>{this.resizeObserver=new ResizeObserver(M(t=>{let e=t[0].devicePixelContentBoxSize[0].inlineSize;this.setLabelSizeByWidth(e)},200)),this.resizeObserver.observe(this.shadowRoot.querySelector(".graph-wrapper"))}),e`
146
+ <div class="panel" id="attribute-card">
147
+ <div class="panel-content-wrapper">
148
+ <div class="panel-title">
149
+ ${this.shouldShowTitle()?e`<span class="panel-title-text">${this.assets[0].name+" - "+l.t(this.assetAttributes[0][1].name)}</span>`:void 0}
150
+ ${this.shouldShowTitle()?T(e`
151
+ <or-mwc-input icon="dots-vertical" type="button"></or-mwc-input>
152
+ `,[{text:l.t("editAttribute"),value:"editAttribute"},{text:l.t("editDelta"),value:"editDelta"},{text:l.t("editCurrentValue"),value:"editCurrentValue"},{text:l.t("delete"),value:"delete"}],void 0,t=>this.handleMenuSelect(t)):void 0}
153
+ </div>
154
+ <div class="panel-content">
155
+ <div class="mainvalue-wrapper">
156
+ ${z(!this._loading,()=>e`
157
+ <span class="main-number-icon">${this.assets&&1===this.assets.length?A(d.getAssetDescriptor(this.assets[0].type)):""}</span>
158
+ <span class="main-number ${this.mainValueSize}">${this.formattedMainValue?this.formattedMainValue.value:""}</span>
159
+ <span class="main-number-unit ${this.mainValueSize}">${this.formattedMainValue?this.formattedMainValue.unit:""}</span>
160
+ `)}
161
+ </div>
162
+ <div class="graph-wrapper">
163
+
164
+ ${z(this._error,()=>e`
165
+ <div style="flex: 0 0 80px;"></div>
166
+ <or-translate .value="${this._error}" style="flex: 1; text-align: center;"></or-translate>
167
+ `,()=>e`
168
+ <div class="chart-wrapper">
169
+ ${z(this._loading,()=>e`
170
+ <or-loading-indicator></or-loading-indicator>
171
+ `,()=>e`
172
+ <canvas id="chart"></canvas>
173
+ `)}
174
+ </div>
175
+ `)}
176
+
177
+ <div class="controls-wrapper">
178
+ <div class="delta-wrapper">
179
+ <span class="delta">${this.delta?this.deltaPlus+(void 0!==this.delta.val&&null!==this.delta.val?this.delta.val:"")+(this.delta.unit||""):""}</span>
180
+ </div>
181
+ ${this.shouldShowControls()?e`
182
+ <div class="period-selector-wrapper">
183
+ ${T(e`<or-mwc-input class="period-selector" .type="${x.BUTTON}" label="${this.period?this.period:"-"}"></or-mwc-input>`,[{value:"hour",text:"hour"},{value:"day",text:"day"},{value:"week",text:"week"},{value:"month",text:"month"},{value:"year",text:"year"}].map(t=>(t.text=l.t(t.value),t)),this.period,t=>this._setPeriodOption(t),void 0,!1,!0,!1,!1,"kpi-menu-id",!0)}
184
+ </div>
185
+ `:e`
186
+ <or-mwc-input class="period-selector" .type="${x.BUTTON}" disabled .label="${l.t(this.period?this.period:"-")}"></or-mwc-input>
187
+ `}
188
+ </div>
189
+ </div>
190
+ </div>
191
+ </div>
192
+ </div>
193
+ `):e`
194
+ <div class="panel panel-empty">
195
+ <div class="panel-content-wrapper">
196
+ <div class="panel-content">
197
+ ${!this.shouldHideAttributePicker()?e`
198
+ <or-mwc-input class="button" .type="${x.BUTTON}" label="selectAttribute" icon="plus" @or-mwc-input-changed="${()=>this._openDialog("editAttribute")}"></or-mwc-input>
199
+ `:e`
200
+ <span style="text-align: center;">${l.t("noAttributeConnected")}</span>
201
+ `}
202
+ </div>
203
+ </div>
204
+ </div>
205
+ `}_openDialog(t){let i;switch(t){case"editDelta":case"editCurrentValue":(i=new V().setHeading(l.t(t)).setDismissAction(null).setContent("editDelta"===t?e`
206
+ <or-mwc-input id="delta-mode-picker" value="${this.deltaFormat}" @or-mwc-input-changed="${t=>{this.deltaFormat=t.detail.value,this.saveSettings()}}" .type="${x.LIST}" .options="${[["percentage","Percentage"],["absolute","Absolute"]]}"></or-mwc-input>
207
+ `:e`
208
+ <or-mwc-input id="current-value-decimals" .label="${l.t("decimals")}" value="${this.mainValueDecimals}" .type="${x.TEXT}"></or-mwc-input>
209
+ `).setActions([{actionName:"cancel",content:e`<or-mwc-input class="button" .type="${x.BUTTON}" label="cancel"></or-mwc-input>`,action:()=>{}},{actionName:"yes",default:!0,content:e`<or-mwc-input class="button" .type="${x.BUTTON}" label="ok" data-mdc-dialog-action="yes"></or-mwc-input>`,action:()=>{if("editDelta"===t)this.delta=this.data?this.getFormattedDelta(this.getFirstKnownMeasurement(this.data),this.getLastKnownMeasurement(this.data)):void 0;else if(i&&i.shadowRoot&&i.shadowRoot.getElementById("current-value-decimals")){let t=parseInt(i.shadowRoot.getElementById("current-value-decimals").value,10);t<0?this.mainValueDecimals=0:t>10?this.mainValueDecimals=10:this.mainValueDecimals=t,this.formattedMainValue=this.getFormattedValue(this.mainValue),this.saveSettings()}}}])).addEventListener(O.NAME,t=>__awaiter(this,void 0,void 0,function*(){let e=t.detail&&t.detail.newNodes.length>0?t.detail.newNodes[0]:void 0;if(e){let t=yield p.events.sendEventWithReply({eventType:"read-asset",assetId:e.asset.id});this.asset=t.asset}else this.asset=void 0}));break;default:(i=new D().setHeading(l.t("selectAttribute"))).addEventListener($.NAME,t=>__awaiter(this,void 0,void 0,function*(){let e=t.detail[0];try{let t=yield p.rest.api.AssetResource.get(e.id);this.asset=t.data,this._setAttribute(e.name)}catch(t){console.error("Failed to get assets requested in settings",t)}}))}i&&S(i)}_setAttribute(t){if(this.asset&&t){let e=this.asset.attributes?this.asset.attributes[t]:void 0;this.assets=[this.asset],this.assetAttributes=e?[[0,e]]:[],this.saveSettings()}}_cleanup(){this._chart&&(this._chart.destroy(),this._chart=void 0)}loadSettings(){return __awaiter(this,arguments,void 0,function*(t=!1){this.assetAttributes=[],(!this.period||t)&&(this.period="day"),(!this.deltaFormat||t)&&(this.deltaFormat="absolute"),(!this.mainValueDecimals||t)&&(this.mainValueDecimals=0),this.realm||(this.realm=p.getRealm());let e=(yield p.console.retrieveData("OrChartConfig"))||[];if(Array.isArray(e)||(e=[e]),0===e.length||!this.panelName)return;let i=window.location.hash,a=e.find(t=>t.realm===this.realm),s=a&&a.views&&a.views[i]?a.views[i][this.panelName]:void 0;if(!s)return;if(!s.attributeRefs){delete a.views[i][this.panelName];let t=[...e.filter(t=>t.realm!==this.realm),a];p.console.storeData("OrChartConfig",t);return}let r=s.attributeRefs.map(t=>t.id);if(0!==r.length&&(this._loading=!0,!r.every(t=>!!this.assets.find(e=>e.id===t)))){try{let t=(yield p.rest.api.AssetResource.queryAssets({ids:r})).data||[];s.attributeRefs=s.attributeRefs.filter(e=>!!t.find(t=>t.id===e.id&&t.attributes&&t.attributes.hasOwnProperty(e.name))),e=[...e.filter(t=>t.realm!==this.realm),a],p.console.storeData("OrChartConfig",e),this.assets=t.filter(t=>s.attributeRefs.find(e=>e.id===t.id))}catch(t){console.error("Failed to get assets requested in settings",t)}this._loading=!1,this.assets&&this.assets.length>0&&(this.assetAttributes=s.attributeRefs.map(t=>{let e=this.assets.findIndex(e=>e.id===t.id),i=e>=0?this.assets[e]:void 0;return i&&i.attributes?[e,i.attributes[t.name]]:void 0}).filter(t=>!!t),this.period=s.period||"day",this.mainValueDecimals=s.decimals||0,this.deltaFormat=s.deltaFormat||"absolute")}})}saveSettings(){return __awaiter(this,void 0,void 0,function*(){if(!this.panelName)return;let t=window.location.hash,e=(yield p.console.retrieveData("OrChartConfig"))||[],i=e.find(t=>t.realm===this.realm);i||(i={realm:this.realm,views:{}}),i.views[t]||(i.views[t]={}),this.assets&&this.assetAttributes&&0!==this.assets.length&&0!==this.assetAttributes.length?(i.realm=this.realm,i.views[t][this.panelName]={attributeRefs:this.assetAttributes.map(([t,e])=>{let i=this.assets[t];return i?{id:i.id,name:e.name}:void 0}).filter(t=>!!t),period:this.period,deltaFormat:this.deltaFormat,decimals:this.mainValueDecimals}):delete i.views[t][this.panelName],e=[...e.filter(t=>t.realm!==this.realm),i],p.console.storeData("OrChartConfig",e)})}loadData(){return __awaiter(this,void 0,void 0,function*(){var t;if(this.data||!this.assetAttributes||!this.assets||0===this.assets.length||0===this.assetAttributes.length||!this.period)return;this._dataAbortController&&(this._dataAbortController.abort("Data request overridden"),delete this._dataAbortController),this._loading=!0;let e="HOUR";switch(this.period){case"hour":e="MINUTE";break;case"day":case"week":e="HOUR";break;case"month":e="DAY";break;case"year":e="MONTH"}e.toLowerCase(),this._startOfPeriod=C().subtract(1,this.period).toDate().getTime(),this._endOfPeriod=C().toDate().getTime();let i=this.assets[0].id,a=this.assetAttributes[0][1].name;this._dataAbortController=new AbortController;try{let t=yield p.rest.api.AssetDatapointResource.getDatapoints(i,a,{type:"lttb",fromTimestamp:this._startOfPeriod,toTimestamp:this._endOfPeriod,amountOfPoints:20},{signal:this._dataAbortController.signal});this._loading=!1,200===t.status&&(this.data=t.data,this.delta=this.getFormattedDelta(this.getFirstKnownMeasurement(this.data),this.getLastKnownMeasurement(this.data)),this.deltaPlus=this.delta&&this.delta.val>0?"+":"",this._error=void 0)}catch(e){if(console.error(e),(null==e?void 0:e.message)==="canceled")return;if(this._loading=!1,m(e)){if(e.message.includes("timeout")){this._error="noAttributeDataTimeout";return}else if((null==(t=e.response)?void 0:t.status)===413){this._error="datapointRequestTooLarge";return}}this._error="couldNotRetrieveAttribute"}finally{this.mainValue=void 0,this.formattedMainValue=void 0;let t=yield p.events.sendEventWithReply({eventType:"read-asset-attribute",ref:{id:i,name:a}});this.mainValue=t.value,this.formattedMainValue=this.getFormattedValue(this.mainValue)}})}getTotalValue(t){return t.reduce((t,e)=>e.y?t+Math.round(e.y):t,0)}getHighestValue(t){return Math.max.apply(Math,t.map(t=>t.y||!1))}getFormattedValue(t){if(void 0===t||!this.assets||!this.assetAttributes||0===this.assets.length||0===this.assetAttributes.length)return;let e=this.assetAttributes[0][1],i=+(null==t?void 0:t.toFixed(this.mainValueDecimals)),a=d.getAttributeDescriptor(e.name,this.assets[0].type),s=c.resolveUnits(c.getAttributeUnits(e,a,this.assets[0].type));return(this.setLabelSizeByLength(i.toString()),s)?{value:i,unit:s}:{value:i,unit:""}}getFirstKnownMeasurement(t){for(let e=0;e<=t.length;e++)if(t[e]&&void 0!==t[e].y)return t[e].y;return 0}getLastKnownMeasurement(t){for(let e=t.length-1;e>=0;e--)if(t[e]&&void 0!==t[e].y)return t[e].y;return 0}getFormattedDelta(t,e){if("percentage"===this.deltaFormat)if(!t||!e)return{val:0,unit:"%"};else if(0===e&&0===t)return{val:0,unit:"%"};else return 0===e&&0!==t?{val:100,unit:"%"}:{val:Math.round((e-t)/t*100),unit:"%"};return{val:Math.round(e-t),unit:""}}handleMenuSelect(t){"delete"===t?(this.assets=[],this.assetAttributes=[],this.saveSettings()):this._openDialog(t)}setLabelSizeByLength(t){t.length>=20&&(this.mainValueSize="xs"),t.length<20&&(this.mainValueSize="s"),t.length<15&&(this.mainValueSize="m"),t.length<10&&(this.mainValueSize="l"),t.length<5&&(this.mainValueSize="xl")}setLabelSizeByWidth(t){t<60?this.mainValueSize="s":t<100?this.mainValueSize="m":t<200?this.mainValueSize="l":this.mainValueSize="xl"}_setPeriodOption(t){this.period=t,this.saveSettings()}};__decorate([r()],OrAttributeCard.prototype,"panelName",void 0),__decorate([r({type:Object})],OrAttributeCard.prototype,"assets",void 0),__decorate([r({type:Object})],OrAttributeCard.prototype,"assetAttributes",void 0),__decorate([r()],OrAttributeCard.prototype,"data",void 0),__decorate([r({type:String})],OrAttributeCard.prototype,"realm",void 0),__decorate([r()],OrAttributeCard.prototype,"mainValue",void 0),__decorate([r()],OrAttributeCard.prototype,"mainValueDecimals",void 0),__decorate([r()],OrAttributeCard.prototype,"mainValueSize",void 0),__decorate([r()],OrAttributeCard.prototype,"delta",void 0),__decorate([r()],OrAttributeCard.prototype,"deltaPlus",void 0),__decorate([r()],OrAttributeCard.prototype,"deltaFormat",void 0),__decorate([r()],OrAttributeCard.prototype,"showControls",void 0),__decorate([r()],OrAttributeCard.prototype,"hideAttributePicker",void 0),__decorate([r()],OrAttributeCard.prototype,"showTitle",void 0),__decorate([r()],OrAttributeCard.prototype,"_loading",void 0),__decorate([r()],OrAttributeCard.prototype,"period",void 0),__decorate([o()],OrAttributeCard.prototype,"_error",void 0),__decorate([n("#chart")],OrAttributeCard.prototype,"_chartElem",void 0),OrAttributeCard=__decorate([s("or-attribute-card")],OrAttributeCard);export{OrAttributeCard};