@acorex-platform/framework-client 2.0.0-next.26 → 2.0.0-next.29

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 (48) hide show
  1. package/fesm2022/acorex-platform-framework-client-auth.mjs +8 -9
  2. package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-framework-client-common.mjs +558 -106
  4. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  5. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BTLgOdQN.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs} +13 -11
  6. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs.map +1 -0
  7. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DH2Wq7ux.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs} +2 -2
  8. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DH2Wq7ux.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-DMgR7yq0.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-DMgR7yq0.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-DLt5p2Iy.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-DLt5p2Iy.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs.map} +1 -1
  13. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-C_JIijQZ.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-C_JIijQZ.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs.map} +1 -1
  15. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  16. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +24 -8
  17. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  18. package/fesm2022/{acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DRh91YCL.mjs → acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CpmGqDUE.mjs} +893 -153
  19. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CpmGqDUE.mjs.map +1 -0
  20. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-Ddx_b04d.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-XgjDH9Oc.mjs} +2 -2
  21. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-Ddx_b04d.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-XgjDH9Oc.mjs.map} +1 -1
  22. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DqIuIn76.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DDczHmAA.mjs} +2 -2
  23. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DqIuIn76.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DDczHmAA.mjs.map} +1 -1
  24. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -1
  25. package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs → acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs} +5 -11
  26. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs.map +1 -0
  27. package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs → acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs} +5 -11
  28. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs → acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs} +15 -4
  30. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs +19 -0
  32. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +15 -6
  34. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  35. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +10 -4
  36. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  37. package/i18n/en-AU/platform-layout-widgets.json +7 -1
  38. package/i18n/en-US/platform-layout-widgets.json +7 -1
  39. package/i18n/fa-IR/platform-layout-widgets.json +7 -1
  40. package/package.json +2 -2
  41. package/types/acorex-platform-framework-client-auth.d.ts +21 -11
  42. package/types/acorex-platform-framework-client-common.d.ts +122 -7
  43. package/types/acorex-platform-framework-client-layout-widgets.d.ts +111 -8
  44. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BTLgOdQN.mjs.map +0 -1
  45. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DRh91YCL.mjs.map +0 -1
  46. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs.map +0 -1
  47. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs.map +0 -1
  48. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs.map +0 -1
@@ -20,7 +20,7 @@ import * as i1$8 from '@acorex/components/text-box';
20
20
  import { AXTextBoxModule } from '@acorex/components/text-box';
21
21
  import * as i1$6 from '@acorex/core/translation';
22
22
  import { AXTranslationModule, AXTranslationService, resolveMultiLanguageString as resolveMultiLanguageString$1 } from '@acorex/core/translation';
23
- import { AXP_LOCALE_MANAGEMENT_PORT, AXPFilterOperatorMiddlewareService, AXPCleanNestedFilters, ALL_DEFAULT_OPERATORS, AXPSettingsService, AXPClipBoardService, DATE_OPERATORS, BOOLEAN_OPERATORS, NUMBER_OPERATORS, STRING_OPERATORS, AXPFilterDefaultOperatorService, resolveDateFilterPresets, findManualPresetIdByOperation, applyDateFilterPreset, isPendingCascadeFilter, AXPFileStorageService, resolveStoredImageDisplayUrl, AXP_INTEGRATION_RUNTIME_PROVIDER, commandMessageTextForError, normalizePositiveNumberOption, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle, downloadGraphicFromElement, printGraphicFromElement, AXPStatusDefinitionProviderService, isStoredImageFileId, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, AXPCommonSettings, AXP_FILTER_DEFAULT_OPERATORS_WIDGET_NAME } from '@acorex-platform/framework-client/common';
23
+ import { AXP_LOCALE_MANAGEMENT_PORT, AXPFilterOperatorMiddlewareService, AXPCleanNestedFilters, ALL_DEFAULT_OPERATORS, AXPSettingsService, AXPClipBoardService, DATE_OPERATORS, BOOLEAN_OPERATORS, NUMBER_OPERATORS, STRING_OPERATORS, AXPFilterDefaultOperatorService, resolveDateFilterPresets, findManualPresetIdByOperation, applyDateFilterPreset, isPendingCascadeFilter, AXPFileStorageService, resolveStoredImageDisplayUrl, AXP_INTEGRATION_RUNTIME_PROVIDER, commandMessageTextForError, normalizePositiveNumberOption, resolveEntityRowDisplayText, isStoredImageFileId, normalizeStoredImageRef, resolveEntityRowDisplayTitle, downloadGraphicFromElement, triggerBrowserDownload, printGraphicFromElement, AXPStatusDefinitionProviderService, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, AXPCommonSettings, AXP_FILTER_DEFAULT_OPERATORS_WIDGET_NAME } from '@acorex-platform/framework-client/common';
24
24
  import { AXPDeviceService, setupPopupFooterKeyboardShortcuts, ensureRuntimeSurfaceClass, AXPColorPaletteService, AXPDebugService, FORM_DIRTY_TRACE_NS, applyFilterArray, AXPTagService, AXPExpressionEvaluatorService, AXPHookService, AXPDataGenerator, AXPLogoComponent, AXPEntityBroadcastService, applyQueryArray, chordToKbdItemKeys, objectKeyValueTransforms } from '@acorex-platform/framework-client/core';
25
25
  import * as i1$5 from '@angular/common';
26
26
  import { CommonModule, AsyncPipe, NgTemplateOutlet } from '@angular/common';
@@ -30,7 +30,7 @@ import * as i1$7 from '@angular/forms';
30
30
  import { FormsModule } from '@angular/forms';
31
31
  import { AXLookupComponent } from '@acorex/components/lookup';
32
32
  import { AXFormatService } from '@acorex/core/format';
33
- import { resolveMultiLanguageString, setSmart, coerceFilterDisplayText, AXPRegionalSetting, omitFilterClauseIdentity, createRandomUuid, themeSurfaceVariantFromClass, toRuntimeSurfaceClassName, resolveToSurfaceClass, parseRuntimeHexSurface, listThemeSurfaceGroups, normalizeHexColor, extractValue, filterOperatorAllowsEmptyValue, shouldUseLocaleMapShape, buildLocaleTextMapValue, isFormValueEqual, runtimeQueryPayloadData, runtimeQueryCollectionData, isSelectionValueEqual, isLocaleStringMap, AXPWidgetsCatalog, AXP_INTEGRATION_CONNECTION_STATUS, AXP_INTEGRATION_AUTH_METHOD_TYPE, sortByMultiLanguageString, axpGridItemPlacementClassMap, AXPFileStorageStatus, collectQueryFilterLeaves, AXPPlatformScope, flattenQueryFilterUserGroups, isPersistableFilterQuery, AXPWidgetsList, axpGridNarrowContainerQueryPrefix, normalizeDefinitionCategories, runtimeQueryFailure, runtimeQuerySuccessObject } from '@acorex-platform/framework-shared/core';
33
+ import { resolveMultiLanguageString, setSmart, coerceFilterDisplayText, AXPRegionalSetting, omitFilterClauseIdentity, createRandomUuid, themeSurfaceVariantFromClass, toRuntimeSurfaceClassName, resolveToSurfaceClass, parseRuntimeHexSurface, listThemeSurfaceGroups, normalizeHexColor, extractValue, filterOperatorAllowsEmptyValue, shouldUseLocaleMapShape, buildLocaleTextMapValue, isFormValueEqual, runtimeQueryPayloadData, runtimeQueryCollectionData, isSelectionValueEqual, isLocaleStringMap, AXPWidgetsCatalog, AXP_INTEGRATION_CONNECTION_STATUS, AXP_INTEGRATION_AUTH_METHOD_TYPE, AXPFileStorageStatus, sortByMultiLanguageString, axpGridItemPlacementClassMap, collectQueryFilterLeaves, AXPPlatformScope, flattenQueryFilterUserGroups, isPersistableFilterQuery, AXPWidgetsList, axpGridNarrowContainerQueryPrefix, normalizeDefinitionCategories, runtimeQueryFailure, runtimeQuerySuccessObject } from '@acorex-platform/framework-shared/core';
34
34
  import { get, set, castArray, isNil, cloneDeep, isEqual, isNull, isEmpty, isPlainObject, isString, isNumber, defaultTo, has } from 'lodash-es';
35
35
  import * as i2$2 from '@acorex/components/loading';
36
36
  import { AXLoadingModule } from '@acorex/components/loading';
