@acorex-platform/framework-client 0.0.38 → 0.0.46

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 (103) 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 +824 -72
  6. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-core.mjs +212 -94
  8. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +292 -11
  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 +3987 -1020
  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-Dc_NpBx6.mjs} +1619 -246
  22. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Dc_NpBx6.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-Cx-n7ZuA.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-Cx-n7ZuA.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-BONV249y.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-BONV249y.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-uTG2nFly.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-uTG2nFly.mjs.map} +1 -1
  29. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  30. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +3 -3
  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 -3278
  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-CDpzvn6z.mjs +33191 -0
  35. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CDpzvn6z.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-Cw3NhWL8.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-Cw3NhWL8.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-BEa-vD6O.mjs} +21 -8
  61. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BEa-vD6O.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-single-view.component-DBUwSzvg.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-CHLsBvBE.mjs} +2 -2
  73. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs.map → acorex-platform-framework-client-themes-default-entity-master-single-view.component-CHLsBvBE.mjs.map} +1 -1
  74. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +373 -70
  75. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  76. package/fesm2022/{acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs → acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs} +102 -1
  77. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs.map +1 -0
  78. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +174 -22
  79. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  80. package/package.json +2 -2
  81. package/realtime/README.md +1 -1
  82. package/types/acorex-platform-framework-client-auth.d.ts +18 -1
  83. package/types/acorex-platform-framework-client-common.d.ts +204 -8
  84. package/types/acorex-platform-framework-client-core.d.ts +149 -114
  85. package/types/acorex-platform-framework-client-layout-builder.d.ts +29 -0
  86. package/types/acorex-platform-framework-client-layout-components.d.ts +699 -146
  87. package/types/acorex-platform-framework-client-layout-designer.d.ts +192 -14
  88. package/types/acorex-platform-framework-client-layout-entity.d.ts +155 -91
  89. package/types/acorex-platform-framework-client-layout-views.d.ts +16 -0
  90. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +140 -37
  91. package/types/acorex-platform-framework-client-layout-widgets.d.ts +235 -117
  92. package/types/acorex-platform-framework-client-realtime.d.ts +16 -3
  93. package/types/acorex-platform-framework-client-themes-default.d.ts +62 -11
  94. package/types/acorex-platform-framework-client-themes-shared.d.ts +25 -2
  95. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs +0 -77
  98. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map +0 -1
  103. 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, 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,22 @@ 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
+ }), /* @ts-ignore */
10364
+ ...(ngDevMode ? [{ debugName: "isActiveQueryViewDirty" }] : /* istanbul ignore next */ []));
10365
+ this.isActiveQueryViewCustom = computed(() => isCustomQueryView(this.view()), /* @ts-ignore */
10366
+ ...(ngDevMode ? [{ debugName: "isActiveQueryViewCustom" }] : /* istanbul ignore next */ []));
10367
+ this.canSaveActiveQueryView = computed(() => this.isActiveQueryViewDirty() && !this.isActiveQueryViewCustom(), /* @ts-ignore */
10368
+ ...(ngDevMode ? [{ debugName: "canSaveActiveQueryView" }] : /* istanbul ignore next */ []));
9732
10369
  this.showRowIndexColumnEnabled = signal(false, /* @ts-ignore */
9733
10370
  ...(ngDevMode ? [{ debugName: "showRowIndexColumnEnabled" }] : /* istanbul ignore next */ []));
10371
+ this.multiLevelHeadersEnabled = signal(false, /* @ts-ignore */
10372
+ ...(ngDevMode ? [{ debugName: "multiLevelHeadersEnabled" }] : /* istanbul ignore next */ []));
9734
10373
  /**
9735
10374
  * Row index column: if the list view defines `indexCol` (true/false), that overrides the user setting;
9736
10375
  * if `indexCol` is omitted, visibility follows {@link AXPCommonSettings.ShowRowIndexColumn}.
@@ -9747,6 +10386,12 @@ class AXPEntityMasterListViewModel {
9747
10386
  /** Layouts enabled via table (always) and `interfaces.master.card.enabled`. */
9748
10387
  this.enabledListLayouts = computed(() => resolveEnabledMasterListLayouts(this.entityDef.interfaces?.master?.card), /* @ts-ignore */
9749
10388
  ...(ngDevMode ? [{ debugName: "enabledListLayouts" }] : /* istanbul ignore next */ []));
10389
+ /** List filter editor mode from `interfaces.master.list.filterMode`. Default advanced while testing. */
10390
+ this.filterMode = computed(() => (this.entityDef.interfaces?.master?.list?.filterMode === 'normal' ? 'normal' : 'advanced'), /* @ts-ignore */
10391
+ ...(ngDevMode ? [{ debugName: "filterMode" }] : /* istanbul ignore next */ []));
10392
+ /** Named sort recipes from `interfaces.master.list.sortPresets`. */
10393
+ this.sortPresets = computed(() => collectEntityListSortPresets(this.entityDef), /* @ts-ignore */
10394
+ ...(ngDevMode ? [{ debugName: "sortPresets" }] : /* istanbul ignore next */ []));
9750
10395
  /** True when the user can switch between multiple enabled layouts. */
9751
10396
  this.canSwitchListLayout = computed(() => this.enabledListLayouts().length > 1, /* @ts-ignore */
9752
10397
  ...(ngDevMode ? [{ debugName: "canSwitchListLayout" }] : /* istanbul ignore next */ []));
@@ -9784,9 +10429,7 @@ class AXPEntityMasterListViewModel {
9784
10429
  },
9785
10430
  load: async (e) => {
9786
10431
  resetPagingForTreeChildrenLoad(e, this.entityDef.parentKey);
9787
- const listRequest = this.entityDef.parentKey != null
9788
- ? applyHierarchicalRootListFilter(e, this.entityDef.parentKey)
9789
- : e;
10432
+ const listRequest = this.entityDef.parentKey != null ? applyHierarchicalRootListFilter(e, this.entityDef.parentKey) : e;
9790
10433
  const fields = this.buildColumnQueryFields();
9791
10434
  const requestWithFields = fields?.length ? { ...listRequest, fields } : listRequest;
9792
10435
  const execute = this.entityDef.queries?.list?.execute;
@@ -9802,6 +10445,7 @@ class AXPEntityMasterListViewModel {
9802
10445
  pageSize: this.view().pageSize || 10,
9803
10446
  key: 'id',
9804
10447
  });
10448
+ this.customQueryViewsLoaded = false;
9805
10449
  this.selectedItems = signal([], /* @ts-ignore */
9806
10450
  ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
9807
10451
  /**
@@ -9890,8 +10534,9 @@ class AXPEntityMasterListViewModel {
9890
10534
  const { columns = [], properties } = this.entityDef;
9891
10535
  // const visibleProperties = properties.filter(({ schema }) => schema?.visible !== false);
9892
10536
  const propNames = new Set(properties.map(({ name }) => name));
9893
- return columns
9894
- .filter(({ name, showAs, options }) => (propNames.has(name) || showAs) && options?.visible !== false)
10537
+ // Keep `options.visible: false` columns — they stay in the picker, off by default.
10538
+ return flattenEntityTableColumns(columns)
10539
+ .filter(({ name, showAs }) => propNames.has(name) || !!showAs)
9895
10540
  .map((column) => {
9896
10541
  const relatedProperty = this.resolveMergeDetailProperty(column.name);
9897
10542
  const entityProperty = properties.find(({ name }) => name === column.name);
@@ -9924,6 +10569,8 @@ class AXPEntityMasterListViewModel {
9924
10569
  };
9925
10570
  this.columns = signal([], /* @ts-ignore */
9926
10571
  ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
10572
+ this.columnTree = signal([], /* @ts-ignore */
10573
+ ...(ngDevMode ? [{ debugName: "columnTree" }] : /* istanbul ignore next */ []));
9927
10574
  this.allAvailableCardFields = () => {
9928
10575
  return this.cardFieldsResolver.resolve(this.entityDef, this.cardLayout());
9929
10576
  };
@@ -9969,13 +10616,16 @@ class AXPEntityMasterListViewModel {
9969
10616
  });
9970
10617
  this.sortedFields.set([]);
9971
10618
  void this.syncShowRowIndexColumnSetting();
10619
+ void this.syncMultiLevelHeadersSetting();
9972
10620
  void this.applyGlobalListDisplayMode();
9973
10621
  this.settings.onLoaded.pipe(takeUntil(this.destroyed)).subscribe(() => {
9974
10622
  void this.syncShowRowIndexColumnSetting();
10623
+ void this.syncMultiLevelHeadersSetting();
9975
10624
  void this.applyGlobalListDisplayMode();
9976
10625
  });
9977
10626
  this.settings.onChanged.pipe(takeUntil(this.destroyed)).subscribe(() => {
9978
10627
  void this.syncShowRowIndexColumnSetting();
10628
+ void this.syncMultiLevelHeadersSetting();
9979
10629
  void this.applyGlobalListDisplayMode();
9980
10630
  });
9981
10631
  }
@@ -9989,6 +10639,28 @@ class AXPEntityMasterListViewModel {
9989
10639
  this.showRowIndexColumnEnabled.set(false);
9990
10640
  }
9991
10641
  }
