@c8y/ngx-components 1024.15.13 → 1024.16.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +303 -63
  2. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
  3. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs +9 -0
  4. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs +4 -0
  6. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +394 -52
  8. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-ai.mjs +329 -19
  10. package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-bookmarks.mjs +1 -1
  12. package/fesm2022/c8y-ngx-components-bookmarks.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +8 -2
  14. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +96 -77
  16. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +92 -47
  18. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  19. package/fesm2022/c8y-ngx-components-device-profile.mjs +1 -1
  20. package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
  21. package/fesm2022/c8y-ngx-components-echart.mjs +39 -12
  22. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  23. package/fesm2022/c8y-ngx-components-ecosystem.mjs +1 -1
  24. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  25. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs +1 -1
  26. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
  27. package/fesm2022/c8y-ngx-components-register-device.mjs +5 -6
  28. package/fesm2022/c8y-ngx-components-register-device.mjs.map +1 -1
  29. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +1 -1
  30. package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
  31. package/fesm2022/c8y-ngx-components-repository-software.mjs +1 -1
  32. package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
  33. package/fesm2022/c8y-ngx-components-sub-assets.mjs +30 -10
  34. package/fesm2022/c8y-ngx-components-sub-assets.mjs.map +1 -1
  35. package/fesm2022/c8y-ngx-components-time-context.mjs +13 -9
  36. package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
  37. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +1 -1
  38. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
  39. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs +3 -2
  40. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs.map +1 -1
  41. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +4 -6
  42. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  43. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +3 -2
  44. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
  45. package/fesm2022/c8y-ngx-components.mjs +122 -24
  46. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  47. package/locales/de.po +147 -16
  48. package/locales/es.po +143 -11
  49. package/locales/fr.po +459 -324
  50. package/locales/ja_JP.po +143 -11
  51. package/locales/ko.po +143 -11
  52. package/locales/locales.pot +139 -10
  53. package/locales/nl.po +143 -11
  54. package/locales/pl.po +143 -11
  55. package/locales/pt_BR.po +143 -11
  56. package/locales/zh_CN.po +143 -11
  57. package/locales/zh_TW.po +143 -11
  58. package/package.json +1 -1
  59. package/types/c8y-ngx-components-ai-agent-chat.d.ts +111 -4
  60. package/types/c8y-ngx-components-ai-agent-chat.d.ts.map +1 -1
  61. package/types/c8y-ngx-components-ai-agents-html.d.ts.map +1 -1
  62. package/types/c8y-ngx-components-ai-agents-scada.d.ts.map +1 -1
  63. package/types/c8y-ngx-components-ai-ai-chat.d.ts +224 -10
  64. package/types/c8y-ngx-components-ai-ai-chat.d.ts.map +1 -1
  65. package/types/c8y-ngx-components-ai.d.ts +176 -6
  66. package/types/c8y-ngx-components-ai.d.ts.map +1 -1
  67. package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
  68. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts +7 -2
  69. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -1
  70. package/types/c8y-ngx-components-datapoint-selector.d.ts +63 -50
  71. package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
  72. package/types/c8y-ngx-components-echart.d.ts +12 -0
  73. package/types/c8y-ngx-components-echart.d.ts.map +1 -1
  74. package/types/c8y-ngx-components-register-device.d.ts.map +1 -1
  75. package/types/c8y-ngx-components-sub-assets.d.ts +10 -1
  76. package/types/c8y-ngx-components-sub-assets.d.ts.map +1 -1
  77. package/types/c8y-ngx-components-time-context.d.ts +2 -0
  78. package/types/c8y-ngx-components-time-context.d.ts.map +1 -1
  79. package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
  80. package/types/c8y-ngx-components.d.ts +37 -5
  81. package/types/c8y-ngx-components.d.ts.map +1 -1
@@ -8,7 +8,7 @@ import { CollapseModule } from 'ngx-bootstrap/collapse';
8
8
  import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
9
9
  import * as i1$2 from 'ngx-bootstrap/modal';
10
10
  import { ModalModule } from 'ngx-bootstrap/modal';
11
- import * as i5 from 'ngx-bootstrap/popover';
11
+ import * as i6 from 'ngx-bootstrap/popover';
12
12
  import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover';
