@acorex/platform 21.0.0-next.90 → 21.0.0-next.91

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 (52) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +1 -1
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-common-common-settings.provider-DilV4dql.mjs.map +1 -1
  4. package/fesm2022/acorex-platform-common.mjs +3 -10
  5. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  6. package/fesm2022/acorex-platform-contracts.mjs +1736 -27
  7. package/fesm2022/acorex-platform-contracts.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-core.mjs +6 -1708
  9. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-domain-contracts.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-layout-components.mjs +2 -2
  13. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-layout-entity-contracts.mjs +27 -1
  17. package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-entity.mjs +263 -115
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +4 -2
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs +87 -11
  24. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  25. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -1
  26. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs.map +1 -1
  27. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-BvFykMTH.mjs.map +1 -1
  28. package/fesm2022/acorex-platform-layout-widgets.mjs +2 -4
  29. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  30. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  31. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs.map +1 -1
  33. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  35. package/fesm2022/{acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs → acorex-platform-themes-shared-settings.provider-DxtfyNGS.mjs} +2 -2
  36. package/fesm2022/acorex-platform-themes-shared-settings.provider-DxtfyNGS.mjs.map +1 -0
  37. package/fesm2022/acorex-platform-themes-shared.mjs +2 -2
  38. package/fesm2022/acorex-platform-workflow.mjs +2 -2
  39. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/types/acorex-platform-common.d.ts +3 -5
  42. package/types/acorex-platform-contracts.d.ts +862 -7
  43. package/types/acorex-platform-core.d.ts +64 -921
  44. package/types/acorex-platform-layout-builder.d.ts +3 -3
  45. package/types/acorex-platform-layout-components.d.ts +6 -6
  46. package/types/acorex-platform-layout-designer.d.ts +4 -5
  47. package/types/acorex-platform-layout-entity-contracts.d.ts +90 -3
  48. package/types/acorex-platform-layout-entity.d.ts +45 -102
  49. package/types/acorex-platform-layout-views.d.ts +13 -11
  50. package/types/acorex-platform-layout-widget-core.d.ts +83 -77
  51. package/types/acorex-platform-layout-widgets.d.ts +9 -8
  52. package/fesm2022/acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs.map +0 -1
@@ -1,21 +1,20 @@
1
- import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
1
+ import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, resolveLookupWidgetCreateOptions, AXPEntityQueryType, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
2
2
  export * from '@acorex/platform/layout/entity-contracts';
3
3
  export { collectNestedCreateHiddenProperties, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, mergeForeignKeyFieldIntoCreateActions } from '@acorex/platform/layout/entity-contracts';
4
4
  import { AXToastService } from '@acorex/components/toast';
5
5
  import * as i3$1 from '@acorex/core/translation';
6
6
  import { AXTranslationService, resolveMultiLanguageString, AXTranslationModule, translateSync } from '@acorex/core/translation';
7
7
  import * as i4$2 from '@acorex/platform/common';
8
- import { AXPNotFoundError, AXPEntityCommandScope, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, AXPRefreshEvent, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPReloadEvent, axpRedirectToNotFound, AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE, AXPCleanNestedFilters, AXPFileTypeProviderService, AXPFileStorageService, resolveEntityRowDisplayTitle, AXPFileActionsService, axpIsEntityRecordNotFound, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, AXPEntityQueryType, AXPWorkflowNavigateAction, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXPMenuItemsDataSourceDefinition } from '@acorex/platform/common';
8
+ import { AXPNotFoundError, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, AXPRefreshEvent, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, AXPReloadEvent, axpRedirectToNotFound, AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE, AXPCleanNestedFilters, AXPFileTypeProviderService, AXPFileStorageService, resolveEntityRowDisplayTitle, AXPFileActionsService, axpIsEntityRecordNotFound, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, AXPWorkflowNavigateAction, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXPMenuItemsDataSourceDefinition } from '@acorex/platform/common';
9
9
  import * as i1$3 from '@acorex/platform/workflow';
10
10
  import { AXPWorkflowEventService, AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
11
11
  import * as i0 from '@angular/core';
12
12
  import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, ChangeDetectorRef, input, signal, computed, effect, ChangeDetectionStrategy, Component, ElementRef, NgModule, viewChild, Input, afterNextRender, untracked, ViewEncapsulation, viewChildren, linkedSignal, HostBinding, output, EnvironmentInjector, makeEnvironmentProviders } from '@angular/core';
13
- import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual as isEqual$1, isObjectLike, isArray, has, isString } from 'lodash-es';
13
+ import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual, isObjectLike, isArray, has, isString } from 'lodash-es';
14
14
  import { Subject, filter, takeUntil } from 'rxjs';
15
+ import { AXPWidgetsCatalog, resolveActionLook, AXPPlatformScope, extractValue, setSmart, getChangedPaths, isSelectionValueEqual, AXPDataGenerator, AXPSystemActionType } from '@acorex/platform/contracts';
15
16
  import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex/platform/layout/builder';
16
- import { AXPWidgetsCatalog, AXPPlatformScope, AXPDataGenerator, AXPSystemActionType } from '@acorex/platform/contracts';
17
- import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXHighlightService, extractValue, setSmart, getChangedPaths, AXPContextStore, isSelectionValueEqual, AXPDebugService, FORM_DIRTY_TRACE_NS, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPHookService, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
18
- import { transform, isEqual } from 'lodash';
17
+ import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, AXPDistributedEventListenerService, AXHighlightService, AXPDebugService, AXPContextStore, FORM_DIRTY_TRACE_NS, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPHookService, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
19
18
  import { AXPSessionService, AXPPermissionDefinitionsDataSourceDefinition } from '@acorex/platform/auth';
20
19
  import { Router, NavigationStart, ActivatedRoute, RouterModule, ROUTES } from '@angular/router';
21
20
  import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_ENTITY, AXPCommandService, AXPQueryService, AXPQueryExecutor, AXPCommandExecutor, provideCommandSetups, provideQuerySetups, AXPCommandRegistry, AXPQueryRegistry } from '@acorex/platform/runtime';
@@ -25,7 +24,7 @@ import { AXButtonModule } from '@acorex/components/button';
25
24
  import * as i3 from '@acorex/components/skeleton';