10642
+ async syncMultiLevelHeadersSetting() {
10643
+ try {
10644
+ const value = await this.settings.get(AXPCommonSettings.EntityMultiLevelHeaders);
10645
+ const enabled = value ?? false;
10646
+ if (this.multiLevelHeadersEnabled() !== enabled) {
10647
+ this.multiLevelHeadersEnabled.set(enabled);
10648
+ this.rebuildColumnTree();
10649
+ }
10650
+ else {
10651
+ this.multiLevelHeadersEnabled.set(enabled);
10652
+ }
10653
+ }
10654
+ catch {
10655
+ if (this.multiLevelHeadersEnabled()) {
10656
+ this.multiLevelHeadersEnabled.set(false);
10657
+ this.rebuildColumnTree();
10658
+ }
10659
+ else {
10660
+ this.multiLevelHeadersEnabled.set(false);
10661
+ }
10662
+ }
10663
+ }
9992
10664
  /**
9993
10665
  * Applies {@link AXPCommonSettings.EntityListPersistenceMode} for this list instance.
9994
10666
  * Call once when the list view model is created (before loading list UI state).
@@ -10016,6 +10688,9 @@ class AXPEntityMasterListViewModel {
10016
10688
  }
10017
10689
  }
10018
10690
  }
10691
+ setListInstanceId(instanceId) {
10692
+ this.listInstanceId.set(axpNormalizeEntityListInstanceId(instanceId));
10693
+ }
10019
10694
  async getListPersistenceMode() {
10020
10695
  if (this.listPersistenceMode != null) {
10021
10696
  return this.listPersistenceMode;
@@ -10052,10 +10727,16 @@ class AXPEntityMasterListViewModel {
10052
10727
  }
10053
10728
  const listViewSetting = await this.settings.get(this.settingEntityKey);
10054
10729
  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;
10730
+ const viewSetting = listViewSetting.list?.views?.[this.view().name];
10731
+ const columnsVersion = Number(viewSetting?.columnsVersion ?? 0);
10732
+ let columns = viewSetting?.columns;
10733
+ // Product modules register migrate-drop columns via configureEntityListColumnsSettingsMigrateDrop.
10734
+ const migrateDrop = getEntityListColumnsSettingsMigrateDrop();
10735
+ const settingsVersion = getEntityListColumnsSettingsVersion();
10736
+ if (columnsVersion < settingsVersion && Array.isArray(columns) && migrateDrop.size > 0) {
10737
+ columns = columns.filter((col) => !migrateDrop.has(String(col.name)));
10738
+ }
10739
+ const sorts = viewSetting?.sorts;
10059
10740
  let columnVisibilityMap;
10060
10741
  let columnWidthsMap;
10061
10742
  if (columns) {
@@ -10065,17 +10746,16 @@ class AXPEntityMasterListViewModel {
10065
10746
  this.loadListPagingFromViewSettings(listViewSetting);
10066
10747
  if (columns && columnVisibilityMap && columnWidthsMap) {
10067
10748
  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)));
10749
+ const next = this.mergePersistedColumnOrder(prev, columns.map((col) => String(col.name)));
10070
10750
  for (const column of next) {
10071
10751
  const columnKey = column.column?.options?.dataPath ?? column.name;
10072
10752
  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;
10753
+ // Definition supplies the default (entity / view `visible`).
10754
+ // Persisted user choice overrides when present (including enabling a default-off column).
10076
10755
  const persistedVisible = columnVisibilityMap.get(columnKey);
10077
- column.visible =
10078
- definitionVisible && (persistedVisible === undefined ? true : persistedVisible !== false);
10756
+ if (persistedVisible !== undefined) {
10757
+ column.visible = persistedVisible !== false;
10758
+ }
10079
10759
  }
10080
10760
  return next;
10081
10761
  });
@@ -10083,11 +10763,10 @@ class AXPEntityMasterListViewModel {
10083
10763
  if (Array.isArray(sorts) && sorts.length) {
10084
10764
  this.setActiveSortsFromQueries(sorts);
10085
10765
  }
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
- // }
10766
+ if (!this.hasQueryParamsFilters) {
10767
+ const persistedFilters = readPersistedEntityListInstanceFilters(listViewSetting, this.listInstanceId(), this.view().name);
10768
+ this.filterQueries.set(mergeEntityListViewAndPersistedFilters(this.filterQueries(), persistedFilters));
10769
+ }
10091
10770
  const expandedRowIds = listViewSetting.list?.views?.[this.view().name]?.expandedRowIds;
10092
10771
  if (Array.isArray(expandedRowIds)) {
10093
10772
  this.expandedRowIds.set(expandedRowIds.map((id) => String(id)).filter(Boolean));
@@ -10117,8 +10796,7 @@ class AXPEntityMasterListViewModel {
10117
10796
  this.loadListPagingFromViewSettings(entitySetting);
10118
10797
  }
10119
10798
  getResolvedListPaging() {
10120
- return (this.resolvedListPaging() ??
10121
- normalizeListPaging(undefined, this.view().pageSize || this.dataSource.config.pageSize || 10));
10799
+ return this.resolvedListPaging() ?? normalizeListPaging(undefined, this.view().pageSize || this.dataSource.config.pageSize || 10);
10122
10800
  }
10123
10801
  applyPagingToDataSourceWithoutLoad() {
10124
10802
  applyDataSourcePagingWithoutLoad(this.dataSource, this.getResolvedListPaging());
@@ -10181,29 +10859,150 @@ class AXPEntityMasterListViewModel {
10181
10859
  * User-applied filters to persist (excludes hidden view conditions and empty values).
10182
10860
  */
10183
10861
  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;
10862
+ return flattenQueryFilterUserGroups(queries).queries.filter((f) => isPersistableFilterQuery(f));
10863
+ }
10864
+ async createCustomQueryView(input) {
10865
+ const sourceViewName = this.view().name;
10866
+ const name = createCustomQueryViewName();
10867
+ const view = this.snapshotActiveQueryView(name, input.title, input.includeActiveView);
10868
+ await this.persistCustomQueryView(view, { activate: false, clearInstanceFilters: false });
10869
+ await this.resetViewInstanceOverlays(sourceViewName);
10870
+ return name;
10871
+ }
10872
+ async updateCustomQueryView(input) {
10873
+ const name = this.view().name;
10874
+ const view = this.snapshotActiveQueryView(name, input.title, true);
10875
+ await this.persistCustomQueryView(view, { activate: true, clearInstanceFilters: true });
10876
+ return name;
10877
+ }
10878
+ async deleteCustomQueryView(name) {
10879
+ const target = this.views().find((view) => view.name === name);
10880
+ if (!target || !isCustomQueryView(target)) {
10881
+ return this.view().name;
10882
+ }
10883
+ await this.enqueueSettingsUpdate((prev) => removePersistedCustomQueryView(prev, name));
10884
+ this.customQueryViews.update((views) => views.filter((view) => view.name !== name));
10885
+ await this.refreshVisibleViews();
10886
+ const remaining = this.views();
10887
+ if (this.view().name !== name) {
10888
+ return this.view().name;
10889
+ }
10890
+ return remaining[0]?.name ?? null;
10891
+ }
10892
+ async loadCustomQueryViews() {
10893
+ if (this.customQueryViewsLoaded) {
10894
+ return;
10895
+ }
10896
+ const setting = await this.settings.get(this.settingEntityKey);
10897
+ this.customQueryViews.set(readPersistedCustomQueryViews(setting));
10898
+ this.customQueryViewsLoaded = true;
10899
+ }
10900
+ async persistCustomQueryView(view, options) {
10901
+ await this.enqueueSettingsUpdate((prev) => upsertPersistedCustomQueryView(prev, view));
10902
+ this.customQueryViews.update((views) => {
10903
+ const index = views.findIndex((item) => item.name === view.name);
10904
+ return index >= 0 ? views.map((item, i) => (i === index ? view : item)) : [...views, view];
10905
+ });
10906
+ await this.refreshVisibleViews();
10907
+ if (options.activate) {
10908
+ const next = this.views().find((item) => item.name === view.name);
10909
+ if (next) {
10910
+ this.view.set(next);
10911
+ this.applyViewSorts();
10912
+ await this.applyViewColumns();
10913
+ await this.applyViewFilters();
10194
10914
  }
10195
- if (Array.isArray(value) && value.length === 0) {
10196
- return false;
10915
+ }
10916
+ if (options.clearInstanceFilters) {
10917
+ await this.saveSettings('filters', []);
10918
+ }
10919
+ }
10920
+ /** Clears user overlays so the source view returns to its definition defaults after Save View. */
10921
+ async resetViewInstanceOverlays(viewName) {
10922
+ if (!(await this.shouldPersistListState())) {
10923
+ return;
10924
+ }
10925
+ await this.enqueueSettingsUpdate((prev) => {
10926
+ const next = cloneDeep(prev ?? {});
10927
+ set(next, entityListInstanceFilterPath(this.listInstanceId(), viewName), []);
10928
+ set(next, ['list', 'views', viewName, 'filters'], []);
10929
+ const viewSetting = next?.list?.views?.[viewName];
10930
+ if (viewSetting && typeof viewSetting === 'object') {
10931
+ delete viewSetting['columns'];
10932
+ delete viewSetting['sorts'];
10197
10933
  }
10198
- return true;
10934
+ return next;
10199
10935
  });
10200
10936
  }
10937
+ snapshotActiveQueryView(name, title, includeActiveView) {
10938
+ return snapshotCustomQueryView({
10939
+ name,
10940
+ title,
10941
+ includeActiveView,
10942
+ activeView: this.toQueryView(this.view()),
10943
+ currentFilters: this.filterQueries(),
10944
+ currentSorts: this.currentQueryViewSorts(),
10945
+ currentColumns: this.currentQueryViewColumns(),
10946
+ });
10947
+ }
10948
+ toQueryView(view) {
10949
+ return {
10950
+ name: view.name,
10951
+ title: view.title,
10952
+ fixed: view.fixed,
10953
+ custom: view.custom,
10954
+ columns: view.columns,
10955
+ conditions: view.conditions,
10956
+ sorts: view.sorts,
10957
+ indexCol: view.indexCol,
10958
+ pageSize: view.pageSize,
10959
+ visible: view.visible,
10960
+ };
10961
+ }
10962
+ currentQueryViewSorts() {
10963
+ return this.sortedFields()
10964
+ .filter((sort) => sort.dir === 'asc' || sort.dir === 'desc')
10965
+ .map((sort) => ({ name: sort.name, dir: sort.dir }));
10966
+ }
10967
+ currentQueryViewColumns() {
10968
+ return this.columns().map((column) => ({
10969
+ name: column.column?.options?.dataPath ?? column.name,
10970
+ visible: isQueryViewColumnVisible(column.visible),
10971
+ width: column.width,
10972
+ }));
10973
+ }
10974
+ defaultQueryViewColumns() {
10975
+ return this.allAvailableColumns().map((column) => ({
10976
+ name: column.column?.options?.dataPath ?? column.name,
10977
+ visible: isQueryViewColumnVisible(column.visible),
10978
+ }));
10979
+ }
10201
10980
  enqueueSettingsUpdate(updateFn) {
10202
10981
  const run = () => this.settings.scope(AXPPlatformScope.User).update(this.settingEntityKey, updateFn);
10203
10982
  const next = this.settingsUpdateChain.then(run);
10204
10983
  this.settingsUpdateChain = next.catch(() => undefined);
10205
10984
  return next;
10206
10985
  }
10986
+ async loadUserStylingRules() {
10987
+ if (!(await this.shouldLoadPersistedListState())) {
10988
+ this.userStylingRules.set([]);
10989
+ return;
10990
+ }
10991
+ const setting = await this.settings.get(this.settingEntityKey);
10992
+ this.userStylingRules.set(readPersistedEntityListStylingRules(setting));
10993
+ }
10994
+ async saveUserStylingRules(rules) {
10995
+ const normalized = normalizeEntityListUserStylingRules(rules);
10996
+ this.userStylingRules.set(normalized);
10997
+ if (!(await this.shouldPersistListState())) {
10998
+ return;
10999
+ }
11000
+ await this.enqueueSettingsUpdate((prev) => {
11001
+ const next = cloneDeep(prev ?? {});
11002
+ set(next, [...entityListStylingRulesPath()], normalized);
11003
+ return next;
11004
+ });
11005
+ }
10207
11006
  async saveSettings(changesType, data) {
10208
11007
  if (!(await this.shouldPersistListState())) {
10209
11008
  return;
@@ -10227,6 +11026,7 @@ class AXPEntityMasterListViewModel {
10227
11026
  width: c.name === field ? columnSizeData.width : c.width,
10228
11027
  }));
10229
11028
  set(newSettings, `list.views.${this.view().name}.columns`, updatedColumns);
11029
+ set(newSettings, `list.views.${this.view().name}.columnsVersion`, getEntityListColumnsSettingsVersion());
10230
11030
  return newSettings;
10231
11031
  });
10232
11032
  break;
@@ -10240,18 +11040,17 @@ class AXPEntityMasterListViewModel {
10240
11040
  visible: c.visible,
10241
11041
  width: c.width,
10242
11042
  })));
11043
+ set(newSettings, `list.views.${this.view().name}.columnsVersion`, getEntityListColumnsSettingsVersion());
10243
11044
  return newSettings;
10244
11045
  });
10245
11046
  break;
10246
11047
  }
10247
11048
  case 'view':
10248
- await this.enqueueSettingsUpdate((prev) => ({
10249
- ...prev,
10250
- list: {
10251
- ...prev?.list,
10252
- currentView: this.view().name,
10253
- },
10254
- }));
11049
+ await this.enqueueSettingsUpdate((prev) => {
11050
+ const newSettings = { ...prev };
11051
+ set(newSettings, entityListInstanceCurrentViewPath(this.listInstanceId()), this.view().name);
11052
+ return newSettings;
11053
+ });
10255
11054
  break;
