@c8y/ngx-components 1023.92.0 → 1023.96.0

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 (92) hide show
  1. package/ai/agents/scada/index.d.ts +10 -0
  2. package/ai/agents/scada/index.d.ts.map +1 -0
  3. package/ai/ai-chat/index.d.ts +1 -1
  4. package/ai/ai-chat/index.d.ts.map +1 -1
  5. package/computed-asset-properties/index.d.ts +89 -1
  6. package/computed-asset-properties/index.d.ts.map +1 -1
  7. package/context-dashboard/index.d.ts +18 -8
  8. package/context-dashboard/index.d.ts.map +1 -1
  9. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +2 -2
  10. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs +893 -0
  12. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -0
  13. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +1 -0
  14. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-asset-properties.mjs +2 -2
  16. package/fesm2022/c8y-ngx-components-asset-properties.mjs.map +1 -1
  17. package/fesm2022/{c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-Cy9R6Ixb.mjs → c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-CHZX7ALq.mjs} +10 -9
  18. package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-CHZX7ALq.mjs.map +1 -0
  19. package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-LrmlAh6V.mjs → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-DgWGXzEx.mjs} +2 -2
  20. package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-LrmlAh6V.mjs.map → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-DgWGXzEx.mjs.map} +1 -1
  21. package/fesm2022/{c8y-ngx-components-computed-asset-properties-last-measurement-config.component-f1u1TcCl.mjs → c8y-ngx-components-computed-asset-properties-last-measurement-config.component-yfc45-l_.mjs} +2 -2
  22. package/fesm2022/{c8y-ngx-components-computed-asset-properties-last-measurement-config.component-f1u1TcCl.mjs.map → c8y-ngx-components-computed-asset-properties-last-measurement-config.component-yfc45-l_.mjs.map} +1 -1
  23. package/fesm2022/c8y-ngx-components-computed-asset-properties.mjs +1 -1
  24. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +44 -36
  25. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  26. package/fesm2022/c8y-ngx-components-global-context.mjs +112 -22
  27. package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
  28. package/fesm2022/c8y-ngx-components-repository-configuration.mjs +292 -115
  29. package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
  30. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +2 -2
  31. package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
  32. package/fesm2022/c8y-ngx-components-repository-software.mjs +1 -1
  33. package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
  34. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs +2 -1
  35. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs.map +1 -1
  36. package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs +169 -0
  37. package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs.map +1 -0
  38. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +2 -1
  39. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
  40. package/fesm2022/c8y-ngx-components-widgets-exports.mjs +8 -1
  41. package/fesm2022/c8y-ngx-components-widgets-exports.mjs.map +1 -1
  42. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +2 -2
  43. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  44. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +3 -3
  45. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  46. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs +2 -2
  47. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs.map +1 -1
  48. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +2 -2
  49. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
  50. package/fesm2022/c8y-ngx-components-widgets-implementations-events.mjs +2 -2
  51. package/fesm2022/c8y-ngx-components-widgets-implementations-events.mjs.map +1 -1
  52. package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs +90 -32
  53. package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs.map +1 -1
  54. package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs +2 -2
  55. package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs.map +1 -1
  56. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +1698 -0
  57. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -0
  58. package/fesm2022/c8y-ngx-components.mjs +190 -40
  59. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  60. package/global-context/index.d.ts +58 -3
  61. package/global-context/index.d.ts.map +1 -1
  62. package/index.d.ts +74 -22
  63. package/index.d.ts.map +1 -1
  64. package/locales/de.po +108 -0
  65. package/locales/es.po +108 -0
  66. package/locales/fr.po +108 -0
  67. package/locales/ja_JP.po +108 -0
  68. package/locales/ko.po +108 -0
  69. package/locales/locales.pot +150 -3
  70. package/locales/nl.po +108 -0
  71. package/locales/pl.po +108 -0
  72. package/locales/pt_BR.po +108 -0
  73. package/locales/zh_CN.po +108 -0
  74. package/locales/zh_TW.po +108 -0
  75. package/package.json +1 -1
  76. package/repository/configuration/index.d.ts +64 -39
  77. package/repository/configuration/index.d.ts.map +1 -1
  78. package/widgets/cockpit-exports/index.d.ts +6 -0
  79. package/widgets/cockpit-exports/index.d.ts.map +1 -1
  80. package/widgets/definitions/index.d.ts +1 -0
  81. package/widgets/definitions/index.d.ts.map +1 -1
  82. package/widgets/definitions/scada/index.d.ts +6 -0
  83. package/widgets/definitions/scada/index.d.ts.map +1 -0
  84. package/widgets/device-management-exports/index.d.ts +6 -0
  85. package/widgets/device-management-exports/index.d.ts.map +1 -1
  86. package/widgets/exports/index.d.ts +8 -1
  87. package/widgets/exports/index.d.ts.map +1 -1
  88. package/widgets/implementations/html-widget/index.d.ts +30 -12
  89. package/widgets/implementations/html-widget/index.d.ts.map +1 -1
  90. package/widgets/implementations/scada/index.d.ts +415 -0
  91. package/widgets/implementations/scada/index.d.ts.map +1 -0
  92. package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-Cy9R6Ixb.mjs.map +0 -1
@@ -4,7 +4,7 @@ import * as i2 from '@c8y/ngx-components';
4
4
  import { IconDirective, C8yTranslatePipe, Permissions, ContextRouteService, Status, NavigatorNode, NEW_DASHBOARD_ROUTER_STATE_PROP, getActivatedRoute, ViewContext, TabsOutletComponent, memoize, hookGeneric, ExtensionPointForPlugins, fromTriggerOnce, getInjectedHooks, stateToFactory, ListGroupModule, C8yComponentOutlet, AlertService, C8yTranslateDirective, DynamicComponentModule, DynamicComponentComponent, sortByPriority, isPromise, CoreModule, WIDGET_CONFIGURATION_GRID_SIZE, HighlightComponent, EmptyStateComponent, FormGroupComponent, RequiredInputPlaceholderDirective, ProductExperienceDirective, ResizableGridComponent, DashboardChildChange, CopyDashboardDisabledReason, TitleComponent, ActionBarItemComponent, HelpComponent, WidgetsDashboardComponent, DatePipe, hookRoute, hookTab, PreviewService, hookNavigator, ManagedObjectRealtimeService, BottomDrawerService, ClipboardService, InputGroupEditableComponent, MessageDirective } from '@c8y/ngx-components';