13
13
  import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
14
14
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@@ -18,7 +18,7 @@ import { gettext } from '@c8y/ngx-components/gettext';
18
18
  import { map, take, filter, startWith, tap, switchMap, shareReplay, distinctUntilChanged, debounceTime } from 'rxjs/operators';
19
19
  import { NgClass, NgTemplateOutlet, KeyValuePipe, AsyncPipe, NgIf, NgFor } from '@angular/common';
20
20
  import chroma from 'chroma-js';
21
- import * as i4 from '@c8y/ngx-components/context-dashboard';
21
+ import * as i5 from '@c8y/ngx-components/context-dashboard';
22
22
  import { WidgetConfigService, WidgetConfigComponent, ContextDashboardComponent, WidgetConfigFeedbackComponent } from '@c8y/ngx-components/context-dashboard';
23
23
  import { pipe, BehaviorSubject, from, combineLatest, filter as filter$1, take as take$1, map as map$1, switchMap as switchMap$1 } from 'rxjs';
24
24
  import * as i1$1 from '@c8y/client';
@@ -294,34 +294,10 @@ class DatapointAttributesFormValidationService {
294
294
  name: [undefined, []]
295
295
  });
296
296
  }
297
- convertStringToNumber(possibleString) {
298
- if (typeof possibleString === 'string') {
299
- try {
300
- return Number.parseFloat(possibleString);
301
- }
302
- catch {
303
- return undefined;
304
- }
305
- }
306
- else {
307
- return possibleString;
308
- }
309
- }
310
- /**
311
- * Derives the primary `renderType` from `renderTypeConfigs`.
312
- * Returns the first enabled type, or falls back to `chart.renderType`.
313
- */
314
- deriveRenderTypeFromConfigs(chart) {
315
- const configs = chart?.renderTypeConfigs;
316
- if (!configs) {
317
- return chart?.renderType;
318
- }
319
- const firstEnabled = Object.keys(configs).find(key => configs[key]?.enabled);
320
- return firstEnabled || chart?.renderType || 'avg';
321
- }
322
297
  /**
323
298
  * Builds `renderTypeConfigs` from backend data, supporting both new format (already has configs)
324
- * and legacy format (only has renderType/renderTypes/renderTypeColors).
299
+ * and legacy format (only has renderType/renderTypes/renderTypeColors). Falls back to `avg`,
300
+ * matching the default the attributes form starts with.
325
301
  */