10256
11055
  case 'pageSize':
10257
11056
  await this.enqueueSettingsUpdate((prev) => ({
@@ -10289,19 +11088,13 @@ class AXPEntityMasterListViewModel {
10289
11088
  }));
10290
11089
  break;
10291
11090
  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
- }));
11091
+ await this.enqueueSettingsUpdate((prev) => {
11092
+ const newSettings = cloneDeep(prev ?? {});
11093
+ const nextFilters = Array.isArray(data) ? data : [];
11094
+ set(newSettings, entityListInstanceFilterPath(this.listInstanceId(), this.view().name), nextFilters);
11095
+ set(newSettings, ['list', 'views', this.view().name, 'filters'], nextFilters);
11096
+ return newSettings;
11097
+ });
10305
11098
  break;
10306
11099
  case 'sorts':
10307
11100
  await this.enqueueSettingsUpdate((prev) => ({
@@ -10361,9 +11154,7 @@ class AXPEntityMasterListViewModel {
10361
11154
  async getPrimaryActions() {
10362
11155
  const scope = this.createLogicExpressionScope(null);
10363
11156
  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())))
11157
+ .filter((a) => a.priority == 'primary' && ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) || (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
10367
11158
  .map(async (a) => {
10368
11159
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
10369
11160
  if (isHidden)
@@ -10378,9 +11169,7 @@ class AXPEntityMasterListViewModel {
10378
11169
  async getSecondaryActions() {
10379
11170
  const scope = this.createLogicExpressionScope(null);
10380
11171
  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())))
11172
+ .filter((a) => a.priority == 'secondary' && ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) || (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
10384
11173
  .map(async (a) => {
10385
11174
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
10386
11175
  if (isHidden)
@@ -10433,19 +11222,7 @@ class AXPEntityMasterListViewModel {
10433
11222
  });
10434
11223
  return items;
10435
11224
  }
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
- ]); }
11225
+ static { this.URL_FILTER_OPERATOR_TYPES = new Set(['equal', 'isNull', 'isEmpty', 'lt', 'lte', 'gt', 'gte', 'startsWith', 'endsWith', 'contains', 'in']); }
10449
11226
  get properties() {
10450
11227
  return this.entityDef.properties;
10451
11228
  }
@@ -10493,13 +11270,37 @@ class AXPEntityMasterListViewModel {
10493
11270
  }
10494
11271
  toUrlFilterPayloadItems(queries) {
10495
11272
  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));
11273
+ .filter((f) => {
11274
+ if (f.filters?.length) {
11275
+ return f.filters.some((child) => isCompleteFilterCondition(child.operator?.type, child.value));
11276
+ }
11277
+ if (typeof f.field !== 'string' || f.field === '') {
11278
+ return false;
11279
+ }
11280
+ return isCompleteFilterCondition(f.operator?.type, f.value);
11281
+ })
11282
+ .map((f) => {
11283
+ if (f.filters?.length) {
11284
+ return {
11285
+ logic: f.logic ?? 'and',
11286
+ filters: f.filters.map((child) => ({
11287
+ field: child.field,
11288
+ operator: AXPEntityMasterListViewModel.coerceFilterOperatorFromUrl(child.operator),
11289
+ value: child.value,
11290
+ })),
11291
+ };
11292
+ }
11293
+ return {
11294
+ field: f.field,
11295
+ operator: AXPEntityMasterListViewModel.coerceFilterOperatorFromUrl(f.operator),
11296
+ value: f.value,
11297
+ };
11298
+ })
11299
+ .sort((a, b) => {
11300
+ const left = resolveFilterQueryIdentityField(a) ?? '';
11301
+ const right = resolveFilterQueryIdentityField(b) ?? '';
11302
+ return left.localeCompare(right);
11303
+ });
10503
11304
  }
