@acorex-platform/framework-client 0.0.38 → 0.0.48

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 (111) hide show
  1. package/fesm2022/acorex-platform-framework-client-auth.mjs +212 -44
  2. package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs → acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs} +31 -1
  4. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-framework-client-common.mjs +1172 -193
  6. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-core.mjs +233 -132
  8. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +295 -59
  10. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs} +10 -6
  12. package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs +66 -0
  14. package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs +195 -0
  16. package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +4015 -1014
  18. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +1179 -304
  20. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
  21. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs} +1701 -300
  22. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs.map +1 -0
  23. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs} +2 -2
  24. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs.map} +1 -1
  25. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs} +2 -2
  26. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs.map} +1 -1
  27. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs} +2 -2
  28. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs.map} +1 -1
  29. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -2
  30. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +47 -8
  31. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +3854 -3292
  33. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs +33319 -0
  35. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs.map +1 -0
  36. package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs} +8 -5
  37. package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs +45 -0
  39. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs +68 -0
  41. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs.map +1 -0
  42. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs +88 -0
  43. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs.map +1 -0
  44. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs +71 -0
  45. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs.map +1 -0
  46. package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs +81 -0
  47. package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs.map +1 -0
  48. package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs} +41 -23
  49. package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs.map +1 -0
  50. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs} +3 -3
  51. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs.map} +1 -1
  52. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs +71 -0
  53. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs.map +1 -0
  54. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs +111 -0
  55. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs.map +1 -0
  56. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs +77 -0
  57. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs.map +1 -0
  58. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs} +3 -3
  59. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs.map} +1 -1
  60. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs} +21 -8
  61. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs.map +1 -0
  62. package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs +124 -0
  63. package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs.map +1 -0
  64. package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs +345 -0
  65. package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs.map +1 -0
  66. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -31985
  67. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
  68. package/fesm2022/acorex-platform-framework-client-realtime.mjs +2 -1
  69. package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
  70. package/fesm2022/acorex-platform-framework-client-runtime.mjs +2 -2
  71. package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
  72. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs} +3 -3
  73. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs.map +1 -0
  74. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs +122 -0
  75. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs.map +1 -0
  76. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs} +3 -3
  77. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs.map +1 -0
  78. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +424 -103
  79. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  80. package/fesm2022/{acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs → acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs} +102 -1
  81. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs.map +1 -0
  82. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +174 -22
  83. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  84. package/package.json +2 -2
  85. package/realtime/README.md +1 -1
  86. package/types/acorex-platform-framework-client-auth.d.ts +18 -1
  87. package/types/acorex-platform-framework-client-common.d.ts +243 -9
  88. package/types/acorex-platform-framework-client-core.d.ts +152 -119
  89. package/types/acorex-platform-framework-client-layout-builder.d.ts +29 -0
  90. package/types/acorex-platform-framework-client-layout-components.d.ts +717 -147
  91. package/types/acorex-platform-framework-client-layout-designer.d.ts +192 -14
  92. package/types/acorex-platform-framework-client-layout-entity.d.ts +167 -92
  93. package/types/acorex-platform-framework-client-layout-views.d.ts +23 -1
  94. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +148 -40
  95. package/types/acorex-platform-framework-client-layout-widgets.d.ts +261 -119
  96. package/types/acorex-platform-framework-client-realtime.d.ts +16 -3
  97. package/types/acorex-platform-framework-client-themes-default.d.ts +62 -11
  98. package/types/acorex-platform-framework-client-themes-shared.d.ts +25 -2
  99. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs +0 -77
  102. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs.map +0 -1
  108. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs +0 -122
  109. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs.map +0 -1
@@ -1,16 +1,16 @@
1
- import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, resolveEntityCardAvatarPath, isEntityCardQrField, collectLeftoverCardMoreFieldNames, parseDottedFieldPath, createEntityMasterStylingScope, normalizeEntityMasterStylingClass, resolveEntityMasterStyling, resolveEntityMasterFieldExpression, resolveEntityCardIdentityKind, resolveEntityCardUserId, ENTITY_CARD_LABELED_PREVIEW_MAX, resolveEntityCardLayout, buildDefaultEntityCardLayout, resolveEntityListFilterContextField, resolveEntityListFilterQueryField, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, isEntityMasterListCardHost, normalizeEntityMasterListLayoutType, getEntityInfo, collectEntityListSortableFields, collectEntityListFilterDefinitions, collectEntityCardUserIdQueryFields, buildEntityQueryFields, AXPEntityQueryType, ENTITY_ROW_POPUP_TITLE_OPTION, resolveEnabledPageListLayouts, buildPageListWidgetName, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, resolveLookupWidgetCreateOptions, promoteLegacyEntityCardLayout, buildEntitySearchTitleContext } from '@acorex-platform/framework-shared/entity';
2
- import { resolveEntityActionCommandInput, defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_ENTITY, analyzeBulkCommandFailures, ENTITY_DELETE_DEFAULT, ENTITY_GET_BY_ID_DEFAULT, ENTITY_QUERY_DEFAULT, ENTITY_INSERT_DEFAULT, ENTITY_UPDATE_DEFAULT, DOMAIN_GET_ENTITY_LAYOUT_DEFAULT, DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT, resolveEntityNameFromRuntimeKey } from '@acorex-platform/framework-shared/runtime';
1
+ import { isEntityColumnBand, mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, relatedEntityListViewWidgetOptions, AXPEntityCommandScope, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, resolveEntityCardAvatarPath, isEntityCardQrField, collectLeftoverCardMoreFieldNames, parseDottedFieldPath, AXP_ENTITY_LIST_RECORD_STYLING_TARGET, isCompleteEntityListStylingCondition, createEntityMasterStylingScope, normalizeEntityMasterStylingClass, resolveEntityMasterStyling, resolveEntityMasterFieldExpression, resolveEntityCardIdentityKind, resolveEntityCardUserId, ENTITY_CARD_LABELED_PREVIEW_MAX, resolveEntityCardLayout, buildDefaultEntityCardLayout, resolveEntityListFilterContextField, resolveEntityListFilterQueryField, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, isEntityMasterListCardHost, normalizeEntityMasterListLayoutType, getEntityInfo, normalizeEntityListUserStylingRules, mergeQueryViewAndUserFilters, mergeDefinitionAndCustomQueryViews, isQueryViewDirty, isCustomQueryView, collectEntityListSortPresets, flattenEntityTableColumns, createCustomQueryViewName, removePersistedCustomQueryView, readPersistedCustomQueryViews, upsertPersistedCustomQueryView, snapshotCustomQueryView, isQueryViewColumnVisible, collectEntityListSortableFields, collectEntityListFilterDefinitions, withQueryViewFilterVisibility, queryViewConditionsToFilterQueries, collectEntityCardUserIdQueryFields, buildEntityQueryFields, normalizeAXPQueryViewColumns, findEntityTableColumnInTree, AXPEntityQueryType, ENTITY_ROW_POPUP_TITLE_OPTION, resolveEnabledPageListLayouts, resolveRelatedEntityListViews, buildPageListWidgetName, applyQueryViewToColumnQueries, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, resolveLookupWidgetCreateOptions, promoteLegacyEntityCardLayout, inferEntityListSortPresets, buildEntitySearchTitleContext } from '@acorex-platform/framework-shared/entity';
2
+ import { resolveEntityActionCommandInput, entityActionDataRecord, defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_ENTITY, analyzeBulkCommandFailures, ENTITY_DELETE_DEFAULT, ENTITY_GET_BY_ID_DEFAULT, ENTITY_QUERY_DEFAULT, ENTITY_INSERT_DEFAULT, ENTITY_UPDATE_DEFAULT, DOMAIN_GET_ENTITY_LAYOUT_DEFAULT, DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT, resolveEntityNameFromRuntimeKey } from '@acorex-platform/framework-shared/runtime';
3
3
  import { AXToastService } from '@acorex/components/toast';
4
4
  import * as i3$1 from '@acorex/core/translation';
5
5
  import { AXTranslationService, AXTranslationModule, resolveMultiLanguageString, translateSync } from '@acorex/core/translation';
6
6
  import * as i4$3 from '@acorex-platform/framework-client/common';
7
- import { AXPNotFoundError, AXPMenuRouteAccessService, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, platformErrorI18nKey, extractRequestErrorInfo, axpNavigateAppPath, AXPFileTypeProviderService, AXPFileStorageService, resolveFileTypeDisplay, resolveEntityRowDisplayTitle, resolveEntityModifyPopupTitle, commandMessageTextForError, resolveStoredImageDisplayUrl, isStoredImageFileId, AXPFilterOperatorMiddlewareService, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, axpRedirectToNotFound, CONTAINS_OPER, toExecuteCommandFailureResult, AXPLocalEntityEngine, AXPLocalEntityRealtimeBridge, AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS, resolveSearchableText, evaluateEntityDisplayTemplate, AXPCleanNestedFilters, axpIsEntityRecordNotFound, coerceAXPSettingRawValueByKind, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, axpIsEntityListPath, axpIsEntityDetailsPath, axpParseEntityListRoute, axpParseEntityDetailsRoute, axpSaveEntityListReturnUrl, AXPMenuRouteGuard, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER } from '@acorex-platform/framework-client/common';
8
- import { AXPWidgetsCatalog, runtimeCommandPayloadData, createRandomUuid, AXPRequestError, runtimeQueryPayloadData, runtimeQueryCollectionData, runtimeQueryFailure, runtimeQuerySuccessObject, runtimeCommandFailure, runtimeCommandSuccessObject, resolveActionLook, AXPWidgetsList, AXPSystemActionType, AXPPlatformScope, AXP_QUERY_QUICK_SEARCH_FIELD, extractValue, setSmart, getChangedPaths, isSelectionValueEqual, runtimeQuerySuccessCollection } from '@acorex-platform/framework-shared/core';
9
- import { AXPDeviceService, AXPExpressionEvaluatorService, AXPEntityBroadcastService, AXPHookService, AXPDebugService, AXPDataGenerator, AXPContextEvalFactory, createCommandExpressionScope, toExpressionRecord, AXPDistributedEventListenerService, applyFilterArray, applySortArray, AXHighlightService, AXPColumnWidthService, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPContextStore, AXPModuleManifestRegistry, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER } from '@acorex-platform/framework-client/core';
7
+ import { AXPNotFoundError, AXPMenuRouteAccessService, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, platformErrorI18nKey, extractRequestErrorInfo, axpNavigateAppPath, AXPFileTypeProviderService, AXPFileStorageService, resolveFileTypeDisplay, resolveEntityRowDisplayTitle, resolveEntityModifyPopupTitle, commandMessageTextForError, resolveStoredImageDisplayUrl, isStoredImageFileId, AXPFilterOperatorMiddlewareService, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, ENTITY_LIST_DEFAULT_INSTANCE_ID, axpNormalizeEntityListInstanceId, axpGetEntityListInstanceIdFromParamMap, axpRedirectToNotFound, CONTAINS_OPER, toExecuteCommandFailureResult, AXPLocalEntityEngine, AXPLocalEntityRealtimeBridge, AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS, resolveSearchableText, evaluateEntityDisplayTemplate, AXPCleanNestedFilters, AXPEntityDetailsNavTrailService, axpComposeEntityDetailsNavTrail, axpIsEntityRecordNotFound, coerceAXPSettingRawValueByKind, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, axpIsEntityListPath, axpIsEntityDetailsPath, axpParseEntityListRoute, axpParseEntityDetailsRoute, axpSaveEntityListReturnUrl, AXPMenuRouteGuard, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER } from '@acorex-platform/framework-client/common';
8
+ import { AXPWidgetsCatalog, runtimeCommandPayloadData, createRandomUuid, AXPRequestError, runtimeQueryPayloadData, runtimeQueryCollectionData, runtimeQueryFailure, runtimeQuerySuccessObject, runtimeCommandFailure, runtimeCommandSuccessObject, resolveActionLook, listThemeSurfaceClasses, parseRuntimeHexSurface, AXP_THEME_SURFACE_STYLES, AXPWidgetsList, AXPSystemActionType, AXPPlatformScope, flattenQueryFilterUserGroups, AXP_QUERY_QUICK_SEARCH_FIELD, wrapQueryFilterRoot, isPersistableFilterQuery, isCompleteFilterCondition, resolveFilterQueryIdentityField, extractValue, setSmart, getChangedPaths, isSelectionValueEqual, runtimeQuerySuccessCollection } from '@acorex-platform/framework-shared/core';
9
+ import { AXPDeviceService, AXPExpressionEvaluatorService, AXPEntityBroadcastService, AXPHookService, AXPDebugService, AXPDataGenerator, AXPContextEvalFactory, ensureRuntimeSurfaceClass, applyFilterArray, createCommandExpressionScope, toExpressionRecord, AXPDistributedEventListenerService, applySortArray, AXHighlightService, AXPColumnWidthService, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPContextStore, AXPModuleManifestRegistry, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER } from '@acorex-platform/framework-client/core';
10
10
  import * as i0 from '@angular/core';
11
11
  import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, signal, output, input, computed, effect, ChangeDetectionStrategy, Component, viewChild, untracked, HostBinding, model, ViewEncapsulation, ElementRef, EnvironmentInjector, NgModule, ChangeDetectorRef, Input, afterNextRender, viewChildren, linkedSignal, DestroyRef, makeEnvironmentProviders } from '@angular/core';
12
12
  import { cloneDeep, merge, get, isNil, set, isArray, isString, castArray, has, isPlainObject, orderBy, defaultTo, isEmpty, isEqual, isObjectLike } from 'lodash-es';
13
- import { Subject, filter, takeUntil, fromEvent, auditTime, merge as merge$1 } from 'rxjs';
13
+ import { Subject, filter, takeUntil, map, distinctUntilChanged, fromEvent, auditTime, merge as merge$1 } from 'rxjs';
14
14
  import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex-platform/framework-client/layout/builder';
15
15
  import { AXPSessionService } from '@acorex-platform/framework-client/auth';
16
16
  import { Router, NavigationStart, ActivatedRoute, ROUTES } from '@angular/router';
@@ -44,7 +44,7 @@ import * as i1$5 from '@angular/forms';
44
44
  import { FormsModule } from '@angular/forms';
45
45
  import { AXUploaderModule } from '@acorex/components/uploader';
46
46
  import { createStringProperty, createBooleanProperty, createNumberProperty, AXPWidgetGroupEnum, AXPPageStatus, AXPWidgetStatus, createSelectProperty } from '@acorex-platform/framework-shared/widget-core';
47
- import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_DOWNLOADABLE_PROPERTY, AXP_READONLY_PROPERTY, AXP_DESCRIPTION_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP, AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_PLACEHOLDER_PROPERTY, AXPProviderSelectWidgetEditBase, AXP_ROW_EXPR_PREFIX, AXP_REPEATER_ENTITY_BY_KEY_LOOKUP } from '@acorex-platform/framework-client/layout/widgets';
47
+ import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_DOWNLOADABLE_PROPERTY, AXP_READONLY_PROPERTY, AXP_DESCRIPTION_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP, AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_PLACEHOLDER_PROPERTY, AXPProviderSelectWidgetEditBase, isDataListColumnBand, AXP_ROW_EXPR_PREFIX, applyLeafVisibilityToDataListColumnTree, AXP_REPEATER_ENTITY_BY_KEY_LOOKUP } from '@acorex-platform/framework-client/layout/widgets';
48
48
  import { AXPopupService } from '@acorex/components/popup';
49
49
  import * as i1$4 from '@acorex/components/skeleton';
50
50
  import { AXSkeletonModule } from '@acorex/components/skeleton';
@@ -677,38 +677,40 @@ class AXPRelatedColumnEnrichmentService {
677
677
  if (!columns?.length) {
678
678
  return entity;
679
679
  }
680
- const enrichedColumns = [];
681
- for (const column of columns) {
682
- let enriched = { ...column };
683
- // Derive dataPath for FK columns when missing
684
- if (!enriched.options?.dataPath) {
685
- const derivedDataPath = this.deriveDataPathForFkColumn(entity, column);
686
- if (derivedDataPath) {
687
- enriched = {
688
- ...enriched,
689
- options: { ...enriched.options, dataPath: derivedDataPath },
690
- };
691
- }
692
- }
693
- // Enrich title/showAs for dotted path columns
694
- const needsMetadataEnrichment = column.name.includes('.') && (!enriched.title || !enriched.showAs);
695
- if (needsMetadataEnrichment) {
696
- const metadata = await this.metadataResolver.resolve(entity, column.name);
697
- if (metadata) {
698
- enriched = {
699
- ...enriched,
700
- title: enriched.title ?? metadata.title,
701
- showAs: enriched.showAs ?? metadata.showAs,
702
- };
703
- }
704
- }
705
- enrichedColumns.push(enriched);
706
- }
680
+ const enrichedColumns = await Promise.all(columns.map((column) => this.enrichColumnNode(entity, column)));
707
681
  return {
708
682
  ...entity,
709
683
  columns: enrichedColumns,
710
684
  };
711
685
  }
686
+ async enrichColumnNode(entity, column) {
687
+ if (isEntityColumnBand(column)) {
688
+ const children = await Promise.all((column.children ?? []).map((child) => this.enrichColumnNode(entity, child)));
689
+ return { ...column, children };
690
+ }
691
+ let enriched = { ...column };
692
+ if (!enriched.options?.dataPath) {
693
+ const derivedDataPath = this.deriveDataPathForFkColumn(entity, column);
694
+ if (derivedDataPath) {
695
+ enriched = {
696
+ ...enriched,
697
+ options: { ...enriched.options, dataPath: derivedDataPath },
698
+ };
699
+ }
700
+ }
701
+ const needsMetadataEnrichment = column.name.includes('.') && (!enriched.title || !enriched.showAs);
702
+ if (needsMetadataEnrichment) {
703
+ const metadata = await this.metadataResolver.resolve(entity, column.name);
704
+ if (metadata) {
705
+ enriched = {
706
+ ...enriched,
707
+ title: enriched.title ?? metadata.title,
708
+ showAs: enriched.showAs ?? metadata.showAs,
709
+ };
710
+ }
711
+ }
712
+ return enriched;
713
+ }
712
714
  /**
713
715
  * Derives dataPath for FK columns from lookup property schema.
714
716
  * Uses expose.target where source matches textField (default 'title').
@@ -1768,6 +1770,7 @@ class PropertyFilter {
1768
1770
  customFilterDefinitions: relatedEntity.customFilterDefinitions,
1769
1771
  ...(foreignKeyField ? { foreignKeyField } : {}),
1770
1772
  ...(nestedCreateHiddenProperties?.length ? { nestedCreateHiddenProperties } : {}),
1773
+ ...relatedEntityListViewWidgetOptions(relatedEntity),
1771
1774
  ...(syncRelatedFromRoot && relatedEntity.conditions?.length
1772
1775
  ? {
1773
1776
  relatedFilterConditionSpecs: cloneDeep(relatedEntity.conditions),
@@ -2511,7 +2514,7 @@ class AXPCreateEntityCommand {
2511
2514
  const processData = options?.process && typeof options.process === 'object'
2512
2515
  ? options.process.data
2513
2516
  : undefined;
2514
- const createSeed = merge({}, data && typeof data === 'object' ? data : {}, processData && typeof processData === 'object' ? processData : {});
2517
+ const createSeed = merge({}, entityActionDataRecord(data) ?? {}, processData && typeof processData === 'object' ? processData : {});
2515
2518
  let chain = this.entityForm.entity(`${moduleName}.${entityName}`).create(createSeed);
2516
2519
  chain.actions((actions) => {
2517
2520
  actions
@@ -2694,7 +2697,7 @@ const axpCreateEntityCommandDefinition = defineCommand({
2694
2697
  {
2695
2698
  name: 'data',
2696
2699
  title: 'Seed data',
2697
- description: 'Optional create form seed object.',
2700
+ description: 'Optional create form seed as a JSON object (not a string). Include resolved lookup ids and dates.',
2698
2701
  interface: { name: 'json' },
2699
2702
  },
2700
2703
  {
@@ -2711,18 +2714,48 @@ const axpCreateEntityCommandDefinition = defineCommand({
2711
2714
  },
2712
2715
  capabilities: ['ai'],
2713
2716
  ai: {
2714
- shortDescription: 'Opens create dialog with pre-filled data; execution waits until the user submits or cancels, then returns—use for human-confirmed inserts into mock storage.',
2717
+ shortDescription: 'Opens create dialog with pre-filled data; execution waits until the user submits or cancels.',
2718
+ instruction: 'Open the native create form when any ListRegisteredEntities property with required true is still empty — including simple text such as title or postal code. Do not ask those missing fields in chat; open Entity:Create with collected data as a JSON object (never a string). Include every slot you already have: lookup FK ids you Query\'d and dates. Leave empty only fields you could not resolve. Do not call Entity:Insert:Default while a required field is missing. Do not Insert a row this conversation already created (Last record).',
2715
2719
  usage: {
2716
2720
  whenToUse: [
2717
- 'Adding a row when the user should review or edit values before save; same entity create pipeline as the UI (storage middlewares apply on submit).',
2721
+ 'Adding a row when the user should review or fill required values before save.',
2722
+ 'Any required field from ListRegisteredEntities is still empty — especially select or lookup.',
2718
2723
  ],
2719
2724
  avoidWhen: [
2720
- 'Non-interactive headless insert—ConnectivityMock:EntityStorage:Insert is disabled; there is no silent insert tool in this catalog.',
2725
+ 'Every required property already has a value — use Entity:Insert:Default.',
2721
2726
  ],
2722
- followUpTools: ['PlatformManagement:ListRegisteredEntities', 'ConnectivityMock:EntityStorage:Query'],
2727
+ followUpTools: ['PlatformManagement:ListRegisteredEntities', 'Entity:Query:Default'],
2723
2728
  },
2724
2729
  tags: ['entity', 'create', 'form', 'dialog', 'human-in-the-loop', 'mock', 'entity-storage', 'wait-user'],
2730
+ toolParametersSchema: {
2731
+ type: 'object',
2732
+ properties: {
2733
+ data: {
2734
+ type: 'object',
2735
+ additionalProperties: true,
2736
+ description: 'Create-form seed as a JSON object, not a string. Include resolved lookup ids and dates. Omit only fields still unknown.',
2737
+ },
2738
+ },
2739
+ required: ['entity'],
2740
+ },
2725
2741
  toolInputDefaults: { ...axpCreateEntityAiToolInputDefaults },
2742
+ contextBindings: [
2743
+ {
2744
+ slot: 'active-entity',
2745
+ map: { entity: '$input.entity' },
2746
+ text: 'Active entity: {{entity}}',
2747
+ },
2748
+ {
2749
+ slot: 'last-record',
2750
+ map: { entity: '$input.entity', id: 'id' },
2751
+ text: 'Last record {{entity}} id={{id}}',
2752
+ },
2753
+ {
2754
+ slot: 'last-record',
2755
+ map: { entity: '$input.entity', id: 'item.id' },
2756
+ text: 'Last record {{entity}} id={{id}}',
2757
+ },
2758
+ ],
2726
2759
  },
2727
2760
  categories: [AXP_COMMAND_DEFINITION_CATEGORY_ENTITY],
2728
2761
  });
@@ -3151,6 +3184,33 @@ const axpDeleteEntityCommandDefinition = defineCommand({
3151
3184
  },
3152
3185
  ai: {
3153
3186
  tags: ['entity', 'delete', 'crud'],
3187
+ contextBindings: [
3188
+ {
3189
+ slot: 'active-entity',
3190
+ map: { entity: '$input.entity' },
3191
+ text: 'Active entity: {{entity}}',
3192
+ },
3193
+ {
3194
+ slot: 'last-deleted',
3195
+ map: { entity: '$input.entity', id: '$input.data' },
3196
+ text: 'Last deleted {{entity}} id={{id}}',
3197
+ },
3198
+ {
3199
+ slot: 'last-deleted',
3200
+ map: { entity: '$input.entity', id: '$input.data.id' },
3201
+ text: 'Last deleted {{entity}} id={{id}}',
3202
+ },
3203
+ {
3204
+ slot: 'last-record',
3205
+ map: { entity: '$input.entity', id: '$input.data' },
3206
+ text: 'Last record {{entity}} id={{id}}',
3207
+ },
3208
+ {
3209
+ slot: 'last-record',
3210
+ map: { entity: '$input.entity', id: '$input.data.id' },
3211
+ text: 'Last record {{entity}} id={{id}}',
3212
+ },
3213
+ ],
3154
3214
  },
3155
3215
  categories: [AXP_COMMAND_DEFINITION_CATEGORY_ENTITY],
3156
3216
  });
@@ -4894,7 +4954,7 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
4894
4954
  return false;
4895
4955
  }
4896
4956
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4897
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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=\"cursor-pointer text-primary 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=\"cursor-pointer text-primary 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=\"text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"lightest-surface dark:dark-surface min-w-[17.5rem] max-w-[26rem] overflow-hidden\">\n <div class=\"border-b border-surface px-4 py-3\">\n <h3 class=\"m-0 text-sm font-semibold leading-normal text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"max-h-64 overflow-y-auto px-3 py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"flex min-h-[120px] items-center justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"text-danger 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: ["@layer properties;.axp-file-uploader-column-popover__empty{margin:0;padding-block:calc(var(--spacing, .25rem) * 2);text-align:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);color:rgb(var(--ax-sys-color-on-lighter-surface))}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i1$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "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", "accept", "maxFileSize", "showUploadZoneHint", "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 }); }
4957
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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=\"cursor-pointer text-primary 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=\"cursor-pointer text-primary 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=\"text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"lightest-surface dark:dark-surface min-w-[17.5rem] max-w-[26rem] overflow-hidden\">\n <div class=\"border-b border-surface px-4 py-3\">\n <h3 class=\"m-0 text-sm font-semibold leading-normal text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"max-h-64 overflow-y-auto px-3 py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"flex min-h-[120px] items-center justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"text-danger 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: ["@layer properties;.axp-file-uploader-column-popover__empty{margin:0;padding-block:calc(var(--spacing, .25rem) * 2);text-align:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);color:rgb(var(--ax-sys-color-on-lighter-surface))}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i1$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "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", "accept", "maxFileSize", "showUploadZoneHint", "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 }); }
4898
4958
  }
4899
4959
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, decorators: [{
4900
4960
  type: Component,
@@ -5489,7 +5549,7 @@ class AXPFileUploaderWidgetEditComponent extends AXPValueWidgetComponent {
5489
5549
  (onRename)="handleFileRename($event)"
5490
5550
  ></axp-file-list>
5491
5551
  </div>
5492
- `, isInline: true, styles: [":host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drop-zone--interactive{cursor:pointer;border:2px dashed rgb(var(--ax-sys-color-border-lighter-surface));border-radius:.5rem;transition:border-color .15s ease,background-color .15s ease}.__drop-zone--interactive:hover{border-color:rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-50),.08)}.__drop-zone--drag-over{border-color:rgb(var(--ax-sys-color-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-50),.16)!important;box-shadow:0 0 0 3px rgba(var(--ax-sys-color-primary-50),.35)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPFileChooserDirective, selector: "[axpFileChooser]", inputs: ["context", "disabled", "items", "busy"], outputs: ["itemsChange", "busyChange"] }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "look", "titleKey", "showLabel", "linksLayout", "files", "accept", "maxFileSize", "showUploadZoneHint", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5552
+ `, isInline: true, styles: [":host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drop-zone--interactive{cursor:pointer;padding-top:.5rem;border:2px dashed rgb(var(--ax-sys-color-border-lighter-surface));border-radius:.5rem;transition:border-color .15s ease,background-color .15s ease}.__drop-zone--interactive:hover{border-color:rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-50),.08)}.__drop-zone--drag-over{border-color:rgb(var(--ax-sys-color-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-50),.16)!important;box-shadow:0 0 0 3px rgba(var(--ax-sys-color-primary-50),.35)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPFileChooserDirective, selector: "[axpFileChooser]", inputs: ["context", "disabled", "items", "busy"], outputs: ["itemsChange", "busyChange"] }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "look", "titleKey", "showLabel", "linksLayout", "files", "accept", "maxFileSize", "showUploadZoneHint", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5493
5553
  }
5494
5554
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFileUploaderWidgetEditComponent, decorators: [{
5495
5555
  type: Component,
@@ -5548,7 +5608,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
5548
5608
  '[class.border]': 'showBorder()',
5549
5609
  '[class.rounded-md]': 'showBorder()',
5550
5610
  '[class.lightest-surface]': 'showBorder()',
5551
- }, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, AXButtonModule, AXDecoratorModule, AXLoadingModule, AXTranslationModule, AXPFileChooserDirective, AXPFileListComponent], styles: [":host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drop-zone--interactive{cursor:pointer;border:2px dashed rgb(var(--ax-sys-color-border-lighter-surface));border-radius:.5rem;transition:border-color .15s ease,background-color .15s ease}.__drop-zone--interactive:hover{border-color:rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-50),.08)}.__drop-zone--drag-over{border-color:rgb(var(--ax-sys-color-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-50),.16)!important;box-shadow:0 0 0 3px rgba(var(--ax-sys-color-primary-50),.35)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
5611
+ }, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, AXButtonModule, AXDecoratorModule, AXLoadingModule, AXTranslationModule, AXPFileChooserDirective, AXPFileListComponent], styles: [":host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drop-zone--interactive{cursor:pointer;padding-top:.5rem;border:2px dashed rgb(var(--ax-sys-color-border-lighter-surface));border-radius:.5rem;transition:border-color .15s ease,background-color .15s ease}.__drop-zone--interactive:hover{border-color:rgb(var(--ax-sys-color-primary-surface));background-color:rgba(var(--ax-sys-color-primary-50),.08)}.__drop-zone--drag-over{border-color:rgb(var(--ax-sys-color-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-50),.16)!important;box-shadow:0 0 0 3px rgba(var(--ax-sys-color-primary-50),.35)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
5552
5612
  }] });
5553
5613
 
5554
5614
  var fileUploaderWidgetEdit_component = /*#__PURE__*/Object.freeze({
@@ -7280,6 +7340,126 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7280
7340
  }, imports: [AXSkeletonModule], template: "<article\n class=\"axp-entity-card-skeleton\"\n [class.axp-entity-card-skeleton--with-body]=\"showContent() && fieldPlaceholders().length && !rowLayout()\"\n [class.axp-entity-card-skeleton--with-footer]=\"showFooter()\"\n [class.axp-entity-card-skeleton--row]=\"rowLayout()\"\n [class.axp-entity-card-skeleton--embedded]=\"embedded()\"\n [class.axp-entity-card-skeleton--elevated]=\"elevated()\"\n aria-hidden=\"true\"\n>\n <!-- ----- Card header placeholders ----- -->\n <div class=\"axp-entity-card-skeleton__identity\">\n <div class=\"axp-entity-card-skeleton__identity-main\">\n @if (showAvatar()) {\n <!-- ----- Avatar placeholder only when the layout has an avatar field ----- -->\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__avatar\"></ax-skeleton>\n }\n <div class=\"axp-entity-card-skeleton__identity-text\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__title\"></ax-skeleton>\n @if (showContent()) {\n <!-- ----- Description or inline fact placeholders ----- -->\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__description\"></ax-skeleton>\n }\n </div>\n @for (index of badgePlaceholders(); track index) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__badge\"></ax-skeleton>\n }\n </div>\n @if (showHeaderMenu()) {\n <!-- ----- Overflow menu placeholder ----- -->\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__menu\"></ax-skeleton>\n }\n </div>\n\n @if (showContent() && !rowLayout()) {\n <!-- ----- Fact placeholders when card content is shown ----- -->\n <!--------------------------------------------------------------->\n @if (fieldPlaceholders().length) {\n <div class=\"axp-entity-card-skeleton__fields\">\n @for (index of fieldPlaceholders(); track index) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__fact\"></ax-skeleton>\n }\n </div>\n }\n }\n\n @if (showFooter()) {\n <!-- ----- Primary action placeholder ----- -->\n <footer class=\"axp-entity-card-skeleton__footer\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__primary-action\"></ax-skeleton>\n </footer>\n }\n</article>\n", styles: ["@layer properties;:host{display:block;width:100%;min-width:0px}:host.axp-entity-card-host--fill{display:flex;width:100%;min-width:0;flex:1 1 auto;flex-direction:column}:host.axp-entity-card-host--elevated{border-radius:var(--radius-md, .375rem);box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-card-skeleton{display:flex;width:100%;flex-direction:column;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card-skeleton .axp-entity-card-skeleton__identity{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3)}.axp-entity-card-skeleton .axp-entity-card-skeleton__identity-main{display:flex;min-width:0px;flex:1;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card-skeleton .axp-entity-card-skeleton__avatar{height:calc(var(--spacing, .25rem) * 12);width:calc(var(--spacing, .25rem) * 12);flex-shrink:0;border-radius:var(--radius-lg, .5rem)}.axp-entity-card-skeleton .axp-entity-card-skeleton__identity-text{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card-skeleton .axp-entity-card-skeleton__title{height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 40);max-width:100%;border-radius:.25rem}.axp-entity-card-skeleton .axp-entity-card-skeleton__badge{height:calc(var(--spacing, .25rem) * 5);width:calc(var(--spacing, .25rem) * 14);flex-shrink:0;border-radius:calc(infinity * 1px)}.axp-entity-card-skeleton .axp-entity-card-skeleton__menu{height:calc(var(--spacing, .25rem) * 8);width:calc(var(--spacing, .25rem) * 8);flex-shrink:0;border-radius:.25rem}.axp-entity-card-skeleton .axp-entity-card-skeleton__description{height:calc(var(--spacing, .25rem) * 3.5);width:calc(var(--spacing, .25rem) * 32);max-width:100%;border-radius:.25rem;color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-entity-card-skeleton .axp-entity-card-skeleton__fields{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3)}.axp-entity-card-skeleton .axp-entity-card-skeleton__fact{height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 40);border-radius:.25rem}.axp-entity-card-skeleton .axp-entity-card-skeleton__footer{margin-top:auto;border-bottom-right-radius:var(--radius-md, .375rem);border-bottom-left-radius:var(--radius-md, .375rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3)}.axp-entity-card-skeleton .axp-entity-card-skeleton__primary-action{height:calc(var(--spacing, .25rem) * 10);width:100%;border-radius:var(--radius-lg, .5rem)}.axp-entity-card-skeleton.axp-entity-card-skeleton--row .axp-entity-card-skeleton__avatar{height:calc(var(--spacing, .25rem) * 10);width:calc(var(--spacing, .25rem) * 10)}.axp-entity-card-skeleton.axp-entity-card-skeleton--elevated{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card-skeleton.axp-entity-card-skeleton--embedded{border-radius:0;border-style:var(--tw-border-style);border-width:0px;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card-skeleton.axp-entity-card-skeleton--embedded .axp-entity-card-skeleton__identity,.axp-entity-card-skeleton.axp-entity-card-skeleton--embedded .axp-entity-card-skeleton__fields{padding-inline:0px}.axp-entity-card-skeleton.axp-entity-card-skeleton--embedded .axp-entity-card-skeleton__identity{padding-block:0px}:host.axp-entity-card-host--fill .axp-entity-card-skeleton{display:flex;width:100%;min-height:0;flex:1 1 auto;flex-direction:column}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7281
7341
  }], propDecorators: { fieldCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldCount", required: false }] }], badgeCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeCount", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showHeaderMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeaderMenu", required: false }] }], showContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "showContent", required: false }] }], rowLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLayout", required: false }] }], showAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAvatar", required: false }] }], fillHost: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHost", required: false }] }], embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], elevated: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevated", required: false }] }] } });