326
302
  buildRenderTypeConfigs(backend) {
327
303
  if (backend.renderTypeConfigs) {
@@ -347,6 +323,31 @@ class DatapointAttributesFormValidationService {
347
323
  }
348
324
  return configs;
349
325
  }
326
+ convertStringToNumber(possibleString) {
327
+ if (typeof possibleString === 'string') {
328
+ try {
329
+ return Number.parseFloat(possibleString);
330
+ }
331
+ catch {
332
+ return undefined;
333
+ }
334
+ }
335
+ else {
336
+ return possibleString;
337
+ }
338
+ }
339
+ /**
340
+ * Derives the primary `renderType` from `renderTypeConfigs`.
341
+ * Returns the first enabled type, or falls back to `chart.renderType`.
342
+ */
343
+ deriveRenderTypeFromConfigs(chart) {
344
+ const configs = chart?.renderTypeConfigs;
345
+ if (!configs) {
346
+ return chart?.renderType;
347
+ }
348
+ const firstEnabled = Object.keys(configs).find(key => configs[key]?.enabled);
349
+ return firstEnabled || chart?.renderType || 'avg';
350
+ }
350
351
  /**
351
352
  * Derives the `renderTypes` array from `renderTypeConfigs`.
352
353
  * If configs exist, returns enabled types; otherwise falls back to `chart.renderTypes`.
@@ -442,8 +443,18 @@ class DatapointAttributesFormComponent {
442
443
  }
443
444
  this.updateRenderAsBandState();
444
445
  if (this.shouldForceInitialValidation) {
446
+ const validBefore = this.formGroup.valid;
445
447
  queueMicrotask(() => {
446
- this.formGroup.updateValueAndValidity();
448
+ // CVA contract: a writeValue must not echo a value change. Validate silently.
449
+ this.formGroup.updateValueAndValidity({ emitEvent: false });
450
+ // Only notify the host when the outcome actually changed. Angular's validator-change hook
451
+ // runs updateValueAndValidity() on the host control, which emits a value event that is
452
+ // indistinguishable from a user edit further up: the list item then re-emits the datapoint
453
+ // enriched with its own control defaults, the parent rebuilds the widget config and the
454
+ // chart refetches. Re-running validation that cannot change anything is not worth a reload.
455
+ if (this.formGroup.valid !== validBefore) {
456
+ this.onValidatorChange?.();
457
+ }
447
458
  });
448
459
  this.shouldForceInitialValidation = false;
449
460
  }
@@ -456,6 +467,9 @@ class DatapointAttributesFormComponent {
456
467
  registerOnTouched(fn) {
457
468
  this.formGroup.valueChanges.pipe(take(1)).subscribe(fn);
458
469
  }
470
+ registerOnValidatorChange(fn) {
471
+ this.onValidatorChange = fn;
472
+ }
459
473
  setDisabledState(isDisabled) {
460
474
  if (this.formGroup?.disabled === isDisabled) {
461
475
  return;
@@ -971,8 +985,9 @@ class DatapointSelectorListItemComponent {
971
985
  }
972
986
  return this.formGroup?.valid ? null : { formInvalid: {} };
973
987
  }
974
- writeValue(obj) {
975
- this.formGroup.patchValue({ ...obj, details: obj });
988
+ writeValue(datapoint) {
989
+ // CVA contract: a model→view write must not re-emit through registerOnChange.
990
+ this.formGroup.patchValue(this.toFormValue(datapoint), { emitEvent: false });
976
991
  }
977
992
  registerOnChange(fn) {
978
993
  this.formGroup.valueChanges.pipe(map(tmp => this.transformFormValue(tmp))).subscribe(fn);
@@ -984,7 +999,12 @@ class DatapointSelectorListItemComponent {
984
999
  if (this.formGroup?.disabled === isDisabled) {
985
1000
  return;
986
1001
  }
987
- isDisabled ? this.formGroup.disable() : this.formGroup.enable();
1002
+ if (isDisabled) {
1003
+ this.formGroup.disable();
1004
+ }
1005
+ else {
1006
+ this.formGroup.enable();
1007
+ }
988
1008
  }
989
1009
  collapse() {
990
1010
  this.isCollapsed = !this.isCollapsed;
@@ -1038,7 +1058,8 @@ class DatapointSelectorListItemComponent {
1038
1058
  const value = template[DATAPOINT_LIBRARY_FRAGMENT][attribute];
1039
1059
  dataPoint[attribute] = value;
1040
1060
  }
1041
- this.writeValue(dataPoint);
1061
+ // A user selection must propagate to the parent form, unlike a writeValue.
1062
+ this.formGroup.patchValue(this.toFormValue(dataPoint));
1042
1063
  this.setPipe('');
1043
1064
  }
1044
1065
  resetUnusedProperties(details) {
@@ -1062,6 +1083,10 @@ class DatapointSelectorListItemComponent {
1062
1083
  typeof mo[DATAPOINT_LIBRARY_FRAGMENT].label === 'string' &&
1063
1084
  mo[DATAPOINT_LIBRARY_FRAGMENT].label.toLowerCase().indexOf(filterStr.toLowerCase()) > -1);
1064
1085
  }
1086
+ /** Inverse of transformFormValue: expands a flat datapoint into the form's { details } shape. */
1087
+ toFormValue(datapoint) {
1088
+ return { ...datapoint, details: datapoint };
1089
+ }
1065
1090
  transformFormValue(formValue) {
1066
1091
  const obj = Object.assign({}, formValue.details || {}, formValue);
1067
1092
  delete obj.details;
@@ -1474,10 +1499,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1474
1499
  }], ctorParameters: () => [{ type: i1$2.BsModalService }] });
1475
1500
 