26
25
  import { AXSkeletonModule } from '@acorex/components/skeleton';
27
26
  import * as i2 from '@acorex/platform/layout/widget-core';
28
- import { AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, createBooleanProperty, AXPWidgetRendererDirective, AXPBaseWidgetComponent, AXPWidgetStatus, createStringProperty, createNumberProperty, AXP_WIDGETS_ADVANCE_SUB_MEDIA, AXP_WIDGETS_ADVANCE_CATEGORY, createSelectProperty, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
27
+ import { AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, createBooleanProperty, AXPWidgetRendererDirective, AXPBaseWidgetComponent, AXPWidgetStatus, WIDGET_CASCADE_TRACE_NS, createStringProperty, createNumberProperty, AXP_WIDGETS_ADVANCE_SUB_MEDIA, AXP_WIDGETS_ADVANCE_CATEGORY, createSelectProperty, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
29
28
  import * as i5 from '@angular/common';
30
29
  import { CommonModule, DOCUMENT, AsyncPipe, NgClass } from '@angular/common';
31
30
  import { AXOverlayService } from '@acorex/cdk/overlay';
@@ -79,6 +78,7 @@ import { AXUploaderZoneDirective } from '@acorex/cdk/uploader';
79
78
  import { AXUploaderModule } from '@acorex/components/uploader';
80
79
  import * as i4$1 from '@acorex/components/collapse';
81
80
  import { AXCollapseModule } from '@acorex/components/collapse';
81
+ import { transform, isEqual as isEqual$1 } from 'lodash';
82
82
 
83
83
  function ensureListActions(ctx) {
84
84
  ctx.interfaces.update((i) => {
@@ -872,39 +872,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
872
872
  }]
873
873
  }] });
874
874
 
875
- /**
876
- * Computes a diff between two plain objects with array-aware semantics.
877
- * - For arrays of objects with an id field, computes added/removed by id.
878
- * - For arrays of primitives or objects without id, uses deep equality.
879
- * - For scalars/objects, reports oldValue/newValue when changed.
880
- */
881
- function detectEntityChanges(oldObj, newObj) {
882
- return transform(newObj, (result, value, key) => {
883
- if (!isEqual(value, oldObj[key])) {
884
- const oldValue = oldObj[key];
885
- if (Array.isArray(value) || Array.isArray(oldValue)) {
886
- const oldArray = Array.isArray(oldValue) ? oldValue : [];
887
- const newArray = Array.isArray(value) ? value : [];
888
- const hasId = newArray.length > 0 && typeof newArray[0] === 'object' && newArray[0] !== null && 'id' in newArray[0];
889
- if (hasId) {
890
- const added = newArray.filter((item) => !oldArray.some((oldItem) => oldItem.id === item.id));
891
- const removed = oldArray.filter((item) => !newArray.some((newItem) => newItem.id === item.id));
892
- result[key] = { oldValue, newValue: value, added, removed };
893
- }
894
- else {
895
- const added = newArray.filter((item) => !oldArray.some((oldItem) => isEqual(item, oldItem)));
896
- const removed = oldArray.filter((item) => !newArray.some((newItem) => isEqual(item, newItem)));
897
- result[key] = { oldValue, newValue: value, added, removed };
898
- }
899
- }
900
- else {
901
- result[key] = { oldValue, newValue: value };
902
- }
903
- }
904
- }, {});
905
- }
906
- //#endregion
907
-
908
875
  /**
909
876
  * Maps entity property `description` (or any i18n key / multi-language payload) to `form-field`
910
877
  * widget options. Returns `undefined` when there is nothing to show.
@@ -4234,7 +4201,6 @@ class AXPEntitiesListDataSourceDefinition {
4234
4201
  }
4235
4202
  }
4236
4203
 
4237
- //#region ---- Imports ----
4238
4204
  //#endregion
4239
4205
  //#region ---- Constants ----
4240
4206
  const DEFAULT_RELATED_ORDER_STEP = 10;
@@ -12838,7 +12804,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
12838
12804
  async reapplyScopedFiltersToDataSource() {
12839
12805
  const merged = this.getMergedToolbarFilters();
12840
12806
  const current = this.getValue();
12841
- if (!isEqual$1(current?.toolbar?.filters, merged)) {
12807
+ if (!isEqual(current?.toolbar?.filters, merged)) {
12842
12808
  this.setValue({
12843
12809
  ...current,
12844
12810
  toolbar: { ...(current?.toolbar ?? {}), filters: merged },
@@ -12885,7 +12851,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
12885
12851
  return;
12886
12852
  }
12887
12853
  const current = this.getValue();
12888
- if (isEqual$1(current?.toolbar?.filters, filters)) {
12854
+ if (isEqual(current?.toolbar?.filters, filters)) {
12889
12855
  return;
12890
12856
  }
12891
12857
  this.setValue({
@@ -13982,31 +13948,6 @@ function compactLookupCreateContext(data) {
13982
13948
  }
13983
13949
  //#endregion
13984
13950
 
13985
- //#endregion
13986
- //#region ---- Resolution ----
13987
- /**
13988
- * Resolves lookup create options from `create` and legacy `allowCreate` (mode).
13989
- */
13990
- function resolveLookupWidgetCreateOptions(options) {
13991
- const create = options.create;
13992
- const legacyMode = options.allowCreate;
13993
- const context = create?.context;
13994
- if (create?.enable !== undefined) {
13995
- if (!create.enable) {
13996
- return { enabled: false, mode: 'none', context };
13997
- }
13998
- const mode = legacyMode && legacyMode !== 'none' ? legacyMode : 'quick';
13999
- return { enabled: true, mode, context };
14000
- }
14001
- const mode = legacyMode ?? 'none';
14002
- return {
14003
- enabled: mode !== 'none',
14004
- mode,
14005
- context,
14006
- };
14007
- }
14008
- //#endregion
14009
-
14010
13951
  //#endregion