7282
7342
 
7343
+ //#region ----- Imports -----
7344
+ //#endregion
7345
+ //#region ----- Constants -----
7346
+ const STYLE_ELEMENT_ID = 'axp-entity-list-surface-chrome';
7347
+ const registeredHexClassNames = new Set();
7348
+ //#endregion
7349
+ //#region ----- Public API -----
7350
+ /** Injects row/cell/card CSS for every theme style × variant (e.g. `primary-light-surface` vs `primary-darkest-surface`). */
7351
+ function ensureEntityListSurfaceChromeStyles() {
7352
+ if (typeof document === 'undefined' || document.getElementById(STYLE_ELEMENT_ID)) {
7353
+ return;
7354
+ }
7355
+ const styleElement = document.createElement('style');
7356
+ styleElement.id = STYLE_ELEMENT_ID;
7357
+ styleElement.textContent = [
7358
+ listThemeSurfaceClasses().map(buildThemeSurfaceChromeRule).join(''),
7359
+ disableRowAnimation('[class*="-surface"]'),
7360
+ disableRowAnimation('[class*="axp-hex-"]'),
7361
+ ].join('');
7362
+ document.head.appendChild(styleElement);
7363
+ }
7364
+ /** Pastel hex classes need the same list chrome as theme surfaces; inject per class. */
7365
+ function ensureEntityListHexChromeClass(className) {
7366
+ const parsed = parseRuntimeHexSurface(className);
7367
+ if (!parsed || registeredHexClassNames.has(parsed.className) || typeof document === 'undefined') {
7368
+ return;
7369
+ }
7370
+ ensureEntityListSurfaceChromeStyles();
7371
+ const styleElement = document.getElementById(STYLE_ELEMENT_ID);
7372
+ if (!styleElement) {
7373
+ return;
7374
+ }
7375
+ styleElement.appendChild(document.createTextNode(buildListChromeRule(parsed.className, parsed.background, parsed.color, parsed.border, parsed.border)));
7376
+ registeredHexClassNames.add(parsed.className);
7377
+ }
7378
+ //#endregion
7379
+ //#region ----- CSS generate -----
7380
+ function disableRowAnimation(selector) {
7381
+ return `axp-entity-master-list-data-table ax-data-table tbody tr${selector}:not(.ax-row-color-pulse) td{animation:none!important;}`;
7382
+ }
7383
+ function buildThemeSurfaceChromeRule(className) {
7384
+ const background = `rgb(var(--ax-sys-color-${className}))`;
7385
+ const color = `rgb(var(--ax-sys-color-on-${className}))`;
7386
+ const border = `rgb(var(--ax-sys-color-border-${className}))`;
7387
+ const borderSoft = `rgb(var(--ax-sys-color-border-${className}) / 0.35)`;
7388
+ return buildListChromeRule(className, background, color, border, borderSoft);
7389
+ }
7390
+ function buildListChromeRule(className, background, color, border, borderSoft) {
7391
+ return (`axp-entity-master-list-data-table ax-data-table tbody tr.${className} > td{background:${background}!important;color:${color};}` +
7392
+ `axp-entity-master-list-data-table ax-data-table tbody tr > td.${className}{background:${background}!important;color:${color};box-shadow:inset 0 0 0 1px ${borderSoft};}` +
7393
+ `.axp-entity-card.${className}{--axp-entity-card-surface:${background};--axp-entity-card-border:${border};color:${color};background-color:var(--axp-entity-card-surface);}` +
7394
+ `.axp-entity-card.${className} .axp-entity-card__footer{background-color:transparent;}` +
7395
+ `.axp-entity-card__field-row.${className},.axp-entity-card__fact.${className},.axp-entity-card__header-badge.${className}{background-color:${background};color:${color};box-shadow:inset 0 0 0 1px ${borderSoft};}` +
7396
+ `.axp-entity-card__field-row.${className}{width:auto;margin-inline:calc(-1 * var(--axp-entity-card-gutter));padding-inline:var(--axp-entity-card-gutter);}`);
7397
+ }
7398
+ //#endregion
7399
+
7400
+ //#region ----- Imports -----
7401
+ //#endregion
7402
+ //#region ----- Public API -----
7403
+ function joinEntityListStylingClasses(...parts) {
7404
+ ensureEntityListSurfaceChromeStyles();
7405
+ const tokens = parts.flatMap((part) => part ? part.split(/\s+/).filter(Boolean).map(toEntityListStylingChromeClass) : []);
7406
+ if (!tokens.length) {
7407
+ return undefined;
7408
+ }
7409
+ const unique = [...new Set(tokens)];
7410
+ for (const token of unique) {
7411
+ ensureRuntimeSurfaceClass(token);
7412
+ ensureEntityListHexChromeClass(token);
7413
+ }
7414
+ return unique.join(' ');
7415
+ }
7416
+ /** Keep full theme surfaces (`primary-darkest-surface`); unwrap `ax-row-color-warning` to `warning` for cards. */
7417
+ function toEntityListStylingChromeClass(className) {
7418
+ const trimmed = className.trim();
7419
+ const rowColor = /^ax-row-color-([a-z0-9]+)$/i.exec(trimmed);
7420
+ if (rowColor && AXP_THEME_SURFACE_STYLES.includes(rowColor[1].toLowerCase())) {
7421
+ return rowColor[1].toLowerCase();
7422
+ }
7423
+ return trimmed;
7424
+ }
7425
+ /** Classes from personal rules whose target is the whole row. */
7426
+ function resolveEntityListUserRecordStylingClass(row, rules) {
7427
+ return resolveEntityListUserStylingClass(row, rules, AXP_ENTITY_LIST_RECORD_STYLING_TARGET);
7428
+ }
7429
+ /** Classes from personal rules whose target is one property. */
7430
+ function resolveEntityListUserFieldStylingClass(row, rules, fieldName) {
7431
+ return resolveEntityListUserStylingClass(row, rules, fieldName);
7432
+ }
7433
+ //#endregion
7434
+ //#region ----- Match -----
7435
+ function resolveEntityListUserStylingClass(row, rules, target) {
7436
+ const classes = [];
7437
+ for (const rule of rules) {
7438
+ if (rule.target !== target || !matchesUserStylingRule(row, rule)) {
7439
+ continue;
7440
+ }
7441
+ classes.push(rule.className);
7442
+ }
7443
+ return joinEntityListStylingClasses(...classes);
7444
+ }
7445
+ function matchesUserStylingRule(row, rule) {
7446
+ if (!rule.className.trim() || !isCompleteEntityListStylingCondition(rule.condition)) {
7447
+ return false;
7448
+ }
7449
+ try {
7450
+ const clause = rule.condition;
7451
+ if (clause.filters?.length) {
7452
+ const logic = clause.logic === 'or' ? 'or' : 'and';
7453
+ return applyFilterArray([row], clause.filters, logic).length > 0;
7454
+ }
7455
+ return applyFilterArray([row], [clause]).length > 0;
7456
+ }
7457
+ catch {
7458
+ return false;
7459
+ }
7460
+ }
7461
+ //#endregion
7462
+
7283
7463
  /** Evaluates a compiled master-styling class expression against record (and optional field) data. */