@@ -39,7 +39,7 @@ import { cloneProperty, AXPWidgetGroupEnum, createSelectProperty, createStringPr
39
39
  import { AXPopupService } from '@acorex/components/popup';
40
40
  import { AXCalendarService, AXTimeDurationFormatter } from '@acorex/core/date-time';
41
41
  import { AXPDialogOpener, AXPLayoutBuilderService } from '@acorex-platform/framework-client/layout/builder';
42
- import { AXPConditionBuilderComponent, AXPConditionBuilderConditionComponent, AXPColorChooserComponent, AXPColorPalettePickerComponent, AXPDragDropListComponent, AXPColumnItemListComponent, AXPImageEditorService, AXPFileChooserService, createAttachedFileProviderMenu, AXPFileViewerComponent, AXPStateMessageComponent, normalizeFileViewerBoundValue, AXPOutcomeResultsViewerComponent, AXPSignatureEditorService, AXP_SIGNATURE_PROVIDER, AXPStopwatchComponent, AXPWidgetFieldConfiguratorComponent, AXPItemConfiguratorComponent, AXPRepeaterRowsLayoutComponent, AXPLocalDataSourceEditorDialogService, AXPSpreadsheetComponent, AXPQueryViewSaveDialogService, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryColumnsComponent, AXPQueryViewSaveButtonComponent, AXPQueryViewTabsComponent } from '@acorex-platform/framework-client/layout/components';
42
+ import { AXPConditionBuilderComponent, AXPConditionBuilderConditionComponent, AXPColorChooserComponent, AXPColorPalettePickerComponent, AXPDragDropListComponent, AXPColumnItemListComponent, AXPImageEditorService, AXPFileChooserService, createAttachedFileProviderMenu, AXPFileViewerComponent, AXPStateMessageComponent, normalizeFileViewerBoundValue, AXPOutcomeResultsViewerComponent, AXP_IMAGE_FILE_CHOOSER_ACCEPT, fileListItemToImageFile, AXPSignatureEditorService, AXP_SIGNATURE_PROVIDER, AXPStopwatchComponent, AXPWidgetFieldConfiguratorComponent, AXPItemConfiguratorComponent, AXPRepeaterRowsLayoutComponent, AXPLocalDataSourceEditorDialogService, AXPSpreadsheetComponent, AXPQueryViewSaveDialogService, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryColumnsComponent, AXPQueryViewSaveButtonComponent, AXPQueryViewTabsComponent } from '@acorex-platform/framework-client/layout/components';
43
43
  import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
44
44
  import { AXValidationModule, AXValidationService } from '@acorex/core/validation';
45
45
  import { AXColorUtil } from '@acorex/core/utils';
@@ -1724,30 +1724,54 @@ var checkboxWidgetDesigner_component = /*#__PURE__*/Object.freeze({
1724
1724
  AXPCheckBoxWidgetDesignerComponent: AXPCheckBoxWidgetDesignerComponent
1725
1725
  });
1726
1726
 
1727
+ function applyNegativeBoolean(value, negative) {
1728
+ if (typeof value !== 'boolean' || !negative) {
1729
+ return value;
1730
+ }
1731
+ return !value;
1732
+ }
1733
+
1734
+ //#endregion
1735
+ //#region ----- Component -----
1727
1736
  class AXPCheckBoxWidgetEditComponent extends AXPValueWidgetComponent {
1728
1737
  constructor() {
1729
1738
  super(...arguments);
1730
- this.disabled = computed(() => this.options()['disabled'], /* @ts-ignore */
1739
+ //#region ----- Computed Properties -----
1740
+ this.negative = computed(() => this.options()['negative'] === true, /* @ts-ignore */
1741
+ ...(ngDevMode ? [{ debugName: "negative" }] : /* istanbul ignore next */ []));
1742
+ this.disabled = computed(() => this.options()['disabled'] === true, /* @ts-ignore */
1731
1743
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1732
- this.readonly = computed(() => this.options()['readonly'], /* @ts-ignore */
1744
+ this.readonly = computed(() => this.options()['readonly'] === true, /* @ts-ignore */
1733
1745
  ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
1734
1746
  this.label = computed(() => this.options()['label'], /* @ts-ignore */
1735
1747
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1736
1748
  }
1749
+ //#endregion
1750
+ //#region ----- Event Handlers -----
1751
+ displayValue() {
1752
+ return applyNegativeBoolean(this.getValue(), this.negative());
1753
+ }
1754
+ onControlChanged(event) {
1755
+ if (!event.isUserInteraction) {
1756
+ return;
1757
+ }
1758
+ this.setValue(applyNegativeBoolean(event.value, this.negative()));
1759
+ }
1737
1760
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCheckBoxWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1738
1761
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPCheckBoxWidgetEditComponent, isStandalone: true, selector: "axp-checkbox-widget-edit", usesInheritance: true, ngImport: i0, template: `
1739
1762
  <ax-check-box
1740
- [ngModel]="this.getValue()"
1763
+ [ngModel]="displayValue()"
1741
1764
  [disabled]="disabled()"
1742
1765
  [readonly]="readonly()"
1743
- (onValueChanged)="handleValueChanged($event)"
1766
+ (onValueChanged)="onControlChanged($event)"
1744
1767
  >
1745
1768
  @for (validation of validationRules(); track $index) {
1746
1769
  <ax-validation-rule
1747
1770
  [rule]="validation.rule"
1748
1771
  [message]="$safeNavigationMigration(validation.options?.message)"
1749
1772
  [options]="validation.options"
1750
- [disabled]="validation.disabled === true"></ax-validation-rule>
1773
+ [disabled]="validation.disabled === true"
1774
+ ></ax-validation-rule>
1751
1775
  }
1752
1776
  @if (label()) {
1753
1777
  <ax-label>{{ label() }}</ax-label>
@@ -1761,17 +1785,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1761
1785
  selector: 'axp-checkbox-widget-edit',
1762
1786
  template: `
1763
1787
  <ax-check-box
1764
- [ngModel]="this.getValue()"
1788
+ [ngModel]="displayValue()"
1765
1789
  [disabled]="disabled()"
1766
1790
  [readonly]="readonly()"
1767
- (onValueChanged)="handleValueChanged($event)"
1791
+ (onValueChanged)="onControlChanged($event)"
1768
1792
  >
1769
1793
  @for (validation of validationRules(); track $index) {
1770
1794
  <ax-validation-rule
1771
1795
  [rule]="validation.rule"
1772
1796
  [message]="$safeNavigationMigration(validation.options?.message)"
1773
1797
  [options]="validation.options"
1774
- [disabled]="validation.disabled === true"></ax-validation-rule>
1798
+ [disabled]="validation.disabled === true"
1799
+ ></ax-validation-rule>
1775
1800
  }
1776
1801
  @if (label()) {
1777
1802
  <ax-label>{{ label() }}</ax-label>
@@ -11167,33 +11192,43 @@ var toggleWidgetColumn_component = /*#__PURE__*/Object.freeze({
11167
11192
  AXPToggleWidgetColumnComponent: AXPToggleWidgetColumnComponent
11168
11193
  });
11169
11194
 
11195
+ //#endregion
11196
+ //#region ----- Component -----
11170
11197
  class AXPToggleWidgetEditComponent extends AXPValueWidgetComponent {
11171
11198
  constructor() {
11172
11199
  super(...arguments);
11173
- this.disabled = computed(() => this.options()['disabled'], /* @ts-ignore */
11200
+ //#region ----- Computed Properties -----
11201
+ this.negative = computed(() => this.options()['negative'] === true, /* @ts-ignore */
11202
+ ...(ngDevMode ? [{ debugName: "negative" }] : /* istanbul ignore next */ []));
11203
+ this.disabled = computed(() => this.options()['disabled'] === true, /* @ts-ignore */
11174
11204
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
11175
- this.readonly = computed(() => this.options()['readonly'], /* @ts-ignore */
11205
+ this.readonly = computed(() => this.options()['readonly'] === true, /* @ts-ignore */
11176
11206
  ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
11177
11207
  this.label = computed(() => this.options()['label'], /* @ts-ignore */
11178
11208
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
11179
11209
  this.color = computed(() => this.options()['color']?.id ?? 'primary', /* @ts-ignore */
11180
11210
  ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
11181
11211
  }
11182
- get __class() {
11183
- const cls = {};
11184
- //
11185
- cls['inline-block'] = true;
11186
- return cls;
11212
+ //#endregion
11213
+ //#region ----- Event Handlers -----
11214
+ displayValue() {
11215
+ return applyNegativeBoolean(this.getValue(), this.negative());
11216
+ }
11217
+ onControlChanged(event) {
11218
+ if (!event.isUserInteraction) {
11219
+ return;
11220
+ }
11221
+ this.setValue(applyNegativeBoolean(event.value, this.negative()));
11187
11222
  }
11188
11223
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPToggleWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
11189
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPToggleWidgetEditComponent, isStandalone: true, selector: "axp-toggle-widget-edit", host: { properties: { "class": "this.__class" } }, usesInheritance: true, ngImport: i0, template: `
11224
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPToggleWidgetEditComponent, isStandalone: true, selector: "axp-toggle-widget-edit", host: { classAttribute: "inline-block" }, usesInheritance: true, ngImport: i0, template: `
11190
11225
  <div class="flex items-center gap-2">
11191
11226
  <ax-switch
11192
- [ngModel]="this.getValue()"
11227
+ [ngModel]="displayValue()"
11193
11228
  [disabled]="disabled()"
11194
11229
  [readonly]="readonly()"
11195
11230
  [color]="color()"
11196
- (onValueChanged)="handleValueChanged($event)"
11231
+ (onValueChanged)="onControlChanged($event)"
11197
11232
  >
11198
11233
  </ax-switch>
11199
11234
  @if (label()) {
@@ -11209,11 +11244,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11209
11244
  template: `
11210
11245
  <div class="flex items-center gap-2">
11211
11246
  <ax-switch
11212
- [ngModel]="this.getValue()"
11247
+ [ngModel]="displayValue()"
11213
11248
  [disabled]="disabled()"
11214
11249
  [readonly]="readonly()"
11215
11250
  [color]="color()"
11216
- (onValueChanged)="handleValueChanged($event)"
11251
+ (onValueChanged)="onControlChanged($event)"
11217
11252
  >
11218
11253
  </ax-switch>
11219
11254
  @if (label()) {
@@ -11222,12 +11257,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11222
11257
  </div>
11223
11258
  `,
11224
11259
  changeDetection: ChangeDetectionStrategy.OnPush,
11225
- imports: [FormsModule, AXFormModule, AXSwitchModule, AXValidationModule, AXLabelModule, AXTranslationModule, AsyncPipe],
11260
+ host: {
11261
+ class: 'inline-block',
11262
+ },
11263
+ imports: [
11264
+ FormsModule,
11265
+ AXFormModule,
11266
+ AXSwitchModule,
11267
+ AXValidationModule,
11268
+ AXLabelModule,
11269
+ AXTranslationModule,
11270
+ AsyncPipe,
11271
+ ],
11226
11272
  }]
11227
- }], propDecorators: { __class: [{
11228
- type: HostBinding,
11229
- args: ['class']
11230
- }] } });
11273
+ }] });
11231
11274
 
11232
11275
  var toggleWidgetEdit_component = /*#__PURE__*/Object.freeze({
11233
11276
  __proto__: null,
@@ -14991,6 +15034,48 @@ const AXPQrcodeWidget = {
14991
15034
  dataSource: ['svg', 'canvas'],
14992
15035
  defaultValue: 'svg',
14993
15036
  }),
15037
+ createBooleanProperty({
15038
+ name: 'attachmentEnabled',
15039
+ title: 'Attachment Enabled',
15040
+ path: 'options.attachment.enabled',
15041
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15042
+ }),
15043
+ createBooleanProperty({
15044
+ name: 'attachmentReadonly',
15045
+ title: 'Attachment Readonly',
15046
+ path: 'options.attachment.readonly',
15047
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15048
+ }),
15049
+ createStringProperty({
15050
+ name: 'attachmentDataPath',
15051
+ title: 'Attachment Data Path',
15052
+ path: 'options.attachment.dataPath',
15053
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15054
+ }),
15055
+ createStringProperty({
15056
+ name: 'attachmentSources',
15057
+ title: 'Attachment Sources',
15058
+ path: 'options.attachment.sources',
15059
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15060
+ }),
15061
+ createStringProperty({
15062
+ name: 'attachmentRefType',
15063
+ title: 'Attachment Ref Type',
15064
+ path: 'options.attachment.fileStorage.refType',
15065
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15066
+ }),
15067
+ createStringProperty({
15068
+ name: 'attachmentRefId',
15069
+ title: 'Attachment Ref Id',
15070
+ path: 'options.attachment.fileStorage.refId',
15071
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15072
+ }),
15073
+ createStringProperty({
15074
+ name: 'attachmentCategory',
15075
+ title: 'Attachment Category',
15076
+ path: 'options.attachment.fileStorage.category',
15077
+ group: AXP_BEHAVIOR_PROPERTY_GROUP,
15078
+ }),
14994
15079
  ],
14995
15080
  components: {
14996
15081
  view: {
@@ -15024,10 +15109,17 @@ class AXPQrcodeViewerService {
15024
15109
  //#endregion
15025
15110
  //#region ---- Public API ----
15026
15111
  async open(options) {
15027
- const contentValue = options.content;
15028
- if (!contentValue) {
15112
+ const contentValue = options.content ?? '';
15113
+ const attachmentRef = options.attachmentRef?.trim() || '';
15114
+ const attachmentDataPath = options.attachmentDataPath?.trim() || '';
15115
+ const showAttachment = !!attachmentRef && !!attachmentDataPath && attachmentDataPath !== 'qr';
15116
+ if (!contentValue && !showAttachment) {
15029
15117
  return;
15030
15118
  }
15119
+ const context = { qr: contentValue };
15120
+ if (showAttachment) {
15121
+ assignContextPath(context, attachmentDataPath, attachmentRef);
15122
+ }
15031
15123
  const ref = await this.layoutBuilder
15032
15124
  .create()
15033
15125
  .dialog((dialog) => {
@@ -15035,7 +15127,7 @@ class AXPQrcodeViewerService {
15035
15127
  .setTitle(this.resolveDialogTitle(options.title))
15036
15128
  .setSize('md')
15037
15129
  .setCloseButton(true)
15038
- .setContext({ qr: contentValue })
15130
+ .setContext(context)
15039
15131
  .content((content) => {
15040
15132
  content
15041
15133
  .setDirection('column')
@@ -15050,7 +15142,17 @@ class AXPQrcodeViewerService {
15050
15142
  color: options.color ?? '#000000',
15051
15143
  readonly: true,
15052
15144
  outputType: options.outputType ?? 'svg',
15053
- showContent: true,
15145
+ showContent: !showAttachment,
15146
+ suppressPreview: true,
15147
+ ...(showAttachment
15148
+ ? {
15149
+ attachment: {
15150
+ enabled: true,
15151
+ readonly: true,
15152
+ dataPath: attachmentDataPath,
15153
+ },
15154
+ }
15155
+ : {}),
15054
15156
  });
15055
15157
  })
15056
15158
  .setActions((actions) => {
@@ -15079,6 +15181,322 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
15079
15181
  type: Injectable,
15080
15182
  args: [{ providedIn: 'root' }]
15081
15183
  }] });
15184
+ function assignContextPath(target, path, value) {
15185
+ const keys = path.split('.').filter((key) => key.length > 0);
15186
+ if (keys.length === 0) {
15187
+ return;
15188
+ }
15189
+ let current = target;
15190
+ for (let index = 0; index < keys.length - 1; index += 1) {
15191
+ const key = keys[index];
15192
+ const next = current[key];
15193
+ if (!next || typeof next !== 'object' || Array.isArray(next)) {
15194
+ current[key] = {};
15195
+ }
15196
+ current = current[key];
15197
+ }
15198
+ current[keys[keys.length - 1]] = value;
15199
+ }
15200
+
15201
+ //#region ---- Constants ----
15202
+ const AXP_QRCODE_ATTACHMENT_FILE_PREFIX = 'file:';
15203
+ const AXP_QRCODE_ATTACHMENT_LINK_PREFIX = 'link:';
15204
+ const AXP_QRCODE_ATTACHMENT_DOCUMENT_PREFIX = 'document:';
15205
+ /** File-storage ref used when the parent entity has not been saved yet. */
15206
+ const AXP_QRCODE_ATTACHMENT_PENDING_REF_ID = 'pending';
15207
+ const AXP_QRCODE_ATTACHMENT_DEFAULT_REF_TYPE = 'qrcode-image';
15208
+ const AXP_QRCODE_ATTACHMENT_DEFAULT_CATEGORY = 'qr-code-image';
15209
+ const DEVICE_SOURCE = 'system';
15210
+ const DRIVE_SOURCE = 'drive';
15211
+ //#endregion
15212
+ //#region ---- Config ----
15213
+ function asRecord(value) {
15214
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
15215
+ return null;
15216
+ }
15217
+ return value;
15218
+ }
15219
+ function readString(value) {
15220
+ if (typeof value !== 'string') {
15221
+ return undefined;
15222
+ }
15223
+ const trimmed = value.trim();
15224
+ return trimmed || undefined;
15225
+ }
15226
+ function normalizeSourceToken(value) {
15227
+ const key = value.trim().toLowerCase();
15228
+ if (key === 'device' || key === 'system') {
15229
+ return DEVICE_SOURCE;
15230
+ }
15231
+ if (key === 'drive') {
15232
+ return DRIVE_SOURCE;
15233
+ }
15234
+ return null;
15235
+ }
15236
+ function collectSourceTokens(value, into) {
15237
+ if (typeof value === 'string') {
15238
+ for (const part of value.split(/[,;\s]+/)) {
15239
+ const normalized = normalizeSourceToken(part);
15240
+ if (normalized && !into.includes(normalized)) {
15241
+ into.push(normalized);
15242
+ }
15243
+ }
15244
+ return;
15245
+ }
15246
+ if (Array.isArray(value)) {
15247
+ for (const entry of value) {
15248
+ collectSourceTokens(entry, into);
15249
+ }
15250
+ return;
15251
+ }
15252
+ const record = asRecord(value);
15253
+ const id = readString(record?.['id']) ?? readString(record?.['key']);
15254
+ if (id) {
15255
+ collectSourceTokens(id, into);
15256
+ }
15257
+ }
15258
+ /**
15259
+ * Reads attachment options. Support stays disabled unless `enabled` is true and a separate `dataPath` is set.
15260
+ * Flat designer keys (`attachmentEnabled`, …) are accepted when the nested `attachment` object is absent.
15261
+ */
15262
+ function resolveQrcodeAttachmentConfig(options) {
15263
+ const source = options ?? {};
15264
+ const nested = asRecord(source['attachment']);
15265
+ const fileStorage = asRecord(nested?.['fileStorage']);
15266
+ const sources = [];
15267
+ collectSourceTokens(nested?.['sources'] ?? source['attachmentSources'], sources);
15268
+ const dataPath = readString(nested?.['dataPath']) ?? readString(source['attachmentDataPath']);
15269
+ const enabledFlag = nested?.['enabled'] === true || source['attachmentEnabled'] === true;
15270
+ return {
15271
+ enabled: enabledFlag && !!dataPath,
15272
+ readonly: nested?.['readonly'] === true || source['attachmentReadonly'] === true,
15273
+ dataPath,
15274
+ sources,
15275
+ fileStorage: {
15276
+ refId: readString(fileStorage?.['refId']) ?? readString(source['attachmentRefId']),
15277
+ refType: readString(fileStorage?.['refType']) ?? readString(source['attachmentRefType']),
15278
+ category: readString(fileStorage?.['category']) ?? readString(source['attachmentCategory']),
15279
+ },
15280
+ };
15281
+ }
15282
+ /** Provider keys to hide so only the configured Device (`system`) and Drive sources remain. */
15283
+ function excludeProvidersForQrcodeAttachmentSources(sources) {
15284
+ if (sources.length === 0) {
15285
+ return [];
15286
+ }
15287
+ const allowed = new Set(sources);
15288
+ const excluded = [];
15289
+ if (!allowed.has(DEVICE_SOURCE)) {
15290
+ excluded.push(DEVICE_SOURCE);
15291
+ }
15292
+ if (!allowed.has(DRIVE_SOURCE)) {
15293
+ excluded.push(DRIVE_SOURCE);
15294
+ }
15295
+ return excluded;
15296
+ }
15297
+ //#endregion
15298
+ //#region ---- Refs ----
15299
+ function stripPrefix(value, prefix) {
15300
+ return value.startsWith(prefix) ? value.slice(prefix.length).trim() : value;
15301
+ }
15302
+ /** Owned upload id (`file:` or a bare file-storage id). Shared `link:` and `document:` refs are excluded. */
15303
+ function ownedQrcodeAttachmentFileId(value) {
15304
+ const trimmed = value?.trim();
15305
+ if (!trimmed || trimmed.startsWith(AXP_QRCODE_ATTACHMENT_LINK_PREFIX) || trimmed.startsWith(AXP_QRCODE_ATTACHMENT_DOCUMENT_PREFIX)) {
15306
+ return null;
15307
+ }
15308
+ const withoutPrefix = trimmed.startsWith(AXP_QRCODE_ATTACHMENT_FILE_PREFIX)
15309
+ ? stripPrefix(trimmed, AXP_QRCODE_ATTACHMENT_FILE_PREFIX)
15310
+ : trimmed;
15311
+ return isStoredImageFileId(withoutPrefix) ? normalizeStoredImageRef(withoutPrefix) : null;
15312
+ }
15313
+ /** File id that can be previewed or downloaded. Drive document refs are not file ids. */
15314
+ function displayQrcodeAttachmentFileId(value) {
15315
+ const trimmed = value?.trim();
15316
+ if (!trimmed || trimmed.startsWith(AXP_QRCODE_ATTACHMENT_DOCUMENT_PREFIX)) {
15317
+ return null;
15318
+ }
15319
+ if (trimmed.startsWith(AXP_QRCODE_ATTACHMENT_LINK_PREFIX)) {
15320
+ const fileId = stripPrefix(trimmed, AXP_QRCODE_ATTACHMENT_LINK_PREFIX);
15321
+ return isStoredImageFileId(fileId) ? normalizeStoredImageRef(fileId) : null;
15322
+ }
15323
+ return ownedQrcodeAttachmentFileId(trimmed);
15324
+ }
15325
+ function isSharedDriveQrcodeAttachmentRef(value) {
15326
+ const trimmed = value?.trim() ?? '';
15327
+ if (!trimmed) {
15328
+ return false;
15329
+ }
15330
+ if (trimmed.startsWith(AXP_QRCODE_ATTACHMENT_DOCUMENT_PREFIX)) {
15331
+ return true;
15332
+ }
15333
+ if (!trimmed.startsWith(AXP_QRCODE_ATTACHMENT_LINK_PREFIX)) {
15334
+ return false;
15335
+ }
15336
+ return displayQrcodeAttachmentFileId(trimmed) != null;
15337
+ }
15338
+ function toOwnedQrcodeAttachmentRef(fileId) {
15339
+ const normalized = normalizeStoredImageRef(fileId) ?? fileId.trim();
15340
+ return `${AXP_QRCODE_ATTACHMENT_FILE_PREFIX}${normalized}`;
15341
+ }
15342
+ function toSharedFileQrcodeAttachmentRef(fileId) {
15343
+ const normalized = normalizeStoredImageRef(fileId) ?? fileId.trim();
15344
+ return `${AXP_QRCODE_ATTACHMENT_LINK_PREFIX}${normalized}`;
15345
+ }
15346
+ function toSharedDocumentQrcodeAttachmentRef(documentId) {
15347
+ return `${AXP_QRCODE_ATTACHMENT_DOCUMENT_PREFIX}${documentId.trim()}`;
15348
+ }
15349
+ function readQrcodeAttachmentRef(data, dataPath) {
15350
+ if (!dataPath?.trim()) {
15351
+ return null;
15352
+ }
15353
+ const value = readPath(data, dataPath.trim());
15354
+ if (typeof value !== 'string') {
15355
+ return null;
15356
+ }
15357
+ const trimmed = value.trim();
15358
+ return trimmed || null;
15359
+ }
15360
+ function readPath(data, path) {
15361
+ return path.split('.').reduce((current, key) => {
15362
+ const record = asRecord(current);
15363
+ if (!record) {
15364
+ return undefined;
15365
+ }
15366
+ return record[key];
15367
+ }, data);
15368
+ }
15369
+ function qrcodeAttachmentImageUrl(ref, getDownloadUrl) {
15370
+ const fileId = displayQrcodeAttachmentFileId(ref);
15371
+ if (!fileId) {
15372
+ return null;
15373
+ }
15374
+ const url = resolveStoredImageDisplayUrl(fileId, getDownloadUrl);
15375
+ return url || null;
15376
+ }
15377
+ //#endregion
15378
+ //#region ---- Display and field patch ----
15379
+ function resolveQrcodeDisplayMode(input) {
15380
+ if (input.enabled && !!input.attachmentRef?.trim()) {
15381
+ return 'image';
15382
+ }
15383
+ if (typeof input.qrValue === 'string' && input.qrValue.trim()) {
15384
+ return 'qr';
15385
+ }
15386
+ return 'empty';
15387
+ }
15388
+ /**
15389
+ * Writes the attachment ref onto its own field.
15390
+ * Throws when the path is missing or is the QR value path, so a file id cannot replace the QR text.
15391
+ */
15392
+ function buildQrcodeAttachmentContextPatch(dataPath, qrPath, nextRef) {
15393
+ const path = dataPath.trim();
15394
+ const qr = qrPath.trim();
15395
+ if (!path || path === qr) {
15396
+ throw new Error('QR attachment dataPath must be a separate field from the QR value.');
15397
+ }
15398
+ return { [path]: nextRef };
15399
+ }
15400
+ function isQrcodeContentReadonly(options) {
15401
+ return !!options?.['readonly'];
15402
+ }
15403
+ /**
15404
+ * Attachment lock. QR-content readonly is intentionally not an input:
15405
+ * a readonly QR payload can still accept an image unless attachment readonly, form lock, or view mode says otherwise.
15406
+ */
15407
+ function isQrcodeAttachmentReadonly(input) {
15408
+ if (input.mode === 'view') {
15409
+ return true;
15410
+ }
15411
+ return !!(input.attachmentReadonly || input.formLocked || input.disabled);
15412
+ }
15413
+ //#endregion
15414
+ //#region ---- Chooser and storage target ----
15415
+ function isCancelledQrcodeAttachmentChoice(items) {
15416
+ return !items || items.length === 0;
15417
+ }
15418
+ function interpretQrcodeChooserItems(items) {
15419
+ const item = items?.[0];
15420
+ if (!item) {
15421
+ return { kind: 'cancel' };
15422
+ }
15423
+ const kind = item.source?.kind;
15424
+ const value = item.source?.value;
15425
+ if (kind === 'blob') {
15426
+ return { kind: 'upload' };
15427
+ }
15428
+ if (kind === 'fileId' && typeof value === 'string' && isStoredImageFileId(value)) {
15429
+ return { kind: 'shared-file', fileId: normalizeStoredImageRef(value) ?? value.trim() };
15430
+ }
15431
+ if (kind === 'reference') {
15432
+ const reference = asRecord(value);
15433
+ const documentId = readString(reference?.['id']) ?? readString(item.id);
15434
+ const type = readString(reference?.['type']);
15435
+ if (documentId && (type === 'document' || type == null)) {
15436
+ return { kind: 'shared-document', documentId };
15437
+ }
15438
+ }
15439
+ return { kind: 'cancel' };
15440
+ }
15441
+ function resolveQrcodeAttachmentStorageTarget(input) {
15442
+ const configuredRefId = input.fileStorage?.refId?.trim();
15443
+ const entityId = typeof input.entityId === 'string' ? input.entityId.trim() : '';
15444
+ return {
15445
+ refId: configuredRefId || entityId || AXP_QRCODE_ATTACHMENT_PENDING_REF_ID,
15446
+ refType: input.fileStorage?.refType?.trim() || AXP_QRCODE_ATTACHMENT_DEFAULT_REF_TYPE,
15447
+ category: input.fileStorage?.category?.trim() || AXP_QRCODE_ATTACHMENT_DEFAULT_CATEGORY,
15448
+ };
15449
+ }
15450
+ //#endregion
15451
+ //#region ---- Replace, remove, and release ----
15452
+ function planQrcodeAttachmentReplacement(currentRef, nextRef) {
15453
+ const owned = ownedQrcodeAttachmentFileId(currentRef);
15454
+ return {
15455
+ nextRef,
15456
+ supersededOwnedFileIds: owned ? [owned] : [],
15457
+ };
15458
+ }
15459
+ function planQrcodeAttachmentRemoval(currentRef) {
15460
+ const owned = ownedQrcodeAttachmentFileId(currentRef);
15461
+ return {
15462
+ nextRef: null,
15463
+ supersededOwnedFileIds: owned ? [owned] : [],
15464
+ };
15465
+ }
15466
+ /**
15467
+ * Owned file ids to mark for deletion.
15468
+ * While the form is still dirty, nothing is released.
15469
+ * Shared Drive refs are never included.
15470
+ * The saved reference is always kept, including when the user discards a replacement.
15471
+ */
15472
+ function fileIdsToRelease(input) {
15473
+ const savedId = ownedQrcodeAttachmentFileId(input.savedRef);
15474
+ const currentId = ownedQrcodeAttachmentFileId(input.currentRef);
15475
+ const settled = (input.currentRef ?? null) === (input.savedRef ?? null);
15476
+ if (!input.abandoning && !settled) {
15477
+ return [];
15478
+ }
15479
+ const keep = new Set();
15480
+ if (savedId) {
15481
+ keep.add(savedId);
15482
+ }
15483
+ if (!input.abandoning && currentId) {
15484
+ keep.add(currentId);
15485
+ }
15486
+ const candidates = [...input.uploadedFileIds, ...input.supersededOwnedFileIds];
15487
+ const released = [];
15488
+ for (const id of candidates) {
15489
+ if (!id || keep.has(id) || released.includes(id)) {
15490
+ continue;
15491
+ }
15492
+ if (!isStoredImageFileId(id)) {
15493
+ continue;
15494
+ }
15495
+ released.push(normalizeStoredImageRef(id) ?? id);
15496
+ }
15497
+ return released;
15498
+ }
15499
+ //#endregion
15082
15500
 
15083
15501
  //#region ---- Imports ----
15084
15502
  //#endregion
@@ -15097,6 +15515,10 @@ function buildQrcodeViewerOpenOptions(params) {
15097
15515
  const resolvedLevel = (typeof levelOption === 'string'
15098
15516
  ? levelOption
15099
15517
  : levelOption?.id) ?? 'M';
15518
+ const attachment = resolveQrcodeAttachmentConfig(params.widgetOptions);
15519
+ const attachmentRef = attachment.enabled
15520
+ ? (params.attachmentRef ?? readQrcodeAttachmentRef(params.data, attachment.dataPath))
15521
+ : null;
15100
15522
  return {
15101
15523
  content: params.content,
15102
15524
  title: title || params.fallbackTitleKey,
@@ -15104,14 +15526,17 @@ function buildQrcodeViewerOpenOptions(params) {
15104
15526
  level: resolvedLevel,
15105
15527
  color: params.widgetOptions['color'] ?? '#000000',
15106
15528
  outputType: params.widgetOptions['outputType'] ?? 'svg',
15529
+ attachmentRef,
15530
+ attachmentDataPath: attachment.enabled ? attachment.dataPath : undefined,
15107
15531
  };
15108
15532
  }
15109
15533
  async function openQrcodeViewer(viewer, params) {
15110
- const content = params.content?.trim();
15111
- if (!content) {
15534
+ const content = params.content?.trim() ?? '';
15535
+ const options = buildQrcodeViewerOpenOptions({ ...params, content });
15536
+ if (!content && !options.attachmentRef?.trim()) {
15112
15537
  return;
15113
15538
  }
15114
- await viewer.open(buildQrcodeViewerOpenOptions({ ...params, content }));
15539
+ await viewer.open(options);
15115
15540
  }
15116
15541
  //#endregion
15117
15542
 
@@ -15123,58 +15548,97 @@ class AXPQrcodeWidgetColumnComponent extends AXPColumnWidgetComponent {
15123
15548
  this.qrcodeViewer = inject(AXPQrcodeViewerService);
15124
15549
  this.formatService = inject(AXFormatService);
15125
15550
  this.translation = inject(AXTranslationService);
15551
+ this.fileStorage = inject(AXPFileStorageService, { optional: true });
15552
+ //#endregion
15553
+ //#region ---- State Signals ----
15554
+ this.imageUrl = signal(null, /* @ts-ignore */
15555
+ ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
15556
+ this.blobObjectUrl = null;
15557
+ this.hydrateRequestId = 0;
15558
+ }
15559
+ //#endregion
15560
+ //#region ---- Derived State ----
15561
+ attachmentConfig() {
15562
+ return resolveQrcodeAttachmentConfig((this.options ?? {}));
15563
+ }
15564
+ attachmentRef() {
15565
+ const config = this.attachmentConfig();
15566
+ if (!config.enabled) {
15567
+ return null;
15568
+ }
15569
+ return readQrcodeAttachmentRef(this.rowData, config.dataPath);
15570
+ }
15571
+ displayMode() {
15572
+ return resolveQrcodeDisplayMode({
15573
+ enabled: this.attachmentConfig().enabled,
15574
+ attachmentRef: this.attachmentRef(),
15575
+ qrValue: this.rawValue,
15576
+ });
15577
+ }
15578
+ //#endregion
15579
+ //#region ---- Lifecycle ----
15580
+ ngOnChanges() {
15581
+ void this.hydrateImageUrl(this.displayMode() === 'image' ? this.attachmentRef() : null);
15582
+ }
15583
+ ngOnDestroy() {
15584
+ this.revokeBlobUrl();
15126
15585
  }
15127
15586
  //#endregion
15128
15587
  //#region ---- UI Handlers ----
15129
15588
  async showPopup() {
15130
- const contentValue = this.rawValue;
15131
- if (!contentValue) {
15589
+ const contentValue = this.rawValue ?? '';
15590
+ if (!contentValue && this.displayMode() !== 'image') {
15132
15591
  return;
15133
15592
  }
15134
15593
  await openQrcodeViewer(this.qrcodeViewer, {
15135
15594
  content: contentValue,
15136
15595
  data: this.rowData,
15137
- widgetOptions: { ...this.options, size: 500 },
15596
+ widgetOptions: { ...(this.options ?? {}), size: 500 },
15138
15597
  formatService: this.formatService,
15139
15598
  activeLang: this.translation.getActiveLang(),
15599
+ attachmentRef: this.attachmentRef(),
15140
15600
  });
15141
15601
  }
15602
+ //#endregion
15603
+ //#region ---- Image Hydration ----
15604
+ async hydrateImageUrl(ref) {
15605
+ const requestId = ++this.hydrateRequestId;
15606
+ this.revokeBlobUrl();
15607
+ if (!ref || !this.fileStorage) {
15608
+ this.imageUrl.set(null);
15609
+ return;
15610
+ }
15611
+ try {
15612
+ const displayUrl = qrcodeAttachmentImageUrl(ref, (fileId) => this.fileStorage.getDownloadUrl(fileId));
15613
+ if (requestId !== this.hydrateRequestId) {
15614
+ if (displayUrl?.startsWith('blob:')) {
15615
+ URL.revokeObjectURL(displayUrl);
15616
+ }
15617
+ return;
15618
+ }
15619
+ if (displayUrl?.startsWith('blob:')) {
15620
+ this.blobObjectUrl = displayUrl;
15621
+ }
15622
+ this.imageUrl.set(displayUrl);
15623
+ }
15624
+ catch {
15625
+ if (requestId === this.hydrateRequestId) {
15626
+ this.imageUrl.set(null);
15627
+ }
15628
+ }
15629
+ }
15630
+ revokeBlobUrl() {
15631
+ if (this.blobObjectUrl) {
15632
+ URL.revokeObjectURL(this.blobObjectUrl);
15633
+ this.blobObjectUrl = null;
15634
+ }
15635
+ }
15142
15636
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
15143
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetColumnComponent, isStandalone: true, selector: "axp-qrcode-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, usesInheritance: true, ngImport: i0, template: `
15144
- <div class="flex items-center gap-2">
15145
- @if (rawValue) {
15146
- <ax-button class="ax-sm" look="twotone" color="default" (click)="showPopup()">
15147
- <ax-icon>
15148
- <i class="fa-regular fa-qrcode"></i>
15149
- </ax-icon>
15150
- </ax-button>
15151
- } @else {
15152
- <span>-</span>
15153
- }
15154
- </div>
15155
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
15637
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetColumnComponent, isStandalone: true, selector: "axp-qrcode-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex items-center gap-2\">\n <!-- ----- Attached image preview when the row stores a QR image ----- -->\n @if (displayMode() === 'image') {\n <button\n type=\"button\"\n class=\"inline-flex shrink-0 overflow-hidden cursor-pointer border border-border-light-surface bg-transparent p-0\"\n style=\"width: 40px; height: 40px; border-radius: 4px\"\n (click)=\"showPopup()\"\n >\n <!-- ----- Thumbnail of the stored image ----- -->\n @if (imageUrl()) {\n <img [src]=\"imageUrl()!\" alt=\"\" class=\"size-full object-contain\" style=\"border-radius: 4px\" />\n }\n </button>\n }\n <!-- ----- Generated QR preview when no attachment image is stored ----- -->\n @else if (rawValue) {\n <ax-button class=\"ax-sm\" look=\"twotone\" color=\"default\" (click)=\"showPopup()\">\n <ax-icon>\n <i class=\"fa-regular fa-qrcode\"></i>\n </ax-icon>\n </ax-button>\n } @else {\n <span>-</span>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
15156
15638
  }
15157
15639
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetColumnComponent, decorators: [{
15158
15640
  type: Component,
15159
- args: [{
15160
- selector: 'axp-qrcode-widget-column',
15161
- imports: [AXButtonModule, AXDecoratorModule],
15162
- template: `
15163
- <div class="flex items-center gap-2">
15164
- @if (rawValue) {
15165
- <ax-button class="ax-sm" look="twotone" color="default" (click)="showPopup()">
15166
- <ax-icon>
15167
- <i class="fa-regular fa-qrcode"></i>
15168
- </ax-icon>
15169
- </ax-button>
15170
- } @else {
15171
- <span>-</span>
15172
- }
15173
- </div>
15174
- `,
15175
- changeDetection: ChangeDetectionStrategy.OnPush,
15176
- inputs: ['rawValue', 'rowData'],
15177
- }]
15641
+ args: [{ selector: 'axp-qrcode-widget-column', imports: [AXButtonModule, AXDecoratorModule], changeDetection: ChangeDetectionStrategy.OnPush, inputs: ['rawValue', 'rowData'], template: "<div class=\"flex items-center gap-2\">\n <!-- ----- Attached image preview when the row stores a QR image ----- -->\n @if (displayMode() === 'image') {\n <button\n type=\"button\"\n class=\"inline-flex shrink-0 overflow-hidden cursor-pointer border border-border-light-surface bg-transparent p-0\"\n style=\"width: 40px; height: 40px; border-radius: 4px\"\n (click)=\"showPopup()\"\n >\n <!-- ----- Thumbnail of the stored image ----- -->\n @if (imageUrl()) {\n <img [src]=\"imageUrl()!\" alt=\"\" class=\"size-full object-contain\" style=\"border-radius: 4px\" />\n }\n </button>\n }\n <!-- ----- Generated QR preview when no attachment image is stored ----- -->\n @else if (rawValue) {\n <ax-button class=\"ax-sm\" look=\"twotone\" color=\"default\" (click)=\"showPopup()\">\n <ax-icon>\n <i class=\"fa-regular fa-qrcode\"></i>\n </ax-icon>\n </ax-button>\n } @else {\n <span>-</span>\n }\n</div>\n" }]
15178
15642
  }] });
15179
15643
 
15180
15644
  var qrcodeWidgetColumn_component = /*#__PURE__*/Object.freeze({
@@ -15184,11 +15648,19 @@ var qrcodeWidgetColumn_component = /*#__PURE__*/Object.freeze({
15184
15648
 
15185
15649
  class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15186
15650
  constructor() {
15187
- super(...arguments);
15651
+ super();
15188
15652
  //#region ---- Services & Dependencies ----
15189
15653
  this.qrcodeViewer = inject(AXPQrcodeViewerService);
15190
15654
  this.formatService = inject(AXFormatService);
15191
15655
  this.translation = inject(AXTranslationService);
15656
+ this.fileChooser = inject(AXPFileChooserService);
15657
+ this.fileStorage = inject(AXPFileStorageService);
15658
+ this.toast = inject(AXToastService);
15659
+ //#endregion
15660
+ //#region ---- Attachment Session ----
15661
+ this.uploadedFileIds = new Set();
15662
+ this.supersededOwnedFileIds = new Set();
15663
+ this.releasing = false;
15192
15664
  //#endregion
15193
15665
  this.value = computed(() => this.getValue(), /* @ts-ignore */
15194
15666
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
@@ -15211,6 +15683,58 @@ class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15211
15683
  ...(ngDevMode ? [{ debugName: "hasClearButton" }] : /* istanbul ignore next */ []));
15212
15684
  this.placeholder = computed(() => this.options()['placeholder'] ?? '@general:terms.common.placeholder', /* @ts-ignore */
15213
15685
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
15686
+ this.attachmentConfig = computed(() => resolveQrcodeAttachmentConfig(this.options()), /* @ts-ignore */
15687
+ ...(ngDevMode ? [{ debugName: "attachmentConfig" }] : /* istanbul ignore next */ []));
15688
+ this.attachmentRef = computed(() => {
15689
+ const config = this.attachmentConfig();
15690
+ if (!config.enabled) {
15691
+ return null;
15692
+ }
15693
+ return readQrcodeAttachmentRef(this.contextService.data(), config.dataPath);
15694
+ }, /* @ts-ignore */
15695
+ ...(ngDevMode ? [{ debugName: "attachmentRef" }] : /* istanbul ignore next */ []));
15696
+ this.displayMode = computed(() => resolveQrcodeDisplayMode({
15697
+ enabled: this.attachmentConfig().enabled,
15698
+ attachmentRef: this.attachmentRef(),
15699
+ qrValue: this.value(),
15700
+ }), /* @ts-ignore */
15701
+ ...(ngDevMode ? [{ debugName: "displayMode" }] : /* istanbul ignore next */ []));
15702
+ this.imageUrl = signal(null, /* @ts-ignore */
15703
+ ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
15704
+ this.blobObjectUrl = null;
15705
+ this.hydrateRequestId = 0;
15706
+ this.choosingAttachment = signal(false, /* @ts-ignore */
15707
+ ...(ngDevMode ? [{ debugName: "choosingAttachment" }] : /* istanbul ignore next */ []));
15708
+ effect(() => {
15709
+ void this.hydrateImageUrl(this.displayMode() === 'image' ? this.attachmentRef() : null);
15710
+ });
15711
+ effect(() => {
15712
+ const config = this.attachmentConfig();
15713
+ if (!config.enabled || !config.dataPath) {
15714
+ return;
15715
+ }
15716
+ const currentRef = readQrcodeAttachmentRef(this.contextService.data(), config.dataPath);
15717
+ const savedRef = readQrcodeAttachmentRef(this.contextService.saved(), config.dataPath);
15718
+ void this.releaseOwnedFiles(currentRef, savedRef, false);
15719
+ });
15720
+ }
15721
+ ngOnDestroy() {
15722
+ this.revokeBlobUrl();
15723
+ const config = this.attachmentConfig();
15724
+ if (!config.enabled || !config.dataPath) {
15725
+ return;
15726
+ }
15727
+ const currentRef = readQrcodeAttachmentRef(this.contextService.data(), config.dataPath);
15728
+ const savedRef = readQrcodeAttachmentRef(this.contextService.saved(), config.dataPath);
15729
+ void this.releaseOwnedFiles(currentRef, savedRef, currentRef !== savedRef);
15730
+ }
15731
+ attachmentActionsLocked() {
15732
+ return isQrcodeAttachmentReadonly({
15733
+ attachmentReadonly: this.attachmentConfig().readonly,
15734
+ formLocked: isAncestorFormLocked(this),
15735
+ disabled: !!this.options()['disabled'],
15736
+ mode: this.mode,
15737
+ });
15214
15738
  }
15215
15739
  onValueChange(e) {
15216
15740
  if (e.isUserInteraction) {
@@ -15232,8 +15756,8 @@ class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15232
15756
  this.draft.set(this.value() ?? '');
15233
15757
  }
15234
15758
  async openPreview() {
15235
- const content = this.value();
15236
- if (!content) {
15759
+ const content = this.value() ?? '';
15760
+ if (!content && this.displayMode() !== 'image') {
15237
15761
  return;
15238
15762
  }
15239
15763
  await openQrcodeViewer(this.qrcodeViewer, {
@@ -15242,6 +15766,7 @@ class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15242
15766
  widgetOptions: this.options(),
15243
15767
  formatService: this.formatService,
15244
15768
  activeLang: this.translation.getActiveLang(),
15769
+ attachmentRef: this.attachmentRef(),
15245
15770
  });
15246
15771
  }
15247
15772
  downloadQr(el) {
@@ -15253,9 +15778,78 @@ class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15253
15778
  fallbackSize: this.size(),
15254
15779
  });
15255
15780
  }
15781
+ async downloadDisplayed(el) {
15782
+ const fileId = displayQrcodeAttachmentFileId(this.attachmentRef());
15783
+ if (this.displayMode() === 'image' && fileId) {
15784
+ try {
15785
+ const blob = await this.fileStorage.download(fileId);
15786
+ const extension = blob.type === 'image/jpeg' ? 'jpg' : blob.type === 'image/webp' ? 'webp' : 'png';
15787
+ triggerBrowserDownload(blob, `qrcode-image.${extension}`);
15788
+ }
15789
+ catch {
15790
+ await this.notifyGenericError();
15791
+ }
15792
+ return;
15793
+ }
15794
+ this.downloadQr(el);
15795
+ }
15256
15796
  clearValue() {
15257
15797
  this.setValue('');
15258
15798
  }
15799
+ async chooseAttachment() {
15800
+ if (this.attachmentActionsLocked() || this.choosingAttachment()) {
15801
+ return;
15802
+ }
15803
+ const config = this.attachmentConfig();
15804
+ if (!config.enabled || !config.dataPath) {
15805
+ return;
15806
+ }
15807
+ this.choosingAttachment.set(true);
15808
+ try {
15809
+ const items = await this.fileChooser.promptChoose({
15810
+ options: {
15811
+ multiple: false,
15812
+ accept: AXP_IMAGE_FILE_CHOOSER_ACCEPT,
15813
+ excludeProviders: excludeProvidersForQrcodeAttachmentSources(config.sources),
15814
+ attachmentType: 'clone',
15815
+ },
15816
+ items: [],
15817
+ });
15818
+ if (isCancelledQrcodeAttachmentChoice(items)) {
15819
+ return;
15820
+ }
15821
+ const interpretation = interpretQrcodeChooserItems(items);
15822
+ if (interpretation.kind === 'cancel') {
15823
+ return;
15824
+ }
15825
+ if (interpretation.kind === 'upload') {
15826
+ const file = fileListItemToImageFile(items[0]);
15827
+ if (!file) {
15828
+ return;
15829
+ }
15830
+ await this.uploadAttachment(file, config);
15831
+ return;
15832
+ }
15833
+ if (interpretation.kind === 'shared-file') {
15834
+ this.applyAttachmentRef(toSharedFileQrcodeAttachmentRef(interpretation.fileId), config);
15835
+ return;
15836
+ }
15837
+ this.applyAttachmentRef(toSharedDocumentQrcodeAttachmentRef(interpretation.documentId), config);
15838
+ }
15839
+ finally {
15840
+ this.choosingAttachment.set(false);
15841
+ }
15842
+ }
15843
+ removeAttachment() {
15844
+ if (this.attachmentActionsLocked()) {
15845
+ return;
15846
+ }
15847
+ const config = this.attachmentConfig();
15848
+ if (!config.enabled) {
15849
+ return;
15850
+ }
15851
+ this.applyAttachmentRef(null, config);
15852
+ }
15259
15853
  async onFileSelected(e) {
15260
15854
  const input = e.target;
15261
15855
  const file = input?.files && input.files.length > 0 ? input.files[0] : null;
@@ -15272,8 +15866,142 @@ class AXPQrcodeWidgetEditComponent extends AXPValueWidgetComponent {
15272
15866
  }
15273
15867
  }
15274
15868
  }
15275
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
15276
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetEditComponent, isStandalone: true, selector: "axp-qrcode-widget-edit", host: { classAttribute: "block flex-1" }, usesInheritance: true, ngImport: i0, template: "<!-- Main Container -->\n<div class=\"flex flex-col gap-3 p-3 w-fit\">\n <div class=\"flex justify-center\">\n <!-- QR Code Container -->\n <div class=\"bg-lightest border border-default rounded-md shadow-md p-3\" #qr>\n <!-- QR Code Display or Empty Placeholder -->\n @if (value()) {\n <!-- Display QR Code when value exists -->\n <ax-qrcode [content]=\"value()\" [size]=\"size()\" [color]=\"color()\" [level]=\"level()\" [outputType]=\"'svg'\">\n </ax-qrcode>\n } @else {\n <!-- Empty State: Show placeholder when value is null or empty -->\n <div\n class=\"flex flex-col items-center justify-center text-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n <ax-icon icon=\"fa-light fa-qrcode\" class=\"text-4xl text-gray-400 mb-3\"></ax-icon>\n <div class=\"text-sm text-gray-500\">\n {{ '@general:state-message.empty.title' | translate | async }}\n </div>\n </div>\n }\n\n <!-- Action Buttons Section -->\n @if (!readonly()) {\n <div class=\"flex items-center justify-between gap-2 pt-4\">\n <!-- Edit Button: Opens popover to edit QR code content -->\n <ax-button\n #editBtn\n look=\"twotone\"\n [title]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"beginEdit()\"\n >\n <!-- Edit Popover: Text input for editing QR code content -->\n <ax-popover #po [target]=\"editBtn\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div\n class=\"bg-lightest border border-default rounded-md shadow-md p-5 w-full sm:w-96\"\n >\n <!-- Text Input for QR Code Content -->\n <ax-text-box\n [value]=\"draft()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"placeholder() | translate | async\"\n (onValueChanged)=\"onDraftChange($event)\"\n >\n @if (hasClearButton()) {\n <ax-clear-button></ax-clear-button>\n }\n </ax-text-box>\n <!-- Popover Action Buttons -->\n <div class=\"flex justify-end gap-2 mt-3\">\n <ax-button\n look=\"outline\"\n class=\"ax-sm\"\n [text]=\"('@general:actions.cancel.title' | translate | async)!\"\n (onClick)=\"cancelEdit(); po.close()\"\n ></ax-button>\n <ax-button\n look=\"solid\"\n class=\"ax-sm\"\n color=\"primary\"\n [text]=\"('@general:actions.submit.title' | translate | async)!\"\n (onClick)=\"applyDraft(); po.close()\"\n ></ax-button>\n </div>\n </div>\n </ax-popover>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n\n <!-- Upload Button: Upload text file to set QR code content -->\n <!-- <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.upload.title' | translate | async)!\"\n (onClick)=\"fileInput.click()\"\n >\n <input #fileInput type=\"file\" accept=\"text/plain\" class=\"hidden\" (change)=\"onFileSelected($event)\" />\n <ax-icon icon=\"fa-light fa-upload\"></ax-icon>\n </ax-button> -->\n\n <!-- Export Button: Download QR code as image (only shown when value exists) -->\n @if (value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.export.title' | translate | async)!\"\n (onClick)=\"downloadQr(qr)\"\n >\n <ax-icon icon=\"fa-light fa-download\"></ax-icon>\n </ax-button>\n }\n\n <!-- Delete Button: Clear QR code value (only shown when not readonly and value exists) -->\n @if (!readonly() && value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"clearValue()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i1$8.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { 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: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i3$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "restoreFocusOnClose", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXQrcodeModule }, { kind: "component", type: i5$1.AXQrcodeComponent, selector: "ax-qrcode", inputs: ["content", "size", "level", "color", "backgroundColor", "outputType"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1$6.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
15869
+ //#region ---- Attachment Persistence ----
15870
+ async uploadAttachment(file, config) {
15871
+ const entityId = this.contextService.data()['id'];
15872
+ const target = resolveQrcodeAttachmentStorageTarget({
15873
+ entityId,
15874
+ fileStorage: config.fileStorage,
15875
+ });
15876
+ let fileId;
15877
+ try {
15878
+ const info = await this.fileStorage.save({
15879
+ file,
15880
+ name: file.name || 'qrcode-image.png',
15881
+ refId: target.refId,
15882
+ refType: target.refType,
15883
+ category: target.category,
15884
+ status: AXPFileStorageStatus.Temporary,
15885
+ });
15886
+ fileId = info.fileId?.trim();
15887
+ if (!fileId) {
15888
+ throw new Error('File storage did not return a fileId.');
15889
+ }
15890
+ await this.fileStorage.commit(fileId);
15891
+ this.uploadedFileIds.add(fileId);
15892
+ this.applyAttachmentRef(toOwnedQrcodeAttachmentRef(fileId), config);
15893
+ }
15894
+ catch {
15895
+ if (fileId) {
15896
+ this.uploadedFileIds.delete(fileId);
15897
+ try {
15898
+ await this.fileStorage.markForDeletion(fileId);
15899
+ }
15900
+ catch {
15901
+ // The failed upload is already unusable; keep the current QR image.
15902
+ }
15903
+ }
15904
+ await this.notifyUploadFailed();
15905
+ }
15906
+ }
15907
+ applyAttachmentRef(nextRef, config) {
15908
+ const dataPath = config.dataPath;
15909
+ if (!dataPath) {
15910
+ return;
15911
+ }
15912
+ const qrPath = this.fullPath() ?? '';
15913
+ let patch;
15914
+ try {
15915
+ patch = buildQrcodeAttachmentContextPatch(dataPath, qrPath, nextRef);
15916
+ }
15917
+ catch {
15918
+ return;
15919
+ }
15920
+ const previousRef = readQrcodeAttachmentRef(this.contextService.data(), dataPath);
15921
+ const plan = nextRef
15922
+ ? planQrcodeAttachmentReplacement(previousRef, nextRef)
15923
+ : planQrcodeAttachmentRemoval(previousRef);
15924
+ for (const id of plan.supersededOwnedFileIds) {
15925
+ this.supersededOwnedFileIds.add(id);
15926
+ }
15927
+ const [path, value] = Object.entries(patch)[0];
15928
+ this.contextService.update(path, value, { origin: 'user' });
15929
+ }
15930
+ async releaseOwnedFiles(currentRef, savedRef, abandoning) {
15931
+ if (this.releasing) {
15932
+ return;
15933
+ }
15934
+ const ids = fileIdsToRelease({
15935
+ savedRef,
15936
+ currentRef,
15937
+ uploadedFileIds: [...this.uploadedFileIds],
15938
+ supersededOwnedFileIds: [...this.supersededOwnedFileIds],
15939
+ abandoning,
15940
+ });
15941
+ if (ids.length === 0) {
15942
+ return;
15943
+ }
15944
+ this.releasing = true;
15945
+ try {
15946
+ for (const id of ids) {
15947
+ this.uploadedFileIds.delete(id);
15948
+ this.supersededOwnedFileIds.delete(id);
15949
+ try {
15950
+ await this.fileStorage.markForDeletion(id);
15951
+ }
15952
+ catch {
15953
+ // Leave the id out of the session so a later save does not retry a shared file.
15954
+ }
15955
+ }
15956
+ }
15957
+ finally {
15958
+ this.releasing = false;
15959
+ }
15960
+ }
15961
+ async hydrateImageUrl(ref) {
15962
+ const requestId = ++this.hydrateRequestId;
15963
+ this.revokeBlobUrl();
15964
+ if (!ref) {
15965
+ this.imageUrl.set(null);
15966
+ return;
15967
+ }
15968
+ try {
15969
+ const displayUrl = qrcodeAttachmentImageUrl(ref, (fileId) => this.fileStorage.getDownloadUrl(fileId));
15970
+ if (requestId !== this.hydrateRequestId) {
15971
+ if (displayUrl?.startsWith('blob:')) {
15972
+ URL.revokeObjectURL(displayUrl);
15973
+ }
15974
+ return;
15975
+ }
15976
+ if (displayUrl?.startsWith('blob:')) {
15977
+ this.blobObjectUrl = displayUrl;
15978
+ }
15979
+ this.imageUrl.set(displayUrl);
15980
+ }
15981
+ catch {
15982
+ if (requestId === this.hydrateRequestId) {
15983
+ this.imageUrl.set(null);
15984
+ }
15985
+ }
15986
+ }
15987
+ revokeBlobUrl() {
15988
+ if (this.blobObjectUrl) {
15989
+ URL.revokeObjectURL(this.blobObjectUrl);
15990
+ this.blobObjectUrl = null;
15991
+ }
15992
+ }
15993
+ async notifyUploadFailed() {
15994
+ const title = await this.translation.translateAsync('@general:messages.generic.error.title');
15995
+ const content = await this.translation.translateAsync('@general:widgets.file-uploader.messages.upload-failed');
15996
+ this.toast.show({ color: 'danger', title, content });
15997
+ }
15998
+ async notifyGenericError() {
15999
+ const title = await this.translation.translateAsync('@general:messages.generic.error.title');
16000
+ const content = await this.translation.translateAsync('@general:messages.generic.error.description');
16001
+ this.toast.show({ color: 'danger', title, content });
16002
+ }
16003
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16004
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetEditComponent, isStandalone: true, selector: "axp-qrcode-widget-edit", host: { classAttribute: "block flex-1" }, usesInheritance: true, ngImport: i0, template: "<!-- Main Container -->\n<div class=\"flex flex-col gap-3 p-3 w-fit\">\n <div class=\"flex justify-center\">\n <!-- QR Code Container -->\n <div class=\"bg-lightest border border-default rounded-md shadow-md p-3\" #qr>\n <!-- QR image when an attachment is stored; otherwise the generated QR -->\n @if (displayMode() === 'image') {\n <!-- ----- Show the stored image at the widget size without cropping ----- -->\n @if (imageUrl()) {\n <img\n [src]=\"imageUrl()!\"\n [attr.alt]=\"('@platform-layout-widgets:widgets.qrcode.attachment.alt' | translate | async) ?? ''\"\n class=\"object-contain\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n />\n } @else {\n <div\n class=\"flex items-center justify-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n ></div>\n }\n } @else if (value()) {\n <!-- Display QR Code when value exists -->\n <ax-qrcode [content]=\"value()\" [size]=\"size()\" [color]=\"color()\" [level]=\"level()\" [outputType]=\"'svg'\">\n </ax-qrcode>\n } @else {\n <!-- Empty State: Show placeholder when value is null or empty -->\n <div\n class=\"flex flex-col items-center justify-center text-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n <ax-icon icon=\"fa-light fa-qrcode\" class=\"text-4xl text-gray-400 mb-3\"></ax-icon>\n <div class=\"text-sm text-gray-500\">\n {{ '@general:state-message.empty.title' | translate | async }}\n </div>\n </div>\n }\n\n <!-- Action Buttons Section -->\n @if (!readonly() || attachmentConfig().enabled) {\n <div class=\"flex items-center justify-between gap-2 pt-4\">\n <!-- Edit Button: Opens popover to edit QR code content -->\n @if (!readonly()) {\n <ax-button\n #editBtn\n look=\"twotone\"\n [title]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"beginEdit()\"\n >\n <!-- Edit Popover: Text input for editing QR code content -->\n <ax-popover #po [target]=\"editBtn\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div\n class=\"bg-lightest border border-default rounded-md shadow-md p-5 w-full sm:w-96\"\n >\n <!-- Text Input for QR Code Content -->\n <ax-text-box\n [value]=\"draft()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"placeholder() | translate | async\"\n (onValueChanged)=\"onDraftChange($event)\"\n >\n @if (hasClearButton()) {\n <ax-clear-button></ax-clear-button>\n }\n </ax-text-box>\n <!-- Popover Action Buttons -->\n <div class=\"flex justify-end gap-2 mt-3\">\n <ax-button\n look=\"outline\"\n class=\"ax-sm\"\n [text]=\"('@general:actions.cancel.title' | translate | async)!\"\n (onClick)=\"cancelEdit(); po.close()\"\n ></ax-button>\n <ax-button\n look=\"solid\"\n class=\"ax-sm\"\n color=\"primary\"\n [text]=\"('@general:actions.submit.title' | translate | async)!\"\n (onClick)=\"applyDraft(); po.close()\"\n ></ax-button>\n </div>\n </div>\n </ax-popover>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n }\n\n <!-- Upload or replace the optional QR image without changing the QR text -->\n @if (attachmentConfig().enabled && !attachmentActionsLocked()) {\n <ax-button\n look=\"twotone\"\n [disabled]=\"choosingAttachment()\"\n [title]=\"\n ((displayMode() === 'image'\n ? '@platform-layout-widgets:widgets.qrcode.attachment.replace'\n : '@platform-layout-widgets:widgets.qrcode.attachment.upload'\n ) | translate | async)!\n \"\n (onClick)=\"chooseAttachment()\"\n >\n <ax-icon [icon]=\"displayMode() === 'image' ? 'fa-light fa-arrows-rotate' : 'fa-light fa-image'\"></ax-icon>\n </ax-button>\n }\n\n <!-- Upload Button: Upload text file to set QR code content -->\n <!-- <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.upload.title' | translate | async)!\"\n (onClick)=\"fileInput.click()\"\n >\n <input #fileInput type=\"file\" accept=\"text/plain\" class=\"hidden\" (change)=\"onFileSelected($event)\" />\n <ax-icon icon=\"fa-light fa-upload\"></ax-icon>\n </ax-button> -->\n\n <!-- Preview and export follow whichever image is currently displayed -->\n @if (displayMode() !== 'empty') {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.export.title' | translate | async)!\"\n (onClick)=\"downloadDisplayed(qr)\"\n >\n <ax-icon icon=\"fa-light fa-download\"></ax-icon>\n </ax-button>\n }\n\n <!-- Remove the attached image and show the generated QR again -->\n @if (attachmentConfig().enabled && !attachmentActionsLocked() && displayMode() === 'image') {\n <ax-button\n look=\"twotone\"\n [title]=\"('@platform-layout-widgets:widgets.qrcode.attachment.remove' | translate | async)!\"\n (onClick)=\"removeAttachment()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-image-slash\"></ax-icon>\n </ax-button>\n }\n\n <!-- Delete Button: Clear QR code value (only shown when not readonly and value exists) -->\n @if (!readonly() && value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"clearValue()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i1$8.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { 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: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i3$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "restoreFocusOnClose", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXQrcodeModule }, { kind: "component", type: i5$1.AXQrcodeComponent, selector: "ax-qrcode", inputs: ["content", "size", "level", "color", "backgroundColor", "outputType"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1$6.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
15277
16005
  }
15278
16006
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetEditComponent, decorators: [{
15279
16007
  type: Component,
@@ -15286,8 +16014,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
15286
16014
  AXTranslationModule,
15287
16015
  AsyncPipe,
15288
16016
  FormsModule,
15289
- ], host: { class: 'block flex-1' }, template: "<!-- Main Container -->\n<div class=\"flex flex-col gap-3 p-3 w-fit\">\n <div class=\"flex justify-center\">\n <!-- QR Code Container -->\n <div class=\"bg-lightest border border-default rounded-md shadow-md p-3\" #qr>\n <!-- QR Code Display or Empty Placeholder -->\n @if (value()) {\n <!-- Display QR Code when value exists -->\n <ax-qrcode [content]=\"value()\" [size]=\"size()\" [color]=\"color()\" [level]=\"level()\" [outputType]=\"'svg'\">\n </ax-qrcode>\n } @else {\n <!-- Empty State: Show placeholder when value is null or empty -->\n <div\n class=\"flex flex-col items-center justify-center text-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n <ax-icon icon=\"fa-light fa-qrcode\" class=\"text-4xl text-gray-400 mb-3\"></ax-icon>\n <div class=\"text-sm text-gray-500\">\n {{ '@general:state-message.empty.title' | translate | async }}\n </div>\n </div>\n }\n\n <!-- Action Buttons Section -->\n @if (!readonly()) {\n <div class=\"flex items-center justify-between gap-2 pt-4\">\n <!-- Edit Button: Opens popover to edit QR code content -->\n <ax-button\n #editBtn\n look=\"twotone\"\n [title]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"beginEdit()\"\n >\n <!-- Edit Popover: Text input for editing QR code content -->\n <ax-popover #po [target]=\"editBtn\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div\n class=\"bg-lightest border border-default rounded-md shadow-md p-5 w-full sm:w-96\"\n >\n <!-- Text Input for QR Code Content -->\n <ax-text-box\n [value]=\"draft()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"placeholder() | translate | async\"\n (onValueChanged)=\"onDraftChange($event)\"\n >\n @if (hasClearButton()) {\n <ax-clear-button></ax-clear-button>\n }\n </ax-text-box>\n <!-- Popover Action Buttons -->\n <div class=\"flex justify-end gap-2 mt-3\">\n <ax-button\n look=\"outline\"\n class=\"ax-sm\"\n [text]=\"('@general:actions.cancel.title' | translate | async)!\"\n (onClick)=\"cancelEdit(); po.close()\"\n ></ax-button>\n <ax-button\n look=\"solid\"\n class=\"ax-sm\"\n color=\"primary\"\n [text]=\"('@general:actions.submit.title' | translate | async)!\"\n (onClick)=\"applyDraft(); po.close()\"\n ></ax-button>\n </div>\n </div>\n </ax-popover>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n\n <!-- Upload Button: Upload text file to set QR code content -->\n <!-- <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.upload.title' | translate | async)!\"\n (onClick)=\"fileInput.click()\"\n >\n <input #fileInput type=\"file\" accept=\"text/plain\" class=\"hidden\" (change)=\"onFileSelected($event)\" />\n <ax-icon icon=\"fa-light fa-upload\"></ax-icon>\n </ax-button> -->\n\n <!-- Export Button: Download QR code as image (only shown when value exists) -->\n @if (value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.export.title' | translate | async)!\"\n (onClick)=\"downloadQr(qr)\"\n >\n <ax-icon icon=\"fa-light fa-download\"></ax-icon>\n </ax-button>\n }\n\n <!-- Delete Button: Clear QR code value (only shown when not readonly and value exists) -->\n @if (!readonly() && value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"clearValue()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
15290
- }] });
16017
+ ], host: { class: 'block flex-1' }, template: "<!-- Main Container -->\n<div class=\"flex flex-col gap-3 p-3 w-fit\">\n <div class=\"flex justify-center\">\n <!-- QR Code Container -->\n <div class=\"bg-lightest border border-default rounded-md shadow-md p-3\" #qr>\n <!-- QR image when an attachment is stored; otherwise the generated QR -->\n @if (displayMode() === 'image') {\n <!-- ----- Show the stored image at the widget size without cropping ----- -->\n @if (imageUrl()) {\n <img\n [src]=\"imageUrl()!\"\n [attr.alt]=\"('@platform-layout-widgets:widgets.qrcode.attachment.alt' | translate | async) ?? ''\"\n class=\"object-contain\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n />\n } @else {\n <div\n class=\"flex items-center justify-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n ></div>\n }\n } @else if (value()) {\n <!-- Display QR Code when value exists -->\n <ax-qrcode [content]=\"value()\" [size]=\"size()\" [color]=\"color()\" [level]=\"level()\" [outputType]=\"'svg'\">\n </ax-qrcode>\n } @else {\n <!-- Empty State: Show placeholder when value is null or empty -->\n <div\n class=\"flex flex-col items-center justify-center text-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n >\n <ax-icon icon=\"fa-light fa-qrcode\" class=\"text-4xl text-gray-400 mb-3\"></ax-icon>\n <div class=\"text-sm text-gray-500\">\n {{ '@general:state-message.empty.title' | translate | async }}\n </div>\n </div>\n }\n\n <!-- Action Buttons Section -->\n @if (!readonly() || attachmentConfig().enabled) {\n <div class=\"flex items-center justify-between gap-2 pt-4\">\n <!-- Edit Button: Opens popover to edit QR code content -->\n @if (!readonly()) {\n <ax-button\n #editBtn\n look=\"twotone\"\n [title]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"beginEdit()\"\n >\n <!-- Edit Popover: Text input for editing QR code content -->\n <ax-popover #po [target]=\"editBtn\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div\n class=\"bg-lightest border border-default rounded-md shadow-md p-5 w-full sm:w-96\"\n >\n <!-- Text Input for QR Code Content -->\n <ax-text-box\n [value]=\"draft()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"placeholder() | translate | async\"\n (onValueChanged)=\"onDraftChange($event)\"\n >\n @if (hasClearButton()) {\n <ax-clear-button></ax-clear-button>\n }\n </ax-text-box>\n <!-- Popover Action Buttons -->\n <div class=\"flex justify-end gap-2 mt-3\">\n <ax-button\n look=\"outline\"\n class=\"ax-sm\"\n [text]=\"('@general:actions.cancel.title' | translate | async)!\"\n (onClick)=\"cancelEdit(); po.close()\"\n ></ax-button>\n <ax-button\n look=\"solid\"\n class=\"ax-sm\"\n color=\"primary\"\n [text]=\"('@general:actions.submit.title' | translate | async)!\"\n (onClick)=\"applyDraft(); po.close()\"\n ></ax-button>\n </div>\n </div>\n </ax-popover>\n <ax-icon icon=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n }\n\n <!-- Upload or replace the optional QR image without changing the QR text -->\n @if (attachmentConfig().enabled && !attachmentActionsLocked()) {\n <ax-button\n look=\"twotone\"\n [disabled]=\"choosingAttachment()\"\n [title]=\"\n ((displayMode() === 'image'\n ? '@platform-layout-widgets:widgets.qrcode.attachment.replace'\n : '@platform-layout-widgets:widgets.qrcode.attachment.upload'\n ) | translate | async)!\n \"\n (onClick)=\"chooseAttachment()\"\n >\n <ax-icon [icon]=\"displayMode() === 'image' ? 'fa-light fa-arrows-rotate' : 'fa-light fa-image'\"></ax-icon>\n </ax-button>\n }\n\n <!-- Upload Button: Upload text file to set QR code content -->\n <!-- <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.upload.title' | translate | async)!\"\n (onClick)=\"fileInput.click()\"\n >\n <input #fileInput type=\"file\" accept=\"text/plain\" class=\"hidden\" (change)=\"onFileSelected($event)\" />\n <ax-icon icon=\"fa-light fa-upload\"></ax-icon>\n </ax-button> -->\n\n <!-- Preview and export follow whichever image is currently displayed -->\n @if (displayMode() !== 'empty') {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.export.title' | translate | async)!\"\n (onClick)=\"downloadDisplayed(qr)\"\n >\n <ax-icon icon=\"fa-light fa-download\"></ax-icon>\n </ax-button>\n }\n\n <!-- Remove the attached image and show the generated QR again -->\n @if (attachmentConfig().enabled && !attachmentActionsLocked() && displayMode() === 'image') {\n <ax-button\n look=\"twotone\"\n [title]=\"('@platform-layout-widgets:widgets.qrcode.attachment.remove' | translate | async)!\"\n (onClick)=\"removeAttachment()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-image-slash\"></ax-icon>\n </ax-button>\n }\n\n <!-- Delete Button: Clear QR code value (only shown when not readonly and value exists) -->\n @if (!readonly() && value()) {\n <ax-button\n look=\"twotone\"\n [title]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"clearValue()\"\n >\n <ax-icon icon=\"text-danger fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
16018
+ }], ctorParameters: () => [] });
16019
+ function isAncestorFormLocked(start) {
16020
+ let current = start?.parent;
16021
+ while (current) {
16022
+ if (current.options?.()?.['readonly'] === true) {
16023
+ return true;
16024
+ }
16025
+ current = current.parent;
16026
+ }
16027
+ return false;
16028
+ }
15291
16029
 
15292
16030
  var qrcodeWidgetEdit_component = /*#__PURE__*/Object.freeze({
15293
16031
  __proto__: null,
@@ -15295,12 +16033,15 @@ var qrcodeWidgetEdit_component = /*#__PURE__*/Object.freeze({
15295
16033
  });
15296
16034
 
15297
16035
  class AXPQrcodeWidgetViewComponent extends AXPValueWidgetComponent {
16036
+ //#endregion
16037
+ //#region ---- Lifecycle ----
15298
16038
  constructor() {
15299
- super(...arguments);
16039
+ super();
15300
16040
  //#region ---- Services & Dependencies ----
15301
16041
  this.qrcodeViewer = inject(AXPQrcodeViewerService);
15302
16042
  this.formatService = inject(AXFormatService);
15303
16043
  this.translation = inject(AXTranslationService);
16044
+ this.fileStorage = inject(AXPFileStorageService, { optional: true });
15304
16045
  //#endregion
15305
16046
  //#region ---- View Children ----
15306
16047
  this.qrContainer = viewChild('qrContainer', /* @ts-ignore */
@@ -15317,14 +16058,44 @@ class AXPQrcodeWidgetViewComponent extends AXPValueWidgetComponent {
15317
16058
  ...(ngDevMode ? [{ debugName: "outputType" }] : /* istanbul ignore next */ []));
15318
16059
  this.showContent = computed(() => !!this.options()['showContent'], /* @ts-ignore */
15319
16060
  ...(ngDevMode ? [{ debugName: "showContent" }] : /* istanbul ignore next */ []));
16061
+ this.suppressPreview = computed(() => !!this.options()['suppressPreview'], /* @ts-ignore */
16062
+ ...(ngDevMode ? [{ debugName: "suppressPreview" }] : /* istanbul ignore next */ []));
15320
16063
  this.contentLabel = computed(() => this.options()['contentLabel'] ?? '@platform-layout-widgets:widgets.qrcode.content', /* @ts-ignore */
15321
16064
  ...(ngDevMode ? [{ debugName: "contentLabel" }] : /* istanbul ignore next */ []));
16065
+ this.attachmentConfig = computed(() => resolveQrcodeAttachmentConfig(this.options()), /* @ts-ignore */
16066
+ ...(ngDevMode ? [{ debugName: "attachmentConfig" }] : /* istanbul ignore next */ []));
16067
+ this.attachmentRef = computed(() => {
16068
+ const config = this.attachmentConfig();
16069
+ if (!config.enabled) {
16070
+ return null;
16071
+ }
16072
+ return readQrcodeAttachmentRef(this.contextService.data(), config.dataPath);
16073
+ }, /* @ts-ignore */
16074
+ ...(ngDevMode ? [{ debugName: "attachmentRef" }] : /* istanbul ignore next */ []));
16075
+ this.displayMode = computed(() => resolveQrcodeDisplayMode({
16076
+ enabled: this.attachmentConfig().enabled,
16077
+ attachmentRef: this.attachmentRef(),
16078
+ qrValue: this.getValue(),
16079
+ }), /* @ts-ignore */
16080
+ ...(ngDevMode ? [{ debugName: "displayMode" }] : /* istanbul ignore next */ []));
16081
+ //#endregion
16082
+ //#region ---- State Signals ----
16083
+ this.imageUrl = signal(null, /* @ts-ignore */
16084
+ ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
16085
+ this.blobObjectUrl = null;
16086
+ this.hydrateRequestId = 0;
16087
+ effect(() => {
16088
+ void this.hydrateImageUrl(this.displayMode() === 'image' ? this.attachmentRef() : null);
16089
+ });
16090
+ }
16091
+ ngOnDestroy() {
16092
+ this.revokeBlobUrl();
15322
16093
  }
15323
16094
  //#endregion
15324
16095
  //#region ---- UI Handlers ----
15325
16096
  async openPreview() {
15326
- const content = this.getValue();
15327
- if (!content) {
16097
+ const content = this.getValue() ?? '';
16098
+ if (!content && this.displayMode() !== 'image') {
15328
16099
  return;
15329
16100
  }
15330
16101
  await openQrcodeViewer(this.qrcodeViewer, {
@@ -15333,6 +16104,7 @@ class AXPQrcodeWidgetViewComponent extends AXPValueWidgetComponent {
15333
16104
  widgetOptions: this.options(),
15334
16105
  formatService: this.formatService,
15335
16106
  activeLang: this.translation.getActiveLang(),
16107
+ attachmentRef: this.attachmentRef(),
15336
16108
  });
15337
16109
  }
15338
16110
  //#endregion
@@ -15345,85 +16117,53 @@ class AXPQrcodeWidgetViewComponent extends AXPValueWidgetComponent {
15345
16117
  printGraphicFromElement(container, {
15346
16118
  fallbackSize: this.size(),
15347
16119
  title: 'QR Code',
15348
- imageAlt: 'QR Code',
16120
+ imageAlt: 'QR Image',
15349
16121
  });
15350
16122
  }
15351
16123
  },
15352
16124
  };
15353
16125
  }
15354
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
15355
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetViewComponent, isStandalone: true, selector: "axp-qrcode-widget", host: { classAttribute: "block w-full" }, viewQueries: [{ propertyName: "qrContainer", first: true, predicate: ["qrContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
15356
- @if (getValue()) {
15357
- <div class="flex w-full flex-col items-center gap-4 text-center">
15358
- <div #qrContainer class="inline-block">
15359
- <ax-qrcode
15360
- [content]="getValue()"
15361
- [size]="size()"
15362
- [color]="color()"
15363
- [level]="level()"
15364
- [outputType]="outputType()"
15365
- >
15366
- </ax-qrcode>
15367
- </div>
15368
- @if (showContent()) {
15369
- <div class="flex max-w-full flex-col items-center gap-1">
15370
- <span class="text-sm font-medium">{{ contentLabel() | translate | async }}</span>
15371
- <span class="break-all text-sm">{{ getValue() }}</span>
15372
- </div>
15373
- } @else {
15374
- <ax-button
15375
- look="twotone"
15376
- class="ax-sm"
15377
- [title]="('@general:actions.preview.title' | translate | async)!"
15378
- (onClick)="openPreview()"
15379
- >
15380
- <ax-icon icon="fa-light fa-expand"></ax-icon>
15381
- </ax-button>
16126
+ //#endregion
16127
+ //#region ---- Image Hydration ----
16128
+ async hydrateImageUrl(ref) {
16129
+ const requestId = ++this.hydrateRequestId;
16130
+ this.revokeBlobUrl();
16131
+ if (!ref || !this.fileStorage) {
16132
+ this.imageUrl.set(null);
16133
+ return;
16134
+ }
16135
+ try {
16136
+ const displayUrl = qrcodeAttachmentImageUrl(ref, (fileId) => this.fileStorage.getDownloadUrl(fileId));
16137
+ if (requestId !== this.hydrateRequestId) {
16138
+ if (displayUrl?.startsWith('blob:')) {
16139
+ URL.revokeObjectURL(displayUrl);
16140
+ }
16141
+ return;
16142
+ }
16143
+ if (displayUrl?.startsWith('blob:')) {
16144
+ this.blobObjectUrl = displayUrl;
16145
+ }
16146
+ this.imageUrl.set(displayUrl);
16147
+ }
16148
+ catch {
16149
+ if (requestId === this.hydrateRequestId) {
16150
+ this.imageUrl.set(null);
16151
+ }
16152
+ }
16153
+ }
16154
+ revokeBlobUrl() {
16155
+ if (this.blobObjectUrl) {
16156
+ URL.revokeObjectURL(this.blobObjectUrl);
16157
+ this.blobObjectUrl = null;
15382
16158
  }
15383
- </div>
15384
16159
  }
15385
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXQrcodeModule }, { kind: "component", type: i5$1.AXQrcodeComponent, selector: "ax-qrcode", inputs: ["content", "size", "level", "color", "backgroundColor", "outputType"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$6.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
16160
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16161
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQrcodeWidgetViewComponent, isStandalone: true, selector: "axp-qrcode-widget", host: { classAttribute: "block w-full" }, viewQueries: [{ propertyName: "qrContainer", first: true, predicate: ["qrContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (displayMode() !== 'empty') {\n <div class=\"flex w-full flex-col items-center gap-4 text-center\">\n <div #qrContainer class=\"inline-block\">\n <!-- ----- Attached image replaces the generated QR while a file is stored ----- -->\n @if (displayMode() === 'image') {\n <!-- ----- Show the stored image at the widget size without cropping ----- -->\n @if (imageUrl()) {\n <img\n [src]=\"imageUrl()!\"\n [attr.alt]=\"('@platform-layout-widgets:widgets.qrcode.attachment.alt' | translate | async) ?? ''\"\n class=\"object-contain\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n />\n } @else {\n <div\n class=\"flex items-center justify-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n ></div>\n }\n } @else {\n <ax-qrcode\n [content]=\"getValue()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [level]=\"level()\"\n [outputType]=\"outputType()\"\n >\n </ax-qrcode>\n }\n </div>\n <!-- ----- QR text under the generated code ----- -->\n @if (displayMode() === 'qr' && showContent()) {\n <div class=\"flex max-w-full flex-col items-center gap-1\">\n <span class=\"text-sm font-medium\">{{ contentLabel() | translate | async }}</span>\n <span class=\"break-all text-sm\">{{ getValue() }}</span>\n </div>\n }\n <!-- ----- Preview for the attached image or the generated QR ----- -->\n @else if (!suppressPreview() && (displayMode() === 'image' || !showContent())) {\n <ax-button\n look=\"twotone\"\n class=\"ax-sm\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.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: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXQrcodeModule }, { kind: "component", type: i5$1.AXQrcodeComponent, selector: "ax-qrcode", inputs: ["content", "size", "level", "color", "backgroundColor", "outputType"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$6.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
15386
16162
  }
15387
16163
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQrcodeWidgetViewComponent, decorators: [{
15388
16164
  type: Component,
15389
- args: [{
15390
- selector: 'axp-qrcode-widget',
15391
- template: `
15392
- @if (getValue()) {
15393
- <div class="flex w-full flex-col items-center gap-4 text-center">
15394
- <div #qrContainer class="inline-block">
15395
- <ax-qrcode
15396
- [content]="getValue()"
15397
- [size]="size()"
15398
- [color]="color()"
15399
- [level]="level()"
15400
- [outputType]="outputType()"
15401
- >
15402
- </ax-qrcode>
15403
- </div>
15404
- @if (showContent()) {
15405
- <div class="flex max-w-full flex-col items-center gap-1">
15406
- <span class="text-sm font-medium">{{ contentLabel() | translate | async }}</span>
15407
- <span class="break-all text-sm">{{ getValue() }}</span>
15408
- </div>
15409
- } @else {
15410
- <ax-button
15411
- look="twotone"
15412
- class="ax-sm"
15413
- [title]="('@general:actions.preview.title' | translate | async)!"
15414
- (onClick)="openPreview()"
15415
- >
15416
- <ax-icon icon="fa-light fa-expand"></ax-icon>
15417
- </ax-button>
15418
- }
15419
- </div>
15420
- }
15421
- `,
15422
- changeDetection: ChangeDetectionStrategy.OnPush,
15423
- imports: [AXButtonModule, AXDecoratorModule, AXQrcodeModule, AXTranslationModule, AsyncPipe],
15424
- host: { class: 'block w-full' },
15425
- }]
15426
- }], propDecorators: { qrContainer: [{ type: i0.ViewChild, args: ['qrContainer', { isSignal: true }] }] } });
16165
+ args: [{ selector: 'axp-qrcode-widget', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXButtonModule, AXDecoratorModule, AXQrcodeModule, AXTranslationModule, AsyncPipe], host: { class: 'block w-full' }, template: "@if (displayMode() !== 'empty') {\n <div class=\"flex w-full flex-col items-center gap-4 text-center\">\n <div #qrContainer class=\"inline-block\">\n <!-- ----- Attached image replaces the generated QR while a file is stored ----- -->\n @if (displayMode() === 'image') {\n <!-- ----- Show the stored image at the widget size without cropping ----- -->\n @if (imageUrl()) {\n <img\n [src]=\"imageUrl()!\"\n [attr.alt]=\"('@platform-layout-widgets:widgets.qrcode.attachment.alt' | translate | async) ?? ''\"\n class=\"object-contain\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n />\n } @else {\n <div\n class=\"flex items-center justify-center\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n ></div>\n }\n } @else {\n <ax-qrcode\n [content]=\"getValue()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [level]=\"level()\"\n [outputType]=\"outputType()\"\n >\n </ax-qrcode>\n }\n </div>\n <!-- ----- QR text under the generated code ----- -->\n @if (displayMode() === 'qr' && showContent()) {\n <div class=\"flex max-w-full flex-col items-center gap-1\">\n <span class=\"text-sm font-medium\">{{ contentLabel() | translate | async }}</span>\n <span class=\"break-all text-sm\">{{ getValue() }}</span>\n </div>\n }\n <!-- ----- Preview for the attached image or the generated QR ----- -->\n @else if (!suppressPreview() && (displayMode() === 'image' || !showContent())) {\n <ax-button\n look=\"twotone\"\n class=\"ax-sm\"\n [title]=\"('@general:actions.preview.title' | translate | async)!\"\n (onClick)=\"openPreview()\"\n >\n <ax-icon icon=\"fa-light fa-expand\"></ax-icon>\n </ax-button>\n }\n </div>\n}\n" }]
16166
+ }], ctorParameters: () => [], propDecorators: { qrContainer: [{ type: i0.ViewChild, args: ['qrContainer', { isSignal: true }] }] } });
15427
16167
 
15428
16168
  var qrcodeWidgetView_component = /*#__PURE__*/Object.freeze({
15429
16169
  __proto__: null,
@@ -20056,7 +20796,7 @@ const AXPRepeaterWidget = {
20056
20796
  component: () => Promise.resolve().then(function () { return repeaterWidgetDesigner_component; }).then((c) => c.AXPRepeaterWidgetDesignerComponent),
20057
20797
  },
20058
20798
  column: {
20059
- component: () => import('./acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-Ddx_b04d.mjs').then((c) => c.AXPRepeaterWidgetColumnComponent),
20799
+ component: () => import('./acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-XgjDH9Oc.mjs').then((c) => c.AXPRepeaterWidgetColumnComponent),
20060
20800
  },
20061
20801
  },
20062
20802
  };
@@ -33466,7 +34206,7 @@ const AXPTextBlockWidget = {
33466
34206
  component: () => Promise.resolve().then(function () { return textBlockWidgetView_component; }).then((c) => c.AXPTextBlockWidgetViewComponent),
33467
34207
  },
33468
34208
  designer: {
33469
- component: () => import('./acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DqIuIn76.mjs').then((c) => c.AXPTextBlockWidgetDesignerComponent),
34209
+ component: () => import('./acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DDczHmAA.mjs').then((c) => c.AXPTextBlockWidgetDesignerComponent),
33470
34210
  },
33471
34211
  },
33472
34212
  };
@@ -34250,5 +34990,5 @@ var getWidgetsForAi_query = /*#__PURE__*/Object.freeze({
34250
34990
  * Generated bundle index. Do not edit.
34251
34991
  */
34252
34992
 
34253
- export { AXPConditionClauseWidget as $, AXP_REPEATER_ENTITY_BY_KEY_LOOKUP as A, AXPCallbackValidationWidgetEditComponent as B, AXPCheckBoxWidget as C, AXPCheckBoxWidgetColumnComponent as D, AXPCheckBoxWidgetDesignerComponent as E, AXPCheckBoxWidgetEditComponent as F, AXPCheckBoxWidgetPrintComponent as G, AXPCheckBoxWidgetViewComponent as H, AXPCodeEditorWidget as I, AXPColorBoxWidget as J, AXPColorBoxWidgetColumnComponent as K, AXPColorBoxWidgetDesignerComponent as L, AXPColorBoxWidgetEditComponent as M, AXPColorBoxWidgetViewComponent as N, AXPColorChooserWidget as O, AXPColorChooserWidgetColumnComponent as P, AXPColorChooserWidgetDesignerComponent as Q, AXPColorChooserWidgetEditComponent as R, AXPColorChooserWidgetViewComponent as S, AXPColorPaletteWidget as T, AXPColorPaletteWidgetColumnComponent as U, AXPColorPaletteWidgetDesignerComponent as V, AXPColorPaletteWidgetEditComponent as W, AXPColorPaletteWidgetViewComponent as X, AXPConditionBuilderWidget as Y, AXPConditionBuilderWidgetEditComponent as Z, AXPConditionBuilderWidgetViewComponent as _, textBlockContentClass as a, AXPLargeTextWidgetPrintComponent as a$, AXPConditionClauseWidgetEditComponent as a0, AXPConnectedDragDropListsWidget as a1, AXPConnectedListsWidgetColumnComponent as a2, AXPConnectedListsWidgetEditComponent as a3, AXPConnectedListsWidgetViewComponent as a4, AXPContactWidget as a5, AXPContactWidgetColumnComponent as a6, AXPContactWidgetEditComponent as a7, AXPContactWidgetViewComponent as a8, AXPDataListColumnFooterComponent as a9, AXPFlexWidget as aA, AXPFlexWidgetDesignerComponent as aB, AXPFlexWidgetViewComponent as aC, AXPGetWidgetsForAIQuery as aD, AXPGreaterThanExpressionValidationWidget as aE, AXPGreaterThanValidationWidgetEditComponent as aF, AXPGridItemOptionsWidget as aG, AXPGridItemOptionsWidgetEditComponent as aH, AXPGridOptionsWidget as aI, AXPGridOptionsWidgetEditComponent as aJ, AXPImageMarkerPopupComponent as aK, AXPImageMarkerWidget as aL, AXPImageMarkerWidgetColumnComponent as aM, AXPImageMarkerWidgetEditComponent as aN, AXPImageMarkerWidgetViewComponent as aO, AXPIntegrationConnectionActionsService as aP, AXPIntegrationConnectionsPanelWidget as aQ, AXPIntegrationConnectionsPanelWidgetEditComponent as aR, AXPItemConfiguratorWidget as aS, AXPItemConfiguratorWidgetColumnComponent as aT, AXPItemConfiguratorWidgetEditComponent as aU, AXPJsonViewerWidget as aV, AXPJsonViewerWidgetEditComponent as aW, AXPJsonViewerWidgetViewComponent as aX, AXPLargeTextWidget as aY, AXPLargeTextWidgetColumnComponent as aZ, AXPLargeTextWidgetEditComponent as a_, AXPDataListWidget as aa, AXPDataListWidgetViewComponent as ab, AXPDataSourceOptionsWidget as ac, AXPDataSourceOptionsWidgetEditComponent as ad, AXPDateTimeBoxWidget as ae, AXPDateTimeBoxWidgetColumnComponent as af, AXPDateTimeBoxWidgetEditComponent as ag, AXPDateTimeBoxWidgetViewComponent as ah, AXPDirectionWidget as ai, AXPDirectionWidgetEditComponent as aj, AXPDragDropListWidget as ak, AXPEqualValidationWidget as al, AXPEqualValidationWidgetEditComponent as am, AXPFieldsetWidget as an, AXPFieldsetWidgetDesignerComponent as ao, AXPFieldsetWidgetViewComponent as ap, AXPFileViewerWidget as aq, AXPFileViewerWidgetEditComponent as ar, AXPFileViewerWidgetViewComponent as as, AXPFlexItemOptionsWidget as at, AXPFlexItemOptionsWidgetEditComponent as au, AXPFlexItemWidget as av, AXPFlexItemWidgetDesignerComponent as aw, AXPFlexItemWidgetViewComponent as ax, AXPFlexOptionsWidget as ay, AXPFlexOptionsWidgetEditComponent as az, AXPAdvancedGridItemWidget as b, AXPSelectBoxWidgetColumnComponent as b$, AXPLargeTextWidgetViewComponent as b0, AXPLessThanExpressionValidationWidget as b1, AXPLessThanValidationWidgetEditComponent as b2, AXPListStylingRulesExtendedWidget as b3, AXPListWidgetColumnComponent as b4, AXPListWidgetEditComponent as b5, AXPListWidgetViewComponent as b6, AXPLocalDataSourceSheetWidget as b7, AXPLocalDataSourceSheetWidgetEditComponent as b8, AXPMapWidgetEditComponent as b9, AXPProviderSelectWidgetColumnComponent as bA, AXPProviderSelectWidgetEditBase as bB, AXPProviderSelectWidgetViewComponent as bC, AXPQrcodeViewerService as bD, AXPQrcodeWidget as bE, AXPQrcodeWidgetColumnComponent as bF, AXPQrcodeWidgetEditComponent as bG, AXPQrcodeWidgetViewComponent as bH, AXPRatePickerWidget as bI, AXPRatePickerWidgetColumnComponent as bJ, AXPRatePickerWidgetEditComponent as bK, AXPRatePickerWidgetViewComponent as bL, AXPRegularExpressionValidationWidget as bM, AXPRegularExpressionValidationWidgetEditComponent as bN, AXPRepeaterWidget as bO, AXPRepeaterWidgetDesignerComponent as bP, AXPRepeaterWidgetEditComponent as bQ, AXPRepeaterWidgetViewComponent as bR, AXPRequiredValidationWidget as bS, AXPRequiredValidationWidgetEditComponent as bT, AXPRichTextWidget as bU, AXPRichTextWidgetColumnComponent as bV, AXPRichTextWidgetEditComponent as bW, AXPRichTextWidgetPrintComponent as bX, AXPRichTextWidgetViewComponent as bY, AXPSchedulerPickerWidget as bZ, AXPSelectBoxWidget as b_, AXPMapWidgetViewComponent as ba, AXPMaxLengthExpressionValidationWidget as bb, AXPMaxLengthValidationWidgetEditComponent as bc, AXPMinLengthExpressionValidationWidget as bd, AXPMinLengthValidationWidgetEditComponent as be, AXPNodeRendererWidget as bf, AXPNodeRendererWidgetDesignerComponent as bg, AXPNodeRendererWidgetEditComponent as bh, AXPNodeRendererWidgetViewComponent as bi, AXPNumberBoxWidget as bj, AXPNumberBoxWidgetColumnComponent as bk, AXPNumberBoxWidgetEditComponent as bl, AXPNumberBoxWidgetPrintComponent as bm, AXPNumberBoxWidgetViewComponent as bn, AXPOutcomeResultsViewerWidget as bo, AXPOutcomeResultsViewerWidgetViewComponent as bp, AXPPageWidget as bq, AXPPageWidgetViewComponent as br, AXPPasswordBoxWidget as bs, AXPPasswordBoxWidgetColumnComponent as bt, AXPPasswordBoxWidgetEditComponent as bu, AXPPasswordBoxWidgetViewComponent as bv, AXPProgressBarWidget as bw, AXPProgressBarWidgetColumnComponent as bx, AXPProgressBarWidgetEditComponent as by, AXPProgressBarWidgetViewComponent as bz, AXPAdvancedGridItemWidgetDesignerComponent as c, AXP_Flex_Box_Justify_Options as c$, AXPSelectBoxWidgetEditComponent as c0, AXPSelectBoxWidgetViewComponent as c1, AXPSelectLanguagePopup as c2, AXPSelectionListWidget as c3, AXPSelectionListWidgetColumnComponent as c4, AXPSelectionListWidgetDesignerComponent as c5, AXPSelectionListWidgetEditComponent as c6, AXPSelectionListWidgetViewComponent as c7, AXPSignatureWidget as c8, AXPSignatureWidgetColumnComponent as c9, AXPTemplateBoxWidgetEditComponent as cA, AXPTemplateBoxWidgetPrintComponent as cB, AXPTemplateBoxWidgetViewComponent as cC, AXPTextBoxWidget as cD, AXPTextBoxWidgetColumnComponent as cE, AXPTextBoxWidgetEditComponent as cF, AXPTextBoxWidgetPrintComponent as cG, AXPTextBoxWidgetViewComponent as cH, AXPToggleWidget as cI, AXPToggleWidgetColumnComponent as cJ, AXPToggleWidgetEditComponent as cK, AXPToggleWidgetPrintComponent as cL, AXPToggleWidgetViewComponent as cM, AXPWidgetFieldConfiguratorWidget as cN, AXPWidgetFieldConfiguratorWidgetColumnComponent as cO, AXPWidgetFieldConfiguratorWidgetEditComponent as cP, AXPWidgetsModule as cQ, AXP_ABSOLUTE_UNITS as cR, AXP_BORDER_RADIUS_UNITS as cS, AXP_BORDER_WIDTH_UNITS as cT, AXP_CONDITION_CLAUSE_WIDGET_NAME as cU, AXP_DATA_LIST_CMD_DELETE as cV, AXP_DATA_LIST_CMD_EDIT as cW, AXP_DATA_LIST_PENDING_DELETE_KEY as cX, AXP_DATETIME_FILTER_DEFAULT_OPERATOR as cY, AXP_Flex_Box_Align_Options as cZ, AXP_Flex_Box_Alignments as c_, AXPSignatureWidgetEditComponent as ca, AXPSignatureWidgetViewComponent as cb, AXPSpacingWidget as cc, AXPSpacingWidgetEditComponent as cd, AXPStatusChipComponent as ce, AXPStatusWidget as cf, AXPStatusWidgetColumnComponent as cg, AXPStatusWidgetEditComponent as ch, AXPStatusWidgetViewComponent as ci, AXPStepWizardWidget as cj, AXPStepWizardWidgetDesignerComponent as ck, AXPStepWizardWidgetViewComponent as cl, AXPStopwatchWidget as cm, AXPStopwatchWidgetViewComponent as cn, AXPTableItemWidget as co, AXPTableItemWidgetDesignerComponent as cp, AXPTableItemWidgetViewComponent as cq, AXPTableWidget as cr, AXPTableWidgetDesignerComponent as cs, AXPTableWidgetViewComponent as ct, AXPTagEditorWidget as cu, AXPTagEditorWidgetColumnComponent as cv, AXPTagEditorWidgetEditComponent as cw, AXPTagEditorWidgetViewComponent as cx, AXPTemplateBoxWidget as cy, AXPTemplateBoxWidgetColumnComponent as cz, AXPAdvancedGridItemWidgetViewComponent as d, AXP_Grid_Box_Align_Items_Options as d0, AXP_Grid_Box_Alignments as d1, AXP_Grid_Box_Justify_Items_Options as d2, AXP_LIST_STYLING_RULES_WIDGET_NAME as d3, AXP_LOCAL_DATA_SOURCE_SHEET_WIDGET_NAME as d4, AXP_RELATIVE_UNITS as d5, AXP_RELATIVE_UNITS_NO_PERCENT as d6, AXP_ROW_EXPR_PREFIX as d7, AXP_SELECT_COLUMN_RESOLVE_QUERY as d8, AXP_SELECT_FILTER_DEFAULT_OPERATOR as d9, AXP_SPACING_UNITS as da, AXP_default_Border_Box_Units as db, AXP_default_Border_Box_Value as dc, AXP_default_Spacing_Box_Units as dd, AXP_default_Spacing_Box_Value as de, DEFAULT_QRCODE_SIZE as df, DEFAULT_STRATEGY_CONFIG as dg, STRATEGY_CONFIG_TOKEN as dh, applyLeafVisibilityToDataListColumnTree as di, flattenDataListWidgetColumns as dj, formatConditionBuilderChip as dk, formatConditionBuilderSentence as dl, isDataListColumnBand as dm, prepareNodeRendererChild as dn, resolveColorChooserGroups as dp, resolveDataListColumnWidth as dq, tokensToPlainText as dr, AXPAdvancedGridOptionsWidget as e, AXPAdvancedGridOptionsWidgetEditComponent as f, AXPAdvancedGridWidget as g, AXPAdvancedGridWidgetDesignerComponent as h, AXPAdvancedGridWidgetViewComponent as i, AXPAvatarWidget as j, AXPAvatarWidgetColumnComponent as k, AXPAvatarWidgetDesignerComponent as l, AXPAvatarWidgetEditComponent as m, AXPAvatarWidgetViewComponent as n, AXPBetweenExpressionValidationWidget as o, AXPBetweenValidationWidgetEditComponent as p, AXPBlockWidget as q, AXPBlockWidgetDesignerComponent as r, AXPBlockWidgetViewComponent as s, textBlockStyleAttribute as t, AXPBorderWidget as u, AXPBorderWidgetEditComponent as v, AXPButtonWidget as w, AXPButtonWidgetColumnComponent as x, AXPButtonWidgetViewComponent as y, AXPCallbackValidationWidget as z };
34254
- //# sourceMappingURL=acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DRh91YCL.mjs.map
34993
+ export { AXPConditionClauseWidget as $, AXP_REPEATER_ENTITY_BY_KEY_LOOKUP as A, AXPCallbackValidationWidgetEditComponent as B, AXPCheckBoxWidget as C, AXPCheckBoxWidgetColumnComponent as D, AXPCheckBoxWidgetDesignerComponent as E, AXPCheckBoxWidgetEditComponent as F, AXPCheckBoxWidgetPrintComponent as G, AXPCheckBoxWidgetViewComponent as H, AXPCodeEditorWidget as I, AXPColorBoxWidget as J, AXPColorBoxWidgetColumnComponent as K, AXPColorBoxWidgetDesignerComponent as L, AXPColorBoxWidgetEditComponent as M, AXPColorBoxWidgetViewComponent as N, AXPColorChooserWidget as O, AXPColorChooserWidgetColumnComponent as P, AXPColorChooserWidgetDesignerComponent as Q, AXPColorChooserWidgetEditComponent as R, AXPColorChooserWidgetViewComponent as S, AXPColorPaletteWidget as T, AXPColorPaletteWidgetColumnComponent as U, AXPColorPaletteWidgetDesignerComponent as V, AXPColorPaletteWidgetEditComponent as W, AXPColorPaletteWidgetViewComponent as X, AXPConditionBuilderWidget as Y, AXPConditionBuilderWidgetEditComponent as Z, AXPConditionBuilderWidgetViewComponent as _, textBlockContentClass as a, AXPLargeTextWidgetPrintComponent as a$, AXPConditionClauseWidgetEditComponent as a0, AXPConnectedDragDropListsWidget as a1, AXPConnectedListsWidgetColumnComponent as a2, AXPConnectedListsWidgetEditComponent as a3, AXPConnectedListsWidgetViewComponent as a4, AXPContactWidget as a5, AXPContactWidgetColumnComponent as a6, AXPContactWidgetEditComponent as a7, AXPContactWidgetViewComponent as a8, AXPDataListColumnFooterComponent as a9, AXPFlexWidget as aA, AXPFlexWidgetDesignerComponent as aB, AXPFlexWidgetViewComponent as aC, AXPGetWidgetsForAIQuery as aD, AXPGreaterThanExpressionValidationWidget as aE, AXPGreaterThanValidationWidgetEditComponent as aF, AXPGridItemOptionsWidget as aG, AXPGridItemOptionsWidgetEditComponent as aH, AXPGridOptionsWidget as aI, AXPGridOptionsWidgetEditComponent as aJ, AXPImageMarkerPopupComponent as aK, AXPImageMarkerWidget as aL, AXPImageMarkerWidgetColumnComponent as aM, AXPImageMarkerWidgetEditComponent as aN, AXPImageMarkerWidgetViewComponent as aO, AXPIntegrationConnectionActionsService as aP, AXPIntegrationConnectionsPanelWidget as aQ, AXPIntegrationConnectionsPanelWidgetEditComponent as aR, AXPItemConfiguratorWidget as aS, AXPItemConfiguratorWidgetColumnComponent as aT, AXPItemConfiguratorWidgetEditComponent as aU, AXPJsonViewerWidget as aV, AXPJsonViewerWidgetEditComponent as aW, AXPJsonViewerWidgetViewComponent as aX, AXPLargeTextWidget as aY, AXPLargeTextWidgetColumnComponent as aZ, AXPLargeTextWidgetEditComponent as a_, AXPDataListWidget as aa, AXPDataListWidgetViewComponent as ab, AXPDataSourceOptionsWidget as ac, AXPDataSourceOptionsWidgetEditComponent as ad, AXPDateTimeBoxWidget as ae, AXPDateTimeBoxWidgetColumnComponent as af, AXPDateTimeBoxWidgetEditComponent as ag, AXPDateTimeBoxWidgetViewComponent as ah, AXPDirectionWidget as ai, AXPDirectionWidgetEditComponent as aj, AXPDragDropListWidget as ak, AXPEqualValidationWidget as al, AXPEqualValidationWidgetEditComponent as am, AXPFieldsetWidget as an, AXPFieldsetWidgetDesignerComponent as ao, AXPFieldsetWidgetViewComponent as ap, AXPFileViewerWidget as aq, AXPFileViewerWidgetEditComponent as ar, AXPFileViewerWidgetViewComponent as as, AXPFlexItemOptionsWidget as at, AXPFlexItemOptionsWidgetEditComponent as au, AXPFlexItemWidget as av, AXPFlexItemWidgetDesignerComponent as aw, AXPFlexItemWidgetViewComponent as ax, AXPFlexOptionsWidget as ay, AXPFlexOptionsWidgetEditComponent as az, AXPAdvancedGridItemWidget as b, AXPSelectBoxWidgetColumnComponent as b$, AXPLargeTextWidgetViewComponent as b0, AXPLessThanExpressionValidationWidget as b1, AXPLessThanValidationWidgetEditComponent as b2, AXPListStylingRulesExtendedWidget as b3, AXPListWidgetColumnComponent as b4, AXPListWidgetEditComponent as b5, AXPListWidgetViewComponent as b6, AXPLocalDataSourceSheetWidget as b7, AXPLocalDataSourceSheetWidgetEditComponent as b8, AXPMapWidgetEditComponent as b9, AXPProviderSelectWidgetColumnComponent as bA, AXPProviderSelectWidgetEditBase as bB, AXPProviderSelectWidgetViewComponent as bC, AXPQrcodeViewerService as bD, AXPQrcodeWidget as bE, AXPQrcodeWidgetColumnComponent as bF, AXPQrcodeWidgetEditComponent as bG, AXPQrcodeWidgetViewComponent as bH, AXPRatePickerWidget as bI, AXPRatePickerWidgetColumnComponent as bJ, AXPRatePickerWidgetEditComponent as bK, AXPRatePickerWidgetViewComponent as bL, AXPRegularExpressionValidationWidget as bM, AXPRegularExpressionValidationWidgetEditComponent as bN, AXPRepeaterWidget as bO, AXPRepeaterWidgetDesignerComponent as bP, AXPRepeaterWidgetEditComponent as bQ, AXPRepeaterWidgetViewComponent as bR, AXPRequiredValidationWidget as bS, AXPRequiredValidationWidgetEditComponent as bT, AXPRichTextWidget as bU, AXPRichTextWidgetColumnComponent as bV, AXPRichTextWidgetEditComponent as bW, AXPRichTextWidgetPrintComponent as bX, AXPRichTextWidgetViewComponent as bY, AXPSchedulerPickerWidget as bZ, AXPSelectBoxWidget as b_, AXPMapWidgetViewComponent as ba, AXPMaxLengthExpressionValidationWidget as bb, AXPMaxLengthValidationWidgetEditComponent as bc, AXPMinLengthExpressionValidationWidget as bd, AXPMinLengthValidationWidgetEditComponent as be, AXPNodeRendererWidget as bf, AXPNodeRendererWidgetDesignerComponent as bg, AXPNodeRendererWidgetEditComponent as bh, AXPNodeRendererWidgetViewComponent as bi, AXPNumberBoxWidget as bj, AXPNumberBoxWidgetColumnComponent as bk, AXPNumberBoxWidgetEditComponent as bl, AXPNumberBoxWidgetPrintComponent as bm, AXPNumberBoxWidgetViewComponent as bn, AXPOutcomeResultsViewerWidget as bo, AXPOutcomeResultsViewerWidgetViewComponent as bp, AXPPageWidget as bq, AXPPageWidgetViewComponent as br, AXPPasswordBoxWidget as bs, AXPPasswordBoxWidgetColumnComponent as bt, AXPPasswordBoxWidgetEditComponent as bu, AXPPasswordBoxWidgetViewComponent as bv, AXPProgressBarWidget as bw, AXPProgressBarWidgetColumnComponent as bx, AXPProgressBarWidgetEditComponent as by, AXPProgressBarWidgetViewComponent as bz, AXPAdvancedGridItemWidgetDesignerComponent as c, AXP_Flex_Box_Justify_Options as c$, AXPSelectBoxWidgetEditComponent as c0, AXPSelectBoxWidgetViewComponent as c1, AXPSelectLanguagePopup as c2, AXPSelectionListWidget as c3, AXPSelectionListWidgetColumnComponent as c4, AXPSelectionListWidgetDesignerComponent as c5, AXPSelectionListWidgetEditComponent as c6, AXPSelectionListWidgetViewComponent as c7, AXPSignatureWidget as c8, AXPSignatureWidgetColumnComponent as c9, AXPTemplateBoxWidgetEditComponent as cA, AXPTemplateBoxWidgetPrintComponent as cB, AXPTemplateBoxWidgetViewComponent as cC, AXPTextBoxWidget as cD, AXPTextBoxWidgetColumnComponent as cE, AXPTextBoxWidgetEditComponent as cF, AXPTextBoxWidgetPrintComponent as cG, AXPTextBoxWidgetViewComponent as cH, AXPToggleWidget as cI, AXPToggleWidgetColumnComponent as cJ, AXPToggleWidgetEditComponent as cK, AXPToggleWidgetPrintComponent as cL, AXPToggleWidgetViewComponent as cM, AXPWidgetFieldConfiguratorWidget as cN, AXPWidgetFieldConfiguratorWidgetColumnComponent as cO, AXPWidgetFieldConfiguratorWidgetEditComponent as cP, AXPWidgetsModule as cQ, AXP_ABSOLUTE_UNITS as cR, AXP_BORDER_RADIUS_UNITS as cS, AXP_BORDER_WIDTH_UNITS as cT, AXP_CONDITION_CLAUSE_WIDGET_NAME as cU, AXP_DATA_LIST_CMD_DELETE as cV, AXP_DATA_LIST_CMD_EDIT as cW, AXP_DATA_LIST_PENDING_DELETE_KEY as cX, AXP_DATETIME_FILTER_DEFAULT_OPERATOR as cY, AXP_Flex_Box_Align_Options as cZ, AXP_Flex_Box_Alignments as c_, AXPSignatureWidgetEditComponent as ca, AXPSignatureWidgetViewComponent as cb, AXPSpacingWidget as cc, AXPSpacingWidgetEditComponent as cd, AXPStatusChipComponent as ce, AXPStatusWidget as cf, AXPStatusWidgetColumnComponent as cg, AXPStatusWidgetEditComponent as ch, AXPStatusWidgetViewComponent as ci, AXPStepWizardWidget as cj, AXPStepWizardWidgetDesignerComponent as ck, AXPStepWizardWidgetViewComponent as cl, AXPStopwatchWidget as cm, AXPStopwatchWidgetViewComponent as cn, AXPTableItemWidget as co, AXPTableItemWidgetDesignerComponent as cp, AXPTableItemWidgetViewComponent as cq, AXPTableWidget as cr, AXPTableWidgetDesignerComponent as cs, AXPTableWidgetViewComponent as ct, AXPTagEditorWidget as cu, AXPTagEditorWidgetColumnComponent as cv, AXPTagEditorWidgetEditComponent as cw, AXPTagEditorWidgetViewComponent as cx, AXPTemplateBoxWidget as cy, AXPTemplateBoxWidgetColumnComponent as cz, AXPAdvancedGridItemWidgetViewComponent as d, AXP_Grid_Box_Align_Items_Options as d0, AXP_Grid_Box_Alignments as d1, AXP_Grid_Box_Justify_Items_Options as d2, AXP_LIST_STYLING_RULES_WIDGET_NAME as d3, AXP_LOCAL_DATA_SOURCE_SHEET_WIDGET_NAME as d4, AXP_RELATIVE_UNITS as d5, AXP_RELATIVE_UNITS_NO_PERCENT as d6, AXP_ROW_EXPR_PREFIX as d7, AXP_SELECT_COLUMN_RESOLVE_QUERY as d8, AXP_SELECT_FILTER_DEFAULT_OPERATOR as d9, AXP_SPACING_UNITS as da, AXP_default_Border_Box_Units as db, AXP_default_Border_Box_Value as dc, AXP_default_Spacing_Box_Units as dd, AXP_default_Spacing_Box_Value as de, DEFAULT_QRCODE_SIZE as df, DEFAULT_STRATEGY_CONFIG as dg, STRATEGY_CONFIG_TOKEN as dh, applyLeafVisibilityToDataListColumnTree as di, displayQrcodeAttachmentFileId as dj, flattenDataListWidgetColumns as dk, formatConditionBuilderChip as dl, formatConditionBuilderSentence as dm, isDataListColumnBand as dn, prepareNodeRendererChild as dp, qrcodeAttachmentImageUrl as dq, resolveColorChooserGroups as dr, resolveDataListColumnWidth as ds, resolveQrcodeDisplayMode as dt, tokensToPlainText as du, AXPAdvancedGridOptionsWidget as e, AXPAdvancedGridOptionsWidgetEditComponent as f, AXPAdvancedGridWidget as g, AXPAdvancedGridWidgetDesignerComponent as h, AXPAdvancedGridWidgetViewComponent as i, AXPAvatarWidget as j, AXPAvatarWidgetColumnComponent as k, AXPAvatarWidgetDesignerComponent as l, AXPAvatarWidgetEditComponent as m, AXPAvatarWidgetViewComponent as n, AXPBetweenExpressionValidationWidget as o, AXPBetweenValidationWidgetEditComponent as p, AXPBlockWidget as q, AXPBlockWidgetDesignerComponent as r, AXPBlockWidgetViewComponent as s, textBlockStyleAttribute as t, AXPBorderWidget as u, AXPBorderWidgetEditComponent as v, AXPButtonWidget as w, AXPButtonWidgetColumnComponent as x, AXPButtonWidgetViewComponent as y, AXPCallbackValidationWidget as z };
34994
+ //# sourceMappingURL=acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CpmGqDUE.mjs.map