14011
13952
  class AXPEntityDataSelectorRowActionsService {
14012
13953
  constructor() {
@@ -15019,10 +14960,20 @@ class AXPLookupWidgetSelectComponent extends LookupWidgetLookBase {
15019
14960
  }
15020
14961
  //#endregion
15021
14962
  clear() {
14963
+ AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-select', 'clear() — value cleared', () => ({
14964
+ entity: this.entityDef()()?.name,
14965
+ }));
15022
14966
  this.valueChanged.emit(null);
15023
14967
  }
15024
14968
  refresh() {
15025
- this.clear();
14969
+ AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-select', 'refresh()', () => ({
14970
+ entity: this.entityDef()()?.name,
14971
+ filter: this.customFilter()(),
14972
+ hasSelection: !isEmpty(this.selectedItemsValue()),
14973
+ }));
14974
+ if (!isEmpty(this.selectedItemsValue())) {
14975
+ this.clear();
14976
+ }
15026
14977
  this.dataSource()?.refresh();
15027
14978
  }
15028
14979
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
@@ -15604,7 +15555,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
15604
15555
  const prevValue = this.previousValue();
15605
15556
  const isInitialized = this.initialized();
15606
15557
  // Check if value has actually changed
15607
- const valueChanged = !isEqual$1(currentValue, prevValue);
15558
+ const valueChanged = !isEqual(currentValue, prevValue);
15608
15559
  // Determine if we should update:
15609
15560
  // 1. First initialization with a value
15610
15561
  // 2. Value becomes empty after initialization
@@ -15880,6 +15831,12 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
15880
15831
  }
15881
15832
  //#region ---- Component Methods ----
15882
15833
  refresh() {
15834
+ AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-widget', 'refresh()', () => ({
15835
+ path: this.fullPath(),
15836
+ entity: this.entity(),
15837
+ look: this.look(),
15838
+ customerPartyId: this.contextService.getValue('customer.partyId'),
15839
+ }));
15883
15840
  this.componentLook()?.refresh();
15884
15841
  }
15885
15842
  clear() {
@@ -16945,8 +16902,6 @@ const AXPLookupWidget = {
16945
16902
  },
16946
16903
  };
16947
16904
 
16948
- //#endregion
16949
-
16950
16905
  /**
16951
16906
  * Source type
16952
16907
  */
@@ -19012,7 +18967,7 @@ class AXPFileListComponent {
19012
18967
  return action.color ?? 'primary';
19013
18968
  }
19014
18969
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
19015
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileListComponent, isStandalone: true, selector: "axp-file-list", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fileEditable: { classPropertyName: "fileEditable", publicName: "fileEditable", isSignal: true, isRequired: false, transformFunction: null }, enableTitleDescription: { classPropertyName: "enableTitleDescription", publicName: "enableTitleDescription", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, titleKey: { classPropertyName: "titleKey", publicName: "titleKey", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, linksLayout: { classPropertyName: "linksLayout", publicName: "linksLayout", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null }, excludePlugins: { classPropertyName: "excludePlugins", publicName: "excludePlugins", isSignal: true, isRequired: false, transformFunction: null }, capabilities: { classPropertyName: "capabilities", publicName: "capabilities", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRemove: "onRemove", onRevert: "onRevert", onRename: "onRename" }, host: { properties: { "class.--look-rows": "look() === \"rows\"", "class.--look-links": "look() === \"links\"", "class.--links-inline": "look() === \"links\" && linksLayout() === \"inline\"" } }, providers: [], ngImport: i0, template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{cursor:pointer;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type:
18970
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileListComponent, isStandalone: true, selector: "axp-file-list", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fileEditable: { classPropertyName: "fileEditable", publicName: "fileEditable", isSignal: true, isRequired: false, transformFunction: null }, enableTitleDescription: { classPropertyName: "enableTitleDescription", publicName: "enableTitleDescription", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, titleKey: { classPropertyName: "titleKey", publicName: "titleKey", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, linksLayout: { classPropertyName: "linksLayout", publicName: "linksLayout", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null }, excludePlugins: { classPropertyName: "excludePlugins", publicName: "excludePlugins", isSignal: true, isRequired: false, transformFunction: null }, capabilities: { classPropertyName: "capabilities", publicName: "capabilities", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRemove: "onRemove", onRevert: "onRevert", onRename: "onRename" }, host: { properties: { "class.--look-rows": "look() === \"rows\"", "class.--look-links": "look() === \"links\"", "class.--links-inline": "look() === \"links\" && linksLayout() === \"inline\"" } }, providers: [], ngImport: i0, template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n } @else {\n <div class=\"__empty-state __empty-state--links\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n look=\"minimal\"\n />\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}.__empty-state--links{padding-top:.5rem;padding-bottom:.5rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type:
19016
18971
  // ACoreX
19017
18972
  AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
19018
18973
  // Platform
@@ -19040,7 +18995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
19040
18995
  AXTranslationModule,
19041
18996
  // Platform
19042
18997
  AXPStateMessageComponent,
19043
- ], providers: [], template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{cursor:pointer;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}\n"] }]
18998
+ ], providers: [], template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n } @else {\n <div class=\"__empty-state __empty-state--links\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n look=\"minimal\"\n />\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}.__empty-state--links{padding-top:.5rem;padding-bottom:.5rem}\n"] }]
19044
18999
  }], propDecorators: { onRemove: [{ type: i0.Output, args: ["onRemove"] }], onRevert: [{ type: i0.Output, args: ["onRevert"] }], onRename: [{ type: i0.Output, args: ["onRename"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], fileEditable: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileEditable", required: false }] }], enableTitleDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableTitleDescription", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], titleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleKey", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], linksLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "linksLayout", required: false }] }], files: [{ type: i0.Input, args: [{ isSignal: true, alias: "files", required: false }] }], plugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "plugins", required: false }] }], excludePlugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludePlugins", required: false }] }], capabilities: [{ type: i0.Input, args: [{ isSignal: true, alias: "capabilities", required: false }] }] } });
19045
19000
 
19046
19001
  //#region ---- Attachment fingerprint (no blob comparison) ----
@@ -19123,6 +19078,9 @@ function persistedAttachments(value) {
19123
19078
  }
19124
19079
  //#endregion
19125
19080
 
19081
+ const FILE_PREFIX = 'file:';
19082
+ const DOCUMENT_PREFIX = 'document:';
19083
+ const REFERENCE_PREFIX = 'reference:';
19126
19084
  //#endregion