5
5
  import * as i1 from '@angular/router';
6
6
  import { RouterOutlet, ActivatedRoute, RouterModule } from '@angular/router';
7
- import { of, Subject, from, combineLatest, map as map$1, merge, BehaviorSubject, tap as tap$1, withLatestFrom, mergeMap as mergeMap$1, shareReplay as shareReplay$1, scan, debounceTime, isObservable, iif, timer, filter as filter$1, switchMap as switchMap$1, take, forkJoin, firstValueFrom } from 'rxjs';
7
+ import { of, Subject, from, combineLatest, map as map$1, merge, BehaviorSubject, tap as tap$1, withLatestFrom, mergeMap as mergeMap$1, shareReplay as shareReplay$1, scan, debounceTime, isObservable, iif, timer, filter as filter$1, switchMap as switchMap$1, take, EMPTY, defer, forkJoin, firstValueFrom } from 'rxjs';
8
8
  import { gettext } from '@c8y/ngx-components/gettext';
9
9
  import { __decorate, __metadata } from 'tslib';
10
10
  import * as i3 from '@angular/common';
@@ -4487,15 +4487,16 @@ class AssetPropertyMappingsService {
4487
4487
  *
4488
4488
  * @param mappings - The asset property mappings configuration.
4489
4489
  * @param realtimeControl$ - Observable that controls realtime notifications (true = enabled, false = disabled, default = enabled).
4490
+ * @param refresh$ - Optional trigger; each emission forces a fresh REST fetch of all property values.
4490
4491
  * @returns Observable emitting updated asset property values as they change.
4491
4492
  */
4492
- getValues$(mappings, realtimeControl$ = of(true)) {
4493
+ getValues$(mappings, realtimeControl$ = of(true), refresh$ = EMPTY) {
4493
4494
  if (!mappings) {
4494
4495
  return of({});
4495
4496
  }
4496
4497
  const { regular, computed } = this.groupByType(mappings);
4497
4498
  const _regularByAssetId = this.groupByAssetId(regular);
4498
- return merge(...computed.map(mapping => this.getComputedPropertyValues$(mapping, realtimeControl$)), ...Object.entries(_regularByAssetId).map(([assetId, mappings]) => this.getRegularPropertyValues$(assetId, mappings, realtimeControl$))).pipe(scan((acc, update) => ({ ...acc, ...update }), {}), startWith({}));
4499
+ return merge(...computed.map(mapping => this.getComputedPropertyValues$(mapping, realtimeControl$, refresh$)), ...Object.entries(_regularByAssetId).map(([assetId, mappings]) => this.getRegularPropertyValues$(assetId, mappings, realtimeControl$, refresh$))).pipe(scan((acc, update) => ({ ...acc, ...update }), {}), startWith({}));
4499
4500
  }
4500
4501
  groupByType(mappings) {
4501
4502
  const regular = [];
@@ -4525,7 +4526,7 @@ class AssetPropertyMappingsService {
4525
4526
  return acc;
4526
4527
  }, {});
4527
4528
  }
4528
- getComputedPropertyValues$(mapping, realtimeControl$) {
4529
+ getComputedPropertyValues$(mapping, realtimeControl$, refresh$) {
4529
4530
  if (!mapping.assetProperty) {
4530
4531
  return of(null);
4531
4532
  }
@@ -4552,28 +4553,21 @@ class AssetPropertyMappingsService {
4552
4553
  return of(value);
4553
4554
  }
4554
4555
  }))));
4555
- return realtimeControl$.pipe(distinctUntilChanged(), switchMap(enabled => (enabled ? computedValue$ : computedValue$.pipe(take$1(1)))), map(value => ({ [mapping.name]: value })), catchError(err => {
4556
- // eslint-disable-next-line no-console
4557
- console.warn(`Error in computed property stream for asset ${mapping.assetProperty.asset.id}, property ${mapping.assetProperty.name}:`, err);
4558
- return of({ [mapping.name]: null });
4559
- }), shareReplay({ bufferSize: 1, refCount: true }));
4560
- }
4561
- getRegularPropertyValues$(assetId, mappings, realtimeControl$) {
4562
- return realtimeControl$.pipe(distinctUntilChanged(), switchMap(enabled => {
4563
- if (!enabled) {
4564
- return from(this.inventory.detail(assetId, { withLatestValues: true })).pipe(map(res => res?.data));
4565
- }
4566
- else {
4567
- return from(this.inventory.detail(assetId, { withLatestValues: true })).pipe(switchMap(initial => this.moRealtime.onAll$(assetId).pipe(map(update => update?.data), startWith(initial?.data))));
4568
- }
4569
- }), map(asset => mappings.reduce((acc, mapping) => ({
4556
+ return combineLatest([
4557
+ realtimeControl$.pipe(distinctUntilChanged()),
4558
+ refresh$.pipe(startWith(undefined))
4559
+ ]).pipe(switchMap(([enabled]) => (enabled ? computedValue$ : computedValue$.pipe(take$1(1)))), map(value => ({ [mapping.name]: value })), shareReplay({ bufferSize: 1, refCount: true }));
4560
+ }
4561
+ getRegularPropertyValues$(assetId, mappings, realtimeControl$, refresh$) {
4562
+ const fetchAsset$ = defer(() => from(this.inventory.detail(assetId, { withLatestValues: true }))).pipe(map(res => res?.data));
4563
+ const liveAsset$ = (initial) => this.moRealtime.onAll$(assetId).pipe(map(update => update?.data), startWith(initial));
4564
+ return combineLatest([
4565
+ realtimeControl$.pipe(distinctUntilChanged()),
4566
+ refresh$.pipe(startWith(undefined))
4567
+ ]).pipe(switchMap(([enabled]) => (enabled ? fetchAsset$.pipe(switchMap(liveAsset$)) : fetchAsset$)), map(asset => mappings.reduce((acc, mapping) => ({
4570
4568
  ...acc,
4571
4569
  [mapping.name]: this.getRegularPropertyValue(asset, mapping.assetProperty)
4572
- }), {})), catchError(err => {
4573
- // eslint-disable-next-line no-console
4574
- console.warn(`Error in controlled asset stream for asset ${assetId}:`, err);
4575
- return of(mappings.reduce((acc, m) => ({ ...acc, [m.name]: null }), {}));
4576
- }), shareReplay({ bufferSize: 1, refCount: true }));
4570
+ }), {})), shareReplay({ bufferSize: 1, refCount: true }));
4577
4571
  }