1476
1501
  class DatapointSelectionListComponent {
1477
- constructor(datapointSelector, datapointLibrary, formBuilder, widgetComponent) {
1502
+ constructor(datapointSelector, datapointLibrary, formBuilder, formValidations, widgetComponent) {
1478
1503
  this.datapointSelector = datapointSelector;
1479
1504
  this.datapointLibrary = datapointLibrary;
1480
1505
  this.formBuilder = formBuilder;
1506
+ this.formValidations = formValidations;
1481
1507
  this.widgetComponent = widgetComponent;
1482
1508
  this.actions = [];
1483
1509
  /**
@@ -1532,15 +1558,8 @@ class DatapointSelectionListComponent {
1532
1558
  };
1533
1559
  }
1534
1560
  writeValue(datapoints) {
1535
- this.formArray.clear();
1536
- if (datapoints?.length) {
1537
- datapoints.forEach(dp => {
1538
- const formgroup = this.formBuilder.group({ details: [] });
1539
- formgroup.patchValue({ details: dp });
1540
- this.formArray.push(formgroup);
1541
- });
1542
- }
1543
- this.calculateMaxActiveCount();
1561
+ // CVA contract: a model→view write must not re-emit through registerOnChange.
1562
+ this.setDatapoints(datapoints, { emitEvent: false });
1544
1563
  }
1545
1564
  registerOnChange(fn) {
1546
1565
  this.formArray.valueChanges
@@ -1562,7 +1581,8 @@ class DatapointSelectionListComponent {
1562
1581
  allowSearch: !this.config?.contextAsset
1563
1582
  })
1564
1583
  .then(result => {
1565
- this.writeValue(result);
1584
+ // A user selection must propagate to the parent form, unlike a writeValue.
1585
+ this.setDatapoints(result);
1566
1586
  }, () => {
1567
1587
  // nothing to do, modal was closed
1568
1588
  });
@@ -1628,6 +1648,31 @@ class DatapointSelectionListComponent {
1628
1648
  moveItemInArray(currentSorting, event.previousIndex, event.currentIndex);
1629
1649
  this.formArray.setValue(currentSorting);
1630
1650
  }
1651
+ setDatapoints(datapoints, options) {
1652
+ this.formArray.clear(options);
1653
+ if (datapoints?.length) {
1654
+ datapoints.forEach(dp => {
1655
+ const formgroup = this.formBuilder.group({ details: [] });
1656
+ formgroup.patchValue({ details: this.withRenderTypeConfigs(dp) });
1657
+ this.formArray.push(formgroup, options);
1658
+ });
1659
+ }
1660
+ this.calculateMaxActiveCount();
1661
+ }
1662
+ /**
1663
+ * A datapoint coming out of the selector modal carries no `renderTypeConfigs`, and the attributes
1664
+ * form is not allowed to emit its defaults back up through the ControlValueAccessor chain.
1665
+ * Without them the aggregation checkboxes read as empty and toggling one is a no-op.
1666
+ */
1667
+ withRenderTypeConfigs(datapoint) {
1668
+ if (!this.defaultFormOptions?.showChart || !datapoint || datapoint.renderTypeConfigs) {
1669
+ return datapoint;
1670
+ }
1671
+ return {
1672
+ ...datapoint,
1673
+ renderTypeConfigs: this.formValidations.buildRenderTypeConfigs(datapoint)
1674
+ };
1675
+ }
1631
1676
  transformValue(formArrayValue) {
1632
1677
  if (!formArrayValue) {
1633
1678
  return [];
@@ -1653,7 +1698,7 @@ class DatapointSelectionListComponent {
1653
1698
  this.formArray.setValidators(validators);
1654
1699
  this.formArray.updateValueAndValidity();
1655
1700
  }
1656
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointSelectionListComponent, deps: [{ token: DatapointSelectorService }, { token: DatapointLibraryService }, { token: i1.FormBuilder }, { token: i4.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1701
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointSelectionListComponent, deps: [{ token: DatapointSelectorService }, { token: DatapointLibraryService }, { token: i1.FormBuilder }, { token: DatapointAttributesFormValidationService }, { token: i5.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1657
1702
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DatapointSelectionListComponent, isStandalone: true, selector: "c8y-datapoint-selection-list", inputs: { actions: "actions", allowDragAndDrop: "allowDragAndDrop", config: "config", defaultFormOptions: "defaultFormOptions", maxActiveCount: "maxActiveCount", minActiveCount: "minActiveCount", resolveContext: "resolveContext", listTitle: "listTitle", removeTitle: "removeTitle" }, outputs: { isValid: "isValid", change: "change" }, providers: [
1658
1703
  {
1659
1704
  provide: NG_VALUE_ACCESSOR,
@@ -1665,7 +1710,7 @@ class DatapointSelectionListComponent {
1665
1710
  useExisting: forwardRef(() => DatapointSelectionListComponent),
1666
1711
  multi: true
1667
1712
  }
1668
- ], usesOnChanges: true, ngImport: i0, template: "@if (!removeTitle) {\n <div class=\"card-header separator sticky-top bg-inherit\">\n <span class=\"card-title h4\">\n {{ (listTitle ? listTitle : DATA_POINTS_LABEL) | translate }}\n </span>\n </div>\n}\n\n<c8y-list-group\n class=\"flex-grow ff-scroll-fix cdk-droplist\"\n [class.separator-top]=\"formArray.controls?.length\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"!allowDragAndDrop || formArray.controls?.length < 2\"\n>\n @if (formArray.errors?.minActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ minActiveErrorMessage | translate: { minActive: minActiveCount } }}\n </div>\n }\n\n @if (formArray.errors?.maxActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ maxActiveErrorMessage | translate: { maxActive: maxActiveCount } }}\n </div>\n }\n\n <ng-content select=\".alert\"></ng-content>\n\n @if (defaultFormOptions?.showAdvancedChartOptions && formArray.controls?.length) {\n <fieldset class=\"c8y-fieldset m-t-0 m-b-16\">\n <legend>\n {{ 'Aggregation display' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n \"\n popover=\"{{\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <div class=\"m-b-8\">\n @for (rt of GLOBAL_AGGREGATION_TYPES; track rt.val) {\n @let aggregationState = getAggregationState(rt.val);\n <label\n class=\"c8y-checkbox checkbox-inline\"\n [title]=\"rt.text | translate\"\n [attr.aria-label]=\"rt.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"aggregationState === 'all'\"\n [indeterminate]=\"aggregationState === 'mixed'\"\n [disabled]=\"wouldLeaveAnyEmpty(rt.val)\"\n (change)=\"toggleGlobalAggregation(rt.val)\"\n />\n <span></span>\n <span>{{ rt.text | translate }}</span>\n </label>\n }\n </div>\n </fieldset>\n }\n\n @if (!formArray.controls?.length) {\n <div class=\"p-t-8\">\n <c8y-ui-empty-state\n class=\"p-t-8\"\n [icon]=\"'c8y-data-points'\"\n [title]=\"'No data points to display.' | translate\"\n [subtitle]=\"'Add your first data point.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n }\n\n @for (formGroup of formGroups; track formGroup; let index = $index) {\n <div [formGroup]=\"formGroup\">\n <c8y-datapoint-selector-list-item\n class=\"d-block\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [activeToggleDisabled]=\"maxActiveCountReached\"\n [showActiveToggle]=\"true\"\n [addButtonType]=\"AddButtonTypes.none\"\n [showOptions]=\"true\"\n [editable]=\"true\"\n [colorPickerDisabled]=\"false\"\n [actions]=\"actions\"\n [optionToRemove]=\"true\"\n [datapointLibraryEntries]=\"datapointLibraryEntries\"\n [hasUnlinkTemplateOption]=\"true\"\n formControlName=\"details\"\n (removed)=\"onItemRemoved(index)\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Click and drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n </c8y-datapoint-selector-list-item>\n </div>\n }\n\n <div class=\"card-footer bg-inherit\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Add data point' | translate\"\n type=\"button\"\n data-cy=\"c8y-datapoint-selection-list--add-datapoint-button\"\n (click)=\"add()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add data point' | translate }}\n </button>\n </div>\n</c8y-list-group>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DatapointSelectorListItemComponent, selector: "c8y-datapoint-selector-list-item", inputs: ["defaultFormOptions", "isSelected", "isCollapsed", "addButtonType", "editable", "showActiveToggle", "activeToggleDisabled", "showOptions", "datapointLibraryEntries", "actions", "optionToRemove", "hasUnlinkTemplateOption", "colorPickerDisabled", "disableTypeaheadIfSelected", "highlightText"], outputs: ["added", "removed"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { 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: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
1713
+ ], usesOnChanges: true, ngImport: i0, template: "@if (!removeTitle) {\n <div class=\"card-header separator sticky-top bg-inherit\">\n <span class=\"card-title h4\">\n {{ (listTitle ? listTitle : DATA_POINTS_LABEL) | translate }}\n </span>\n </div>\n}\n\n<c8y-list-group\n class=\"flex-grow ff-scroll-fix cdk-droplist\"\n [class.separator-top]=\"formArray.controls?.length\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"!allowDragAndDrop || formArray.controls?.length < 2\"\n>\n @if (formArray.errors?.minActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ minActiveErrorMessage | translate: { minActive: minActiveCount } }}\n </div>\n }\n\n @if (formArray.errors?.maxActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ maxActiveErrorMessage | translate: { maxActive: maxActiveCount } }}\n </div>\n }\n\n <ng-content select=\".alert\"></ng-content>\n\n @if (defaultFormOptions?.showAdvancedChartOptions && formArray.controls?.length) {\n <fieldset class=\"c8y-fieldset m-t-0 m-b-16\">\n <legend>\n {{ 'Aggregation display' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n \"\n popover=\"{{\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <div class=\"m-b-8\">\n @for (rt of GLOBAL_AGGREGATION_TYPES; track rt.val) {\n @let aggregationState = getAggregationState(rt.val);\n <label\n class=\"c8y-checkbox checkbox-inline\"\n [title]=\"rt.text | translate\"\n [attr.aria-label]=\"rt.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"aggregationState === 'all'\"\n [indeterminate]=\"aggregationState === 'mixed'\"\n [disabled]=\"wouldLeaveAnyEmpty(rt.val)\"\n (change)=\"toggleGlobalAggregation(rt.val)\"\n />\n <span></span>\n <span>{{ rt.text | translate }}</span>\n </label>\n }\n </div>\n </fieldset>\n }\n\n @if (!formArray.controls?.length) {\n <div class=\"p-t-8\">\n <c8y-ui-empty-state\n class=\"p-t-8\"\n [icon]=\"'c8y-data-points'\"\n [title]=\"'No data points to display.' | translate\"\n [subtitle]=\"'Add your first data point.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n }\n\n @for (formGroup of formGroups; track formGroup; let index = $index) {\n <div [formGroup]=\"formGroup\">\n <c8y-datapoint-selector-list-item\n class=\"d-block\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [activeToggleDisabled]=\"maxActiveCountReached\"\n [showActiveToggle]=\"true\"\n [addButtonType]=\"AddButtonTypes.none\"\n [showOptions]=\"true\"\n [editable]=\"true\"\n [colorPickerDisabled]=\"false\"\n [actions]=\"actions\"\n [optionToRemove]=\"true\"\n [datapointLibraryEntries]=\"datapointLibraryEntries\"\n [hasUnlinkTemplateOption]=\"true\"\n formControlName=\"details\"\n (removed)=\"onItemRemoved(index)\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Click and drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n </c8y-datapoint-selector-list-item>\n </div>\n }\n\n <div class=\"card-footer bg-inherit\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Add data point' | translate\"\n type=\"button\"\n data-cy=\"c8y-datapoint-selection-list--add-datapoint-button\"\n (click)=\"add()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add data point' | translate }}\n </button>\n </div>\n</c8y-list-group>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DatapointSelectorListItemComponent, selector: "c8y-datapoint-selector-list-item", inputs: ["defaultFormOptions", "isSelected", "isCollapsed", "addButtonType", "editable", "showActiveToggle", "activeToggleDisabled", "showOptions", "datapointLibraryEntries", "actions", "optionToRemove", "hasUnlinkTemplateOption", "colorPickerDisabled", "disableTypeaheadIfSelected", "highlightText"], outputs: ["added", "removed"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i6.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
1669
1714
  }
1670
1715
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointSelectionListComponent, decorators: [{
1671
1716
  type: Component,
@@ -1694,7 +1739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1694
1739
  C8yTranslatePipe,
1695
1740
  PopoverModule
1696
1741
  ], template: "@if (!removeTitle) {\n <div class=\"card-header separator sticky-top bg-inherit\">\n <span class=\"card-title h4\">\n {{ (listTitle ? listTitle : DATA_POINTS_LABEL) | translate }}\n </span>\n </div>\n}\n\n<c8y-list-group\n class=\"flex-grow ff-scroll-fix cdk-droplist\"\n [class.separator-top]=\"formArray.controls?.length\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"!allowDragAndDrop || formArray.controls?.length < 2\"\n>\n @if (formArray.errors?.minActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ minActiveErrorMessage | translate: { minActive: minActiveCount } }}\n </div>\n }\n\n @if (formArray.errors?.maxActiveCount && formArray.touched) {\n <div\n class=\"alert alert-warning m-t-8\"\n role=\"alert\"\n >\n {{ maxActiveErrorMessage | translate: { maxActive: maxActiveCount } }}\n </div>\n }\n\n <ng-content select=\".alert\"></ng-content>\n\n @if (defaultFormOptions?.showAdvancedChartOptions && formArray.controls?.length) {\n <fieldset class=\"c8y-fieldset m-t-0 m-b-16\">\n <legend>\n {{ 'Aggregation display' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n \"\n popover=\"{{\n 'Select which aggregations to display for all data points. These options apply to every data point in the list.'\n | translate\n }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <div class=\"m-b-8\">\n @for (rt of GLOBAL_AGGREGATION_TYPES; track rt.val) {\n @let aggregationState = getAggregationState(rt.val);\n <label\n class=\"c8y-checkbox checkbox-inline\"\n [title]=\"rt.text | translate\"\n [attr.aria-label]=\"rt.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"aggregationState === 'all'\"\n [indeterminate]=\"aggregationState === 'mixed'\"\n [disabled]=\"wouldLeaveAnyEmpty(rt.val)\"\n (change)=\"toggleGlobalAggregation(rt.val)\"\n />\n <span></span>\n <span>{{ rt.text | translate }}</span>\n </label>\n }\n </div>\n </fieldset>\n }\n\n @if (!formArray.controls?.length) {\n <div class=\"p-t-8\">\n <c8y-ui-empty-state\n class=\"p-t-8\"\n [icon]=\"'c8y-data-points'\"\n [title]=\"'No data points to display.' | translate\"\n [subtitle]=\"'Add your first data point.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n }\n\n @for (formGroup of formGroups; track formGroup; let index = $index) {\n <div [formGroup]=\"formGroup\">\n <c8y-datapoint-selector-list-item\n class=\"d-block\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [activeToggleDisabled]=\"maxActiveCountReached\"\n [showActiveToggle]=\"true\"\n [addButtonType]=\"AddButtonTypes.none\"\n [showOptions]=\"true\"\n [editable]=\"true\"\n [colorPickerDisabled]=\"false\"\n [actions]=\"actions\"\n [optionToRemove]=\"true\"\n [datapointLibraryEntries]=\"datapointLibraryEntries\"\n [hasUnlinkTemplateOption]=\"true\"\n formControlName=\"details\"\n (removed)=\"onItemRemoved(index)\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Click and drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n </c8y-datapoint-selector-list-item>\n </div>\n }\n\n <div class=\"card-footer bg-inherit\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"'Add data point' | translate\"\n type=\"button\"\n data-cy=\"c8y-datapoint-selection-list--add-datapoint-button\"\n (click)=\"add()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add data point' | translate }}\n </button>\n </div>\n</c8y-list-group>\n" }]
1697
- }], ctorParameters: () => [{ type: DatapointSelectorService }, { type: DatapointLibraryService }, { type: i1.FormBuilder }, { type: i4.WidgetConfigComponent, decorators: [{
1742
+ }], ctorParameters: () => [{ type: DatapointSelectorService }, { type: DatapointLibraryService }, { type: i1.FormBuilder }, { type: DatapointAttributesFormValidationService }, { type: i5.WidgetConfigComponent, decorators: [{
1698
1743
  type: Optional
1699
1744
  }] }], propDecorators: { actions: [{
1700
1745
  type: Input