19127
19085
  //#region ---- Helpers ----
19128
19086
  function isFileListItem(value) {
@@ -19180,6 +19138,120 @@ function attachmentFieldCount(fieldValue) {
19180
19138
  function normalizeEntityFieldToFileList(fieldValue) {
19181
19139
  return parseAttachmentFieldEntries(fieldValue).filter(isFileListItem);
19182
19140
  }
19141
+ /** Whether a stored value is a persisted file/document/reference token. */
19142
+ function isAttachmentStorageRef(value) {
19143
+ return (isString(value) &&
19144
+ (value.startsWith(FILE_PREFIX) ||
19145
+ value.startsWith(DOCUMENT_PREFIX) ||
19146
+ value.startsWith(REFERENCE_PREFIX)));
19147
+ }
19148
+ /** True when the field has entries that cannot be shown without hydration (e.g. mixed `file:` refs + objects). */
19149
+ function attachmentNeedsHydration(fieldValue) {
19150
+ const entries = parseAttachmentFieldEntries(fieldValue);
19151
+ const count = entries.filter(isAttachmentListEntry).length;
19152
+ if (count === 0) {
19153
+ return false;
19154
+ }
19155
+ const normalizedCount = entries.filter(isFileListItem).length;
19156
+ if (normalizedCount < count) {
19157
+ return true;
19158
+ }
19159
+ return entries.some(isAttachmentStorageRef);
19160
+ }
19161
+ function removeFilePrefix(prefixedId) {
19162
+ return prefixedId.startsWith(FILE_PREFIX) ? prefixedId.substring(FILE_PREFIX.length) : prefixedId;
19163
+ }
19164
+ function storageInfoToFileListItem(info) {
19165
+ const item = {
19166
+ id: info.fileId,
19167
+ name: info.name || 'Unknown',
19168
+ size: info.size,
19169
+ status: 'uploaded',
19170
+ source: { kind: 'fileId', value: info.fileId },
19171
+ };
19172
+ if (info.title !== undefined) {
19173
+ item.title = info.title;
19174
+ }
19175
+ if (info.description !== undefined) {
19176
+ item.description = info.description;
19177
+ }
19178
+ if (info.readOnly === true) {
19179
+ item.readOnly = true;
19180
+ }
19181
+ return item;
19182
+ }
19183
+ /**
19184
+ * Resolves inline attachment field values to displayable file list items.
19185
+ * Handles mixed arrays of `file:` refs and already-hydrated AXPFileListItem objects.
19186
+ */
19187
+ async function hydrateAttachmentFieldToFileList(fieldValue, fileStorage) {
19188
+ const entries = parseAttachmentFieldEntries(fieldValue).filter(isAttachmentListEntry);
19189
+ if (entries.length === 0) {
19190
+ return [];
19191
+ }
19192
+ const fileIds = entries
19193
+ .filter(isAttachmentStorageRef)
19194
+ .filter((ref) => ref.startsWith(FILE_PREFIX))
19195
+ .map(removeFilePrefix);
19196
+ const infoMap = new Map();
19197
+ if (fileIds.length > 0) {
19198
+ const infos = await fileStorage.findMany(fileIds);
19199
+ for (const info of infos) {
19200
+ infoMap.set(info.fileId, info);
19201
+ }
19202
+ }
19203
+ const result = [];
19204
+ for (const entry of entries) {
19205
+ if (isFileListItem(entry)) {
19206
+ result.push(entry);
19207
+ continue;
19208
+ }
19209
+ if (isAttachmentStorageRef(entry) && entry.startsWith(FILE_PREFIX)) {
19210
+ const id = removeFilePrefix(entry);
19211
+ const info = infoMap.get(id);
19212
+ if (info) {
19213
+ result.push(storageInfoToFileListItem(info));
19214
+ }
19215
+ else {
19216
+ result.push({
19217
+ id,
19218
+ name: 'Unknown File',
19219
+ status: 'remote',
19220
+ source: { kind: 'fileId', value: id },
19221
+ });
19222
+ }
19223
+ continue;
19224
+ }
19225
+ if (isAttachmentStorageRef(entry)) {
19226
+ result.push({
19227
+ id: entry,
19228
+ name: 'File',
19229
+ status: 'remote',
19230
+ source: { kind: 'fileId', value: entry },
19231
+ });
19232
+ }
19233
+ }
19234
+ return result;
19235
+ }
19236
+ /** Attachment field path from widget options or column path fallback. */
19237
+ function resolveAttachmentFieldPath(options, fieldFallback) {
19238
+ const entityBlock = get(options, 'entity');
19239
+ const fromEntityBlock = entityBlock != null && typeof entityBlock === 'object'
19240
+ ? get(entityBlock, 'field')
19241
+ : undefined;
19242
+ const field = get(options, 'entityField') ?? fromEntityBlock ?? fieldFallback;
19243
+ if (typeof field !== 'string' || !field.trim()) {
19244
+ return undefined;
19245
+ }
19246
+ return field.trim();
19247
+ }
19248
+ /** True when the list row includes the attachment field (even when empty). */
19249
+ function isAttachmentFieldPresentOnRow(rowData, fieldPath) {
19250
+ if (!fieldPath || !rowData) {
19251
+ return false;
19252
+ }
19253
+ return has(rowData, fieldPath);
19254
+ }
19183
19255
  /** Resolve entity scope for column popup / load when widget options carry list-row expressions. */
19184
19256
  function resolveEntityId(entityIdOption, rowData) {
19185
19257
  if (isString(entityIdOption) && entityIdOption.trim() && !entityIdOption.includes('{{')) {
@@ -19219,10 +19291,14 @@ function resolveFileUploaderEntityScope(options, rowData, fieldFallback) {
19219
19291
  }
19220
19292
  //#endregion
19221
19293
 
19294
+ /** Trace namespace for file-uploader attachment column, load/save, and hydration. */
19295
+ const FILE_UPLOADER_TRACE_NS = 'file-uploader-attachments';
19296
+
19222
19297
  class AXPFileUploaderLoadFilesQuery {
19223
19298
  constructor() {
19224
19299
  //#region ---- Services & Dependencies ----
19225
19300
  this.injector = inject(Injector);
19301
+ this.debug = inject(AXPDebugService);
19226
19302
  }
19227
19303
  //#endregion
19228
19304
  //#region ---- Query Execution ----
@@ -19236,8 +19312,28 @@ class AXPFileUploaderLoadFilesQuery {
19236
19312
  return dataService.getOne(entityId);
19237
19313
  });
19238
19314
  const fieldValue = get(record, field);
19239
- const files = normalizeEntityFieldToFileList(fieldValue);
19240
19315
  const count = attachmentFieldCount(fieldValue);
19316
+ const inlineFiles = normalizeEntityFieldToFileList(fieldValue);
19317
+ const needsHydration = attachmentNeedsHydration(fieldValue);
19318
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'load-files', 'Fetched entity attachment field', () => ({
19319
+ entityRef,
19320
+ entityId,
19321
+ field,
19322
+ count,
19323
+ inlineFiles: inlineFiles.length,
19324
+ needsHydration,
19325
+ }));
19326
+ let files = inlineFiles;
19327
+ if (needsHydration) {
19328
+ const fileStorage = runInInjectionContext(this.injector, () => inject(AXPFileStorageService));
19329
+ files = await hydrateAttachmentFieldToFileList(fieldValue, fileStorage);
19330
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'load-files', 'Hydrated attachment refs', () => ({
19331
+ entityId,
19332
+ field,
19333
+ hydratedCount: files.length,
19334
+ fileNames: files.map((f) => f.name),
19335
+ }));
19336
+ }
19241
19337
  return { files, count };
19242
19338
  }
19243
19339
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderLoadFilesQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -19252,6 +19348,7 @@ class AXPFileUploaderSaveFilesCommand {
19252
19348
  constructor() {
19253
19349
  //#region ---- Services & Dependencies ----
19254
19350
  this.injector = inject(Injector);
19351
+ this.debug = inject(AXPDebugService);
19255
19352
  //#endregion
19256
19353
  }
19257
19354
  //#endregion
@@ -19259,6 +19356,14 @@ class AXPFileUploaderSaveFilesCommand {
19259
19356
  async execute(input) {
19260
19357
  const { name: entityRef, id: entityId, field } = input;
19261
19358
  const files = (input.files ?? []).filter(isFileListItem);
19359
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'save-files', 'Saving attachment field', () => ({
19360
+ entityRef,
19361
+ entityId,
19362
+ field,
19363
+ inputCount: input.files?.length ?? 0,
19364
+ savingCount: files.length,
19365
+ attachmentCount: attachmentFieldCount(files),
19366
+ }));
19262
19367
  if (!entityRef?.trim() || !entityId?.trim() || !field?.trim()) {
19263
19368
  return {
19264
19369
  success: false,
@@ -19298,7 +19403,6 @@ function hasFileUploaderTitleOrDescriptionFields(editDialog) {
19298
19403
  }
19299
19404
  //#endregion
19300
19405
 
19301
- //#region ---- Imports ----
19302
19406
  //#endregion
19303
19407
  //#region ---- Component ----
19304
19408
  class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
@@ -19311,23 +19415,32 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19311
19415
  this.entityResolver = inject(AXPEntityDefinitionRegistryService);
19312
19416
  this.formatService = inject(AXFormatService);
19313
19417
  this.translation = inject(AXTranslationService);
19418
+ this.debug = inject(AXPDebugService);
19314
19419
  //#endregion
19315
19420
  //#region ---- View Children ----
19316
19421
  this.fileListTrigger = viewChild('fileListTrigger', ...(ngDevMode ? [{ debugName: "fileListTrigger" }] : /* istanbul ignore next */ []));
19317
19422
  this.fileListPopover = viewChild('fileListPopover', ...(ngDevMode ? [{ debugName: "fileListPopover" }] : /* istanbul ignore next */ []));
19318
19423
  //#endregion
19319
19424
  //#region ---- State ----
19320
- this.fileCount = signal(0, ...(ngDevMode ? [{ debugName: "fileCount" }] : /* istanbul ignore next */ []));
19321
19425
  this.popoverFiles = signal([], ...(ngDevMode ? [{ debugName: "popoverFiles" }] : /* istanbul ignore next */ []));
19322
19426
  this.loadStatus = signal('idle', ...(ngDevMode ? [{ debugName: "loadStatus" }] : /* istanbul ignore next */ []));
19323
19427
  this.loadError = signal(null, ...(ngDevMode ? [{ debugName: "loadError" }] : /* istanbul ignore next */ []));
19324
19428
  this.isPopoverOpen = signal(false, ...(ngDevMode ? [{ debugName: "isPopoverOpen" }] : /* istanbul ignore next */ []));
19325
19429
  this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : /* istanbul ignore next */ []));
19326
- this.loadRequestId = 0;
19327
19430
  this.popoverLoadRequestId = 0;
19328
19431
  //#endregion
19329
19432
  //#region ---- Computed ----
19330
19433
  this.entityScope = computed(() => resolveFileUploaderEntityScope(this.options ?? {}, this.rowData, this.path), ...(ngDevMode ? [{ debugName: "entityScope" }] : /* istanbul ignore next */ []));
19434
+ this.attachmentFieldPath = computed(() => resolveAttachmentFieldPath(this.options ?? {}, this.path), ...(ngDevMode ? [{ debugName: "attachmentFieldPath" }] : /* istanbul ignore next */ []));
19435
+ this.inlineFieldPresent = computed(() => isAttachmentFieldPresentOnRow(this.rowData, this.attachmentFieldPath()), ...(ngDevMode ? [{ debugName: "inlineFieldPresent" }] : /* istanbul ignore next */ []));
19436
+ this.fileCount = computed(() => {
19437
+ if (!this.inlineFieldPresent()) {
19438
+ return 0;
19439
+ }
19440
+ return attachmentFieldCount(this.rawValue);
19441
+ }, ...(ngDevMode ? [{ debugName: "fileCount" }] : /* istanbul ignore next */ []));
19442
+ /** Clickable when count is unknown or zero — opens popover (lazy load or inline empty). */
19443
+ this.showAttachmentsLink = computed(() => this.fileCount() === 0 && this.entityScope() != null, ...(ngDevMode ? [{ debugName: "showAttachmentsLink" }] : /* istanbul ignore next */ []));
19331
19444
  this.popoverTitle = computed(() => {
19332
19445
  const row = this.rowData;
19333
19446
  const lang = this.translation.getActiveLang();
@@ -19344,10 +19457,7 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19344
19457
  return '@document-management:terms.common.file';
19345
19458
  }, ...(ngDevMode ? [{ debugName: "popoverTitle" }] : /* istanbul ignore next */ []));
19346
19459
  effect(() => {
19347
- const raw = this.rawValue;
19348
19460
  const row = this.rowData;
19349
- const opts = this.options ?? {};
19350
- const path = this.path;
19351
19461
  const rowId = row?.['id'] != null ? String(row['id']) : undefined;
19352
19462
  if (rowId !== this.previousRowId) {
19353
19463
  this.previousRowId = rowId;
@@ -19358,33 +19468,6 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19358
19468
  this.popoverLoadRequestId++;
19359
19469
  });
19360
19470
  }
19361
- const inlineCount = attachmentFieldCount(raw);
19362
- if (inlineCount > 0) {
19363
- untracked(() => this.fileCount.set(inlineCount));
19364
- return;
19365
- }
19366
- const entity = resolveFileUploaderEntityScope(opts, row, path);
19367
- if (!entity) {
19368
- untracked(() => this.fileCount.set(0));
19369
- return;
19370
- }
19371
- const requestId = ++this.loadRequestId;
19372
- untracked(() => {
19373
- void this.queryExecutor
19374
- .fetch('FileUploader:LoadFiles', entity)
19375
- .then((result) => {
19376
- if (requestId !== this.loadRequestId) {
19377
- return;
19378
- }
19379
- const count = result?.count ?? result?.files?.length ?? 0;
19380
- this.fileCount.set(count);
19381
- })
19382
- .catch(() => {
19383
- if (requestId === this.loadRequestId) {
19384
- this.fileCount.set(0);
19385
- }
19386
- });
19387
- });
19388
19471
  });
19389
19472
  effect(() => {
19390
19473
  const scope = this.entityScope();
@@ -19423,25 +19506,45 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19423
19506
  if (this.loadStatus() === 'loading') {
19424
19507
  return;
19425
19508
  }
19509
+ const count = attachmentFieldCount(this.rawValue);
19426
19510
  const inline = normalizeEntityFieldToFileList(this.rawValue);
19427
- if (inline.length > 0) {
19511
+ const needsHydration = attachmentNeedsHydration(this.rawValue);
19512
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Ensure popover files', () => ({
19513
+ rowId: this.previousRowId,
19514
+ inlineFieldPresent: this.inlineFieldPresent(),
19515
+ count,
19516
+ inlineFiles: inline.length,
19517
+ needsHydration,
19518
+ loadStatus: this.loadStatus(),
19519
+ }));
19520
+ if (inline.length > 0 && !needsHydration) {
19428
19521
  this.popoverFiles.set(inline);
19429
19522
  this.loadStatus.set('ready');
19430
19523
  this.loadError.set(null);
19431
19524
  return;
19432
19525
  }
19526
+ if (this.inlineFieldPresent() && count === 0) {
19527
+ this.popoverFiles.set([]);
19528
+ this.loadStatus.set('ready');
19529
+ this.loadError.set(null);
19530
+ return;
19531
+ }
19433
19532
  const entity = this.entityScope();
19434
19533
  if (!entity) {
19435
19534
  this.popoverFiles.set([]);
19436
19535
  this.loadStatus.set('ready');
19437
19536
  return;
19438
19537
  }
19439
- if (this.loadStatus() === 'ready' && this.popoverFiles().length > 0) {
19538
+ if (this.loadStatus() === 'ready' && this.popoverFiles().length > 0 && !needsHydration) {
19440
19539
  return;
19441
19540
  }
19442
19541
  const requestId = ++this.popoverLoadRequestId;
19443
19542
  this.loadStatus.set('loading');
19444
19543
  this.loadError.set(null);
19544
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Loading files via FileUploader:LoadFiles', () => ({
19545
+ entity,
19546
+ reason: needsHydration ? 'hydration-required' : 'lazy-or-empty',
19547
+ }));
19445
19548
  try {
19446
19549
  const result = await this.queryExecutor.fetch('FileUploader:LoadFiles', entity);
19447
19550
  if (requestId !== this.popoverLoadRequestId) {
@@ -19449,11 +19552,19 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19449
19552
  }
19450
19553
  this.popoverFiles.set(result?.files ?? []);
19451
19554
  this.loadStatus.set('ready');
19555
+ this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Popover files loaded', () => ({
19556
+ loadedCount: result?.files?.length ?? 0,
19557
+ expectedCount: result?.count ?? 0,
19558
+ }));
19452
19559
  }