4578
4572
  getRegularPropertyValue(asset, property) {
4579
4573
  if (!asset || !property) {
@@ -4699,6 +4693,10 @@ class AssetPropertyMappingsComponent {
4699
4693
  this.allowAddingNewMappings = input(true, ...(ngDevMode ? [{ debugName: "allowAddingNewMappings" }] : []));
4700
4694
  this.allowRenamingMappings = input(true, ...(ngDevMode ? [{ debugName: "allowRenamingMappings" }] : []));
4701
4695
  this.allowRelabellingMappings = input(true, ...(ngDevMode ? [{ debugName: "allowRelabellingMappings" }] : []));
4696
+ /** When set, mapping names must match this regex. Validated on rename. */
4697
+ this.mappingNameFormatRegex = input(null, ...(ngDevMode ? [{ debugName: "mappingNameFormatRegex" }] : []));
4698
+ /** Error message shown when a name fails the mappingNameFormatRegex check. */
4699
+ this.mappingNameFormatErrorMessage = input(gettext('Name does not match the required format.'), ...(ngDevMode ? [{ debugName: "mappingNameFormatErrorMessage" }] : []));
4702
4700
  this.allowEditingMappings = input(true, ...(ngDevMode ? [{ debugName: "allowEditingMappings" }] : []));
4703
4701
  this.allowRemovingMappings = input(true, ...(ngDevMode ? [{ debugName: "allowRemovingMappings" }] : []));
4704
4702
  this.showLabels = input(true, ...(ngDevMode ? [{ debugName: "showLabels" }] : []));
@@ -4711,10 +4709,14 @@ class AssetPropertyMappingsComponent {
4711
4709
  * Callback to transform a mapping into the text that gets copied to the clipboard.
4712
4710
  * Exposed as an input so widget config factories can override the default (e.g. to
4713
4711
  * produce a template expression like `${this.c8yProperties?.temperature}`).
4712
+ * The second argument is the current widget config, which can be used to adjust
4713
+ * the output based on widget-specific settings (e.g. legacy mode).
4714
4714
  */
4715
4715
  this.onBeforeCopyMappingToClipboard = input((mapping) => String(mapping.name), ...(ngDevMode ? [{ debugName: "onBeforeCopyMappingToClipboard" }] : []));
4716
- this.emptyStateTitle = gettext('No asset property mappings');
4717
- this.emptyStateSubtitle = gettext('Add first asset property mapping.');
4716
+ this.emptyStateTitle = input(gettext('No asset property mappings'), ...(ngDevMode ? [{ debugName: "emptyStateTitle" }] : []));
4717
+ this.emptyStateSubtitle = input(gettext('Add first asset property mapping.'), ...(ngDevMode ? [{ debugName: "emptyStateSubtitle" }] : []));
4718
+ /** Message shown in the section's feedback area. Available placeholder: {{ count }} */
4719
+ this.feedbackMessage = input(gettext('{{ count }} selected'), ...(ngDevMode ? [{ debugName: "feedbackMessage" }] : []));
4718
4720
  this.mappings$ = this.widgetConfigService.currentConfig$.pipe(map$1(config => get(config, this.widgetConfigPath())));
4719
4721
  this.keys$ = this.mappings$.pipe(map$1(mappings => Object.keys(mappings || {}).sort((a, b) => a.localeCompare(b))));
4720
4722
  this.mappingsSignal = toSignal(this.mappings$, { initialValue: null });
@@ -4753,7 +4755,7 @@ class AssetPropertyMappingsComponent {
4753
4755
  const config = await firstValueFrom(this.widgetConfigService.currentConfig$);
4754
4756
  if (!get(config, this.widgetConfigPath())) {
4755
4757
  const newConfig = { ...config };
4756
- const mappings = structuredClone(this.initialMappings());
4758
+ const mappings = structuredClone(this.initialMappings() ?? {});
4757
4759
  for (const [key, mapping] of Object.entries(mappings)) {
4758
4760
  if (mapping.assetProperty && !mapping.assetProperty.asset) {
4759
4761
  if (!config.device) {
@@ -4815,7 +4817,7 @@ class AssetPropertyMappingsComponent {
4815
4817
  set(newConfig, this.widgetConfigPath(), mappings);
4816
4818
  this.widgetConfigService.updateConfig(newConfig);
4817
4819
  }
4818
- catch (ex) {
4820
+ catch {
4819
4821
  // cancelled
4820
4822
  }
4821
4823
  finally {
@@ -4855,7 +4857,7 @@ class AssetPropertyMappingsComponent {
4855
4857
  set(newConfig, this.widgetConfigPath(), mappings);
4856
4858
  this.widgetConfigService.updateConfig(newConfig);
4857
4859
  }
4858
- catch (ex) {
4860
+ catch {
4859
4861
  // cancelled
4860
4862
  }
4861
4863
  finally {
@@ -4869,7 +4871,8 @@ class AssetPropertyMappingsComponent {
4869
4871
  }
4870
4872
  async copyMappingToClipboard(name, mapping) {
4871
4873
  const mappingToTextFn = this.onBeforeCopyMappingToClipboard();
4872
- const text = mappingToTextFn({ name, ...mapping });
4874
+ const config = await firstValueFrom(this.widgetConfigService.currentConfig$);
4875
+ const text = mappingToTextFn({ name, ...mapping }, config);
4873
4876
  await this.clipboardService.writeText(text);
4874
4877
  }
4875
4878
  async removeMapping(name) {
@@ -4897,11 +4900,17 @@ class AssetPropertyMappingsComponent {
4897
4900
  }
4898
4901
  getNameValidators(key) {
4899
4902
  if (!this.nameValidatorCache.has(key)) {
4903
+ const regex = this.mappingNameFormatRegex();
4900
4904
  this.nameValidatorCache.set(key, [
4901
4905
  Validators.required,
4902
4906
  ctrl => this.isNameAlreadyUsed(ctrl.value, key, this.keysSignal())
4903
4907
  ? { 'key-already-used': true }
4904
- : null
4908
+ : null,
4909
+ ...(regex
4910
+ ? [
4911
+ (ctrl) => regex.test(ctrl.value?.trim()) ? null : { 'key-invalid-format': true }
4912
+ ]
4913
+ : [])
4905
4914
  ]);
4906
4915
  }
4907
4916
  return this.nameValidatorCache.get(key);
@@ -4956,7 +4965,7 @@ class AssetPropertyMappingsComponent {
4956
4965
  return result;
4957
4966
  }
4958
4967
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AssetPropertyMappingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4959
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AssetPropertyMappingsComponent, isStandalone: true, selector: "c8y-asset-property-mappings", inputs: { widgetConfigPath: { classPropertyName: "widgetConfigPath", publicName: "widgetConfigPath", isSignal: true, isRequired: false, transformFunction: null }, initialMappings: { classPropertyName: "initialMappings", publicName: "initialMappings", isSignal: true, isRequired: false, transformFunction: null }, allowAddingNewMappings: { classPropertyName: "allowAddingNewMappings", publicName: "allowAddingNewMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRenamingMappings: { classPropertyName: "allowRenamingMappings", publicName: "allowRenamingMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRelabellingMappings: { classPropertyName: "allowRelabellingMappings", publicName: "allowRelabellingMappings", isSignal: true, isRequired: false, transformFunction: null }, allowEditingMappings: { classPropertyName: "allowEditingMappings", publicName: "allowEditingMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRemovingMappings: { classPropertyName: "allowRemovingMappings", publicName: "allowRemovingMappings", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, showNames: { classPropertyName: "showNames", publicName: "showNames", isSignal: true, isRequired: false, transformFunction: null }, showAssets: { classPropertyName: "showAssets", publicName: "showAssets", isSignal: true, isRequired: false, transformFunction: null }, showProperties: { classPropertyName: "showProperties", publicName: "showProperties", isSignal: true, isRequired: false, transformFunction: null }, showValues: { classPropertyName: "showValues", publicName: "showValues", isSignal: true, isRequired: false, transformFunction: null }, actionsColumnSpan: { classPropertyName: "actionsColumnSpan", publicName: "actionsColumnSpan", isSignal: true, isRequired: false, transformFunction: null }, onBeforeCopyMappingToClipboard: { classPropertyName: "onBeforeCopyMappingToClipboard", publicName: "onBeforeCopyMappingToClipboard", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"responsive-grid-table-wrapper--300 responsive-grid-table-wrapper--striped inner-scroll separator-top\"\n style=\"max-height: 300px\"\n>\n @let keys = keys$ | async;\n @let resolvedAssets = resolvedAssets$ | async;\n @let allMappings = mappings$ | async;\n @if (!keys?.length) {\n <div class=\"p-24\">\n <c8y-ui-empty-state\n icon=\"code\"\n [title]=\"emptyStateTitle | translate\"\n [subtitle]=\"emptyStateSubtitle | translate\"\n ></c8y-ui-empty-state>\n </div>\n } @else {\n @for (key of keys; track key) {\n @let mapping = allMappings?.[key];\n @let property = mapping?.assetProperty;\n @let asset = resolvedAssets?.get(property?.asset?.id);\n <div\n class=\"responsive-grid-table responsive-grid-table__body responsive-grid-table--condensed responsive-grid-table--separator p-l-16\"\n >\n @if (showLabels()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.label\"\n [attr.aria-label]=\"'Label' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Label' | translate }}</p>\n @if (allowRelabellingMappings()) {\n <c8y-input-group-editable\n name=\"label-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Label' | translate\"\n [ngModel]=\"mapping?.label || key\"\n [validators]=\"getLabelValidators(key)\"\n (ngModelChange)=\"saveLabel(key, $event)\"\n >\n <c8y-message\n name=\"label-already-used\"\n [text]=\"'Label already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n <span class=\"tag tag--default text-bold\">{{ mapping?.label || key }}</span>\n }\n </div>\n </div>\n }\n @if (showNames()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.name\"\n [attr.aria-label]=\"'Name' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Name' | translate }}</p>\n @if (allowRenamingMappings()) {\n <c8y-input-group-editable\n class=\"text-bold\"\n name=\"name-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Name' | translate\"\n [ngModel]=\"key\"\n [validators]=\"getNameValidators(key)\"\n (ngModelChange)=\"saveName(key, $event)\"\n >\n <c8y-message\n name=\"key-already-used\"\n [text]=\"'Name already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n {{ key }}\n }\n </div>\n </div>\n }\n <div [class]=\"'showOnHover col-' + actionsColumnSpan()\">\n <div class=\"col-actions fit-w min-width-0\">\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Copy mapping to clipboard' | translate\"\n tooltip=\"{{ 'Copy mapping to clipboard' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"copyMappingToClipboard(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"clipboard\"\n aria-hidden=\"true\"\n ></i>\n </button>\n @if (allowEditingMappings() && !mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Assign property' | translate\"\n tooltip=\"{{ 'Assign property' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"editMapping(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"pencil\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowEditingMappings() && mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Clear mapping' | translate\"\n tooltip=\"{{ 'Clear mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"clearMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove-property\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowRemovingMappings()) {\n <button\n class=\"btn-dot btn-sm btn-dot--danger m-0\"\n [attr.aria-label]=\"'Remove mapping' | translate\"\n tooltip=\"{{ 'Remove mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n </div>\n </div>\n @if (showAssets()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.asset\"\n [attr.aria-label]=\"'Asset' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Asset' | translate }}</p>\n {{ mapping?.assetProperty?.asset?.name || mapping?.assetProperty?.asset?.id || '\u2014' }}\n </div>\n </div>\n }\n @if (showProperties()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.property\"\n [attr.aria-label]=\"'Property' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Property' | translate }}</p>\n {{ property?.label || property?.name || '\u2014' }}\n </div>\n </div>\n }\n @if (showValues()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.value\"\n [attr.aria-label]=\"'Value' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Value' | translate }}</p>\n @if (property && asset) {\n @let value = (property | c8yAssetPropertyValue: asset | async) ?? '\u2014';\n <samp\n class=\"text-truncate min-width-0\"\n title=\"{{ value }}\"\n >\n {{ value }}\n </samp>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n</div>\n@if (allowAddingNewMappings() || (allowRemovingMappings() && (keys$ | async)?.length)) {\n <div class=\"p-16 separator-top d-flex j-c-between a-i-center\">\n @if (allowAddingNewMappings()) {\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"addMappings()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Add mappings' | translate }}\n </button>\n }\n @if (allowRemovingMappings() && (keys$ | async)?.length) {\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"removeAllMappings()\"\n >\n <i\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Remove all mappings' | translate }}\n </button>\n }\n </div>\n}\n\n<c8y-widget-config-feedback>\n <span\n class=\"tag tag--info chip text-12 m-4\"\n ngNonBindable\n translate\n [translateParams]=\"{\n count: (keys$ | async)?.length ?? 0\n }\"\n >\n {{ count }} selected\n </span>\n</c8y-widget-config-feedback>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: InputGroupEditableComponent, selector: "c8y-input-group-editable", inputs: ["ariaLabel", "name", "size", "placeholder", "validators", "asyncValidators"], outputs: ["save", "cancel"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$4.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: "component", type: WidgetConfigFeedbackComponent, selector: "c8y-widget-config-feedback" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AssetPropertyValuePipe, name: "c8yAssetPropertyValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4968
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AssetPropertyMappingsComponent, isStandalone: true, selector: "c8y-asset-property-mappings", inputs: { widgetConfigPath: { classPropertyName: "widgetConfigPath", publicName: "widgetConfigPath", isSignal: true, isRequired: false, transformFunction: null }, initialMappings: { classPropertyName: "initialMappings", publicName: "initialMappings", isSignal: true, isRequired: false, transformFunction: null }, allowAddingNewMappings: { classPropertyName: "allowAddingNewMappings", publicName: "allowAddingNewMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRenamingMappings: { classPropertyName: "allowRenamingMappings", publicName: "allowRenamingMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRelabellingMappings: { classPropertyName: "allowRelabellingMappings", publicName: "allowRelabellingMappings", isSignal: true, isRequired: false, transformFunction: null }, mappingNameFormatRegex: { classPropertyName: "mappingNameFormatRegex", publicName: "mappingNameFormatRegex", isSignal: true, isRequired: false, transformFunction: null }, mappingNameFormatErrorMessage: { classPropertyName: "mappingNameFormatErrorMessage", publicName: "mappingNameFormatErrorMessage", isSignal: true, isRequired: false, transformFunction: null }, allowEditingMappings: { classPropertyName: "allowEditingMappings", publicName: "allowEditingMappings", isSignal: true, isRequired: false, transformFunction: null }, allowRemovingMappings: { classPropertyName: "allowRemovingMappings", publicName: "allowRemovingMappings", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, showNames: { classPropertyName: "showNames", publicName: "showNames", isSignal: true, isRequired: false, transformFunction: null }, showAssets: { classPropertyName: "showAssets", publicName: "showAssets", isSignal: true, isRequired: false, transformFunction: null }, showProperties: { classPropertyName: "showProperties", publicName: "showProperties", isSignal: true, isRequired: false, transformFunction: null }, showValues: { classPropertyName: "showValues", publicName: "showValues", isSignal: true, isRequired: false, transformFunction: null }, actionsColumnSpan: { classPropertyName: "actionsColumnSpan", publicName: "actionsColumnSpan", isSignal: true, isRequired: false, transformFunction: null }, onBeforeCopyMappingToClipboard: { classPropertyName: "onBeforeCopyMappingToClipboard", publicName: "onBeforeCopyMappingToClipboard", isSignal: true, isRequired: false, transformFunction: null }, emptyStateTitle: { classPropertyName: "emptyStateTitle", publicName: "emptyStateTitle", isSignal: true, isRequired: false, transformFunction: null }, emptyStateSubtitle: { classPropertyName: "emptyStateSubtitle", publicName: "emptyStateSubtitle", isSignal: true, isRequired: false, transformFunction: null }, feedbackMessage: { classPropertyName: "feedbackMessage", publicName: "feedbackMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"responsive-grid-table-wrapper--300 responsive-grid-table-wrapper--striped inner-scroll separator-top\"\n style=\"max-height: 300px\"\n>\n @let keys = keys$ | async;\n @let resolvedAssets = resolvedAssets$ | async;\n @let allMappings = mappings$ | async;\n @if (!keys?.length) {\n <div class=\"p-24\">\n <c8y-ui-empty-state\n icon=\"code\"\n [title]=\"emptyStateTitle() | translate\"\n [subtitle]=\"emptyStateSubtitle() | translate\"\n ></c8y-ui-empty-state>\n </div>\n } @else {\n @for (key of keys; track key) {\n @let mapping = allMappings?.[key];\n @let property = mapping?.assetProperty;\n @let asset = resolvedAssets?.get(property?.asset?.id);\n <div\n class=\"responsive-grid-table responsive-grid-table__body responsive-grid-table--condensed responsive-grid-table--separator p-l-16\"\n >\n @if (showLabels()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.label\"\n [attr.aria-label]=\"'Label' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Label' | translate }}</p>\n @if (allowRelabellingMappings()) {\n <c8y-input-group-editable\n name=\"label-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Label' | translate\"\n [ngModel]=\"mapping?.label || key\"\n [validators]=\"getLabelValidators(key)\"\n (ngModelChange)=\"saveLabel(key, $event)\"\n >\n <c8y-message\n name=\"label-already-used\"\n [text]=\"'Label already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n <span class=\"tag tag--default text-bold\">{{ mapping?.label || key }}</span>\n }\n </div>\n </div>\n }\n @if (showNames()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.name\"\n [attr.aria-label]=\"'Name' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Name' | translate }}</p>\n @if (allowRenamingMappings()) {\n <c8y-input-group-editable\n class=\"text-bold\"\n name=\"name-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Name' | translate\"\n [ngModel]=\"key\"\n [validators]=\"getNameValidators(key)\"\n (ngModelChange)=\"saveName(key, $event)\"\n >\n <c8y-message\n name=\"key-already-used\"\n [text]=\"'Name already used. Use a different one.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"key-invalid-format\"\n [text]=\"mappingNameFormatErrorMessage() | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n {{ key }}\n }\n </div>\n </div>\n }\n <div [class]=\"'showOnHover col-' + actionsColumnSpan()\">\n <div class=\"col-actions fit-w min-width-0\">\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Copy mapping to clipboard' | translate\"\n tooltip=\"{{ 'Copy mapping to clipboard' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"copyMappingToClipboard(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"clipboard\"\n aria-hidden=\"true\"\n ></i>\n </button>\n @if (allowEditingMappings() && !mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Assign property' | translate\"\n tooltip=\"{{ 'Assign property' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"editMapping(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"pencil\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowEditingMappings() && mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Clear mapping' | translate\"\n tooltip=\"{{ 'Clear mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"clearMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove-property\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowRemovingMappings()) {\n <button\n class=\"btn-dot btn-sm btn-dot--danger m-0\"\n [attr.aria-label]=\"'Remove mapping' | translate\"\n tooltip=\"{{ 'Remove mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n </div>\n </div>\n @if (showAssets()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.asset\"\n [attr.aria-label]=\"'Asset' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Asset' | translate }}</p>\n {{ mapping?.assetProperty?.asset?.name || mapping?.assetProperty?.asset?.id || '\u2014' }}\n </div>\n </div>\n }\n @if (showProperties()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.property\"\n [attr.aria-label]=\"'Property' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Property' | translate }}</p>\n {{ property?.label || property?.name || '\u2014' }}\n </div>\n </div>\n }\n @if (showValues()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.value\"\n [attr.aria-label]=\"'Value' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Value' | translate }}</p>\n @if (property && asset) {\n @let value = (property | c8yAssetPropertyValue: asset | async) ?? '\u2014';\n <samp\n class=\"text-truncate min-width-0\"\n title=\"{{ value }}\"\n >\n {{ value }}\n </samp>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n</div>\n@if (allowAddingNewMappings() || (allowRemovingMappings() && (keys$ | async)?.length)) {\n <div class=\"p-16 separator-top d-flex j-c-between a-i-center\">\n @if (allowAddingNewMappings()) {\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"addMappings()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Add mappings' | translate }}\n </button>\n }\n @if (allowRemovingMappings() && (keys$ | async)?.length) {\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"removeAllMappings()\"\n >\n <i\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Remove all mappings' | translate }}\n </button>\n }\n </div>\n}\n\n<c8y-widget-config-feedback>\n <span class=\"tag tag--info chip text-12 m-4\">\n {{ feedbackMessage() | translate: { count: keys?.length ?? 0 } }}\n </span>\n</c8y-widget-config-feedback>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: InputGroupEditableComponent, selector: "c8y-input-group-editable", inputs: ["ariaLabel", "name", "size", "placeholder", "validators", "asyncValidators", "autocomplete"], outputs: ["save", "cancel"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$4.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: "component", type: WidgetConfigFeedbackComponent, selector: "c8y-widget-config-feedback" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AssetPropertyValuePipe, name: "c8yAssetPropertyValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4960
4969
  }
4961
4970
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AssetPropertyMappingsComponent, decorators: [{
4962
4971
  type: Component,
@@ -4965,7 +4974,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4965
4974
  FormsModule,
4966
4975
  IconDirective,
4967
4976
  C8yTranslatePipe,
4968
- C8yTranslateDirective,
4969
4977
  InputGroupEditableComponent,
4970
4978
  MessageDirective,
4971
4979
  EmptyStateComponent,
@@ -4973,12 +4981,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4973
4981
  BsDropdownModule,
4974
4982
  TooltipModule,
4975
4983
  WidgetConfigFeedbackComponent
4976
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"responsive-grid-table-wrapper--300 responsive-grid-table-wrapper--striped inner-scroll separator-top\"\n style=\"max-height: 300px\"\n>\n @let keys = keys$ | async;\n @let resolvedAssets = resolvedAssets$ | async;\n @let allMappings = mappings$ | async;\n @if (!keys?.length) {\n <div class=\"p-24\">\n <c8y-ui-empty-state\n icon=\"code\"\n [title]=\"emptyStateTitle | translate\"\n [subtitle]=\"emptyStateSubtitle | translate\"\n ></c8y-ui-empty-state>\n </div>\n } @else {\n @for (key of keys; track key) {\n @let mapping = allMappings?.[key];\n @let property = mapping?.assetProperty;\n @let asset = resolvedAssets?.get(property?.asset?.id);\n <div\n class=\"responsive-grid-table responsive-grid-table__body responsive-grid-table--condensed responsive-grid-table--separator p-l-16\"\n >\n @if (showLabels()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.label\"\n [attr.aria-label]=\"'Label' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Label' | translate }}</p>\n @if (allowRelabellingMappings()) {\n <c8y-input-group-editable\n name=\"label-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Label' | translate\"\n [ngModel]=\"mapping?.label || key\"\n [validators]=\"getLabelValidators(key)\"\n (ngModelChange)=\"saveLabel(key, $event)\"\n >\n <c8y-message\n name=\"label-already-used\"\n [text]=\"'Label already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n <span class=\"tag tag--default text-bold\">{{ mapping?.label || key }}</span>\n }\n </div>\n </div>\n }\n @if (showNames()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.name\"\n [attr.aria-label]=\"'Name' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Name' | translate }}</p>\n @if (allowRenamingMappings()) {\n <c8y-input-group-editable\n class=\"text-bold\"\n name=\"name-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Name' | translate\"\n [ngModel]=\"key\"\n [validators]=\"getNameValidators(key)\"\n (ngModelChange)=\"saveName(key, $event)\"\n >\n <c8y-message\n name=\"key-already-used\"\n [text]=\"'Name already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n {{ key }}\n }\n </div>\n </div>\n }\n <div [class]=\"'showOnHover col-' + actionsColumnSpan()\">\n <div class=\"col-actions fit-w min-width-0\">\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Copy mapping to clipboard' | translate\"\n tooltip=\"{{ 'Copy mapping to clipboard' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"copyMappingToClipboard(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"clipboard\"\n aria-hidden=\"true\"\n ></i>\n </button>\n @if (allowEditingMappings() && !mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Assign property' | translate\"\n tooltip=\"{{ 'Assign property' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"editMapping(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"pencil\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowEditingMappings() && mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Clear mapping' | translate\"\n tooltip=\"{{ 'Clear mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"clearMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove-property\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowRemovingMappings()) {\n <button\n class=\"btn-dot btn-sm btn-dot--danger m-0\"\n [attr.aria-label]=\"'Remove mapping' | translate\"\n tooltip=\"{{ 'Remove mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n </div>\n </div>\n @if (showAssets()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.asset\"\n [attr.aria-label]=\"'Asset' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Asset' | translate }}</p>\n {{ mapping?.assetProperty?.asset?.name || mapping?.assetProperty?.asset?.id || '\u2014' }}\n </div>\n </div>\n }\n @if (showProperties()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.property\"\n [attr.aria-label]=\"'Property' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Property' | translate }}</p>\n {{ property?.label || property?.name || '\u2014' }}\n </div>\n </div>\n }\n @if (showValues()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.value\"\n [attr.aria-label]=\"'Value' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Value' | translate }}</p>\n @if (property && asset) {\n @let value = (property | c8yAssetPropertyValue: asset | async) ?? '\u2014';\n <samp\n class=\"text-truncate min-width-0\"\n title=\"{{ value }}\"\n >\n {{ value }}\n </samp>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n</div>\n@if (allowAddingNewMappings() || (allowRemovingMappings() && (keys$ | async)?.length)) {\n <div class=\"p-16 separator-top d-flex j-c-between a-i-center\">\n @if (allowAddingNewMappings()) {\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"addMappings()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Add mappings' | translate }}\n </button>\n }\n @if (allowRemovingMappings() && (keys$ | async)?.length) {\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"removeAllMappings()\"\n >\n <i\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Remove all mappings' | translate }}\n </button>\n }\n </div>\n}\n\n<c8y-widget-config-feedback>\n <span\n class=\"tag tag--info chip text-12 m-4\"\n ngNonBindable\n translate\n [translateParams]=\"{\n count: (keys$ | async)?.length ?? 0\n }\"\n >\n {{ count }} selected\n </span>\n</c8y-widget-config-feedback>\n" }]
4977
- }], propDecorators: { widgetConfigPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "widgetConfigPath", required: false }] }], initialMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialMappings", required: false }] }], allowAddingNewMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAddingNewMappings", required: false }] }], allowRenamingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRenamingMappings", required: false }] }], allowRelabellingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRelabellingMappings", required: false }] }], allowEditingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEditingMappings", required: false }] }], allowRemovingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRemovingMappings", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], showNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNames", required: false }] }], showAssets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAssets", required: false }] }], showProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "showProperties", required: false }] }], showValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValues", required: false }] }], actionsColumnSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsColumnSpan", required: false }] }], onBeforeCopyMappingToClipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "onBeforeCopyMappingToClipboard", required: false }] }] } });
4984
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"responsive-grid-table-wrapper--300 responsive-grid-table-wrapper--striped inner-scroll separator-top\"\n style=\"max-height: 300px\"\n>\n @let keys = keys$ | async;\n @let resolvedAssets = resolvedAssets$ | async;\n @let allMappings = mappings$ | async;\n @if (!keys?.length) {\n <div class=\"p-24\">\n <c8y-ui-empty-state\n icon=\"code\"\n [title]=\"emptyStateTitle() | translate\"\n [subtitle]=\"emptyStateSubtitle() | translate\"\n ></c8y-ui-empty-state>\n </div>\n } @else {\n @for (key of keys; track key) {\n @let mapping = allMappings?.[key];\n @let property = mapping?.assetProperty;\n @let asset = resolvedAssets?.get(property?.asset?.id);\n <div\n class=\"responsive-grid-table responsive-grid-table__body responsive-grid-table--condensed responsive-grid-table--separator p-l-16\"\n >\n @if (showLabels()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.label\"\n [attr.aria-label]=\"'Label' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Label' | translate }}</p>\n @if (allowRelabellingMappings()) {\n <c8y-input-group-editable\n name=\"label-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Label' | translate\"\n [ngModel]=\"mapping?.label || key\"\n [validators]=\"getLabelValidators(key)\"\n (ngModelChange)=\"saveLabel(key, $event)\"\n >\n <c8y-message\n name=\"label-already-used\"\n [text]=\"'Label already used. Use a different one.' | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n <span class=\"tag tag--default text-bold\">{{ mapping?.label || key }}</span>\n }\n </div>\n </div>\n }\n @if (showNames()) {\n <div\n [class]=\"'col-' + row1ColumnSpans.name\"\n [attr.aria-label]=\"'Name' | translate\"\n >\n <div class=\"fit-w\">\n <p class=\"text-label-small\">{{ 'Name' | translate }}</p>\n @if (allowRenamingMappings()) {\n <c8y-input-group-editable\n class=\"text-bold\"\n name=\"name-{{ key }}\"\n size=\"sm\"\n [ariaLabel]=\"'Name' | translate\"\n [ngModel]=\"key\"\n [validators]=\"getNameValidators(key)\"\n (ngModelChange)=\"saveName(key, $event)\"\n >\n <c8y-message\n name=\"key-already-used\"\n [text]=\"'Name already used. Use a different one.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"key-invalid-format\"\n [text]=\"mappingNameFormatErrorMessage() | translate\"\n ></c8y-message>\n </c8y-input-group-editable>\n } @else {\n {{ key }}\n }\n </div>\n </div>\n }\n <div [class]=\"'showOnHover col-' + actionsColumnSpan()\">\n <div class=\"col-actions fit-w min-width-0\">\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Copy mapping to clipboard' | translate\"\n tooltip=\"{{ 'Copy mapping to clipboard' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"copyMappingToClipboard(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"clipboard\"\n aria-hidden=\"true\"\n ></i>\n </button>\n @if (allowEditingMappings() && !mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Assign property' | translate\"\n tooltip=\"{{ 'Assign property' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"editMapping(key, mapping!)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"pencil\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowEditingMappings() && mapping?.assetProperty) {\n <button\n class=\"btn-dot btn-sm m-0\"\n [attr.aria-label]=\"'Clear mapping' | translate\"\n tooltip=\"{{ 'Clear mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"clearMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove-property\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n @if (allowRemovingMappings()) {\n <button\n class=\"btn-dot btn-sm btn-dot--danger m-0\"\n [attr.aria-label]=\"'Remove mapping' | translate\"\n tooltip=\"{{ 'Remove mapping' | translate }}\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeMapping(key)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n </div>\n </div>\n @if (showAssets()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.asset\"\n [attr.aria-label]=\"'Asset' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Asset' | translate }}</p>\n {{ mapping?.assetProperty?.asset?.name || mapping?.assetProperty?.asset?.id || '\u2014' }}\n </div>\n </div>\n }\n @if (showProperties()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.property\"\n [attr.aria-label]=\"'Property' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Property' | translate }}</p>\n {{ property?.label || property?.name || '\u2014' }}\n </div>\n </div>\n }\n @if (showValues()) {\n <div\n [class]=\"'p-b-16 col-' + row2ColumnSpans.value\"\n [attr.aria-label]=\"'Value' | translate\"\n >\n <div class=\"min-width-0\">\n <p class=\"text-label-small\">{{ 'Value' | translate }}</p>\n @if (property && asset) {\n @let value = (property | c8yAssetPropertyValue: asset | async) ?? '\u2014';\n <samp\n class=\"text-truncate min-width-0\"\n title=\"{{ value }}\"\n >\n {{ value }}\n </samp>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n</div>\n@if (allowAddingNewMappings() || (allowRemovingMappings() && (keys$ | async)?.length)) {\n <div class=\"p-16 separator-top d-flex j-c-between a-i-center\">\n @if (allowAddingNewMappings()) {\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"addMappings()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Add mappings' | translate }}\n </button>\n }\n @if (allowRemovingMappings() && (keys$ | async)?.length) {\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n [disabled]=\"isDrawerOpen()\"\n (click)=\"removeAllMappings()\"\n >\n <i\n c8yIcon=\"minus-circle\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Remove all mappings' | translate }}\n </button>\n }\n </div>\n}\n\n<c8y-widget-config-feedback>\n <span class=\"tag tag--info chip text-12 m-4\">\n {{ feedbackMessage() | translate: { count: keys?.length ?? 0 } }}\n </span>\n</c8y-widget-config-feedback>\n" }]
4985
+ }], propDecorators: { widgetConfigPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "widgetConfigPath", required: false }] }], initialMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialMappings", required: false }] }], allowAddingNewMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAddingNewMappings", required: false }] }], allowRenamingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRenamingMappings", required: false }] }], allowRelabellingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRelabellingMappings", required: false }] }], mappingNameFormatRegex: [{ type: i0.Input, args: [{ isSignal: true, alias: "mappingNameFormatRegex", required: false }] }], mappingNameFormatErrorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "mappingNameFormatErrorMessage", required: false }] }], allowEditingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEditingMappings", required: false }] }], allowRemovingMappings: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRemovingMappings", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], showNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNames", required: false }] }], showAssets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAssets", required: false }] }], showProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "showProperties", required: false }] }], showValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValues", required: false }] }], actionsColumnSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsColumnSpan", required: false }] }], onBeforeCopyMappingToClipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "onBeforeCopyMappingToClipboard", required: false }] }], emptyStateTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyStateTitle", required: false }] }], emptyStateSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyStateSubtitle", required: false }] }], feedbackMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "feedbackMessage", required: false }] }] } });
4978
4986
 