10504
11305
  static coerceFilterOperatorFromUrl(op) {
10505
11306
  if (op && typeof op === 'object' && op !== null && 'type' in op) {
@@ -10565,7 +11366,7 @@ class AXPEntityMasterListViewModel {
10565
11366
  }
10566
11367
  /**
10567
11368
  * 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.
11369
+ * Handles known keys (`view`, `filters`, `list`) and re-evaluates view visibility for expression-driven params.
10569
11370
  *
10570
11371
  * Data reload is owned by {@link applyFilterAndSort} → `events$` when criteria change.
10571
11372
  * `reloadList` stays false so callers do not issue a second `reloadListData` for the same transition.
@@ -10576,12 +11377,24 @@ class AXPEntityMasterListViewModel {
10576
11377
  return { reloadList: false };
10577
11378
  }
10578
11379
  this.routeQueryContextKey = contextKey;
11380
+ const nextInstanceId = axpGetEntityListInstanceIdFromParamMap(queryParamMap);
11381
+ const instanceChanged = nextInstanceId !== this.listInstanceId();
11382
+ if (instanceChanged) {
11383
+ this.listInstanceId.set(nextInstanceId);
11384
+ this.hasQueryParamsFilters = false;
11385
+ }
10579
11386
  const previousViewName = this.view().name;
10580
11387
  await this.setView(queryParamMap.get('view'));
11388
+ if (instanceChanged) {
11389
+ this.applyViewFilters();
11390
+ this.applyViewSorts();
11391
+ await this.loadPersistedInstanceFilters();
11392
+ this.listFilterSeedEpoch.update((epoch) => epoch + 1);
11393
+ }
10581
11394
  const filtersChanged = await this.syncFiltersFromRouteQueryParam(queryParamMap.get('filters'));
10582
11395
  await this.refreshVisibleViews();
10583
11396
  const viewChanged = this.view().name !== previousViewName;
10584
- if (filtersChanged || viewChanged) {
11397
+ if (filtersChanged || viewChanged || instanceChanged) {
10585
11398
  this.lastAppliedFilterKey = null;
10586
11399
  this.lastAppliedSortKey = null;
10587
11400
  // Keys were cleared to force apply; pass reset so URL view/filter changes still reset paging
@@ -10658,12 +11471,16 @@ class AXPEntityMasterListViewModel {
10658
11471
  if (this.hasQueryParamsFilters) {
10659
11472
  return;
10660
11473
  }
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);
11474
+ const view = this.toQueryView(this.view());
11475
+ this.filterQueries.set(withQueryViewFilterVisibility(view, queryViewConditionsToFilterQueries(view)));
11476
+ }
11477
+ async loadPersistedInstanceFilters() {
11478
+ if (this.hasQueryParamsFilters || !(await this.shouldLoadPersistedListState())) {
11479
+ return;
11480
+ }
11481
+ const setting = await this.settings.get(this.settingEntityKey);
11482
+ const persistedFilters = readPersistedEntityListInstanceFilters(setting, this.listInstanceId(), this.view().name);
11483
+ this.filterQueries.set(mergeEntityListViewAndPersistedFilters(this.filterQueries(), persistedFilters));
10667
11484
  }
10668
11485
  resetFilters() {
10669
11486
  this.hasQueryParamsFilters = false; // Reset flag when user resets filters
@@ -10725,12 +11542,12 @@ class AXPEntityMasterListViewModel {
10725
11542
  });
10726
11543
  }
10727
11544
  updateAppliedInlineFilterHighlightText(filters) {
10728
- const quickFilter = filters.find((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD);
11545
+ const quickFilter = flattenQueryFilterUserGroups(filters).queries.find((f) => f.field === 'all' || f.field === AXP_QUERY_QUICK_SEARCH_FIELD);
10729
11546
  const value = quickFilter?.value;
10730
11547
  this.inlineFilterHighlightText.set(typeof value === 'string' ? value.trim() : '');
10731
11548
  }
10732
11549
  //****************** Columns ******************//
10733
- resolveMergeDetailProperty(columnName) {
11550
+ resolveMergeDetailSource(columnName) {
10734
11551
  const parsed = parseDottedFieldPath(columnName);
10735
11552
  if (!parsed) {
10736
11553
  return null;
@@ -10741,7 +11558,173 @@ class AXPEntityMasterListViewModel {
10741
11558
  return null;
10742
11559
  }
10743
11560
  const relatedDef = this.getRegisteredEntity(related.entity);
10744
- return relatedDef?.properties?.find((property) => property.name === propertyName) ?? null;
11561
+ const property = relatedDef?.properties?.find((item) => item.name === propertyName);
11562
+ if (!relatedDef || !property) {
11563
+ return null;
11564
+ }
11565
+ return { entity: relatedDef, property };
11566
+ }
11567
+ resolveMergeDetailProperty(columnName) {
11568
+ return this.resolveMergeDetailSource(columnName)?.property ?? null;
11569
+ }
11570
+ resolveColumnSection(column) {
11571
+ const mergeSource = this.resolveMergeDetailSource(column.name);
11572
+ const groupId = mergeSource?.property.groupId ?? column.property.groupId;
11573
+ if (!groupId) {
11574
+ return null;
11575
+ }
11576
+ const groups = mergeSource?.entity.groups ?? this.entityDef.groups;
11577
+ const group = groups?.find((item) => item.id === groupId);
11578
+ const title = group?.title?.trim();
11579
+ if (!title) {
11580
+ return null;
11581
+ }
11582
+ return { id: groupId, title };
11583
+ }
11584
+ findInnermostAuthorBand(columns, columnName) {
11585
+ for (const column of columns) {
11586
+ if (!isEntityColumnBand(column)) {
11587
+ continue;
11588
+ }
11589
+ const leaves = flattenEntityTableColumns(column.children);
11590
+ if (!leaves.some((leaf) => leaf.name === columnName)) {
11591
+ continue;
11592
+ }
11593
+ const deeper = this.findInnermostAuthorBand(column.children ?? [], columnName);
11594
+ return deeper ?? column;
11595
+ }
11596
+ return null;
11597
+ }
11598
+ buildSectionBandedColumnTree(leafByName) {
11599
+ const bucketOrder = [];
11600
+ const buckets = new Map();
11601
+ for (const column of this.columns()) {
11602
+ const authorBand = this.findInnermostAuthorBand(this.entityDef.columns ?? [], column.name);
11603
+ if (authorBand) {
11604
+ const key = `author:${authorBand.name}`;
11605
+ if (!buckets.has(key)) {
11606
+ bucketOrder.push(key);
11607
+ buckets.set(key, authorBand);
11608
+ }
11609
+ continue;
11610
+ }
11611
+ const section = this.resolveColumnSection(column);
11612
+ if (section) {
11613
+ const key = `section:${section.id}`;
11614
+ const existing = buckets.get(key);
11615
+ if (existing && typeof existing === 'object' && 'kind' in existing && existing.kind === 'section') {
11616
+ existing.leafNames.push(column.name);
11617
+ }
11618
+ else if (!existing) {
11619
+ bucketOrder.push(key);
11620
+ buckets.set(key, { kind: 'section', id: section.id, title: section.title, leafNames: [column.name] });
11621
+ }
11622
+ continue;
11623
+ }
11624
+ bucketOrder.push(`singleton:${column.name}`);
11625
+ }
11626
+ const nodes = [];
11627
+ for (const key of bucketOrder) {
11628
+ const bucket = buckets.get(key);
11629
+ if (!bucket) {
11630
+ continue;
11631
+ }
11632
+ if (key.startsWith('author:')) {
11633
+ const band = bucket;
11634
+ nodes.push(...this.buildMasterListColumnTree([band], leafByName));
11635
+ continue;
11636
+ }
11637
+ if (key.startsWith('section:')) {
11638
+ const sectionBucket = bucket;
11639
+ const children = [];
11640
+ for (const leafName of sectionBucket.leafNames) {
11641
+ const leaf = leafByName.get(leafName);
11642
+ if (!leaf) {
11643
+ continue;
11644
+ }
11645
+ children.push({
11646
+ kind: 'leaf',
11647
+ column: leaf,
11648
+ visible: leaf.visible !== false,
11649
+ });
11650
+ }
11651
+ if (children.length === 0) {
11652
+ continue;
11653
+ }
11654
+ if (children.length === 1) {
11655
+ nodes.push(children[0]);
11656
+ continue;
11657
+ }
11658
+ nodes.push({
11659
+ kind: 'band',
11660
+ name: `axp-section-${sectionBucket.id}`,
11661
+ title: sectionBucket.title,
11662
+ visible: children.some((child) => child.visible),
11663
+ children,
11664
+ });
11665
+ continue;
11666
+ }
11667
+ if (key.startsWith('singleton:')) {
11668
+ const leafName = key.slice('singleton:'.length);
11669
+ const leaf = leafByName.get(leafName);
11670
+ if (!leaf) {
11671
+ continue;
11672
+ }
11673
+ nodes.push({
11674
+ kind: 'leaf',
11675
+ column: leaf,
11676
+ visible: leaf.visible !== false,
11677
+ });
11678
+ }
11679
+ }
11680
+ return nodes;
11681
+ }
11682
+ /**
11683
+ * Merges persisted column order onto the definition order.
11684
+ * Columns missing from saved prefs keep their definition-relative position.
11685
+ */
11686
+ mergePersistedColumnOrder(definitionColumns, persistedNames) {
11687
+ const columnKey = (column) => column.column?.options?.dataPath ?? column.name;
11688
+ const byKey = new Map(definitionColumns.map((column) => [columnKey(column), column]));
11689
+ const result = [];
11690
+ const placed = new Set();
11691
+ for (const name of persistedNames) {
11692
+ const column = byKey.get(name);
11693
+ if (!column) {
11694
+ continue;
11695
+ }
11696
+ result.push(column);
11697
+ placed.add(name);
11698
+ }
11699
+ for (let index = 0; index < definitionColumns.length; index++) {
11700
+ const column = definitionColumns[index];
11701
+ const key = columnKey(column);
11702
+ if (placed.has(key)) {
11703
+ continue;
11704
+ }
11705
+ let insertAt = result.length;
11706
+ for (let prev = index - 1; prev >= 0; prev--) {
11707
+ const prevKey = columnKey(definitionColumns[prev]);
11708
+ const prevIndex = result.findIndex((entry) => columnKey(entry) === prevKey);
11709
+ if (prevIndex !== -1) {
11710
+ insertAt = prevIndex + 1;
11711
+ break;
11712
+ }
11713
+ }
11714
+ if (insertAt === result.length) {
11715
+ for (let next = index + 1; next < definitionColumns.length; next++) {
11716
+ const nextKey = columnKey(definitionColumns[next]);
11717
+ const nextIndex = result.findIndex((entry) => columnKey(entry) === nextKey);
11718
+ if (nextIndex !== -1) {
11719
+ insertAt = nextIndex;
11720
+ break;
11721
+ }
11722
+ }
11723
+ }
11724
+ result.splice(insertAt, 0, column);
11725
+ placed.add(key);
11726
+ }
11727
+ return result;
10745
11728
  }
10746
11729
  collectCardLayoutQueryFields() {
10747
11730
  const card = this.cardLayout();
@@ -10764,8 +11747,7 @@ class AXPEntityMasterListViewModel {
10764
11747
  for (const path of collectEntityCardUserIdQueryFields(this.entityDef, card.header?.avatar ?? resolveEntityCardAvatarPath(this.entityDef, this.entityDef.columns))) {
10765
11748
  add(path);
10766
11749
  }
10767
- const occupied = new Set([card.header?.title, card.header?.description, card.header?.avatar]
10768
- .filter((name) => !!name && !name.includes('{{')));
11750
+ const occupied = new Set([card.header?.title, card.header?.description, card.header?.avatar].filter((name) => !!name && !name.includes('{{')));
10769
11751
  for (const field of card.fields ?? []) {
10770
11752
  add(field.name);
10771
11753
  add(field.options?.dataPath);
@@ -10797,34 +11779,87 @@ class AXPEntityMasterListViewModel {
10797
11779
  await this.applyViewColumns();
10798
11780
  }
10799
11781
  async onColumnsChanged(columns) {
11782
+ this.rebuildColumnTree();
10800
11783
  this.saveSettings('columnOrders', columns);
10801
11784
  }
10802
11785
  /**
10803
11786
  * 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
11787
+ * - empty `view.columns` → all entity list columns
11788
+ * - non-empty → whitelist (string or {@link AXPQueryColumn}); listed columns stay in the
11789
+ * picker even when `visible: false`
11790
+ * - entity `options.visible` / view column `visible` set the default switch state
10806
11791
  */
10807
11792
  async applyViewColumns() {
10808
- const viewColumnNames = this.view().columns ?? [];
11793
+ const viewColumns = normalizeAXPQueryViewColumns(this.view().columns);
11794
+ const viewByName = new Map(viewColumns.map((column) => [column.name, column]));
11795
+ const whitelistActive = viewColumns.length > 0;
10809
11796
  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;
11797
+ const available = this.allAvailableColumns();
11798
+ const availableByName = new Map(available.map((column) => [column.name, column]));
11799
+ const source = whitelistActive ? viewColumns.map((viewColumn) => availableByName.get(viewColumn.name)).filter((column) => column != null) : available;
11800
+ const cloned = (await Promise.all(source.map(async (c) => {
11801
+ const entityColumn = findEntityTableColumnInTree(this.entityDef.columns, c.name);
11802
+ const viewColumn = viewByName.get(c.name);
11803
+ if (!entityColumn) {
11804
+ return null;
11805
+ }
11806
+ const columnDef = viewColumn?.width != null && String(viewColumn.width).trim() !== ''
11807
+ ? {
11808
+ ...entityColumn,
11809
+ options: {
11810
+ ...entityColumn.options,
11811
+ width: String(viewColumn.width),
11812
+ },
11813
+ }
11814
+ : entityColumn;
11815
+ const col = new AXPEntityListViewColumnViewModel(c.property, columnDef);
11816
+ if (viewColumn) {
11817
+ col.visible = viewColumn.visible;
11818
+ }
11819
+ else {
11820
+ col.visible = await this.resolveColumnVisibleExpression(col.visible, scope);
11821
+ }
10816
11822
  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;
11823
+ }))).filter((column) => column != null);
11824
+ this.columns.set(cloned);
11825
+ this.rebuildColumnTree();
11826
+ }
11827
+ rebuildColumnTree() {
11828
+ const leafByName = new Map(this.columns().map((column) => [column.name, column]));
11829
+ if (this.multiLevelHeadersEnabled()) {
11830
+ this.columnTree.set(this.buildSectionBandedColumnTree(leafByName));
11831
+ return;
11832
+ }
11833
+ this.columnTree.set(this.buildMasterListColumnTree(this.entityDef.columns ?? [], leafByName));
11834
+ }
11835
+ buildMasterListColumnTree(entityColumns, leafByName) {
11836
+ const nodes = [];
11837
+ for (const column of entityColumns) {
11838
+ if (isEntityColumnBand(column)) {
11839
+ const children = this.buildMasterListColumnTree(column.children ?? [], leafByName);
11840
+ if (children.length === 0) {
11841
+ continue;
11842
+ }
11843
+ nodes.push({
11844
+ kind: 'band',
11845
+ name: column.name,
11846
+ title: column.title ?? column.name,
11847
+ visible: children.some((child) => child.visible),
11848
+ children,
11849
+ });
11850
+ continue;
11851
+ }
11852
+ const leaf = leafByName.get(column.name);
11853
+ if (!leaf) {
11854
+ continue;
11855
+ }
11856
+ nodes.push({
11857
+ kind: 'leaf',
11858
+ column: leaf,
11859
+ visible: leaf.visible !== false,
10825
11860
  });
10826
11861
  }
10827
- this.columns.set(cloned);
11862
+ return nodes;
10828
11863
  }
10829
11864
  /**
10830
11865
  * Resolves column `options.visible` (boolean or expression) to a boolean for the current list scope.
@@ -10850,6 +11885,7 @@ class AXPEntityMasterListViewModel {
10850
11885
  const columns = [...this.columns()];
10851
11886
  moveItemInArray(columns, event.previousIndex - 1, event.currentIndex - 1);
10852
11887
  this.columns.set(columns);
11888
+ this.rebuildColumnTree();
10853
11889
  this.saveSettings('columnOrders', columns);
10854
11890
  }
10855
11891
  //****************** Card fields ******************//
@@ -10896,9 +11932,7 @@ class AXPEntityMasterListViewModel {
10896
11932
  return null;
10897
11933
  }
10898
11934
  getRegisteredEntity(fullName) {
10899
- return this.entityDefinitionRegistry
10900
- .getAll()
10901
- .find((entity) => `${entity.module}.${entity.name}` === fullName);
11935
+ return this.entityDefinitionRegistry.getAll().find((entity) => `${entity.module}.${entity.name}` === fullName);
10902
11936
  }
10903
11937
  resolveRelatedEntityProperty(fieldName) {
10904
11938
  const relatedRef = this.findRelatedEntityForField(fieldName);
@@ -10946,8 +11980,7 @@ class AXPEntityMasterListViewModel {
10946
11980
  if (parentColumn?.options?.dataPath) {
10947
11981
  return parentColumn.options.dataPath;
10948
11982
  }
10949
- const relatedDataPath = this.resolveRelatedEntityColumnDataPath(relatedEntityKey, fieldName) ??
10950
- this.deriveDataPathFromLookupProperty(relatedProperty);
11983
+ const relatedDataPath = this.resolveRelatedEntityColumnDataPath(relatedEntityKey, fieldName) ?? this.deriveDataPathFromLookupProperty(relatedProperty);
10951
11984
  if (!relatedDataPath) {
10952
11985
  return undefined;
10953
11986
  }
@@ -10957,9 +11990,7 @@ class AXPEntityMasterListViewModel {
10957
11990
  if (!expose) {
10958
11991
  continue;
10959
11992
  }
10960
- const match = expose.find((entry) => entry.target === relatedDataPath ||
10961
- entry.target.endsWith(`.${relatedDataPath}`) ||
10962
- (relatedLeaf != null && entry.source === relatedLeaf));
11993
+ const match = expose.find((entry) => entry.target === relatedDataPath || entry.target.endsWith(`.${relatedDataPath}`) || (relatedLeaf != null && entry.source === relatedLeaf));
10963
11994
  if (match) {
10964
11995
  return match.target;
10965
11996
  }
@@ -11198,6 +12229,7 @@ const AXPEntityListViewModelResolver = async (route, state, service = inject(AXP
11198
12229
  const entityName = route.paramMap.get('entity');
11199
12230
  try {
11200
12231
  const vm = await service.create(moduleName, entityName);
12232
+ vm.setListInstanceId(axpGetEntityListInstanceIdFromParamMap(route.queryParamMap));
11201
12233
  const viewFromUrl = route.queryParamMap.get('view');
11202
12234
  // TODO: Consolidate list init setView calls (resolver, toolbar, list-view queryParamSub / ngAfterViewInit).
11203
12235
  await vm.setView(viewFromUrl);
@@ -12767,7 +13799,7 @@ class AXMAttachmentsPageComponentProvider {
12767
13799
  return [
12768
13800
  {
12769
13801
  key: ATTACHMENTS_PAGE_COMPONENT_KEY,
12770
- loader: () => import('./acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs').then((m) => m.AXMAttachmentsPageComponent),
13802
+ loader: () => import('./acorex-platform-framework-client-layout-entity-attachments-page.component-Cx-n7ZuA.mjs').then((m) => m.AXMAttachmentsPageComponent),
12771
13803
  },
12772
13804
  ];
12773
13805
  }
@@ -13304,7 +14336,7 @@ class AXMGalleryPageComponentProvider {
13304
14336
  return [
13305
14337
  {
13306
14338
  key: GALLERY_PAGE_COMPONENT_KEY,
13307
- loader: () => import('./acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs').then((m) => m.AXMGalleryPageComponent),
14339
+ loader: () => import('./acorex-platform-framework-client-layout-entity-gallery-page.component-uTG2nFly.mjs').then((m) => m.AXMGalleryPageComponent),
13308
14340
  },
13309
14341
  ];
13310
14342
  }
@@ -17392,7 +18424,15 @@ function mapPropertyToWidgetColumn(property) {
17392
18424
  * Merges with the entity's registered column definition so related-list overrides inherit showAs/dataPath.
17393
18425
  */
17394
18426
  function mapEntityColumnToWidgetColumn(entity, column) {
17395
- const registeredColumn = entity.columns?.find((c) => c.name === column.name);
18427
+ if (isEntityColumnBand(column)) {
18428
+ return {
18429
+ name: column.name,
18430
+ title: column.title,
18431
+ visible: column.options?.visible !== false,
18432
+ children: (column.children ?? []).map((child) => mapEntityColumnToWidgetColumn(entity, child)),
18433
+ };
18434
+ }
18435
+ const registeredColumn = findEntityTableColumnInTree(entity.columns, column.name);
17396
18436
  const columnDef = registeredColumn
17397
18437
  ? {
17398
18438
  ...registeredColumn,
@@ -17460,6 +18500,12 @@ function mapEntityColumnToWidgetColumn(entity, column) {
17460
18500
  */
17461
18501
  function applyDataListColumnWidths(columns, columnWidthService) {
17462
18502
  return columns.map((column) => {
18503
+ if (isDataListColumnBand(column)) {
18504
+ return {
18505
+ ...column,
18506
+ children: applyDataListColumnWidths(column.children ?? [], columnWidthService),
18507
+ };
18508
+ }
17463
18509
  const existingWidth = column.width ?? column.widget?.options?.width;
17464
18510
  if (existingWidth) {
17465
18511
  return existingWidth === column.width ? column : { ...column, width: String(existingWidth) };
@@ -17490,6 +18536,30 @@ function applyIncludeExclude(items, include = [], exclude = []) {
17490
18536
  }
17491
18537
  return result;
17492
18538
  }
18539
+ /**
18540
+ * Applies include/exclude filters to leaf columns in a band tree; removes empty bands.
18541
+ */
18542
+ function applyIncludeExcludeToDataListColumnTree(items, include = [], exclude = []) {
18543
+ const filterNode = (column) => {
18544
+ if (isDataListColumnBand(column)) {
18545
+ const children = (column.children ?? [])
18546
+ .map(filterNode)
18547
+ .filter((c) => c != null);
18548
+ if (children.length === 0) {
18549
+ return null;
18550
+ }
18551
+ return { ...column, children };
18552
+ }
18553
+ if (include.length > 0 && !include.includes(column.name)) {
18554
+ return null;
18555
+ }
18556
+ if (exclude.length > 0 && exclude.includes(column.name)) {
18557
+ return null;
18558
+ }
18559
+ return column;
18560
+ };
18561
+ return items.map(filterNode).filter((c) => c != null);
18562
+ }
17493
18563
  /**
17494
18564
  * Returns only visible (non-hidden) properties of an entity.
17495
18565
  */
@@ -17536,7 +18606,7 @@ class AXPEntityListTableService {
17536
18606
  }
17537
18607
  const listOptions = {
17538
18608
  // 📊 Data Source
17539
- dataSource: this.createDataSource(entity),
18609
+ dataSource: this.createDataSource(entity, options),
17540
18610
  // 📋 Columns from Properties
17541
18611
  columns: this.createColumnsFromProperties(entity, options),
17542
18612
  // 🎯 Row Commands from Actions
@@ -17567,7 +18637,7 @@ class AXPEntityListTableService {
17567
18637
  /**
17568
18638
  * Create DataSource for Entity
17569
18639
  */
17570
- createDataSource(entity) {
18640
+ createDataSource(entity, options) {
17571
18641
  return new AXDataSource({
17572
18642
  byKey: (key) => {
17573
18643
  const func = entity.queries?.byKey?.execute;
@@ -17581,7 +18651,7 @@ class AXPEntityListTableService {
17581
18651
  resetPagingForTreeChildrenLoad(e, entity.parentKey);
17582
18652
  return func(e);
17583
18653
  },
17584
- pageSize: entity.interfaces?.master?.list?.views?.[0]?.pageSize || 10,
18654
+ pageSize: options?.pageSize || entity.interfaces?.master?.list?.views?.[0]?.pageSize || 10,
17585
18655
  key: 'id',
17586
18656
  });
17587
18657
  }
@@ -17602,7 +18672,7 @@ class AXPEntityListTableService {
17602
18672
  else {
17603
18673
  baseColumns = getVisibleProperties(entity).map((prop) => mapPropertyToWidgetColumn(prop));
17604
18674
  }
17605
- return applyDataListColumnWidths(applyIncludeExclude(baseColumns, includeColumns, excludeColumns), this.columnWidthService);
18675
+ return applyDataListColumnWidths(applyIncludeExcludeToDataListColumnTree(baseColumns, includeColumns, excludeColumns), this.columnWidthService);
17606
18676
  }
17607
18677
  /**
17608
18678
  * Map EntityTableColumn to ListWidgetColumn
@@ -17746,6 +18816,7 @@ class AXPEntityListToolbarService {
17746
18816
  filterDefinitions: this.mergeFilterDefinitions(baseFilters, options?.customFilterDefinitions),
17747
18817
  columnDefinitions: this.createColumnDefinitions(entity, options),
17748
18818
  sortDefinitions: await this.createSortDefinitions(entity),
18819
+ sortPresets: collectEntityListSortPresets(entity),
17749
18820
  canFilter: true,
17750
18821
  canColumns: true,
17751
18822
  canSort: true,
@@ -17837,7 +18908,6 @@ class AXPEntityListToolbarService {
17837
18908
  const includeColumns = options?.includeColumns || [];
17838
18909
  const relatedTableColumns = options?.relatedTableColumns;
17839
18910
  const visibleProperties = getVisibleProperties(entity);
17840
- const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
17841
18911
  let baseColumns;
17842
18912
  if (relatedTableColumns?.length) {
17843
18913
  baseColumns = relatedTableColumns.map((column) => {
@@ -17850,13 +18920,11 @@ class AXPEntityListToolbarService {
17850
18920
  });
17851
18921
  }
17852
18922
  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);
18923
+ baseColumns = flattenEntityTableColumns(columns).map((column) => {
18924
+ const property = entity.properties.find(({ name }) => name === column.name) ?? visibleProperties.find(({ name }) => name === column.name);
17857
18925
  return {
17858
18926
  name: column.name,
17859
- title: property?.title,
18927
+ title: column.title || property?.title || column.name,
17860
18928
  visible: column?.options?.visible ?? true,
17861
18929
  };
17862
18930
  });
@@ -17962,6 +19030,20 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
17962
19030
  ...(ngDevMode ? [{ debugName: "showEntityActions" }] : /* istanbul ignore next */ []));
17963
19031
  this.showToolbar = computed(() => this.options()['showToolbar'] ?? true, /* @ts-ignore */
17964
19032
  ...(ngDevMode ? [{ debugName: "showToolbar" }] : /* istanbul ignore next */ []));
19033
+ this.canViews = computed(() => this.options()['canViews'] !== false, /* @ts-ignore */
19034
+ ...(ngDevMode ? [{ debugName: "canViews" }] : /* istanbul ignore next */ []));
19035
+ this.resolvedQueryViews = computed(() => {
19036
+ if (!this.canViews()) {
19037
+ return [];
19038
+ }
19039
+ const override = this.options()['views'];
19040
+ return resolveRelatedEntityListViews(override !== undefined ? { items: override } : undefined, this.entity()?.interfaces?.master?.list?.views);
19041
+ }, /* @ts-ignore */
19042
+ ...(ngDevMode ? [{ debugName: "resolvedQueryViews" }] : /* istanbul ignore next */ []));
19043
+ this.showViews = computed(() => this.resolvedQueryViews().length > 0, /* @ts-ignore */
19044
+ ...(ngDevMode ? [{ debugName: "showViews" }] : /* istanbul ignore next */ []));
19045
+ this.showListToolbar = computed(() => this.showToolbar() || this.showViews(), /* @ts-ignore */
19046
+ ...(ngDevMode ? [{ debugName: "showListToolbar" }] : /* istanbul ignore next */ []));
17965
19047
  //actions
17966
19048
  this.allActions = computed(() => {
17967
19049
  const originalList = this.entity()?.interfaces?.master?.list?.actions ?? [];
@@ -18701,6 +19783,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18701
19783
  handleQueryChanges(queries, dataSource, listInstance, isMounted) {
18702
19784
  const changeTracker = this.analyzeChanges(queries);
18703
19785
  this.previousQueries = queries;
19786
+ this.applyViewPageSize(dataSource, queries, changeTracker);
18704
19787
  this.applyDataSourceChanges(dataSource, queries, changeTracker, isMounted);
18705
19788
  this.handleListRefresh(listInstance, changeTracker, isMounted);
18706
19789
  this.handleColumnChanges(changeTracker);
@@ -18714,9 +19797,26 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18714
19797
  isFilterChanged: changes.includes('filters'),
18715
19798
  isSortChanged: changes.includes('sorts'),
18716
19799
  isColumnsChanged: changes.includes('columns'),
19800
+ isViewChanged: changes.includes('view'),
18717
19801
  hasAnyChange: changes.length > 0,
18718
19802
  };
18719
19803
  }
19804
+ applyViewPageSize(dataSource, queries, changeTracker) {
19805
+ if (!changeTracker.isViewChanged) {
19806
+ return;
19807
+ }
19808
+ const view = this.resolvedQueryViews().find((item) => item.name === queries.view);
19809
+ if (view?.pageSize && dataSource.config) {
19810
+ dataSource.config.pageSize = view.pageSize;
19811
+ }
19812
+ }
19813
+ resolveQueryViewsForEntity(entity) {
19814
+ if (this.options()['canViews'] === false) {
19815
+ return [];
19816
+ }
19817
+ const override = this.options()['views'];
19818
+ return resolveRelatedEntityListViews(override !== undefined ? { items: override } : undefined, entity.interfaces?.master?.list?.views);
19819
+ }
18720
19820
  /**
18721
19821
  * Maps toolbar sort queries ({ name, dir }) to AXDataSource sort options ({ field, dir }).
18722
19822
  */
@@ -18770,19 +19870,12 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18770
19870
  // Current columns from list options
18771
19871
  const currentColumns = (listInstance.options()['columns'] ||
18772
19872
  []);
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
19873
+ const visibilityByName = new Map(toolbarState.columns.map((q) => [
19874
+ q.name,
19875
+ q.visible !== false && q.visible !== 'false',
19876
+ ]));
19877
+ const leafOrder = toolbarState.columns.map((q) => q.name);
19878
+ const updatedColumns = applyLeafVisibilityToDataListColumnTree(currentColumns, visibilityByName, leafOrder);
18786
19879
  listInstance.setOptions({
18787
19880
  columns: applyDataListColumnWidths(updatedColumns, this.columnWidthService),
18788
19881
  });
@@ -18818,21 +19911,34 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18818
19911
  this.settingsService.onChanged.pipe(takeUntil(this.destroyed)).subscribe(() => {
18819
19912
  void this.applyGlobalListDisplayMode();
18820
19913
  });
18821
- const options = {
19914
+ const convertOptions = {
18822
19915
  excludeColumns: this.excludeColumns(),
18823
19916
  includeColumns: this.includeColumns(),
18824
19917
  relatedTableColumns: this.relatedTableColumns(),
18825
19918
  customFilterDefinitions: this.customFilterDefinitions(),
18826
19919
  excludeProperties: this.options()['excludeProperties'],
18827
19920
  };
18828
- const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, options, this.allActions());
19921
+ const queryViews = this.resolveQueryViewsForEntity(resolvedEntity);
19922
+ const initialView = queryViews[0];
19923
+ const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, { ...convertOptions, pageSize: initialView?.pageSize }, this.allActions());
18829
19924
  if (this.isViewDestroyed) {
18830
19925
  return;
18831
19926
  }
18832
- const toolbarOptions = await this.entityListToolbarService.convertEntityToolbarOptions(resolvedEntity, options);
19927
+ const toolbarOptions = await this.entityListToolbarService.convertEntityToolbarOptions(resolvedEntity, convertOptions);
18833
19928
  if (this.isViewDestroyed) {
18834
19929
  return;
18835
19930
  }
19931
+ const showFilterToolbar = this.showToolbar();
19932
+ const toolbarWidgetOptions = {
19933
+ ...toolbarOptions,
19934
+ canFilter: showFilterToolbar,
19935
+ canColumns: showFilterToolbar,
19936
+ canSort: showFilterToolbar,
19937
+ canViews: this.canViews() && queryViews.length > 0,
19938
+ views: queryViews,
19939
+ entitySettingKey: `${resolvedEntity.module}:${resolvedEntity.name}`,
19940
+ canListDisplay: showFilterToolbar,
19941
+ };
18836
19942
  this.initListTimeoutId = setTimeout(() => {
18837
19943
  this.initListTimeoutId = null;
18838
19944
  if (this.isViewDestroyed) {
@@ -18851,18 +19957,30 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18851
19957
  mode: 'view',
18852
19958
  defaultValue: this.getValue()?.table,
18853
19959
  });
18854
- const mergedToolbarFilters = this.getMergedToolbarFilters();
19960
+ const parentFilters = this.getMergedToolbarFilters();
19961
+ const viewFilters = initialView ? queryViewConditionsToFilterQueries(initialView) : [];
19962
+ const toolbarState = {
19963
+ view: initialView?.name,
19964
+ filters: initialView ? [...parentFilters, ...viewFilters] : parentFilters,
19965
+ sorts: initialView?.sorts ?? this.getValue()?.toolbar?.sorts,
19966
+ columns: initialView
19967
+ ? applyQueryViewToColumnQueries(toolbarWidgetOptions.columnDefinitions, initialView)
19968
+ : this.getValue()?.toolbar?.columns,
19969
+ displayMode: this.listDisplayMode(),
19970
+ };
19971
+ this.setValue({
19972
+ ...this.getValue(),
19973
+ toolbar: {
19974
+ ...(this.getValue()?.toolbar ?? {}),
19975
+ ...toolbarState,
19976
+ },
19977
+ });
18855
19978
  this.toolbarNode.set({
18856
19979
  type: AXPWidgetsCatalog.listToolbar,
18857
19980
  path: `toolbar`,
18858
- options: toolbarOptions,
19981
+ options: toolbarWidgetOptions,
18859
19982
  mode: 'view',
18860
- defaultValue: {
18861
- filters: mergedToolbarFilters,
18862
- sorts: this.getValue()?.toolbar?.sorts,
18863
- columns: this.getValue()?.toolbar?.columns,
18864
- displayMode: this.listDisplayMode(),
18865
- },
19983
+ defaultValue: toolbarState,
18866
19984
  });
18867
19985
  queueMicrotask(() => {
18868
19986
  if (!this.isViewDestroyed) {
@@ -18993,7 +20111,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
18993
20111
  </div>
18994
20112
  }
18995
20113
  <div class="flex min-h-0 h-full flex-col gap-2" [style.max-height]="maxHeight()">
18996
- @if (toolbarNode() != null && showToolbar()) {
20114
+ @if (toolbarNode() != null && showListToolbar()) {
18997
20115
  <ng-container
18998
20116
  #toolbar
18999
20117
  axp-widget-renderer
@@ -19069,7 +20187,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
19069
20187
  }
19070
20188
  </div>
19071
20189
  </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 }); }
20190
+ `, 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
20191
  }
19074
20192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityListWidgetViewComponent, decorators: [{
19075
20193
  type: Component,
@@ -19154,7 +20272,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
19154
20272
  </div>
19155
20273
  }
19156
20274
  <div class="flex min-h-0 h-full flex-col gap-2" [style.max-height]="maxHeight()">
19157
- @if (toolbarNode() != null && showToolbar()) {
20275
+ @if (toolbarNode() != null && showListToolbar()) {
19158
20276
  <ng-container
19159
20277
  #toolbar
19160
20278
  axp-widget-renderer
@@ -19938,6 +21056,132 @@ function resolvePolymorphicRefTypePath(columnName, entityOption, expose) {
19938
21056
  }
19939
21057
  //#endregion
19940
21058
 
21059
+ //#region ----- Imports -----
21060
+ //#endregion
21061
+ //#region ----- Helpers -----
21062
+ function resolveLookupEntityCacheKey(entity) {
21063
+ if (typeof entity === 'string') {
21064
+ return entity.trim();
21065
+ }
21066
+ return `${entity.module}.${entity.name}`;
21067
+ }
21068
+ function normalizeLookupCacheId(id) {
21069
+ if (id == null || id === '') {
21070
+ return null;
21071
+ }
21072
+ return String(id);
21073
+ }
21074
+ //#endregion
21075
+ //#region ----- Service -----
21076
+ /**
21077
+ * Session-scoped GetById cache for lookup widgets.
21078
+ * Shared across edit/view/column instances so remounts and list cells reuse rows.
21079
+ */
21080
+ class AXPLookupByKeyCacheService {
21081
+ //#endregion
21082
+ //#region ----- Lifecycle -----
21083
+ constructor() {
21084
+ //#region ----- Services & Dependencies -----
21085
+ this.sessionService = inject(AXPSessionService);
21086
+ //#endregion
21087
+ //#region ----- State -----
21088
+ this.rows = new Map();
21089
+ this.inflight = new Map();
21090
+ this.generation = 0;
21091
+ this.bindSessionReset(this.sessionService.tenant$.pipe(map((tenant) => tenant?.id ?? null), distinctUntilChanged()));
21092
+ this.bindSessionReset(this.sessionService.user$.pipe(map((user) => user?.id ?? null), distinctUntilChanged()));
21093
+ }
21094
+ //#endregion
21095
+ //#region ----- Public API -----
21096
+ remember(entityKey, id, row) {
21097
+ const cacheId = normalizeLookupCacheId(id);
21098
+ const key = entityKey.trim();
21099
+ if (!key || cacheId == null || row == null) {
21100
+ return;
21101
+ }
21102
+ let entityRows = this.rows.get(key);
21103
+ if (!entityRows) {
21104
+ entityRows = new Map();
21105
+ this.rows.set(key, entityRows);
21106
+ }
21107
+ entityRows.set(cacheId, row);
21108
+ }
21109
+ peek(entityKey, id) {
21110
+ const cacheId = normalizeLookupCacheId(id);
21111
+ if (cacheId == null) {
21112
+ return undefined;
21113
+ }
21114
+ return this.rows.get(entityKey.trim())?.get(cacheId);
21115
+ }
21116
+ async getOrFetch(entityKey, id, fetch) {
21117
+ const key = entityKey.trim();
21118
+ const cacheId = normalizeLookupCacheId(id);
21119
+ if (!key || cacheId == null) {
21120
+ return null;
21121
+ }
21122
+ const cached = this.rows.get(key)?.get(cacheId);
21123
+ if (cached !== undefined) {
21124
+ return cached;
21125
+ }
21126
+ const flightKey = `${key}:${cacheId}`;
21127
+ const pending = this.inflight.get(flightKey);
21128
+ if (pending) {
21129
+ return pending;
21130
+ }
21131
+ const generation = this.generation;
21132
+ const request = Promise.resolve()
21133
+ .then(() => fetch(id))
21134
+ .then((row) => {
21135
+ if (row != null && generation === this.generation) {
21136
+ this.remember(key, cacheId, row);
21137
+ return row;
21138
+ }
21139
+ return row ?? null;
21140
+ })
21141
+ .finally(() => {
21142
+ this.inflight.delete(flightKey);
21143
+ });
21144
+ this.inflight.set(flightKey, request);
21145
+ return request;
21146
+ }
21147
+ wrap(entityKey, fetch) {
21148
+ return (id) => this.getOrFetch(entityKey, id, fetch);
21149
+ }
21150
+ clear(entityKey) {
21151
+ this.generation += 1;
21152
+ if (entityKey?.trim()) {
21153
+ this.rows.delete(entityKey.trim());
21154
+ const prefix = `${entityKey.trim()}:`;
21155
+ for (const flightKey of [...this.inflight.keys()]) {
21156
+ if (flightKey.startsWith(prefix)) {
21157
+ this.inflight.delete(flightKey);
21158
+ }
21159
+ }
21160
+ return;
21161
+ }
21162
+ this.rows.clear();
21163
+ this.inflight.clear();
21164
+ }
21165
+ //#endregion
21166
+ //#region ----- Session -----
21167
+ bindSessionReset(source) {
21168
+ let initialized = false;
21169
+ source.subscribe(() => {
21170
+ if (!initialized) {
21171
+ initialized = true;
21172
+ return;
21173
+ }
21174
+ this.clear();
21175
+ });
21176
+ }
21177
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21178
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, providedIn: 'root' }); }
21179
+ }
21180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupByKeyCacheService, decorators: [{
21181
+ type: Injectable,
21182
+ args: [{ providedIn: 'root' }]
21183
+ }], ctorParameters: () => [] });
21184
+
19941
21185
  class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19942
21186
  constructor() {
19943
21187
  super(...arguments);
@@ -19946,6 +21190,7 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19946
21190
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
19947
21191
  this.contextEvalFactory = inject(AXPContextEvalFactory);
19948
21192
  this.entityResolver = inject(AXPEntityDefinitionRegistryService);
21193
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
19949
21194
  this.entity = computed(() => this.options()['entity'], /* @ts-ignore */
19950
21195
  ...(ngDevMode ? [{ debugName: "entity" }] : /* istanbul ignore next */ []));
19951
21196
  this.multiple = computed(() => this.options()['multiple'], /* @ts-ignore */
@@ -19997,8 +21242,14 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
19997
21242
  const byKey = def?.queries?.byKey?.execute;
19998
21243
  if (byKey) {
19999
21244
  this.loading.set(true);
20000
- const fetchedItem = await byKey(item);
21245
+ const fetchedItem = await this.lookupByKeyCache.getOrFetch(this.entity(), item, (id) => byKey(id));
20001
21246
  this.loading.set(false);
21247
+ if (fetchedItem == null || typeof fetchedItem !== 'object') {
21248
+ return {
21249
+ id: item,
21250
+ text: item,
21251
+ };
21252
+ }
20002
21253
  return {
20003
21254
  id: fetchedItem[this.valueField()],
20004
21255
  text: await this.getDisplayRaw(fetchedItem),
@@ -20516,6 +21767,7 @@ class AXPEntityDataSelectorService {
20516
21767
  this.translationService = inject(AXTranslationService);
20517
21768
  this.rowActionsService = inject(AXPEntityDataSelectorRowActionsService);
20518
21769
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
21770
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
20519
21771
  }
20520
21772
  //#endregion
20521
21773
  //#region ---- Public Methods ----
@@ -20662,10 +21914,14 @@ class AXPEntityDataSelectorService {
20662
21914
  const { entity } = options;
20663
21915
  const filters = options.filter?.value;
20664
21916
  const parentFilters = options.filter?.parent;
21917
+ const entityKey = resolveLookupEntityCacheKey(entity);
20665
21918
  return new AXDataSource({
20666
21919
  byKey: (key) => {
20667
21920
  const func = entity.queries?.byKey?.execute;
20668
- return func(key);
21921
+ if (!func) {
21922
+ return Promise.resolve(null);
21923
+ }
21924
+ return this.lookupByKeyCache.getOrFetch(entityKey, key, (id) => func(id));
20669
21925
  },
20670
21926
  load: (e) => {
20671
21927
  const func = entity.queries?.list?.execute;
@@ -21264,11 +22520,12 @@ function isLookupValueFieldPrimaryKey(entity, valueField) {
21264
22520
  const normalized = valueField.trim() || 'id';
21265
22521
  return normalized === resolveLookupEntityPrimaryKeyField(entity);
21266
22522
  }
21267
- function rememberFetchedLookupRow(map, key, row) {
22523
+ function rememberFetchedLookupRow(map, key, row, onRow) {
21268
22524
  map.set(key, row);
21269
22525
  if (key != null) {
21270
22526
  map.set(String(key), row);
21271
22527
  }
22528
+ onRow?.(key, row);
21272
22529
  }
21273
22530
  function readFetchedLookupRow(map, key) {
21274
22531
  if (key == null) {
@@ -21298,7 +22555,7 @@ async function fetchLookupRowsByKeys(config) {
21298
22555
  uniqueKeys.forEach((key, index) => {
21299
22556
  const row = rows[index];
21300
22557
  if (row != null) {
21301
- rememberFetchedLookupRow(fetchedByKey, key, row);
22558
+ rememberFetchedLookupRow(fetchedByKey, key, row, config.onRow);
21302
22559
  }
21303
22560
  });
21304
22561
  return fetchedByKey;
@@ -21309,7 +22566,7 @@ async function fetchLookupRowsByKeys(config) {
21309
22566
  uniqueKeys.forEach((key, index) => {
21310
22567
  const row = rows[index];
21311
22568
  if (row != null) {
21312
- rememberFetchedLookupRow(fetchedByKey, key, row);
22569
+ rememberFetchedLookupRow(fetchedByKey, key, row, config.onRow);
21313
22570
  }
21314
22571
  });
21315
22572
  }
@@ -21332,7 +22589,7 @@ async function fetchLookupRowsByKeys(config) {
21332
22589
  if (storedKey == null) {
21333
22590
  continue;
21334
22591
  }
21335
- rememberFetchedLookupRow(fetchedByKey, storedKey, row);
22592
+ rememberFetchedLookupRow(fetchedByKey, storedKey, row, config.onRow);
21336
22593
  }
21337
22594
  return fetchedByKey;
21338
22595
  }
@@ -21348,7 +22605,7 @@ function createLookupEntityDataSource(config) {
21348
22605
  const valueField = config.valueField?.trim() || 'id';
21349
22606
  return new AXDataSource({
21350
22607
  byKey: async (key) => {
21351
- const byKeyExecute = entity.queries?.byKey?.execute;
22608
+ const byKeyExecute = config.byKey ?? entity.queries?.byKey?.execute;
21352
22609
  const listExecute = entity.queries?.list?.execute;
21353
22610
  const fetchedByKey = await fetchLookupRowsByKeys({
21354
22611
  entity,
@@ -21362,6 +22619,7 @@ function createLookupEntityDataSource(config) {
21362
22619
  }
21363
22620
  : undefined,
21364
22621
  queryList: listExecute,
22622
+ onRow: config.onRow,
21365
22623
  });
21366
22624
  const row = readFetchedLookupRow(fetchedByKey, key);
21367
22625
  if (row == null) {
@@ -21568,7 +22826,7 @@ function areLookupSelectionItemsHydrated(rawValue, items, options) {
21568
22826
  }
21569
22827
  //#endregion
21570
22828
 
21571
- //#region ----- Imports -----
22829
+ //#region ---- Imports -----
21572
22830
  //#endregion
21573
22831
  //#region ----- Constants -----
21574
22832
  const DEFAULT_LOOKUP_COLUMN_NAMES = ['title', 'displayName', 'name', 'code', 'description'];
@@ -21599,7 +22857,9 @@ function resolveEntityListRowTitleTemplate(entity) {
21599
22857
  return entity.interfaces?.master?.single?.title ?? entity.formats?.searchResult?.title ?? entity.formats?.individual;
21600
22858
  }
21601
22859
  function resolveDefaultColumnNames(entity) {
21602
- const fromEntity = (entity.columns ?? []).map((column) => column.name?.trim()).filter((name) => !!name);
22860
+ const fromEntity = flattenEntityTableColumns(entity.columns)
22861
+ .map((column) => column.name?.trim())
22862
+ .filter((name) => !!name);
21603
22863
  if (fromEntity.length) {
21604
22864
  return fromEntity;
21605
22865
  }
@@ -21610,7 +22870,7 @@ function resolveColumnsToProcess(entity, columnSpecs) {
21610
22870
  const { columns: entityColumns = [], properties } = entity;
21611
22871
  const visibleProperties = properties.filter(({ schema }) => schema?.visible !== false);
21612
22872
  const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
21613
- const filteredColumns = entityColumns.filter(({ name, showAs }) => visiblePropNames.has(name) || showAs);
22873
+ const filteredColumns = flattenEntityTableColumns(entityColumns).filter(({ name, showAs }) => visiblePropNames.has(name) || showAs);
21614
22874
  if (columnSpecs.length === 0) {
21615
22875
  return filteredColumns
21616
22876
  .filter((column) => DEFAULT_LOOKUP_COLUMN_NAMES.includes(column.name))
@@ -22142,7 +23402,7 @@ class AXPLookupWidgetTablePanelComponent {
22142
23402
  return Boolean(item[this.disabledField()]);
22143
23403
  }
22144
23404
  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 }); }
23405
+ 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
23406
  }
22147
23407
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetTablePanelComponent, decorators: [{
22148
23408
  type: Component,
@@ -22468,7 +23728,7 @@ class AXPLookupWidgetTableHostComponent extends NXValueComponent {
22468
23728
  { provide: AXComponent, useExisting: AXPLookupWidgetTableHostComponent },
22469
23729
  { provide: AXClearableComponent, useExisting: AXPLookupWidgetTableHostComponent },
22470
23730
  { 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 }); }
23731
+ ], 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
23732
  }
22473
23733
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetTableHostComponent, decorators: [{
22474
23734
  type: Component,
@@ -22503,6 +23763,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22503
23763
  this.contextEvalFactory = inject(AXPContextEvalFactory);
22504
23764
  this.localeService = inject(AXLocaleService);
22505
23765
  this.destroyRef = inject(DestroyRef);
23766
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
22506
23767
  //#endregion
22507
23768
  //#region ----- View Children -----
22508
23769
  this.lookup = viewChild(AXLookupComponent, /* @ts-ignore */
@@ -22530,6 +23791,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22530
23791
  ...(ngDevMode ? [{ debugName: "shouldFocus" }] : /* istanbul ignore next */ []));
22531
23792
  /** Skips one {@link findByValue} pass after inline create when selection is already hydrated. */
22532
23793
  this.skipFindByValueOnce = false;
23794
+ this.lastEditorLocaleKey = this.resolveEditorLocaleKey();
22533
23795
  //#endregion
22534
23796
  //#region ----- Computed Properties -----
22535
23797
  this.expose = computed(() => this.options()['expose'], /* @ts-ignore */
@@ -22654,6 +23916,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22654
23916
  if (!entity) {
22655
23917
  return null;
22656
23918
  }
23919
+ const entityKey = resolveLookupEntityCacheKey(entity);
22657
23920
  return createLookupEntityDataSource({
22658
23921
  entity,
22659
23922
  displayField,
@@ -22662,6 +23925,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22662
23925
  getCustomFilter: () => this.customFilter(),
22663
23926
  transformFilter: (filter) => this.filterOperatorMiddleware.transformFilter(filter),
22664
23927
  decorateItem: (item) => this.decorateLookupItem(item),
23928
+ byKey: this.lookupByKeyCache.wrap(entityKey, (id) => {
23929
+ const execute = entity.queries?.byKey?.execute;
23930
+ return execute ? execute(id) : Promise.resolve(null);
23931
+ }),
23932
+ onRow: (key, row) => this.lookupByKeyCache.remember(entityKey, key, row),
22665
23933
  });
22666
23934
  }, /* @ts-ignore */
22667
23935
  ...(ngDevMode ? [{ debugName: "entityDataSource" }] : /* istanbul ignore next */ []));
@@ -22731,7 +23999,14 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22731
23999
  //#region ----- Lifecycle -----
22732
24000
  this.editorLocaleChanged = merge$1(this.mlsResolver.langChanges$, this.localeService.profileChanged$)
22733
24001
  .pipe(takeUntilDestroyed(this.destroyRef))
22734
- .subscribe(() => this.rerenderEditor());
24002
+ .subscribe(() => {
24003
+ const next = this.resolveEditorLocaleKey();
24004
+ if (next === this.lastEditorLocaleKey) {
24005
+ return;
24006
+ }
24007
+ this.lastEditorLocaleKey = next;
24008
+ this.rerenderEditor();
24009
+ });
22735
24010
  this.#efEntity = effect(async () => {
22736
24011
  const key = this.entity();
22737
24012
  if (!key?.includes('.')) {
@@ -22936,14 +24211,16 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22936
24211
  const existing = currentItems.find((item) => get(item, valueField) === id);
22937
24212
  return existing == null || !isLookupItemHydrated(existing, hydration);
22938
24213
  });
24214
+ const entityKey = this.entity();
22939
24215
  const fetchedById = entityDef
22940
24216
  ? await fetchLookupRowsByKeys({
22941
24217
  entity: entityDef,
22942
24218
  valueField,
22943
24219
  keys: idsToFetch,
22944
24220
  getQueryFields: () => this.lookupQueryFields(),
22945
- byKey: (id) => entityDataAccessor.byKey(id),
24221
+ byKey: this.lookupByKeyCache.wrap(entityKey, (id) => entityDataAccessor.byKey(id)),
22946
24222
  queryList: (request) => entityDataAccessor.query(request),
24223
+ onRow: (key, row) => this.lookupByKeyCache.remember(entityKey, key, row),
22947
24224
  })
22948
24225
  : new Map();
22949
24226
  const mergedItems = (await Promise.all(ids.map(async (id) => {
@@ -22977,6 +24254,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
22977
24254
  filterMode: this.filterMode(),
22978
24255
  };
22979
24256
  }
24257
+ resolveEditorLocaleKey() {
24258
+ const lang = this.mlsResolver.getActiveLang() ?? '';
24259
+ const profile = this.localeService.activeProfile()?.localeInfo?.code ?? '';
24260
+ return `${lang}:${profile}`;
24261
+ }
22980
24262
  rerenderEditor() {
22981
24263
  this.localeEpoch.update((epoch) => epoch + 1);
22982
24264
  this.editorKey.set(false);
@@ -23010,6 +24292,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
23010
24292
  return;
23011
24293
  }
23012
24294
  const decorated = await this.decorateLookupItem(createdItem);
24295
+ this.lookupByKeyCache.remember(this.entity(), newId, createdItem);
23013
24296
  this.skipFindByValueOnce = true;
23014
24297
  this.lookup()?.seedItems([decorated]);
23015
24298
  if (this.multiple()) {
@@ -23239,6 +24522,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23239
24522
  this.queryExecutor = inject(AXPQueryExecutor);
23240
24523
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
23241
24524
  this.contextEvalFactory = inject(AXPContextEvalFactory);
24525
+ this.lookupByKeyCache = inject(AXPLookupByKeyCacheService);
23242
24526
  //#endregion
23243
24527
  //#region ---- View Children ----
23244
24528
  this.moreButton = viewChild('moreButton', /* @ts-ignore */
@@ -23752,7 +25036,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23752
25036
  this.resolveError.set(null);
23753
25037
  try {
23754
25038
  const accessor = this.entityService.withEntity(entityKey).data();
23755
- const results = await Promise.all(ids.map((id) => accessor.byKey(id)));
25039
+ const results = await Promise.all(ids.map((id) => this.lookupByKeyCache.getOrFetch(entityKey, id, (key) => accessor.byKey(key))));
23756
25040
  this.resolvedPopoverItems.set(results.filter((item) => item != null));
23757
25041
  this.resolveStatus.set('ready');
23758
25042
  }
@@ -23858,7 +25142,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23858
25142
  const requestId = ++this.hydrateRequestId;
23859
25143
  try {
23860
25144
  const accessor = this.entityService.withEntity(entityKey).data();
23861
- const items = await Promise.all(ids.map((id) => accessor.byKey(id)));
25145
+ const items = await Promise.all(ids.map((id) => this.lookupByKeyCache.getOrFetch(entityKey, id, (key) => accessor.byKey(key))));
23862
25146
  if (requestId !== this.hydrateRequestId) {
23863
25147
  return;
23864
25148
  }
@@ -23996,7 +25280,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
23996
25280
  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
25281
  }
23998
25282
  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 }); }
25283
+ 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
25284
  }
24001
25285
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLookupWidgetColumnComponent, decorators: [{
24002
25286
  type: Component,
@@ -24741,7 +26025,7 @@ class AXPMultiSourceSelectorComponent extends AXBasePageComponent {
24741
26025
  ></ax-button>
24742
26026
  </ax-suffix>
24743
26027
  </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 }); }
26028
+ `, 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
26029
  }
24746
26030
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPMultiSourceSelectorComponent, decorators: [{
24747
26031
  type: Component,
@@ -27883,6 +29167,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
27883
29167
  relatedTableColumns,
27884
29168
  customFilterDefinitions: relatedEntity.customFilterDefinitions,
27885
29169
  excludeProperties: relatedEntity.excludeProperties,
29170
+ ...relatedEntityListViewWidgetOptions(relatedEntity),
27886
29171
  },
27887
29172
  },
27888
29173
  ],
@@ -28002,6 +29287,7 @@ class AXPTabListConverter extends AXPBaseRelatedEntityConverter {
28002
29287
  relatedTableColumns,
28003
29288
  customFilterDefinitions: relatedEntity.customFilterDefinitions,
28004
29289
  excludeProperties: relatedEntity.excludeProperties,
29290
+ ...relatedEntityListViewWidgetOptions(relatedEntity),
28005
29291
  },
28006
29292
  },
28007
29293
  ],
@@ -29307,9 +30593,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
29307
30593
  * Use high numbers (990+) for columns that should appear at the end.
29308
30594
  */
29309
30595
  const DEFAULT_COLUMN_ORDER = {
29310
- // Identifier columns first
30596
+ // Identifier columns first (after profile band on Employee)
30597
+ profile: 0,
29311
30598
  code: 1,
29312
- employeeCode: 1,
30599
+ employeeCode: 2,
29313
30600
  // Common display columns
29314
30601
  title: 3,
29315
30602
  name: 4,
@@ -29338,6 +30625,7 @@ const DEFAULT_COLUMN_ORDER = {
29338
30625
  attachments: 800,
29339
30626
  //
29340
30627
  statusId: 995,
30628
+ status: 995,
29341
30629
  isArchived: 999,
29342
30630
  isDisabled: 999,
29343
30631
  };
@@ -29752,6 +31040,69 @@ const defaultCardLayoutMiddlewareProvider = {
29752
31040
  };
29753
31041
  //#endregion
29754
31042
 
31043
+ //#region ----- Default sort presets middleware -----
31044
+ /**
31045
+ * When an entity has a master list, fills missing Quick Presets from date/title fields.
31046
+ * Entity-authored `sortPresets` with the same `name` win.
31047
+ */
31048
+ const defaultSortPresetsMiddleware = (context) => {
31049
+ if (!context.interfaces.master.list.get()) {
31050
+ return;
31051
+ }
31052
+ const inferred = inferEntityListSortPresets(context.entity);
31053
+ if (!inferred.length) {
31054
+ return;
31055
+ }
31056
+ context.interfaces.master.list.update((list) => {
31057
+ const existing = list?.sortPresets ?? [];
31058
+ const existingNames = new Set(existing.map((preset) => preset.name));
31059
+ const extras = inferred.filter((preset) => !existingNames.has(preset.name));
31060
+ if (!extras.length) {
31061
+ return list ?? { views: [] };
31062
+ }
31063
+ return {
31064
+ ...list,
31065
+ views: list?.views ?? [],
31066
+ sortPresets: [...existing, ...extras],
31067
+ };
31068
+ });
31069
+ };
31070
+ //#endregion
31071
+ //#region ----- Provider registration -----
31072
+ const defaultSortPresetsMiddlewareProvider = {
31073
+ entityName: '*',
31074
+ modifier: defaultSortPresetsMiddleware,
31075
+ order: 500,
31076
+ };
31077
+ //#endregion
31078
+
31079
+ //#region ----- Query sort locale -----
31080
+ /**
31081
+ * Copies the active UI locale onto `params.locale` so server sort can resolve
31082
+ * multi-language fields for that language. Keeps an explicit locale already set.
31083
+ */
31084
+ function stampQueryLocale(input, locale) {
31085
+ if (!isPlainObject(input)) {
31086
+ return input;
31087
+ }
31088
+ const record = input;
31089
+ const currentParams = isPlainObject(record['params'])
31090
+ ? { ...record['params'] }
31091
+ : {};
31092
+ const existing = currentParams['locale'];
31093
+ if (typeof existing === 'string' && existing.trim()) {
31094
+ return input;
31095
+ }
31096
+ return {
31097
+ ...record,
31098
+ params: {
31099
+ ...currentParams,
31100
+ locale: locale.trim() || 'en-US',
31101
+ },
31102
+ };
31103
+ }
31104
+ //#endregion
31105
+
29755
31106
  //#region ----- Imports -----
29756
31107
  //#endregion
29757
31108
  //#region ----- Helpers -----
@@ -29876,8 +31227,16 @@ function createEntityQueryBridge(op) {
29876
31227
  return next(context);
29877
31228
  }
29878
31229
  const skipContext = inject(AXPEntityMiddlewareSkipContext);
31230
+ const translation = inject(AXTranslationService);
31231
+ const locale = translation.getActiveLang()?.trim() || 'en-US';
29879
31232
  if (skipContext.isSkipped) {
29880
- return next(context);
31233
+ if (op !== 'query') {
31234
+ return next(context);
31235
+ }
31236
+ return next({
31237
+ ...context,
31238
+ input: stampQueryLocale(context.input, locale),
31239
+ });
29881
31240
  }
29882
31241
  const injector = inject(EnvironmentInjector);
29883
31242
  const accessor = inject(AXPEntityRuntimeAccessorService);
@@ -29895,7 +31254,10 @@ function createEntityQueryBridge(op) {
29895
31254
  const ctx = createEntityMiddlewareContext(op, entityName, accessor, {
29896
31255
  request: input,
29897
31256
  });
29898
- await runEntityMiddlewarePipeline(allMiddlewares, ctx, async () => next({ key, input: (ctx.request ?? input) }), injector);
31257
+ await runEntityMiddlewarePipeline(allMiddlewares, ctx, async () => next({
31258
+ key,
31259
+ input: stampQueryLocale(ctx.request ?? input, locale),
31260
+ }), injector);
29899
31261
  return ctx.result;
29900
31262
  };
29901
31263
  }
@@ -30044,6 +31406,7 @@ const AXPCrudModifier = {
30044
31406
  const parentKey = ctx.parentKey.get();
30045
31407
  const request = parentKey != null ? applyHierarchicalRootListFilter(e, parentKey) : e;
30046
31408
  const result = await queryService.fetch(ENTITY_QUERY_DEFAULT, { entity: entityKey, ...request });
31409
+ console.log('event', e);
30047
31410
  if (result && !result.success) {
30048
31411
  throw AXPRequestError.fromCommandResult(result);
30049
31412
  }
@@ -30433,6 +31796,11 @@ class AXPEntityModule {
30433
31796
  useValue: defaultMultiLanguageMiddlewareProvider,
30434
31797
  multi: true,
30435
31798
  },
31799
+ {
31800
+ provide: AXP_ENTITY_MODIFIER,
31801
+ useValue: defaultSortPresetsMiddlewareProvider,
31802
+ multi: true,
31803
+ },
30436
31804
  provideCommandSetups([
30437
31805
  {
30438
31806
  key: 'Entity:OpenDetails',
@@ -30460,7 +31828,7 @@ class AXPEntityModule {
30460
31828
  },
30461
31829
  {
30462
31830
  key: 'Entity:Bulk',
30463
- command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs').then((c) => c.AXPBulkEntityCommand),
31831
+ command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-BONV249y.mjs').then((c) => c.AXPBulkEntityCommand),
30464
31832
  },
30465
31833
  {
30466
31834
  key: 'Entity:OpenList',
@@ -30589,6 +31957,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
30589
31957
  useValue: defaultMultiLanguageMiddlewareProvider,
30590
31958
  multi: true,
30591
31959
  },
31960
+ {
31961
+ provide: AXP_ENTITY_MODIFIER,
31962
+ useValue: defaultSortPresetsMiddlewareProvider,
31963
+ multi: true,
31964
+ },
30592
31965
  provideCommandSetups([
30593
31966
  {
30594
31967
  key: 'Entity:OpenDetails',
@@ -30616,7 +31989,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
30616
31989
  },
30617
31990
  {
30618
31991
  key: 'Entity:Bulk',
30619
- command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs').then((c) => c.AXPBulkEntityCommand),
31992
+ command: () => import('./acorex-platform-framework-client-layout-entity-bulk-entity.command-BONV249y.mjs').then((c) => c.AXPBulkEntityCommand),
30620
31993
  },
30621
31994
  {
30622
31995
  key: 'Entity:OpenList',
@@ -30941,5 +32314,5 @@ function detectEntityChanges(oldObj, newObj) {
30941
32314
  * Generated bundle index. Do not edit.
30942
32315
  */
30943
32316
 
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
32317
+ 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 };
32318
+ //# sourceMappingURL=acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Dc_NpBx6.mjs.map