19453
- catch {
19560
+ catch (error) {
19454
19561
  if (requestId !== this.popoverLoadRequestId) {
19455
19562
  return;
19456
19563
  }
19564
+ this.debug.warn(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Failed to load popover files', () => ({
19565
+ entity,
19566
+ error: error instanceof Error ? error.message : String(error),
19567
+ }));
19457
19568
  const msg = await this.translation.translateAsync('@general:widgets.lookup.column.load-failed');
19458
19569
  this.loadError.set(msg);
19459
19570
  this.loadStatus.set('error');
@@ -19476,11 +19587,11 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
19476
19587
  return false;
19477
19588
  }
19478
19589
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
19479
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileUploaderWidgetColumnComponent, isStandalone: true, selector: "axp-file-uploader-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "fileListTrigger", first: true, predicate: ["fileListTrigger"], descendants: true, isSignal: true }, { propertyName: "fileListPopover", first: true, predicate: ["fileListPopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (fileCount() > 0) {\n<span class=\"ax-cursor-pointer ax-text-primary ax-underline\" (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger>\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n</span>\n} @else {\n<span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else {\n <axp-file-list [files]=\"popoverFiles()\" look=\"links\" linksLayout=\"menu\" [showLabel]=\"false\" [readonly]=\"true\" />\n }\n </div>\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "look", "titleKey", "showLabel", "linksLayout", "files", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
19590
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileUploaderWidgetColumnComponent, isStandalone: true, selector: "axp-file-uploader-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "fileListTrigger", first: true, predicate: ["fileListTrigger"], descendants: true, isSignal: true }, { propertyName: "fileListPopover", first: true, predicate: ["fileListPopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (fileCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n </span>\n} @else if (showAttachmentsLink()) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{ '@general:widgets.file-uploader.attachments.title' | translate | async }}\n </span>\n} @else {\n <span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else if (popoverFiles().length === 0) {\n <p class=\"axp-file-uploader-column-popover__empty\">\n {{ '@general:widgets.file-uploader.empty-state.title' | translate | async }}\n </p>\n } @else {\n <axp-file-list\n [files]=\"popoverFiles()\"\n look=\"links\"\n linksLayout=\"menu\"\n [showLabel]=\"false\"\n [readonly]=\"true\"\n />\n }\n </div>\n </div>\n</ax-popover>\n", styles: [".axp-file-uploader-column-popover__empty{margin:0;padding-top:.5rem;padding-bottom:.5rem;text-align:center;font-size:.875rem;line-height:1.25rem;line-height:1.375;color:rgb(var(--ax-sys-color-on-lighter-surface))}\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "look", "titleKey", "showLabel", "linksLayout", "files", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
19480
19591
  }
19481
19592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, decorators: [{
19482
19593
  type: Component,
19483
- args: [{ selector: 'axp-file-uploader-widget-column', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXTranslationModule, AsyncPipe, AXPopoverModule, AXLoadingModule, AXPFileListComponent], inputs: ['rawValue', 'rowData'], template: "@if (fileCount() > 0) {\n<span class=\"ax-cursor-pointer ax-text-primary ax-underline\" (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger>\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n</span>\n} @else {\n<span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else {\n <axp-file-list [files]=\"popoverFiles()\" look=\"links\" linksLayout=\"menu\" [showLabel]=\"false\" [readonly]=\"true\" />\n }\n </div>\n </div>\n</ax-popover>" }]
19594
+ args: [{ selector: 'axp-file-uploader-widget-column', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXTranslationModule, AsyncPipe, AXPopoverModule, AXLoadingModule, AXPFileListComponent], inputs: ['rawValue', 'rowData'], template: "@if (fileCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n </span>\n} @else if (showAttachmentsLink()) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{ '@general:widgets.file-uploader.attachments.title' | translate | async }}\n </span>\n} @else {\n <span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else if (popoverFiles().length === 0) {\n <p class=\"axp-file-uploader-column-popover__empty\">\n {{ '@general:widgets.file-uploader.empty-state.title' | translate | async }}\n </p>\n } @else {\n <axp-file-list\n [files]=\"popoverFiles()\"\n look=\"links\"\n linksLayout=\"menu\"\n [showLabel]=\"false\"\n [readonly]=\"true\"\n />\n }\n </div>\n </div>\n</ax-popover>\n", styles: [".axp-file-uploader-column-popover__empty{margin:0;padding-top:.5rem;padding-bottom:.5rem;text-align:center;font-size:.875rem;line-height:1.25rem;line-height:1.375;color:rgb(var(--ax-sys-color-on-lighter-surface))}\n"] }]
19484
19595
  }], ctorParameters: () => [], propDecorators: { fileListTrigger: [{ type: i0.ViewChild, args: ['fileListTrigger', { isSignal: true }] }], fileListPopover: [{ type: i0.ViewChild, args: ['fileListPopover', { isSignal: true }] }] } });