4979
4987
  /**
4980
4988
  * Generated bundle index. Do not edit.
4981
4989
  */
4982
4990
 
4983
- export { ALL_GLOBAL_ROLES_SELECTED, AddDashboardComponent, AddDashboardFactory, AppearanceSettingsComponent, AssetPropertyMappingsComponent, AssetPropertyMappingsService, CONTEXT_DASHBOARD_CONFIG, ContextDashboardComponent, ContextDashboardModule, ContextDashboardService, ContextDashboardType, DASHBOARD_CHILDREN_STATE_NAME, DASHBOARD_DETAILS_OUTLET, DASHBOARD_DETAILS_TABS_OUTLET_NAME, DASHBOARD_SETTINGS_CHANGES, DASHBOARD_THEME_CLASSES, DashboardActionBarFactory, DashboardDetailComponent, DashboardDetailService, DashboardDetailsTabId, DeviceInfoDashboardComponent, DeviceInfoDashboardModule, DeviceManagementHomeDashboardComponent, DeviceManagementHomeDashboardModule, GlobalContextSectionComponent, HOOK_WIDGET_CONFIG, NewDashboardGuard, PRODUCT_EXPERIENCE, PasteDashboardActionComponent, REPORT_DEFAULT_NAVIGATION_NODE_PRIORITY, STYLING_CLASS_PREFIXES, TypeDashboardInfoComponent, WIDGET_CONTENT_CLASSES, WIDGET_HEADER_CLASSES, WidgetAssetSelectorComponent, WidgetConfigAppearanceComponent, WidgetConfigComponent, WidgetConfigFeedbackComponent, WidgetConfigGeneralComponent, WidgetConfigSectionComponent, WidgetConfigSectionService, WidgetConfigService, WidgetPreviewComponent, WidgetPreviewWrapperComponent, WidgetService, getPropertyBaseKey, hookWidgetConfig, newDashboardTab, quoteAndEscape, renamePropertyKeyInCode };
4991
+ export { ALL_GLOBAL_ROLES_SELECTED, AddDashboardComponent, AddDashboardFactory, AppearanceSettingsComponent, AssetPropertyMappingsComponent, AssetPropertyMappingsService, CONTEXT_DASHBOARD_CONFIG, ContextDashboardComponent, ContextDashboardModule, ContextDashboardService, ContextDashboardType, DASHBOARD_CHILDREN_STATE_NAME, DASHBOARD_DETAILS_OUTLET, DASHBOARD_DETAILS_TABS_OUTLET_NAME, DASHBOARD_SETTINGS_CHANGES, DASHBOARD_THEME_CLASSES, DashboardActionBarFactory, DashboardDetailComponent, DashboardDetailService, DashboardDetailsTabId, DeviceInfoDashboardComponent, DeviceInfoDashboardModule, DeviceManagementHomeDashboardComponent, DeviceManagementHomeDashboardModule, GlobalContextSectionComponent, HOOK_WIDGET_CONFIG, NewDashboardGuard, PRODUCT_EXPERIENCE, PasteDashboardActionComponent, REPORT_DEFAULT_NAVIGATION_NODE_PRIORITY, STYLING_CLASS_PREFIXES, TypeDashboardInfoComponent, WIDGET_CONTENT_CLASSES, WIDGET_HEADER_CLASSES, WidgetAssetSelectorComponent, WidgetConfigAppearanceComponent, WidgetConfigComponent, WidgetConfigFeedbackComponent, WidgetConfigGeneralComponent, WidgetConfigSectionComponent, WidgetConfigSectionService, WidgetConfigService, WidgetPreviewComponent, WidgetPreviewWrapperComponent, WidgetService, escapeForRegExp, getPropertyBaseKey, hookWidgetConfig, newDashboardTab, quoteAndEscape, renamePropertyKeyInCode };
4984
4992
  //# sourceMappingURL=c8y-ngx-components-context-dashboard.mjs.map