@acorex-platform/framework-client 2.0.0-next.20 → 2.0.0-next.22

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 (44) hide show
  1. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs → acorex-platform-framework-client-common-common-settings.provider-Biu0_ryw.mjs} +18 -2
  2. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Biu0_ryw.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-framework-client-common.mjs +335 -168
  4. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +20 -0
  6. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +192 -29
  8. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  9. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-uEA2EE9v.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CRocGF2a.mjs} +124 -23
  10. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CRocGF2a.mjs.map +1 -0
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-i9bfszKb.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-ByeXrO6p.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-i9bfszKb.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-ByeXrO6p.mjs.map} +1 -1
  13. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-Ej4_qrGa.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-C6dSe9Y2.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-Ej4_qrGa.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-C6dSe9Y2.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BbYsgq32.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-BuI50fZ4.mjs} +2 -2
  16. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BbYsgq32.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-BuI50fZ4.mjs.map} +1 -1
  17. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-CWc-6CZ8.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-DZ3lioc_.mjs} +2 -2
  18. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-CWc-6CZ8.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-DZ3lioc_.mjs.map} +1 -1
  19. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  20. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +6 -0
  21. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  22. package/fesm2022/{acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DZMgisgf.mjs → acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CELbt6ig.mjs} +82 -22
  23. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CELbt6ig.mjs.map +1 -0
  24. package/fesm2022/acorex-platform-framework-client-layout-widgets-filter-default-operators-widget-edit.component-DOEn58--.mjs +103 -0
  25. package/fesm2022/acorex-platform-framework-client-layout-widgets-filter-default-operators-widget-edit.component-DOEn58--.mjs.map +1 -0
  26. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BejeCu5q.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BSjcMKNA.mjs} +2 -2
  27. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BejeCu5q.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BSjcMKNA.mjs.map} +1 -1
  28. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-C2XsTtkl.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-Co5_b33I.mjs} +2 -2
  29. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-C2XsTtkl.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-Co5_b33I.mjs.map} +1 -1
  30. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -1
  31. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +82 -26
  32. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  33. package/i18n/en-AU/general.json +16 -0
  34. package/i18n/en-US/general.json +16 -0
  35. package/i18n/fa-IR/general.json +16 -0
  36. package/package.json +2 -2
  37. package/types/acorex-platform-framework-client-common.d.ts +44 -3
  38. package/types/acorex-platform-framework-client-layout-components.d.ts +12 -2
  39. package/types/acorex-platform-framework-client-layout-entity.d.ts +45 -5
  40. package/types/acorex-platform-framework-client-layout-widgets.d.ts +8 -0
  41. package/types/acorex-platform-framework-client-themes-default.d.ts +12 -0
  42. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs.map +0 -1
  43. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-uEA2EE9v.mjs.map +0 -1
  44. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DZMgisgf.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { AXPRegionalSetting, resolveActionLook, resolveToSurfaceClass, AXPWidgetsCatalog, createRandomUuid, omitFilterClauseIdentity, AXPPlatformScope, AXPFileStorageStatus, flattenQueryFilterUserGroups, hasQueryFilterGroupId, isCompleteFilterCondition, coerceFilterDisplayText, AXP_QUERY_QUICK_SEARCH_FIELD, wrapQueryFilterRoot, QUERY_FILTER_CHIP_EXPAND_MAX_CONDITIONS, AXPKeyboardShortcutPriority, runtimeQueryCollectionData, isQueryFilterAllNode, resolveQueryFilterGroupId, createQueryFilterGroupId, resolveQueryFilterConditionContextField, createQueryFilterConditionId, QUERY_FILTER_CONDITION_KEY_INFIX, compareMultiLanguageStrings, containsHtmlMarkup, isFormValueEqual, extractTextFromHtml, AXPWidgetsList, coerceUnknownToTrimmedString, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY } from '@acorex-platform/framework-shared/core';
1
+ import { AXPRegionalSetting, resolveActionLook, resolveToSurfaceClass, AXPWidgetsCatalog, createRandomUuid, omitFilterClauseIdentity, coerceFilterDisplayText, AXPPlatformScope, AXPFileStorageStatus, flattenQueryFilterUserGroups, hasQueryFilterGroupId, isCompleteFilterCondition, AXP_QUERY_QUICK_SEARCH_FIELD, wrapQueryFilterRoot, QUERY_FILTER_CHIP_EXPAND_MAX_CONDITIONS, AXPKeyboardShortcutPriority, runtimeQueryCollectionData, isQueryFilterAllNode, resolveQueryFilterGroupId, createQueryFilterGroupId, resolveQueryFilterConditionContextField, createQueryFilterConditionId, QUERY_FILTER_CONDITION_KEY_INFIX, compareMultiLanguageStrings, containsHtmlMarkup, isFormValueEqual, extractTextFromHtml, AXPWidgetsList, coerceUnknownToTrimmedString, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY } from '@acorex-platform/framework-shared/core';
2
2
  import { AXLocaleService } from '@acorex/core/locale';
3
3
  import * as i1$2 from '@acorex/components/button';
4
4
  import { AXButtonModule } from '@acorex/components/button';
@@ -3324,6 +3324,7 @@ class AXPConditionBuilderConditionComponent {
3324
3324
  operator: it?.operator?.type ?? 'equal',
3325
3325
  value: it?.value ?? undefined,
3326
3326
  isParametric: it?.isParametric ?? false,
3327
+ displayText: coerceFilterDisplayText(it?.displayText),
3327
3328
  });
3328
3329
  this.updateFilterWidgetNode();
3329
3330
  this.updateContext();