19485
19596
 
19486
19597
  var fileUploaderWidgetColumn_component = /*#__PURE__*/Object.freeze({
@@ -20209,16 +20320,21 @@ var index = /*#__PURE__*/Object.freeze({
20209
20320
  AXPFileUploaderWidgetService: AXPFileUploaderWidgetService,
20210
20321
  AXPFileUploaderWidgetViewComponent: AXPFileUploaderWidgetViewComponent,
20211
20322
  attachmentFieldCount: attachmentFieldCount,
20323
+ attachmentNeedsHydration: attachmentNeedsHydration,
20212
20324
  attachmentsSemanticallyEqual: attachmentsSemanticallyEqual,
20213
20325
  committedAttachments: committedAttachments,
20214
20326
  fingerprintAttachmentItem: fingerprintAttachmentItem,
20215
20327
  fingerprintAttachments: fingerprintAttachments,
20216
20328
  hasFileUploaderTitleOrDescriptionFields: hasFileUploaderTitleOrDescriptionFields,
20329
+ hydrateAttachmentFieldToFileList: hydrateAttachmentFieldToFileList,
20330
+ isAttachmentFieldPresentOnRow: isAttachmentFieldPresentOnRow,
20217
20331
  isAttachmentListEntry: isAttachmentListEntry,
20332
+ isAttachmentStorageRef: isAttachmentStorageRef,
20218
20333
  isFileListItem: isFileListItem,
20219
20334
  isFileUploaderEditDialogAuto: isFileUploaderEditDialogAuto,
20220
20335
  normalizeEntityFieldToFileList: normalizeEntityFieldToFileList,
20221
20336
  persistedAttachments: persistedAttachments,
20337
+ resolveAttachmentFieldPath: resolveAttachmentFieldPath,
20222
20338
  resolveFileUploaderEditDialog: resolveFileUploaderEditDialog,
20223
20339
  resolveFileUploaderEntityScope: resolveFileUploaderEntityScope
20224
20340
  });
@@ -20281,7 +20397,6 @@ var selectorStructureWidgetColumn_component = /*#__PURE__*/Object.freeze({
20281
20397
  AXPSelectorStructureWidgetColumnComponent: AXPSelectorStructureWidgetColumnComponent
20282
20398
  });
20283
20399
 
20284
- //#region ---- Imports ----
20285
20400
  /** Internal key for stable row tracking before a selector value is committed (persisted with the row). */
20286
20401
  const SELECTOR_STRUCTURE_ROW_UID = '__rowUid';
20287
20402
  //#endregion
@@ -25890,9 +26005,42 @@ var getEntityDetails_query = /*#__PURE__*/Object.freeze({
25890
26005
  AXPGetEntityDetailsQuery: AXPGetEntityDetailsQuery
25891
26006
  });
25892
26007
 
26008
+ /**
26009
+ * Computes a diff between two plain objects with array-aware semantics.
26010
+ * - For arrays of objects with an id field, computes added/removed by id.
26011
+ * - For arrays of primitives or objects without id, uses deep equality.
26012
+ * - For scalars/objects, reports oldValue/newValue when changed.
26013
+ */
26014
+ function detectEntityChanges(oldObj, newObj) {
26015
+ return transform(newObj, (result, value, key) => {
26016
+ if (!isEqual$1(value, oldObj[key])) {
26017
+ const oldValue = oldObj[key];
26018
+ if (Array.isArray(value) || Array.isArray(oldValue)) {
26019
+ const oldArray = Array.isArray(oldValue) ? oldValue : [];
26020
+ const newArray = Array.isArray(value) ? value : [];
26021
+ const hasId = newArray.length > 0 && typeof newArray[0] === 'object' && newArray[0] !== null && 'id' in newArray[0];
26022
+ if (hasId) {
26023
+ const added = newArray.filter((item) => !oldArray.some((oldItem) => oldItem.id === item.id));
26024
+ const removed = oldArray.filter((item) => !newArray.some((newItem) => newItem.id === item.id));
26025
+ result[key] = { oldValue, newValue: value, added, removed };
26026
+ }
26027
+ else {
26028
+ const added = newArray.filter((item) => !oldArray.some((oldItem) => isEqual$1(item, oldItem)));
26029
+ const removed = oldArray.filter((item) => !newArray.some((newItem) => isEqual$1(item, newItem)));
26030
+ result[key] = { oldValue, newValue: value, added, removed };
26031
+ }
26032
+ }
26033
+ else {
26034
+ result[key] = { oldValue, newValue: value };
26035
+ }
26036
+ }
26037
+ }, {});
26038
+ }
26039
+ //#endregion
26040
+
25893
26041
  /**
25894
26042
  * Generated bundle index. Do not edit.
25895
26043
  */
25896
26044
 
25897
- export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService, AXPEntityDefinitionProviderWidget, AXPEntityDefinitionProviderWidgetEditComponent, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityFormBuilderService, AXPEntityListPersistenceModeDefault, AXPEntityListTableService, AXPEntityListToolbarService, AXPEntityListViewCardFieldViewModel, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListCardSelectActionName, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityPreloadFiltersContainerComponent, AXPEntityPreloadFiltersViewModel, AXPEntityPreloadFiltersViewModelResolver, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPFileListComponent, AXPFileUploaderLoadFilesQuery, AXPFileUploaderSaveFilesCommand, AXPFileUploaderWidget, AXPFileUploaderWidgetColumnComponent, AXPFileUploaderWidgetEditComponent, AXPFileUploaderWidgetService, AXPFileUploaderWidgetViewComponent, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPRelatedColumnEnrichmentService, AXPRelatedColumnMetadataResolver, AXPSelectorStructureWidget, AXPSelectorStructureWidgetColumnComponent, AXPSelectorStructureWidgetEditComponent, AXPSelectorStructureWidgetViewComponent, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_APPEARANCE_SECTION_ORDER, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXP_CLASSIFICATION_SECTION_ORDER, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_COLUMN_ORDER, DEFAULT_PAIR_SPAN_RULES, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY, EntityBuilder, EntityDataAccessor, actionExists, applyDataSourcePagingWithoutLoad, attachmentFieldCount, attachmentsPlugin, attachmentsSemanticallyEqual, axpCreateEntityAiToolInputDefaults, axpCreateEntityCommandDefinition, canPersistEntityListState, cloneLayoutArrays, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, formatLookupItemDisplayAsync, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, hasFileUploaderTitleOrDescriptionFields, isAXPMiddlewareAbortError, isAttachmentListEntry, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, persistedAttachments, provideEntity, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
26045
+ export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService, AXPEntityDefinitionProviderWidget, AXPEntityDefinitionProviderWidgetEditComponent, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityFormBuilderService, AXPEntityListPersistenceModeDefault, AXPEntityListTableService, AXPEntityListToolbarService, AXPEntityListViewCardFieldViewModel, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListCardSelectActionName, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityPreloadFiltersContainerComponent, AXPEntityPreloadFiltersViewModel, AXPEntityPreloadFiltersViewModelResolver, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPFileListComponent, AXPFileUploaderLoadFilesQuery, AXPFileUploaderSaveFilesCommand, AXPFileUploaderWidget, AXPFileUploaderWidgetColumnComponent, AXPFileUploaderWidgetEditComponent, AXPFileUploaderWidgetService, AXPFileUploaderWidgetViewComponent, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPRelatedColumnEnrichmentService, AXPRelatedColumnMetadataResolver, AXPSelectorStructureWidget, AXPSelectorStructureWidgetColumnComponent, AXPSelectorStructureWidgetEditComponent, AXPSelectorStructureWidgetViewComponent, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_APPEARANCE_SECTION_ORDER, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXP_CLASSIFICATION_SECTION_ORDER, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_COLUMN_ORDER, DEFAULT_PAIR_SPAN_RULES, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY, EntityBuilder, EntityDataAccessor, actionExists, applyDataSourcePagingWithoutLoad, attachmentFieldCount, attachmentNeedsHydration, attachmentsPlugin, attachmentsSemanticallyEqual, axpCreateEntityAiToolInputDefaults, axpCreateEntityCommandDefinition, canPersistEntityListState, cloneLayoutArrays, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, formatLookupItemDisplayAsync, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, hasFileUploaderTitleOrDescriptionFields, hydrateAttachmentFieldToFileList, isAXPMiddlewareAbortError, isAttachmentFieldPresentOnRow, isAttachmentListEntry, isAttachmentStorageRef, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, persistedAttachments, provideEntity, resolveAttachmentFieldPath, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
25898
26046
  //# sourceMappingURL=acorex-platform-layout-entity.mjs.map