7284
7464
  async function resolveEntityMasterStylingClass(evaluator, expression, data, fieldName) {
7285
7465
  if (!expression) {
@@ -7324,6 +7504,9 @@ class AXPEntityCardComponent {
7324
7504
  ...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
7325
7505
  this.fields = input([], /* @ts-ignore */
7326
7506
  ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
7507
+ /** Personal highlight rules. Merged with `interfaces.master.styling`. */
7508
+ this.userStylingRules = input([], /* @ts-ignore */
7509
+ ...(ngDevMode ? [{ debugName: "userStylingRules" }] : /* istanbul ignore next */ []));
7327
7510
  this.variant = input('card', /* @ts-ignore */
7328
7511
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
7329
7512
  this.interactive = input(false, /* @ts-ignore */
@@ -7460,13 +7643,14 @@ class AXPEntityCardComponent {
7460
7643
  const row = this.row();
7461
7644
  const header = this.header();
7462
7645
  const fields = this.fields();
7646
+ const userStylingRules = this.userStylingRules();
7463
7647
  const badgeFields = this.headerBadgeFields().filter((field) => !this.isStatusBadgeField(field));
7464
7648
  const loader = this.secondaryActionLoader();
7465
7649
  untracked(() => {
7466
7650
  void this.loadSecondaryActions(row, loader);
7467
7651
  void this.resolveHeaderFields(row, header);
7468
7652
  void this.resolveBadgeColors(row, badgeFields);
7469
- void this.resolveStylingClasses(row, fields);
7653
+ void this.resolveStylingClasses(row, fields, userStylingRules);
7470
7654
  });
7471
7655
  });
7472
7656
  }
@@ -7605,15 +7789,16 @@ class AXPEntityCardComponent {
7605
7789
  }
7606
7790
  //#endregion
7607
7791
  //#region ----- Private Helpers -----
7608
- async resolveStylingClasses(row, fields) {
7792
+ async resolveStylingClasses(row, fields, userStylingRules) {
7609
7793
  const entity = this.entity();
7610
7794
  const recordClass = await resolveEntityMasterRecordStylingClass(this.expressionEvaluator, entity, row);
7611
- this.recordStylingClass.set(recordClass);
7795
+ this.recordStylingClass.set(joinEntityListStylingClasses(recordClass, resolveEntityListUserRecordStylingClass(row, userStylingRules)));
7612
7796
  const fieldClasses = {};
7613
7797
  await Promise.all(fields.map(async (field) => {
7614
7798
  const fieldClass = await resolveEntityMasterFieldStylingClass(this.expressionEvaluator, entity, row, field.name);
7615
- if (fieldClass) {
7616
- fieldClasses[field.name] = fieldClass;
7799
+ const merged = joinEntityListStylingClasses(fieldClass, resolveEntityListUserFieldStylingClass(row, userStylingRules, field.name));
7800
+ if (merged) {
7801
+ fieldClasses[field.name] = merged;
7617
7802
  }
7618
7803
  }));
7619
7804
  this.fieldStylingClassByName.set(fieldClasses);
@@ -7794,7 +7979,7 @@ class AXPEntityCardComponent {
7794
7979
  }
7795
7980
  }
7796
7981
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7797
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPEntityCardComponent, isStandalone: true, selector: "axp-entity-card", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, elevated: { classPropertyName: "elevated", publicName: "elevated", isSignal: true, isRequired: false, transformFunction: null }, disableLookupPopover: { classPropertyName: "disableLookupPopover", publicName: "disableLookupPopover", isSignal: true, isRequired: false, transformFunction: null }, fillHost: { classPropertyName: "fillHost", publicName: "fillHost", isSignal: true, isRequired: false, transformFunction: null }, extraExpanded: { classPropertyName: "extraExpanded", publicName: "extraExpanded", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, showNewBadge: { classPropertyName: "showNewBadge", publicName: "showNewBadge", isSignal: true, isRequired: false, transformFunction: null }, showSelection: { classPropertyName: "showSelection", publicName: "showSelection", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, primaryActions: { classPropertyName: "primaryActions", publicName: "primaryActions", isSignal: true, isRequired: false, transformFunction: null }, primaryActionLook: { classPropertyName: "primaryActionLook", publicName: "primaryActionLook", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionLoader: { classPropertyName: "secondaryActionLoader", publicName: "secondaryActionLoader", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { extraExpanded: "extraExpandedChange", selectionChange: "selectionChange", commandClick: "commandClick", closeClick: "closeClick" }, host: { properties: { "class.axp-entity-card-host--fill": "fillHost()", "class.axp-entity-card-host--elevated": "elevated()" } }, ngImport: i0, template: "<article\n class=\"axp-entity-card\"\n [ngClass]=\"recordStylingClass()\"\n [class.axp-entity-card--selected]=\"selected()\"\n [class.axp-entity-card--new]=\"showNewBadge()\"\n [class.axp-entity-card--row]=\"isRowLayout()\"\n [class.axp-entity-card--compact]=\"variant() === 'compact'\"\n [class.axp-entity-card--embedded]=\"embedded()\"\n [class.axp-entity-card--elevated]=\"elevated()\"\n [class.axp-entity-card--static]=\"!interactive()\"\n [class.axp-entity-card--with-body]=\"hasCardBody()\"\n [class.axp-entity-card--with-footer]=\"hasCardFooter()\"\n [class.axp-entity-card--expandable]=\"canShowMore()\"\n [class.axp-entity-card--expanded]=\"extraExpanded()\"\n [attr.role]=\"interactive() ? 'button' : undefined\"\n [attr.tabindex]=\"interactive() ? 0 : undefined\"\n [attr.aria-selected]=\"interactive() ? selected() : undefined\"\n (click)=\"onCardClick($event)\"\n (dblclick)=\"onCardDblClick($event)\"\n (keydown)=\"onCardKeydown($event)\"\n>\n <div class=\"axp-entity-card__content\">\n <!-- ----- Identity row: optional avatar, title, status, and actions ----- -->\n <div class=\"axp-entity-card__identity\">\n <div class=\"axp-entity-card__identity-main\">\n @if (showUserAvatar()) {\n <!-- ----- Person or user identity uses the user avatar ----- -->\n <axp-user-avatar class=\"axp-entity-card__avatar\" [size]=\"avatarSize()\" [userId]=\"userAvatarId()\" [displayName]=\"toDisplayName(titleText())\" [displayAvatar]=\"avatarSrc()\" [showPresence]=\"false\" [axpUserCard]=\"userAvatarId()\" />\n }\n <!--------------------------------------------------------------->\n @if (showIdentityImage()) {\n <!-- ----- Logo or company image for entities that store an image/logo ----- -->\n <div class=\"axp-entity-card__logo\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <img [src]=\"avatarSrc()\" [alt]=\"toDisplayName(titleText())\" />\n </div>\n }\n <!--------------------------------------------------------------->\n @if (identityQrField(); as field) {\n <!-- ----- QR widget occupies the identity visual slot when there is no avatar or logo ----- -->\n <div class=\"axp-entity-card__qr\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n\n <div class=\"axp-entity-card__identity-text\">\n <div class=\"axp-entity-card__title-row\">\n @if (iconClass(); as icon) {\n <!-- ----- Optional header icon from the card layout ----- -->\n <i [class]=\"icon + ' axp-entity-card__icon'\" aria-hidden=\"true\"></i>\n }\n\n <h3 class=\"axp-entity-card__title\">\n {{ titleText() | translate | async }}\n </h3>\n\n @if (showNewBadge()) {\n <!-- ----- New-row highlight badge ----- -->\n <ax-badge class=\"axp-entity-card__header-badge\" [text]=\"('@acorex:dataTable.rowHighlight.new' | translate | async) || ''\" color=\"success\" />\n }\n\n @for (field of headerBadgeFields(); track field.name) {\n <!--------------------------------------------------------------->\n @if (isStatusBadgeField(field)) {\n <!-- ----- Status widget rendered in the header ----- -->\n <div class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldHeaderBadgeNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n <!-- ----- Non-status field rendered as a simple badge ----- -->\n @else if (resolveBadgeText(field)) {\n <ax-badge class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\" [text]=\"resolveBadgeText(field)\" [color]=\"resolveBadgeColor(field)\" />\n }\n }\n </div>\n\n @if (descriptionText()) {\n <!-- ----- Optional description under the title ----- -->\n <p class=\"axp-entity-card__description\">\n {{ descriptionText() | translate | async }}\n </p>\n }\n\n @if (headerMetaFields().length) {\n <!-- ----- Unlabeled header extra (identifier or contact) ----- -->\n <div class=\"axp-entity-card__facts axp-entity-card__facts--inline\">\n @for (field of headerMetaFields(); track field.name) {\n <div class=\"axp-entity-card__fact\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasIdentityActions()) {\n <!-- ----- Selection, overflow actions, or popover dismiss ----- -->\n <div class=\"axp-entity-card__identity-actions\">\n @if (showSelection()) {\n <!-- ----- Multi-select checkbox ----- -->\n <ax-check-box class=\"axp-entity-card__select-checkbox\" [value]=\"selected()\" (onValueChanged)=\"onSelectionCheckboxChange($event)\" (click)=\"onSelectionCheckboxClick($event)\" />\n }\n <!-- ----- Row actions menu when the card is not in selection mode ----- -->\n @else if (secondaryActions().length) {\n <ax-button [look]=\"'blank'\" [color]=\"'default'\" class=\"ax-sm\" (onClick)=\"stopClickPropagation($event)\">\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (item of secondaryActions(); track $index) {\n @if (item.divided) {\n <!-- ----- Divider before this overflow action ----- -->\n <ax-divider />\n }\n <ax-button-item [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\" (onClick)=\"onSecondaryActionClick(item, $event)\">\n @if (item.icon) {\n <!-- ----- Overflow action icon ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-- ----- Close when hosted as a lookup / detail popover ----- -->\n @if (showClose()) {\n <ax-button\n class=\"axp-entity-card__close ax-sm\"\n [look]=\"'blank'\"\n [color]=\"'default'\"\n [iconOnly]=\"true\"\n [attr.title]=\"'@general:actions.close.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.close.title' | translate | async\"\n (onClick)=\"onCloseClick($event)\"\n >\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-button>\n }\n </div>\n }\n </div>\n\n @if (hasLabeledBody()) {\n <!-- ----- Divider between unlabeled identity header and labeled body facts ----- -->\n <div class=\"axp-entity-card__divider\"></div>\n <div class=\"axp-entity-card__body\">\n <div class=\"axp-entity-card__fields\">\n @for (field of previewFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n <!--------------------------------------------------------------->\n @if (extraFields().length) {\n <!-- ----- Extra fields stay mounted; collapse hides them without a body fade ----- -->\n <div class=\"axp-entity-card__extra\" [class.axp-entity-card__extra--collapsed]=\"!extraExpanded()\">\n @for (field of extraFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @if (showInlineMore()) {\n <!-- ----- Quiet More/Less under the fields when the card has no action footer ----- -->\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--inline\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (hasCardFooter()) {\n <!-- ----- One footer row: optional More on the left, primary actions on the right ----- -->\n <footer class=\"axp-entity-card__footer\">\n <!-- ----- More/Less shares the footer with the action button ----- -->\n @if (showFooterMore()) {\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--footer\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n <div class=\"axp-entity-card__footer-actions\">\n @for (action of primaryActions(); track $index) {\n <ax-button\n class=\"axp-entity-card__primary-action ax-sm\"\n [look]=\"primaryActionLook()\"\n [color]=\"action.color\"\n [disabled]=\"action.disabled\"\n [text]=\"(action.title | translate | async)!\"\n (onClick)=\"onPrimaryActionClick(action.name, $event)\"\n >\n @if (action.icon) {\n <!-- ----- Primary action icon ----- -->\n <ax-prefix>\n <i class=\"fa-light {{ action.icon }}\"></i>\n </ax-prefix>\n }\n </ax-button>\n }\n </div>\n </footer>\n }\n</article>\n", styles: ["@layer properties;:host{display:block;width:100%;min-width:0px}:host.axp-entity-card-host--fill{display:flex;width:100%;min-width:0;flex:1 1 auto;flex-direction:column}:host.axp-entity-card-host--elevated{border-radius:var(--radius-md, .375rem);box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-card{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));--axp-entity-card-border: rgb(var(--ax-sys-color-border-light-surface));--axp-entity-card-gutter: 1rem;position:relative;display:flex;width:100%;flex-direction:column;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));background-color:var(--axp-entity-card-surface);border-color:var(--axp-entity-card-border)}.axp-entity-card:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card.axp-entity-card--selected{border-color:rgba(var(--ax-sys-color-primary-500));--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);box-shadow:0 0 0 1px rgb(var(--ax-sys-color-primary-500) / .25),0 2px 6px #0000000f}.axp-entity-card.axp-entity-card--new{border-color:rgb(var(--ax-sys-color-border-success-surface));box-shadow:0 0 0 1px rgb(var(--ax-sys-color-success-500) / .2)}.axp-entity-card.primary{--axp-entity-card-surface: rgb(var(--ax-sys-color-primary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-primary-lightest-surface))}.axp-entity-card.secondary{--axp-entity-card-surface: rgb(var(--ax-sys-color-secondary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-secondary-lightest-surface))}.axp-entity-card.success{--axp-entity-card-surface: rgb(var(--ax-sys-color-success-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-success-lightest-surface))}.axp-entity-card.warning{--axp-entity-card-surface: rgb(var(--ax-sys-color-warning-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-warning-lightest-surface))}.axp-entity-card.danger{--axp-entity-card-surface: rgb(var(--ax-sys-color-danger-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-danger-lightest-surface))}.axp-entity-card.accent1{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent1-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent1-lightest-surface))}.axp-entity-card.accent2{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent2-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent2-lightest-surface))}.axp-entity-card.accent3{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent3-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent3-lightest-surface))}.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3{background-color:var(--axp-entity-card-surface)}:is(.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3) .axp-entity-card__footer{background-color:transparent}.axp-entity-card:not(.axp-entity-card--static){cursor:pointer}.axp-entity-card.axp-entity-card--static{cursor:default}.axp-entity-card.axp-entity-card--elevated{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated .axp-entity-card__footer{background-color:rgb(var(--ax-sys-color-lightest-surface))}.axp-entity-card.axp-entity-card--embedded{border-radius:0;border-style:var(--tw-border-style);border-width:0px;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--axp-entity-card-surface: transparent;background-color:transparent}.axp-entity-card.axp-entity-card--embedded:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__identity{padding-inline:0px;padding-block:0px}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__fields{padding-inline:0px;padding-top:calc(var(--spacing, .25rem) * 2);padding-bottom:0}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__divider{margin-inline:0px}.axp-entity-card .axp-entity-card__identity{display:flex;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__identity-main{display:flex;min-width:0px;flex:1;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__avatar{flex-shrink:0}.axp-entity-card .axp-entity-card__logo{flex-shrink:0;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-surface))}.axp-entity-card .axp-entity-card__logo img{width:100%;height:100%;object-fit:contain}.axp-entity-card .axp-entity-card__qr{display:flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-lightest-surface));padding:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__qr axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__identity-text{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__title-row{display:flex;min-width:0px;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__select-checkbox,.axp-entity-card .axp-entity-card__header-badge{flex-shrink:0}.axp-entity-card .axp-entity-card__identity-actions{display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__close{margin-inline-end:calc(var(--spacing, .25rem) * -1);margin-top:calc(var(--spacing, .25rem) * -.5)}.axp-entity-card .axp-entity-card__content{position:relative;flex:1}.axp-entity-card .axp-entity-card__more{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 8);flex-shrink:0;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding-inline:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__more span,.axp-entity-card .axp-entity-card__more i{pointer-events:none}.axp-entity-card .axp-entity-card__more i{font-size:10px;--tw-leading: 1;line-height:1}.axp-entity-card .axp-entity-card__more:hover,.axp-entity-card .axp-entity-card__more:focus-visible{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__more:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card .axp-entity-card__more--footer{margin-block:calc(var(--spacing, .25rem) * -2.5);margin-inline-start:calc(var(--spacing, .25rem) * -1);min-height:calc(var(--spacing, .25rem) * 10);align-self:stretch;padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__more--inline{margin-inline:var(--axp-entity-card-gutter);margin-top:calc(var(--spacing, .25rem) * .5);margin-bottom:calc(var(--spacing, .25rem) * 2);padding-inline:var(--spacing, .25rem);padding-block:calc(var(--spacing, .25rem) * 2)}.axp-entity-card.axp-entity-card--expanded .axp-entity-card__more{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__title{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-entity-card .axp-entity-card__icon{flex-shrink:0;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__description{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);opacity:65%}.axp-entity-card .axp-entity-card__facts{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-bottom:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__facts--inline{flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:calc(var(--spacing, .25rem) * 4);row-gap:var(--spacing, .25rem);padding-inline:0px;padding-block:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__fact{min-width:0px;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__fact axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__divider{margin-inline:var(--axp-entity-card-gutter);border-top:1px solid var(--axp-entity-card-border)}.axp-entity-card .axp-entity-card__body{position:relative;overflow:hidden}.axp-entity-card .axp-entity-card__extra{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__extra--collapsed{display:none}.axp-entity-card .axp-entity-card__fields{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3{width:auto;margin-inline:calc(-1 * var(--axp-entity-card-gutter));padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__field-row.primary{--axp-entity-styling-border: var(--ax-sys-color-border-primary-lightest-surface);background-color:rgb(var(--ax-sys-color-primary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-primary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__field-row.secondary{--axp-entity-styling-border: var(--ax-sys-color-border-secondary-lightest-surface);background-color:rgb(var(--ax-sys-color-secondary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-secondary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__field-row.success{--axp-entity-styling-border: var(--ax-sys-color-border-success-lightest-surface);background-color:rgb(var(--ax-sys-color-success-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-success-lightest-surface))}.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__field-row.warning{--axp-entity-styling-border: var(--ax-sys-color-border-warning-lightest-surface);background-color:rgb(var(--ax-sys-color-warning-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-warning-lightest-surface))}.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__field-row.danger{--axp-entity-styling-border: var(--ax-sys-color-border-danger-lightest-surface);background-color:rgb(var(--ax-sys-color-danger-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-danger-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__field-row.accent1{--axp-entity-styling-border: var(--ax-sys-color-border-accent1-lightest-surface);background-color:rgb(var(--ax-sys-color-accent1-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent1-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__field-row.accent2{--axp-entity-styling-border: var(--ax-sys-color-border-accent2-lightest-surface);background-color:rgb(var(--ax-sys-color-accent2-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent2-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.accent3,.axp-entity-card .axp-entity-card__field-row.accent3{--axp-entity-styling-border: var(--ax-sys-color-border-accent3-lightest-surface);background-color:rgb(var(--ax-sys-color-accent3-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent3-lightest-surface))}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__header-badge.accent3{border-radius:var(--radius-sm, .25rem);padding-inline:var(--spacing, .25rem)}.axp-entity-card .axp-entity-card__field-row{display:flex;width:100%;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__field-label{display:inline-flex;min-width:0px;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__field-value{margin-inline-start:auto;max-width:60%;min-width:0px;overflow:hidden;text-align:start;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);overflow-wrap:break-word;color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;width:100%;max-width:100%;min-width:0px;overflow:hidden;text-align:start;overflow-wrap:break-word}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell *{text-align:start}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell .flex{justify-content:flex-start}.axp-entity-card .axp-entity-card__field-value :is(.truncate,.whitespace-nowrap){max-width:100%;min-width:0px;overflow-wrap:break-word;white-space:normal;overflow:visible;text-overflow:unset}:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-label,:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-value{color:inherit}.axp-entity-card .axp-entity-card__field-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-entity-card .axp-entity-card__footer{margin-top:auto;display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-block:calc(var(--spacing, .25rem) * 2.5);padding-inline:var(--axp-entity-card-gutter);border-top-color:var(--axp-entity-card-border);background-color:var(--axp-entity-card-surface)}.axp-entity-card .axp-entity-card__footer-actions{margin-inline-start:auto;display:flex;min-width:0px;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__primary-action{min-width:0px}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact):not(.axp-entity-card--embedded) .axp-entity-card__identity{padding-block:calc(var(--spacing, .25rem) * 2.5)}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact) .axp-entity-card__title{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact).axp-entity-card--expandable.axp-entity-card--expanded .axp-entity-card__identity{padding-bottom:calc(var(--spacing, .25rem) * 2.5)}:host.axp-entity-card-host--fill .axp-entity-card{display:flex;width:100%;min-height:0;flex:1 1 auto;flex-direction:column}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i4.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "directive", type: AXPUserCardDirective, selector: "[axpUserCard]", inputs: ["axpUserCard", "axpUserCardDisabled", "axpUserCardTrigger"] }, { kind: "component", type: AXPWidgetColumnCellComponent, selector: "axp-widget-column-cell", inputs: ["node", "rowData", "caption"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7982
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPEntityCardComponent, isStandalone: true, selector: "axp-entity-card", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, userStylingRules: { classPropertyName: "userStylingRules", publicName: "userStylingRules", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, elevated: { classPropertyName: "elevated", publicName: "elevated", isSignal: true, isRequired: false, transformFunction: null }, disableLookupPopover: { classPropertyName: "disableLookupPopover", publicName: "disableLookupPopover", isSignal: true, isRequired: false, transformFunction: null }, fillHost: { classPropertyName: "fillHost", publicName: "fillHost", isSignal: true, isRequired: false, transformFunction: null }, extraExpanded: { classPropertyName: "extraExpanded", publicName: "extraExpanded", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, showNewBadge: { classPropertyName: "showNewBadge", publicName: "showNewBadge", isSignal: true, isRequired: false, transformFunction: null }, showSelection: { classPropertyName: "showSelection", publicName: "showSelection", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, primaryActions: { classPropertyName: "primaryActions", publicName: "primaryActions", isSignal: true, isRequired: false, transformFunction: null }, primaryActionLook: { classPropertyName: "primaryActionLook", publicName: "primaryActionLook", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionLoader: { classPropertyName: "secondaryActionLoader", publicName: "secondaryActionLoader", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { extraExpanded: "extraExpandedChange", selectionChange: "selectionChange", commandClick: "commandClick", closeClick: "closeClick" }, host: { properties: { "class.axp-entity-card-host--fill": "fillHost()", "class.axp-entity-card-host--elevated": "elevated()" } }, ngImport: i0, template: "<article\n class=\"axp-entity-card\"\n [ngClass]=\"recordStylingClass()\"\n [class.axp-entity-card--selected]=\"selected()\"\n [class.axp-entity-card--new]=\"showNewBadge()\"\n [class.axp-entity-card--row]=\"isRowLayout()\"\n [class.axp-entity-card--compact]=\"variant() === 'compact'\"\n [class.axp-entity-card--embedded]=\"embedded()\"\n [class.axp-entity-card--elevated]=\"elevated()\"\n [class.axp-entity-card--static]=\"!interactive()\"\n [class.axp-entity-card--with-body]=\"hasCardBody()\"\n [class.axp-entity-card--with-footer]=\"hasCardFooter()\"\n [class.axp-entity-card--expandable]=\"canShowMore()\"\n [class.axp-entity-card--expanded]=\"extraExpanded()\"\n [attr.role]=\"interactive() ? 'button' : undefined\"\n [attr.tabindex]=\"interactive() ? 0 : undefined\"\n [attr.aria-selected]=\"interactive() ? selected() : undefined\"\n (click)=\"onCardClick($event)\"\n (dblclick)=\"onCardDblClick($event)\"\n (keydown)=\"onCardKeydown($event)\"\n>\n <div class=\"axp-entity-card__content\">\n <!-- ----- Identity row: optional avatar, title, status, and actions ----- -->\n <div class=\"axp-entity-card__identity\">\n <div class=\"axp-entity-card__identity-main\">\n @if (showUserAvatar()) {\n <!-- ----- Person or user identity uses the user avatar ----- -->\n <axp-user-avatar class=\"axp-entity-card__avatar\" [size]=\"avatarSize()\" [userId]=\"userAvatarId()\" [displayName]=\"toDisplayName(titleText())\" [displayAvatar]=\"avatarSrc()\" [showPresence]=\"false\" [axpUserCard]=\"userAvatarId()\" />\n }\n <!--------------------------------------------------------------->\n @if (showIdentityImage()) {\n <!-- ----- Logo or company image for entities that store an image/logo ----- -->\n <div class=\"axp-entity-card__logo\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <img [src]=\"avatarSrc()\" [alt]=\"toDisplayName(titleText())\" />\n </div>\n }\n <!--------------------------------------------------------------->\n @if (identityQrField(); as field) {\n <!-- ----- QR widget occupies the identity visual slot when there is no avatar or logo ----- -->\n <div class=\"axp-entity-card__qr\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n\n <div class=\"axp-entity-card__identity-text\">\n <div class=\"axp-entity-card__title-row\">\n @if (iconClass(); as icon) {\n <!-- ----- Optional header icon from the card layout ----- -->\n <i [class]=\"icon + ' axp-entity-card__icon'\" aria-hidden=\"true\"></i>\n }\n\n <h3 class=\"axp-entity-card__title\">\n {{ titleText() | translate | async }}\n </h3>\n\n @if (showNewBadge()) {\n <!-- ----- New-row highlight badge ----- -->\n <ax-badge class=\"axp-entity-card__header-badge\" [text]=\"('@acorex:dataTable.rowHighlight.new' | translate | async) || ''\" color=\"success\" />\n }\n\n @for (field of headerBadgeFields(); track field.name) {\n <!--------------------------------------------------------------->\n @if (isStatusBadgeField(field)) {\n <!-- ----- Status widget rendered in the header ----- -->\n <div class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldHeaderBadgeNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n <!-- ----- Non-status field rendered as a simple badge ----- -->\n @else if (resolveBadgeText(field)) {\n <ax-badge class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\" [text]=\"resolveBadgeText(field)\" [color]=\"resolveBadgeColor(field)\" />\n }\n }\n </div>\n\n @if (descriptionText()) {\n <!-- ----- Optional description under the title ----- -->\n <p class=\"axp-entity-card__description\">\n {{ descriptionText() | translate | async }}\n </p>\n }\n\n @if (headerMetaFields().length) {\n <!-- ----- Unlabeled header extra (identifier or contact) ----- -->\n <div class=\"axp-entity-card__facts axp-entity-card__facts--inline\">\n @for (field of headerMetaFields(); track field.name) {\n <div class=\"axp-entity-card__fact\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasIdentityActions()) {\n <!-- ----- Selection, overflow actions, or popover dismiss ----- -->\n <div class=\"axp-entity-card__identity-actions\">\n @if (showSelection()) {\n <!-- ----- Multi-select checkbox ----- -->\n <ax-check-box class=\"axp-entity-card__select-checkbox\" [value]=\"selected()\" (onValueChanged)=\"onSelectionCheckboxChange($event)\" (click)=\"onSelectionCheckboxClick($event)\" />\n }\n <!-- ----- Row actions menu when the card is not in selection mode ----- -->\n @else if (secondaryActions().length) {\n <ax-button [look]=\"'blank'\" [color]=\"'default'\" class=\"ax-sm\" (onClick)=\"stopClickPropagation($event)\">\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (item of secondaryActions(); track $index) {\n @if (item.divided) {\n <!-- ----- Divider before this overflow action ----- -->\n <ax-divider />\n }\n <ax-button-item [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\" (onClick)=\"onSecondaryActionClick(item, $event)\">\n @if (item.icon) {\n <!-- ----- Overflow action icon ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-- ----- Close when hosted as a lookup / detail popover ----- -->\n @if (showClose()) {\n <ax-button\n class=\"axp-entity-card__close ax-sm\"\n [look]=\"'blank'\"\n [color]=\"'default'\"\n [iconOnly]=\"true\"\n [attr.title]=\"'@general:actions.close.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.close.title' | translate | async\"\n (onClick)=\"onCloseClick($event)\"\n >\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-button>\n }\n </div>\n }\n </div>\n\n @if (hasLabeledBody()) {\n <!-- ----- Divider between unlabeled identity header and labeled body facts ----- -->\n <div class=\"axp-entity-card__divider\"></div>\n <div class=\"axp-entity-card__body\">\n <div class=\"axp-entity-card__fields\">\n @for (field of previewFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n <!--------------------------------------------------------------->\n @if (extraFields().length) {\n <!-- ----- Extra fields stay mounted; collapse hides them without a body fade ----- -->\n <div class=\"axp-entity-card__extra\" [class.axp-entity-card__extra--collapsed]=\"!extraExpanded()\">\n @for (field of extraFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @if (showInlineMore()) {\n <!-- ----- Quiet More/Less under the fields when the card has no action footer ----- -->\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--inline\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (hasCardFooter()) {\n <!-- ----- One footer row: optional More on the left, primary actions on the right ----- -->\n <footer class=\"axp-entity-card__footer\">\n <!-- ----- More/Less shares the footer with the action button ----- -->\n @if (showFooterMore()) {\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--footer\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n <div class=\"axp-entity-card__footer-actions\">\n @for (action of primaryActions(); track $index) {\n <ax-button\n class=\"axp-entity-card__primary-action ax-sm\"\n [look]=\"primaryActionLook()\"\n [color]=\"action.color\"\n [disabled]=\"action.disabled\"\n [text]=\"(action.title | translate | async)!\"\n (onClick)=\"onPrimaryActionClick(action.name, $event)\"\n >\n @if (action.icon) {\n <!-- ----- Primary action icon ----- -->\n <ax-prefix>\n <i class=\"fa-light {{ action.icon }}\"></i>\n </ax-prefix>\n }\n </ax-button>\n }\n </div>\n </footer>\n }\n</article>\n", styles: ["@layer properties;:host{display:block;width:100%;min-width:0px}:host.axp-entity-card-host--fill{display:flex;width:100%;min-width:0;flex:1 1 auto;flex-direction:column}:host.axp-entity-card-host--elevated{border-radius:var(--radius-md, .375rem);box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-card{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));--axp-entity-card-border: rgb(var(--ax-sys-color-border-light-surface));--axp-entity-card-gutter: 1rem;position:relative;display:flex;width:100%;flex-direction:column;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));background-color:var(--axp-entity-card-surface);border-color:var(--axp-entity-card-border)}.axp-entity-card:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card.axp-entity-card--selected{border-color:rgba(var(--ax-sys-color-primary-500));--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);box-shadow:0 0 0 1px rgb(var(--ax-sys-color-primary-500) / .25),0 2px 6px #0000000f}.axp-entity-card.axp-entity-card--new{border-color:rgb(var(--ax-sys-color-border-success-surface));box-shadow:0 0 0 1px rgb(var(--ax-sys-color-success-500) / .2)}.axp-entity-card.primary{--axp-entity-card-surface: rgb(var(--ax-sys-color-primary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-primary-lightest-surface))}.axp-entity-card.secondary{--axp-entity-card-surface: rgb(var(--ax-sys-color-secondary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-secondary-lightest-surface))}.axp-entity-card.success{--axp-entity-card-surface: rgb(var(--ax-sys-color-success-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-success-lightest-surface))}.axp-entity-card.warning{--axp-entity-card-surface: rgb(var(--ax-sys-color-warning-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-warning-lightest-surface))}.axp-entity-card.danger{--axp-entity-card-surface: rgb(var(--ax-sys-color-danger-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-danger-lightest-surface))}.axp-entity-card.accent1{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent1-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent1-lightest-surface))}.axp-entity-card.accent2{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent2-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent2-lightest-surface))}.axp-entity-card.accent3{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent3-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent3-lightest-surface))}.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3{background-color:var(--axp-entity-card-surface)}:is(.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3) .axp-entity-card__footer{background-color:transparent}.axp-entity-card:not(.axp-entity-card--static){cursor:pointer}.axp-entity-card.axp-entity-card--static{cursor:default}.axp-entity-card.axp-entity-card--elevated{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated .axp-entity-card__footer{background-color:rgb(var(--ax-sys-color-lightest-surface))}.axp-entity-card.axp-entity-card--embedded{border-radius:0;border-style:var(--tw-border-style);border-width:0px;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--axp-entity-card-surface: transparent;background-color:transparent}.axp-entity-card.axp-entity-card--embedded:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__identity{padding-inline:0px;padding-block:0px}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__fields{padding-inline:0px;padding-top:calc(var(--spacing, .25rem) * 2);padding-bottom:0}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__divider{margin-inline:0px}.axp-entity-card .axp-entity-card__identity{display:flex;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__identity-main{display:flex;min-width:0px;flex:1;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__avatar{flex-shrink:0}.axp-entity-card .axp-entity-card__logo{flex-shrink:0;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-surface))}.axp-entity-card .axp-entity-card__logo img{width:100%;height:100%;object-fit:contain}.axp-entity-card .axp-entity-card__qr{display:flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-lightest-surface));padding:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__qr axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__identity-text{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__title-row{display:flex;min-width:0px;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__select-checkbox,.axp-entity-card .axp-entity-card__header-badge{flex-shrink:0}.axp-entity-card .axp-entity-card__identity-actions{display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__close{margin-inline-end:calc(var(--spacing, .25rem) * -1);margin-top:calc(var(--spacing, .25rem) * -.5)}.axp-entity-card .axp-entity-card__content{position:relative;flex:1}.axp-entity-card .axp-entity-card__more{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 8);flex-shrink:0;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding-inline:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__more span,.axp-entity-card .axp-entity-card__more i{pointer-events:none}.axp-entity-card .axp-entity-card__more i{font-size:10px;--tw-leading: 1;line-height:1}.axp-entity-card .axp-entity-card__more:hover,.axp-entity-card .axp-entity-card__more:focus-visible{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__more:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card .axp-entity-card__more--footer{margin-block:calc(var(--spacing, .25rem) * -2.5);margin-inline-start:calc(var(--spacing, .25rem) * -1);min-height:calc(var(--spacing, .25rem) * 10);align-self:stretch;padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__more--inline{margin-inline:var(--axp-entity-card-gutter);margin-top:calc(var(--spacing, .25rem) * .5);margin-bottom:calc(var(--spacing, .25rem) * 2);padding-inline:var(--spacing, .25rem);padding-block:calc(var(--spacing, .25rem) * 2)}.axp-entity-card.axp-entity-card--expanded .axp-entity-card__more{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__title{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-entity-card .axp-entity-card__icon{flex-shrink:0;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__description{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);opacity:65%}.axp-entity-card .axp-entity-card__facts{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-bottom:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__facts--inline{flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:calc(var(--spacing, .25rem) * 4);row-gap:var(--spacing, .25rem);padding-inline:0px;padding-block:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__fact{min-width:0px;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__fact axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__divider{margin-inline:var(--axp-entity-card-gutter);border-top:1px solid var(--axp-entity-card-border)}.axp-entity-card .axp-entity-card__body{position:relative;overflow:hidden}.axp-entity-card .axp-entity-card__extra{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__extra--collapsed{display:none}.axp-entity-card .axp-entity-card__fields{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3{width:auto;margin-inline:calc(-1 * var(--axp-entity-card-gutter));padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__field-row.primary{--axp-entity-styling-border: var(--ax-sys-color-border-primary-lightest-surface);background-color:rgb(var(--ax-sys-color-primary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-primary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__field-row.secondary{--axp-entity-styling-border: var(--ax-sys-color-border-secondary-lightest-surface);background-color:rgb(var(--ax-sys-color-secondary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-secondary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__field-row.success{--axp-entity-styling-border: var(--ax-sys-color-border-success-lightest-surface);background-color:rgb(var(--ax-sys-color-success-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-success-lightest-surface))}.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__field-row.warning{--axp-entity-styling-border: var(--ax-sys-color-border-warning-lightest-surface);background-color:rgb(var(--ax-sys-color-warning-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-warning-lightest-surface))}.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__field-row.danger{--axp-entity-styling-border: var(--ax-sys-color-border-danger-lightest-surface);background-color:rgb(var(--ax-sys-color-danger-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-danger-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__field-row.accent1{--axp-entity-styling-border: var(--ax-sys-color-border-accent1-lightest-surface);background-color:rgb(var(--ax-sys-color-accent1-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent1-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__field-row.accent2{--axp-entity-styling-border: var(--ax-sys-color-border-accent2-lightest-surface);background-color:rgb(var(--ax-sys-color-accent2-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent2-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.accent3,.axp-entity-card .axp-entity-card__field-row.accent3{--axp-entity-styling-border: var(--ax-sys-color-border-accent3-lightest-surface);background-color:rgb(var(--ax-sys-color-accent3-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent3-lightest-surface))}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__header-badge.accent3{border-radius:var(--radius-sm, .25rem);padding-inline:var(--spacing, .25rem)}.axp-entity-card .axp-entity-card__field-row{display:flex;width:100%;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__field-label{display:inline-flex;min-width:0px;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__field-value{margin-inline-start:auto;max-width:60%;min-width:0px;overflow:hidden;text-align:start;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);overflow-wrap:break-word;color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;width:100%;max-width:100%;min-width:0px;overflow:hidden;text-align:start;overflow-wrap:break-word}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell *{text-align:start}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell .flex{justify-content:flex-start}.axp-entity-card .axp-entity-card__field-value :is(.truncate,.whitespace-nowrap){max-width:100%;min-width:0px;overflow-wrap:break-word;white-space:normal;overflow:visible;text-overflow:unset}:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-label,:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-value{color:inherit}.axp-entity-card .axp-entity-card__field-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-entity-card .axp-entity-card__footer{margin-top:auto;display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-block:calc(var(--spacing, .25rem) * 2.5);padding-inline:var(--axp-entity-card-gutter);border-top-color:var(--axp-entity-card-border);background-color:var(--axp-entity-card-surface)}.axp-entity-card .axp-entity-card__footer-actions{margin-inline-start:auto;display:flex;min-width:0px;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__primary-action{min-width:0px}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact):not(.axp-entity-card--embedded) .axp-entity-card__identity{padding-block:calc(var(--spacing, .25rem) * 2.5)}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact) .axp-entity-card__title{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact).axp-entity-card--expandable.axp-entity-card--expanded .axp-entity-card__identity{padding-bottom:calc(var(--spacing, .25rem) * 2.5)}:host.axp-entity-card-host--fill .axp-entity-card{display:flex;width:100%;min-height:0;flex:1 1 auto;flex-direction:column}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i4.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "directive", type: AXPUserCardDirective, selector: "[axpUserCard]", inputs: ["axpUserCard", "axpUserCardDisabled", "axpUserCardTrigger"] }, { kind: "component", type: AXPWidgetColumnCellComponent, selector: "axp-widget-column-cell", inputs: ["node", "rowData", "caption"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7798
7983
  }
7799
7984
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityCardComponent, decorators: [{
7800
7985
  type: Component,
@@ -7813,7 +7998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7813
7998
  AXPUserCardDirective,
7814
7999
  AXPWidgetColumnCellComponent,
7815
8000
  ], template: "<article\n class=\"axp-entity-card\"\n [ngClass]=\"recordStylingClass()\"\n [class.axp-entity-card--selected]=\"selected()\"\n [class.axp-entity-card--new]=\"showNewBadge()\"\n [class.axp-entity-card--row]=\"isRowLayout()\"\n [class.axp-entity-card--compact]=\"variant() === 'compact'\"\n [class.axp-entity-card--embedded]=\"embedded()\"\n [class.axp-entity-card--elevated]=\"elevated()\"\n [class.axp-entity-card--static]=\"!interactive()\"\n [class.axp-entity-card--with-body]=\"hasCardBody()\"\n [class.axp-entity-card--with-footer]=\"hasCardFooter()\"\n [class.axp-entity-card--expandable]=\"canShowMore()\"\n [class.axp-entity-card--expanded]=\"extraExpanded()\"\n [attr.role]=\"interactive() ? 'button' : undefined\"\n [attr.tabindex]=\"interactive() ? 0 : undefined\"\n [attr.aria-selected]=\"interactive() ? selected() : undefined\"\n (click)=\"onCardClick($event)\"\n (dblclick)=\"onCardDblClick($event)\"\n (keydown)=\"onCardKeydown($event)\"\n>\n <div class=\"axp-entity-card__content\">\n <!-- ----- Identity row: optional avatar, title, status, and actions ----- -->\n <div class=\"axp-entity-card__identity\">\n <div class=\"axp-entity-card__identity-main\">\n @if (showUserAvatar()) {\n <!-- ----- Person or user identity uses the user avatar ----- -->\n <axp-user-avatar class=\"axp-entity-card__avatar\" [size]=\"avatarSize()\" [userId]=\"userAvatarId()\" [displayName]=\"toDisplayName(titleText())\" [displayAvatar]=\"avatarSrc()\" [showPresence]=\"false\" [axpUserCard]=\"userAvatarId()\" />\n }\n <!--------------------------------------------------------------->\n @if (showIdentityImage()) {\n <!-- ----- Logo or company image for entities that store an image/logo ----- -->\n <div class=\"axp-entity-card__logo\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <img [src]=\"avatarSrc()\" [alt]=\"toDisplayName(titleText())\" />\n </div>\n }\n <!--------------------------------------------------------------->\n @if (identityQrField(); as field) {\n <!-- ----- QR widget occupies the identity visual slot when there is no avatar or logo ----- -->\n <div class=\"axp-entity-card__qr\" [style.width.px]=\"avatarSize()\" [style.height.px]=\"avatarSize()\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n\n <div class=\"axp-entity-card__identity-text\">\n <div class=\"axp-entity-card__title-row\">\n @if (iconClass(); as icon) {\n <!-- ----- Optional header icon from the card layout ----- -->\n <i [class]=\"icon + ' axp-entity-card__icon'\" aria-hidden=\"true\"></i>\n }\n\n <h3 class=\"axp-entity-card__title\">\n {{ titleText() | translate | async }}\n </h3>\n\n @if (showNewBadge()) {\n <!-- ----- New-row highlight badge ----- -->\n <ax-badge class=\"axp-entity-card__header-badge\" [text]=\"('@acorex:dataTable.rowHighlight.new' | translate | async) || ''\" color=\"success\" />\n }\n\n @for (field of headerBadgeFields(); track field.name) {\n <!--------------------------------------------------------------->\n @if (isStatusBadgeField(field)) {\n <!-- ----- Status widget rendered in the header ----- -->\n <div class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldHeaderBadgeNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n <!-- ----- Non-status field rendered as a simple badge ----- -->\n @else if (resolveBadgeText(field)) {\n <ax-badge class=\"axp-entity-card__header-badge\" [ngClass]=\"fieldStylingClass(field.name)\" [text]=\"resolveBadgeText(field)\" [color]=\"resolveBadgeColor(field)\" />\n }\n }\n </div>\n\n @if (descriptionText()) {\n <!-- ----- Optional description under the title ----- -->\n <p class=\"axp-entity-card__description\">\n {{ descriptionText() | translate | async }}\n </p>\n }\n\n @if (headerMetaFields().length) {\n <!-- ----- Unlabeled header extra (identifier or contact) ----- -->\n <div class=\"axp-entity-card__facts axp-entity-card__facts--inline\">\n @for (field of headerMetaFields(); track field.name) {\n <div class=\"axp-entity-card__fact\" [ngClass]=\"fieldStylingClass(field.name)\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (hasIdentityActions()) {\n <!-- ----- Selection, overflow actions, or popover dismiss ----- -->\n <div class=\"axp-entity-card__identity-actions\">\n @if (showSelection()) {\n <!-- ----- Multi-select checkbox ----- -->\n <ax-check-box class=\"axp-entity-card__select-checkbox\" [value]=\"selected()\" (onValueChanged)=\"onSelectionCheckboxChange($event)\" (click)=\"onSelectionCheckboxClick($event)\" />\n }\n <!-- ----- Row actions menu when the card is not in selection mode ----- -->\n @else if (secondaryActions().length) {\n <ax-button [look]=\"'blank'\" [color]=\"'default'\" class=\"ax-sm\" (onClick)=\"stopClickPropagation($event)\">\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (item of secondaryActions(); track $index) {\n @if (item.divided) {\n <!-- ----- Divider before this overflow action ----- -->\n <ax-divider />\n }\n <ax-button-item [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\" (onClick)=\"onSecondaryActionClick(item, $event)\">\n @if (item.icon) {\n <!-- ----- Overflow action icon ----- -->\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-- ----- Close when hosted as a lookup / detail popover ----- -->\n @if (showClose()) {\n <ax-button\n class=\"axp-entity-card__close ax-sm\"\n [look]=\"'blank'\"\n [color]=\"'default'\"\n [iconOnly]=\"true\"\n [attr.title]=\"'@general:actions.close.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.close.title' | translate | async\"\n (onClick)=\"onCloseClick($event)\"\n >\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-button>\n }\n </div>\n }\n </div>\n\n @if (hasLabeledBody()) {\n <!-- ----- Divider between unlabeled identity header and labeled body facts ----- -->\n <div class=\"axp-entity-card__divider\"></div>\n <div class=\"axp-entity-card__body\">\n <div class=\"axp-entity-card__fields\">\n @for (field of previewFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n <!--------------------------------------------------------------->\n @if (extraFields().length) {\n <!-- ----- Extra fields stay mounted; collapse hides them without a body fade ----- -->\n <div class=\"axp-entity-card__extra\" [class.axp-entity-card__extra--collapsed]=\"!extraExpanded()\">\n @for (field of extraFields(); track field.name) {\n <div class=\"axp-entity-card__field-row\" [ngClass]=\"fieldStylingClass(field.name)\">\n <span class=\"axp-entity-card__field-label\">\n @if (resolveFieldIcon(field); as icon) {\n <!-- ----- Field icon from lookup entity or widget definition ----- -->\n <i class=\"axp-entity-card__field-icon {{ icon }}\" aria-hidden=\"true\"></i>\n }\n {{ field.title | translate | async }}\n </span>\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"fieldColumnNode(field)\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @if (showInlineMore()) {\n <!-- ----- Quiet More/Less under the fields when the card has no action footer ----- -->\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--inline\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (hasCardFooter()) {\n <!-- ----- One footer row: optional More on the left, primary actions on the right ----- -->\n <footer class=\"axp-entity-card__footer\">\n <!-- ----- More/Less shares the footer with the action button ----- -->\n @if (showFooterMore()) {\n <button type=\"button\" class=\"axp-entity-card__more axp-entity-card__more--footer\" [attr.aria-expanded]=\"extraExpanded()\" (click)=\"onToggleExtra($event)\">\n <span>\n {{ (extraExpanded() ? '@general:terms.interface.less-card' : '@general:terms.interface.more-card') | translate | async }}\n </span>\n <i class=\"fa-light\" [class.fa-chevron-down]=\"!extraExpanded()\" [class.fa-chevron-up]=\"extraExpanded()\" aria-hidden=\"true\"></i>\n </button>\n }\n <div class=\"axp-entity-card__footer-actions\">\n @for (action of primaryActions(); track $index) {\n <ax-button\n class=\"axp-entity-card__primary-action ax-sm\"\n [look]=\"primaryActionLook()\"\n [color]=\"action.color\"\n [disabled]=\"action.disabled\"\n [text]=\"(action.title | translate | async)!\"\n (onClick)=\"onPrimaryActionClick(action.name, $event)\"\n >\n @if (action.icon) {\n <!-- ----- Primary action icon ----- -->\n <ax-prefix>\n <i class=\"fa-light {{ action.icon }}\"></i>\n </ax-prefix>\n }\n </ax-button>\n }\n </div>\n </footer>\n }\n</article>\n", styles: ["@layer properties;:host{display:block;width:100%;min-width:0px}:host.axp-entity-card-host--fill{display:flex;width:100%;min-width:0;flex:1 1 auto;flex-direction:column}:host.axp-entity-card-host--elevated{border-radius:var(--radius-md, .375rem);box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-card{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));--axp-entity-card-border: rgb(var(--ax-sys-color-border-light-surface));--axp-entity-card-gutter: 1rem;position:relative;display:flex;width:100%;flex-direction:column;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));background-color:var(--axp-entity-card-surface);border-color:var(--axp-entity-card-border)}.axp-entity-card:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card.axp-entity-card--selected{border-color:rgba(var(--ax-sys-color-primary-500));--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);box-shadow:0 0 0 1px rgb(var(--ax-sys-color-primary-500) / .25),0 2px 6px #0000000f}.axp-entity-card.axp-entity-card--new{border-color:rgb(var(--ax-sys-color-border-success-surface));box-shadow:0 0 0 1px rgb(var(--ax-sys-color-success-500) / .2)}.axp-entity-card.primary{--axp-entity-card-surface: rgb(var(--ax-sys-color-primary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-primary-lightest-surface))}.axp-entity-card.secondary{--axp-entity-card-surface: rgb(var(--ax-sys-color-secondary-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-secondary-lightest-surface))}.axp-entity-card.success{--axp-entity-card-surface: rgb(var(--ax-sys-color-success-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-success-lightest-surface))}.axp-entity-card.warning{--axp-entity-card-surface: rgb(var(--ax-sys-color-warning-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-warning-lightest-surface))}.axp-entity-card.danger{--axp-entity-card-surface: rgb(var(--ax-sys-color-danger-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-danger-lightest-surface))}.axp-entity-card.accent1{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent1-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent1-lightest-surface))}.axp-entity-card.accent2{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent2-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent2-lightest-surface))}.axp-entity-card.accent3{--axp-entity-card-surface: rgb(var(--ax-sys-color-accent3-50));--axp-entity-card-border: rgb(var(--ax-sys-color-border-accent3-lightest-surface))}.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3{background-color:var(--axp-entity-card-surface)}:is(.axp-entity-card.primary,.axp-entity-card.secondary,.axp-entity-card.success,.axp-entity-card.warning,.axp-entity-card.danger,.axp-entity-card.accent1,.axp-entity-card.accent2,.axp-entity-card.accent3) .axp-entity-card__footer{background-color:transparent}.axp-entity-card:not(.axp-entity-card--static){cursor:pointer}.axp-entity-card.axp-entity-card--static{cursor:default}.axp-entity-card.axp-entity-card--elevated{--axp-entity-card-surface: rgb(var(--ax-sys-color-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--elevated .axp-entity-card__footer{background-color:rgb(var(--ax-sys-color-lightest-surface))}.axp-entity-card.axp-entity-card--embedded{border-radius:0;border-style:var(--tw-border-style);border-width:0px;--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--axp-entity-card-surface: transparent;background-color:transparent}.axp-entity-card.axp-entity-card--embedded:hover{--tw-shadow: 0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__identity{padding-inline:0px;padding-block:0px}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__fields{padding-inline:0px;padding-top:calc(var(--spacing, .25rem) * 2);padding-bottom:0}.axp-entity-card.axp-entity-card--embedded .axp-entity-card__divider{margin-inline:0px}.axp-entity-card .axp-entity-card__identity{display:flex;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__identity-main{display:flex;min-width:0px;flex:1;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__avatar{flex-shrink:0}.axp-entity-card .axp-entity-card__logo{flex-shrink:0;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-surface))}.axp-entity-card .axp-entity-card__logo img{width:100%;height:100%;object-fit:contain}.axp-entity-card .axp-entity-card__qr{display:flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-light-surface));background-color:rgba(var(--ax-sys-color-lightest-surface));padding:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__qr axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__identity-text{display:flex;min-width:0px;flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__title-row{display:flex;min-width:0px;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__select-checkbox,.axp-entity-card .axp-entity-card__header-badge{flex-shrink:0}.axp-entity-card .axp-entity-card__identity-actions{display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__close{margin-inline-end:calc(var(--spacing, .25rem) * -1);margin-top:calc(var(--spacing, .25rem) * -.5)}.axp-entity-card .axp-entity-card__content{position:relative;flex:1}.axp-entity-card .axp-entity-card__more{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 8);flex-shrink:0;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding-inline:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__more span,.axp-entity-card .axp-entity-card__more i{pointer-events:none}.axp-entity-card .axp-entity-card__more i{font-size:10px;--tw-leading: 1;line-height:1}.axp-entity-card .axp-entity-card__more:hover,.axp-entity-card .axp-entity-card__more:focus-visible{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__more:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500))}.axp-entity-card .axp-entity-card__more--footer{margin-block:calc(var(--spacing, .25rem) * -2.5);margin-inline-start:calc(var(--spacing, .25rem) * -1);min-height:calc(var(--spacing, .25rem) * 10);align-self:stretch;padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__more--inline{margin-inline:var(--axp-entity-card-gutter);margin-top:calc(var(--spacing, .25rem) * .5);margin-bottom:calc(var(--spacing, .25rem) * 2);padding-inline:var(--spacing, .25rem);padding-block:calc(var(--spacing, .25rem) * 2)}.axp-entity-card.axp-entity-card--expanded .axp-entity-card__more{color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__title{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-entity-card .axp-entity-card__icon{flex-shrink:0;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__description{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);opacity:65%}.axp-entity-card .axp-entity-card__facts{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-bottom:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__facts--inline{flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:calc(var(--spacing, .25rem) * 4);row-gap:var(--spacing, .25rem);padding-inline:0px;padding-block:calc(var(--spacing, .25rem) * .5)}.axp-entity-card .axp-entity-card__fact{min-width:0px;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-lightest-surface))}.axp-entity-card .axp-entity-card__fact axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card .axp-entity-card__divider{margin-inline:var(--axp-entity-card-gutter);border-top:1px solid var(--axp-entity-card-border)}.axp-entity-card .axp-entity-card__body{position:relative;overflow:hidden}.axp-entity-card .axp-entity-card__extra{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__extra--collapsed{display:none}.axp-entity-card .axp-entity-card__fields{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 3);padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3{width:auto;margin-inline:calc(-1 * var(--axp-entity-card-gutter));padding-inline:var(--axp-entity-card-gutter)}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__field-row.primary{--axp-entity-styling-border: var(--ax-sys-color-border-primary-lightest-surface);background-color:rgb(var(--ax-sys-color-primary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-primary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__field-row.secondary{--axp-entity-styling-border: var(--ax-sys-color-border-secondary-lightest-surface);background-color:rgb(var(--ax-sys-color-secondary-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-secondary-lightest-surface))}.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__field-row.success{--axp-entity-styling-border: var(--ax-sys-color-border-success-lightest-surface);background-color:rgb(var(--ax-sys-color-success-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-success-lightest-surface))}.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__field-row.warning{--axp-entity-styling-border: var(--ax-sys-color-border-warning-lightest-surface);background-color:rgb(var(--ax-sys-color-warning-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-warning-lightest-surface))}.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__field-row.danger{--axp-entity-styling-border: var(--ax-sys-color-border-danger-lightest-surface);background-color:rgb(var(--ax-sys-color-danger-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-danger-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__field-row.accent1{--axp-entity-styling-border: var(--ax-sys-color-border-accent1-lightest-surface);background-color:rgb(var(--ax-sys-color-accent1-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent1-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__field-row.accent2{--axp-entity-styling-border: var(--ax-sys-color-border-accent2-lightest-surface);background-color:rgb(var(--ax-sys-color-accent2-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent2-lightest-surface))}.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.accent3,.axp-entity-card .axp-entity-card__field-row.accent3{--axp-entity-styling-border: var(--ax-sys-color-border-accent3-lightest-surface);background-color:rgb(var(--ax-sys-color-accent3-100));box-shadow:inset 0 0 0 1px rgb(var(--axp-entity-styling-border) / .35);color:rgb(var(--ax-sys-color-on-accent3-lightest-surface))}.axp-entity-card .axp-entity-card__fact.primary,.axp-entity-card .axp-entity-card__fact.secondary,.axp-entity-card .axp-entity-card__fact.success,.axp-entity-card .axp-entity-card__fact.warning,.axp-entity-card .axp-entity-card__fact.danger,.axp-entity-card .axp-entity-card__fact.accent1,.axp-entity-card .axp-entity-card__fact.accent2,.axp-entity-card .axp-entity-card__fact.accent3,.axp-entity-card .axp-entity-card__header-badge.primary,.axp-entity-card .axp-entity-card__header-badge.secondary,.axp-entity-card .axp-entity-card__header-badge.success,.axp-entity-card .axp-entity-card__header-badge.warning,.axp-entity-card .axp-entity-card__header-badge.danger,.axp-entity-card .axp-entity-card__header-badge.accent1,.axp-entity-card .axp-entity-card__header-badge.accent2,.axp-entity-card .axp-entity-card__header-badge.accent3{border-radius:var(--radius-sm, .25rem);padding-inline:var(--spacing, .25rem)}.axp-entity-card .axp-entity-card__field-row{display:flex;width:100%;align-items:flex-start;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}.axp-entity-card .axp-entity-card__field-label{display:inline-flex;min-width:0px;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);text-align:start;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:var(--color-gray-500, oklch(55.1% .027 264.364))}.axp-entity-card .axp-entity-card__field-value{margin-inline-start:auto;max-width:60%;min-width:0px;overflow:hidden;text-align:start;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);overflow-wrap:break-word;color:rgba(var(--ax-sys-color-on-surface))}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;width:100%;max-width:100%;min-width:0px;overflow:hidden;text-align:start;overflow-wrap:break-word}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell *{text-align:start}.axp-entity-card .axp-entity-card__field-value axp-widget-column-cell .flex{justify-content:flex-start}.axp-entity-card .axp-entity-card__field-value :is(.truncate,.whitespace-nowrap){max-width:100%;min-width:0px;overflow-wrap:break-word;white-space:normal;overflow:visible;text-overflow:unset}:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-label,:is(.axp-entity-card .axp-entity-card__field-row.primary,.axp-entity-card .axp-entity-card__field-row.secondary,.axp-entity-card .axp-entity-card__field-row.success,.axp-entity-card .axp-entity-card__field-row.warning,.axp-entity-card .axp-entity-card__field-row.danger,.axp-entity-card .axp-entity-card__field-row.accent1,.axp-entity-card .axp-entity-card__field-row.accent2,.axp-entity-card .axp-entity-card__field-row.accent3) .axp-entity-card__field-value{color:inherit}.axp-entity-card .axp-entity-card__field-icon{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-gray-400, oklch(70.7% .022 261.325))}.axp-entity-card .axp-entity-card__footer{margin-top:auto;display:flex;flex-shrink:0;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-top-style:var(--tw-border-style);border-top-width:1px;padding-block:calc(var(--spacing, .25rem) * 2.5);padding-inline:var(--axp-entity-card-gutter);border-top-color:var(--axp-entity-card-border);background-color:var(--axp-entity-card-surface)}.axp-entity-card .axp-entity-card__footer-actions{margin-inline-start:auto;display:flex;min-width:0px;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}.axp-entity-card .axp-entity-card__primary-action{min-width:0px}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact):not(.axp-entity-card--embedded) .axp-entity-card__identity{padding-block:calc(var(--spacing, .25rem) * 2.5)}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact) .axp-entity-card__title{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}:is(.axp-entity-card.axp-entity-card--row,.axp-entity-card.axp-entity-card--compact).axp-entity-card--expandable.axp-entity-card--expanded .axp-entity-card__identity{padding-bottom:calc(var(--spacing, .25rem) * 2.5)}:host.axp-entity-card-host--fill .axp-entity-card{display:flex;width:100%;min-height:0;flex:1 1 auto;flex-direction:column}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7816
- }], ctorParameters: () => [], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], elevated: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevated", required: false }] }], disableLookupPopover: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableLookupPopover", required: false }] }], fillHost: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHost", required: false }] }], extraExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraExpanded", required: false }] }, { type: i0.Output, args: ["extraExpandedChange"] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], showNewBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNewBadge", required: false }] }], showSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelection", required: false }] }], showClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClose", required: false }] }], primaryActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryActions", required: false }] }], primaryActionLook: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryActionLook", required: false }] }], secondaryActionLoader: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActionLoader", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], commandClick: [{ type: i0.Output, args: ["commandClick"] }], closeClick: [{ type: i0.Output, args: ["closeClick"] }] } });
8001
+ }], ctorParameters: () => [], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], userStylingRules: [{ type: i0.Input, args: [{ isSignal: true, alias: "userStylingRules", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], elevated: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevated", required: false }] }], disableLookupPopover: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableLookupPopover", required: false }] }], fillHost: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHost", required: false }] }], extraExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraExpanded", required: false }] }, { type: i0.Output, args: ["extraExpandedChange"] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], showNewBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNewBadge", required: false }] }], showSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelection", required: false }] }], showClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClose", required: false }] }], primaryActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryActions", required: false }] }], primaryActionLook: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryActionLook", required: false }] }], secondaryActionLoader: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActionLoader", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], commandClick: [{ type: i0.Output, args: ["commandClick"] }], closeClick: [{ type: i0.Output, args: ["closeClick"] }] } });
7817
8002
 