@@ -3395,10 +3396,18 @@ class AXPConditionBuilderConditionComponent {
3395
3396
  const it = this.item();
3396
3397
  untracked(() => {
3397
3398
  const prev = this.selectedField();
3398
- if (!it ||
3399
- (it.field === prev?.field &&
3400
- it.value === prev?.value &&
3401
- (it.operator?.type ?? 'equal') === (prev?.operator ?? 'equal'))) {
3399
+ if (!it) {
3400
+ return;
3401
+ }
3402
+ const displayText = coerceFilterDisplayText(it.displayText);
3403
+ const sameLeaf = it.field === prev?.field &&
3404
+ sameStoredFilterValue(it.value, prev?.value) &&
3405
+ (it.operator?.type ?? 'equal') === (prev?.operator ?? 'equal');
3406
+ if (sameLeaf && displayText === prev?.displayText) {
3407
+ return;
3408
+ }
3409
+ if (sameLeaf && prev) {
3410
+ this.selectedField.set({ ...prev, displayText });
3402
3411
  return;
3403
3412
  }
3404
3413
  this.selectedField.set({
@@ -3407,6 +3416,7 @@ class AXPConditionBuilderConditionComponent {
3407
3416
  operator: it.operator?.type ?? 'equal',
3408
3417
  value: it.value ?? undefined,
3409
3418
  isParametric: it?.isParametric ?? false,
3419
+ displayText,
3410
3420
  });
3411
3421
  this.updateFilterWidgetNode();
3412
3422
  this.updateContext();
@@ -3476,6 +3486,7 @@ class AXPConditionBuilderConditionComponent {
3476
3486
  field: fieldId,
3477
3487
  operator: filterDef?.operator?.type ?? 'equal',
3478
3488
  value: undefined,
3489
+ displayText: undefined,
3479
3490
  isParametric: prev?.isParametric ?? false,
3480
3491
  }));
3481
3492
  this.updateFilterWidgetNode();
@@ -3489,14 +3500,27 @@ class AXPConditionBuilderConditionComponent {
3489
3500
  if (event.state !== 'changed' || event.origin === 'system' || event.origin === 'hydrate') {
3490
3501
  return;
3491
3502
  }
3492
- const filterData = event.data?.filter;
3493
- if (!filterData)
3503
+ const payload = readFilterWidgetPayload(event.data?.['filter']);
3504
+ if (!payload) {
3494
3505
  return;
3495
- this.selectedField.update((prev) => ({
3496
- ...prev,
3497
- operator: filterData.operation?.type ?? prev?.operator ?? 'equal',
3498
- value: filterData.value,
3499
- }));
3506
+ }
3507
+ this.selectedField.update((prev) => {
3508
+ const sameValue = sameStoredFilterValue(payload.value, prev?.value);
3509
+ const displayText = payload.hasDisplayText
3510
+ ? (payload.displayText ?? (sameValue ? prev?.displayText : undefined))
3511
+ : sameValue
3512
+ ? prev?.displayText
3513
+ : undefined;
3514
+ return {
3515
+ ...prev,
3516
+ id: prev?.id ?? '',
3517
+ field: prev?.field ?? '',
3518
+ operator: payload.operationType ?? prev?.operator ?? 'equal',
3519
+ value: payload.value,
3520
+ isParametric: prev?.isParametric ?? false,
3521
+ displayText,
3522
+ };
3523
+ });
3500
3524
  this.updateContext();
3501
3525
  this.itemChange.emit(this.selectedField());
3502
3526
  }
@@ -3526,8 +3550,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3526
3550
  AXTranslationModule,
3527
3551
  ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"__condition-row\" [class.__condition-row--comfortable]=\"!compact()\">\n <div class=\"__item-content\">\n <!-- Field Selector -->\n <div class=\"__field-selector\">\n <ax-lookup\n mode=\"drop-down-list\"\n [class.ax-sm]=\"compact()\"\n [dataSource]=\"availableFields()\"\n [ngModel]=\"selectedFieldValue()\"\n (onValueChanged)=\"onFieldChange($event)\"\n valueField=\"value\"\n textField=\"text\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.condition.select-field' | translate | async) || 'Select a field'\"\n [look]=\"'outline'\">\n </ax-lookup>\n </div>\n\n <!-- Filter Widget (Operator + Value) -->\n <div class=\"__operator-selector\">\n @if (filterHostKeys().length) {\n <!-- ----- Operator and value for the selected field ----- -->\n @for (hostKey of filterHostKeys(); track hostKey) {\n <axp-widgets-container\n class=\"__filter-widget-container\"\n [context]=\"context()\"\n (onContextChanged)=\"onContextChange($event)\">\n <ng-container axp-widget-renderer [node]=\"filterNode()\" [mode]=\"'edit'\">\n </ng-container>\n </axp-widgets-container>\n }\n }\n <!-- ----- Prompt until a field is chosen ----- -->\n @else {\n <div class=\"__filter-placeholder\">\n <span class=\"__placeholder-text\">{{\n ('@data-management:metadata-definitions.components.query-builder.condition.select-field-first' | translate | async) || 'Select a field first'\n }}</span>\n </div>\n }\n </div>\n\n <!-- Fill By User (optional) -->\n @if (showFillByUser()) {\n <div class=\"__fill-by-user\">\n <ax-check-box\n class=\"text-xs\"\n [ngModel]=\"$safeNavigationMigration(selectedField()?.isParametric)\"\n (ngModelChange)=\"onFillByUserChange($event)\">\n <ax-label>\n {{ '@data-management:metadata-definitions.components.query-builder.condition.fill-by-user' | translate | async }}\n </ax-label>\n </ax-check-box>\n </div>\n }\n </div>\n</div>\n", styles: ["@layer properties;.__condition-row{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.__condition-row .__item-content{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 3);display:grid;grid-template-columns:1fr 1fr;gap:.75rem}.__condition-row .__item-content .__field-selector{min-width:0px}.__condition-row .__item-content .__field-selector ax-lookup{width:100%}.__condition-row .__item-content .__operator-selector{min-width:0px}.__condition-row .__item-content .__operator-selector .__filter-widget-container{width:100%}.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep .axp-widgets-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep ax-lookup{min-width:140px}.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep axp-filter-operations.axp-filter-operations--select{min-width:9rem}.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep ax-text-box,.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep ax-number-box,.__condition-row .__item-content .__operator-selector .__filter-widget-container ::ng-deep ax-date-time-box{flex:1}.__condition-row .__item-content .__operator-selector .__filter-placeholder{display:flex;align-items:center;justify-content:center;border-radius:.25rem;border-style:var(--tw-border-style);--tw-border-style: dashed;border-style:dashed;background-color:var(--color-lightest);color:var(--color-on-lightest);border-color:var(--color-border-lightest);padding:calc(var(--spacing, .25rem) * 3);border-color:rgba(var(--ax-sys-color-border-lighter-surface),1);border-width:1px}.__condition-row .__item-content .__operator-selector .__filter-placeholder .__placeholder-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-500, oklch(55.6% 0 none));font-style:italic}.__condition-row .__item-content .__fill-by-user{grid-column:1 / -1}.__condition-row.__condition-row--comfortable .__field-selector ax-lookup,.__condition-row.__condition-row--comfortable .__filter-placeholder{min-height:var(--ax-sys-size-base, 2.5rem)}.__condition-row.__condition-row--comfortable .__filter-placeholder{justify-content:flex-start;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:0px}.__condition-row.__condition-row--comfortable .__operator-selector ::ng-deep ax-text-box,.__condition-row.__condition-row--comfortable .__operator-selector ::ng-deep ax-number-box,.__condition-row.__condition-row--comfortable .__operator-selector ::ng-deep ax-date-time-box,.__condition-row.__condition-row--comfortable .__operator-selector ::ng-deep ax-lookup,.__condition-row.__condition-row--comfortable .__operator-selector ::ng-deep .ax-editor-container{min-height:var(--ax-sys-size-base, 2.5rem)}@media(max-width:768px){.__condition-row{flex-direction:column;align-items:stretch}.__condition-row .__item-content{grid-template-columns:1fr}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3528
3552
  }], ctorParameters: () => [], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], filterDefinitions: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterDefinitions", required: false }] }], onResolveWidget: [{ type: i0.Input, args: [{ isSignal: true, alias: "onResolveWidget", required: false }] }], showFillByUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFillByUser", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], operationsLook: [{ type: i0.Input, args: [{ isSignal: true, alias: "operationsLook", required: false }] }], itemChange: [{ type: i0.Output, args: ["itemChange"] }], removeItem: [{ type: i0.Output, args: ["removeItem"] }] } });
3529
- //#endregion
3530
- //#region ---- Helpers ----
3553
+ function readFilterWidgetPayload(raw) {
3554
+ if (raw == null) {
3555
+ return undefined;
3556
+ }
3557
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
3558
+ return { value: raw, hasDisplayText: false };
3559
+ }
3560
+ const record = raw;
3561
+ if (!('value' in record) && !('operation' in record) && !('displayText' in record)) {
3562
+ return { value: raw, hasDisplayText: false };
3563
+ }
3564
+ const operation = record['operation'];
3565
+ const operationType = operation && typeof operation === 'object' && !Array.isArray(operation)
3566
+ ? readPayloadText(operation['type'])
3567
+ : undefined;
3568
+ return {
3569
+ value: record['value'],
3570
+ operationType,
3571
+ displayText: coerceFilterDisplayText(record['displayText']),
3572
+ hasDisplayText: 'displayText' in record,
3573
+ };
3574
+ }
3575
+ function readPayloadText(value) {
3576
+ if (typeof value !== 'string') {
3577
+ return undefined;
3578
+ }
3579
+ const trimmed = value.trim();
3580
+ return trimmed || undefined;
3581
+ }
3582
+ function sameStoredFilterValue(left, right) {
3583
+ if (Object.is(left, right)) {
3584
+ return true;
3585
+ }
3586
+ if (left == null || right == null || typeof left !== 'object' || typeof right !== 'object') {
3587
+ return false;
3588
+ }
3589
+ try {
3590
+ return JSON.stringify(left) === JSON.stringify(right);
3591
+ }
3592
+ catch {
3593
+ return false;
3594
+ }
3595
+ }
3531
3596
  function readConditionFieldId(value) {
3532
3597
  if (typeof value === 'string') {
3533
3598
  const trimmed = value.trim();
@@ -3825,13 +3890,18 @@ class AXPConditionBuilderComponent {
3825
3890
  this.queryData.update((data) => {
3826
3891
  const updateFilters = (filters) => filters.map((f) => {
3827
3892
  if (f.id === condition.id) {
3828
- return {
3893
+ const next = {
3829
3894
  ...f,
3830
3895
  field: condition.field,
3831
3896
  operator: { type: condition.operator },
3832
3897
  value: condition.value,
3833
3898
  isParametric: condition.isParametric,
3899
+ displayText: condition.displayText,
3834
3900
  };
3901
+ if (!next.displayText) {
3902
+ delete next.displayText;
3903
+ }
3904
+ return next;
3835
3905
  }
3836
3906
  if (f.filters)
3837
3907
  return { ...f, filters: updateFilters(f.filters) };
@@ -9387,6 +9457,12 @@ class AXPItemConfiguratorComponent {
9387
9457
  /** Values edited in the property viewer (merged from dialog result). */
9388
9458
  this.values = model({}, /* @ts-ignore */
9389
9459
  ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
9460
+ /**
9461
+ * Property-viewer fields whose path is the widget node root (`defaultValue`, `triggers`, …),
9462
+ * not `options.*`. The options bag alone drops them on save.
9463
+ */
9464
+ this.nodeFields = model({}, /* @ts-ignore */
9465
+ ...(ngDevMode ? [{ debugName: "nodeFields" }] : /* istanbul ignore next */ []));
9390
9466
  this.label = input('@general:terms.widget', /* @ts-ignore */
9391
9467
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
9392
9468
  this.readonly = input(false, /* @ts-ignore */
@@ -9563,9 +9639,11 @@ class AXPItemConfiguratorComponent {
9563
9639
  if (tabs.length === 0) {
9564
9640
  return;
9565
9641
  }
9566
- // Property definitions use paths like `options` / `options.*`; viewer context must nest the
9567
- // widget options bag under `options`, not at the root (same as widget-property-viewer).
9642
+ // Property definitions use paths like `options` / `options.*` and also node-root paths
9643
+ // (`defaultValue`, `triggers`). Viewer context must nest the options bag under `options`
9644
+ // and keep those root fields beside it (same as widget-property-viewer).
9568
9645
  const context = buildPropertyViewerInitialContextFromProperties(defs, {
9646
+ ...cloneDeep(this.nodeFields()),
9569
9647
  options: cloneDeep(this.values()),
9570
9648
  });
9571
9649
  const rawTitle = this.currentItemConfig()?.title?.trim() || this.selectedItemId().trim();
@@ -9577,6 +9655,7 @@ class AXPItemConfiguratorComponent {
9577
9655
  params: { name: nameForDialog || '—' },
9578
9656
  })) || `Configure ${nameForDialog || '—'}`;
9579
9657
  const valuesSnapshot = cloneDeep(this.values());
9658
+ const nodeFieldsSnapshot = cloneDeep(this.nodeFields());
9580
9659
  const result = (await this.propertyViewerService
9581
9660
  .create()
9582
9661
  .dialog((d) => {
@@ -9590,17 +9669,16 @@ class AXPItemConfiguratorComponent {
9590
9669
  if (event.mode !== 'update' || !event.values || typeof event.values !== 'object') {
9591
9670
  return;
9592
9671
  }
9593
- const optsPatch = extractOptionsPatchFromPropertyViewerValues(event.values);
9594
- this.values.set(mergeObjectsReplacingArrays(valuesSnapshot, optsPatch));
9672
+ this.applyPropertyViewerValues(valuesSnapshot, event.values);
9595
9673
  });
9596
9674
  })
9597
9675
  .show());
9598
9676
  if (result?.values && typeof result.values === 'object') {
9599
- const optsPatch = extractOptionsPatchFromPropertyViewerValues(result.values);
9600
- this.values.set(mergeObjectsReplacingArrays(valuesSnapshot, optsPatch));
9677
+ this.applyPropertyViewerValues(valuesSnapshot, result.values);
9601
9678
  return;
9602
9679
  }
9603
9680
  this.values.set(cloneDeep(valuesSnapshot));
9681
+ this.nodeFields.set(cloneDeep(nodeFieldsSnapshot));
9604
9682
  }
9605
9683
  onHeaderActionClick(action) {
9606
9684
  if (this.readonly() || this.isHeaderActionDisabled(action)) {
@@ -9617,8 +9695,13 @@ class AXPItemConfiguratorComponent {
9617
9695
  isHeaderActionDisabled(action) {
9618
9696
  return action.disabled === true;
9619
9697
  }
9698
+ applyPropertyViewerValues(optionsSnapshot, viewerValues) {
9699
+ const optsPatch = extractOptionsPatchFromPropertyViewerValues(viewerValues);
9700
+ this.values.set(mergeObjectsReplacingArrays(optionsSnapshot, optsPatch));
9701
+ this.nodeFields.set(extractWidgetNodeFields(viewerValues));
9702
+ }
9620
9703
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPItemConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9621
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPItemConfiguratorComponent, isStandalone: true, selector: "axp-item-configurator", inputs: { selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemId: "selectedItemIdChange", values: "valuesChange" }, viewQueries: [{ propertyName: "itemLookup", first: true, predicate: AXLookupComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Item selector & info container -->\n<div class=\"__item-container\">\n @if (isEditMode()) {\n <div class=\"__item-selector\">\n <ax-lookup\n #itemLookup\n mode=\"drop-down-list\"\n [ngModel]=\"selectedItemId()\"\n [dataSource]=\"itemDataSource\"\n [placeholder]=\"\n ('@general:actions.select.title' | translate | async) ?? ''\n \"\n [readonly]=\"readonly()\"\n (onValueChanged)=\"onSelectionChange($event)\"\n valueField=\"value\"\n textField=\"text\"\n [searchable]=\"true\"\n [itemTemplate]=\"itemTemplate\"\n [loadingTemplate]=\"loadingTemplate\"\n [itemHeight]=\"optionRowHeight\"\n [maxVisibleItems]=\"optionMaxVisibleRows\"\n [selectedTemplate]=\"selectedTemplate\"\n (onClosed)=\"exitEditMode()\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-lookup>\n </div>\n }\n\n @if (!isEditMode()) {\n @if (selectedItemId() && currentItemConfig(); as config) {\n <div class=\"__item-info\">\n <div\n class=\"__item-header\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <div>\n @if (config.icon) {\n <ax-icon [icon]=\"config.icon\"></ax-icon>\n }\n <div>\n <span>\n {{ config.title | translate | async }}\n </span>\n @if (config.description) {\n <p>\n {{ (config.description | translate | async) ?? '' }}\n </p>\n }\n </div>\n </div>\n\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n @if (config.hasProperties) {\n <ax-button\n [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"\n ('@general:actions.configure.title' | translate | async) ?? ''\n \"\n look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\"\n size=\"sm\"\n (onClick)=\"openConfigureDialog()\"\n >\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n @for (\n action of visibleHeaderActions();\n track action.name ?? $index\n ) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [color]=\"action.color ?? 'default'\"\n [disabled]=\"readonly() || isHeaderActionDisabled(action)\"\n [title]=\"(action.title | translate | async) ?? ''\"\n [class.icon-only]=\"action.iconOnly === true\"\n (onClick)=\"onHeaderActionClick(action)\"\n >\n @if (action.icon) {\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n }\n @if (action.iconOnly !== true) {\n <span>{{ (action.title | translate | async) ?? '' }}</span>\n }\n </ax-button>\n }\n </div>\n </div>\n </div>\n } @else {\n <div\n class=\"__item-empty\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{\n ('@general:widgets.widget-configurator.select-widget-type'\n | translate\n | async) ?? 'Select an item type'\n }}\n </span>\n </div>\n }\n }\n\n <ng-template #itemTemplate let-item>\n @let title = (item.title | translate | async) ?? '';\n @let description = (item.description | translate | async) ?? '';\n <div class=\"axp-item-configurator-option\">\n <ax-icon [icon]=\"item.icon || fallbackIcon\"></ax-icon>\n <div class=\"axp-item-configurator-option__text\">\n <span class=\"axp-item-configurator-option__title\">\n {{ title }}\n </span>\n <!-- ----- One-line description under the title ----- -->\n @if (item.description) {\n <span class=\"axp-item-configurator-option__description\">\n {{ description }}\n </span>\n }\n </div>\n </div>\n </ng-template>\n\n <ng-template #loadingTemplate>\n <div class=\"axp-item-configurator-option axp-item-configurator-option--loading\">\n <span class=\"axp-item-configurator-option__icon-slot\"></span>\n <span class=\"axp-item-configurator-option__bar\"></span>\n </div>\n </ng-template>\n\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.icon) {\n <ax-icon [icon]=\"item.icon\"></ax-icon>\n }\n <span>\n {{ (item?.title | translate | async) ?? '' }}\n </span>\n </div>\n </ng-template>\n</div>\n", styles: ["@layer properties;axp-item-configurator{display:flex;flex-direction:column}axp-item-configurator .__item-selector{display:flex;flex-direction:column}axp-item-configurator .__item-selector ax-lookup{width:100%}axp-item-configurator .__item-info{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}axp-item-configurator .__item-info .__item-header{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1.5)}axp-item-configurator .__item-info .__item-header.__editable{cursor:pointer}axp-item-configurator .__item-info .__item-header.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-info .__item-header:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-info .__item-header>div:first-child{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-info .__item-header>div:first-child ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));flex-shrink:0}axp-item-configurator .__item-info .__item-header>div:first-child>div{display:flex;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}axp-item-configurator .__item-info .__item-header>div:first-child>div>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-item-configurator .__item-info .__item-header>div:first-child>div>p{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__item-info .__action-buttons{display:flex;align-items:center;gap:var(--spacing, .25rem);flex-shrink:0}axp-item-configurator .__item-empty{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-empty.__editable{cursor:pointer}axp-item-configurator .__item-empty.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-empty:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-empty>i{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-neutral-400, oklch(70.8% 0 none))}axp-item-configurator .__item-empty>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__selected-template{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__selected-template>ax-icon{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axp-item-configurator .__selected-template>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}axp-item-configurator :host([readonly]){pointer-events:none;opacity:.7}.ax-lookup-viewport:has(.axp-item-configurator-option){min-height:224px;overflow-y:scroll;scrollbar-gutter:stable}.ax-lookup-option-host:has(.axp-item-configurator-option){overflow:hidden}.axp-item-configurator-option{box-sizing:border-box;display:flex;align-items:center;gap:.625rem;width:100%;height:100%;min-width:0;overflow:hidden;padding-inline:.75rem}.axp-item-configurator-option>ax-icon{flex-shrink:0;width:1.125rem;font-size:1rem;line-height:1;text-align:center}.axp-item-configurator-option__text{display:flex;min-width:0;flex:1;flex-direction:column;justify-content:center;gap:.125rem;line-height:1.25}.axp-item-configurator-option__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;font-weight:500;line-height:1.25}.axp-item-configurator-option__description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-neutral-600, oklch(43.9% 0 none));font-size:.75rem;line-height:1.25}.axp-item-configurator-option--loading{gap:.5rem}.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{display:block;border-radius:.25rem;background:currentColor}@supports (color: color-mix(in lab,red,red)){.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{background:color-mix(in srgb,currentColor 12%,transparent)}}.axp-item-configurator-option__icon-slot{width:1rem;height:1rem;flex-shrink:0}.axp-item-configurator-option__bar{height:.5rem;width:40%}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXLookupComponent, selector: "ax-lookup", inputs: ["name", "mode", "dataSource", "treeDataSource", "valueField", "textField", "disabledField", "columns", "treeParentField", "hasChildrenField", "searchable", "adaptivityEnabled", "caption", "alternate", "searchPlaceholder", "placeholder", "disabled", "readonly", "look", "itemHeight", "maxVisibleItems", "treeSelectionBehavior", "highlightSearch", "allowSelectAll", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "value", "valueItems", "prefetch"], outputs: ["lookChange", "valueChange", "onValueChanged", "onSelectionChanged", "onFocus", "onBlur", "onItemClick", "onItemSelected", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
9704
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPItemConfiguratorComponent, isStandalone: true, selector: "axp-item-configurator", inputs: { selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, nodeFields: { classPropertyName: "nodeFields", publicName: "nodeFields", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemId: "selectedItemIdChange", values: "valuesChange", nodeFields: "nodeFieldsChange" }, viewQueries: [{ propertyName: "itemLookup", first: true, predicate: AXLookupComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Item selector & info container -->\n<div class=\"__item-container\">\n @if (isEditMode()) {\n <div class=\"__item-selector\">\n <ax-lookup\n #itemLookup\n mode=\"drop-down-list\"\n [ngModel]=\"selectedItemId()\"\n [dataSource]=\"itemDataSource\"\n [placeholder]=\"\n ('@general:actions.select.title' | translate | async) ?? ''\n \"\n [readonly]=\"readonly()\"\n (onValueChanged)=\"onSelectionChange($event)\"\n valueField=\"value\"\n textField=\"text\"\n [searchable]=\"true\"\n [itemTemplate]=\"itemTemplate\"\n [loadingTemplate]=\"loadingTemplate\"\n [itemHeight]=\"optionRowHeight\"\n [maxVisibleItems]=\"optionMaxVisibleRows\"\n [selectedTemplate]=\"selectedTemplate\"\n (onClosed)=\"exitEditMode()\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-lookup>\n </div>\n }\n\n @if (!isEditMode()) {\n @if (selectedItemId() && currentItemConfig(); as config) {\n <div class=\"__item-info\">\n <div\n class=\"__item-header\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <div>\n @if (config.icon) {\n <ax-icon [icon]=\"config.icon\"></ax-icon>\n }\n <div>\n <span>\n {{ config.title | translate | async }}\n </span>\n @if (config.description) {\n <p>\n {{ (config.description | translate | async) ?? '' }}\n </p>\n }\n </div>\n </div>\n\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n @if (config.hasProperties) {\n <ax-button\n [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"\n ('@general:actions.configure.title' | translate | async) ?? ''\n \"\n look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\"\n size=\"sm\"\n (onClick)=\"openConfigureDialog()\"\n >\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n @for (\n action of visibleHeaderActions();\n track action.name ?? $index\n ) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [color]=\"action.color ?? 'default'\"\n [disabled]=\"readonly() || isHeaderActionDisabled(action)\"\n [title]=\"(action.title | translate | async) ?? ''\"\n [class.icon-only]=\"action.iconOnly === true\"\n (onClick)=\"onHeaderActionClick(action)\"\n >\n @if (action.icon) {\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n }\n @if (action.iconOnly !== true) {\n <span>{{ (action.title | translate | async) ?? '' }}</span>\n }\n </ax-button>\n }\n </div>\n </div>\n </div>\n } @else {\n <div\n class=\"__item-empty\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{\n ('@general:widgets.widget-configurator.select-widget-type'\n | translate\n | async) ?? 'Select an item type'\n }}\n </span>\n </div>\n }\n }\n\n <ng-template #itemTemplate let-item>\n @let title = (item.title | translate | async) ?? '';\n @let description = (item.description | translate | async) ?? '';\n <div class=\"axp-item-configurator-option\">\n <ax-icon [icon]=\"item.icon || fallbackIcon\"></ax-icon>\n <div class=\"axp-item-configurator-option__text\">\n <span class=\"axp-item-configurator-option__title\">\n {{ title }}\n </span>\n <!-- ----- One-line description under the title ----- -->\n @if (item.description) {\n <span class=\"axp-item-configurator-option__description\">\n {{ description }}\n </span>\n }\n </div>\n </div>\n </ng-template>\n\n <ng-template #loadingTemplate>\n <div class=\"axp-item-configurator-option axp-item-configurator-option--loading\">\n <span class=\"axp-item-configurator-option__icon-slot\"></span>\n <span class=\"axp-item-configurator-option__bar\"></span>\n </div>\n </ng-template>\n\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.icon) {\n <ax-icon [icon]=\"item.icon\"></ax-icon>\n }\n <span>\n {{ (item?.title | translate | async) ?? '' }}\n </span>\n </div>\n </ng-template>\n</div>\n", styles: ["@layer properties;axp-item-configurator{display:flex;flex-direction:column}axp-item-configurator .__item-selector{display:flex;flex-direction:column}axp-item-configurator .__item-selector ax-lookup{width:100%}axp-item-configurator .__item-info{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}axp-item-configurator .__item-info .__item-header{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1.5)}axp-item-configurator .__item-info .__item-header.__editable{cursor:pointer}axp-item-configurator .__item-info .__item-header.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-info .__item-header:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-info .__item-header>div:first-child{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-info .__item-header>div:first-child ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));flex-shrink:0}axp-item-configurator .__item-info .__item-header>div:first-child>div{display:flex;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}axp-item-configurator .__item-info .__item-header>div:first-child>div>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-item-configurator .__item-info .__item-header>div:first-child>div>p{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__item-info .__action-buttons{display:flex;align-items:center;gap:var(--spacing, .25rem);flex-shrink:0}axp-item-configurator .__item-empty{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-empty.__editable{cursor:pointer}axp-item-configurator .__item-empty.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-empty:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-empty>i{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-neutral-400, oklch(70.8% 0 none))}axp-item-configurator .__item-empty>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__selected-template{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__selected-template>ax-icon{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axp-item-configurator .__selected-template>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}axp-item-configurator :host([readonly]){pointer-events:none;opacity:.7}.ax-lookup-viewport:has(.axp-item-configurator-option){min-height:224px;overflow-y:scroll;scrollbar-gutter:stable}.ax-lookup-option-host:has(.axp-item-configurator-option){overflow:hidden}.axp-item-configurator-option{box-sizing:border-box;display:flex;align-items:center;gap:.625rem;width:100%;height:100%;min-width:0;overflow:hidden;padding-inline:.75rem}.axp-item-configurator-option>ax-icon{flex-shrink:0;width:1.125rem;font-size:1rem;line-height:1;text-align:center}.axp-item-configurator-option__text{display:flex;min-width:0;flex:1;flex-direction:column;justify-content:center;gap:.125rem;line-height:1.25}.axp-item-configurator-option__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;font-weight:500;line-height:1.25}.axp-item-configurator-option__description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-neutral-600, oklch(43.9% 0 none));font-size:.75rem;line-height:1.25}.axp-item-configurator-option--loading{gap:.5rem}.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{display:block;border-radius:.25rem;background:currentColor}@supports (color: color-mix(in lab,red,red)){.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{background:color-mix(in srgb,currentColor 12%,transparent)}}.axp-item-configurator-option__icon-slot{width:1rem;height:1rem;flex-shrink:0}.axp-item-configurator-option__bar{height:.5rem;width:40%}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXLookupComponent, selector: "ax-lookup", inputs: ["name", "mode", "dataSource", "treeDataSource", "valueField", "textField", "disabledField", "columns", "treeParentField", "hasChildrenField", "searchable", "adaptivityEnabled", "caption", "alternate", "searchPlaceholder", "placeholder", "disabled", "readonly", "look", "itemHeight", "maxVisibleItems", "treeSelectionBehavior", "highlightSearch", "allowSelectAll", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "value", "valueItems", "prefetch"], outputs: ["lookChange", "valueChange", "onValueChanged", "onSelectionChanged", "onFocus", "onBlur", "onItemClick", "onItemSelected", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
9622
9705
  }
9623
9706
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPItemConfiguratorComponent, decorators: [{
9624
9707
  type: Component,
@@ -9631,7 +9714,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9631
9714
  AXDecoratorModule,
9632
9715
  AXTranslationModule,
9633
9716
  ], template: "<!-- Item selector & info container -->\n<div class=\"__item-container\">\n @if (isEditMode()) {\n <div class=\"__item-selector\">\n <ax-lookup\n #itemLookup\n mode=\"drop-down-list\"\n [ngModel]=\"selectedItemId()\"\n [dataSource]=\"itemDataSource\"\n [placeholder]=\"\n ('@general:actions.select.title' | translate | async) ?? ''\n \"\n [readonly]=\"readonly()\"\n (onValueChanged)=\"onSelectionChange($event)\"\n valueField=\"value\"\n textField=\"text\"\n [searchable]=\"true\"\n [itemTemplate]=\"itemTemplate\"\n [loadingTemplate]=\"loadingTemplate\"\n [itemHeight]=\"optionRowHeight\"\n [maxVisibleItems]=\"optionMaxVisibleRows\"\n [selectedTemplate]=\"selectedTemplate\"\n (onClosed)=\"exitEditMode()\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-lookup>\n </div>\n }\n\n @if (!isEditMode()) {\n @if (selectedItemId() && currentItemConfig(); as config) {\n <div class=\"__item-info\">\n <div\n class=\"__item-header\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <div>\n @if (config.icon) {\n <ax-icon [icon]=\"config.icon\"></ax-icon>\n }\n <div>\n <span>\n {{ config.title | translate | async }}\n </span>\n @if (config.description) {\n <p>\n {{ (config.description | translate | async) ?? '' }}\n </p>\n }\n </div>\n </div>\n\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n @if (config.hasProperties) {\n <ax-button\n [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"\n ('@general:actions.configure.title' | translate | async) ?? ''\n \"\n look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\"\n size=\"sm\"\n (onClick)=\"openConfigureDialog()\"\n >\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n @for (\n action of visibleHeaderActions();\n track action.name ?? $index\n ) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [color]=\"action.color ?? 'default'\"\n [disabled]=\"readonly() || isHeaderActionDisabled(action)\"\n [title]=\"(action.title | translate | async) ?? ''\"\n [class.icon-only]=\"action.iconOnly === true\"\n (onClick)=\"onHeaderActionClick(action)\"\n >\n @if (action.icon) {\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n }\n @if (action.iconOnly !== true) {\n <span>{{ (action.title | translate | async) ?? '' }}</span>\n }\n </ax-button>\n }\n </div>\n </div>\n </div>\n } @else {\n <div\n class=\"__item-empty\"\n [class.__editable]=\"!readonly()\"\n (click)=\"enterEditMode()\"\n >\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{\n ('@general:widgets.widget-configurator.select-widget-type'\n | translate\n | async) ?? 'Select an item type'\n }}\n </span>\n </div>\n }\n }\n\n <ng-template #itemTemplate let-item>\n @let title = (item.title | translate | async) ?? '';\n @let description = (item.description | translate | async) ?? '';\n <div class=\"axp-item-configurator-option\">\n <ax-icon [icon]=\"item.icon || fallbackIcon\"></ax-icon>\n <div class=\"axp-item-configurator-option__text\">\n <span class=\"axp-item-configurator-option__title\">\n {{ title }}\n </span>\n <!-- ----- One-line description under the title ----- -->\n @if (item.description) {\n <span class=\"axp-item-configurator-option__description\">\n {{ description }}\n </span>\n }\n </div>\n </div>\n </ng-template>\n\n <ng-template #loadingTemplate>\n <div class=\"axp-item-configurator-option axp-item-configurator-option--loading\">\n <span class=\"axp-item-configurator-option__icon-slot\"></span>\n <span class=\"axp-item-configurator-option__bar\"></span>\n </div>\n </ng-template>\n\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.icon) {\n <ax-icon [icon]=\"item.icon\"></ax-icon>\n }\n <span>\n {{ (item?.title | translate | async) ?? '' }}\n </span>\n </div>\n </ng-template>\n</div>\n", styles: ["@layer properties;axp-item-configurator{display:flex;flex-direction:column}axp-item-configurator .__item-selector{display:flex;flex-direction:column}axp-item-configurator .__item-selector ax-lookup{width:100%}axp-item-configurator .__item-info{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}axp-item-configurator .__item-info .__item-header{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1.5)}axp-item-configurator .__item-info .__item-header.__editable{cursor:pointer}axp-item-configurator .__item-info .__item-header.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-info .__item-header:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-info .__item-header>div:first-child{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-info .__item-header>div:first-child ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));flex-shrink:0}axp-item-configurator .__item-info .__item-header>div:first-child>div{display:flex;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}axp-item-configurator .__item-info .__item-header>div:first-child>div>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-item-configurator .__item-info .__item-header>div:first-child>div>p{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25);color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__item-info .__action-buttons{display:flex;align-items:center;gap:var(--spacing, .25rem);flex-shrink:0}axp-item-configurator .__item-empty{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__item-empty.__editable{cursor:pointer}axp-item-configurator .__item-empty.__editable:hover{border-radius:var(--radius-md, .375rem);background-color:rgba(var(--ax-sys-color-lighter-surface))}axp-item-configurator .__item-empty:not(.__editable){cursor:not-allowed}axp-item-configurator .__item-empty>i{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-neutral-400, oklch(70.8% 0 none))}axp-item-configurator .__item-empty>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}axp-item-configurator .__selected-template{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}axp-item-configurator .__selected-template>ax-icon{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axp-item-configurator .__selected-template>span{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}axp-item-configurator :host([readonly]){pointer-events:none;opacity:.7}.ax-lookup-viewport:has(.axp-item-configurator-option){min-height:224px;overflow-y:scroll;scrollbar-gutter:stable}.ax-lookup-option-host:has(.axp-item-configurator-option){overflow:hidden}.axp-item-configurator-option{box-sizing:border-box;display:flex;align-items:center;gap:.625rem;width:100%;height:100%;min-width:0;overflow:hidden;padding-inline:.75rem}.axp-item-configurator-option>ax-icon{flex-shrink:0;width:1.125rem;font-size:1rem;line-height:1;text-align:center}.axp-item-configurator-option__text{display:flex;min-width:0;flex:1;flex-direction:column;justify-content:center;gap:.125rem;line-height:1.25}.axp-item-configurator-option__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;font-weight:500;line-height:1.25}.axp-item-configurator-option__description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-neutral-600, oklch(43.9% 0 none));font-size:.75rem;line-height:1.25}.axp-item-configurator-option--loading{gap:.5rem}.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{display:block;border-radius:.25rem;background:currentColor}@supports (color: color-mix(in lab,red,red)){.axp-item-configurator-option__icon-slot,.axp-item-configurator-option__bar{background:color-mix(in srgb,currentColor 12%,transparent)}}.axp-item-configurator-option__icon-slot{width:1rem;height:1rem;flex-shrink:0}.axp-item-configurator-option__bar{height:.5rem;width:40%}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
9634
- }], ctorParameters: () => [], propDecorators: { selectedItemId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemId", required: false }] }, { type: i0.Output, args: ["selectedItemIdChange"] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }, { type: i0.Output, args: ["valuesChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], headerActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerActions", required: false }] }], itemLookup: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXLookupComponent), { isSignal: true }] }] } });
9717
+ }], ctorParameters: () => [], propDecorators: { selectedItemId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemId", required: false }] }, { type: i0.Output, args: ["selectedItemIdChange"] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }, { type: i0.Output, args: ["valuesChange"] }], nodeFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeFields", required: false }] }, { type: i0.Output, args: ["nodeFieldsChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], headerActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerActions", required: false }] }], itemLookup: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXLookupComponent), { isSignal: true }] }] } });
9635
9718
  //#region ---- Helpers ----
9636
9719
  function isPropertyDefinitionArray(value) {
9637
9720
  if (!Array.isArray(value) || value.length === 0) {
@@ -9651,6 +9734,17 @@ function extractOptionsPatchFromPropertyViewerValues(values) {
9651
9734
  }
9652
9735
  return values;
9653
9736
  }
9737
+ /** Widget-node fields configured beside `options` (path is the node root, not `options.*`). */
9738
+ const WIDGET_NODE_FIELD_KEYS$1 = ['defaultValue', 'triggers', 'name', 'path', 'visible', 'mode', 'meta', 'valueTransforms'];
9739
+ function extractWidgetNodeFields(values) {
9740
+ const out = {};
9741
+ for (const key of WIDGET_NODE_FIELD_KEYS$1) {
9742
+ if (key in values) {
9743
+ out[key] = values[key];
9744
+ }
9745
+ }
9746
+ return out;
9747
+ }
9654
9748
  function readLookupFilterText(filter) {
9655
9749
  if (!filter || typeof filter !== 'object') {
9656
9750
  return '';
@@ -16647,6 +16741,9 @@ class AXPWidgetFieldConfiguratorComponent {
16647
16741
  ...(ngDevMode ? [{ debugName: "selectedItemIdModel" }] : /* istanbul ignore next */ []));
16648
16742
  this.valuesModel = model({}, /* @ts-ignore */
16649
16743
  ...(ngDevMode ? [{ debugName: "valuesModel" }] : /* istanbul ignore next */ []));
16744
+ /** Node-root fields (`defaultValue`, `triggers`, …) kept beside `options`. */
16745
+ this.nodeFieldsModel = model({}, /* @ts-ignore */
16746
+ ...(ngDevMode ? [{ debugName: "nodeFieldsModel" }] : /* istanbul ignore next */ []));
16650
16747
  /**
16651
16748
  * List entries from {@link AXPWidgetRegistryService} (form editors), with
16652
16749
  * {@link ItemConfiguratorListItem.propertyDefinitions} from each registered config.
@@ -16696,18 +16793,22 @@ class AXPWidgetFieldConfiguratorComponent {
16696
16793
  const w = this.widget();
16697
16794
  const sid = w?.type ?? '';
16698
16795
  const opts = (w?.options ?? {});
16796
+ const nodeFields = readWidgetNodeFields(w);
16699
16797
  const curSid = untracked(() => this.selectedItemIdModel());
16700
16798
  const curVals = untracked(() => this.valuesModel());
16701
- if (sid !== curSid || !isEqual(opts, curVals)) {
16799
+ const curNodeFields = untracked(() => this.nodeFieldsModel());
16800
+ if (sid !== curSid || !isEqual(opts, curVals) || !isEqual(nodeFields, curNodeFields)) {
16702
16801
  untracked(() => {
16703
16802
  this.selectedItemIdModel.set(sid);
16704
16803
  this.valuesModel.set(opts);
16804
+ this.nodeFieldsModel.set(nodeFields);
16705
16805
  });
16706
16806
  }
16707
16807
  });
16708
16808
  effect(() => {
16709
16809
  const sid = this.selectedItemIdModel();
16710
16810
  const vals = this.valuesModel();
16811
+ const nodeFields = this.nodeFieldsModel();
16711
16812
  const current = untracked(() => this.widget());
16712
16813
  const empty = { type: '', options: {} };
16713
16814
  if (!sid) {
@@ -16716,27 +16817,28 @@ class AXPWidgetFieldConfiguratorComponent {
16716
16817
  }
16717
16818
  return;
16718
16819
  }
16719
- const next = {
16820
+ const next = applyWidgetNodeFields({
16720
16821
  ...(current && typeof current === 'object' ? current : {}),
16721
16822
  type: sid,
16722
16823
  options: vals,
16723
- };
16824
+ }, nodeFields);
16724
16825
  if (!isEqual(next, current)) {
16725
16826
  untracked(() => this.widget.set(next));
16726
16827
  }
16727
16828
  });
16728
16829
  }
16729
16830
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPWidgetFieldConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16730
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPWidgetFieldConfiguratorComponent, isStandalone: true, selector: "axp-widget-field-configurator", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, fieldName: { classPropertyName: "fieldName", publicName: "fieldName", isSignal: true, isRequired: false, transformFunction: null }, fieldTitle: { classPropertyName: "fieldTitle", publicName: "fieldTitle", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, selectedItemIdModel: { classPropertyName: "selectedItemIdModel", publicName: "selectedItemIdModel", isSignal: true, isRequired: false, transformFunction: null }, valuesModel: { classPropertyName: "valuesModel", publicName: "valuesModel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { widget: "widgetChange", selectedItemIdModel: "selectedItemIdModelChange", valuesModel: "valuesModelChange" }, host: { properties: { "attr.readonly": "readonly() ? \"\" : null" }, classAttribute: "flex flex-col" }, ngImport: i0, template: `
16831
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPWidgetFieldConfiguratorComponent, isStandalone: true, selector: "axp-widget-field-configurator", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, fieldName: { classPropertyName: "fieldName", publicName: "fieldName", isSignal: true, isRequired: false, transformFunction: null }, fieldTitle: { classPropertyName: "fieldTitle", publicName: "fieldTitle", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, selectedItemIdModel: { classPropertyName: "selectedItemIdModel", publicName: "selectedItemIdModel", isSignal: true, isRequired: false, transformFunction: null }, valuesModel: { classPropertyName: "valuesModel", publicName: "valuesModel", isSignal: true, isRequired: false, transformFunction: null }, nodeFieldsModel: { classPropertyName: "nodeFieldsModel", publicName: "nodeFieldsModel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { widget: "widgetChange", selectedItemIdModel: "selectedItemIdModelChange", valuesModel: "valuesModelChange", nodeFieldsModel: "nodeFieldsModelChange" }, host: { properties: { "attr.readonly": "readonly() ? \"\" : null" }, classAttribute: "flex flex-col" }, ngImport: i0, template: `
16731
16832
  <axp-item-configurator
16732
16833
  [(selectedItemId)]="selectedItemIdModel"
16733
16834
  [(values)]="valuesModel"
16835
+ [(nodeFields)]="nodeFieldsModel"
16734
16836
  [label]="label()"
16735
16837
  [readonly]="readonly()"
16736
16838
  [items]="configuratorItems()"
16737
16839
  [headerActions]="previewHeaderActions()"
16738
16840
  />
16739
- `, isInline: true, styles: [":host([readonly]){pointer-events:none;opacity:.7}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPItemConfiguratorComponent, selector: "axp-item-configurator", inputs: ["selectedItemId", "values", "label", "readonly", "items", "headerActions"], outputs: ["selectedItemIdChange", "valuesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
16841
+ `, isInline: true, styles: [":host([readonly]){pointer-events:none;opacity:.7}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPItemConfiguratorComponent, selector: "axp-item-configurator", inputs: ["selectedItemId", "values", "nodeFields", "label", "readonly", "items", "headerActions"], outputs: ["selectedItemIdChange", "valuesChange", "nodeFieldsChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
16740
16842
  }
16741
16843
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPWidgetFieldConfiguratorComponent, decorators: [{
16742
16844
  type: Component,
@@ -16744,6 +16846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16744
16846
  <axp-item-configurator
16745
16847
  [(selectedItemId)]="selectedItemIdModel"
16746
16848
  [(values)]="valuesModel"
16849
+ [(nodeFields)]="nodeFieldsModel"
16747
16850
  [label]="label()"
16748
16851
  [readonly]="readonly()"
16749
16852
  [items]="configuratorItems()"
@@ -16753,7 +16856,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16753
16856
  class: 'flex flex-col',
16754
16857
  '[attr.readonly]': 'readonly() ? "" : null',
16755
16858
  }, imports: [AXPItemConfiguratorComponent], styles: [":host([readonly]){pointer-events:none;opacity:.7}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
16756
- }], ctorParameters: () => [], propDecorators: { widget: [{ type: i0.Input, args: [{ isSignal: true, alias: "widget", required: false }] }, { type: i0.Output, args: ["widgetChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldName", required: false }] }], fieldTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldTitle", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], selectedItemIdModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemIdModel", required: false }] }, { type: i0.Output, args: ["selectedItemIdModelChange"] }], valuesModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valuesModel", required: false }] }, { type: i0.Output, args: ["valuesModelChange"] }] } });
16859
+ }], ctorParameters: () => [], propDecorators: { widget: [{ type: i0.Input, args: [{ isSignal: true, alias: "widget", required: false }] }, { type: i0.Output, args: ["widgetChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldName", required: false }] }], fieldTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldTitle", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], selectedItemIdModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemIdModel", required: false }] }, { type: i0.Output, args: ["selectedItemIdModelChange"] }], valuesModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valuesModel", required: false }] }, { type: i0.Output, args: ["valuesModelChange"] }], nodeFieldsModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeFieldsModel", required: false }] }, { type: i0.Output, args: ["nodeFieldsModelChange"] }] } });
16860
+ //#endregion
16861
+ //#region ---- Node-root fields ----
16862
+ const WIDGET_NODE_FIELD_KEYS = ['defaultValue', 'triggers', 'name', 'path', 'visible', 'mode', 'meta', 'valueTransforms'];
16863
+ function readWidgetNodeFields(widget) {
16864
+ const out = {};
16865
+ if (!widget) {
16866
+ return out;
16867
+ }
16868
+ for (const key of WIDGET_NODE_FIELD_KEYS) {
16869
+ const value = widget[key];
16870
+ if (value !== undefined) {
16871
+ out[key] = value;
16872
+ }
16873
+ }
16874
+ return out;
16875
+ }
16876
+ function applyWidgetNodeFields(widget, fields) {
16877
+ const next = { ...widget };
16878
+ for (const key of WIDGET_NODE_FIELD_KEYS) {
16879
+ if (!(key in fields)) {
16880
+ continue;
16881
+ }
16882
+ const value = fields[key];
16883
+ const cleared = value === undefined || value === null || (key === 'defaultValue' && value === '');
16884
+ if (cleared) {
16885
+ delete next[key];
16886
+ continue;
16887
+ }
16888
+ assignWidgetNodeField(next, key, value);
16889
+ }
16890
+ return next;
16891
+ }
16892
+ function assignWidgetNodeField(widget, key, value) {
16893
+ switch (key) {
16894
+ case 'defaultValue':
16895
+ widget.defaultValue = value;
16896
+ break;
16897
+ case 'triggers':
16898
+ widget.triggers = value;
16899
+ break;
16900
+ case 'name':
16901
+ widget.name = value;
16902
+ break;
16903
+ case 'path':
16904
+ widget.path = value;
16905
+ break;
16906
+ case 'visible':
16907
+ widget.visible = value;
16908
+ break;
16909
+ case 'mode':
16910
+ widget.mode = value;
16911
+ break;
16912
+ case 'meta':
16913
+ widget.meta = value;
16914
+ break;
16915
+ case 'valueTransforms':
16916
+ widget.valueTransforms = value;
16917
+ break;
16918
+ }
16919
+ }
16757
16920
 
16758
16921
  const WIDGET_ITEM_I18N = {
16759
16922
  pin: '@general:widgets.widget-item.pin',