7818
8003
  class AXPEntityDetailPopoverComponent {
7819
8004
  constructor() {
@@ -7947,7 +8132,7 @@ class AXPEntityDetailPopoverComponent {
7947
8132
  }
7948
8133
  }
7949
8134
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityDetailPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7950
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-entity-detail-popover\">\n @if (breadcrumb()) {\n <!-- ----- Optional lookup breadcrumb above the shared entity card ----- -->\n <div class=\"text-xs text-neutral-500 mb-2\">{{ breadcrumb() }}</div>\n }\n @if (isLoadingDetails()) {\n <!-- ----- Loading placeholder while Entity:GetDetails is fetched ----- -->\n <div class=\"axp-entity-detail-popover__loading\">\n @if (canClose()) {\n <!-- ----- Dismiss while the lookup card is still loading ----- -->\n <ax-button\n class=\"axp-entity-detail-popover__close ax-sm\"\n [look]=\"'blank'\"\n [color]=\"'default'\"\n [iconOnly]=\"true\"\n [attr.title]=\"('@general:actions.close.title' | translate | async)\"\n [attr.aria-label]=\"('@general:actions.close.title' | translate | async)\"\n (onClick)=\"onClose()\"\n >\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-button>\n }\n <axp-entity-card-skeleton\n [fieldCount]=\"skeletonFieldCount()\"\n [badgeCount]=\"skeletonBadgeCount()\"\n [showContent]=\"true\"\n [showFooter]=\"true\"\n [showAvatar]=\"showSkeletonAvatar()\"\n [elevated]=\"true\"\n />\n </div>\n }\n <!-- ----- Same card chrome as the master list; Open Details uses the card footer ----- -->\n @else if (entityDefinition(); as definition) {\n <!--->\n <!-- ----- Entity card when row details have loaded ----- -->\n @if (entityData(); as row) {\n <axp-entity-card\n [entity]=\"definition\"\n [layout]=\"cardLayout()\"\n [row]=\"row\"\n [fields]=\"cardFields()\"\n variant=\"card\"\n [interactive]=\"false\"\n [elevated]=\"true\"\n [showClose]=\"canClose()\"\n primaryActionLook=\"solid\"\n [disableLookupPopover]=\"true\"\n [primaryActions]=\"openDetailsActions()\"\n (commandClick)=\"onCardCommandClick($event)\"\n (closeClick)=\"onClose()\"\n />\n }\n }\n</div>\n", styles: [":host{display:block;border-radius:var(--radius-md, .375rem);width:min(600px,calc(100vw - 2rem));background-color:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-detail-popover__loading{position:relative}.axp-entity-detail-popover__close{position:absolute;z-index:20;inset-block-start:.75rem;inset-inline-end:1rem}.axp-entity-detail-popover-overlay,.axp-entity-detail-popover-overlay.ax-overlay-container,.axp-entity-detail-popover-overlay.ax-overlay-pane,.axp-entity-detail-popover-overlay .ax-overlay-pane,.axp-entity-detail-popover-overlay .overlay-pane{width:min(600px,calc(100vw - 2rem))!important;min-width:min(600px,calc(100vw - 2rem));overflow:visible!important;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPEntityCardComponent, selector: "axp-entity-card", inputs: ["entity", "layout", "row", "fields", "variant", "interactive", "embedded", "elevated", "disableLookupPopover", "fillHost", "extraExpanded", "selected", "showNewBadge", "showSelection", "showClose", "primaryActions", "primaryActionLook", "secondaryActionLoader"], outputs: ["extraExpandedChange", "selectionChange", "commandClick", "closeClick"] }, { kind: "component", type: AXPEntityCardSkeletonComponent, selector: "axp-entity-card-skeleton", inputs: ["fieldCount", "badgeCount", "showFooter", "showHeaderMenu", "showContent", "rowLayout", "showAvatar", "fillHost", "embedded", "elevated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-entity-detail-popover\">\n @if (breadcrumb()) {\n <!-- ----- Optional lookup breadcrumb above the shared entity card ----- -->\n <div class=\"text-xs text-neutral-500 mb-2\">{{ breadcrumb() }}</div>\n }\n @if (isLoadingDetails()) {\n <!-- ----- Loading placeholder while Entity:GetDetails is fetched ----- -->\n <div class=\"axp-entity-detail-popover__loading\">\n @if (canClose()) {\n <!-- ----- Dismiss while the lookup card is still loading ----- -->\n <ax-button\n class=\"axp-entity-detail-popover__close ax-sm\"\n [look]=\"'blank'\"\n [color]=\"'default'\"\n [iconOnly]=\"true\"\n [attr.title]=\"('@general:actions.close.title' | translate | async)\"\n [attr.aria-label]=\"('@general:actions.close.title' | translate | async)\"\n (onClick)=\"onClose()\"\n >\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-button>\n }\n <axp-entity-card-skeleton\n [fieldCount]=\"skeletonFieldCount()\"\n [badgeCount]=\"skeletonBadgeCount()\"\n [showContent]=\"true\"\n [showFooter]=\"true\"\n [showAvatar]=\"showSkeletonAvatar()\"\n [elevated]=\"true\"\n />\n </div>\n }\n <!-- ----- Same card chrome as the master list; Open Details uses the card footer ----- -->\n @else if (entityDefinition(); as definition) {\n <!--->\n <!-- ----- Entity card when row details have loaded ----- -->\n @if (entityData(); as row) {\n <axp-entity-card\n [entity]=\"definition\"\n [layout]=\"cardLayout()\"\n [row]=\"row\"\n [fields]=\"cardFields()\"\n variant=\"card\"\n [interactive]=\"false\"\n [elevated]=\"true\"\n [showClose]=\"canClose()\"\n primaryActionLook=\"solid\"\n [disableLookupPopover]=\"true\"\n [primaryActions]=\"openDetailsActions()\"\n (commandClick)=\"onCardCommandClick($event)\"\n (closeClick)=\"onClose()\"\n />\n }\n }\n</div>\n", styles: [":host{display:block;border-radius:var(--radius-md, .375rem);width:min(600px,calc(100vw - 2rem));background-color:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 8px 16px #00000029,0 24px 48px #00000038,0 48px 96px #00000047}.axp-entity-detail-popover__loading{position:relative}.axp-entity-detail-popover__close{position:absolute;z-index:20;inset-block-start:.75rem;inset-inline-end:1rem}.axp-entity-detail-popover-overlay,.axp-entity-detail-popover-overlay.ax-overlay-container,.axp-entity-detail-popover-overlay.ax-overlay-pane,.axp-entity-detail-popover-overlay .ax-overlay-pane,.axp-entity-detail-popover-overlay .overlay-pane{width:min(600px,calc(100vw - 2rem))!important;min-width:min(600px,calc(100vw - 2rem));overflow:visible!important;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPEntityCardComponent, selector: "axp-entity-card", inputs: ["entity", "layout", "row", "fields", "userStylingRules", "variant", "interactive", "embedded", "elevated", "disableLookupPopover", "fillHost", "extraExpanded", "selected", "showNewBadge", "showSelection", "showClose", "primaryActions", "primaryActionLook", "secondaryActionLoader"], outputs: ["extraExpandedChange", "selectionChange", "commandClick", "closeClick"] }, { kind: "component", type: AXPEntityCardSkeletonComponent, selector: "axp-entity-card-skeleton", inputs: ["fieldCount", "badgeCount", "showFooter", "showHeaderMenu", "showContent", "rowLayout", "showAvatar", "fillHost", "embedded", "elevated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
7951
8136
  }
7952
8137
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityDetailPopoverComponent, decorators: [{
7953
8138
  type: Component,
@@ -9138,6 +9323,41 @@ function fireEntityLifecycleHook(hooks, key, payload) {
9138
9323
  }
9139
9324
  }
9140
9325
 
9326
+ //#region ----- Entity list column settings (configure APIs) -----
9327
+ /**
9328
+ * Product modules register column names whose persisted list prefs should be
9329
+ * dropped once when migrating to a newer {@link getEntityListColumnsSettingsVersion}.
9330
+ * Framework keeps empty defaults — no product column names here.
9331
+ */
9332
+ let columnsSettingsVersion = 1;
9333
+ const migrateDropColumns = new Set();
9334
+ /** Raise the persisted columns-settings schema version (monotonic). */
9335
+ function configureEntityListColumnsSettingsVersion(version) {
9336
+ if (!Number.isFinite(version)) {
9337
+ return;
9338
+ }
9339
+ const next = Math.floor(version);
9340
+ if (next > columnsSettingsVersion) {
9341
+ columnsSettingsVersion = next;
9342
+ }
9343
+ }
9344
+ /** Register column names to strip from stale user list prefs during version migration. */
9345
+ function configureEntityListColumnsSettingsMigrateDrop(columnNames) {
9346
+ for (const name of columnNames) {
9347
+ const trimmed = String(name ?? '').trim();
9348
+ if (trimmed) {
9349
+ migrateDropColumns.add(trimmed);
9350
+ }
9351
+ }
9352
+ }
9353
+ function getEntityListColumnsSettingsVersion() {
9354
+ return columnsSettingsVersion;
9355
+ }
9356
+ function getEntityListColumnsSettingsMigrateDrop() {
9357
+ return migrateDropColumns;
9358
+ }
9359
+ //#endregion
9360
+
9141
9361
  /**
9142
9362
  * Resolves a stable row id from entity list row data.
9143
9363
  */
@@ -9215,6 +9435,15 @@ function normalizeEntityListPersistenceMode(value) {
9215
9435
  function canPersistEntityListState(mode) {
9216
9436
  return mode !== 'none';
9217
9437
  }
9438
+ const ENTITY_LIST_STYLING_RULES_PATH = ['list', 'stylingRules'];
9439
+ /** Personal highlight rules live on the entity setting, not on one query view. */
9440
+ function entityListStylingRulesPath() {
9441
+ return ENTITY_LIST_STYLING_RULES_PATH;
9442
+ }
9443
+ /** Personal highlight rules for this entity. Shared by every view of the list. */
9444
+ function readPersistedEntityListStylingRules(setting) {
9445
+ return normalizeEntityListUserStylingRules(getNested(setting, [...ENTITY_LIST_STYLING_RULES_PATH]));
9446
+ }
9218
9447
  /** `none` never reads list state from user settings. */
9219
9448
  function shouldLoadEntityListStateFromStorage(mode) {
9220
9449
  return mode !== 'none';
@@ -9224,6 +9453,55 @@ function shouldResetEntityListStateOnRouteEntry(mode) {
9224
9453
  return mode === 'route';
9225
9454
  }
9226
9455
  const ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY = 'axp-entity-list-route-context';
9456
+ function entityListInstanceFilterPath(instanceId, viewName) {
9457
+ return ['list', 'instances', instanceId, 'views', viewName, 'filters'];
9458
+ }
9459
+ function entityListInstanceCurrentViewPath(instanceId) {
9460
+ return ['list', 'instances', instanceId, 'currentView'];
9461
+ }
9462
+ function readPersistedEntityListInstanceFilters(setting, instanceId, viewName) {
9463
+ const instanceFilters = getNested(setting, entityListInstanceFilterPath(instanceId, viewName));
9464
+ if (instanceFilters === null) {
9465
+ return [];
9466
+ }
9467
+ if (Array.isArray(instanceFilters)) {
9468
+ return instanceFilters;
9469
+ }
9470
+ if (instanceId === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
9471
+ const legacy = getNested(setting, ['list', 'views', viewName, 'filters']);
9472
+ if (Array.isArray(legacy)) {
9473
+ return legacy;
9474
+ }
9475
+ }
9476
+ return undefined;
9477
+ }
9478
+ function readPersistedEntityListInstanceCurrentView(setting, instanceId) {
9479
+ const instanceView = getNested(setting, entityListInstanceCurrentViewPath(instanceId));
9480
+ if (typeof instanceView === 'string' && instanceView.trim()) {
9481
+ return instanceView;
9482
+ }
9483
+ if (instanceId === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
9484
+ const legacy = getNested(setting, ['list', 'currentView']);
9485
+ if (typeof legacy === 'string' && legacy.trim()) {
9486
+ return legacy;
9487
+ }
9488
+ }
9489
+ return undefined;
9490
+ }
9491
+ /** View conditions first; persisted user filters overlay fields the view does not already own. */
9492
+ function mergeEntityListViewAndPersistedFilters(viewFilters, persisted) {
9493
+ return mergeQueryViewAndUserFilters(viewFilters, persisted);
9494
+ }
9495
+ function getNested(source, path) {
9496
+ let current = source;
9497
+ for (const key of path) {
9498
+ if (!current || typeof current !== 'object') {
9499
+ return undefined;
9500
+ }
9501
+ current = current[String(key)];
9502
+ }
9503
+ return current;
9504
+ }
9227
9505
 
9228
9506
  class AXPEntityCreateViewSectionViewModel {
9229
9507
  constructor(entity, section) {
@@ -9425,6 +9703,336 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9425
9703
  args: [{ providedIn: 'root' }]
9426
9704
  }] });
9427
9705
 
9706
+ //#region ----- Imports -----
9707
+ //#endregion
9708
+ //#region ----- Constants -----
9709
+ const PREVIEW_TITLE_CAP = 8;
9710
+ const PREVIEW_TITLE_MAX_CHARS = 80;
9711
+ const SECRET_NAME_PATTERN = /password|secret|token|apikey|api_key|credential|privatekey|private_key/i;
9712
+ const FILTER_OPERATOR_TYPES = new Set([
9713
+ 'equal',
9714
+ 'isNull',
9715
+ 'isEmpty',
9716
+ 'lt',
9717
+ 'lte',
9718
+ 'gt',
9719
+ 'gte',
9720
+ 'startsWith',
9721
+ 'endsWith',
9722
+ 'contains',
9723
+ 'in',
9724
+ ]);
9725
+ const ENTITY_LIST_ACTIONS = [
9726
+ {
9727
+ id: 'set-view',
9728
+ title: 'Set list view',
9729
+ params: [{ name: 'viewName', required: true, description: 'View name from snapshot.views[].name (e.g. archive).' }],
9730
+ },
9731
+ {
9732
+ id: 'set-filter',
9733
+ title: 'Set filter',
9734
+ params: [
9735
+ { name: 'field', required: true, description: 'Filter field from snapshot.filterFields[].field.' },
9736
+ { name: 'operatorType', required: true, description: 'equal, contains, in, startsWith, …' },
9737
+ { name: 'value', required: true, description: 'Filter value.' },
9738
+ ],
9739
+ },
9740
+ {
9741
+ id: 'remove-filter',
9742
+ title: 'Remove filter',
9743
+ params: [{ name: 'field', required: true, description: 'Visible filter field to remove (not hidden view conditions).' }],
9744
+ },
9745
+ {
9746
+ id: 'clear-filters',
9747
+ title: 'Clear filters',
9748
+ params: [],
9749
+ },
9750
+ {
9751
+ id: 'set-search',
9752
+ title: 'Set list search',
9753
+ params: [{ name: 'text', required: false, description: 'Quick-search text. Empty string clears search.' }],
9754
+ },
9755
+ ];
9756
+ //#endregion
9757
+ //#region ----- Snapshot -----
9758
+ function axpBuildEntityListPageContextSnapshot(vm, resolveTitle) {
9759
+ const entityInfo = getEntityInfo(vm.entityDef);
9760
+ const fullName = entityInfo.source;
9761
+ const currentView = vm.view();
9762
+ const filters = vm.filterQueries();
9763
+ const filterDefs = vm.filterDefinitions();
9764
+ const quickSearch = readQuickSearch(filters);
9765
+ const dataSource = vm.dataSource;
9766
+ const isLoading = dataSource.isLoading === true;
9767
+ const itemCount = dataSource.items?.length ?? 0;
9768
+ const status = isLoading ? 'loading' : itemCount === 0 ? 'empty' : 'ready';
9769
+ const filterFieldTitleByName = new Map();
9770
+ for (const def of filterDefs) {
9771
+ const field = def.field?.trim();
9772
+ if (!field) {
9773
+ continue;
9774
+ }
9775
+ filterFieldTitleByName.set(field, resolveTitle(def.title) || field);
9776
+ }
9777
+ const snapshotFilters = flattenQueryFilterUserGroups(filters)
9778
+ .queries.filter((f) => !isQuickSearchField(f.field))
9779
+ .map((f) => {
9780
+ const field = typeof f.field === 'string' ? f.field : '';
9781
+ const operatorType = typeof f.operator?.type === 'string' ? f.operator.type : undefined;
9782
+ return {
9783
+ field,
9784
+ operatorType,
9785
+ value: f.value,
9786
+ title: filterFieldTitleByName.get(field) ?? (typeof f.displayText === 'string' ? f.displayText : undefined),
9787
+ hidden: f.hidden === true,
9788
+ };
9789
+ })
9790
+ .filter((f) => f.field.length > 0);
9791
+ const columns = vm
9792
+ .columns()
9793
+ .filter((c) => c.visible)
9794
+ .map((c) => ({
9795
+ name: c.name,
9796
+ title: resolveTitle(c.title) || c.name,
9797
+ }));
9798
+ const selectedRecords = readSelectedRecords(vm, resolveTitle);
9799
+ const selectedIds = selectedRecords.map((row) => row.id);
9800
+ const sorts = vm
9801
+ .sortedFields()
9802
+ .filter((s) => s.dir)
9803
+ .map((s) => ({ field: s.name, dir: s.dir }));
9804
+ return {
9805
+ kind: 'entity-list',
9806
+ title: resolveTitle(vm.title()) || fullName,
9807
+ status,
9808
+ entity: {
9809
+ fullName,
9810
+ title: resolveTitle(vm.entityDef.formats.plural) || fullName,
9811
+ },
9812
+ view: {
9813
+ name: currentView.name,
9814
+ title: resolveTitle(currentView.title) || currentView.name,
9815
+ },
9816
+ views: vm.views().map((v) => ({
9817
+ name: v.name,
9818
+ title: resolveTitle(v.title) || v.name,
9819
+ })),
9820
+ filters: snapshotFilters,
9821
+ filterFields: filterDefs
9822
+ .map((def) => {
9823
+ const field = def.field?.trim();
9824
+ if (!field) {
9825
+ return null;
9826
+ }
9827
+ return { field, title: filterFieldTitleByName.get(field) ?? field };
9828
+ })
9829
+ .filter((row) => row != null),
9830
+ ...(quickSearch ? { quickSearch } : {}),
9831
+ ...(selectedIds.length ? { selectedIds } : {}),
9832
+ ...(selectedRecords.length ? { selectedRecords } : {}),
9833
+ columns,
9834
+ previewTitles: buildPreviewTitles(vm, dataSource.items ?? []),
9835
+ appliedQuery: {
9836
+ skip: dataSource._query?.skip,
9837
+ take: dataSource._query?.take,
9838
+ ...(sorts.length ? { sort: sorts } : {}),
9839
+ filter: snapshotFilters.filter((f) => f.hidden !== true),
9840
+ },
9841
+ actions: ENTITY_LIST_ACTIONS,
9842
+ };
9843
+ }
9844
+ //#endregion
9845
+ //#region ----- Run -----
9846
+ async function axpRunEntityListPageContextAction(vm, actionId, args, resolveTitle) {
9847
+ const result = await runEntityListAction(vm, actionId, args);
9848
+ return {
9849
+ ...result,
9850
+ snapshot: axpBuildEntityListPageContextSnapshot(vm, resolveTitle),
9851
+ };
9852
+ }
9853
+ async function runEntityListAction(vm, actionId, args) {
9854
+ switch (actionId) {
9855
+ case 'set-view':
9856
+ return setViewAction(vm, args);
9857
+ case 'set-filter':
9858
+ return setFilterAction(vm, args);
9859
+ case 'remove-filter':
9860
+ return removeFilterAction(vm, args);
9861
+ case 'clear-filters':
9862
+ vm.resetFilters();
9863
+ await vm.applyFilterAndSort({ resetPagination: true });
9864
+ return { success: true };
9865
+ case 'set-search':
9866
+ return setSearchAction(vm, args);
9867
+ default:
9868
+ return { success: false, message: `Unknown page action "${actionId}".` };
9869
+ }
9870
+ }
9871
+ async function setViewAction(vm, args) {
9872
+ const viewName = readStringArg(args, 'viewName');
9873
+ if (!viewName) {
9874
+ return { success: false, message: 'set-view requires viewName.' };
9875
+ }
9876
+ const match = vm.views().find((v) => v.name === viewName);
9877
+ if (!match) {
9878
+ return { success: false, message: `View "${viewName}" is not on this list.` };
9879
+ }
9880
+ await vm.setView(viewName);
9881
+ await vm.applyFilterAndSort({ resetPagination: true });
9882
+ return { success: true };
9883
+ }
9884
+ async function setFilterAction(vm, args) {
9885
+ const field = readStringArg(args, 'field');
9886
+ const operatorType = (readStringArg(args, 'operatorType') || 'equal');
9887
+ if (!field) {
9888
+ return { success: false, message: 'set-filter requires field.' };
9889
+ }
9890
+ if (isQuickSearchField(field)) {
9891
+ return { success: false, message: 'Use set-search for list search, not set-filter.' };
9892
+ }
9893
+ if (!FILTER_OPERATOR_TYPES.has(operatorType)) {
9894
+ return { success: false, message: `Unsupported operatorType "${operatorType}".` };
9895
+ }
9896
+ if (!isKnownFilterField(vm, field)) {
9897
+ return { success: false, message: `Field "${field}" is not a filterable field on this list.` };
9898
+ }
9899
+ const value = args['value'];
9900
+ if (!operatorAllowsEmpty(operatorType) && isEmptyFilterValue(value)) {
9901
+ return { success: false, message: 'set-filter requires value.' };
9902
+ }
9903
+ const next = vm
9904
+ .filterQueries()
9905
+ .filter((f) => f.hidden === true || f.field !== field)
9906
+ .concat({
9907
+ field,
9908
+ operator: { type: operatorType },
9909
+ value,
9910
+ hidden: false,
9911
+ });
9912
+ vm.filterQueries.set(next);
9913
+ await vm.applyFilterAndSort({ resetPagination: true });
9914
+ return { success: true };
9915
+ }
9916
+ async function removeFilterAction(vm, args) {
9917
+ const field = readStringArg(args, 'field');
9918
+ if (!field) {
9919
+ return { success: false, message: 'remove-filter requires field.' };
9920
+ }
9921
+ const next = vm.filterQueries().filter((f) => {
9922
+ if (f.hidden === true) {
9923
+ return true;
9924
+ }
9925
+ if (isQuickSearchField(field) && isQuickSearchField(f.field)) {
9926
+ return false;
9927
+ }
9928
+ return f.field !== field;
9929
+ });
9930
+ vm.filterQueries.set(next);
9931
+ await vm.applyFilterAndSort({ resetPagination: true });
9932
+ return { success: true };
9933
+ }
9934
+ async function setSearchAction(vm, args) {
9935
+ const text = typeof args['text'] === 'string' ? args['text'].trim() : '';
9936
+ const { rootLogic, queries } = flattenQueryFilterUserGroups(vm.filterQueries());
9937
+ const withoutSearch = queries.filter((f) => !isQuickSearchField(f.field));
9938
+ const next = text.length === 0
9939
+ ? withoutSearch
9940
+ : [
9941
+ ...withoutSearch,
9942
+ {
9943
+ field: AXP_QUERY_QUICK_SEARCH_FIELD,
9944
+ operator: { type: 'contains' },
9945
+ value: text,
9946
+ hidden: false,
9947
+ displayText: 'All',
9948
+ },
9949
+ ];
9950
+ vm.filterQueries.set(wrapQueryFilterRoot(next, rootLogic));
9951
+ await vm.applyFilterAndSort({ resetPagination: true });
9952
+ return { success: true };
9953
+ }
9954
+ //#endregion
9955
+ //#region ----- Helpers -----
9956
+ function isQuickSearchField(field) {
9957
+ return field === AXP_QUERY_QUICK_SEARCH_FIELD || field === 'all';
9958
+ }
9959
+ function readQuickSearch(filters) {
9960
+ const row = flattenQueryFilterUserGroups(filters).queries.find((f) => isQuickSearchField(f.field));
9961
+ const value = row?.value;
9962
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
9963
+ }
9964
+ function readStringArg(args, key) {
9965
+ const value = args[key];
9966
+ return typeof value === 'string' ? value.trim() : '';
9967
+ }
9968
+ function isEmptyFilterValue(value) {
9969
+ if (value === undefined || value === null || value === '') {
9970
+ return true;
9971
+ }
9972
+ return Array.isArray(value) && value.length === 0;
9973
+ }
9974
+ function operatorAllowsEmpty(operatorType) {
9975
+ return operatorType === 'isNull' || operatorType === 'isEmpty';
9976
+ }
9977
+ function isKnownFilterField(vm, field) {
9978
+ if (vm.filterDefinitions().some((def) => def.field === field)) {
9979
+ return true;
9980
+ }
9981
+ return vm.entityDef.properties.some((property) => property.name === field);
9982
+ }
9983
+ function buildPreviewTitles(vm, items) {
9984
+ const path = resolvePreviewPath(vm);
9985
+ if (!path || SECRET_NAME_PATTERN.test(path)) {
9986
+ return [];
9987
+ }
9988
+ const titles = [];
9989
+ for (const item of items) {
9990
+ if (titles.length >= PREVIEW_TITLE_CAP) {
9991
+ break;
9992
+ }
9993
+ if (!item || typeof item !== 'object') {
9994
+ continue;
9995
+ }
9996
+ const raw = get(item, path);
9997
+ const text = typeof raw === 'string' ? raw.trim() : raw != null && typeof raw !== 'object' ? String(raw).trim() : '';
9998
+ if (!text) {
9999
+ continue;
10000
+ }
10001
+ titles.push(text.length > PREVIEW_TITLE_MAX_CHARS ? `${text.slice(0, PREVIEW_TITLE_MAX_CHARS)}…` : text);
10002
+ }
10003
+ return titles;
10004
+ }
10005
+ function readSelectedRecords(vm, resolveTitle) {
10006
+ const path = resolvePreviewPath(vm);
10007
+ const records = [];
10008
+ for (const row of vm.selectedItems()) {
10009
+ if (!row || typeof row !== 'object') {
10010
+ continue;
10011
+ }
10012
+ const rawId = row.id;
10013
+ const id = typeof rawId === 'string' ? rawId.trim() : typeof rawId === 'number' && Number.isFinite(rawId) ? String(rawId) : '';
10014
+ if (!id) {
10015
+ continue;
10016
+ }
10017
+ const rawTitle = path ? get(row, path) : undefined;
10018
+ const title = resolveTitle(rawTitle).trim() || id;
10019
+ records.push({ id, title });
10020
+ }
10021
+ return records;
10022
+ }
10023
+ function resolvePreviewPath(vm) {
10024
+ const names = new Set(vm.entityDef.properties.map((p) => p.name));
10025
+ if (names.has('title')) {
10026
+ return 'title';
10027
+ }
10028
+ if (names.has('name')) {
10029
+ return 'name';
10030
+ }
10031
+ const firstVisible = vm.columns().find((c) => c.visible && !SECRET_NAME_PATTERN.test(c.name));
10032
+ return firstVisible?.name;
10033
+ }
10034
+ //#endregion
10035
+
9428
10036
  const ENTITY_MASTER_LIST_TRACE_NS = 'entity-master-list';
9429
10037
  /**
9430
10038
  * Emits entity master list diagnostics when tenant Debug Mode is enabled.
@@ -9462,6 +10070,8 @@ class AXPEntityMasterListViewQueryViewModel {
9462
10070
  this.indexCol = this.view.indexCol;
9463
10071
  this.pageSize = this.view.pageSize;
9464
10072
  this.visible = this.view.visible;
10073
+ this.fixed = this.view.fixed;
10074
+ this.custom = this.view.custom === true;
9465
10075
  }
9466
10076
  }
9467
10077
  class AXPEntityMasterListViewModel {
@@ -9596,16 +10206,20 @@ class AXPEntityMasterListViewModel {
9596
10206
  return typeof resolved === 'string' && resolved.trim() !== '' ? resolved : title;
9597
10207
  }
9598
10208
  /**
9599
- * Resolves the record CSS class from `interfaces.master.styling.record`.
10209
+ * Resolves the record CSS class from entity styling plus personal highlight rules.
9600
10210
  */
9601
10211
  async resolveRecordStylingClass(rowData) {
9602
- return resolveEntityMasterRecordStylingClass(this.expressionEvaluator, this.entityDef, rowData);
10212
+ const entityClass = await resolveEntityMasterRecordStylingClass(this.expressionEvaluator, this.entityDef, rowData);
10213
+ const userClass = resolveEntityListUserRecordStylingClass(rowData, this.userStylingRules());
10214
+ return joinEntityListStylingClasses(entityClass, userClass);
9603
10215
  }
9604
10216
  /**
9605
- * Resolves the field CSS class from `interfaces.master.styling.fields`.
10217
+ * Resolves the field CSS class from `interfaces.master.styling.fields` plus personal rules.
9606
10218
  */
9607
10219
  async resolveFieldStylingClass(rowData, fieldName) {
9608
- return resolveEntityMasterFieldStylingClass(this.expressionEvaluator, this.entityDef, rowData, fieldName);
10220
+ const entityClass = await resolveEntityMasterFieldStylingClass(this.expressionEvaluator, this.entityDef, rowData, fieldName);
10221
+ const userClass = resolveEntityListUserFieldStylingClass(rowData, this.userStylingRules(), fieldName);
10222
+ return joinEntityListStylingClasses(entityClass, userClass);
9609
10223
  }
9610
10224
  async resolveTriggerName(triggerName, data) {
9611
10225
  if (!triggerName) {
@@ -9629,6 +10243,8 @@ class AXPEntityMasterListViewModel {
9629
10243
  activeListLayout: this.activeListLayout(),
9630
10244
  }));
9631
10245
  await this.settings.ensureLoaded();
10246
+ await this.loadUserStylingRules();
10247
+ await this.loadCustomQueryViews();
9632
10248
  await this.refreshVisibleViews();
9633
10249
  const availableViews = this.views();
9634
10250
  if (!availableViews.length) {
@@ -9640,12 +10256,11 @@ class AXPEntityMasterListViewModel {
9640
10256
  }
9641
10257
  else if (await this.shouldLoadPersistedListState()) {
9642
10258
  const entitySetting = await this.settings.get(this.settingEntityKey);
9643
- resolvedViewName = entitySetting?.list?.currentView;
10259
+ resolvedViewName = readPersistedEntityListInstanceCurrentView(entitySetting, this.listInstanceId());
9644
10260
  }
9645
10261
  const currentViewName = this.view().name;
9646
10262
  const currentViewUnavailable = !availableViews.some((v) => v.name === currentViewName);
9647
- const targetView = availableViews.find((c) => c.name === resolvedViewName) ??
9648
- (currentViewUnavailable ? availableViews[0] : this.view());
10263
+ const targetView = availableViews.find((c) => c.name === resolvedViewName) ?? (currentViewUnavailable ? availableViews[0] : this.view());
9649
10264
  const viewChanged = targetView.name !== this.view().name;
9650
10265
  // Columns start empty; bootstrap them on first setView even when the view name is unchanged
9651
10266
  // (e.g. URL already has ?view=all matching the default view).
@@ -9698,6 +10313,11 @@ class AXPEntityMasterListViewModel {
9698
10313
  this.lastAppliedFilterKey = null;
9699
10314
  this.hasQueryParamsFilters = false; // Flag to prevent overriding queryParams filters
9700
10315
  this.routeQueryContextKey = null;
10316
+ this.listInstanceId = signal(ENTITY_LIST_DEFAULT_INSTANCE_ID, /* @ts-ignore */
10317
+ ...(ngDevMode ? [{ debugName: "listInstanceId" }] : /* istanbul ignore next */ []));
10318
+ /** Bumped when list-instance filters are re-seeded so the toolbar chips catch up. */
10319
+ this.listFilterSeedEpoch = signal(0, /* @ts-ignore */
10320
+ ...(ngDevMode ? [{ debugName: "listFilterSeedEpoch" }] : /* istanbul ignore next */ []));
9701
10321
  this.settingsUpdateChain = Promise.resolve();
9702
10322
  this.initialListSettingsApplied = false;
9703
10323
  /** Persisted expanded row ids for hierarchical lists (per view). */
@@ -9712,9 +10332,14 @@ class AXPEntityMasterListViewModel {
9712
10332
  this.skipListPagingPersistence = false;
9713
10333
  this.listPersistenceMode = null;
9714
10334
  this.events$ = new Subject();
10335
+ /** Personal row/cell highlight rules for this entity. */
10336
+ this.userStylingRules = signal([], /* @ts-ignore */
10337
+ ...(ngDevMode ? [{ debugName: "userStylingRules" }] : /* istanbul ignore next */ []));
9715
10338
  //****************** Views ******************//
10339
+ this.customQueryViews = signal([], /* @ts-ignore */
10340
+ ...(ngDevMode ? [{ debugName: "customQueryViews" }] : /* istanbul ignore next */ []));
9716
10341
  this.allViews = computed(() => {
9717
- const views = this.entityDef.interfaces?.master?.list?.views ?? [];
10342
+ const views = mergeDefinitionAndCustomQueryViews(this.entityDef.interfaces?.master?.list?.views, this.customQueryViews());
9718
10343
  return views.map((v) => {
9719
10344
  return new AXPEntityMasterListViewQueryViewModel(this.entityDef, this, v);
9720
10345
  });
@@ -9729,8 +10354,23 @@ class AXPEntityMasterListViewModel {
9729
10354
  ...(ngDevMode ? [{ debugName: "views" }] : /* istanbul ignore next */ []));
9730
10355
  this.view = signal(this.allViews()[0], /* @ts-ignore */
9731
10356
  ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
10357
+ this.isActiveQueryViewDirty = computed(() => isQueryViewDirty({
10358
+ view: this.toQueryView(this.view()),
10359
+ persistableFilters: this.getPersistableFilterQueries(this.filterQueries()),
10360
+ currentSorts: this.currentQueryViewSorts(),
10361
+ currentColumns: this.currentQueryViewColumns(),
10362
+ defaultColumns: this.defaultQueryViewColumns(),
10363
+ sortableFieldNames: this.sortableFieldDefinitions().map((field) => field.name),
10364
+ }), /* @ts-ignore */
10365
+ ...(ngDevMode ? [{ debugName: "isActiveQueryViewDirty" }] : /* istanbul ignore next */ []));
10366
+ this.isActiveQueryViewCustom = computed(() => isCustomQueryView(this.view()), /* @ts-ignore */
10367
+ ...(ngDevMode ? [{ debugName: "isActiveQueryViewCustom" }] : /* istanbul ignore next */ []));
10368
+ this.canSaveActiveQueryView = computed(() => this.isActiveQueryViewDirty() && !this.isActiveQueryViewCustom(), /* @ts-ignore */
10369
+ ...(ngDevMode ? [{ debugName: "canSaveActiveQueryView" }] : /* istanbul ignore next */ []));
9732
10370
  this.showRowIndexColumnEnabled = signal(false, /* @ts-ignore */
9733
10371
  ...(ngDevMode ? [{ debugName: "showRowIndexColumnEnabled" }] : /* istanbul ignore next */ []));
10372
+ this.multiLevelHeadersEnabled = signal(false, /* @ts-ignore */
10373
+ ...(ngDevMode ? [{ debugName: "multiLevelHeadersEnabled" }] : /* istanbul ignore next */ []));
9734
10374
  /**
9735
10375
  * Row index column: if the list view defines `indexCol` (true/false), that overrides the user setting;
9736
10376
  * if `indexCol` is omitted, visibility follows {@link AXPCommonSettings.ShowRowIndexColumn}.
@@ -9747,6 +10387,12 @@ class AXPEntityMasterListViewModel {
9747
10387
  /** Layouts enabled via table (always) and `interfaces.master.card.enabled`. */
9748
10388
  this.enabledListLayouts = computed(() => resolveEnabledMasterListLayouts(this.entityDef.interfaces?.master?.card), /* @ts-ignore */
9749
10389
  ...(ngDevMode ? [{ debugName: "enabledListLayouts" }] : /* istanbul ignore next */ []));
10390
+ /** List filter editor mode from `interfaces.master.list.filterMode`. Default advanced while testing. */
10391
+ this.filterMode = computed(() => (this.entityDef.interfaces?.master?.list?.filterMode === 'normal' ? 'normal' : 'advanced'), /* @ts-ignore */
10392
+ ...(ngDevMode ? [{ debugName: "filterMode" }] : /* istanbul ignore next */ []));
10393
+ /** Named sort recipes from `interfaces.master.list.sortPresets`. */
10394
+ this.sortPresets = computed(() => collectEntityListSortPresets(this.entityDef), /* @ts-ignore */
10395
+ ...(ngDevMode ? [{ debugName: "sortPresets" }] : /* istanbul ignore next */ []));
9750
10396
  /** True when the user can switch between multiple enabled layouts. */
9751
10397
  this.canSwitchListLayout = computed(() => this.enabledListLayouts().length > 1, /* @ts-ignore */
9752
10398
  ...(ngDevMode ? [{ debugName: "canSwitchListLayout" }] : /* istanbul ignore next */ []));
@@ -9784,9 +10430,7 @@ class AXPEntityMasterListViewModel {
9784
10430
  },
9785
10431
  load: async (e) => {
9786
10432
  resetPagingForTreeChildrenLoad(e, this.entityDef.parentKey);
9787
- const listRequest = this.entityDef.parentKey != null
9788
- ? applyHierarchicalRootListFilter(e, this.entityDef.parentKey)
9789
- : e;
10433
+ const listRequest = this.entityDef.parentKey != null ? applyHierarchicalRootListFilter(e, this.entityDef.parentKey) : e;
9790
10434
  const fields = this.buildColumnQueryFields();
9791
10435
  const requestWithFields = fields?.length ? { ...listRequest, fields } : listRequest;
9792
10436
  const execute = this.entityDef.queries?.list?.execute;
@@ -9802,6 +10446,7 @@ class AXPEntityMasterListViewModel {
9802
10446
  pageSize: this.view().pageSize || 10,
9803
10447
  key: 'id',
9804
10448
  });
10449
+ this.customQueryViewsLoaded = false;
9805
10450
  this.selectedItems = signal([], /* @ts-ignore */
9806
10451
  ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
9807
10452
  /**
@@ -9819,6 +10464,12 @@ class AXPEntityMasterListViewModel {
9819
10464
  return this.selectedItems().length > 0;
9820
10465
  }, /* @ts-ignore */
9821
10466
  ...(ngDevMode ? [{ debugName: "hasSelectedItems" }] : /* istanbul ignore next */ []));
10467
+ /**
10468
+ * Category sidebar constraints merged with toolbar filters on every list query.
10469
+ * Empty when "All" is selected. Not persisted as user filters.
10470
+ */
10471
+ this.categoryListFilters = signal([], /* @ts-ignore */
10472
+ ...(ngDevMode ? [{ debugName: "categoryListFilters" }] : /* istanbul ignore next */ []));
9822
10473
  //****************** Title ******************//
9823
10474
  this.title = computed(() => {
9824
10475
  return this._viewDef.title ?? this.entityDef.formats.plural;
@@ -9890,8 +10541,9 @@ class AXPEntityMasterListViewModel {
9890
10541
  const { columns = [], properties } = this.entityDef;
9891
10542
  // const visibleProperties = properties.filter(({ schema }) => schema?.visible !== false);
9892
10543
  const propNames = new Set(properties.map(({ name }) => name));
9893
- return columns
9894
- .filter(({ name, showAs, options }) => (propNames.has(name) || showAs) && options?.visible !== false)
10544
+ // Keep `options.visible: false` columns — they stay in the picker, off by default.
10545
+ return flattenEntityTableColumns(columns)
10546
+ .filter(({ name, showAs }) => propNames.has(name) || !!showAs)
9895
10547
  .map((column) => {
9896
10548
  const relatedProperty = this.resolveMergeDetailProperty(column.name);
9897
10549
  const entityProperty = properties.find(({ name }) => name === column.name);
@@ -9924,6 +10576,8 @@ class AXPEntityMasterListViewModel {
9924
10576
  };
9925
10577
  this.columns = signal([], /* @ts-ignore */
9926
10578
  ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
10579
+ this.columnTree = signal([], /* @ts-ignore */
10580
+ ...(ngDevMode ? [{ debugName: "columnTree" }] : /* istanbul ignore next */ []));
9927
10581
  this.allAvailableCardFields = () => {
9928
10582
  return this.cardFieldsResolver.resolve(this.entityDef, this.cardLayout());
9929
10583
  };
@@ -9969,13 +10623,16 @@ class AXPEntityMasterListViewModel {
9969
10623
  });
9970
10624
  this.sortedFields.set([]);
9971
10625
  void this.syncShowRowIndexColumnSetting();
10626
+ void this.syncMultiLevelHeadersSetting();
9972
10627
  void this.applyGlobalListDisplayMode();
9973
10628
  this.settings.onLoaded.pipe(takeUntil(this.destroyed)).subscribe(() => {
9974
10629
  void this.syncShowRowIndexColumnSetting();
10630
+ void this.syncMultiLevelHeadersSetting();
9975
10631
  void this.applyGlobalListDisplayMode();
9976
10632
  });
9977
10633
  this.settings.onChanged.pipe(takeUntil(this.destroyed)).subscribe(() => {
9978
10634
  void this.syncShowRowIndexColumnSetting();
10635
+ void this.syncMultiLevelHeadersSetting();
9979
10636
  void this.applyGlobalListDisplayMode();
9980
10637
  });
9981
10638
  }
@@ -9989,6 +10646,28 @@ class AXPEntityMasterListViewModel {
9989
10646
  this.showRowIndexColumnEnabled.set(false);
9990
10647
  }
9991
10648
  }
10649
+ async syncMultiLevelHeadersSetting() {
10650
+ try {
10651
+ const value = await this.settings.get(AXPCommonSettings.EntityMultiLevelHeaders);
10652
+ const enabled = value ?? false;
10653
+ if (this.multiLevelHeadersEnabled() !== enabled) {
10654
+ this.multiLevelHeadersEnabled.set(enabled);
10655
+ this.rebuildColumnTree();
10656
+ }
10657
+ else {
10658
+ this.multiLevelHeadersEnabled.set(enabled);
10659
+ }
10660
+ }
10661
+ catch {
10662
+ if (this.multiLevelHeadersEnabled()) {
10663
+ this.multiLevelHeadersEnabled.set(false);
10664
+ this.rebuildColumnTree();
10665
+ }
10666
+ else {
10667
+ this.multiLevelHeadersEnabled.set(false);
10668
+ }
10669
+ }
10670
+ }
9992
10671
  /**
9993
10672
  * Applies {@link AXPCommonSettings.EntityListPersistenceMode} for this list instance.
9994
10673
  * Call once when the list view model is created (before loading list UI state).
@@ -10016,6 +10695,9 @@ class AXPEntityMasterListViewModel {
10016
10695
  }
10017
10696
  }
10018
10697
  }
10698
+ setListInstanceId(instanceId) {
10699
+ this.listInstanceId.set(axpNormalizeEntityListInstanceId(instanceId));
10700
+ }
10019
10701
  async getListPersistenceMode() {
10020
10702
  if (this.listPersistenceMode != null) {
10021
10703
  return this.listPersistenceMode;
@@ -10052,10 +10734,16 @@ class AXPEntityMasterListViewModel {
10052
10734
  }
10053
10735
  const listViewSetting = await this.settings.get(this.settingEntityKey);
10054
10736
  if (listViewSetting) {
10055
- const columns = listViewSetting.list?.views?.[this.view().name]?.columns;
10056
- const sorts = listViewSetting.list?.views?.[this.view().name]?.sorts;
10057
- // TODO: Re-enable loading persisted list filters after entity-list filter/settings sync is fixed.
10058
- // const filters = listViewSetting.list?.views?.[this.view().name]?.filters as AXPFilterQuery[] | undefined;
10737
+ const viewSetting = listViewSetting.list?.views?.[this.view().name];
10738
+ const columnsVersion = Number(viewSetting?.columnsVersion ?? 0);
10739
+ let columns = viewSetting?.columns;
10740
+ // Product modules register migrate-drop columns via configureEntityListColumnsSettingsMigrateDrop.
10741
+ const migrateDrop = getEntityListColumnsSettingsMigrateDrop();
10742
+ const settingsVersion = getEntityListColumnsSettingsVersion();
10743
+ if (columnsVersion < settingsVersion && Array.isArray(columns) && migrateDrop.size > 0) {
10744
+ columns = columns.filter((col) => !migrateDrop.has(String(col.name)));
10745
+ }
10746
+ const sorts = viewSetting?.sorts;
10059
10747
  let columnVisibilityMap;
10060
10748
  let columnWidthsMap;
10061
10749
  if (columns) {
@@ -10065,17 +10753,16 @@ class AXPEntityMasterListViewModel {
10065
10753
  this.loadListPagingFromViewSettings(listViewSetting);
10066
10754
  if (columns && columnVisibilityMap && columnWidthsMap) {
10067
10755
  this.columns.update((prev) => {
10068
- const next = [...prev].sort((a, b) => columns.findIndex((col) => col.name === (a.column?.options?.dataPath ?? a.name)) -
10069
- columns.findIndex((col) => col.name === (b.column?.options?.dataPath ?? b.name)));
10756
+ const next = this.mergePersistedColumnOrder(prev, columns.map((col) => String(col.name)));
10070
10757
  for (const column of next) {
10071
10758
  const columnKey = column.column?.options?.dataPath ?? column.name;
10072
10759
  column.width = defaultTo(columnWidthsMap.get(columnKey), column.column?.options?.width);
10073
- // Definition visibility (view.columns whitelist + options.visible) always wins for "hide".
10074
- // Persisted settings may only further hide an already-allowed column.
10075
- const definitionVisible = column.visible === true;
10760
+ // Definition supplies the default (entity / view `visible`).
10761
+ // Persisted user choice overrides when present (including enabling a default-off column).
10076
10762
  const persistedVisible = columnVisibilityMap.get(columnKey);
10077
- column.visible =
10078
- definitionVisible && (persistedVisible === undefined ? true : persistedVisible !== false);
10763
+ if (persistedVisible !== undefined) {
10764
+ column.visible = persistedVisible !== false;
10765
+ }
10079
10766
  }
10080
10767
  return next;
10081
10768
  });
@@ -10083,11 +10770,10 @@ class AXPEntityMasterListViewModel {
10083
10770
  if (Array.isArray(sorts) && sorts.length) {
10084
10771
  this.setActiveSortsFromQueries(sorts);
10085
10772
  }
10086
- // TODO: Re-enable loading persisted list filters after entity-list filter/settings sync is fixed.
10087
- // Don't override filters if they came from queryParams
10088
- // if (Array.isArray(filters) && !this.hasQueryParamsFilters) {
10089
- // this.filterQueries.set(filters);
10090
- // }
10773
+ if (!this.hasQueryParamsFilters) {
10774
+ const persistedFilters = readPersistedEntityListInstanceFilters(listViewSetting, this.listInstanceId(), this.view().name);
10775
+ this.filterQueries.set(mergeEntityListViewAndPersistedFilters(this.filterQueries(), persistedFilters));
10776
+ }
10091
10777
  const expandedRowIds = listViewSetting.list?.views?.[this.view().name]?.expandedRowIds;
10092
10778
  if (Array.isArray(expandedRowIds)) {
10093
10779
  this.expandedRowIds.set(expandedRowIds.map((id) => String(id)).filter(Boolean));
@@ -10117,8 +10803,7 @@ class AXPEntityMasterListViewModel {
10117
10803
  this.loadListPagingFromViewSettings(entitySetting);
10118
10804
  }
10119
10805
  getResolvedListPaging() {
10120
- return (this.resolvedListPaging() ??
10121
- normalizeListPaging(undefined, this.view().pageSize || this.dataSource.config.pageSize || 10));
10806
+ return this.resolvedListPaging() ?? normalizeListPaging(undefined, this.view().pageSize || this.dataSource.config.pageSize || 10);
10122
10807
  }
10123
10808
  applyPagingToDataSourceWithoutLoad() {
10124
10809
  applyDataSourcePagingWithoutLoad(this.dataSource, this.getResolvedListPaging());
@@ -10181,29 +10866,150 @@ class AXPEntityMasterListViewModel {
10181
10866
  * User-applied filters to persist (excludes hidden view conditions and empty values).
10182
10867
  */
10183
10868
  getPersistableFilterQueries(queries = this.filterQueries()) {
10184
- return queries.filter((f) => {
10185
- if (f.hidden === true) {
10186
- return false;
10187
- }
10188
- if (f.readOnly === true) {
10189
- return false;
10190
- }
10191
- const value = f.value;
10192
- if (value === undefined || value === null || value === '') {
10193
- return false;
10869
+ return flattenQueryFilterUserGroups(queries).queries.filter((f) => isPersistableFilterQuery(f));
10870
+ }
10871
+ async createCustomQueryView(input) {
10872
+ const sourceViewName = this.view().name;
10873
+ const name = createCustomQueryViewName();
10874
+ const view = this.snapshotActiveQueryView(name, input.title, input.includeActiveView);
10875
+ await this.persistCustomQueryView(view, { activate: false, clearInstanceFilters: false });
10876
+ await this.resetViewInstanceOverlays(sourceViewName);
10877
+ return name;
10878
+ }
10879
+ async updateCustomQueryView(input) {
10880
+ const name = this.view().name;
10881
+ const view = this.snapshotActiveQueryView(name, input.title, true);
10882
+ await this.persistCustomQueryView(view, { activate: true, clearInstanceFilters: true });
10883
+ return name;
10884
+ }
10885
+ async deleteCustomQueryView(name) {
10886
+ const target = this.views().find((view) => view.name === name);
10887
+ if (!target || !isCustomQueryView(target)) {
10888
+ return this.view().name;
10889
+ }
10890
+ await this.enqueueSettingsUpdate((prev) => removePersistedCustomQueryView(prev, name));
10891
+ this.customQueryViews.update((views) => views.filter((view) => view.name !== name));
10892
+ await this.refreshVisibleViews();
10893
+ const remaining = this.views();
10894
+ if (this.view().name !== name) {
10895
+ return this.view().name;
10896
+ }
10897
+ return remaining[0]?.name ?? null;
10898
+ }
10899
+ async loadCustomQueryViews() {
10900
+ if (this.customQueryViewsLoaded) {
10901
+ return;
10902
+ }
10903
+ const setting = await this.settings.get(this.settingEntityKey);
10904
+ this.customQueryViews.set(readPersistedCustomQueryViews(setting));
10905
+ this.customQueryViewsLoaded = true;
10906
+ }
10907
+ async persistCustomQueryView(view, options) {
10908
+ await this.enqueueSettingsUpdate((prev) => upsertPersistedCustomQueryView(prev, view));
10909
+ this.customQueryViews.update((views) => {
10910
+ const index = views.findIndex((item) => item.name === view.name);
10911
+ return index >= 0 ? views.map((item, i) => (i === index ? view : item)) : [...views, view];
10912
+ });
10913
+ await this.refreshVisibleViews();
10914
+ if (options.activate) {
10915
+ const next = this.views().find((item) => item.name === view.name);
10916
+ if (next) {
10917
+ this.view.set(next);
10918
+ this.applyViewSorts();
10919
+ await this.applyViewColumns();
10920
+ await this.applyViewFilters();
10194
10921
  }
10195
- if (Array.isArray(value) && value.length === 0) {
10196
- return false;
10922
+ }
10923
+ if (options.clearInstanceFilters) {
10924
+ await this.saveSettings('filters', []);
10925
+ }
10926
+ }
10927
+ /** Clears user overlays so the source view returns to its definition defaults after Save View. */
10928
+ async resetViewInstanceOverlays(viewName) {
10929
+ if (!(await this.shouldPersistListState())) {
10930
+ return;
10931
+ }
10932
+ await this.enqueueSettingsUpdate((prev) => {
10933
+ const next = cloneDeep(prev ?? {});
10934
+ set(next, entityListInstanceFilterPath(this.listInstanceId(), viewName), []);
10935
+ set(next, ['list', 'views', viewName, 'filters'], []);
10936
+ const viewSetting = next?.list?.views?.[viewName];
10937
+ if (viewSetting && typeof viewSetting === 'object') {
10938
+ delete viewSetting['columns'];
10939
+ delete viewSetting['sorts'];
10197
10940
  }
10198
- return true;
10941
+ return next;
10942
+ });
10943
+ }
10944
+ snapshotActiveQueryView(name, title, includeActiveView) {
10945
+ return snapshotCustomQueryView({
10946
+ name,
10947
+ title,
10948
+ includeActiveView,
10949
+ activeView: this.toQueryView(this.view()),
10950
+ currentFilters: this.filterQueries(),
10951
+ currentSorts: this.currentQueryViewSorts(),
10952
+ currentColumns: this.currentQueryViewColumns(),
10199
10953
  });
10200
10954
  }
10955
+ toQueryView(view) {
10956
+ return {
10957
+ name: view.name,
10958
+ title: view.title,
10959
+ fixed: view.fixed,
10960
+ custom: view.custom,
10961
+ columns: view.columns,
10962
+ conditions: view.conditions,
10963
+ sorts: view.sorts,
10964
+ indexCol: view.indexCol,
10965
+ pageSize: view.pageSize,
10966
+ visible: view.visible,
10967
+ };
10968
+ }
10969
+ currentQueryViewSorts() {
10970
+ return this.sortedFields()
10971
+ .filter((sort) => sort.dir === 'asc' || sort.dir === 'desc')
10972
+ .map((sort) => ({ name: sort.name, dir: sort.dir }));
10973
+ }
10974
+ currentQueryViewColumns() {
10975
+ return this.columns().map((column) => ({
10976
+ name: column.column?.options?.dataPath ?? column.name,
10977
+ visible: isQueryViewColumnVisible(column.visible),
10978
+ width: column.width,
10979
+ }));
10980
+ }
10981
+ defaultQueryViewColumns() {
10982
+ return this.allAvailableColumns().map((column) => ({
10983
+ name: column.column?.options?.dataPath ?? column.name,
10984
+ visible: isQueryViewColumnVisible(column.visible),
10985
+ }));
10986
+ }
10201
10987
  enqueueSettingsUpdate(updateFn) {
10202
10988
  const run = () => this.settings.scope(AXPPlatformScope.User).update(this.settingEntityKey, updateFn);
10203
10989
  const next = this.settingsUpdateChain.then(run);
10204
10990
  this.settingsUpdateChain = next.catch(() => undefined);
10205
10991
  return next;
10206
10992
  }
10993
+ async loadUserStylingRules() {
10994
+ if (!(await this.shouldLoadPersistedListState())) {
10995
+ this.userStylingRules.set([]);
10996
+ return;
10997
+ }
10998
+ const setting = await this.settings.get(this.settingEntityKey);
10999
+ this.userStylingRules.set(readPersistedEntityListStylingRules(setting));
11000
+ }
11001
+ async saveUserStylingRules(rules) {
11002
+ const normalized = normalizeEntityListUserStylingRules(rules);
11003
+ this.userStylingRules.set(normalized);
11004
+ if (!(await this.shouldPersistListState())) {
11005
+ return;
11006
+ }
11007
+ await this.enqueueSettingsUpdate((prev) => {
11008
+ const next = cloneDeep(prev ?? {});
11009
+ set(next, [...entityListStylingRulesPath()], normalized);
11010
+ return next;
11011
+ });
11012
+ }
10207
11013
  async saveSettings(changesType, data) {
10208
11014
  if (!(await this.shouldPersistListState())) {
10209
11015
  return;
@@ -10227,6 +11033,7 @@ class AXPEntityMasterListViewModel {
10227
11033
  width: c.name === field ? columnSizeData.width : c.width,
10228
11034
  }));
10229
11035
  set(newSettings, `list.views.${this.view().name}.columns`, updatedColumns);
11036
+ set(newSettings, `list.views.${this.view().name}.columnsVersion`, getEntityListColumnsSettingsVersion());
10230
11037
  return newSettings;
10231
11038
  });
10232
11039
  break;
@@ -10240,18 +11047,17 @@ class AXPEntityMasterListViewModel {
10240
11047
  visible: c.visible,
10241
11048
  width: c.width,
10242
11049
  })));
11050
+ set(newSettings, `list.views.${this.view().name}.columnsVersion`, getEntityListColumnsSettingsVersion());
10243
11051
  return newSettings;
10244
11052
  });
10245
11053
  break;
10246
11054
  }
10247
11055
  case 'view':
10248
- await this.enqueueSettingsUpdate((prev) => ({
10249
- ...prev,
10250
- list: {
10251
- ...prev?.list,
10252
- currentView: this.view().name,
10253
- },
10254
- }));
11056
+ await this.enqueueSettingsUpdate((prev) => {
11057
+ const newSettings = { ...prev };
11058
+ set(newSettings, entityListInstanceCurrentViewPath(this.listInstanceId()), this.view().name);
11059
+ return newSettings;
11060
+ });
10255
11061
  break;
10256
11062
  case 'pageSize':
10257
11063
  await this.enqueueSettingsUpdate((prev) => ({
@@ -10289,19 +11095,13 @@ class AXPEntityMasterListViewModel {
10289
11095
  }));
10290
11096
  break;
10291
11097
  case 'filters':
10292
- await this.enqueueSettingsUpdate((prev) => ({
10293
- ...prev,
10294
- list: {
10295
- ...prev?.list,
10296
- views: {
10297
- ...prev?.list?.views,
10298
- [this.view().name]: {
10299
- ...prev?.list?.views?.[this.view().name],
10300
- filters: data,
10301
- },
10302
- },
10303
- },
10304
- }));
11098
+ await this.enqueueSettingsUpdate((prev) => {
11099
+ const newSettings = cloneDeep(prev ?? {});
11100
+ const nextFilters = Array.isArray(data) ? data : [];
11101
+ set(newSettings, entityListInstanceFilterPath(this.listInstanceId(), this.view().name), nextFilters);
11102
+ set(newSettings, ['list', 'views', this.view().name, 'filters'], nextFilters);
11103
+ return newSettings;
11104
+ });
10305
11105
  break;
10306
11106
  case 'sorts':
10307
11107
  await this.enqueueSettingsUpdate((prev) => ({
@@ -10347,6 +11147,9 @@ class AXPEntityMasterListViewModel {
10347
11147
  setSelectedCategory(category) {
10348
11148
  this.selectedCategory.set(category);
10349
11149
  }
11150
+ setCategoryListFilters(filters) {
11151
+ this.categoryListFilters.set(filters);
11152
+ }
10350
11153
  /** Keeps the first action when list definitions repeat the same trigger name. */
10351
11154
  dedupeActionsByName(actions) {
10352
11155
  const seen = new Set();
@@ -10361,9 +11164,7 @@ class AXPEntityMasterListViewModel {
10361
11164
  async getPrimaryActions() {
10362
11165
  const scope = this.createLogicExpressionScope(null);
10363
11166
  const actions = await Promise.all(this.allActions()
10364
- .filter((a) => a.priority == 'primary' &&
10365
- ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
10366
- (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
11167
+ .filter((a) => a.priority == 'primary' && ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) || (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
10367
11168
  .map(async (a) => {
10368
11169
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
10369
11170
  if (isHidden)
@@ -10378,9 +11179,7 @@ class AXPEntityMasterListViewModel {
10378
11179
  async getSecondaryActions() {
10379
11180
  const scope = this.createLogicExpressionScope(null);
10380
11181
  const actions = await Promise.all(this.allActions()
10381
- .filter((a) => a.priority == 'secondary' &&
10382
- ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
10383
- (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
11182
+ .filter((a) => a.priority == 'secondary' && ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) || (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
10384
11183
  .map(async (a) => {
10385
11184
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
10386
11185
  if (isHidden)
@@ -10433,19 +11232,7 @@ class AXPEntityMasterListViewModel {
10433
11232
  });
10434
11233
  return items;
10435
11234
  }
10436
- static { this.URL_FILTER_OPERATOR_TYPES = new Set([
10437
- 'equal',
10438
- 'isNull',
10439
- 'isEmpty',
10440
- 'lt',
10441
- 'lte',
10442
- 'gt',
10443
- 'gte',
10444
- 'startsWith',
10445
- 'endsWith',
10446
- 'contains',
10447
- 'in',
10448
- ]); }
11235
+ static { this.URL_FILTER_OPERATOR_TYPES = new Set(['equal', 'isNull', 'isEmpty', 'lt', 'lte', 'gt', 'gte', 'startsWith', 'endsWith', 'contains', 'in']); }
10449
11236
  get properties() {
10450
11237
  return this.entityDef.properties;
10451
11238
  }
@@ -10493,13 +11280,37 @@ class AXPEntityMasterListViewModel {
10493
11280
  }
10494
11281
  toUrlFilterPayloadItems(queries) {
10495
11282
  return queries
10496
- .filter((f) => typeof f.field === 'string' && f.field !== '' && f.value !== undefined && f.value !== null && f.value !== '')
10497
- .map((f) => ({
10498
- field: f.field,
10499
- operator: AXPEntityMasterListViewModel.coerceFilterOperatorFromUrl(f.operator),
10500
- value: f.value,
10501
- }))
10502
- .sort((a, b) => a.field.localeCompare(b.field));
11283
+ .filter((f) => {
11284
+ if (f.filters?.length) {
11285
+ return f.filters.some((child) => isCompleteFilterCondition(child.operator?.type, child.value));
11286
+ }
11287
+ if (typeof f.field !== 'string' || f.field === '') {
11288
+ return false;
11289
+ }
11290
+ return isCompleteFilterCondition(f.operator?.type, f.value);
11291
+ })
11292
+ .map((f) => {
11293
+ if (f.filters?.length) {
11294
+ return {
11295
+ logic: f.logic ?? 'and',
11296
+ filters: f.filters.map((child) => ({
11297
+ field: child.field,
11298
+ operator: AXPEntityMasterListViewModel.coerceFilterOperatorFromUrl(child.operator),
11299
+ value: child.value,
11300
+ })),
11301
+ };
11302
+ }
11303
+ return {
11304
+ field: f.field,
11305
+ operator: AXPEntityMasterListViewModel.coerceFilterOperatorFromUrl(f.operator),
11306
+ value: f.value,
11307
+ };
11308
+ })
11309
+ .sort((a, b) => {
11310
+ const left = resolveFilterQueryIdentityField(a) ?? '';
11311
+ const right = resolveFilterQueryIdentityField(b) ?? '';
11312
+ return left.localeCompare(right);
11313
+ });
10503
11314
  }
10504
11315
  static coerceFilterOperatorFromUrl(op) {
10505
11316
  if (op && typeof op === 'object' && op !== null && 'type' in op) {
@@ -10565,7 +11376,7 @@ class AXPEntityMasterListViewModel {
10565
11376
  }
10566
11377
  /**
10567
11378
  * Reacts to any route query param change while the list route is reused (`reuse: queryParamsChange`).
10568
- * Handles known keys (`view`, `filters`) and re-evaluates view visibility for expression-driven params.
11379
+ * Handles known keys (`view`, `filters`, `list`) and re-evaluates view visibility for expression-driven params.
10569
11380
  *
10570
11381
  * Data reload is owned by {@link applyFilterAndSort} → `events$` when criteria change.
10571
11382
  * `reloadList` stays false so callers do not issue a second `reloadListData` for the same transition.
@@ -10576,12 +11387,24 @@ class AXPEntityMasterListViewModel {
10576
11387
  return { reloadList: false };
10577
11388
  }
10578
11389
  this.routeQueryContextKey = contextKey;
11390
+ const nextInstanceId = axpGetEntityListInstanceIdFromParamMap(queryParamMap);
11391
+ const instanceChanged = nextInstanceId !== this.listInstanceId();
11392
+ if (instanceChanged) {
11393
+ this.listInstanceId.set(nextInstanceId);
11394
+ this.hasQueryParamsFilters = false;
11395
+ }
10579
11396
  const previousViewName = this.view().name;
10580
11397
  await this.setView(queryParamMap.get('view'));
11398
+ if (instanceChanged) {
11399
+ this.applyViewFilters();
11400
+ this.applyViewSorts();
11401
+ await this.loadPersistedInstanceFilters();
11402
+ this.listFilterSeedEpoch.update((epoch) => epoch + 1);
11403
+ }
10581
11404
  const filtersChanged = await this.syncFiltersFromRouteQueryParam(queryParamMap.get('filters'));
10582
11405
  await this.refreshVisibleViews();
10583
11406
  const viewChanged = this.view().name !== previousViewName;
10584
- if (filtersChanged || viewChanged) {
11407
+ if (filtersChanged || viewChanged || instanceChanged) {
10585
11408
  this.lastAppliedFilterKey = null;
10586
11409
  this.lastAppliedSortKey = null;
10587
11410
  // Keys were cleared to force apply; pass reset so URL view/filter changes still reset paging
@@ -10658,12 +11481,16 @@ class AXPEntityMasterListViewModel {
10658
11481
  if (this.hasQueryParamsFilters) {
10659
11482
  return;
10660
11483
  }
10661
- const viewFilters = this.view().conditions.map((f) => ({
10662
- field: f.name,
10663
- operator: f.operator,
10664
- value: f.value,
10665
- }));
10666
- this.filterQueries.set(viewFilters);
11484
+ const view = this.toQueryView(this.view());
11485
+ this.filterQueries.set(withQueryViewFilterVisibility(view, queryViewConditionsToFilterQueries(view)));
11486
+ }
11487
+ async loadPersistedInstanceFilters() {
11488
+ if (this.hasQueryParamsFilters || !(await this.shouldLoadPersistedListState())) {
11489
+ return;
11490
+ }
11491
+ const setting = await this.settings.get(this.settingEntityKey);
11492
+ const persistedFilters = readPersistedEntityListInstanceFilters(setting, this.listInstanceId(), this.view().name);
11493
+ this.filterQueries.set(mergeEntityListViewAndPersistedFilters(this.filterQueries(), persistedFilters));
10667
11494
  }
10668
11495
  resetFilters() {
10669
11496
  this.hasQueryParamsFilters = false; // Reset flag when user resets filters
@@ -10674,7 +11501,8 @@ class AXPEntityMasterListViewModel {
10674
11501
  const sorts = this.sortedFields()
10675
11502
  .filter((sf) => sf.dir)
10676
11503
  .map((s) => ({ name: s.name, dir: s.dir }));
10677
- const filters = this.filterQueries();
11504
+ const toolbarFilters = this.filterQueries();
11505
+ const filters = this.mergeToolbarAndCategoryFilters(toolbarFilters);
10678
11506
  const sortKey = JSON.stringify(sorts);
10679
11507
  const transformedFilter = this.filterOperatorMiddleware.transformFilter({
10680
11508
  field: null,
@@ -10691,7 +11519,7 @@ class AXPEntityMasterListViewModel {
10691
11519
  }));
10692
11520
  return; // No effective change; avoid redundant refresh
10693
11521
  }
10694
- this.updateAppliedInlineFilterHighlightText(filters);
11522
+ this.updateAppliedInlineFilterHighlightText(toolbarFilters);
10695
11523
  const filtersChanged = this.lastAppliedFilterKey != null && filterKey !== this.lastAppliedFilterKey;
10696
11524
  const sortsChanged = this.lastAppliedSortKey != null && sortKey !== this.lastAppliedSortKey;
10697
11525
  const shouldResetPagination = options?.resetPagination === true || filtersChanged;
@@ -10700,48 +11528,225 @@ class AXPEntityMasterListViewModel {
10700
11528
  if (shouldResetPagination) {
10701
11529
  this.resetListPagingSkip();
10702
11530
  }
10703
- this.dataSource.clearFilter();
10704
- this.dataSource.sort(...sorts.map((s) => ({ dir: s.dir, field: s.name })));
10705
- this.dataSource.filter(transformedFilter);
10706
- traceEntityMasterList('viewmodel', 'applyFilterAndSort emitting refresh', () => ({
10707
- entity: getEntityInfo(this.entityDef).source,
10708
- viewName: this.view().name,
10709
- activeListLayout: this.activeListLayout(),
10710
- filtersChanged,
10711
- resetPagination: shouldResetPagination,
10712
- filterCount: filters.length,
10713
- sortCount: sorts.length,
10714
- dataSource: buildDataSourceTraceSnapshot(this.dataSource),
10715
- }));
10716
- this.events$.next({ action: 'refresh', meta: { resetPagination: shouldResetPagination } });
10717
- const hooks = this.injector.get(AXPHookService);
10718
- fireEntityLifecycleHook(hooks, AXPEntityLifecycleHookKeys.ListCriteriaApplied, {
10719
- module: this.entityDef.module,
10720
- entityName: this.entityDef.name,
10721
- filterCount: filters.length,
10722
- sortCount: sorts.length,
10723
- viewName: this.view().name,
10724
- kind: sortsChanged && !filtersChanged ? 'sort' : filters.some((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD) ? 'search' : 'filter',
10725
- });
10726
- }
10727
- updateAppliedInlineFilterHighlightText(filters) {
10728
- const quickFilter = filters.find((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD);
10729
- const value = quickFilter?.value;
10730
- this.inlineFilterHighlightText.set(typeof value === 'string' ? value.trim() : '');
11531
+ this.dataSource.clearFilter();
11532
+ this.dataSource.sort(...sorts.map((s) => ({ dir: s.dir, field: s.name })));
11533
+ this.dataSource.filter(transformedFilter);
11534
+ traceEntityMasterList('viewmodel', 'applyFilterAndSort emitting refresh', () => ({
11535
+ entity: getEntityInfo(this.entityDef).source,
11536
+ viewName: this.view().name,
11537
+ activeListLayout: this.activeListLayout(),
11538
+ filtersChanged,
11539
+ resetPagination: shouldResetPagination,
11540
+ filterCount: filters.length,
11541
+ sortCount: sorts.length,
11542
+ dataSource: buildDataSourceTraceSnapshot(this.dataSource),
11543
+ }));
11544
+ this.events$.next({ action: 'refresh', meta: { resetPagination: shouldResetPagination } });
11545
+ const hooks = this.injector.get(AXPHookService);
11546
+ fireEntityLifecycleHook(hooks, AXPEntityLifecycleHookKeys.ListCriteriaApplied, {
11547
+ module: this.entityDef.module,
11548
+ entityName: this.entityDef.name,
11549
+ filterCount: filters.length,
11550
+ sortCount: sorts.length,
11551
+ viewName: this.view().name,
11552
+ kind: sortsChanged && !filtersChanged ? 'sort' : filters.some((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD) ? 'search' : 'filter',
11553
+ });
11554
+ }
11555
+ /**
11556
+ * Toolbar filters stay in `filterQueries`. Category sidebar filters are applied
11557
+ * beside them so a later toolbar change does not drop the selected category.
11558
+ */
11559
+ mergeToolbarAndCategoryFilters(toolbarFilters) {
11560
+ const categoryFilters = this.categoryListFilters();
11561
+ if (!categoryFilters.length) {
11562
+ return toolbarFilters;
11563
+ }
11564
+ return [...toolbarFilters, ...categoryFilters];
11565
+ }
11566
+ updateAppliedInlineFilterHighlightText(filters) {
11567
+ const quickFilter = flattenQueryFilterUserGroups(filters).queries.find((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD);
11568
+ const value = quickFilter?.value;
11569
+ this.inlineFilterHighlightText.set(typeof value === 'string' ? value.trim() : '');
11570
+ }
11571
+ //****************** Columns ******************//
11572
+ resolveMergeDetailSource(columnName) {
11573
+ const parsed = parseDottedFieldPath(columnName);
11574
+ if (!parsed) {
11575
+ return null;
11576
+ }
11577
+ const { dataPath, propertyName } = parsed;
11578
+ const related = this.entityDef.relatedEntities?.find((entry) => entry.layout?.type === 'merge-detail' && entry.persistence?.dataPath?.trim() === dataPath);
11579
+ if (!related?.entity) {
11580
+ return null;
11581
+ }
11582
+ const relatedDef = this.getRegisteredEntity(related.entity);
11583
+ const property = relatedDef?.properties?.find((item) => item.name === propertyName);
11584
+ if (!relatedDef || !property) {
11585
+ return null;
11586
+ }
11587
+ return { entity: relatedDef, property };
11588
+ }
11589
+ resolveMergeDetailProperty(columnName) {
11590
+ return this.resolveMergeDetailSource(columnName)?.property ?? null;
11591
+ }
11592
+ resolveColumnSection(column) {
11593
+ const mergeSource = this.resolveMergeDetailSource(column.name);
11594
+ const groupId = mergeSource?.property.groupId ?? column.property.groupId;
11595
+ if (!groupId) {
11596
+ return null;
11597
+ }
11598
+ const groups = mergeSource?.entity.groups ?? this.entityDef.groups;
11599
+ const group = groups?.find((item) => item.id === groupId);
11600
+ const title = group?.title?.trim();
11601
+ if (!title) {
11602
+ return null;
11603
+ }
11604
+ return { id: groupId, title };
11605
+ }
11606
+ findInnermostAuthorBand(columns, columnName) {
11607
+ for (const column of columns) {
11608
+ if (!isEntityColumnBand(column)) {
11609
+ continue;
11610
+ }
11611
+ const leaves = flattenEntityTableColumns(column.children);
11612
+ if (!leaves.some((leaf) => leaf.name === columnName)) {
11613
+ continue;
11614
+ }
11615
+ const deeper = this.findInnermostAuthorBand(column.children ?? [], columnName);
11616
+ return deeper ?? column;
11617
+ }
11618
+ return null;
11619
+ }
11620
+ buildSectionBandedColumnTree(leafByName) {
11621
+ const bucketOrder = [];
11622
+ const buckets = new Map();
11623
+ for (const column of this.columns()) {
11624
+ const authorBand = this.findInnermostAuthorBand(this.entityDef.columns ?? [], column.name);
11625
+ if (authorBand) {
11626
+ const key = `author:${authorBand.name}`;
11627
+ if (!buckets.has(key)) {
11628
+ bucketOrder.push(key);
11629
+ buckets.set(key, authorBand);
11630
+ }
11631
+ continue;
11632
+ }
11633
+ const section = this.resolveColumnSection(column);
11634
+ if (section) {
11635
+ const key = `section:${section.id}`;
11636
+ const existing = buckets.get(key);
11637
+ if (existing && typeof existing === 'object' && 'kind' in existing && existing.kind === 'section') {
11638
+ existing.leafNames.push(column.name);
11639
+ }
11640
+ else if (!existing) {
11641
+ bucketOrder.push(key);
11642
+ buckets.set(key, { kind: 'section', id: section.id, title: section.title, leafNames: [column.name] });
11643
+ }
11644
+ continue;
11645
+ }
11646
+ bucketOrder.push(`singleton:${column.name}`);
11647
+ }
11648
+ const nodes = [];
11649
+ for (const key of bucketOrder) {
11650
+ const bucket = buckets.get(key);
11651
+ if (!bucket) {
11652
+ continue;
11653
+ }
11654
+ if (key.startsWith('author:')) {
11655
+ const band = bucket;
11656
+ nodes.push(...this.buildMasterListColumnTree([band], leafByName));
11657
+ continue;
11658
+ }
11659
+ if (key.startsWith('section:')) {
11660
+ const sectionBucket = bucket;
11661
+ const children = [];
11662
+ for (const leafName of sectionBucket.leafNames) {
11663
+ const leaf = leafByName.get(leafName);
11664
+ if (!leaf) {
11665
+ continue;
11666
+ }
11667
+ children.push({
11668
+ kind: 'leaf',
11669
+ column: leaf,
11670
+ visible: leaf.visible !== false,
11671
+ });
11672
+ }
11673
+ if (children.length === 0) {
11674
+ continue;
11675
+ }
11676
+ if (children.length === 1) {
11677
+ nodes.push(children[0]);
11678
+ continue;
11679
+ }
11680
+ nodes.push({
11681
+ kind: 'band',
11682
+ name: `axp-section-${sectionBucket.id}`,
11683
+ title: sectionBucket.title,
11684
+ visible: children.some((child) => child.visible),
11685
+ children,
11686
+ });
11687
+ continue;
11688
+ }
11689
+ if (key.startsWith('singleton:')) {
11690
+ const leafName = key.slice('singleton:'.length);
11691
+ const leaf = leafByName.get(leafName);
11692
+ if (!leaf) {
11693
+ continue;
11694
+ }
11695
+ nodes.push({
11696
+ kind: 'leaf',
11697
+ column: leaf,
11698
+ visible: leaf.visible !== false,
11699
+ });
11700
+ }
11701
+ }
11702
+ return nodes;
10731
11703
  }
10732
- //****************** Columns ******************//
10733
- resolveMergeDetailProperty(columnName) {
10734
- const parsed = parseDottedFieldPath(columnName);
10735
- if (!parsed) {
10736
- return null;
11704
+ /**
11705
+ * Merges persisted column order onto the definition order.
11706
+ * Columns missing from saved prefs keep their definition-relative position.
11707
+ */
11708
+ mergePersistedColumnOrder(definitionColumns, persistedNames) {
11709
+ const columnKey = (column) => column.column?.options?.dataPath ?? column.name;
11710
+ const byKey = new Map(definitionColumns.map((column) => [columnKey(column), column]));
11711
+ const result = [];
11712
+ const placed = new Set();
11713
+ for (const name of persistedNames) {
11714
+ const column = byKey.get(name);
11715
+ if (!column) {
11716
+ continue;
11717
+ }
11718
+ result.push(column);
11719
+ placed.add(name);
10737
11720
  }
10738
- const { dataPath, propertyName } = parsed;
10739
- const related = this.entityDef.relatedEntities?.find((entry) => entry.layout?.type === 'merge-detail' && entry.persistence?.dataPath?.trim() === dataPath);
10740
- if (!related?.entity) {
10741
- return null;
11721
+ for (let index = 0; index < definitionColumns.length; index++) {
11722
+ const column = definitionColumns[index];
11723
+ const key = columnKey(column);
11724
+ if (placed.has(key)) {
11725
+ continue;
11726
+ }
11727
+ let insertAt = result.length;
11728
+ for (let prev = index - 1; prev >= 0; prev--) {
11729
+ const prevKey = columnKey(definitionColumns[prev]);
11730
+ const prevIndex = result.findIndex((entry) => columnKey(entry) === prevKey);
11731
+ if (prevIndex !== -1) {
11732
+ insertAt = prevIndex + 1;
11733
+ break;
11734
+ }
11735
+ }
11736
+ if (insertAt === result.length) {
11737
+ for (let next = index + 1; next < definitionColumns.length; next++) {
11738
+ const nextKey = columnKey(definitionColumns[next]);
11739
+ const nextIndex = result.findIndex((entry) => columnKey(entry) === nextKey);
11740
+ if (nextIndex !== -1) {
11741
+ insertAt = nextIndex;
11742
+ break;
11743
+ }
11744
+ }
11745
+ }
11746
+ result.splice(insertAt, 0, column);
11747
+ placed.add(key);
10742
11748
  }
10743
- const relatedDef = this.getRegisteredEntity(related.entity);
10744
- return relatedDef?.properties?.find((property) => property.name === propertyName) ?? null;
11749
+ return result;
10745
11750
  }
10746
11751
  collectCardLayoutQueryFields() {
10747
11752
  const card = this.cardLayout();
@@ -10764,8 +11769,7 @@ class AXPEntityMasterListViewModel {
10764
11769
  for (const path of collectEntityCardUserIdQueryFields(this.entityDef, card.header?.avatar ?? resolveEntityCardAvatarPath(this.entityDef, this.entityDef.columns))) {
10765
11770
  add(path);
10766
11771
  }
10767
- const occupied = new Set([card.header?.title, card.header?.description, card.header?.avatar]
10768
- .filter((name) => !!name && !name.includes('{{')));
11772
+ const occupied = new Set([card.header?.title, card.header?.description, card.header?.avatar].filter((name) => !!name && !name.includes('{{')));
10769
11773
  for (const field of card.fields ?? []) {
10770
11774
  add(field.name);
10771
11775
  add(field.options?.dataPath);
@@ -10797,34 +11801,87 @@ class AXPEntityMasterListViewModel {
10797
11801
  await this.applyViewColumns();
10798
11802
  }
10799
11803
  async onColumnsChanged(columns) {
11804
+ this.rebuildColumnTree();
10800
11805
  this.saveSettings('columnOrders', columns);
10801
11806
  }
10802
11807
  /**
10803
11808
  * Builds list columns for the active view:
10804
- * - `view.columns` is a whitelist (empty = all columns)
10805
- * - string `options.visible` is evaluated against the master-list scope
11809
+ * - empty `view.columns` → all entity list columns
11810
+ * - non-empty → whitelist (string or {@link AXPQueryColumn}); listed columns stay in the
11811
+ * picker even when `visible: false`
11812
+ * - entity `options.visible` / view column `visible` set the default switch state
10806
11813
  */
10807
11814
  async applyViewColumns() {
10808
- const viewColumnNames = this.view().columns ?? [];
11815
+ const viewColumns = normalizeAXPQueryViewColumns(this.view().columns);
11816
+ const viewByName = new Map(viewColumns.map((column) => [column.name, column]));
11817
+ const whitelistActive = viewColumns.length > 0;
10809
11818
  const scope = this.createLogicExpressionScope(null);
10810
- const cloned = await Promise.all(this.allAvailableColumns().map(async (c) => {
10811
- const column = this.entityDef.columns?.find((cc) => cc.name == c.name);
10812
- const col = new AXPEntityListViewColumnViewModel(c.property, column);
10813
- const expressionVisible = await this.resolveColumnVisibleExpression(col.visible, scope);
10814
- const includedInView = viewColumnNames.length === 0 || viewColumnNames.some((name) => name === col.name);
10815
- col.visible = includedInView && expressionVisible;
11819
+ const available = this.allAvailableColumns();
11820
+ const availableByName = new Map(available.map((column) => [column.name, column]));
11821
+ const source = whitelistActive ? viewColumns.map((viewColumn) => availableByName.get(viewColumn.name)).filter((column) => column != null) : available;
11822
+ const cloned = (await Promise.all(source.map(async (c) => {
11823
+ const entityColumn = findEntityTableColumnInTree(this.entityDef.columns, c.name);
11824
+ const viewColumn = viewByName.get(c.name);
11825
+ if (!entityColumn) {
11826
+ return null;
11827
+ }
11828
+ const columnDef = viewColumn?.width != null && String(viewColumn.width).trim() !== ''
11829
+ ? {
11830
+ ...entityColumn,
11831
+ options: {
11832
+ ...entityColumn.options,
11833
+ width: String(viewColumn.width),
11834
+ },
11835
+ }
11836
+ : entityColumn;
11837
+ const col = new AXPEntityListViewColumnViewModel(c.property, columnDef);
11838
+ if (viewColumn) {
11839
+ col.visible = viewColumn.visible;
11840
+ }
11841
+ else {
11842
+ col.visible = await this.resolveColumnVisibleExpression(col.visible, scope);
11843
+ }
10816
11844
  return col;
10817
- }));
10818
- if (viewColumnNames.length > 0) {
10819
- cloned.sort((a, b) => {
10820
- const aIndex = viewColumnNames.indexOf(a.name);
10821
- const bIndex = viewColumnNames.indexOf(b.name);
10822
- const aOrder = aIndex === -1 ? Number.MAX_SAFE_INTEGER : aIndex;
10823
- const bOrder = bIndex === -1 ? Number.MAX_SAFE_INTEGER : bIndex;
10824
- return aOrder - bOrder;
11845
+ }))).filter((column) => column != null);
11846
+ this.columns.set(cloned);
11847
+ this.rebuildColumnTree();
11848
+ }
11849
+ rebuildColumnTree() {
11850
+ const leafByName = new Map(this.columns().map((column) => [column.name, column]));
11851
+ if (this.multiLevelHeadersEnabled()) {
11852
+ this.columnTree.set(this.buildSectionBandedColumnTree(leafByName));
11853
+ return;
11854
+ }
11855
+ this.columnTree.set(this.buildMasterListColumnTree(this.entityDef.columns ?? [], leafByName));
11856
+ }
11857
+ buildMasterListColumnTree(entityColumns, leafByName) {
11858
+ const nodes = [];
11859
+ for (const column of entityColumns) {
11860
+ if (isEntityColumnBand(column)) {
11861
+ const children = this.buildMasterListColumnTree(column.children ?? [], leafByName);
11862
+ if (children.length === 0) {
11863
+ continue;
11864
+ }
11865
+ nodes.push({
11866
+ kind: 'band',
11867
+ name: column.name,
11868
+ title: column.title ?? column.name,
11869
+ visible: children.some((child) => child.visible),
11870
+ children,
11871
+ });
11872
+ continue;
11873
+ }
11874
+ const leaf = leafByName.get(column.name);
11875
+ if (!leaf) {
11876
+ continue;
11877
+ }
11878
+ nodes.push({
11879
+ kind: 'leaf',
11880
+ column: leaf,
11881
+ visible: leaf.visible !== false,
10825
11882
  });
10826
11883
  }
10827
- this.columns.set(cloned);
11884
+ return nodes;
10828
11885
  }
10829
11886
  /**
10830
11887
  * Resolves column `options.visible` (boolean or expression) to a boolean for the current list scope.
@@ -10850,6 +11907,7 @@ class AXPEntityMasterListViewModel {
10850
11907
  const columns = [...this.columns()];
10851
11908
  moveItemInArray(columns, event.previousIndex - 1, event.currentIndex - 1);
10852
11909
  this.columns.set(columns);
11910
+ this.rebuildColumnTree();
10853
11911
  this.saveSettings('columnOrders', columns);
10854
11912
  }
10855
11913
  //****************** Card fields ******************//
@@ -10896,9 +11954,7 @@ class AXPEntityMasterListViewModel {
10896
11954
  return null;
10897
11955
  }
10898
11956
  getRegisteredEntity(fullName) {
10899
- return this.entityDefinitionRegistry
10900
- .getAll()
10901
- .find((entity) => `${entity.module}.${entity.name}` === fullName);
11957
+ return this.entityDefinitionRegistry.getAll().find((entity) => `${entity.module}.${entity.name}` === fullName);
10902
11958
  }
10903
11959
  resolveRelatedEntityProperty(fieldName) {
10904
11960
  const relatedRef = this.findRelatedEntityForField(fieldName);
@@ -10946,8 +12002,7 @@ class AXPEntityMasterListViewModel {
10946
12002
  if (parentColumn?.options?.dataPath) {
10947
12003
  return parentColumn.options.dataPath;
10948
12004
  }
10949
- const relatedDataPath = this.resolveRelatedEntityColumnDataPath(relatedEntityKey, fieldName) ??
10950
- this.deriveDataPathFromLookupProperty(relatedProperty);
12005
+ const relatedDataPath = this.resolveRelatedEntityColumnDataPath(relatedEntityKey, fieldName) ?? this.deriveDataPathFromLookupProperty(relatedProperty);
10951
12006
  if (!relatedDataPath) {
10952
12007
  return undefined;
10953
12008
  }
@@ -10957,9 +12012,7 @@ class AXPEntityMasterListViewModel {
10957
12012
  if (!expose) {
10958
12013
  continue;
10959
12014
  }
10960
- const match = expose.find((entry) => entry.target === relatedDataPath ||
10961
- entry.target.endsWith(`.${relatedDataPath}`) ||
10962
- (relatedLeaf != null && entry.source === relatedLeaf));
12015
+ const match = expose.find((entry) => entry.target === relatedDataPath || entry.target.endsWith(`.${relatedDataPath}`) || (relatedLeaf != null && entry.source === relatedLeaf));
10963
12016
  if (match) {
10964
12017
  return match.target;
10965
12018
  }
@@ -11198,6 +12251,7 @@ const AXPEntityListViewModelResolver = async (route, state, service = inject(AXP
11198
12251
  const entityName = route.paramMap.get('entity');
11199
12252
  try {
11200
12253
  const vm = await service.create(moduleName, entityName);
12254
+ vm.setListInstanceId(axpGetEntityListInstanceIdFromParamMap(route.queryParamMap));
11201
12255
  const viewFromUrl = route.queryParamMap.get('view');
11202
12256
  // TODO: Consolidate list init setView calls (resolver, toolbar, list-view queryParamSub / ngAfterViewInit).
11203
12257
  await vm.setView(viewFromUrl);
@@ -12767,7 +13821,7 @@ class AXMAttachmentsPageComponentProvider {
12767
13821
  return [
12768
13822
  {
12769
13823
  key: ATTACHMENTS_PAGE_COMPONENT_KEY,
12770
- loader: () => import('./acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs').then((m) => m.AXMAttachmentsPageComponent),
13824
+ loader: () => import('./acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs').then((m) => m.AXMAttachmentsPageComponent),
12771
13825
  },
12772
13826
  ];
12773
13827
  }
@@ -13304,7 +14358,7 @@ class AXMGalleryPageComponentProvider {
13304
14358
  return [
13305
14359
  {
13306
14360
  key: GALLERY_PAGE_COMPONENT_KEY,
13307
- loader: () => import('./acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs').then((m) => m.AXMGalleryPageComponent),
14361
+ loader: () => import('./acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs').then((m) => m.AXMGalleryPageComponent),
13308
14362
  },
13309
14363
  ];
13310
14364
  }
@@ -17392,7 +18446,15 @@ function mapPropertyToWidgetColumn(property) {
17392
18446
  * Merges with the entity's registered column definition so related-list overrides inherit showAs/dataPath.
17393
18447
  */
17394
18448
  function mapEntityColumnToWidgetColumn(entity, column) {
17395
- const registeredColumn = entity.columns?.find((c) => c.name === column.name);
18449
+ if (isEntityColumnBand(column)) {
18450
+ return {
18451
+ name: column.name,
18452
+ title: column.title,
18453
+ visible: column.options?.visible !== false,
18454
+ children: (column.children ?? []).map((child) => mapEntityColumnToWidgetColumn(entity, child)),
18455
+ };
18456
+ }
18457
+ const registeredColumn = findEntityTableColumnInTree(entity.columns, column.name);
17396
18458
  const columnDef = registeredColumn
17397
18459
  ? {
17398
18460
  ...registeredColumn,
@@ -17460,6 +18522,12 @@ function mapEntityColumnToWidgetColumn(entity, column) {
17460
18522
  */
17461
18523
  function applyDataListColumnWidths(columns, columnWidthService) {
17462
18524
  return columns.map((column) => {
18525
+ if (isDataListColumnBand(column)) {
18526
+ return {
18527
+ ...column,
18528
+ children: applyDataListColumnWidths(column.children ?? [], columnWidthService),
18529
+ };
18530
+ }
17463
18531
  const existingWidth = column.width ?? column.widget?.options?.width;
17464
18532
  if (existingWidth) {
17465
18533
  return existingWidth === column.width ? column : { ...column, width: String(existingWidth) };
@@ -17490,6 +18558,30 @@ function applyIncludeExclude(items, include = [], exclude = []) {
17490
18558
  }
17491
18559
  return result;
17492
18560
  }
18561
+ /**
18562
+ * Applies include/exclude filters to leaf columns in a band tree; removes empty bands.
18563
+ */
18564
+ function applyIncludeExcludeToDataListColumnTree(items, include = [], exclude = []) {
18565
+ const filterNode = (column) => {
18566
+ if (isDataListColumnBand(column)) {
18567
+ const children = (column.children ?? [])
18568
+ .map(filterNode)
18569
+ .filter((c) => c != null);
18570
+ if (children.length === 0) {
18571
+ return null;
18572
+ }
18573
+ return { ...column, children };
18574
+ }
18575
+ if (include.length > 0 && !include.includes(column.name)) {
18576
+ return null;
18577
+ }
18578
+ if (exclude.length > 0 && exclude.includes(column.name)) {
18579
+ return null;
18580
+ }
18581
+ return column;
18582
+ };
18583
+ return items.map(filterNode).filter((c) => c != null);
18584
+ }
17493
18585
  /**
17494
18586
  * Returns only visible (non-hidden) properties of an entity.
17495
18587
  */
@@ -17536,7 +18628,7 @@ class AXPEntityListTableService {
17536
18628
  }
17537
18629
  const listOptions = {
17538
18630
  // 📊 Data Source
17539
- dataSource: this.createDataSource(entity),
18631
+ dataSource: this.createDataSource(entity, options),
17540
18632
  // 📋 Columns from Properties
17541
18633
  columns: this.createColumnsFromProperties(entity, options),
17542
18634
  // 🎯 Row Commands from Actions
@@ -17567,7 +18659,7 @@ class AXPEntityListTableService {
17567
18659
  /**
17568
18660
  * Create DataSource for Entity
17569
18661
  */
17570
- createDataSource(entity) {
18662
+ createDataSource(entity, options) {
17571
18663
  return new AXDataSource({
17572
18664
  byKey: (key) => {
17573
18665
  const func = entity.queries?.byKey?.execute;
@@ -17581,7 +18673,7 @@ class AXPEntityListTableService {
17581
18673
  resetPagingForTreeChildrenLoad(e, entity.parentKey);
17582
18674
  return func(e);
17583
18675
  },
17584
- pageSize: entity.interfaces?.master?.list?.views?.[0]?.pageSize || 10,
18676
+ pageSize: options?.pageSize || entity.interfaces?.master?.list?.views?.[0]?.pageSize || 10,
17585
18677
  key: 'id',
17586
18678
  });
17587
18679
  }
@@ -17602,7 +18694,7 @@ class AXPEntityListTableService {
17602
18694
  else {
17603
18695
  baseColumns = getVisibleProperties(entity).map((prop) => mapPropertyToWidgetColumn(prop));
17604
18696
  }
17605
- return applyDataListColumnWidths(applyIncludeExclude(baseColumns, includeColumns, excludeColumns), this.columnWidthService);
18697
+ return applyDataListColumnWidths(applyIncludeExcludeToDataListColumnTree(baseColumns, includeColumns, excludeColumns), this.columnWidthService);
17606
18698
  }
17607
18699
  /**
17608
18700
  * Map EntityTableColumn to ListWidgetColumn
@@ -17746,6 +18838,7 @@ class AXPEntityListToolbarService {
17746
18838
  filterDefinitions: this.mergeFilterDefinitions(baseFilters, options?.customFilterDefinitions),
17747
18839
  columnDefinitions: this.createColumnDefinitions(entity, options),
17748
18840
  sortDefinitions: await this.createSortDefinitions(entity),
18841
+ sortPresets: collectEntityListSortPresets(entity),
17749
18842
  canFilter: true,
17750
18843
  canColumns: true,
17751
18844
  canSort: true,
@@ -17837,7 +18930,6 @@ class AXPEntityListToolbarService {
17837
18930
  const includeColumns = options?.includeColumns || [];
17838
18931
  const relatedTableColumns = options?.relatedTableColumns;
17839
18932
  const visibleProperties = getVisibleProperties(entity);
17840
- const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
17841
18933
  let baseColumns;
17842
18934
  if (relatedTableColumns?.length) {
17843
18935
  baseColumns = relatedTableColumns.map((column) => {
@@ -17850,13 +18942,11 @@ class AXPEntityListToolbarService {
17850
18942
  });
17851
18943
  }
17852
18944
  else if (columns.length > 0) {
17853
- baseColumns = columns
17854
- .filter(({ name }) => visiblePropNames.has(name))
17855
- .map((column) => {
17856
- const property = visibleProperties.find(({ name }) => name === column.name);
18945
+ baseColumns = flattenEntityTableColumns(columns).map((column) => {
18946
+ const property = entity.properties.find(({ name }) => name === column.name) ?? visibleProperties.find(({ name }) => name === column.name);
17857
18947
  return {
17858
18948
  name: column.name,
17859
- title: property?.title,
18949
+ title: column.title || property?.title || column.name,
17860
18950
  visible: column?.options?.visible ?? true,
17861
18951
  };
17862
18952
  });
@@ -17962,6 +19052,20 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
17962
19052
  ...(ngDevMode ? [{ debugName: "showEntityActions" }] : /* istanbul ignore next */ []));
17963
19053
  this.showToolbar = computed(() => this.options()['showToolbar'] ?? true, /* @ts-ignore */
17964
19054
  ...(ngDevMode ? [{ debugName: "showToolbar" }] : /* istanbul ignore next */ []));
19055
+ this.canViews = computed(() => this.options()['canViews'] !== false, /* @ts-ignore */
19056
+ ...(ngDevMode ? [{ debugName: "canViews" }] : /* istanbul ignore next */ []));
19057
+ this.resolvedQueryViews = computed(() => {
19058
+ if (!this.canViews()) {
19059
+ return [];
19060
+ }
19061
+ const override = this.options()['views'];
19062
+ return resolveRelatedEntityListViews(override !== undefined ? { items: override } : undefined, this.entity()?.interfaces?.master?.list?.views);
19063
+ }, /* @ts-ignore */
19064
+ ...(ngDevMode ? [{ debugName: "resolvedQueryViews" }] : /* istanbul ignore next */ []));
19065
+ this.showViews = computed(() => this.resolvedQueryViews().length > 0, /* @ts-ignore */
19066
+ ...(ngDevMode ? [{ debugName: "showViews" }] : /* istanbul ignore next */ []));
19067
+ this.showListToolbar = computed(() => this.showToolbar() || this.showViews(), /* @ts-ignore */
19068
+ ...(ngDevMode ? [{ debugName: "showListToolbar" }] : /* istanbul ignore next */ []));
17965
19069
  //actions
17966
19070
  this.allActions = computed(() => {
17967
19071
  const originalList = this.entity()?.interfaces?.master?.list?.actions ?? [];
@@ -18701,6 +19805,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18701
19805
  handleQueryChanges(queries, dataSource, listInstance, isMounted) {
18702
19806
  const changeTracker = this.analyzeChanges(queries);
18703
19807
  this.previousQueries = queries;
19808
+ this.applyViewPageSize(dataSource, queries, changeTracker);
18704
19809
  this.applyDataSourceChanges(dataSource, queries, changeTracker, isMounted);
18705
19810
  this.handleListRefresh(listInstance, changeTracker, isMounted);
18706
19811
  this.handleColumnChanges(changeTracker);
@@ -18714,9 +19819,26 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18714
19819
  isFilterChanged: changes.includes('filters'),
18715
19820
  isSortChanged: changes.includes('sorts'),
18716
19821
  isColumnsChanged: changes.includes('columns'),
19822
+ isViewChanged: changes.includes('view'),
18717
19823
  hasAnyChange: changes.length > 0,
18718
19824
  };
18719
19825
  }
19826
+ applyViewPageSize(dataSource, queries, changeTracker) {
19827
+ if (!changeTracker.isViewChanged) {
19828
+ return;
19829
+ }
19830
+ const view = this.resolvedQueryViews().find((item) => item.name === queries.view);
19831
+ if (view?.pageSize && dataSource.config) {
19832
+ dataSource.config.pageSize = view.pageSize;
19833
+ }
19834
+ }
19835
+ resolveQueryViewsForEntity(entity) {
19836
+ if (this.options()['canViews'] === false) {
19837
+ return [];
19838
+ }
19839
+ const override = this.options()['views'];
19840
+ return resolveRelatedEntityListViews(override !== undefined ? { items: override } : undefined, entity.interfaces?.master?.list?.views);
19841
+ }
18720
19842
  /**
18721
19843
  * Maps toolbar sort queries ({ name, dir }) to AXDataSource sort options ({ field, dir }).
18722
19844
  */
@@ -18770,19 +19892,12 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18770
19892
  // Current columns from list options
18771
19893
  const currentColumns = (listInstance.options()['columns'] ||
18772
19894
  []);
18773
- const columnByName = new Map(currentColumns.map((c) => [c.name, c]));
18774
- // Build new ordered columns array based on toolbar order/visibility
18775
- const updatedColumns = toolbarState.columns
18776
- .map((q) => {
18777
- const base = columnByName.get(q.name);
18778
- if (!base) {
18779
- return null;
18780
- }
18781
- // Preserve all existing column config but update visibility
18782
- return { ...base, visible: q.visible };
18783
- })
18784
- .filter((c) => c != null);
18785
- // Apply updated columns to the list widget and refresh
19895
+ const visibilityByName = new Map(toolbarState.columns.map((q) => [
19896
+ q.name,
19897
+ q.visible !== false && q.visible !== 'false',
19898
+ ]));
19899
+ const leafOrder = toolbarState.columns.map((q) => q.name);
19900
+ const updatedColumns = applyLeafVisibilityToDataListColumnTree(currentColumns, visibilityByName, leafOrder);
18786
19901
  listInstance.setOptions({
18787
19902
  columns: applyDataListColumnWidths(updatedColumns, this.columnWidthService),
18788
19903
  });
@@ -18818,21 +19933,34 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18818
19933
  this.settingsService.onChanged.pipe(takeUntil(this.destroyed)).subscribe(() => {
18819
19934
  void this.applyGlobalListDisplayMode();
18820
19935
  });
18821
- const options = {
19936
+ const convertOptions = {
18822
19937
  excludeColumns: this.excludeColumns(),
18823
19938
  includeColumns: this.includeColumns(),
18824
19939
  relatedTableColumns: this.relatedTableColumns(),
18825
19940
  customFilterDefinitions: this.customFilterDefinitions(),
18826
19941
  excludeProperties: this.options()['excludeProperties'],
18827
19942
  };
18828
- const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, options, this.allActions());
19943
+ const queryViews = this.resolveQueryViewsForEntity(resolvedEntity);
19944
+ const initialView = queryViews[0];
19945
+ const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, { ...convertOptions, pageSize: initialView?.pageSize }, this.allActions());
18829
19946
  if (this.isViewDestroyed) {
18830
19947
  return;
18831
19948
  }
18832
- const toolbarOptions = await this.entityListToolbarService.convertEntityToolbarOptions(resolvedEntity, options);
19949
+ const toolbarOptions = await this.entityListToolbarService.convertEntityToolbarOptions(resolvedEntity, convertOptions);
18833
19950
  if (this.isViewDestroyed) {
18834
19951
  return;
18835
19952
  }
19953
+ const showFilterToolbar = this.showToolbar();
19954
+ const toolbarWidgetOptions = {
19955
+ ...toolbarOptions,
19956
+ canFilter: showFilterToolbar,
19957
+ canColumns: showFilterToolbar,
19958
+ canSort: showFilterToolbar,
19959
+ canViews: this.canViews() && queryViews.length > 0,
19960
+ views: queryViews,
19961
+ entitySettingKey: `${resolvedEntity.module}:${resolvedEntity.name}`,
19962
+ canListDisplay: showFilterToolbar,
19963
+ };
18836
19964
  this.initListTimeoutId = setTimeout(() => {
18837
19965
  this.initListTimeoutId = null;
18838
19966
  if (this.isViewDestroyed) {
@@ -18851,18 +19979,30 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18851
19979
  mode: 'view',
18852
19980
  defaultValue: this.getValue()?.table,
18853
19981
  });
18854
- const mergedToolbarFilters = this.getMergedToolbarFilters();
19982
+ const parentFilters = this.getMergedToolbarFilters();
19983
+ const viewFilters = initialView ? queryViewConditionsToFilterQueries(initialView) : [];
19984
+ const toolbarState = {
19985
+ view: initialView?.name,
19986
+ filters: initialView ? [...parentFilters, ...viewFilters] : parentFilters,
19987
+ sorts: initialView?.sorts ?? this.getValue()?.toolbar?.sorts,
19988
+ columns: initialView
19989
+ ? applyQueryViewToColumnQueries(toolbarWidgetOptions.columnDefinitions, initialView)
19990
+ : this.getValue()?.toolbar?.columns,
19991
+ displayMode: this.listDisplayMode(),
19992
+ };
19993
+ this.setValue({
19994
+ ...this.getValue(),
19995
+ toolbar: {
19996
+ ...(this.getValue()?.toolbar ?? {}),
19997
+ ...toolbarState,
19998
+ },
19999
+ });
18855
20000
  this.toolbarNode.set({
18856
20001
  type: AXPWidgetsCatalog.listToolbar,
18857
20002
  path: `toolbar`,
18858
- options: toolbarOptions,
20003
+ options: toolbarWidgetOptions,
18859
20004
  mode: 'view',
18860
- defaultValue: {
18861
- filters: mergedToolbarFilters,
18862
- sorts: this.getValue()?.toolbar?.sorts,
18863
- columns: this.getValue()?.toolbar?.columns,
18864
- displayMode: this.listDisplayMode(),
18865
- },
20005
+ defaultValue: toolbarState,
18866
20006
  });
18867
20007
  queueMicrotask(() => {
18868
20008
  if (!this.isViewDestroyed) {
@@ -18993,7 +20133,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18993
20133
  </div>
18994
20134
  }
18995
20135
  <div class="flex min-h-0 h-full flex-col gap-2" [style.max-height]="maxHeight()">
18996
- @if (toolbarNode() != null && showToolbar()) {
20136
+ @if (toolbarNode() != null && showListToolbar()) {
18997
20137
  <ng-container
18998
20138
  #toolbar
18999
20139
  axp-widget-renderer
@@ -19069,7 +20209,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
19069
20209
  }
19070
20210
  </div>
19071
20211
  </div>
19072
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "directive", type: i1$6.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPEntityCardComponent, selector: "axp-entity-card", inputs: ["entity", "layout", "row", "fields", "variant", "interactive", "embedded", "elevated", "disableLookupPopover", "fillHost", "extraExpanded", "selected", "showNewBadge", "showSelection", "showClose", "primaryActions", "primaryActionLook", "secondaryActionLoader"], outputs: ["extraExpandedChange", "selectionChange", "commandClick", "closeClick"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
20212
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "directive", type: i1$6.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPEntityCardComponent, selector: "axp-entity-card", inputs: ["entity", "layout", "row", "fields", "userStylingRules", "variant", "interactive", "embedded", "elevated", "disableLookupPopover", "fillHost", "extraExpanded", "selected", "showNewBadge", "showSelection", "showClose", "primaryActions", "primaryActionLook", "secondaryActionLoader"], outputs: ["extraExpandedChange", "selectionChange", "commandClick", "closeClick"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
19073
20213
  }
19074
20214
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityListWidgetViewComponent, decorators: [{
19075
20215
  type: Component,
@@ -19154,7 +20294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
19154
20294
  </div>
19155
20295
  }
19156
20296
  <div class="flex min-h-0 h-full flex-col gap-2" [style.max-height]="maxHeight()">
19157
- @if (toolbarNode() != null && showToolbar()) {
20297
+ @if (toolbarNode() != null && showListToolbar()) {
19158
20298
  <ng-container
19159
20299
  #toolbar
19160
20300
  axp-widget-renderer
@@ -19938,6 +21078,132 @@ function resolvePolymorphicRefTypePath(columnName, entityOption, expose) {
19938
21078
  }
19939
21079
  //#endregion
19940
21080
 
21081
+ //#region ----- Imports -----
21082
+ //#endregion
21083
+ //#region ----- Helpers -----
21084
+ function resolveLookupEntityCacheKey(entity) {
21085
+ if (typeof entity === 'string') {
21086
+ return entity.trim();
21087
+ }
21088
+ return `${entity.module}.${entity.name}`;
21089
+ }
21090
+ function normalizeLookupCacheId(id) {
21091
+ if (id == null || id === '') {
21092
+ return null;
21093
+ }
21094
+ return String(id);
21095
+ }
21096
+ //#endregion
21097
+ //#region ----- Service -----
21098
+ /**
21099
+ * Session-scoped GetById cache for lookup widgets.
21100
+ * Shared across edit/view/column instances so remounts and list cells reuse rows.
21101
+ */
21102
+ class AXPLookupByKeyCacheService {
21103
+ //#endregion
21104
+ //#region ----- Lifecycle -----
21105
+ constructor() {
21106
+ //#region ----- Services & Dependencies -----
21107
+ this.sessionService = inject(AXPSessionService);
21108
+ //#endregion
21109
+ //#region ----- State -----
21110
+ this.rows = new Map();
21111
+ this.inflight = new Map();
21112
+ this.generation = 0;
21113
+ this.bindSessionReset(this.sessionService.tenant$.pipe(map((tenant) => tenant?.id ?? null), distinctUntilChanged()));
21114
+ this.bindSessionReset(this.sessionService.user$.pipe(map((user) => user?.id ?? null), distinctUntilChanged()));
21115
+ }
21116
+ //#endregion
21117
+ //#region ----- Public API -----
21118
+ remember(entityKey, id, row) {
21119
+ const cacheId = normalizeLookupCacheId(id);
21120
+ const key = entityKey.trim();
21121
+ if (!key || cacheId == null || row == null) {
21122
+ return;
21123
+ }
21124
+ let entityRows = this.rows.get(key);
21125
+ if (!entityRows) {
21126
+ entityRows = new Map();
21127
+ this.rows.set(key, entityRows);
21128
+ }
21129
+ entityRows.set(cacheId, row);
21130
+ }
21131
+ peek(entityKey, id) {
21132
+ const cacheId = normalizeLookupCacheId(id);
21133
+ if (cacheId == null) {
21134
+ return undefined;
21135
+ }
21136
+ return this.rows.get(entityKey.trim())?.get(cacheId);
21137
+ }
21138
+ async getOrFetch(entityKey, id, fetch) {
21139
+ const key = entityKey.trim();
21140
+ const cacheId = normalizeLookupCacheId(id);
21141
+ if (!key || cacheId == null) {
21142
+ return null;
21143
+ }
21144
+ const cached = this.rows.get(key)?.get(cacheId);
21145
+ if (cached !== undefined) {
21146
+ return cached;
21147
+ }
21148
+ const flightKey = `${key}:${cacheId}`;
21149
+ const pending = this.inflight.get(flightKey);
21150
+ if (pending) {
21151
+ return pending;
21152
+ }
21153
+ const generation = this.generation;
21154
+ const request = Promise.resolve()
21155
+ .then(() => fetch(id))
21156
+ .then((row) => {
21157
+ if (row != null && generation === this.generation) {
21158
+ this.remember(key, cacheId, row);
21159
+ return row;
21160
+ }
21161
+ return row ?? null;
21162
+ })
21163
+ .finally(() => {
21164
+ this.inflight.delete(flightKey);
21165
+ });
21166
+ this.inflight.set(flightKey, request);
21167
+ return request;
21168
+ }
21169
+ wrap(entityKey, fetch) {
21170
+ return (id) => this.getOrFetch(entityKey, id, fetch);
21171
+ }
21172
+ clear(entityKey) {
21173
+ this.generation += 1;
21174
+ if (entityKey?.trim()) {
21175
+ this.rows.delete(entityKey.trim());
21176
+ const prefix = `${entityKey.trim()}:`;
21177
+ for (const flightKey of [...this.inflight.keys()]) {
21178
+ if (flightKey.startsWith(prefix)) {
21179
+ this.inflight.delete(flightKey);
21180
+ }
21181
+ }
21182
+ return;
21183
+ }
21184
+ this.rows.clear();
21185
+ this.inflight.clear();
21186
+ }
21187
+ //#endregion
21188
+ //#region ----- Session -----
21189
+ bindSessionReset(source) {
21190
+ let initialized = false;
21191
+ source.subscribe(() => {
21192
+ if (!initialized) {
21193
+ initialized = true;
21194
+ return;
21195
+ }
21196
+ this.clear();
21197
+ });
21198
+ }
21199
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21200
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, providedIn: 'root' }); }
21201
+ }
21202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, decorators: [{
21203
+ type: Injectable,
21204
+ args: [{ providedIn: 'root' }]
21205
+ }], ctorParameters: () => [] });
21206
+
19941
21207
  class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19942
21208
  constructor() {
19943
21209
  super(...arguments);
@@ -19946,6 +21212,7 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19946
21212
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
19947
21213
  this.contextEvalFactory = inject(AXPContextEvalFactory);
19948
21214
  this.entityResolver = inject(AXPEntityDefinitionRegistryService);
21215
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
19949
21216
  this.entity = computed(() => this.options()['entity'], /* @ts-ignore */
19950
21217
  ...(ngDevMode ? [{ debugName: "entity" }] : /* istanbul ignore next */ []));
19951
21218
  this.multiple = computed(() => this.options()['multiple'], /* @ts-ignore */
@@ -19997,8 +21264,14 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19997
21264
  const byKey = def?.queries?.byKey?.execute;
19998
21265
  if (byKey) {
19999
21266
  this.loading.set(true);
20000
- const fetchedItem = await byKey(item);
21267
+ const fetchedItem = await this.lookupByKeyCache.getOrFetch(this.entity(), item, (id) => byKey(id));
20001
21268
  this.loading.set(false);
21269
+ if (fetchedItem == null || typeof fetchedItem !== 'object') {
21270
+ return {
21271
+ id: item,
21272
+ text: item,
21273
+ };
21274
+ }
20002
21275
  return {
20003
21276
  id: fetchedItem[this.valueField()],
20004
21277
  text: await this.getDisplayRaw(fetchedItem),
@@ -20516,6 +21789,7 @@ class AXPEntityDataSelectorService {
20516
21789
  this.translationService = inject(AXTranslationService);
20517
21790
  this.rowActionsService = inject(AXPEntityDataSelectorRowActionsService);
20518
21791
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
21792
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
20519
21793
  }
20520
21794
  //#endregion
20521
21795
  //#region ---- Public Methods ----
@@ -20662,10 +21936,14 @@ class AXPEntityDataSelectorService {
20662
21936
  const { entity } = options;
20663
21937
  const filters = options.filter?.value;
20664
21938
  const parentFilters = options.filter?.parent;
21939
+ const entityKey = resolveLookupEntityCacheKey(entity);
20665
21940
  return new AXDataSource({
20666
21941
  byKey: (key) => {
20667
21942
  const func = entity.queries?.byKey?.execute;
20668
- return func(key);
21943
+ if (!func) {
21944
+ return Promise.resolve(null);
21945
+ }
21946
+ return this.lookupByKeyCache.getOrFetch(entityKey, key, (id) => func(id));
20669
21947
  },
20670
21948
  load: (e) => {
20671
21949
  const func = entity.queries?.list?.execute;
@@ -21264,11 +22542,12 @@ function isLookupValueFieldPrimaryKey(entity, valueField) {
21264
22542
  const normalized = valueField.trim() || 'id';
21265
22543
  return normalized === resolveLookupEntityPrimaryKeyField(entity);
21266
22544
  }
21267
- function rememberFetchedLookupRow(map, key, row) {
22545
+ function rememberFetchedLookupRow(map, key, row, onRow) {
21268
22546
  map.set(key, row);
21269
22547
  if (key != null) {
21270
22548
  map.set(String(key), row);
21271
22549
  }
22550
+ onRow?.(key, row);
21272
22551
  }
21273
22552
  function readFetchedLookupRow(map, key) {
21274
22553
  if (key == null) {
@@ -21298,7 +22577,7 @@ async function fetchLookupRowsByKeys(config) {
21298
22577
  uniqueKeys.forEach((key, index) => {
21299
22578
  const row = rows[index];
21300
22579
  if (row != null) {
21301
- rememberFetchedLookupRow(fetchedByKey, key, row);
22580
+ rememberFetchedLookupRow(fetchedByKey, key, row, config.onRow);
21302
22581
  }
21303
22582
  });
21304
22583
  return fetchedByKey;
@@ -21309,7 +22588,7 @@ async function fetchLookupRowsByKeys(config) {
21309
22588
  uniqueKeys.forEach((key, index) => {
21310
22589
  const row = rows[index];
21311
22590
  if (row != null) {
21312
- rememberFetchedLookupRow(fetchedByKey, key, row);
22591
+ rememberFetchedLookupRow(fetchedByKey, key, row, config.onRow);
21313
22592
  }
21314
22593
  });
21315
22594
  }
@@ -21332,7 +22611,7 @@ async function fetchLookupRowsByKeys(config) {
21332
22611
  if (storedKey == null) {
21333
22612
  continue;
21334
22613
  }
21335
- rememberFetchedLookupRow(fetchedByKey, storedKey, row);
22614
+ rememberFetchedLookupRow(fetchedByKey, storedKey, row, config.onRow);
21336
22615
  }
21337
22616
  return fetchedByKey;
21338
22617
  }
@@ -21348,7 +22627,7 @@ function createLookupEntityDataSource(config) {
21348
22627
  const valueField = config.valueField?.trim() || 'id';
21349
22628
  return new AXDataSource({
21350
22629
  byKey: async (key) => {
21351
- const byKeyExecute = entity.queries?.byKey?.execute;
22630
+ const byKeyExecute = config.byKey ?? entity.queries?.byKey?.execute;
21352
22631
  const listExecute = entity.queries?.list?.execute;
21353
22632
  const fetchedByKey = await fetchLookupRowsByKeys({
21354
22633
  entity,
@@ -21362,6 +22641,7 @@ function createLookupEntityDataSource(config) {
21362
22641
  }
21363
22642
  : undefined,
21364
22643
  queryList: listExecute,
22644
+ onRow: config.onRow,
21365
22645
  });
21366
22646
  const row = readFetchedLookupRow(fetchedByKey, key);
21367
22647
  if (row == null) {
@@ -21568,7 +22848,7 @@ function areLookupSelectionItemsHydrated(rawValue, items, options) {
21568
22848
  }
21569
22849
  //#endregion
21570
22850
 
21571
- //#region ----- Imports -----
22851
+ //#region ---- Imports -----
21572
22852
  //#endregion
21573
22853
  //#region ----- Constants -----
21574
22854
  const DEFAULT_LOOKUP_COLUMN_NAMES = ['title', 'displayName', 'name', 'code', 'description'];
@@ -21599,7 +22879,9 @@ function resolveEntityListRowTitleTemplate(entity) {
21599
22879
  return entity.interfaces?.master?.single?.title ?? entity.formats?.searchResult?.title ?? entity.formats?.individual;
21600
22880
  }
21601
22881
  function resolveDefaultColumnNames(entity) {
21602
- const fromEntity = (entity.columns ?? []).map((column) => column.name?.trim()).filter((name) => !!name);
22882
+ const fromEntity = flattenEntityTableColumns(entity.columns)
22883
+ .map((column) => column.name?.trim())
22884
+ .filter((name) => !!name);
21603
22885
  if (fromEntity.length) {
21604
22886
  return fromEntity;
21605
22887
  }
@@ -21610,7 +22892,7 @@ function resolveColumnsToProcess(entity, columnSpecs) {
21610
22892
  const { columns: entityColumns = [], properties } = entity;
21611
22893
  const visibleProperties = properties.filter(({ schema }) => schema?.visible !== false);
21612
22894
  const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
21613
- const filteredColumns = entityColumns.filter(({ name, showAs }) => visiblePropNames.has(name) || showAs);
22895
+ const filteredColumns = flattenEntityTableColumns(entityColumns).filter(({ name, showAs }) => visiblePropNames.has(name) || showAs);
21614
22896
  if (columnSpecs.length === 0) {
21615
22897
  return filteredColumns
21616
22898
  .filter((column) => DEFAULT_LOOKUP_COLUMN_NAMES.includes(column.name))
@@ -22142,7 +23424,7 @@ class AXPLookupWidgetTablePanelComponent {
22142
23424
  return Boolean(item[this.disabledField()]);
22143
23425
  }
22144
23426
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetTablePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22145
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLookupWidgetTablePanelComponent, isStandalone: true, selector: "axp-lookup-widget-table-panel", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, disabledField: { classPropertyName: "disabledField", publicName: "disabledField", isSignal: true, isRequired: false, transformFunction: null }, selectedValues: { classPropertyName: "selectedValues", publicName: "selectedValues", isSignal: true, isRequired: false, transformFunction: null }, parentField: { classPropertyName: "parentField", publicName: "parentField", isSignal: true, isRequired: false, transformFunction: null }, hasChildrenField: { classPropertyName: "hasChildrenField", publicName: "hasChildrenField", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleItems: { classPropertyName: "maxVisibleItems", publicName: "maxVisibleItems", isSignal: true, isRequired: false, transformFunction: null }, alternate: { classPropertyName: "alternate", publicName: "alternate", isSignal: true, isRequired: false, transformFunction: null }, highlightText: { classPropertyName: "highlightText", publicName: "highlightText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.ax-lookup-multi-column-tree": "!!parentField()", "style.height.px": "tableHeight()" }, classAttribute: "ax-lookup-multi-column block min-h-0" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: AXDataTableComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-data-table\n class=\"ax-lookup-multi-column-table\"\n look=\"minimal\"\n [dataSource]=\"parentField() ? dataSource() : tableDataSource\"\n [parentField]=\"parentField() ?? ''\"\n [hasChildrenField]=\"hasChildrenField()\"\n [itemHeight]=\"itemHeight()\"\n [alternative]=\"alternate()\"\n [highlightText]=\"highlightText()\"\n [loading]=\"loadingConfig()\"\n [paging]=\"false\"\n [showHeader]=\"true\"\n [fixedHeader]=\"true\"\n [showFooter]=\"false\"\n [allowReordering]=\"false\"\n [rowCssClass]=\"resolveRowCssClass\"\n (onRowClick)=\"handleRowClick($event)\"\n>\n @for (column of visibleColumns(); track column.name) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && !!parentField()\"\n [caption]=\"column.title\"\n [customWidth]=\"resolveColumnWidth(column)\"\n [node]=\"column.node\"\n ></axp-widget-column-renderer>\n }\n</ax-data-table>\n", dependencies: [{ kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i1$7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "rowCssClass", "cellCssClass", "highlightText", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1$6.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "sortEnabled", "headerSortDirection", "headerSortPriority", "columnFixed", "cellTemplate", "headerTemplate"], outputs: ["sortToggle"] }, { kind: "ngmodule", type: AXTranslationModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
23427
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLookupWidgetTablePanelComponent, isStandalone: true, selector: "axp-lookup-widget-table-panel", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, disabledField: { classPropertyName: "disabledField", publicName: "disabledField", isSignal: true, isRequired: false, transformFunction: null }, selectedValues: { classPropertyName: "selectedValues", publicName: "selectedValues", isSignal: true, isRequired: false, transformFunction: null }, parentField: { classPropertyName: "parentField", publicName: "parentField", isSignal: true, isRequired: false, transformFunction: null }, hasChildrenField: { classPropertyName: "hasChildrenField", publicName: "hasChildrenField", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleItems: { classPropertyName: "maxVisibleItems", publicName: "maxVisibleItems", isSignal: true, isRequired: false, transformFunction: null }, alternate: { classPropertyName: "alternate", publicName: "alternate", isSignal: true, isRequired: false, transformFunction: null }, highlightText: { classPropertyName: "highlightText", publicName: "highlightText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.ax-lookup-multi-column-tree": "!!parentField()", "style.height.px": "tableHeight()" }, classAttribute: "ax-lookup-multi-column block min-h-0" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: AXDataTableComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-data-table\n class=\"ax-lookup-multi-column-table\"\n look=\"minimal\"\n [dataSource]=\"parentField() ? dataSource() : tableDataSource\"\n [parentField]=\"parentField() ?? ''\"\n [hasChildrenField]=\"hasChildrenField()\"\n [itemHeight]=\"itemHeight()\"\n [alternative]=\"alternate()\"\n [highlightText]=\"highlightText()\"\n [loading]=\"loadingConfig()\"\n [paging]=\"false\"\n [showHeader]=\"true\"\n [fixedHeader]=\"true\"\n [showFooter]=\"false\"\n [allowReordering]=\"false\"\n [rowCssClass]=\"resolveRowCssClass\"\n (onRowClick)=\"handleRowClick($event)\"\n>\n @for (column of visibleColumns(); track column.name) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && !!parentField()\"\n [caption]=\"column.title\"\n [customWidth]=\"resolveColumnWidth(column)\"\n [node]=\"column.node\"\n ></axp-widget-column-renderer>\n }\n</ax-data-table>\n", dependencies: [{ kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i1$7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "rowCssClass", "cellCssClass", "highlightText", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1$6.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "columnKey", "node", "footerTemplate", "expandHandler", "sortEnabled", "headerSortDirection", "headerSortPriority", "columnFixed", "cellTemplate", "headerTemplate"], outputs: ["sortToggle"] }, { kind: "ngmodule", type: AXTranslationModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
22146
23428
  }
22147
23429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetTablePanelComponent, decorators: [{
22148
23430
  type: Component,
@@ -22468,7 +23750,7 @@ class AXPLookupWidgetTableHostComponent extends NXValueComponent {
22468
23750
  { provide: AXComponent, useExisting: AXPLookupWidgetTableHostComponent },
22469
23751
  { provide: AXClearableComponent, useExisting: AXPLookupWidgetTableHostComponent },
22470
23752
  { provide: AXValuableComponent, useExisting: AXPLookupWidgetTableHostComponent },
22471
- ], viewQueries: [{ propertyName: "triggerSearchInput", first: true, predicate: ["triggerSearchInput"], descendants: true, isSignal: true }, { propertyName: "popoverRef", first: true, predicate: AXPopoverComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n #origin\n class=\"ax-editor-container ax-solid ax-default ax-lookup-trigger w-full\"\n [class.ax-state-disabled]=\"disabled()\"\n [class.ax-state-readonly]=\"readonly()\"\n (click)=\"onTriggerClick()\"\n>\n <div class=\"ax-lookup-value\">\n @if (showSelectedTemplate()) {\n <div class=\"ax-lookup-selected-content\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"selectedTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: valueItems()[0] }\"\n />\n </div>\n }\n <input\n #triggerSearchInput\n type=\"text\"\n class=\"ax-input\"\n [class.ax-lookup-select-input]=\"!searchable()\"\n [class.ax-lookup-input-overlay]=\"showSelectedTemplate()\"\n [placeholder]=\"triggerSearchPlaceholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly() || !searchable()\"\n [attr.inputmode]=\"searchable() ? null : 'none'\"\n [value]=\"triggerInputValue()\"\n (input)=\"onTriggerSearchInput($any($event.target).value)\"\n (keydown)=\"onTriggerKeydown($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n\n @if (selectedValues().length > 0 && !disabled() && !readonly()) {\n <ng-content select=\"ax-clear-button\"></ng-content>\n }\n\n <button type=\"button\" class=\"ax-general-button-icon\" tabindex=\"-1\" [disabled]=\"disabled() || readonly()\">\n <span\n class=\"ax-icon\"\n [class.ax-icon-chevron-down]=\"!expanded()\"\n [class.ax-icon-chevron-up]=\"expanded()\"\n ></span>\n </button>\n\n <ng-content select=\"ax-validation-rule\"></ng-content>\n</div>\n\n<ax-popover\n [target]=\"origin\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'bottom-start'\"\n [width]=\"origin.offsetWidth + 'px'\"\n [disabled]=\"disabled() || readonly()\"\n (onClosed)=\"onPopoverClosed()\"\n>\n <div class=\"ax-lookup-popup\" (keydown.escape)=\"expanded.set(false)\">\n <axp-lookup-widget-table-panel\n [dataSource]=\"resolvedTableDataSource()\"\n [columns]=\"columns()\"\n [highlightText]=\"highlightQuery()\"\n [valueField]=\"valueField()\"\n [disabledField]=\"disabledField()\"\n [parentField]=\"parentField()\"\n [hasChildrenField]=\"hasChildrenField()\"\n [selectedValues]=\"selectedValues()\"\n (itemClick)=\"handleTableItemClick($event)\"\n ></axp-lookup-widget-table-panel>\n </div>\n</ax-popover>\n", styles: ["@layer properties;:host{display:block;width:100%}:host .ax-editor-container{justify-content:flex-start;gap:var(--spacing, .25rem)}:host .ax-lookup-trigger{cursor:pointer;-webkit-user-select:none;user-select:none}:host .ax-lookup-value{position:relative;display:flex;min-width:0px;flex:1;align-items:center;overflow:hidden}:host .ax-lookup-select-input{cursor:pointer;caret-color:transparent;-webkit-user-select:none;user-select:none}:host .ax-lookup-selected-content{pointer-events:none;position:relative;z-index:0;display:flex;min-width:0px;flex:1;align-items:center;overflow:hidden}:host .ax-lookup-input-overlay{position:absolute;inset:0;z-index:10;margin:0!important;height:100%;width:100%;border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:0!important;color:transparent;caret-color:transparent}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPLookupWidgetTablePanelComponent, selector: "axp-lookup-widget-table-panel", inputs: ["dataSource", "columns", "valueField", "disabledField", "selectedValues", "parentField", "hasChildrenField", "itemHeight", "maxVisibleItems", "alternate", "highlightText"], outputs: ["itemClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
23753
+ ], viewQueries: [{ propertyName: "triggerSearchInput", first: true, predicate: ["triggerSearchInput"], descendants: true, isSignal: true }, { propertyName: "popoverRef", first: true, predicate: AXPopoverComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n #origin\n class=\"ax-editor-container ax-solid ax-default ax-lookup-trigger w-full\"\n [class.ax-state-disabled]=\"disabled()\"\n [class.ax-state-readonly]=\"readonly()\"\n (click)=\"onTriggerClick()\"\n>\n <div class=\"ax-lookup-value\">\n @if (showSelectedTemplate()) {\n <div class=\"ax-lookup-selected-content\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"selectedTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: valueItems()[0] }\"\n />\n </div>\n }\n <input\n #triggerSearchInput\n type=\"text\"\n class=\"ax-input\"\n [class.ax-lookup-select-input]=\"!searchable()\"\n [class.ax-lookup-input-overlay]=\"showSelectedTemplate()\"\n [placeholder]=\"triggerSearchPlaceholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly() || !searchable()\"\n [attr.inputmode]=\"searchable() ? null : 'none'\"\n [value]=\"triggerInputValue()\"\n (input)=\"onTriggerSearchInput($any($event.target).value)\"\n (keydown)=\"onTriggerKeydown($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n\n @if (selectedValues().length > 0 && !disabled() && !readonly()) {\n <ng-content select=\"ax-clear-button\"></ng-content>\n }\n\n <button type=\"button\" class=\"ax-general-button-icon\" tabindex=\"-1\" [disabled]=\"disabled() || readonly()\">\n <span\n class=\"ax-icon\"\n [class.ax-icon-chevron-down]=\"!expanded()\"\n [class.ax-icon-chevron-up]=\"expanded()\"\n ></span>\n </button>\n\n <ng-content select=\"ax-validation-rule\"></ng-content>\n</div>\n\n<ax-popover\n [target]=\"origin\"\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [placement]=\"'bottom-start'\"\n [width]=\"origin.offsetWidth + 'px'\"\n [disabled]=\"disabled() || readonly()\"\n (onClosed)=\"onPopoverClosed()\"\n>\n <div class=\"ax-lookup-popup\" (keydown.escape)=\"expanded.set(false)\">\n <axp-lookup-widget-table-panel\n [dataSource]=\"resolvedTableDataSource()\"\n [columns]=\"columns()\"\n [highlightText]=\"highlightQuery()\"\n [valueField]=\"valueField()\"\n [disabledField]=\"disabledField()\"\n [parentField]=\"parentField()\"\n [hasChildrenField]=\"hasChildrenField()\"\n [selectedValues]=\"selectedValues()\"\n (itemClick)=\"handleTableItemClick($event)\"\n ></axp-lookup-widget-table-panel>\n </div>\n</ax-popover>\n", styles: ["@layer properties;:host{display:block;width:100%}:host .ax-editor-container{justify-content:flex-start;gap:var(--spacing, .25rem)}:host .ax-lookup-trigger{cursor:pointer;-webkit-user-select:none;user-select:none}:host .ax-lookup-value{position:relative;display:flex;min-width:0px;flex:1;align-items:center;overflow:hidden}:host .ax-lookup-select-input{cursor:pointer;caret-color:transparent;-webkit-user-select:none;user-select:none}:host .ax-lookup-selected-content{pointer-events:none;position:relative;z-index:0;display:flex;min-width:0px;flex:1;align-items:center;overflow:hidden}:host .ax-lookup-input-overlay{position:absolute;inset:0;z-index:10;margin:0!important;height:100%;width:100%;border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:0!important;color:transparent;caret-color:transparent}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPLookupWidgetTablePanelComponent, selector: "axp-lookup-widget-table-panel", inputs: ["dataSource", "columns", "valueField", "disabledField", "selectedValues", "parentField", "hasChildrenField", "itemHeight", "maxVisibleItems", "alternate", "highlightText"], outputs: ["itemClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
22472
23754
  }
22473
23755
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetTableHostComponent, decorators: [{
22474
23756
  type: Component,
@@ -22503,6 +23785,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22503
23785
  this.contextEvalFactory = inject(AXPContextEvalFactory);
22504
23786
  this.localeService = inject(AXLocaleService);
22505
23787
  this.destroyRef = inject(DestroyRef);
23788
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
22506
23789
  //#endregion
22507
23790
  //#region ----- View Children -----
22508
23791
  this.lookup = viewChild(AXLookupComponent, /* @ts-ignore */
@@ -22530,6 +23813,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22530
23813
  ...(ngDevMode ? [{ debugName: "shouldFocus" }] : /* istanbul ignore next */ []));
22531
23814
  /** Skips one {@link findByValue} pass after inline create when selection is already hydrated. */
22532
23815
  this.skipFindByValueOnce = false;
23816
+ this.lastEditorLocaleKey = this.resolveEditorLocaleKey();
22533
23817
  //#endregion
22534
23818
  //#region ----- Computed Properties -----
22535
23819
  this.expose = computed(() => this.options()['expose'], /* @ts-ignore */
@@ -22654,6 +23938,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22654
23938
  if (!entity) {
22655
23939
  return null;
22656
23940
  }
23941
+ const entityKey = resolveLookupEntityCacheKey(entity);
22657
23942
  return createLookupEntityDataSource({
22658
23943
  entity,
22659
23944
  displayField,
@@ -22662,6 +23947,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22662
23947
  getCustomFilter: () => this.customFilter(),
22663
23948
  transformFilter: (filter) => this.filterOperatorMiddleware.transformFilter(filter),
22664
23949
  decorateItem: (item) => this.decorateLookupItem(item),
23950
+ byKey: this.lookupByKeyCache.wrap(entityKey, (id) => {
23951
+ const execute = entity.queries?.byKey?.execute;
23952
+ return execute ? execute(id) : Promise.resolve(null);
23953
+ }),
23954
+ onRow: (key, row) => this.lookupByKeyCache.remember(entityKey, key, row),
22665
23955
  });
22666
23956
  }, /* @ts-ignore */
22667
23957
  ...(ngDevMode ? [{ debugName: "entityDataSource" }] : /* istanbul ignore next */ []));
@@ -22731,7 +24021,14 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22731
24021
  //#region ----- Lifecycle -----
22732
24022
  this.editorLocaleChanged = merge$1(this.mlsResolver.langChanges$, this.localeService.profileChanged$)
22733
24023
  .pipe(takeUntilDestroyed(this.destroyRef))
22734
- .subscribe(() => this.rerenderEditor());
24024
+ .subscribe(() => {
24025
+ const next = this.resolveEditorLocaleKey();
24026
+ if (next === this.lastEditorLocaleKey) {
24027
+ return;
24028
+ }
24029
+ this.lastEditorLocaleKey = next;
24030
+ this.rerenderEditor();
24031
+ });
22735
24032
  this.#efEntity = effect(async () => {
22736
24033
  const key = this.entity();
22737
24034
  if (!key?.includes('.')) {
@@ -22936,14 +24233,16 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22936
24233
  const existing = currentItems.find((item) => get(item, valueField) === id);
22937
24234
  return existing == null || !isLookupItemHydrated(existing, hydration);
22938
24235
  });
24236
+ const entityKey = this.entity();
22939
24237
  const fetchedById = entityDef
22940
24238
  ? await fetchLookupRowsByKeys({
22941
24239
  entity: entityDef,
22942
24240
  valueField,
22943
24241
  keys: idsToFetch,
22944
24242
  getQueryFields: () => this.lookupQueryFields(),
22945
- byKey: (id) => entityDataAccessor.byKey(id),
24243
+ byKey: this.lookupByKeyCache.wrap(entityKey, (id) => entityDataAccessor.byKey(id)),
22946
24244
  queryList: (request) => entityDataAccessor.query(request),
24245
+ onRow: (key, row) => this.lookupByKeyCache.remember(entityKey, key, row),
22947
24246
  })
22948
24247
  : new Map();
22949
24248
  const mergedItems = (await Promise.all(ids.map(async (id) => {
@@ -22977,6 +24276,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22977
24276
  filterMode: this.filterMode(),
22978
24277
  };
22979
24278
  }
24279
+ resolveEditorLocaleKey() {
24280
+ const lang = this.mlsResolver.getActiveLang() ?? '';
24281
+ const profile = this.localeService.activeProfile()?.localeInfo?.code ?? '';
24282
+ return `${lang}:${profile}`;
24283
+ }
22980
24284
  rerenderEditor() {
22981
24285
  this.localeEpoch.update((epoch) => epoch + 1);
22982
24286
  this.editorKey.set(false);
@@ -23010,6 +24314,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
23010
24314
  return;
23011
24315
  }
23012
24316
  const decorated = await this.decorateLookupItem(createdItem);
24317
+ this.lookupByKeyCache.remember(this.entity(), newId, createdItem);
23013
24318
  this.skipFindByValueOnce = true;
23014
24319
  this.lookup()?.seedItems([decorated]);
23015
24320
  if (this.multiple()) {
@@ -23239,6 +24544,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23239
24544
  this.queryExecutor = inject(AXPQueryExecutor);
23240
24545
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
23241
24546
  this.contextEvalFactory = inject(AXPContextEvalFactory);
24547
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
23242
24548
  //#endregion
23243
24549
  //#region ---- View Children ----
23244
24550
  this.moreButton = viewChild('moreButton', /* @ts-ignore */
@@ -23752,7 +25058,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23752
25058
  this.resolveError.set(null);
23753
25059
  try {
23754
25060
  const accessor = this.entityService.withEntity(entityKey).data();
23755
- const results = await Promise.all(ids.map((id) => accessor.byKey(id)));
25061
+ const results = await Promise.all(ids.map((id) => this.lookupByKeyCache.getOrFetch(entityKey, id, (key) => accessor.byKey(key))));
23756
25062
  this.resolvedPopoverItems.set(results.filter((item) => item != null));
23757
25063
  this.resolveStatus.set('ready');
23758
25064
  }
@@ -23858,7 +25164,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23858
25164
  const requestId = ++this.hydrateRequestId;
23859
25165
  try {
23860
25166
  const accessor = this.entityService.withEntity(entityKey).data();
23861
- const items = await Promise.all(ids.map((id) => accessor.byKey(id)));
25167
+ const items = await Promise.all(ids.map((id) => this.lookupByKeyCache.getOrFetch(entityKey, id, (key) => accessor.byKey(key))));
23862
25168
  if (requestId !== this.hydrateRequestId) {
23863
25169
  return;
23864
25170
  }
@@ -23996,7 +25302,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23996
25302
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) || /^\d+$/.test(value);
23997
25303
  }
23998
25304
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
23999
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n <div class=\"relative flex min-w-0 items-center gap-1\">\n @for (item of visibleItems(); track $index) {\n <span\n [class.cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:text-primary]=\"detailPopoverEnabled()\"\n [class.hover:underline]=\"detailPopoverEnabled()\"\n (click)=\"handleItemClick($index, $event)\"\n >\n {{ getItemLabel($index) }}\n </span>\n @if ($index < visibleItems().length - 1) {\n <span class=\"text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"absolute end-0 flex h-full cursor-pointer items-center px-1 hover:primary-lighter-surface\"\n (click)=\"showMoreItems(); $event.stopPropagation()\"\n #moreButton\n >\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n </div>\n} @else {\n <div class=\"flex min-w-0 items-center gap-1\">\n @if (displayCount() > 0) {\n <span\n class=\"cursor-pointer text-primary hover:underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\"\n #lazyTrigger\n >\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"text-muted\">---</span>\n }\n </div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"lightest-surface dark:dark-surface min-w-[280px] rounded-lg p-4 shadow-lg\">\n <div class=\"mb-4 border-b pb-2\">\n <h3 class=\"text-base font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === 'loading') {\n <div class=\"flex min-h-[120px] items-center justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"text-danger text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"flex max-h-64 flex-col gap-3\">\n @for (item of popoverListItems(); track $index) {\n <span\n [class.cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:text-primary]=\"detailPopoverEnabled()\"\n [class.hover:underline]=\"detailPopoverEnabled()\"\n (click)=\"handlePopoverItemClick($index, $event)\"\n >\n {{ getPopoverItemLabel($index) }}\n </span>\n } @empty {\n <span class=\"text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i1$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25305
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n <div class=\"relative flex min-w-0 items-center gap-1\">\n @for (item of visibleItems(); track $index) {\n <span\n [class.cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:text-primary]=\"detailPopoverEnabled()\"\n [class.hover:underline]=\"detailPopoverEnabled()\"\n (click)=\"handleItemClick($index, $event)\"\n >\n {{ getItemLabel($index) }}\n </span>\n @if ($index < visibleItems().length - 1) {\n <span class=\"text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"absolute end-0 flex h-full cursor-pointer items-center px-1 hover:primary-lighter-surface\"\n (click)=\"showMoreItems(); $event.stopPropagation()\"\n #moreButton\n >\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n </div>\n} @else {\n <div class=\"flex min-w-0 items-center gap-1\">\n @if (displayCount() > 0) {\n <span\n class=\"cursor-pointer text-primary hover:underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\"\n #lazyTrigger\n >\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"text-muted\">---</span>\n }\n </div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"lightest-surface dark:dark-surface min-w-[280px] rounded-lg p-4 shadow-lg\">\n <div class=\"mb-4 border-b pb-2\">\n <h3 class=\"text-base font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === 'loading') {\n <div class=\"flex min-h-[120px] items-center justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"text-danger text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"flex max-h-64 flex-col gap-3\">\n @for (item of popoverListItems(); track $index) {\n <span\n [class.cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:text-primary]=\"detailPopoverEnabled()\"\n [class.hover:underline]=\"detailPopoverEnabled()\"\n (click)=\"handlePopoverItemClick($index, $event)\"\n >\n {{ getPopoverItemLabel($index) }}\n </span>\n } @empty {\n <span class=\"text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i1$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24000
25306
  }
24001
25307
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetColumnComponent, decorators: [{
24002
25308
  type: Component,
@@ -24741,7 +26047,7 @@ class AXPMultiSourceSelectorComponent extends AXBasePageComponent {
24741
26047
  ></ax-button>
24742
26048
  </ax-suffix>
24743
26049
  </ax-footer>
24744
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$1.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i2$1.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26050
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$1.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i2$1.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24745
26051
  }
24746
26052
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPMultiSourceSelectorComponent, decorators: [{
24747
26053
  type: Component,
@@ -26930,6 +28236,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
26930
28236
  class AXPLayoutAdapterBuilder {
26931
28237
  constructor() {
26932
28238
  this.badgeStatusService = inject(AXPDetailsViewBadgeStatusService);
28239
+ this.navTrailService = inject(AXPEntityDetailsNavTrailService);
26933
28240
  this.adapter = {};
26934
28241
  }
26935
28242
  setEntity(entity, rootContext) {
@@ -26995,26 +28302,26 @@ class AXPLayoutAdapterBuilder {
26995
28302
  const primaryPageId = this.resolvePrimaryPageId();
26996
28303
  // Same-route breadcrumb clicks keep the current `?page=` unless the primary page is explicit.
26997
28304
  const entityViewPath = primaryPageId ? `${viewPath}?page=${encodeURIComponent(primaryPageId)}` : viewPath;
26998
- return [
26999
- {
27000
- title: this.entity?.formats.plural ?? '',
27001
- command: {
27002
- name: 'navigate',
27003
- options: {
27004
- path: `/${session.application?.name}/m/${moduleName}/e/${entityName}/list`,
27005
- },
28305
+ const listCrumb = {
28306
+ title: this.entity?.formats.plural ?? '',
28307
+ command: {
28308
+ name: 'navigate',
28309
+ options: {
28310
+ path: `/${session.application?.name}/m/${moduleName}/e/${entityName}/list`,
27006
28311
  },
27007
28312
  },
27008
- {
27009
- title: this.rootTitle ?? this.entity?.interfaces?.master?.single?.title ?? '',
27010
- command: {
27011
- name: 'navigate',
27012
- options: {
27013
- path: entityViewPath,
27014
- },
28313
+ };
28314
+ const recordCrumb = {
28315
+ title: this.rootTitle ?? this.entity?.interfaces?.master?.single?.title ?? '',
28316
+ command: {
28317
+ name: 'navigate',
28318
+ options: {
28319
+ path: entityViewPath,
27015
28320
  },
27016
28321
  },
27017
- ];
28322
+ };
28323
+ const origin = this.navTrailService.getOriginTrail(moduleName, entityName, String(this.rootContext?.id ?? ''));
28324
+ return axpComposeEntityDetailsNavTrail(origin, listCrumb, recordCrumb);
27018
28325
  }
27019
28326
  createExecuteFunction() {
27020
28327
  return (command, context) => {
@@ -27170,6 +28477,7 @@ class AXPBaseRelatedEntityConverter {
27170
28477
  colSpan: layout?.positions?.lg?.colSpan ?? 12,
27171
28478
  colStart: layout?.positions?.lg?.colStart,
27172
28479
  colEnd: layout?.positions?.lg?.colEnd,
28480
+ ...(layout?.positions ? { positions: layout.positions } : {}),
27173
28481
  },
27174
28482
  children: [
27175
28483
  {
@@ -27225,6 +28533,7 @@ class AXPBaseRelatedEntityConverter {
27225
28533
  colSpan: s.layout?.positions?.lg?.colSpan ?? 12,
27226
28534
  colStart: s.layout?.positions?.lg?.colStart,
27227
28535
  colEnd: s.layout?.positions?.lg?.colEnd,
28536
+ ...(s.layout?.positions ? { positions: s.layout.positions } : {}),
27228
28537
  },
27229
28538
  children: [
27230
28539
  {
@@ -27883,6 +29192,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
27883
29192
  relatedTableColumns,
27884
29193
  customFilterDefinitions: relatedEntity.customFilterDefinitions,
27885
29194
  excludeProperties: relatedEntity.excludeProperties,
29195
+ ...relatedEntityListViewWidgetOptions(relatedEntity),
27886
29196
  },
27887
29197
  },
27888
29198
  ],
@@ -28002,6 +29312,7 @@ class AXPTabListConverter extends AXPBaseRelatedEntityConverter {
28002
29312
  relatedTableColumns,
28003
29313
  customFilterDefinitions: relatedEntity.customFilterDefinitions,
28004
29314
  excludeProperties: relatedEntity.excludeProperties,
29315
+ ...relatedEntityListViewWidgetOptions(relatedEntity),
28005
29316
  },
28006
29317
  },
28007
29318
  ],
@@ -28536,6 +29847,7 @@ class AXPMainEntityContentBuilder {
28536
29847
  colSpan: s.layout?.positions?.lg?.colSpan ?? 12,
28537
29848
  colStart: s.layout?.positions?.lg?.colStart ?? 1,
28538
29849
  colEnd: s.layout?.positions?.lg?.colEnd ?? 13,
29850
+ ...(s.layout?.positions ? { positions: s.layout.positions } : {}),
28539
29851
  },
28540
29852
  children: [
28541
29853
  {
@@ -28598,6 +29910,7 @@ class AXPMainEntityContentBuilder {
28598
29910
  rowSpan: layout?.positions?.lg?.rowSpan,
28599
29911
  rowStart: layout?.positions?.lg?.rowStart,
28600
29912
  rowEnd: layout?.positions?.lg?.rowEnd,
29913
+ ...(layout?.positions ? { positions: layout.positions } : {}),
28601
29914
  ...(formFieldVisible !== undefined ? { visible: formFieldVisible } : {}),
28602
29915
  ...(hintFormFieldOptionsFromDescription(p.description) ?? {}),
28603
29916
  },
@@ -29307,9 +30620,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
29307
30620
  * Use high numbers (990+) for columns that should appear at the end.
29308
30621
  */
29309
30622
  const DEFAULT_COLUMN_ORDER = {
29310
- // Identifier columns first
30623
+ // Identifier columns first (after profile band on Employee)
30624
+ profile: 0,
29311
30625
  code: 1,
29312
- employeeCode: 1,
30626
+ employeeCode: 2,
29313
30627
  // Common display columns
29314
30628
  title: 3,
29315
30629
  name: 4,
@@ -29338,6 +30652,7 @@ const DEFAULT_COLUMN_ORDER = {
29338
30652
  attachments: 800,
29339
30653
  //
29340
30654
  statusId: 995,
30655
+ status: 995,
29341
30656
  isArchived: 999,
29342
30657
  isDisabled: 999,
29343
30658
  };
@@ -29752,6 +31067,69 @@ const defaultCardLayoutMiddlewareProvider = {
29752
31067
  };
29753
31068
  //#endregion
29754
31069
 
31070
+ //#region ----- Default sort presets middleware -----
31071
+ /**
31072
+ * When an entity has a master list, fills missing Quick Presets from date/title fields.
31073
+ * Entity-authored `sortPresets` with the same `name` win.
31074
+ */
31075
+ const defaultSortPresetsMiddleware = (context) => {
31076
+ if (!context.interfaces.master.list.get()) {
31077
+ return;
31078
+ }
31079
+ const inferred = inferEntityListSortPresets(context.entity);
31080
+ if (!inferred.length) {
31081
+ return;
31082
+ }
31083
+ context.interfaces.master.list.update((list) => {
31084
+ const existing = list?.sortPresets ?? [];
31085
+ const existingNames = new Set(existing.map((preset) => preset.name));
31086
+ const extras = inferred.filter((preset) => !existingNames.has(preset.name));
31087
+ if (!extras.length) {
31088
+ return list ?? { views: [] };
31089
+ }
31090
+ return {
31091
+ ...list,
31092
+ views: list?.views ?? [],
31093
+ sortPresets: [...existing, ...extras],
31094
+ };
31095
+ });
31096
+ };
31097
+ //#endregion
31098
+ //#region ----- Provider registration -----
31099
+ const defaultSortPresetsMiddlewareProvider = {
31100
+ entityName: '*',
31101
+ modifier: defaultSortPresetsMiddleware,
31102
+ order: 500,
31103
+ };
31104
+ //#endregion
31105
+
31106
+ //#region ----- Query sort locale -----
31107
+ /**
31108
+ * Copies the active UI locale onto `params.locale` so server sort can resolve
31109
+ * multi-language fields for that language. Keeps an explicit locale already set.
31110
+ */
31111
+ function stampQueryLocale(input, locale) {
31112
+ if (!isPlainObject(input)) {
31113
+ return input;
31114
+ }
31115
+ const record = input;
31116
+ const currentParams = isPlainObject(record['params'])
31117
+ ? { ...record['params'] }
31118
+ : {};
31119
+ const existing = currentParams['locale'];
31120
+ if (typeof existing === 'string' && existing.trim()) {
31121
+ return input;
31122
+ }
31123
+ return {
31124
+ ...record,
31125
+ params: {
31126
+ ...currentParams,
31127
+ locale: locale.trim() || 'en-US',
31128
+ },
31129
+ };
31130
+ }
31131
+ //#endregion
31132
+
29755
31133
  //#region ----- Imports -----
29756
31134
  //#endregion
29757
31135
  //#region ----- Helpers -----
@@ -29876,8 +31254,16 @@ function createEntityQueryBridge(op) {
29876
31254
  return next(context);
29877
31255
  }
29878
31256
  const skipContext = inject(AXPEntityMiddlewareSkipContext);
31257
+ const translation = inject(AXTranslationService);
31258
+ const locale = translation.getActiveLang()?.trim() || 'en-US';
29879
31259
  if (skipContext.isSkipped) {
29880
- return next(context);
31260
+ if (op !== 'query') {
31261
+ return next(context);
31262
+ }
31263
+ return next({
31264
+ ...context,
31265
+ input: stampQueryLocale(context.input, locale),
31266
+ });
29881
31267
  }
29882
31268
  const injector = inject(EnvironmentInjector);
29883
31269
  const accessor = inject(AXPEntityRuntimeAccessorService);
@@ -29895,7 +31281,10 @@ function createEntityQueryBridge(op) {
29895
31281
  const ctx = createEntityMiddlewareContext(op, entityName, accessor, {
29896
31282
  request: input,
29897
31283
  });
29898
- await runEntityMiddlewarePipeline(allMiddlewares, ctx, async () => next({ key, input: (ctx.request ?? input) }), injector);
31284
+ await runEntityMiddlewarePipeline(allMiddlewares, ctx, async () => next({
31285
+ key,
31286
+ input: stampQueryLocale(ctx.request ?? input, locale),
31287
+ }), injector);
29899
31288
  return ctx.result;
29900
31289
  };
29901
31290
  }
@@ -30044,6 +31433,7 @@ const AXPCrudModifier = {
30044
31433
  const parentKey = ctx.parentKey.get();
30045
31434
  const request = parentKey != null ? applyHierarchicalRootListFilter(e, parentKey) : e;
30046
31435
  const result = await queryService.fetch(ENTITY_QUERY_DEFAULT, { entity: entityKey, ...request });
31436
+ console.log('event', e);
30047
31437
  if (result && !result.success) {
30048
31438
  throw AXPRequestError.fromCommandResult(result);
30049
31439
  }
@@ -30345,6 +31735,7 @@ function routesFacory() {
30345
31735
  class AXPEntityModule {
30346
31736
  constructor() {
30347
31737
  inject(AXPEntityListReturnUrlCaptureService);
31738
+ inject(AXPEntityDetailsNavTrailService);
30348
31739
  }
30349
31740
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
30350
31741
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityModule, imports: [AXPAttachmentsPluginModule,
@@ -30433,6 +31824,11 @@ class AXPEntityModule {
30433
31824
  useValue: defaultMultiLanguageMiddlewareProvider,
30434
31825
  multi: true,
30435
31826
  },
31827
+ {
31828
+ provide: AXP_ENTITY_MODIFIER,
31829
+ useValue: defaultSortPresetsMiddlewareProvider,
31830
+ multi: true,
31831
+ },
30436
31832
  provideCommandSetups([
30437
31833
  {
30438
31834
  key: 'Entity:OpenDetails',
@@ -30460,7 +31856,7 @@ class AXPEntityModule {
30460
31856
  },
30461
31857
  {
30462
31858
  key: 'Entity:Bulk',
30463
- command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs').then((c) => c.AXPBulkEntityCommand),
31859
+ command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs').then((c) => c.AXPBulkEntityCommand),
30464
31860
  },
30465
31861
  {
30466
31862
  key: 'Entity:OpenList',
@@ -30589,6 +31985,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
30589
31985
  useValue: defaultMultiLanguageMiddlewareProvider,
30590
31986
  multi: true,
30591
31987
  },
31988
+ {
31989
+ provide: AXP_ENTITY_MODIFIER,
31990
+ useValue: defaultSortPresetsMiddlewareProvider,
31991
+ multi: true,
31992
+ },
30592
31993
  provideCommandSetups([
30593
31994
  {
30594
31995
  key: 'Entity:OpenDetails',
@@ -30616,7 +32017,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
30616
32017
  },
30617
32018
  {
30618
32019
  key: 'Entity:Bulk',
30619
- command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs').then((c) => c.AXPBulkEntityCommand),
32020
+ command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs').then((c) => c.AXPBulkEntityCommand),
30620
32021
  },
30621
32022
  {
30622
32023
  key: 'Entity:OpenList',
@@ -30941,5 +32342,5 @@ function detectEntityChanges(oldObj, newObj) {
30941
32342
  * Generated bundle index. Do not edit.
30942
32343
  */
30943
32344
 
30944
- export { AXPEntityListViewModelResolver as $, AXPEntityDefinitionRegistryService as A, AXPEntityCategoryWidgetViewComponent as B, AXPEntityCommandTriggerViewModel as C, AXPEntityCreateViewElementViewModel as D, AXPEntityCreateViewModelFactory as E, AXPEntityCreateViewSectionViewModel as F, AXPEntityDataProvider as G, AXPEntityDataProviderImpl as H, AXPEntityDataSelectorRowActionsService as I, AXPEntityDataSelectorService as J, AXPEntityDefinitionProviderWidget as K, AXPEntityDefinitionProviderWidgetEditComponent as L, AXPEntityDeletePerformService as M, AXPEntityDetailListViewModel as N, AXPEntityDetailPopoverComponent as O, AXPEntityDetailPopoverService as P, AXPEntityDetailViewModelFactory as Q, AXPEntityDetailViewModelResolver as R, AXPEntityEventDispatcherService as S, AXPEntityFormBuilderService as T, AXPEntityLifecycleHookKeys as U, AXPEntityListPersistenceModeDefault as V, AXPEntityListTableService as W, AXPEntityListToolbarService as X, AXPEntityListViewCardFieldViewModel as Y, AXPEntityListViewColumnViewModel as Z, AXPEntityListViewModelFactory as _, showOperationResultToast as a, AXP_CLASSIFICATION_SECTION_ORDER as a$, AXPEntityListWidget as a0, AXPEntityListWidgetViewComponent as a1, AXPEntityMasterCreateViewModel as a2, AXPEntityMasterListCardSelectActionName as a3, AXPEntityMasterListViewModel as a4, AXPEntityMasterListViewQueryViewModel as a5, AXPEntityMasterSingleElementViewModel as a6, AXPEntityMasterSingleViewGroupViewModel as a7, AXPEntityMasterSingleViewModel as a8, AXPEntityMasterUpdateElementViewModel as a9, AXPMiddlewareAbortError as aA, AXPMiddlewareEntityStorageService as aB, AXPMultiSourceDefinitionProviderContext as aC, AXPMultiSourceDefinitionProviderService as aD, AXPMultiSourceFederatedSearchService as aE, AXPMultiSourceSelectorComponent as aF, AXPMultiSourceSelectorService as aG, AXPMultiSourceSelectorWidget as aH, AXPMultiSourceSelectorWidgetColumnComponent as aI, AXPMultiSourceSelectorWidgetEditComponent as aJ, AXPMultiSourceSelectorWidgetViewComponent as aK, AXPMultiSourceType as aL, AXPOpenEntityDetailsCommand as aM, AXPOpenEntityListCommand as aN, AXPRelatedColumnEnrichmentService as aO, AXPRelatedColumnMetadataResolver as aP, AXPSelectorStructureWidget as aQ, AXPSelectorStructureWidgetColumnComponent as aR, AXPSelectorStructureWidgetEditComponent as aS, AXPSelectorStructureWidgetViewComponent as aT, AXPShowFileUploaderPopupCommand as aU, AXPTruncatedBreadcrumbComponent as aV, AXPUpdateEntityCommand as aW, AXPUpdateEntityStatusCommand as aX, AXPViewEntityDetailsCommand as aY, AXP_APPEARANCE_SECTION_ORDER as aZ, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY as a_, AXPEntityMasterUpdateViewModel as aa, AXPEntityMasterUpdateViewModelFactory as ab, AXPEntityMiddlewareSkipContext as ac, AXPEntityModule as ad, AXPEntityPreloadFiltersContainerComponent as ae, AXPEntityPreloadFiltersViewModel as af, AXPEntityPreloadFiltersViewModelResolver as ag, AXPEntityResolver as ah, AXPEntityRuntimeAccessorService as ai, AXPEntityService as aj, AXPEntityStorageService as ak, AXPEntityUpdateViewSectionViewModel as al, AXPFileListComponent as am, AXPFileUploaderLoadFilesQuery as an, AXPFileUploaderSaveFilesCommand as ao, AXPFileUploaderWidget as ap, AXPFileUploaderWidgetColumnComponent as aq, AXPFileUploaderWidgetEditComponent as ar, AXPFileUploaderWidgetService as as, AXPFileUploaderWidgetViewComponent as at, AXPGetEntityDetailsQuery as au, AXPLayoutOrderingConfigService as av, AXPLookupWidget as aw, AXPLookupWidgetColumnComponent as ax, AXPLookupWidgetEditComponent as ay, AXPLookupWidgetViewComponent as az, buildSelectedIdsFilter as b, entityDeleteBridgeMiddleware as b$, AXP_CLIENT_LOCAL_DEFAULT_MAX_ITEMS as b0, AXP_CLIENT_LOCAL_PLUGIN_NAME as b1, AXP_DATA_SEEDER_TOKEN as b2, AXP_ENTITY_ACTION_PLUGIN as b3, AXP_ENTITY_CONFIG_TOKEN as b4, AXP_ENTITY_DEFINITION_LOADER as b5, AXP_ENTITY_MIDDLEWARE as b6, AXP_ENTITY_MODIFIER as b7, AXP_ENTITY_STORAGE_MIDDLEWARE as b8, AXP_MULTI_SOURCE_DEFINITION_PROVIDER as b9, clientLocalPlugin as bA, cloneLayoutArrays as bB, columnOrderingMiddleware as bC, columnOrderingMiddlewareProvider as bD, columnWidthMiddleware as bE, columnWidthMiddlewareProvider as bF, committedAttachments as bG, composeEntityMiddlewares as bH, composeEntityStorageMiddlewares as bI, computeEntityAggregates as bJ, createColumnOrderingMiddlewareProvider as bK, createEntityCardDisplayScope as bL, createEntityCardLogicScope as bM, createEntityMiddlewareContext as bN, createEntityStorageContext as bO, createLayoutOrderingMiddlewareProvider as bP, defaultCardLayoutMiddleware as bQ, defaultCardLayoutMiddlewareProvider as bR, defaultMultiLanguageMiddleware as bS, defaultMultiLanguageMiddlewareProvider as bT, detectEntityChanges as bU, dispatchEntityModifiedSideEffects as bV, ensureHierarchicalRootFilter as bW, ensureLayoutPropertyView as bX, ensureLayoutSection as bY, ensureListActions as bZ, entityCreateBridgeMiddleware as b_, DEFAULT_COLUMN_ORDER as ba, DEFAULT_PAIR_SPAN_RULES as bb, DEFAULT_PROPERTY_ORDER as bc, DEFAULT_SECTION_ORDER as bd, ENTITY_FORM_ACTION_FIRST_STEP_CONTINUE as be, ENTITY_LIST_LAYOUT_META as bf, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY as bg, ENTITY_MASTER_LIST_TRACE_NS as bh, EntityBuilder as bi, EntityDataAccessor as bj, GALLERY_PAGE_COMPONENT_KEY as bk, TREE_CHILDREN_QUERY_TAKE as bl, actionExists as bm, applyDataSourcePagingWithoutLoad as bn, attachmentFieldCount as bo, attachmentNeedsHydration as bp, attachmentsPlugin as bq, attachmentsSemanticallyEqual as br, axpCreateEntityAiToolInputDefaults as bs, axpCreateEntityCommandDefinition as bt, axpDeleteEntityCommandDefinition as bu, axpOpenEntityListCommandDefinition as bv, axpShowFileUploaderPopupCommandDefinition as bw, axpUpdateEntityStatusCommandDefinition as bx, buildDataSourceTraceSnapshot as by, canPersistEntityListState as bz, ATTACHMENTS_PAGE_COMPONENT_KEY as c, resolveMasterInterfacePropertyOrder as c$, entityGetOneBridgeMiddleware as c0, entityQueryBridgeMiddleware as c1, entityStorageCreateBridgeMiddleware as c2, entityStorageDeleteBridgeMiddleware as c3, entityStorageGetOneBridgeMiddleware as c4, entityStorageQueryBridgeMiddleware as c5, entityStorageUpdateBridgeMiddleware as c6, entityUpdateBridgeMiddleware as c7, eventDispatchMiddleware as c8, filterEntityMiddlewares as c9, mapEntityStorageErrorToCommandResult as cA, mapLegacyEntityDataSelectorOptions as cB, normalizeEntityCardHeaderDisplayValue as cC, normalizeEntityDataSelectorColumnSpecs as cD, normalizeEntityDataSelectorOptions as cE, normalizeEntityFieldToFileList as cF, normalizeEntityListPersistenceMode as cG, normalizeListPaging as cH, prefetchClientLocalRelated as cI, provideEntity as cJ, provideEntityMiddlewareBridge as cK, provideEntityRealtimeHandlers as cL, provideEntityStorageMiddlewareBridge as cM, provideLocalEntityCatalog as cN, resetPagingForTreeChildrenLoad as cO, resolveAttachmentFieldPath as cP, resolveEntityCardBadgeColorValue as cQ, resolveEntityCardHeaderValue as cR, resolveEntityMasterFieldStylingClass as cS, resolveEntityMasterRecordStylingClass as cT, resolveEntityMasterStylingClass as cU, resolveEntityPluginDetailPageOrder as cV, resolveFileUploaderEditDialog as cW, resolveFileUploaderEntityScope as cX, resolveLookupDisplayField as cY, resolveLookupDisplayTemplate as cZ, resolveLookupEntityKey as c_, filterEntityStorageMiddlewares as ca, filterSortEntityRows as cb, filterTouchesParentKey as cc, findEntityListRowDataInTree as cd, fingerprintAttachmentItem as ce, fingerprintAttachments as cf, fireEntityLifecycleHook as cg, formatLookupItemDisplay as ch, formatLookupItemDisplayAsync as ci, galleryPlugin as cj, getDataSourcePageIndex as ck, getEntityListRowId as cl, getMasterInterfacePropertySortKey as cm, hasFileUploaderTitleOrDescriptionFields as cn, hydrateAttachmentFieldToFileList as co, isAXPMiddlewareAbortError as cp, isAttachmentFieldPresentOnRow as cq, isAttachmentListEntry as cr, isAttachmentStorageRef as cs, isCategoryEntity as ct, isCategoryFilter as cu, isFileListItem as cv, isFileUploaderEditDialogAuto as cw, isLegacyEntityDataSelectorOptions as cx, layoutOrderingMiddlewareFactory as cy, layoutOrderingMiddlewareProvider as cz, AXMEntityCrudService as d, restoreEntityListExpandedRows as d0, runEntityMiddlewarePipeline as d1, runEntityQuery as d2, runEntityStorageMiddlewarePipeline as d3, searchResultDescriptionMiddleware as d4, searchResultDescriptionMiddlewareProvider as d5, shouldLoadEntityListStateFromStorage as d6, shouldResetEntityListStateOnRouteEntry as d7, traceEntityMasterList as d8, AXMEntityCrudServiceImpl as e, AXPCategoryTreeService as f, AXPClientLocalPluginModule as g, AXPCreateEntityCommand as h, AXPDataSeederService as i, AXPDeleteEntityCommand as j, AXPDomainQueryEntityDefinitionLoader as k, AXPEditFileUploaderCommand as l, AXPEntityBulkPatchPerformService as m, newBulkExecutionId as n, AXPEntityCardComponent as o, persistedAttachments as p, AXPEntityCardFieldsResolver as q, resolveBulkFailureBody as r, settleAfterLoadingDialog as s, AXPEntityCardSelectActionName as t, AXPEntityCardSkeletonComponent as u, AXPEntityCategoryTreeSelectorComponent as v, watchBulkProgress as w, AXPEntityCategoryWidget as x, AXPEntityCategoryWidgetColumnComponent as y, AXPEntityCategoryWidgetEditComponent as z };
30945
- //# sourceMappingURL=acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs.map
32345
+ export { AXPEntityListViewModelResolver as $, AXPEntityDefinitionRegistryService as A, AXPEntityCategoryWidgetViewComponent as B, AXPEntityCommandTriggerViewModel as C, AXPEntityCreateViewElementViewModel as D, AXPEntityCreateViewModelFactory as E, AXPEntityCreateViewSectionViewModel as F, AXPEntityDataProvider as G, AXPEntityDataProviderImpl as H, AXPEntityDataSelectorRowActionsService as I, AXPEntityDataSelectorService as J, AXPEntityDefinitionProviderWidget as K, AXPEntityDefinitionProviderWidgetEditComponent as L, AXPEntityDeletePerformService as M, AXPEntityDetailListViewModel as N, AXPEntityDetailPopoverComponent as O, AXPEntityDetailPopoverService as P, AXPEntityDetailViewModelFactory as Q, AXPEntityDetailViewModelResolver as R, AXPEntityEventDispatcherService as S, AXPEntityFormBuilderService as T, AXPEntityLifecycleHookKeys as U, AXPEntityListPersistenceModeDefault as V, AXPEntityListTableService as W, AXPEntityListToolbarService as X, AXPEntityListViewCardFieldViewModel as Y, AXPEntityListViewColumnViewModel as Z, AXPEntityListViewModelFactory as _, showOperationResultToast as a, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY as a$, AXPEntityListWidget as a0, AXPEntityListWidgetViewComponent as a1, AXPEntityMasterCreateViewModel as a2, AXPEntityMasterListCardSelectActionName as a3, AXPEntityMasterListViewModel as a4, AXPEntityMasterListViewQueryViewModel as a5, AXPEntityMasterSingleElementViewModel as a6, AXPEntityMasterSingleViewGroupViewModel as a7, AXPEntityMasterSingleViewModel as a8, AXPEntityMasterUpdateElementViewModel as a9, AXPLookupWidgetViewComponent as aA, AXPMiddlewareAbortError as aB, AXPMiddlewareEntityStorageService as aC, AXPMultiSourceDefinitionProviderContext as aD, AXPMultiSourceDefinitionProviderService as aE, AXPMultiSourceFederatedSearchService as aF, AXPMultiSourceSelectorComponent as aG, AXPMultiSourceSelectorService as aH, AXPMultiSourceSelectorWidget as aI, AXPMultiSourceSelectorWidgetColumnComponent as aJ, AXPMultiSourceSelectorWidgetEditComponent as aK, AXPMultiSourceSelectorWidgetViewComponent as aL, AXPMultiSourceType as aM, AXPOpenEntityDetailsCommand as aN, AXPOpenEntityListCommand as aO, AXPRelatedColumnEnrichmentService as aP, AXPRelatedColumnMetadataResolver as aQ, AXPSelectorStructureWidget as aR, AXPSelectorStructureWidgetColumnComponent as aS, AXPSelectorStructureWidgetEditComponent as aT, AXPSelectorStructureWidgetViewComponent as aU, AXPShowFileUploaderPopupCommand as aV, AXPTruncatedBreadcrumbComponent as aW, AXPUpdateEntityCommand as aX, AXPUpdateEntityStatusCommand as aY, AXPViewEntityDetailsCommand as aZ, AXP_APPEARANCE_SECTION_ORDER as a_, AXPEntityMasterUpdateViewModel as aa, AXPEntityMasterUpdateViewModelFactory as ab, AXPEntityMiddlewareSkipContext as ac, AXPEntityModule as ad, AXPEntityPreloadFiltersContainerComponent as ae, AXPEntityPreloadFiltersViewModel as af, AXPEntityPreloadFiltersViewModelResolver as ag, AXPEntityResolver as ah, AXPEntityRuntimeAccessorService as ai, AXPEntityService as aj, AXPEntityStorageService as ak, AXPEntityUpdateViewSectionViewModel as al, AXPFileListComponent as am, AXPFileUploaderLoadFilesQuery as an, AXPFileUploaderSaveFilesCommand as ao, AXPFileUploaderWidget as ap, AXPFileUploaderWidgetColumnComponent as aq, AXPFileUploaderWidgetEditComponent as ar, AXPFileUploaderWidgetService as as, AXPFileUploaderWidgetViewComponent as at, AXPGetEntityDetailsQuery as au, AXPLayoutOrderingConfigService as av, AXPLookupByKeyCacheService as aw, AXPLookupWidget as ax, AXPLookupWidgetColumnComponent as ay, AXPLookupWidgetEditComponent as az, buildSelectedIdsFilter as b, detectEntityChanges as b$, AXP_CLASSIFICATION_SECTION_ORDER as b0, AXP_CLIENT_LOCAL_DEFAULT_MAX_ITEMS as b1, AXP_CLIENT_LOCAL_PLUGIN_NAME as b2, AXP_DATA_SEEDER_TOKEN as b3, AXP_ENTITY_ACTION_PLUGIN as b4, AXP_ENTITY_CONFIG_TOKEN as b5, AXP_ENTITY_DEFINITION_LOADER as b6, AXP_ENTITY_MIDDLEWARE as b7, AXP_ENTITY_MODIFIER as b8, AXP_ENTITY_STORAGE_MIDDLEWARE as b9, axpUpdateEntityStatusCommandDefinition as bA, buildDataSourceTraceSnapshot as bB, canPersistEntityListState as bC, clientLocalPlugin as bD, cloneLayoutArrays as bE, columnOrderingMiddleware as bF, columnOrderingMiddlewareProvider as bG, columnWidthMiddleware as bH, columnWidthMiddlewareProvider as bI, committedAttachments as bJ, composeEntityMiddlewares as bK, composeEntityStorageMiddlewares as bL, computeEntityAggregates as bM, configureEntityListColumnsSettingsMigrateDrop as bN, configureEntityListColumnsSettingsVersion as bO, createColumnOrderingMiddlewareProvider as bP, createEntityCardDisplayScope as bQ, createEntityCardLogicScope as bR, createEntityMiddlewareContext as bS, createEntityStorageContext as bT, createLayoutOrderingMiddlewareProvider as bU, defaultCardLayoutMiddleware as bV, defaultCardLayoutMiddlewareProvider as bW, defaultMultiLanguageMiddleware as bX, defaultMultiLanguageMiddlewareProvider as bY, defaultSortPresetsMiddleware as bZ, defaultSortPresetsMiddlewareProvider as b_, AXP_MULTI_SOURCE_DEFINITION_PROVIDER as ba, DEFAULT_COLUMN_ORDER as bb, DEFAULT_PAIR_SPAN_RULES as bc, DEFAULT_PROPERTY_ORDER as bd, DEFAULT_SECTION_ORDER as be, ENTITY_FORM_ACTION_FIRST_STEP_CONTINUE as bf, ENTITY_LIST_LAYOUT_META as bg, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY as bh, ENTITY_MASTER_LIST_TRACE_NS as bi, EntityBuilder as bj, EntityDataAccessor as bk, GALLERY_PAGE_COMPONENT_KEY as bl, TREE_CHILDREN_QUERY_TAKE as bm, actionExists as bn, applyDataSourcePagingWithoutLoad as bo, attachmentFieldCount as bp, attachmentNeedsHydration as bq, attachmentsPlugin as br, attachmentsSemanticallyEqual as bs, axpBuildEntityListPageContextSnapshot as bt, axpCreateEntityAiToolInputDefaults as bu, axpCreateEntityCommandDefinition as bv, axpDeleteEntityCommandDefinition as bw, axpOpenEntityListCommandDefinition as bx, axpRunEntityListPageContextAction as by, axpShowFileUploaderPopupCommandDefinition as bz, ATTACHMENTS_PAGE_COMPONENT_KEY as c, readPersistedEntityListInstanceCurrentView as c$, dispatchEntityModifiedSideEffects as c0, ensureHierarchicalRootFilter as c1, ensureLayoutPropertyView as c2, ensureLayoutSection as c3, ensureListActions as c4, entityCreateBridgeMiddleware as c5, entityDeleteBridgeMiddleware as c6, entityGetOneBridgeMiddleware as c7, entityListInstanceCurrentViewPath as c8, entityListInstanceFilterPath as c9, hydrateAttachmentFieldToFileList as cA, isAXPMiddlewareAbortError as cB, isAttachmentFieldPresentOnRow as cC, isAttachmentListEntry as cD, isAttachmentStorageRef as cE, isCategoryEntity as cF, isCategoryFilter as cG, isFileListItem as cH, isFileUploaderEditDialogAuto as cI, isLegacyEntityDataSelectorOptions as cJ, layoutOrderingMiddlewareFactory as cK, layoutOrderingMiddlewareProvider as cL, mapEntityStorageErrorToCommandResult as cM, mapLegacyEntityDataSelectorOptions as cN, mergeEntityListViewAndPersistedFilters as cO, normalizeEntityCardHeaderDisplayValue as cP, normalizeEntityDataSelectorColumnSpecs as cQ, normalizeEntityDataSelectorOptions as cR, normalizeEntityFieldToFileList as cS, normalizeEntityListPersistenceMode as cT, normalizeListPaging as cU, prefetchClientLocalRelated as cV, provideEntity as cW, provideEntityMiddlewareBridge as cX, provideEntityRealtimeHandlers as cY, provideEntityStorageMiddlewareBridge as cZ, provideLocalEntityCatalog as c_, entityListStylingRulesPath as ca, entityQueryBridgeMiddleware as cb, entityStorageCreateBridgeMiddleware as cc, entityStorageDeleteBridgeMiddleware as cd, entityStorageGetOneBridgeMiddleware as ce, entityStorageQueryBridgeMiddleware as cf, entityStorageUpdateBridgeMiddleware as cg, entityUpdateBridgeMiddleware as ch, eventDispatchMiddleware as ci, filterEntityMiddlewares as cj, filterEntityStorageMiddlewares as ck, filterSortEntityRows as cl, filterTouchesParentKey as cm, findEntityListRowDataInTree as cn, fingerprintAttachmentItem as co, fingerprintAttachments as cp, fireEntityLifecycleHook as cq, formatLookupItemDisplay as cr, formatLookupItemDisplayAsync as cs, galleryPlugin as ct, getDataSourcePageIndex as cu, getEntityListColumnsSettingsMigrateDrop as cv, getEntityListColumnsSettingsVersion as cw, getEntityListRowId as cx, getMasterInterfacePropertySortKey as cy, hasFileUploaderTitleOrDescriptionFields as cz, AXMEntityCrudService as d, readPersistedEntityListInstanceFilters as d0, readPersistedEntityListStylingRules as d1, resetPagingForTreeChildrenLoad as d2, resolveAttachmentFieldPath as d3, resolveEntityCardBadgeColorValue as d4, resolveEntityCardHeaderValue as d5, resolveEntityMasterFieldStylingClass as d6, resolveEntityMasterRecordStylingClass as d7, resolveEntityMasterStylingClass as d8, resolveEntityPluginDetailPageOrder as d9, resolveFileUploaderEditDialog as da, resolveFileUploaderEntityScope as db, resolveLookupDisplayField as dc, resolveLookupDisplayTemplate as dd, resolveLookupEntityCacheKey as de, resolveLookupEntityKey as df, resolveMasterInterfacePropertyOrder as dg, restoreEntityListExpandedRows as dh, runEntityMiddlewarePipeline as di, runEntityQuery as dj, runEntityStorageMiddlewarePipeline as dk, searchResultDescriptionMiddleware as dl, searchResultDescriptionMiddlewareProvider as dm, shouldLoadEntityListStateFromStorage as dn, shouldResetEntityListStateOnRouteEntry as dp, traceEntityMasterList as dq, AXMEntityCrudServiceImpl as e, AXPCategoryTreeService as f, AXPClientLocalPluginModule as g, AXPCreateEntityCommand as h, AXPDataSeederService as i, AXPDeleteEntityCommand as j, AXPDomainQueryEntityDefinitionLoader as k, AXPEditFileUploaderCommand as l, AXPEntityBulkPatchPerformService as m, newBulkExecutionId as n, AXPEntityCardComponent as o, persistedAttachments as p, AXPEntityCardFieldsResolver as q, resolveBulkFailureBody as r, settleAfterLoadingDialog as s, AXPEntityCardSelectActionName as t, AXPEntityCardSkeletonComponent as u, AXPEntityCategoryTreeSelectorComponent as v, watchBulkProgress as w, AXPEntityCategoryWidget as x, AXPEntityCategoryWidgetColumnComponent as y, AXPEntityCategoryWidgetEditComponent as z };
32346
+ //# sourceMappingURL=acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs.map