@acorex-platform/module-auth-client 0.0.18 → 0.0.21

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 (123) hide show
  1. package/fesm2022/{acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs → acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs} +940 -608
  2. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-BVbu-f8h.mjs +75 -0
  4. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-BVbu-f8h.mjs.map +1 -0
  5. package/fesm2022/{acorex-platform-module-auth-client-blank.layout-BRGgntib.mjs → acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs} +6 -6
  6. package/fesm2022/acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs.map +1 -0
  7. package/fesm2022/{acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs → acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs} +51 -41
  8. package/fesm2022/acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs +257 -0
  10. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs +46 -10
  12. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs.map +1 -1
  13. package/fesm2022/{acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs → acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs} +5 -5
  14. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs.map +1 -0
  15. package/fesm2022/{acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs → acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs} +5 -5
  16. package/fesm2022/acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs +80 -0
  18. package/fesm2022/acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs.map +1 -0
  19. package/fesm2022/{acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs → acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs} +6 -6
  20. package/fesm2022/acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs.map +1 -0
  21. package/fesm2022/{acorex-platform-module-auth-client-login.module-C4S0RjM7.mjs → acorex-platform-module-auth-client-login.module-DJVL3bAF.mjs} +8 -21
  22. package/fesm2022/acorex-platform-module-auth-client-login.module-DJVL3bAF.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs +39 -0
  24. package/fesm2022/acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs.map +1 -0
  25. package/fesm2022/{acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs → acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs} +11 -15
  26. package/fesm2022/acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs +200 -0
  28. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-module-auth-client-password.component-CIr6IBG6.mjs → acorex-platform-module-auth-client-password.component-CNKRWfuG.mjs} +86 -45
  30. package/fesm2022/acorex-platform-module-auth-client-password.component-CNKRWfuG.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-module-auth-client-password.component-CW0t9fEn.mjs +87 -0
  32. package/fesm2022/acorex-platform-module-auth-client-password.component-CW0t9fEn.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-module-auth-client-platform-settings-unavailable.component-BEVkQ3jh.mjs +47 -0
  34. package/fesm2022/acorex-platform-module-auth-client-platform-settings-unavailable.component-BEVkQ3jh.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-module-auth-client-profile-activity-chart.component-DTY1eEI_.mjs → acorex-platform-module-auth-client-profile-activity-chart.component-CtSrYARX.mjs} +38 -46
  36. package/fesm2022/acorex-platform-module-auth-client-profile-activity-chart.component-CtSrYARX.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs → acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs} +5 -5
  38. package/fesm2022/acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-C6u3AB4N.mjs → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-D0QS8joQ.mjs} +18 -13
  40. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-C6u3AB4N.mjs.map → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-D0QS8joQ.mjs.map} +1 -1
  41. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs → acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs} +7 -7
  42. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs.map → acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs.map} +1 -1
  43. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CdxseoJX.mjs +650 -0
  44. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CdxseoJX.mjs.map +1 -0
  45. package/fesm2022/{acorex-platform-module-auth-client-register-password.component-ia6tdvTc.mjs → acorex-platform-module-auth-client-register-password.component-D-tBrCJv.mjs} +15 -14
  46. package/fesm2022/acorex-platform-module-auth-client-register-password.component-D-tBrCJv.mjs.map +1 -0
  47. package/fesm2022/{acorex-platform-module-auth-client-register.module--DG9m8iC.mjs → acorex-platform-module-auth-client-register.module-BrXqva0B.mjs} +23 -23
  48. package/fesm2022/acorex-platform-module-auth-client-register.module-BrXqva0B.mjs.map +1 -0
  49. package/fesm2022/{acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs → acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs} +7 -7
  50. package/fesm2022/acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs.map +1 -0
  51. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CcwDb6Wb.mjs +115 -0
  52. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CcwDb6Wb.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-module-auth-client-result.component-DYJaB-FD.mjs → acorex-platform-module-auth-client-result.component-DWv1hmQR.mjs} +6 -6
  54. package/fesm2022/acorex-platform-module-auth-client-result.component-DWv1hmQR.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-module-auth-client-routes-DVN2Y2Ps.mjs → acorex-platform-module-auth-client-routes-IX2qmeqU.mjs} +3 -3
  56. package/fesm2022/{acorex-platform-module-auth-client-routes-DVN2Y2Ps.mjs.map → acorex-platform-module-auth-client-routes-IX2qmeqU.mjs.map} +1 -1
  57. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-BhsTAmVe.mjs +361 -0
  58. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-BhsTAmVe.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs +116 -0
  60. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs.map +1 -0
  61. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.component-BHVqbYFv.mjs → acorex-platform-module-auth-client-set-pin-code.component-Cq4skm_3.mjs} +29 -20
  62. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.component-Cq4skm_3.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs → acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs} +139 -11
  64. package/fesm2022/acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs.map +1 -0
  65. package/fesm2022/{acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs → acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs} +5 -6
  66. package/fesm2022/acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs.map +1 -0
  67. package/fesm2022/{acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs → acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs} +5 -5
  68. package/fesm2022/acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-CHmg7D5H.mjs +67 -0
  70. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-CHmg7D5H.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-nsB4v25Z.mjs +40 -0
  72. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-nsB4v25Z.mjs.map +1 -0
  73. package/fesm2022/{acorex-platform-module-auth-client-two-factor.module-FAqKbmBb.mjs → acorex-platform-module-auth-client-two-factor.module-_jYo6xXr.mjs} +8 -11
  74. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-_jYo6xXr.mjs.map +1 -0
  75. package/fesm2022/{acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs → acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs} +13 -11
  76. package/fesm2022/acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs.map +1 -0
  77. package/fesm2022/acorex-platform-module-auth-client.mjs +1 -1
  78. package/package.json +1 -1
  79. package/types/acorex-platform-module-auth-client-contracts.d.ts +43 -9
  80. package/types/acorex-platform-module-auth-client.d.ts +63 -56
  81. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs.map +0 -1
  82. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-IPLp1kVv.mjs +0 -67
  83. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-IPLp1kVv.mjs.map +0 -1
  84. package/fesm2022/acorex-platform-module-auth-client-blank.layout-BRGgntib.mjs.map +0 -1
  85. package/fesm2022/acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs.map +0 -1
  86. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs +0 -192
  87. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs.map +0 -1
  88. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs.map +0 -1
  89. package/fesm2022/acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs.map +0 -1
  90. package/fesm2022/acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs.map +0 -1
  91. package/fesm2022/acorex-platform-module-auth-client-login.module-C4S0RjM7.mjs.map +0 -1
  92. package/fesm2022/acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs +0 -24
  93. package/fesm2022/acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs.map +0 -1
  94. package/fesm2022/acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs +0 -196
  96. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-module-auth-client-password.component-CIr6IBG6.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-module-auth-client-password.component-DnFItGdA.mjs +0 -88
  99. package/fesm2022/acorex-platform-module-auth-client-password.component-DnFItGdA.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-module-auth-client-profile-activity-chart.component-DTY1eEI_.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CJ9AA3ZN.mjs +0 -446
  103. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CJ9AA3ZN.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-module-auth-client-register-password.component-ia6tdvTc.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-module-auth-client-register.module--DG9m8iC.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CTlrt_18.mjs +0 -115
  108. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CTlrt_18.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-module-auth-client-result.component-DYJaB-FD.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-CN1JqPBW.mjs +0 -346
  111. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-CN1JqPBW.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs +0 -33
  113. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.component-BHVqbYFv.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs.map +0 -1
  118. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-B_9s4F36.mjs +0 -59
  119. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-B_9s4F36.mjs.map +0 -1
  120. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-DAxlYlhM.mjs +0 -40
  121. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-DAxlYlhM.mjs.map +0 -1
  122. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-FAqKbmBb.mjs.map +0 -1
  123. package/fesm2022/acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs.map +0 -1
@@ -1,56 +1,56 @@
1
- import * as i1$4 from '@acorex-platform/framework-client/common';
2
- import { AXPFileStorageService, AXPSettingsService, AXPHomePageService, AXPDataProvider, AXPCommonSettings, AXP_PROTECTED_ROUTE_GUARDS, AXPCommonModule, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/common';
3
- import { AXPSessionService, AXPUserProfileIdentityService, AXPUnauthorizedError, AXPUnauthenticatedError, AXPAuthStrategyRegistryService, AXPAuthGuard, AXPSessionStatus } from '@acorex-platform/framework-client/auth';
1
+ import * as i1$5 from '@acorex-platform/framework-client/common';
2
+ import { AXPFileStorageService, AXPHomePageService, AXPPlatformSettingsLoadState, AXPSettingsService, AXPDataProvider, AXPCommonSettings, AXP_PROTECTED_ROUTE_GUARDS, AXPCommonModule, AXPPlatformSettingsOfflineBootstrapService, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/common';
3
+ import { AXPSessionService, AXPUnauthorizedError, AXPUnauthenticatedError, AXPAuthStrategyRegistryService, traceAuthGuard, AXPAuthGuard, AXPSessionStatus } from '@acorex-platform/framework-client/auth';
4
4
  import { AXPUserAvatarService, AXPUserAvatarComponent, AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';
5
- import { AXPFileStorageStatus, AXPWidgetsCatalog, coerceUnknownToTrimmedString, AXPPlatformScope, AXPKeyboardShortcutPriority, verifyPassword } from '@acorex-platform/framework-shared/core';
6
- import { RootConfig } from '@acorex-platform/module-person-core-client/contracts';
7
- import { RootConfig as RootConfig$1 } from '@acorex-platform/module-security-management-client/contracts';
5
+ import { AXPFileStorageStatus, coerceUnknownToTrimmedString, AXPPlatformScope, AXPKeyboardShortcutPriority, verifyPassword } from '@acorex-platform/framework-shared/core';
6
+ import { RootConfig } from '@acorex-platform/module-security-management-client/contracts';
8
7
  import { AXPEntityService, AXP_ENTITY_STORAGE_MIDDLEWARE } from '@acorex-platform/framework-client/layout/entity';
9
8
  import * as i0 from '@angular/core';
10
- import { inject, Injectable, isDevMode, InjectionToken, NgModule, input, output, viewChild, viewChildren, signal, computed, effect, ChangeDetectionStrategy, Component, DestroyRef, ViewEncapsulation, ViewChild, Injector, afterNextRender, provideAppInitializer } from '@angular/core';
11
- import { first, isEmpty, isNil, isString, orderBy, get, defaultTo } from 'lodash';
12
- import { AXDataSource } from '@acorex/cdk/common';
13
- import { AXMAuthDataSourceKeys, AXPAuthSettings, AXMAuthCommandKeys } from '@acorex-platform/module-auth-client/contracts';
9
+ import { inject, Injectable, isDevMode, InjectionToken, NgModule, input, output, viewChild, viewChildren, signal, computed, effect, ChangeDetectionStrategy, Component, DestroyRef, ViewEncapsulation, ViewChild, Injector, afterNextRender, ApplicationRef } from '@angular/core';
14
10
  import { AXPLayoutThemeService, AXPMenuVerticalMode } from '@acorex-platform/framework-client/themes/shared';
15
11
  import { HttpErrorResponse } from '@angular/common/http';
16
- import * as i1$5 from '@angular/router';
17
- import { Router, RouterModule, ROUTES } from '@angular/router';
12
+ import * as i1$6 from '@angular/router';
13
+ import { Router, RouterModule, ROUTES, NavigationStart } from '@angular/router';
14
+ import { AXPAuthCredentialTypeOptions, AXP_AUTH_SIGN_IN_PAGE_SLOGAN_DEFAULT, AXP_AUTH_SIGN_IN_PAGE_DESCRIPTION_DEFAULT, AXPAuthSettings, AXMAuthCommandKeys } from '@acorex-platform/module-auth-client/contracts';
18
15
  import * as i1 from '@acorex/core/validation';
19
16
  import { AXValidationModule } from '@acorex/core/validation';
20
- import * as i1$3 from '@acorex-platform/framework-client/core';
21
- import { axpApplicationLogoKey, AXPEntityLogoRegistrationService, AXPLogoComponent, axpTenantLogoKey, AXPHookService, AXPKeyboardShortcutRegistry, chordToKbdItemKeys, getPrimaryKeyboardShortcutChord, normalizeKeyboardShortcuts, AXPDeviceService, AXPComponentSlotModule, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, provideLazyProvider, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPComponentSlotDirective } from '@acorex-platform/framework-client/core';
22
- import { AXPCommandService, provideCommandSetups } from '@acorex-platform/framework-client/runtime';
17
+ import { isNil, isString, orderBy, isEmpty, get, defaultTo } from 'lodash';
18
+ import * as i1$4 from '@acorex-platform/framework-client/core';
19
+ import { axpApplicationLogoKey, AXPEntityLogoRegistrationService, AXPLogoComponent, axpTenantLogoKey, AXPHookService, AXPKeyboardShortcutRegistry, chordToKbdItemKeys, getPrimaryKeyboardShortcutChord, normalizeKeyboardShortcuts, AXPDeviceService, AXPComponentSlotModule, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, provideLazyProvider, AXPComponentSlotDirective } from '@acorex-platform/framework-client/core';
20
+ import { AXPCommandService, provideQuerySetups, provideCommandSetups } from '@acorex-platform/framework-client/runtime';
23
21
  import { AXPRootLayoutComponent } from '@acorex-platform/framework-client/themes/default';
24
- import * as i6 from '@angular/common';
25
- import { CommonModule, AsyncPipe } from '@angular/common';
26
- import { first as first$1, firstValueFrom, filter, combineLatest, switchMap, from } from 'rxjs';
22
+ import * as i3 from '@angular/common';
23
+ import { CommonModule, AsyncPipe, Location } from '@angular/common';
24
+ import { first, filter, firstValueFrom, take, combineLatest, distinctUntilChanged, switchMap, EMPTY, from, timeout } from 'rxjs';
27
25
  import * as i1$1 from '@acorex/components/button';
28
26
  import { AXButtonModule } from '@acorex/components/button';
29
27
  import * as i3$1 from '@acorex/components/decorators';
30
28
  import { AXDecoratorModule } from '@acorex/components/decorators';
31
29
  import * as i2$1 from '@acorex/components/popover';
32
30
  import { AXPopoverModule } from '@acorex/components/popover';
33
- import { RootConfig as RootConfig$2 } from '@acorex-platform/module-application-management-client/contracts';
34
- import * as i5 from '@acorex/cdk/list-navigation';
31
+ import { RootConfig as RootConfig$1 } from '@acorex-platform/module-application-management-client/contracts';
32
+ import * as i6 from '@acorex/cdk/list-navigation';
35
33
  import { AXListNavigationDirective, AXListNavigationItemDirective, AXListNavigationModule } from '@acorex/cdk/list-navigation';
36
- import * as i4 from '@acorex/components/search-box';
34
+ import * as i5 from '@acorex/components/search-box';
37
35
  import { AXSearchBoxModule } from '@acorex/components/search-box';
38
- import * as i3 from '@acorex/components/select-box';
36
+ import * as i4 from '@acorex/components/select-box';
39
37
  import { AXSelectBoxModule } from '@acorex/components/select-box';
40
- import * as i2 from '@acorex/components/skeleton';
38
+ import * as i2 from '@acorex/components/loading';
39
+ import { AXLoadingModule } from '@acorex/components/loading';
40
+ import * as i1$2 from '@acorex/components/skeleton';
41
41
  import { AXSkeletonModule } from '@acorex/components/skeleton';
42
- import * as i7 from '@acorex/core/translation';
43
- import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
42
+ import * as i5$1 from '@acorex/core/translation';
43
+ import { AXTranslationModule, AXTranslationService, resolveMultiLanguageString } from '@acorex/core/translation';
44
44
  import { AXAvatarModule } from '@acorex/components/avatar';
45
45
  import { AXImageModule } from '@acorex/components/image';
46
- import { AXLoadingModule } from '@acorex/components/loading';
47
46
  import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
48
- import * as i1$2 from '@angular/forms';
47
+ import * as i1$3 from '@angular/forms';
49
48
  import { FormsModule } from '@angular/forms';
50
49
  import { AXToastService } from '@acorex/components/toast';
51
50
  import { AXMDeviceSessionsService } from '@acorex-platform/module-security-management-client';
52
51
  import { AXOverlayService } from '@acorex/cdk/overlay';
53
52
  import { AXPlatform } from '@acorex/core/platform';
53
+ import { PRESENCE_SET_AVAILABILITY } from '@acorex-platform/framework-shared/runtime';
54
54
 
55
55
  //#region ---- Hook keys ----
56
56
  const PROFILE_PAGE_GROUPS_HOOK = 'profile-page.groups';
@@ -69,6 +69,10 @@ function resolveUserProfileSectionContent(section) {
69
69
  function isUserProfileGroupComponent(group) {
70
70
  return group.content?.mode === 'component';
71
71
  }
72
+ /** True when section hooks should run for `groupId` (all groups when the payload omits it). */
73
+ function isUserProfileSectionsGroupRequested(payload, groupId) {
74
+ return payload.groupId == null || payload.groupId === groupId;
75
+ }
72
76
  /** Visible actions on a section card. */
73
77
  function visibleUserProfileSectionActions(actions) {
74
78
  return actions.filter((action) => action.visible !== false);
@@ -84,7 +88,6 @@ function resolveDefaultUserProfileSectionAction(actions) {
84
88
  //#endregion
85
89
 
86
90
  //#region ---- Avatar storage constants ----
87
- const AXP_PROFILE_PHOTO_REF_TYPE = 'PersonCore.Person';
88
91
  const AXP_PROFILE_PHOTO_USER_REF_TYPE = 'SecurityManagement.User';
89
92
  const AXP_PROFILE_PHOTO_CATEGORY = 'profile-photo';
90
93
  const FILE_STORAGE_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
@@ -134,11 +137,11 @@ function dataUrlToBlob(dataUrl) {
134
137
  }
135
138
  //#endregion
136
139
 
137
- //#endregion
138
140
  //#region ---- User avatar sync service (client) ----
139
141
  /**
140
142
  * Client-side profile photo operations for self-service flows.
141
- * Bidirectional Person ↔ User sync runs on the server via HCM avatar middleware.
143
+ * Canonical store is SecurityManagement.User.avatar; Person.image is mirrored
144
+ * on the server by HCM avatar sync middleware.
142
145
  */
143
146
  class AXPUserAvatarSyncService {
144
147
  constructor() {
@@ -146,30 +149,14 @@ class AXPUserAvatarSyncService {
146
149
  this.entityService = inject(AXPEntityService);
147
150
  this.fileStorage = inject(AXPFileStorageService);
148
151
  this.sessionService = inject(AXPSessionService);
149
- this.identityService = inject(AXPUserProfileIdentityService);
150
152
  this.userAvatarService = inject(AXPUserAvatarService);
151
153
  }
152
154
  //#endregion
153
155
  //#region ---- Public API ----
154
- async resolveStorageTarget(userId) {
155
- const person = await this.findPersonByUserId(userId);
156
- if (person?.id) {
157
- return { kind: 'person', personId: person.id, userId };
158
- }
159
- return { kind: 'user', userId };
160
- }
161
156
  async getCurrentAvatarRef(userId) {
162
157
  const sessionUser = this.sessionService.user;
163
- if (sessionUser?.id === userId) {
164
- const sessionRef = normalizeAvatarRef(sessionUser.avatar);
165
- if (sessionRef) {
166
- return sessionRef;
167
- }
168
- }
169
- const target = await this.resolveStorageTarget(userId);
170
- if (target.kind === 'person') {
171
- const person = await this.personData().byKey(target.personId);
172
- return normalizeAvatarRef(person?.image);
158
+ if (sessionUser?.id === userId && sessionUser.avatar !== undefined) {
159
+ return normalizeAvatarRef(sessionUser.avatar);
173
160
  }
174
161
  const user = await this.userData().byKey(userId);
175
162
  return normalizeAvatarRef(user?.avatar);
@@ -187,20 +174,23 @@ class AXPUserAvatarSyncService {
187
174
  return response.blob();
188
175
  }
189
176
  if (isFileStorageId(ref)) {
190
- return this.fileStorage.download(ref);
177
+ try {
178
+ return await this.fileStorage.download(ref);
179
+ }
180
+ catch {
181
+ return null;
182
+ }
191
183
  }
192
184
  return null;
193
185
  }
194
186
  async uploadAndSetAvatar(userId, file) {
195
- const target = await this.resolveStorageTarget(userId);
196
- const previousRef = await this.getCurrentAvatarRef(userId);
197
- const refId = target.kind === 'person' ? target.personId : userId;
198
- const refType = target.kind === 'person' ? AXP_PROFILE_PHOTO_REF_TYPE : AXP_PROFILE_PHOTO_USER_REF_TYPE;
187
+ // Save as Temporary; HCM UserAvatarSyncMiddleware commits on attach and
188
+ // removes the previous avatar file server-side (no client File:Remove).
199
189
  const info = await this.fileStorage.save({
200
190
  file,
201
191
  name: file.name || 'profile-photo.png',
202
- refId,
203
- refType,
192
+ refId: userId,
193
+ refType: AXP_PROFILE_PHOTO_USER_REF_TYPE,
204
194
  category: AXP_PROFILE_PHOTO_CATEGORY,
205
195
  status: AXPFileStorageStatus.Temporary,
206
196
  });
@@ -208,32 +198,14 @@ class AXPUserAvatarSyncService {
208
198
  if (!fileId) {
209
199
  throw new Error('File storage did not return a fileId.');
210
200
  }
211
- await this.fileStorage.commit(fileId);
212
- if (target.kind === 'person') {
213
- await this.personData().update(target.personId, { image: fileId });
214
- }
215
- else {
216
- await this.userData().update(userId, { avatar: fileId });
217
- }
201
+ await this.userData().update(userId, { avatar: fileId });
218
202
  await this.notifyAvatarChanged(userId, fileId);
219
- if (previousRef && isFileStorageId(previousRef) && previousRef !== fileId) {
220
- await this.safeRemoveFile(previousRef);
221
- }
222
203
  return fileId;
223
204
  }
224
205
  async removeAvatar(userId) {
225
- const target = await this.resolveStorageTarget(userId);
226
- const previousRef = await this.getCurrentAvatarRef(userId);
227
- if (target.kind === 'person') {
228
- await this.personData().update(target.personId, { image: undefined });
229
- }
230
- else {
231
- await this.userData().update(userId, { avatar: null });
232
- }
206
+ // Previous file cleanup runs in HCM avatar middleware when avatar is cleared.
207
+ await this.userData().update(userId, { avatar: null });
233
208
  await this.notifyAvatarChanged(userId, null);
234
- if (previousRef && isFileStorageId(previousRef)) {
235
- await this.safeRemoveFile(previousRef);
236
- }
237
209
  }
238
210
  /** Keeps session, avatar cache, and shell avatars in sync after any avatar change. */
239
211
  async notifyAvatarChanged(userId, avatar) {
@@ -242,50 +214,49 @@ class AXPUserAvatarSyncService {
242
214
  //#endregion
243
215
  //#region ---- Private helpers ----
244
216
  async refreshClientDisplay(userId, avatar) {
245
- const isCurrentUser = this.sessionService.user?.id === userId;
246
- if (isCurrentUser) {
247
- await this.identityService.applySessionPatch({
248
- avatar: avatar === null ? '' : avatar,
249
- });
217
+ try {
218
+ const isCurrentUser = this.sessionService.user?.id === userId;
219
+ const session = isCurrentUser ? this.sessionService.getSessionData() : null;
220
+ if (avatar === null && session?.user?.avatar) {
221
+ this.userAvatarService.invalidateDisplayUrl(session.user.avatar);
222
+ }
223
+ if (isCurrentUser && session?.user) {
224
+ this.sessionService.setSession({
225
+ ...session,
226
+ user: {
227
+ ...session.user,
228
+ avatar,
229
+ },
230
+ });
231
+ }
232
+ const sessionUser = isCurrentUser ? this.sessionService.user : null;
233
+ const displayName = sessionUser?.title || sessionUser?.name || '';
234
+ const parts = displayName.trim().split(/\s+/).filter(Boolean);
235
+ const patch = {
236
+ id: userId,
237
+ status: 'offline',
238
+ username: sessionUser?.name || '',
239
+ firstName: parts[0] ?? '',
240
+ lastName: parts.slice(1).join(' '),
241
+ };
242
+ if (avatar) {
243
+ patch.avatarUrl = avatar;
244
+ }
245
+ this.userAvatarService.patchCachedUser(userId, patch);
246
+ }
247
+ catch (error) {
248
+ console.warn('Avatar display refresh failed after profile photo change', error);
250
249
  }
251
- this.userAvatarService.clearCache(userId);
252
- await this.userAvatarService.refreshUserInfo(userId);
253
- }
254
- personData() {
255
- return this.entityService
256
- .withEntity(RootConfig.module.name, RootConfig.entities.person.name)
257
- .data();
258
250
  }
259
251
  userData() {
260
252
  return this.entityService
261
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.users.name)
253
+ .withEntity(RootConfig.module.name, RootConfig.entities.users.name)
262
254
  .data();
263
255
  }
264
- async findPersonByUserId(userId) {
265
- const result = await this.personData().query({
266
- filter: { field: 'userId', operator: { type: 'equal' }, value: userId },
267
- take: 1,
268
- skip: 0,
269
- });
270
- return first(result.items) ?? null;
271
- }
272
- async safeRemoveFile(fileId) {
273
- try {
274
- await this.fileStorage.remove(fileId);
275
- }
276
- catch {
277
- try {
278
- await this.fileStorage.markForDeletion(fileId);
279
- }
280
- catch {
281
- /* ignore cleanup failures */
282
- }
283
- }
284
- }
285
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserAvatarSyncService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
286
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserAvatarSyncService, providedIn: 'root' }); }
256
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserAvatarSyncService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
257
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserAvatarSyncService, providedIn: 'root' }); }
287
258
  }
288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserAvatarSyncService, decorators: [{
259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserAvatarSyncService, decorators: [{
289
260
  type: Injectable,
290
261
  args: [{ providedIn: 'root' }]
291
262
  }] });
@@ -508,144 +479,6 @@ function extractUserActivityEndDate(filter) {
508
479
  }
509
480
  //#endregion
510
481
 
511
- //#region ---- User activity data source ----
512
- function resolveLoadParams(request) {
513
- const userId = extractUserActivityUserId(request?.filter);
514
- if (isEmpty(userId)) {
515
- return null;
516
- }
517
- const defaultRange = resolveDefaultUserActivityDateRange();
518
- const startDate = extractUserActivityStartDate(request?.filter) ?? defaultRange.startDate;
519
- const endDate = extractUserActivityEndDate(request?.filter) ?? defaultRange.endDate;
520
- return {
521
- userId: userId,
522
- startDate,
523
- endDate,
524
- };
525
- }
526
- /** Contribution-style user activity heatmap derived from device session sign-in dates. */
527
- class AXMUserActivityDataSourceDefinition {
528
- constructor() {
529
- //#region ---- Services & Dependencies ----
530
- this.entityService = inject(AXPEntityService);
531
- //#endregion
532
- }
533
- //#endregion
534
- //#region ---- Public API ----
535
- items() {
536
- const sampleParams = resolveDefaultUserActivityDateRange();
537
- const sampleItem = buildUserActivityDataSourceItem({ userId: 'sample-user', ...sampleParams }, []);
538
- return Promise.resolve([
539
- {
540
- name: AXMAuthDataSourceKeys.UserActivity,
541
- title: 'User Activity',
542
- columns: [
543
- {
544
- name: 'id',
545
- title: 'ID',
546
- datatype: 'string',
547
- type: AXPWidgetsCatalog.text,
548
- },
549
- {
550
- name: 'userId',
551
- title: 'User ID',
552
- datatype: 'string',
553
- type: AXPWidgetsCatalog.text,
554
- },
555
- {
556
- name: 'startDate',
557
- title: 'Start Date',
558
- datatype: 'date',
559
- type: AXPWidgetsCatalog.dateTime,
560
- },
561
- {
562
- name: 'endDate',
563
- title: 'End Date',
564
- datatype: 'date',
565
- type: AXPWidgetsCatalog.dateTime,
566
- },
567
- ],
568
- filters: [
569
- {
570
- field: 'userId',
571
- title: 'User',
572
- operator: { type: 'equal' },
573
- widget: { type: AXPWidgetsCatalog.text },
574
- filterType: { advance: true, inline: true },
575
- },
576
- {
577
- field: 'startDate',
578
- title: 'Start Date',
579
- operator: { type: 'gte' },
580
- widget: { type: AXPWidgetsCatalog.dateTime, options: { format: 'date' } },
581
- filterType: { advance: true, inline: true },
582
- },
583
- {
584
- field: 'endDate',
585
- title: 'End Date',
586
- operator: { type: 'lte' },
587
- widget: { type: AXPWidgetsCatalog.dateTime, options: { format: 'date' } },
588
- filterType: { advance: true, inline: true },
589
- },
590
- ],
591
- textField: { name: 'id', title: 'ID' },
592
- valueField: { name: 'id', title: 'ID' },
593
- samples: [sampleItem],
594
- source: () => new AXDataSource({
595
- key: 'id',
596
- pageSize: 1,
597
- load: async (request) => {
598
- const params = resolveLoadParams(request);
599
- if (!params) {
600
- return { items: [], total: 0 };
601
- }
602
- const sessions = await this.loadUserSessions(params.userId);
603
- const item = buildUserActivityDataSourceItem(params, sessions);
604
- return { items: [item], total: 1 };
605
- },
606
- }),
607
- },
608
- ]);
609
- }
610
- //#endregion
611
- //#region ---- Private Methods ----
612
- async loadUserSessions(userId) {
613
- const response = await this.entityService
614
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.deviceSessions.name)
615
- .data()
616
- .query({
617
- skip: 0,
618
- take: 1000,
619
- filter: {
620
- field: 'userId',
621
- operator: { type: 'equal' },
622
- value: userId,
623
- },
624
- });
625
- return response.items ?? [];
626
- }
627
- }
628
- //#endregion
629
-
630
- //#region ---- Auth data source provider ----
631
- /**
632
- * Registers auth module data source definitions.
633
- */
634
- class AXMAuthDataSourceProvider {
635
- constructor() {
636
- this.userActivity = new AXMUserActivityDataSourceDefinition();
637
- }
638
- async items() {
639
- return [...(await this.userActivity.items())];
640
- }
641
- }
642
- //#endregion
643
-
644
- var datasource_provider = /*#__PURE__*/Object.freeze({
645
- __proto__: null,
646
- AXMAuthDataSourceProvider: AXMAuthDataSourceProvider
647
- });
648
-
649
482
  class AXMAuthErrorHandler {
650
483
  constructor() {
651
484
  this.router = inject(Router);
@@ -680,26 +513,46 @@ class AXMAuthErrorHandler {
680
513
  }
681
514
  this.layoutService.setNavigationLoading(false);
682
515
  }
683
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
684
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthErrorHandler }); }
516
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
517
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthErrorHandler }); }
685
518
  }
686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthErrorHandler, decorators: [{
519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthErrorHandler, decorators: [{
687
520
  type: Injectable
688
521
  }] });
689
522
 
523
+ //#region ----- Login page guard -----
690
524
  /**
691
- * Guard for login page. Clears incomplete sessions so a prior OAuth attempt
692
- * does not leak into the next username/password sign-in.
525
+ * Login page guard.
526
+ * If the user already has a cookie session but has not finished tenant/app binding,
527
+ * send them to the chooser — never destroy the session.
528
+ * If the session is fully bound, send them home (do not show login again).
693
529
  */
694
- const canActivateLogin = async (route, state) => {
530
+ const canActivateLogin = async (_route, _state) => {
695
531
  const sessionService = inject(AXPSessionService);
532
+ const homePageService = inject(AXPHomePageService);
533
+ const platformSettingsLoadState = inject(AXPPlatformSettingsLoadState);
534
+ const router = inject(Router);
535
+ if (platformSettingsLoadState.hasFailure()) {
536
+ return router.createUrlTree(['/auth/unavailable']);
537
+ }
696
538
  const session = sessionService.getSessionData();
697
- if (session?.user?.id && (!session.tenant?.id || !session.application?.id)) {
698
- await sessionService.signout();
539
+ if (session?.user?.id && session.cookieSession) {
540
+ if (!session.tenant?.id) {
541
+ return router.createUrlTree(['/auth/account/tenant-chooser']);
542
+ }
543
+ if (!session.application?.id) {
544
+ return router.createUrlTree(['/auth/account/app-chooser']);
545
+ }
546
+ if (sessionService.isAuthorized && sessionService.application?.name) {
547
+ return homePageService.resolveAuthorizedHomeUrlTree();
548
+ }
549
+ return router.createUrlTree(['/auth/account/app-chooser']);
699
550
  }
700
551
  return true;
701
552
  };
553
+ //#endregion
702
554
 
555
+ //#region ----- Authentication types -----
703
556
  var AXMAuthenticationTypes;
704
557
  (function (AXMAuthenticationTypes) {
705
558
  AXMAuthenticationTypes[AXMAuthenticationTypes["UsernamePassword"] = 0] = "UsernamePassword";
@@ -709,21 +562,35 @@ var AXMAuthenticationTypes;
709
562
  AXMAuthenticationTypes[AXMAuthenticationTypes["EmailCode"] = 4] = "EmailCode";
710
563
  AXMAuthenticationTypes[AXMAuthenticationTypes["MobileCode"] = 5] = "MobileCode";
711
564
  })(AXMAuthenticationTypes || (AXMAuthenticationTypes = {}));
565
+ /** Map persisted credential-type setting values to {@link AXMAuthenticationTypes}. */
566
+ function parseAuthCredentialType(value) {
567
+ const raw = typeof value === 'string' ? value.trim() : '';
568
+ switch (raw) {
569
+ case AXPAuthCredentialTypeOptions.UsernameEmailPassword:
570
+ return AXMAuthenticationTypes.UsernameEmailPassword;
571
+ case AXPAuthCredentialTypeOptions.EmailPassword:
572
+ return AXMAuthenticationTypes.EmailPassword;
573
+ case AXPAuthCredentialTypeOptions.MobilePassword:
574
+ return AXMAuthenticationTypes.MobilePassword;
575
+ case AXPAuthCredentialTypeOptions.EmailCode:
576
+ return AXMAuthenticationTypes.EmailCode;
577
+ case AXPAuthCredentialTypeOptions.MobileCode:
578
+ return AXMAuthenticationTypes.MobileCode;
579
+ case AXPAuthCredentialTypeOptions.UsernamePassword:
580
+ default:
581
+ return AXMAuthenticationTypes.UsernamePassword;
582
+ }
583
+ }
712
584
  const AXM_AUTH_CONFIG_TOKEN = new InjectionToken('app-module-auth-config', {
713
585
  providedIn: 'root',
714
- factory: () => {
715
- return AXMDefaultAuthConfigs;
716
- },
586
+ factory: () => AXMDefaultAuthConfigs,
717
587
  });
718
- const AXMDefaultAuthConfigs = {
719
- type: AXMAuthenticationTypes.UsernamePassword,
720
- // defaultStrategyName:'oidc',
721
- // حذف authConfig از اینجا چون از environment خوانده می‌شود
722
- defaultStrategyName: 'user-pass',
723
- };
588
+ const AXMDefaultAuthConfigs = {};
724
589
  function configAuthModule(config = AXMDefaultAuthConfigs) {
725
590
  return { ...AXMDefaultAuthConfigs, ...config };
726
591
  }
592
+ //#endregion
593
+ //#region ----- Login Guard Token -----
727
594
  /**
728
595
  * Injection token for login page guard.
729
596
  * Apps can provide their own custom guard by providing this token.
@@ -735,6 +602,76 @@ const AXM_LOGIN_GUARD_TOKEN = new InjectionToken('AXM_LOGIN_GUARD_TOKEN', {
735
602
  });
736
603
  //#endregion
737
604
 
605
+ //#region ----- Constants -----
606
+ const DEFAULT_SLOGAN = AXP_AUTH_SIGN_IN_PAGE_SLOGAN_DEFAULT;
607
+ const DEFAULT_DESCRIPTION = AXP_AUTH_SIGN_IN_PAGE_DESCRIPTION_DEFAULT;
608
+ const DEFAULT_STRATEGY = 'user-pass';
609
+ const DEFAULT_SIGNUP_URL = '/auth/register';
610
+ //#endregion
611
+ //#region ----- Auth platform settings (P) -----
612
+ /**
613
+ * Reads public platform auth UI settings loaded during app startup.
614
+ * Slogan and description are multi-language strings.
615
+ */
616
+ class AXMAuthPlatformSettingsService {
617
+ constructor() {
618
+ this.settings = inject(AXPSettingsService);
619
+ }
620
+ //#region ----- Sign-in page -----
621
+ slogan() {
622
+ return this.readMls(AXPAuthSettings.SignInPageSlogan, DEFAULT_SLOGAN);
623
+ }
624
+ description() {
625
+ return this.readMls(AXPAuthSettings.SignInPageDescription, DEFAULT_DESCRIPTION);
626
+ }
627
+ //#endregion
628
+ //#region ----- Sign-up -----
629
+ signupEnabled() {
630
+ const value = this.settings.peekCached(AXPAuthSettings.SignUpEnabled);
631
+ return value === true || value === 'true';
632
+ }
633
+ signupUrl() {
634
+ const value = this.settings.peekCached(AXPAuthSettings.SignUpUrl);
635
+ if (typeof value === 'string' && value.trim()) {
636
+ return value.trim();
637
+ }
638
+ return DEFAULT_SIGNUP_URL;
639
+ }
640
+ //#endregion
641
+ //#region ----- Sign-in -----
642
+ credentialType() {
643
+ return parseAuthCredentialType(this.settings.peekCached(AXPAuthSettings.SignInCredentialType));
644
+ }
645
+ defaultStrategyName() {
646
+ const value = this.settings.peekCached(AXPAuthSettings.SignInDefaultStrategy);
647
+ if (typeof value === 'string' && value.trim()) {
648
+ return value.trim();
649
+ }
650
+ return DEFAULT_STRATEGY;
651
+ }
652
+ //#endregion
653
+ //#region ----- Private -----
654
+ readMls(key, fallback) {
655
+ const value = this.settings.peekCached(key);
656
+ if (value == null || value === '') {
657
+ return fallback;
658
+ }
659
+ if (typeof value === 'string') {
660
+ return value;
661
+ }
662
+ if (typeof value === 'object' && !Array.isArray(value)) {
663
+ return value;
664
+ }
665
+ return fallback;
666
+ }
667
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthPlatformSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
668
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthPlatformSettingsService, providedIn: 'root' }); }
669
+ }
670
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthPlatformSettingsService, decorators: [{
671
+ type: Injectable,
672
+ args: [{ providedIn: 'root' }]
673
+ }] });
674
+
738
675
  //#region ---- Types ----
739
676
  const AXPAuthPasswordComplexityLevels = {
740
677
  Low: 'Low',
@@ -852,10 +789,10 @@ class AXPAuthPasswordComplexityService {
852
789
  const effectiveValue = await this.settingsService.get(AXPAuthSettings.PasswordComplexity);
853
790
  return normalizePasswordComplexityLevel(effectiveValue);
854
791
  }
855
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordComplexityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
856
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordComplexityService, providedIn: 'root' }); }
792
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordComplexityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
793
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordComplexityService, providedIn: 'root' }); }
857
794
  }
858
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordComplexityService, decorators: [{
795
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordComplexityService, decorators: [{
859
796
  type: Injectable,
860
797
  args: [{ providedIn: 'root' }]
861
798
  }] });
@@ -899,22 +836,22 @@ class PasswordComplexityValidationRule {
899
836
  }
900
837
  return this.passwordComplexityService.getLevel();
901
838
  }
902
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PasswordComplexityValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
903
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PasswordComplexityValidationRule }); }
839
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PasswordComplexityValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
840
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PasswordComplexityValidationRule }); }
904
841
  }
905
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PasswordComplexityValidationRule, decorators: [{
842
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PasswordComplexityValidationRule, decorators: [{
906
843
  type: Injectable
907
844
  }] });
908
845
 
909
846
  //#region ---- Auth Validation Rules Module ----
910
847
  class AXMAuthValidationRulesModule {
911
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthValidationRulesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
912
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthValidationRulesModule, imports: [i1.AXValidationModule] }); }
913
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthValidationRulesModule, imports: [AXValidationModule.forChild({
848
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthValidationRulesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
849
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthValidationRulesModule, imports: [i1.AXValidationModule] }); }
850
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthValidationRulesModule, imports: [AXValidationModule.forChild({
914
851
  rules: [PasswordComplexityValidationRule],
915
852
  })] }); }
916
853
  }
917
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthValidationRulesModule, decorators: [{
854
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthValidationRulesModule, decorators: [{
918
855
  type: NgModule,
919
856
  args: [{
920
857
  imports: [
@@ -934,34 +871,38 @@ const routes = [
934
871
  pathMatch: 'full',
935
872
  redirectTo: 'login',
936
873
  },
874
+ {
875
+ path: 'unavailable',
876
+ loadComponent: () => import('./acorex-platform-module-auth-client-platform-settings-unavailable.component-BEVkQ3jh.mjs').then((c) => c.AXMPlatformSettingsUnavailableComponent),
877
+ },
937
878
  {
938
879
  path: '',
939
- loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
940
- loadChildren: () => import('./acorex-platform-module-auth-client-login.module-C4S0RjM7.mjs').then((c) => c.AXPSignInModule),
880
+ loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
881
+ loadChildren: () => import('./acorex-platform-module-auth-client-login.module-DJVL3bAF.mjs').then((c) => c.AXPSignInModule),
941
882
  },
942
883
  {
943
884
  path: '',
944
- loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
945
- loadChildren: () => import('./acorex-platform-module-auth-client-two-factor.module-FAqKbmBb.mjs').then((c) => c.AXPTwoFactorModule),
885
+ loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
886
+ loadChildren: () => import('./acorex-platform-module-auth-client-two-factor.module-_jYo6xXr.mjs').then((c) => c.AXPTwoFactorModule),
946
887
  },
947
888
  {
948
889
  path: '',
949
- loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
950
- loadChildren: () => import('./acorex-platform-module-auth-client-routes-DVN2Y2Ps.mjs').then((c) => c),
890
+ loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
891
+ loadChildren: () => import('./acorex-platform-module-auth-client-routes-IX2qmeqU.mjs').then((c) => c),
951
892
  },
952
893
  {
953
- path: 'axp-oauth-callback',
954
- loadComponent: () => import('./acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs').then((c) => c.AXPOAuthCallbackComponent),
894
+ path: 'oauth-callback',
895
+ loadComponent: () => import('./acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs').then((c) => c.AXPOAuthCallbackComponent),
955
896
  },
956
897
  {
957
898
  path: 'account',
958
- loadComponent: () => import('./acorex-platform-module-auth-client-blank.layout-BRGgntib.mjs').then((c) => c.AXPAuthBlankLayoutComponent),
899
+ loadComponent: () => import('./acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs').then((c) => c.AXPAuthBlankLayoutComponent),
959
900
  loadChildren: () => Promise.resolve().then(function () { return account_module; }).then((c) => c.AXPAccountModule),
960
901
  },
961
902
  {
962
903
  path: '',
963
- loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
964
- loadChildren: () => import('./acorex-platform-module-auth-client-register.module--DG9m8iC.mjs').then((c) => c.AXPRegisterModule),
904
+ loadComponent: () => import('./acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs').then((c) => c.AXPAuthMasterLayoutComponent),
905
+ loadChildren: () => import('./acorex-platform-module-auth-client-register.module-BrXqva0B.mjs').then((c) => c.AXPRegisterModule),
965
906
  },
966
907
  ],
967
908
  },
@@ -985,26 +926,43 @@ class AXPAppChooserListComponent {
985
926
  this.homePageService = inject(AXPHomePageService);
986
927
  this.authStrategyRegistry = inject(AXPAuthStrategyRegistryService);
987
928
  this.logoRegistration = inject(AXPEntityLogoRegistrationService);
988
- this.applicationService = this.entityService.withEntity(RootConfig$2.module.name, RootConfig$2.entities.application.name).data();
929
+ this.applicationService = this.entityService.withEntity(RootConfig$1.module.name, RootConfig$1.entities.application.name).data();
989
930
  this.strategyName = this.sessionService.getSessionData()?.strategy;
990
931
  this.strategy = this.authStrategyRegistry.get(this.strategyName);
991
932
  //#endregion
992
933
  //#region ---- Inputs & Outputs ----
993
- this.simple = input(false, ...(ngDevMode ? [{ debugName: "simple" }] : /* istanbul ignore next */ []));
934
+ this.simple = input(false, /* @ts-ignore */
935
+ ...(ngDevMode ? [{ debugName: "simple" }] : /* istanbul ignore next */ []));
994
936
  this.applicationChosen = output();
937
+ this.loadingChange = output();
995
938
  //#endregion
996
939
  //#region ---- View References ----
997
- this.listNav = viewChild(AXListNavigationDirective, ...(ngDevMode ? [{ debugName: "listNav" }] : /* istanbul ignore next */ []));
998
- this.listItems = viewChildren(AXListNavigationItemDirective, ...(ngDevMode ? [{ debugName: "listItems" }] : /* istanbul ignore next */ []));
940
+ this.listNav = viewChild(AXListNavigationDirective, /* @ts-ignore */
941
+ ...(ngDevMode ? [{ debugName: "listNav" }] : /* istanbul ignore next */ []));
942
+ this.listItems = viewChildren(AXListNavigationItemDirective, /* @ts-ignore */
943
+ ...(ngDevMode ? [{ debugName: "listItems" }] : /* istanbul ignore next */ []));
999
944
  //#endregion
1000
945
  //#region ---- State ----
1001
- this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1002
- this.allApplications = signal([], ...(ngDevMode ? [{ debugName: "allApplications" }] : /* istanbul ignore next */ []));
1003
- this.useSelectBox = computed(() => this.allApplications().length > 3, ...(ngDevMode ? [{ debugName: "useSelectBox" }] : /* istanbul ignore next */ []));
1004
- this.selectedApplication = signal(null, ...(ngDevMode ? [{ debugName: "selectedApplication" }] : /* istanbul ignore next */ []));
1005
- this.isSelectBoxOpen = signal(false, ...(ngDevMode ? [{ debugName: "isSelectBoxOpen" }] : /* istanbul ignore next */ []));
1006
- this.canApply = computed(() => !!this.selectedApplication(), ...(ngDevMode ? [{ debugName: "canApply" }] : /* istanbul ignore next */ []));
946
+ this.isLoading = signal(true, /* @ts-ignore */
947
+ ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
948
+ this.isChoosing = signal(false, /* @ts-ignore */
949
+ ...(ngDevMode ? [{ debugName: "isChoosing" }] : /* istanbul ignore next */ []));
950
+ this.choosingId = signal(null, /* @ts-ignore */
951
+ ...(ngDevMode ? [{ debugName: "choosingId" }] : /* istanbul ignore next */ []));
952
+ this.allApplications = signal([], /* @ts-ignore */
953
+ ...(ngDevMode ? [{ debugName: "allApplications" }] : /* istanbul ignore next */ []));
954
+ this.useSelectBox = computed(() => this.allApplications().length > 3, /* @ts-ignore */
955
+ ...(ngDevMode ? [{ debugName: "useSelectBox" }] : /* istanbul ignore next */ []));
956
+ this.selectedApplication = signal(null, /* @ts-ignore */
957
+ ...(ngDevMode ? [{ debugName: "selectedApplication" }] : /* istanbul ignore next */ []));
958
+ this.isSelectBoxOpen = signal(false, /* @ts-ignore */
959
+ ...(ngDevMode ? [{ debugName: "isSelectBoxOpen" }] : /* istanbul ignore next */ []));
960
+ this.canApply = computed(() => !!this.selectedApplication(), /* @ts-ignore */
961
+ ...(ngDevMode ? [{ debugName: "canApply" }] : /* istanbul ignore next */ []));
1007
962
  this.skeletonItems = [1, 2, 3];
963
+ effect(() => {
964
+ this.loadingChange.emit(this.isLoading());
965
+ });
1008
966
  effect(() => {
1009
967
  if (!this.isLoading() && !this.useSelectBox() && this.allApplications().length > 0) {
1010
968
  queueMicrotask(() => this.focusFirstListItem());
@@ -1014,7 +972,7 @@ class AXPAppChooserListComponent {
1014
972
  //#endregion
1015
973
  //#region ---- Lifecycle Methods ----
1016
974
  ngOnInit() {
1017
- this.sessionService.applications$.pipe(first$1()).subscribe((applications) => {
975
+ this.sessionService.applications$.pipe(first()).subscribe((applications) => {
1018
976
  this.logoRegistration.registerApplications(applications);
1019
977
  this.allApplications.set(applications);
1020
978
  if (applications.length > 0) {
@@ -1054,43 +1012,64 @@ class AXPAppChooserListComponent {
1054
1012
  }
1055
1013
  }
1056
1014
  applySelection() {
1015
+ if (this.isChoosing()) {
1016
+ return;
1017
+ }
1057
1018
  const application = this.selectedApplication();
1058
1019
  if (application) {
1059
1020
  void this.chooseApplication(application);
1060
1021
  }
1061
1022
  }
1062
1023
  async chooseApplication(item) {
1063
- const tenantId = this.sessionService.tenant?.id || '';
1064
- if (!tenantId) {
1065
- throw new Error('Tenant ID is missing. Cannot choose application.');
1066
- }
1067
- const fullApplication = await this.applicationService.byKey(item.id);
1068
- if (!fullApplication) {
1069
- throw new Error(`Application not found: ${item.id}`);
1070
- }
1071
- let selectedEdition = item.edition;
1072
- if (!selectedEdition && fullApplication.editions && fullApplication.editions.length > 0) {
1073
- selectedEdition = {
1074
- id: fullApplication.editions[0].id,
1075
- title: fullApplication.editions[0].title,
1076
- description: fullApplication.editions[0].description,
1077
- };
1024
+ if (this.isChoosing()) {
1025
+ return;
1078
1026
  }
1079
- const applicationWithEdition = {
1080
- ...item,
1081
- version: fullApplication.version || item.version,
1082
- edition: selectedEdition,
1083
- };
1084
- if (this.strategy && typeof this.strategy.updateToken === 'function') {
1085
- const updateContext = {
1086
- application: applicationWithEdition,
1087
- user: this.sessionService.user,
1088
- tenant: this.sessionService.tenant,
1089
- };
1090
- await this.sessionService.updateToken(updateContext);
1027
+ this.isChoosing.set(true);
1028
+ this.choosingId.set(item.id);
1029
+ try {
1030
+ const tenantId = this.sessionService.tenant?.id || '';
1031
+ if (!tenantId) {
1032
+ throw new Error('Tenant ID is missing. Cannot choose application.');
1033
+ }
1034
+ let applicationWithEdition = { ...item };
1035
+ if (this.strategy && typeof this.strategy.updateToken === 'function') {
1036
+ await this.sessionService.updateToken({
1037
+ application: applicationWithEdition,
1038
+ user: this.sessionService.user,
1039
+ tenant: this.sessionService.tenant,
1040
+ });
1041
+ }
1042
+ if (!applicationWithEdition.edition) {
1043
+ const fullApplication = await this.applicationService.byKey(item.id);
1044
+ if (!fullApplication) {
1045
+ throw new Error(`Application not found: ${item.id}`);
1046
+ }
1047
+ if (fullApplication.editions && fullApplication.editions.length > 0) {
1048
+ applicationWithEdition = {
1049
+ ...applicationWithEdition,
1050
+ version: fullApplication.version || applicationWithEdition.version,
1051
+ edition: {
1052
+ id: fullApplication.editions[0].id,
1053
+ title: fullApplication.editions[0].title,
1054
+ description: fullApplication.editions[0].description,
1055
+ },
1056
+ };
1057
+ if (this.strategy && typeof this.strategy.updateToken === 'function') {
1058
+ await this.sessionService.updateToken({
1059
+ application: applicationWithEdition,
1060
+ user: this.sessionService.user,
1061
+ tenant: this.sessionService.tenant,
1062
+ });
1063
+ }
1064
+ }
1065
+ }
1066
+ this.applicationChosen.emit();
1067
+ await this.homePageService.navigateTo();
1068
+ }
1069
+ finally {
1070
+ this.isChoosing.set(false);
1071
+ this.choosingId.set(null);
1091
1072
  }
1092
- this.applicationChosen.emit();
1093
- await this.homePageService.navigateTo();
1094
1073
  }
1095
1074
  //#endregion
1096
1075
  //#region ---- Utility Methods ----
@@ -1103,39 +1082,41 @@ class AXPAppChooserListComponent {
1103
1082
  nav.navigateTo(items[currentIndex >= 0 ? currentIndex : 0]);
1104
1083
  }
1105
1084
  }
1106
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAppChooserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1107
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPAppChooserListComponent, isStandalone: true, selector: "axp-app-chooser-list", inputs: { simple: { classPropertyName: "simple", publicName: "simple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { applicationChosen: "applicationChosen" }, viewQueries: [{ propertyName: "listNav", first: true, predicate: AXListNavigationDirective, descendants: true, isSignal: true }, { propertyName: "listItems", predicate: AXListNavigationItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-2 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"w-12 h-12 rounded-full shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-6 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div class=\"w-full flex flex-col gap-4\" (keydown.capture)=\"handleSelectBoxKeyDown($event)\">\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allApplications()\"\n textField=\"title\"\n valueField=\"id\"\n [itemHeight]=\"56\"\n [value]=\"selectedApplication()\"\n [placeholder]=\"('@auth:application-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"applicationItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleApplicationSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n ></ax-button>\n </div>\n} @else {\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col gap-1\"\n role=\"listbox\"\n >\n @for (application of allApplications(); track application.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isApplicationSelected(application)\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.bg-primary-lighter]=\"isApplicationSelected(application)\"\n [class.dark:bg-primary-darker]=\"isApplicationSelected(application)\"\n [class.text-primary-on-lighter]=\"isApplicationSelected(application)\"\n [class.dark:text-primary-on-darker]=\"isApplicationSelected(application)\"\n [class.ring-2]=\"navItem.isActive()\"\n [class.ring-primary]=\"navItem.isActive()\"\n (click)=\"chooseApplication(application)\"\n (keydown)=\"handleListItemKeyDown($event, application)\"\n >\n <div class=\"flex flex-1 gap-2 items-center min-w-0\">\n <div\n class=\"shrink-0 flex justify-center items-center rounded-full bg-neutral-100\"\n [class.w-10]=\"simple()\"\n [class.h-10]=\"simple()\"\n [class.w-12]=\"!simple()\"\n [class.h-12]=\"!simple()\"\n >\n <axp-logo\n [logoKey]=\"applicationLogoKey(application)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"application.title\"\n class=\"flex! items-center justify-center text-sm! bg-neutral-200 dark:bg-neutral-800 rounded-full\"\n [class.w-8]=\"simple()\"\n [class.h-8]=\"simple()\"\n [class.w-10]=\"!simple()\"\n [class.h-10]=\"!simple()\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{ application.title }}</span>\n @if (application.edition?.title) {\n <span class=\"text-muted text-xs shrink-0\">{{ application.edition?.title }}</span>\n }\n </div>\n </div>\n }\n </div>\n}\n\n<ng-template #applicationItemTemplate let-item>\n <div class=\"flex gap-2 items-center p-2\">\n <div\n class=\"w-10 h-10 flex justify-center items-center rounded-full bg-neutral-100 shrink-0\"\n >\n <axp-logo\n [logoKey]=\"applicationLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"32\"\n [attr.alt]=\"item.data.title\"\n class=\"flex! items-center justify-center text-sm! w-8 h-8 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ item.data.title }}</span>\n @if (item.data.edition?.title) {\n <span class=\"text-muted text-xs\">{{ item.data.edition.title }}</span>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i3.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i5.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i5.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1085
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAppChooserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1086
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPAppChooserListComponent, isStandalone: true, selector: "axp-app-chooser-list", inputs: { simple: { classPropertyName: "simple", publicName: "simple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { applicationChosen: "applicationChosen", loadingChange: "loadingChange" }, viewQueries: [{ propertyName: "listNav", first: true, predicate: AXListNavigationDirective, descendants: true, isSignal: true }, { propertyName: "listItems", predicate: AXListNavigationItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-3 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"size-10 rounded-lg shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-5 rounded-md\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"w-16 h-4 rounded-md shrink-0\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div\n class=\"w-full flex flex-col gap-4\"\n [class.pointer-events-none]=\"isChoosing()\"\n [class.opacity-60]=\"isChoosing()\"\n (keydown.capture)=\"handleSelectBoxKeyDown($event)\"\n >\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allApplications()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedApplication()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:application-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"applicationItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleApplicationSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply() || isChoosing()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n >\n @if (isChoosing()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n} @else {\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n role=\"listbox\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (application of allApplications(); track application.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isApplicationSelected(application)\"\n [attr.aria-busy]=\"choosingId() === application.id\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary\"\n [class.bg-primary-lighter]=\"isApplicationSelected(application)\"\n [class.dark:bg-primary-darker]=\"isApplicationSelected(application)\"\n [class.text-primary-on-lighter]=\"isApplicationSelected(application)\"\n [class.dark:text-primary-on-darker]=\"isApplicationSelected(application)\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== application.id\"\n [class.cursor-wait]=\"isChoosing()\"\n (click)=\"chooseApplication(application)\"\n (keydown)=\"handleListItemKeyDown($event, application)\"\n >\n <div class=\"flex flex-1 gap-3 items-center min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"applicationLogoKey(application)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(application.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 min-w-0 text-start md:text-base text-sm break-words md:truncate\">{{\n application.title | translate | async\n }}</span>\n @if (application.edition?.title) {\n <span class=\"text-muted text-xs shrink-0\">{{\n application.edition?.title | translate | async\n }}</span>\n }\n </div>\n @if (choosingId() === application.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n}\n\n<ng-template #applicationItemTemplate let-item>\n <div class=\"flex gap-3 items-center p-2\">\n <div class=\"size-12 overflow-hidden rounded-lg shrink-0\">\n <axp-logo\n [logoKey]=\"applicationLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(item.data.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ item.data.title | translate | async }}</span>\n @if (item.data.edition?.title) {\n <span class=\"text-muted text-xs\">{{ item.data.edition.title | translate | async }}</span>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i4.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i6.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i6.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1108
1087
  }
1109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAppChooserListComponent, decorators: [{
1088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAppChooserListComponent, decorators: [{
1110
1089
  type: Component,
1111
1090
  args: [{ selector: 'axp-app-chooser-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1112
1091
  CommonModule,
1113
1092
  AXButtonModule,
1114
1093
  AXDecoratorModule,
1094
+ AXLoadingModule,
1115
1095
  AXSkeletonModule,
1116
1096
  AXSelectBoxModule,
1117
1097
  AXSearchBoxModule,
1118
1098
  AXListNavigationModule,
1119
1099
  AXTranslationModule,
1120
1100
  AXPLogoComponent,
1121
- ], template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-2 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"w-12 h-12 rounded-full shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-6 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div class=\"w-full flex flex-col gap-4\" (keydown.capture)=\"handleSelectBoxKeyDown($event)\">\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allApplications()\"\n textField=\"title\"\n valueField=\"id\"\n [itemHeight]=\"56\"\n [value]=\"selectedApplication()\"\n [placeholder]=\"('@auth:application-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"applicationItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleApplicationSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n ></ax-button>\n </div>\n} @else {\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col gap-1\"\n role=\"listbox\"\n >\n @for (application of allApplications(); track application.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isApplicationSelected(application)\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.bg-primary-lighter]=\"isApplicationSelected(application)\"\n [class.dark:bg-primary-darker]=\"isApplicationSelected(application)\"\n [class.text-primary-on-lighter]=\"isApplicationSelected(application)\"\n [class.dark:text-primary-on-darker]=\"isApplicationSelected(application)\"\n [class.ring-2]=\"navItem.isActive()\"\n [class.ring-primary]=\"navItem.isActive()\"\n (click)=\"chooseApplication(application)\"\n (keydown)=\"handleListItemKeyDown($event, application)\"\n >\n <div class=\"flex flex-1 gap-2 items-center min-w-0\">\n <div\n class=\"shrink-0 flex justify-center items-center rounded-full bg-neutral-100\"\n [class.w-10]=\"simple()\"\n [class.h-10]=\"simple()\"\n [class.w-12]=\"!simple()\"\n [class.h-12]=\"!simple()\"\n >\n <axp-logo\n [logoKey]=\"applicationLogoKey(application)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"application.title\"\n class=\"flex! items-center justify-center text-sm! bg-neutral-200 dark:bg-neutral-800 rounded-full\"\n [class.w-8]=\"simple()\"\n [class.h-8]=\"simple()\"\n [class.w-10]=\"!simple()\"\n [class.h-10]=\"!simple()\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{ application.title }}</span>\n @if (application.edition?.title) {\n <span class=\"text-muted text-xs shrink-0\">{{ application.edition?.title }}</span>\n }\n </div>\n </div>\n }\n </div>\n}\n\n<ng-template #applicationItemTemplate let-item>\n <div class=\"flex gap-2 items-center p-2\">\n <div\n class=\"w-10 h-10 flex justify-center items-center rounded-full bg-neutral-100 shrink-0\"\n >\n <axp-logo\n [logoKey]=\"applicationLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"32\"\n [attr.alt]=\"item.data.title\"\n class=\"flex! items-center justify-center text-sm! w-8 h-8 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ item.data.title }}</span>\n @if (item.data.edition?.title) {\n <span class=\"text-muted text-xs\">{{ item.data.edition.title }}</span>\n }\n </div>\n</ng-template>\n" }]
1122
- }], ctorParameters: () => [], propDecorators: { simple: [{ type: i0.Input, args: [{ isSignal: true, alias: "simple", required: false }] }], applicationChosen: [{ type: i0.Output, args: ["applicationChosen"] }], listNav: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXListNavigationDirective), { isSignal: true }] }], listItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => AXListNavigationItemDirective), { isSignal: true }] }] } });
1101
+ ], template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-3 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"size-10 rounded-lg shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-5 rounded-md\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"w-16 h-4 rounded-md shrink-0\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div\n class=\"w-full flex flex-col gap-4\"\n [class.pointer-events-none]=\"isChoosing()\"\n [class.opacity-60]=\"isChoosing()\"\n (keydown.capture)=\"handleSelectBoxKeyDown($event)\"\n >\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allApplications()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedApplication()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:application-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"applicationItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleApplicationSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply() || isChoosing()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n >\n @if (isChoosing()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n} @else {\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n role=\"listbox\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (application of allApplications(); track application.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isApplicationSelected(application)\"\n [attr.aria-busy]=\"choosingId() === application.id\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary\"\n [class.bg-primary-lighter]=\"isApplicationSelected(application)\"\n [class.dark:bg-primary-darker]=\"isApplicationSelected(application)\"\n [class.text-primary-on-lighter]=\"isApplicationSelected(application)\"\n [class.dark:text-primary-on-darker]=\"isApplicationSelected(application)\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== application.id\"\n [class.cursor-wait]=\"isChoosing()\"\n (click)=\"chooseApplication(application)\"\n (keydown)=\"handleListItemKeyDown($event, application)\"\n >\n <div class=\"flex flex-1 gap-3 items-center min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"applicationLogoKey(application)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(application.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 min-w-0 text-start md:text-base text-sm break-words md:truncate\">{{\n application.title | translate | async\n }}</span>\n @if (application.edition?.title) {\n <span class=\"text-muted text-xs shrink-0\">{{\n application.edition?.title | translate | async\n }}</span>\n }\n </div>\n @if (choosingId() === application.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n}\n\n<ng-template #applicationItemTemplate let-item>\n <div class=\"flex gap-3 items-center p-2\">\n <div class=\"size-12 overflow-hidden rounded-lg shrink-0\">\n <axp-logo\n [logoKey]=\"applicationLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(item.data.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ item.data.title | translate | async }}</span>\n @if (item.data.edition?.title) {\n <span class=\"text-muted text-xs\">{{ item.data.edition.title | translate | async }}</span>\n }\n </div>\n</ng-template>\n" }]
1102
+ }], ctorParameters: () => [], propDecorators: { simple: [{ type: i0.Input, args: [{ isSignal: true, alias: "simple", required: false }] }], applicationChosen: [{ type: i0.Output, args: ["applicationChosen"] }], loadingChange: [{ type: i0.Output, args: ["loadingChange"] }], listNav: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXListNavigationDirective), { isSignal: true }] }], listItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => AXListNavigationItemDirective), { isSignal: true }] }] } });
1123
1103
 
1124
1104
  class AXMAppChooserSlotComponent {
1125
1105
  constructor() {
1126
1106
  this.sessionService = inject(AXPSessionService);
1127
1107
  this.applications$ = this.sessionService.applications$;
1128
- this.appPopover = viewChild('appPopover', ...(ngDevMode ? [{ debugName: "appPopover" }] : /* istanbul ignore next */ []));
1108
+ this.appPopover = viewChild('appPopover', /* @ts-ignore */
1109
+ ...(ngDevMode ? [{ debugName: "appPopover" }] : /* istanbul ignore next */ []));
1129
1110
  }
1130
1111
  closePopover() {
1131
1112
  this.appPopover()?.close();
1132
1113
  }
1133
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAppChooserSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1134
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMAppChooserSlotComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "appPopover", first: true, predicate: ["appPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (((applications$ | async)?.length ?? 0) > 1) {\n <ax-button color=\"primary\" #appChooser>\n <ax-icon class=\"fa-regular fa-grid-2\"> </ax-icon>\n </ax-button>\n <ax-popover [target]=\"appChooser\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #appPopover>\n <div class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\">\n <axp-app-chooser-list [simple]=\"true\" (applicationChosen)=\"closePopover()\"></axp-app-chooser-list>\n </div>\n </ax-popover>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXPAppChooserListComponent, selector: "axp-app-chooser-list", inputs: ["simple"], outputs: ["applicationChosen"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] }); }
1114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAppChooserSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1115
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAppChooserSlotComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "appPopover", first: true, predicate: ["appPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (applications$ | async; as applications) {\n @if (applications.length > 1) {\n <ax-button color=\"primary\" #appChooser>\n <ax-icon class=\"fa-regular fa-grid-2\"> </ax-icon>\n </ax-button>\n <ax-popover [target]=\"appChooser\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #appPopover>\n <div class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\">\n <axp-app-chooser-list [simple]=\"true\" (applicationChosen)=\"closePopover()\"></axp-app-chooser-list>\n </div>\n </ax-popover>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$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: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXPAppChooserListComponent, selector: "axp-app-chooser-list", inputs: ["simple"], outputs: ["applicationChosen", "loadingChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
1135
1116
  }
1136
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAppChooserSlotComponent, decorators: [{
1117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAppChooserSlotComponent, decorators: [{
1137
1118
  type: Component,
1138
- args: [{ imports: [CommonModule, AXButtonModule, AXPopoverModule, AXDecoratorModule, AXPAppChooserListComponent], template: "@if (((applications$ | async)?.length ?? 0) > 1) {\n <ax-button color=\"primary\" #appChooser>\n <ax-icon class=\"fa-regular fa-grid-2\"> </ax-icon>\n </ax-button>\n <ax-popover [target]=\"appChooser\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #appPopover>\n <div class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\">\n <axp-app-chooser-list [simple]=\"true\" (applicationChosen)=\"closePopover()\"></axp-app-chooser-list>\n </div>\n </ax-popover>\n}\n" }]
1119
+ args: [{ changeDetection: ChangeDetectionStrategy.Eager, imports: [CommonModule, AXButtonModule, AXPopoverModule, AXDecoratorModule, AXPAppChooserListComponent], template: "@if (applications$ | async; as applications) {\n @if (applications.length > 1) {\n <ax-button color=\"primary\" #appChooser>\n <ax-icon class=\"fa-regular fa-grid-2\"> </ax-icon>\n </ax-button>\n <ax-popover [target]=\"appChooser\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #appPopover>\n <div class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\">\n <axp-app-chooser-list [simple]=\"true\" (applicationChosen)=\"closePopover()\"></axp-app-chooser-list>\n </div>\n </ax-popover>\n }\n}\n" }]
1139
1120
  }], propDecorators: { appPopover: [{ type: i0.ViewChild, args: ['appPopover', { isSignal: true }] }] } });
1140
1121
 
1141
1122
  class AXPTenantChooserListComponent {
@@ -1154,27 +1135,44 @@ class AXPTenantChooserListComponent {
1154
1135
  this.sessionService = inject(AXPSessionService);
1155
1136
  this.authStrategyRegistry = inject(AXPAuthStrategyRegistryService);
1156
1137
  this.logoRegistration = inject(AXPEntityLogoRegistrationService);
1138
+ this.translationService = inject(AXTranslationService);
1157
1139
  this.router = inject(Router);
1158
1140
  this.strategyName = this.sessionService.getSessionData()?.strategy;
1159
1141
  this.strategy = this.authStrategyRegistry.get(this.strategyName);
1160
1142
  //#endregion
1161
1143
  //#region ---- Inputs & Outputs ----
1162
- this.simple = input(false, ...(ngDevMode ? [{ debugName: "simple" }] : /* istanbul ignore next */ []));
1144
+ this.simple = input(false, /* @ts-ignore */
1145
+ ...(ngDevMode ? [{ debugName: "simple" }] : /* istanbul ignore next */ []));
1163
1146
  this.tenantChosen = output();
1147
+ this.loadingChange = output();
1164
1148
  //#endregion
1165
1149
  //#region ---- View References ----
1166
- this.listNav = viewChild(AXListNavigationDirective, ...(ngDevMode ? [{ debugName: "listNav" }] : /* istanbul ignore next */ []));
1167
- this.listItems = viewChildren(AXListNavigationItemDirective, ...(ngDevMode ? [{ debugName: "listItems" }] : /* istanbul ignore next */ []));
1150
+ this.listNav = viewChild(AXListNavigationDirective, /* @ts-ignore */
1151
+ ...(ngDevMode ? [{ debugName: "listNav" }] : /* istanbul ignore next */ []));
1152
+ this.listItems = viewChildren(AXListNavigationItemDirective, /* @ts-ignore */
1153
+ ...(ngDevMode ? [{ debugName: "listItems" }] : /* istanbul ignore next */ []));
1168
1154
  //#endregion
1169
1155
  //#region ---- State ----
1170
- this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1171
- this.allTenants = signal([], ...(ngDevMode ? [{ debugName: "allTenants" }] : /* istanbul ignore next */ []));
1172
- this.searchValue = signal('', ...(ngDevMode ? [{ debugName: "searchValue" }] : /* istanbul ignore next */ []));
1173
- this.showAll = signal(false, ...(ngDevMode ? [{ debugName: "showAll" }] : /* istanbul ignore next */ []));
1174
- this.useSelectBox = computed(() => this.allTenants().length > 3, ...(ngDevMode ? [{ debugName: "useSelectBox" }] : /* istanbul ignore next */ []));
1175
- this.selectedTenant = signal(null, ...(ngDevMode ? [{ debugName: "selectedTenant" }] : /* istanbul ignore next */ []));
1176
- this.isSelectBoxOpen = signal(false, ...(ngDevMode ? [{ debugName: "isSelectBoxOpen" }] : /* istanbul ignore next */ []));
1177
- this.canApply = computed(() => !!this.selectedTenant(), ...(ngDevMode ? [{ debugName: "canApply" }] : /* istanbul ignore next */ []));
1156
+ this.isLoading = signal(true, /* @ts-ignore */
1157
+ ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1158
+ this.isChoosing = signal(false, /* @ts-ignore */
1159
+ ...(ngDevMode ? [{ debugName: "isChoosing" }] : /* istanbul ignore next */ []));
1160
+ this.choosingId = signal(null, /* @ts-ignore */
1161
+ ...(ngDevMode ? [{ debugName: "choosingId" }] : /* istanbul ignore next */ []));
1162
+ this.allTenants = signal([], /* @ts-ignore */
1163
+ ...(ngDevMode ? [{ debugName: "allTenants" }] : /* istanbul ignore next */ []));
1164
+ this.searchValue = signal('', /* @ts-ignore */
1165
+ ...(ngDevMode ? [{ debugName: "searchValue" }] : /* istanbul ignore next */ []));
1166
+ this.showAll = signal(false, /* @ts-ignore */
1167
+ ...(ngDevMode ? [{ debugName: "showAll" }] : /* istanbul ignore next */ []));
1168
+ this.useSelectBox = computed(() => this.allTenants().length > 3, /* @ts-ignore */
1169
+ ...(ngDevMode ? [{ debugName: "useSelectBox" }] : /* istanbul ignore next */ []));
1170
+ this.selectedTenant = signal(null, /* @ts-ignore */
1171
+ ...(ngDevMode ? [{ debugName: "selectedTenant" }] : /* istanbul ignore next */ []));
1172
+ this.isSelectBoxOpen = signal(false, /* @ts-ignore */
1173
+ ...(ngDevMode ? [{ debugName: "isSelectBoxOpen" }] : /* istanbul ignore next */ []));
1174
+ this.canApply = computed(() => !!this.selectedTenant(), /* @ts-ignore */
1175
+ ...(ngDevMode ? [{ debugName: "canApply" }] : /* istanbul ignore next */ []));
1178
1176
  this.skeletonItems = [1, 2, 3];
1179
1177
  /** Tenants shown in the list (respects search and view-all toggle). */
1180
1178
  this.displayedTenants = computed(() => {
@@ -1183,8 +1181,13 @@ class AXPTenantChooserListComponent {
1183
1181
  return tenants;
1184
1182
  }
1185
1183
  return tenants.slice(0, 4);
1186
- }, ...(ngDevMode ? [{ debugName: "displayedTenants" }] : /* istanbul ignore next */ []));
1187
- this.showSearchAndViewAll = computed(() => this.allTenants().length > 4, ...(ngDevMode ? [{ debugName: "showSearchAndViewAll" }] : /* istanbul ignore next */ []));
1184
+ }, /* @ts-ignore */
1185
+ ...(ngDevMode ? [{ debugName: "displayedTenants" }] : /* istanbul ignore next */ []));
1186
+ this.showSearchAndViewAll = computed(() => this.allTenants().length > 4, /* @ts-ignore */
1187
+ ...(ngDevMode ? [{ debugName: "showSearchAndViewAll" }] : /* istanbul ignore next */ []));
1188
+ effect(() => {
1189
+ this.loadingChange.emit(this.isLoading());
1190
+ });
1188
1191
  effect(() => {
1189
1192
  if (!this.isLoading() && !this.useSelectBox() && !this.simple() && this.allTenants().length > 0) {
1190
1193
  queueMicrotask(() => this.focusFirstListItem());
@@ -1194,7 +1197,7 @@ class AXPTenantChooserListComponent {
1194
1197
  //#endregion
1195
1198
  //#region ---- Lifecycle Methods ----
1196
1199
  ngOnInit() {
1197
- this.sessionService.tenants$.pipe(first$1()).subscribe((tenants) => {
1200
+ this.sessionService.tenants$.pipe(first()).subscribe((tenants) => {
1198
1201
  this.logoRegistration.registerTenants(tenants);
1199
1202
  this.allTenants.set(tenants);
1200
1203
  if (tenants.length > 0) {
@@ -1207,7 +1210,11 @@ class AXPTenantChooserListComponent {
1207
1210
  //#region ---- UI Handlers ----
1208
1211
  filterTenants(tenants) {
1209
1212
  const query = this.searchValue().toLowerCase();
1210
- return tenants.filter((tenant) => tenant.title.toLowerCase().includes(query));
1213
+ if (!query) {
1214
+ return tenants;
1215
+ }
1216
+ const locale = this.translationService.getActiveLang();
1217
+ return tenants.filter((tenant) => resolveMultiLanguageString(tenant.title, locale).toLowerCase().includes(query));
1211
1218
  }
1212
1219
  handleSearch(event) {
1213
1220
  if (event !== undefined) {
@@ -1246,21 +1253,35 @@ class AXPTenantChooserListComponent {
1246
1253
  }
1247
1254
  }
1248
1255
  applySelection() {
1256
+ if (this.isChoosing()) {
1257
+ return;
1258
+ }
1249
1259
  const tenant = this.selectedTenant();
1250
1260
  if (tenant) {
1251
1261
  void this.chooseTenant(tenant);
1252
1262
  }
1253
1263
  }
1254
1264
  async chooseTenant(item) {
1255
- if (this.strategy) {
1256
- const updateContext = {
1257
- tenant: item,
1258
- user: this.sessionService.user,
1259
- };
1260
- await this.sessionService.updateToken(updateContext);
1265
+ if (this.isChoosing()) {
1266
+ return;
1267
+ }
1268
+ this.isChoosing.set(true);
1269
+ this.choosingId.set(item.id);
1270
+ try {
1271
+ if (this.strategy) {
1272
+ const updateContext = {
1273
+ tenant: item,
1274
+ user: this.sessionService.user,
1275
+ };
1276
+ await this.sessionService.updateToken(updateContext);
1277
+ }
1278
+ this.tenantChosen.emit();
1279
+ return this.router.navigate(['/auth/account/app-chooser']);
1280
+ }
1281
+ finally {
1282
+ this.isChoosing.set(false);
1283
+ this.choosingId.set(null);
1261
1284
  }
1262
- this.tenantChosen.emit();
1263
- return this.router.navigate(['/auth/account/app-chooser']);
1264
1285
  }
1265
1286
  //#endregion
1266
1287
  //#region ---- Utility Methods ----
@@ -1273,10 +1294,10 @@ class AXPTenantChooserListComponent {
1273
1294
  nav.navigateTo(items[currentIndex >= 0 ? currentIndex : 0]);
1274
1295
  }
1275
1296
  }
1276
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTenantChooserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1277
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPTenantChooserListComponent, isStandalone: true, selector: "axp-tenant-chooser-list", inputs: { simple: { classPropertyName: "simple", publicName: "simple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tenantChosen: "tenantChosen" }, viewQueries: [{ propertyName: "listNav", first: true, predicate: AXListNavigationDirective, descendants: true, isSignal: true }, { propertyName: "listItems", predicate: AXListNavigationItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-2 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"w-12 h-12 rounded-full shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-6 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (simple()) {\n <div class=\"w-full overflow-auto max-h-[300px] pe-2\">\n @for (tenant of allTenants(); track tenant.id) {\n <div\n class=\"flex gap-2 justify-between border-b last:border-b-0 py-3 items-start cursor-pointer\"\n (click)=\"chooseTenant(tenant)\"\n >\n <div class=\"flex flex-1 gap-2 items-center font-medium\">\n <div\n class=\"w-12 h-12 flex justify-center items-center rounded-full bg-neutral-100 m-auto\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"tenant.title\"\n class=\"flex! items-center justify-center text-sm! mx-auto w-10 h-10 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ tenant.title }}</span>\n </div>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div class=\"w-full flex flex-col gap-4\" (keydown.capture)=\"handleSelectBoxKeyDown($event)\">\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allTenants()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedTenant()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:tenant-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"tenantItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleTenantSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n ></ax-button>\n </div>\n} @else {\n @if (showSearchAndViewAll()) {\n <ax-search-box\n [placeholder]=\"'@general:search.title' | translate | async\"\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"handleSearch($event)\"\n class=\"w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n }\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col gap-1\"\n role=\"listbox\"\n >\n @for (tenant of displayedTenants(); track tenant.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isTenantSelected(tenant)\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.bg-primary-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:bg-primary-darker]=\"isTenantSelected(tenant)\"\n [class.text-primary-on-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:text-primary-on-darker]=\"isTenantSelected(tenant)\"\n [class.ring-2]=\"navItem.isActive()\"\n [class.ring-primary]=\"navItem.isActive()\"\n (click)=\"chooseTenant(tenant)\"\n (keydown)=\"handleListItemKeyDown($event, tenant)\"\n >\n <div class=\"flex flex-1 gap-2 items-center min-w-0\">\n <div\n class=\"shrink-0 flex justify-center items-center rounded-full bg-neutral-100\"\n [class.w-10]=\"simple()\"\n [class.h-10]=\"simple()\"\n [class.w-12]=\"!simple()\"\n [class.h-12]=\"!simple()\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"tenant.title\"\n class=\"flex! items-center justify-center text-sm! bg-neutral-200 dark:bg-neutral-800 rounded-full\"\n [class.w-8]=\"simple()\"\n [class.h-8]=\"simple()\"\n [class.w-10]=\"!simple()\"\n [class.h-10]=\"!simple()\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{ tenant.title }}</span>\n </div>\n </div>\n }\n </div>\n @if (showSearchAndViewAll()) {\n <div class=\"mt-6 w-full flex justify-center\">\n <ax-button\n (onClick)=\"showAllTenants()\"\n class=\"w-full\"\n look=\"outline\"\n [text]=\"\n showAll()\n ? ('@general:actions.view-less.title' | translate | async)\n : ('@general:actions.view-all.title' | translate | async)\n \"\n ></ax-button>\n </div>\n }\n}\n\n<ng-template #tenantItemTemplate let-item>\n <div class=\"flex gap-2 items-center p-2\">\n <div\n class=\"w-10 h-10 flex justify-center items-center rounded-full bg-neutral-100 shrink-0\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"32\"\n [attr.alt]=\"item.data.title\"\n class=\"flex! items-center justify-center text-sm! w-8 h-8 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"text-start md:text-base text-sm\">{{ item.data.title }}</span>\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i3.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i5.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i5.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1297
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPTenantChooserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1298
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPTenantChooserListComponent, isStandalone: true, selector: "axp-tenant-chooser-list", inputs: { simple: { classPropertyName: "simple", publicName: "simple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tenantChosen: "tenantChosen", loadingChange: "loadingChange" }, viewQueries: [{ propertyName: "listNav", first: true, predicate: AXListNavigationDirective, descendants: true, isSignal: true }, { propertyName: "listItems", predicate: AXListNavigationItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-3 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"size-12 rounded-lg shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-5 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (simple()) {\n <div\n class=\"w-full overflow-auto max-h-[300px] pe-2 flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (tenant of allTenants(); track tenant.id) {\n <div\n class=\"flex gap-2 justify-between py-3 items-center cursor-pointer rounded-md transition-colors hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== tenant.id\"\n [class.cursor-wait]=\"isChoosing()\"\n [attr.aria-busy]=\"choosingId() === tenant.id\"\n (click)=\"chooseTenant(tenant)\"\n >\n <div class=\"flex flex-1 gap-3 items-center font-medium min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(tenant.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{\n tenant.title | translate | async\n }}</span>\n </div>\n @if (choosingId() === tenant.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div\n class=\"w-full flex flex-col gap-4\"\n [class.pointer-events-none]=\"isChoosing()\"\n [class.opacity-60]=\"isChoosing()\"\n (keydown.capture)=\"handleSelectBoxKeyDown($event)\"\n >\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allTenants()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedTenant()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:tenant-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"tenantItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleTenantSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply() || isChoosing()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n >\n @if (isChoosing()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n} @else {\n @if (showSearchAndViewAll()) {\n <ax-search-box\n [placeholder]=\"'@general:search.title' | translate | async\"\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"handleSearch($event)\"\n class=\"w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n }\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n role=\"listbox\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (tenant of displayedTenants(); track tenant.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isTenantSelected(tenant)\"\n [attr.aria-busy]=\"choosingId() === tenant.id\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary\"\n [class.bg-primary-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:bg-primary-darker]=\"isTenantSelected(tenant)\"\n [class.text-primary-on-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:text-primary-on-darker]=\"isTenantSelected(tenant)\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== tenant.id\"\n [class.cursor-wait]=\"isChoosing()\"\n (click)=\"chooseTenant(tenant)\"\n (keydown)=\"handleListItemKeyDown($event, tenant)\"\n >\n <div class=\"flex flex-1 gap-3 items-center min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(tenant.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{\n tenant.title | translate | async\n }}</span>\n </div>\n @if (choosingId() === tenant.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n @if (showSearchAndViewAll()) {\n <div class=\"mt-6 w-full flex justify-center\">\n <ax-button\n (onClick)=\"showAllTenants()\"\n class=\"w-full\"\n look=\"outline\"\n [disabled]=\"isChoosing()\"\n [text]=\"\n showAll()\n ? ('@general:actions.view-less.title' | translate | async)\n : ('@general:actions.view-all.title' | translate | async)\n \"\n ></ax-button>\n </div>\n }\n}\n\n<ng-template #tenantItemTemplate let-item>\n <div class=\"flex gap-3 items-center p-2\">\n <div class=\"size-12 overflow-hidden rounded-lg shrink-0\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(item.data.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"text-start md:text-base text-sm\">{{ item.data.title | translate | async }}</span>\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i4.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i6.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i6.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1278
1299
  }
1279
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTenantChooserListComponent, decorators: [{
1300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPTenantChooserListComponent, decorators: [{
1280
1301
  type: Component,
1281
1302
  args: [{ selector: 'axp-tenant-chooser-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1282
1303
  CommonModule,
@@ -1284,30 +1305,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1284
1305
  AXTranslationModule,
1285
1306
  AXButtonModule,
1286
1307
  AXDecoratorModule,
1308
+ AXLoadingModule,
1287
1309
  AXSkeletonModule,
1288
1310
  AXSelectBoxModule,
1289
1311
  AXSearchBoxModule,
1290
1312
  AXListNavigationModule,
1291
1313
  AXPLogoComponent,
1292
- ], template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-2 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"w-12 h-12 rounded-full shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-6 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (simple()) {\n <div class=\"w-full overflow-auto max-h-[300px] pe-2\">\n @for (tenant of allTenants(); track tenant.id) {\n <div\n class=\"flex gap-2 justify-between border-b last:border-b-0 py-3 items-start cursor-pointer\"\n (click)=\"chooseTenant(tenant)\"\n >\n <div class=\"flex flex-1 gap-2 items-center font-medium\">\n <div\n class=\"w-12 h-12 flex justify-center items-center rounded-full bg-neutral-100 m-auto\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"tenant.title\"\n class=\"flex! items-center justify-center text-sm! mx-auto w-10 h-10 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 text-start md:text-base text-sm\">{{ tenant.title }}</span>\n </div>\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div class=\"w-full flex flex-col gap-4\" (keydown.capture)=\"handleSelectBoxKeyDown($event)\">\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allTenants()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedTenant()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:tenant-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"tenantItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleTenantSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n ></ax-button>\n </div>\n} @else {\n @if (showSearchAndViewAll()) {\n <ax-search-box\n [placeholder]=\"'@general:search.title' | translate | async\"\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"handleSearch($event)\"\n class=\"w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n }\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col gap-1\"\n role=\"listbox\"\n >\n @for (tenant of displayedTenants(); track tenant.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isTenantSelected(tenant)\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.bg-primary-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:bg-primary-darker]=\"isTenantSelected(tenant)\"\n [class.text-primary-on-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:text-primary-on-darker]=\"isTenantSelected(tenant)\"\n [class.ring-2]=\"navItem.isActive()\"\n [class.ring-primary]=\"navItem.isActive()\"\n (click)=\"chooseTenant(tenant)\"\n (keydown)=\"handleListItemKeyDown($event, tenant)\"\n >\n <div class=\"flex flex-1 gap-2 items-center min-w-0\">\n <div\n class=\"shrink-0 flex justify-center items-center rounded-full bg-neutral-100\"\n [class.w-10]=\"simple()\"\n [class.h-10]=\"simple()\"\n [class.w-12]=\"!simple()\"\n [class.h-12]=\"!simple()\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"40\"\n [attr.alt]=\"tenant.title\"\n class=\"flex! items-center justify-center text-sm! bg-neutral-200 dark:bg-neutral-800 rounded-full\"\n [class.w-8]=\"simple()\"\n [class.h-8]=\"simple()\"\n [class.w-10]=\"!simple()\"\n [class.h-10]=\"!simple()\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{ tenant.title }}</span>\n </div>\n </div>\n }\n </div>\n @if (showSearchAndViewAll()) {\n <div class=\"mt-6 w-full flex justify-center\">\n <ax-button\n (onClick)=\"showAllTenants()\"\n class=\"w-full\"\n look=\"outline\"\n [text]=\"\n showAll()\n ? ('@general:actions.view-less.title' | translate | async)\n : ('@general:actions.view-all.title' | translate | async)\n \"\n ></ax-button>\n </div>\n }\n}\n\n<ng-template #tenantItemTemplate let-item>\n <div class=\"flex gap-2 items-center p-2\">\n <div\n class=\"w-10 h-10 flex justify-center items-center rounded-full bg-neutral-100 shrink-0\"\n >\n <axp-logo\n [logoKey]=\"tenantLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"32\"\n [attr.alt]=\"item.data.title\"\n class=\"flex! items-center justify-center text-sm! w-8 h-8 bg-neutral-200 rounded-full\"\n ></axp-logo>\n </div>\n <span class=\"text-start md:text-base text-sm\">{{ item.data.title }}</span>\n </div>\n</ng-template>\n" }]
1293
- }], ctorParameters: () => [], propDecorators: { simple: [{ type: i0.Input, args: [{ isSignal: true, alias: "simple", required: false }] }], tenantChosen: [{ type: i0.Output, args: ["tenantChosen"] }], listNav: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXListNavigationDirective), { isSignal: true }] }], listItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => AXListNavigationItemDirective), { isSignal: true }] }] } });
1314
+ ], template: "@if (isLoading()) {\n <div class=\"w-full flex flex-col gap-3\">\n @for (item of skeletonItems; track item) {\n <div class=\"flex gap-3 items-center p-2\">\n <ax-skeleton [animated]=\"true\" class=\"size-12 rounded-lg shrink-0\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"flex-1 h-5 rounded-md\"></ax-skeleton>\n </div>\n }\n </div>\n} @else if (simple()) {\n <div\n class=\"w-full overflow-auto max-h-[300px] pe-2 flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (tenant of allTenants(); track tenant.id) {\n <div\n class=\"flex gap-2 justify-between py-3 items-center cursor-pointer rounded-md transition-colors hover:bg-primary-lightest hover:dark:bg-primary-dark\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== tenant.id\"\n [class.cursor-wait]=\"isChoosing()\"\n [attr.aria-busy]=\"choosingId() === tenant.id\"\n (click)=\"chooseTenant(tenant)\"\n >\n <div class=\"flex flex-1 gap-3 items-center font-medium min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(tenant.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{\n tenant.title | translate | async\n }}</span>\n </div>\n @if (choosingId() === tenant.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n} @else if (useSelectBox()) {\n <div\n class=\"w-full flex flex-col gap-4\"\n [class.pointer-events-none]=\"isChoosing()\"\n [class.opacity-60]=\"isChoosing()\"\n (keydown.capture)=\"handleSelectBoxKeyDown($event)\"\n >\n <ax-select-box\n class=\"w-full\"\n [dataSource]=\"allTenants()\"\n textField=\"title\"\n valueField=\"id\"\n [value]=\"selectedTenant()\"\n [itemHeight]=\"56\"\n [placeholder]=\"('@auth:tenant-chooser.select-placeholder' | translate | async) ?? ''\"\n [itemTemplate]=\"tenantItemTemplate\"\n (onOpened)=\"isSelectBoxOpen.set(true)\"\n (onClosed)=\"isSelectBoxOpen.set(false)\"\n (onValueChanged)=\"handleTenantSelect($event)\"\n >\n <ax-search-box look=\"fill\"></ax-search-box>\n </ax-select-box>\n <ax-button\n class=\"w-full\"\n color=\"primary\"\n [disabled]=\"!canApply() || isChoosing()\"\n [text]=\"('@general:actions.apply.title' | translate | async) ?? ''\"\n (onClick)=\"applySelection()\"\n >\n @if (isChoosing()) {\n <ax-loading></ax-loading>\n }\n </ax-button>\n </div>\n} @else {\n @if (showSearchAndViewAll()) {\n <ax-search-box\n [placeholder]=\"'@general:search.title' | translate | async\"\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"handleSearch($event)\"\n class=\"w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n }\n <div\n axListNavigation\n #listNav=\"axListNavigation\"\n class=\"w-full overflow-auto max-h-[300px] flex flex-col divide-y divide-neutral-100 dark:divide-neutral-800\"\n role=\"listbox\"\n [class.pointer-events-none]=\"isChoosing()\"\n >\n @for (tenant of displayedTenants(); track tenant.id) {\n <div\n axListNavigationItem\n #navItem=\"axListNavigationItem\"\n tabindex=\"0\"\n role=\"option\"\n [attr.aria-selected]=\"isTenantSelected(tenant)\"\n [attr.aria-busy]=\"choosingId() === tenant.id\"\n class=\"flex gap-2 items-center p-2 cursor-pointer rounded-md transition-colors outline-none hover:bg-primary-lightest hover:dark:bg-primary-dark focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary\"\n [class.bg-primary-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:bg-primary-darker]=\"isTenantSelected(tenant)\"\n [class.text-primary-on-lighter]=\"isTenantSelected(tenant)\"\n [class.dark:text-primary-on-darker]=\"isTenantSelected(tenant)\"\n [class.opacity-50]=\"isChoosing() && choosingId() !== tenant.id\"\n [class.cursor-wait]=\"isChoosing()\"\n (click)=\"chooseTenant(tenant)\"\n (keydown)=\"handleListItemKeyDown($event, tenant)\"\n >\n <div class=\"flex flex-1 gap-3 items-center min-w-0\">\n <div class=\"shrink-0 size-12 overflow-hidden rounded-lg\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(tenant)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(tenant.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"flex-1 truncate text-start md:text-base text-sm\">{{\n tenant.title | translate | async\n }}</span>\n </div>\n @if (choosingId() === tenant.id) {\n <ax-loading class=\"shrink-0\"></ax-loading>\n }\n </div>\n }\n </div>\n @if (showSearchAndViewAll()) {\n <div class=\"mt-6 w-full flex justify-center\">\n <ax-button\n (onClick)=\"showAllTenants()\"\n class=\"w-full\"\n look=\"outline\"\n [disabled]=\"isChoosing()\"\n [text]=\"\n showAll()\n ? ('@general:actions.view-less.title' | translate | async)\n : ('@general:actions.view-all.title' | translate | async)\n \"\n ></ax-button>\n </div>\n }\n}\n\n<ng-template #tenantItemTemplate let-item>\n <div class=\"flex gap-3 items-center p-2\">\n <div class=\"size-12 overflow-hidden rounded-lg shrink-0\">\n <axp-logo\n [logoKey]=\"tenantLogoKey(item.data)\"\n appearance=\"colored\"\n [size]=\"42\"\n [attr.alt]=\"(item.data.title | translate | async) ?? ''\"\n class=\"size-12 overflow-hidden rounded-lg\"\n ></axp-logo>\n </div>\n <span class=\"text-start md:text-base text-sm\">{{ item.data.title | translate | async }}</span>\n </div>\n</ng-template>\n" }]
1315
+ }], ctorParameters: () => [], propDecorators: { simple: [{ type: i0.Input, args: [{ isSignal: true, alias: "simple", required: false }] }], tenantChosen: [{ type: i0.Output, args: ["tenantChosen"] }], loadingChange: [{ type: i0.Output, args: ["loadingChange"] }], listNav: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXListNavigationDirective), { isSignal: true }] }], listItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => AXListNavigationItemDirective), { isSignal: true }] }] } });
1294
1316
 
1295
1317
  class AXPTenantChooserDropdownComponent {
1296
1318
  constructor() {
1319
+ //#region ----- Services & Dependencies -----
1297
1320
  this.sessionService = inject(AXPSessionService);
1321
+ //#endregion
1322
+ //#region ----- State Signals -----
1298
1323
  this.tenants$ = this.sessionService.tenants$;
1299
- this.tenant = this.sessionService.tenant;
1300
- this.tenantPopover = viewChild('tenantPopover', ...(ngDevMode ? [{ debugName: "tenantPopover" }] : /* istanbul ignore next */ []));
1324
+ this.tenant$ = this.sessionService.tenant$;
1325
+ this.tenantsLoading = signal(true, /* @ts-ignore */
1326
+ ...(ngDevMode ? [{ debugName: "tenantsLoading" }] : /* istanbul ignore next */ []));
1327
+ this.tenantPopover = viewChild('tenantPopover', /* @ts-ignore */
1328
+ ...(ngDevMode ? [{ debugName: "tenantPopover" }] : /* istanbul ignore next */ []));
1301
1329
  }
1330
+ //#endregion
1331
+ //#region ----- Lifecycle -----
1332
+ ngOnInit() {
1333
+ this.tenants$.pipe(first()).subscribe(() => {
1334
+ this.tenantsLoading.set(false);
1335
+ });
1336
+ }
1337
+ //#endregion
1338
+ //#region ----- Event Handlers -----
1302
1339
  closePopover() {
1303
1340
  this.tenantPopover()?.close();
1304
1341
  }
1305
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTenantChooserDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1306
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPTenantChooserDropdownComponent, isStandalone: true, selector: "axp-tenant-chooser-dropdown", viewQueries: [{ propertyName: "tenantPopover", first: true, predicate: ["tenantPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (tenants$ | async; as tenants) {\n @if (tenants.length > 1) {\n <ax-button\n [text]=\"tenant?.title ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n #tenantChooser\n >\n <ax-suffix>\n <ax-icon class=\"fa-solid fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n <ax-popover\n [target]=\"tenantChooser\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n #tenantPopover\n >\n <div\n class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\"\n >\n <axp-tenant-chooser-list\n [simple]=\"true\"\n (tenantChosen)=\"closePopover()\"\n ></axp-tenant-chooser-list>\n </div>\n </ax-popover>\n } @else {\n <ax-button\n [text]=\"tenant?.title ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n ></ax-button>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$1.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: "component", type: AXPTenantChooserListComponent, selector: "axp-tenant-chooser-list", inputs: ["simple"], outputs: ["tenantChosen"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] }); }
1342
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPTenantChooserDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1343
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPTenantChooserDropdownComponent, isStandalone: true, selector: "axp-tenant-chooser-dropdown", viewQueries: [{ propertyName: "tenantPopover", first: true, predicate: ["tenantPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (tenantsLoading()) {\n <ax-skeleton [animated]=\"true\" class=\"h-5 w-32 max-w-full\"></ax-skeleton>\n} @else if (tenants$ | async; as tenants) {\n @if (tenants.length > 1) {\n <ax-button\n [text]=\"((tenant$ | async)?.title | translate | async) ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n #tenantChooser\n >\n <ax-suffix>\n <ax-icon class=\"fa-solid fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n <ax-popover\n [target]=\"tenantChooser\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n #tenantPopover\n >\n <div\n class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\"\n >\n <axp-tenant-chooser-list\n [simple]=\"true\"\n (tenantChosen)=\"closePopover()\"\n ></axp-tenant-chooser-list>\n </div>\n </ax-popover>\n } @else {\n <ax-button\n [text]=\"((tenant$ | async)?.title | translate | async) ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n ></ax-button>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$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: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$1.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: AXSkeletonModule }, { kind: "component", type: i1$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPTenantChooserListComponent, selector: "axp-tenant-chooser-list", inputs: ["simple"], outputs: ["tenantChosen", "loadingChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
1307
1344
  }
1308
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTenantChooserDropdownComponent, decorators: [{
1345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPTenantChooserDropdownComponent, decorators: [{
1309
1346
  type: Component,
1310
- args: [{ selector: 'axp-tenant-chooser-dropdown', imports: [CommonModule, AXButtonModule, AXPopoverModule, AXDecoratorModule, AXPTenantChooserListComponent], template: "@if (tenants$ | async; as tenants) {\n @if (tenants.length > 1) {\n <ax-button\n [text]=\"tenant?.title ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n #tenantChooser\n >\n <ax-suffix>\n <ax-icon class=\"fa-solid fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n <ax-popover\n [target]=\"tenantChooser\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n #tenantPopover\n >\n <div\n class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\"\n >\n <axp-tenant-chooser-list\n [simple]=\"true\"\n (tenantChosen)=\"closePopover()\"\n ></axp-tenant-chooser-list>\n </div>\n </ax-popover>\n } @else {\n <ax-button\n [text]=\"tenant?.title ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n ></ax-button>\n }\n}\n" }]
1347
+ args: [{ selector: 'axp-tenant-chooser-dropdown', changeDetection: ChangeDetectionStrategy.Eager, imports: [
1348
+ CommonModule,
1349
+ AXTranslationModule,
1350
+ AXButtonModule,
1351
+ AXPopoverModule,
1352
+ AXDecoratorModule,
1353
+ AXSkeletonModule,
1354
+ AXPTenantChooserListComponent,
1355
+ ], template: "@if (tenantsLoading()) {\n <ax-skeleton [animated]=\"true\" class=\"h-5 w-32 max-w-full\"></ax-skeleton>\n} @else if (tenants$ | async; as tenants) {\n @if (tenants.length > 1) {\n <ax-button\n [text]=\"((tenant$ | async)?.title | translate | async) ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n #tenantChooser\n >\n <ax-suffix>\n <ax-icon class=\"fa-solid fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n <ax-popover\n [target]=\"tenantChooser\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n #tenantPopover\n >\n <div\n class=\"bg-lightest border overflow-hidden rounded-md shadow-md w-full min-w-64 p-1\"\n >\n <axp-tenant-chooser-list\n [simple]=\"true\"\n (tenantChosen)=\"closePopover()\"\n ></axp-tenant-chooser-list>\n </div>\n </ax-popover>\n } @else {\n <ax-button\n [text]=\"((tenant$ | async)?.title | translate | async) ?? ''\"\n class=\"ax-sm\"\n look=\"blank\"\n ></ax-button>\n }\n}\n" }]
1311
1356
  }], propDecorators: { tenantPopover: [{ type: i0.ViewChild, args: ['tenantPopover', { isSignal: true }] }] } });
1312
1357
 
1313
1358
  //#region ---- Profile slot menu hook ----
@@ -1338,7 +1383,8 @@ class AXMAuthProfileSlotComponent {
1338
1383
  this.tenant$ = this.sessionService.tenant$;
1339
1384
  this.isAuthenticated$ = this.sessionService.isAuthenticated$;
1340
1385
  this.isAuthenticated = toSignal(this.sessionService.isAuthenticated$, { initialValue: false });
1341
- this.menuItems = signal([], ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
1386
+ this.menuItems = signal([], /* @ts-ignore */
1387
+ ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
1342
1388
  //#endregion
1343
1389
  //#region ---- UI Handlers ----
1344
1390
  this.appName = () => this.sessionService.application?.name;
@@ -1432,17 +1478,17 @@ class AXMAuthProfileSlotComponent {
1432
1478
  await this.commandService.execute(command.name, command.options ?? {});
1433
1479
  }
1434
1480
  }
1435
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthProfileSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1436
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMAuthProfileSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "@if (isAuthenticated$ | async) {\n <div class=\"size-fit\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"36\"\n [userId]=\"(user$ | async)?.id!\"\n ></axp-user-avatar>\n </div>\n\n <ax-popover [target]=\"avatar\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #p>\n <div\n class=\"bg-lightest border border-lightest rounded-md shadow-md w-full min-w-64\"\n >\n <div class=\"flex flex-col items-center p-4 border-b\">\n <axp-user-avatar\n [size]=\"64\"\n [userId]=\"(user$ | async)?.id!\"\n ></axp-user-avatar>\n\n <div class=\"flex flex-col items-center justify-center mt-2\">\n <div class=\"text-base font-bold\">{{ (user$ | async)?.title }}</div>\n <axp-tenant-chooser-dropdown></axp-tenant-chooser-dropdown>\n </div>\n </div>\n <div class=\"axp-profile-slot-menus\">\n <ul>\n @for (item of menuItems(); track item.name ?? item.title) {\n @if (item.visible != false) {\n @if (hasProfileSlotMenuBreakBefore(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n <li [class]=\"menuItemClass(item)\">\n <a (click)=\"handleMenuItemClick(item, p)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"flex-1\">{{\n item.title | translate | async\n }}</span>\n </a>\n </li>\n @if (hasProfileSlotMenuBreakAfter(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n }\n }\n </ul>\n </div>\n </div>\n </ax-popover>\n </div>\n} @else {\n <ax-button\n color=\"default\"\n look=\"blank\"\n text=\"Sign Up / Sign In\"\n (click)=\"handleSignIn()\"\n >\n <ax-icon>\n <i class=\"fa-solid fa-user text-slate-400 dark:text-slate-200\"></i>\n </ax-icon>\n </ax-button>\n}\n", styles: ["@layer properties;.axp-profile-slot-menus ul{margin-top:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul:last-child{border-style:var(--tw-border-style);border-width:0px}.axp-profile-slot-menus ul li{display:flex;cursor:pointer;border-radius:var(--radius-md, .375rem)}.axp-profile-slot-menus ul li:last-child{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul li:hover{background-color:rgba(var(--ax-sys-color-dark-surface))}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break{pointer-events:none;margin-inline:calc(var(--spacing, .25rem) * 2);margin-block:var(--spacing, .25rem);height:0;min-height:0;cursor:default;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding:0}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break:hover{background-color:transparent}.axp-profile-slot-menus ul li i{margin-inline-end:calc(var(--spacing, .25rem) * 3);display:grid;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);place-items:center;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-profile-slot-menus ul li a{display:flex;height:100%;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 2)}@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.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1481
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthProfileSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1482
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAuthProfileSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "@if (isAuthenticated$ | async) {\n <div class=\"size-fit\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"36\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"true\"\n ></axp-user-avatar>\n </div>\n\n <ax-popover\n [target]=\"avatar\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"false\"\n #p\n >\n <div\n class=\"bg-lightest border border-lightest rounded-md shadow-md w-full min-w-64\"\n >\n <div class=\"flex flex-col items-center p-4 border-b\">\n <axp-user-avatar\n [size]=\"64\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"false\"\n ></axp-user-avatar>\n\n <div class=\"flex flex-col items-center justify-center mt-2\">\n <div class=\"text-base font-bold\">{{ (user$ | async)?.title }}</div>\n <axp-tenant-chooser-dropdown></axp-tenant-chooser-dropdown>\n </div>\n </div>\n <div class=\"axp-profile-slot-menus\">\n <ul>\n @for (item of menuItems(); track item.name ?? item.title) {\n @if (item.visible != false) {\n @if (hasProfileSlotMenuBreakBefore(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n <li [class]=\"menuItemClass(item)\">\n <a (click)=\"handleMenuItemClick(item, p)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"flex-1\">{{\n item.title | translate | async\n }}</span>\n </a>\n </li>\n @if (hasProfileSlotMenuBreakAfter(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n }\n }\n </ul>\n </div>\n </div>\n </ax-popover>\n </div>\n} @else {\n <ax-button\n color=\"default\"\n look=\"blank\"\n text=\"Sign Up / Sign In\"\n (click)=\"handleSignIn()\"\n >\n <ax-icon>\n <i class=\"fa-solid fa-user text-slate-400 dark:text-slate-200\"></i>\n </ax-icon>\n </ax-button>\n}\n", styles: ["@layer properties;.axp-profile-slot-menus ul{margin-top:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul:last-child{border-style:var(--tw-border-style);border-width:0px}.axp-profile-slot-menus ul li{display:flex;cursor:pointer;border-radius:var(--radius-md, .375rem)}.axp-profile-slot-menus ul li:last-child{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul li:hover{background-color:rgba(var(--ax-sys-color-dark-surface))}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break{pointer-events:none;margin-inline:calc(var(--spacing, .25rem) * 2);margin-block:var(--spacing, .25rem);height:0px;min-height:0px;cursor:default;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding:0}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break:hover{background-color:transparent}.axp-profile-slot-menus ul li i{margin-inline-end:calc(var(--spacing, .25rem) * 3);display:grid;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);place-items:center;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-profile-slot-menus ul li a{display:flex;height:100%;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 2)}@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: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1437
1483
  //
1438
- AXImageModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type:
1484
+ AXImageModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$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: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type:
1439
1485
  // AXKBDComponent,
1440
1486
  // AXKBDItemComponent,
1441
- AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId"] }, { kind: "component", type:
1487
+ AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "component", type:
1442
1488
  //
1443
- AXPTenantChooserDropdownComponent, selector: "axp-tenant-chooser-dropdown" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1489
+ AXPTenantChooserDropdownComponent, selector: "axp-tenant-chooser-dropdown" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1444
1490
  }
1445
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthProfileSlotComponent, decorators: [{
1491
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthProfileSlotComponent, decorators: [{
1446
1492
  type: Component,
1447
1493
  args: [{ imports: [
1448
1494
  CommonModule,
@@ -1460,7 +1506,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1460
1506
  AXPUserAvatarComponent,
1461
1507
  //
1462
1508
  AXPTenantChooserDropdownComponent,
1463
- ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (isAuthenticated$ | async) {\n <div class=\"size-fit\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"36\"\n [userId]=\"(user$ | async)?.id!\"\n ></axp-user-avatar>\n </div>\n\n <ax-popover [target]=\"avatar\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" #p>\n <div\n class=\"bg-lightest border border-lightest rounded-md shadow-md w-full min-w-64\"\n >\n <div class=\"flex flex-col items-center p-4 border-b\">\n <axp-user-avatar\n [size]=\"64\"\n [userId]=\"(user$ | async)?.id!\"\n ></axp-user-avatar>\n\n <div class=\"flex flex-col items-center justify-center mt-2\">\n <div class=\"text-base font-bold\">{{ (user$ | async)?.title }}</div>\n <axp-tenant-chooser-dropdown></axp-tenant-chooser-dropdown>\n </div>\n </div>\n <div class=\"axp-profile-slot-menus\">\n <ul>\n @for (item of menuItems(); track item.name ?? item.title) {\n @if (item.visible != false) {\n @if (hasProfileSlotMenuBreakBefore(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n <li [class]=\"menuItemClass(item)\">\n <a (click)=\"handleMenuItemClick(item, p)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"flex-1\">{{\n item.title | translate | async\n }}</span>\n </a>\n </li>\n @if (hasProfileSlotMenuBreakAfter(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n }\n }\n </ul>\n </div>\n </div>\n </ax-popover>\n </div>\n} @else {\n <ax-button\n color=\"default\"\n look=\"blank\"\n text=\"Sign Up / Sign In\"\n (click)=\"handleSignIn()\"\n >\n <ax-icon>\n <i class=\"fa-solid fa-user text-slate-400 dark:text-slate-200\"></i>\n </ax-icon>\n </ax-button>\n}\n", styles: ["@layer properties;.axp-profile-slot-menus ul{margin-top:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul:last-child{border-style:var(--tw-border-style);border-width:0px}.axp-profile-slot-menus ul li{display:flex;cursor:pointer;border-radius:var(--radius-md, .375rem)}.axp-profile-slot-menus ul li:last-child{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul li:hover{background-color:rgba(var(--ax-sys-color-dark-surface))}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break{pointer-events:none;margin-inline:calc(var(--spacing, .25rem) * 2);margin-block:var(--spacing, .25rem);height:0;min-height:0;cursor:default;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding:0}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break:hover{background-color:transparent}.axp-profile-slot-menus ul li i{margin-inline-end:calc(var(--spacing, .25rem) * 3);display:grid;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);place-items:center;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-profile-slot-menus ul li a{display:flex;height:100%;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 2)}@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.2 | MIT License | https://tailwindcss.com */\n"] }]
1509
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (isAuthenticated$ | async) {\n <div class=\"size-fit\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"36\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"true\"\n ></axp-user-avatar>\n </div>\n\n <ax-popover\n [target]=\"avatar\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"false\"\n #p\n >\n <div\n class=\"bg-lightest border border-lightest rounded-md shadow-md w-full min-w-64\"\n >\n <div class=\"flex flex-col items-center p-4 border-b\">\n <axp-user-avatar\n [size]=\"64\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"false\"\n ></axp-user-avatar>\n\n <div class=\"flex flex-col items-center justify-center mt-2\">\n <div class=\"text-base font-bold\">{{ (user$ | async)?.title }}</div>\n <axp-tenant-chooser-dropdown></axp-tenant-chooser-dropdown>\n </div>\n </div>\n <div class=\"axp-profile-slot-menus\">\n <ul>\n @for (item of menuItems(); track item.name ?? item.title) {\n @if (item.visible != false) {\n @if (hasProfileSlotMenuBreakBefore(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n <li [class]=\"menuItemClass(item)\">\n <a (click)=\"handleMenuItemClick(item, p)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"flex-1\">{{\n item.title | translate | async\n }}</span>\n </a>\n </li>\n @if (hasProfileSlotMenuBreakAfter(item.break)) {\n <li class=\"axp-profile-slot-menu-break\" role=\"separator\"></li>\n }\n }\n }\n </ul>\n </div>\n </div>\n </ax-popover>\n </div>\n} @else {\n <ax-button\n color=\"default\"\n look=\"blank\"\n text=\"Sign Up / Sign In\"\n (click)=\"handleSignIn()\"\n >\n <ax-icon>\n <i class=\"fa-solid fa-user text-slate-400 dark:text-slate-200\"></i>\n </ax-icon>\n </ax-button>\n}\n", styles: ["@layer properties;.axp-profile-slot-menus ul{margin-top:calc(var(--spacing, .25rem) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding-inline:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul:last-child{border-style:var(--tw-border-style);border-width:0px}.axp-profile-slot-menus ul li{display:flex;cursor:pointer;border-radius:var(--radius-md, .375rem)}.axp-profile-slot-menus ul li:last-child{margin-bottom:calc(var(--spacing, .25rem) * 2)}.axp-profile-slot-menus ul li:hover{background-color:rgba(var(--ax-sys-color-dark-surface))}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break{pointer-events:none;margin-inline:calc(var(--spacing, .25rem) * 2);margin-block:var(--spacing, .25rem);height:0px;min-height:0px;cursor:default;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-border-default);padding:0}.axp-profile-slot-menus ul li.axp-profile-slot-menu-break:hover{background-color:transparent}.axp-profile-slot-menus ul li i{margin-inline-end:calc(var(--spacing, .25rem) * 3);display:grid;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);place-items:center;font-size:var(--text-xl, 1.25rem);line-height:var(--tw-leading, var(--text-xl--line-height, calc(1.75 / 1.25)))}.axp-profile-slot-menus ul li a{display:flex;height:100%;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 2)}@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"] }]
1464
1510
  }] });
1465
1511
 
1466
1512
  class AXMUserProfileCardSlotComponent {
@@ -1473,15 +1519,18 @@ class AXMUserProfileCardSlotComponent {
1473
1519
  this.isCompactMode = computed(() => {
1474
1520
  this.deviceService.screenSize();
1475
1521
  return this.themeStore.effectiveMenuVerticalMode() === AXPMenuVerticalMode.Compact;
1476
- }, ...(ngDevMode ? [{ debugName: "isCompactMode" }] : /* istanbul ignore next */ []));
1477
- this.hasPicture = signal(true, ...(ngDevMode ? [{ debugName: "hasPicture" }] : /* istanbul ignore next */ []));
1478
- this.avatarText = signal('', ...(ngDevMode ? [{ debugName: "avatarText" }] : /* istanbul ignore next */ []));
1522
+ }, /* @ts-ignore */
1523
+ ...(ngDevMode ? [{ debugName: "isCompactMode" }] : /* istanbul ignore next */ []));
1524
+ this.hasPicture = signal(true, /* @ts-ignore */
1525
+ ...(ngDevMode ? [{ debugName: "hasPicture" }] : /* istanbul ignore next */ []));
1526
+ this.avatarText = signal('', /* @ts-ignore */
1527
+ ...(ngDevMode ? [{ debugName: "avatarText" }] : /* istanbul ignore next */ []));
1479
1528
  this.user$ = this.sessionService.user$;
1480
1529
  this.tenant$ = this.sessionService.tenant$;
1481
1530
  this.isAuthenticated$ = this.sessionService.isAuthenticated$;
1482
1531
  this.appName = () => this.sessionService.application?.name;
1483
1532
  this.getAvatarText = () => {
1484
- this.user$.pipe(first$1()).subscribe((user) => {
1533
+ this.user$.pipe(first()).subscribe((user) => {
1485
1534
  const names = user?.title.split(' ');
1486
1535
  if (names?.length && names?.length > 1) {
1487
1536
  this.avatarText.set(`${names[0][0].toUpperCase()}${names[names.length - 1][0].toUpperCase()}`);
@@ -1528,16 +1577,16 @@ class AXMUserProfileCardSlotComponent {
1528
1577
  this.src = '';
1529
1578
  }
1530
1579
  }
1531
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMUserProfileCardSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1532
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMUserProfileCardSlotComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "profilePopover", first: true, predicate: ["profilePopover"], descendants: true }], ngImport: i0, template: "@if((isAuthenticated$ | async)) {\n<div class=\"p-3 flex items-center gap-1 border-b border-border-lighter\" [class.justify-center]=\"isCompactMode()\">\n <div #avatar>\n <axp-user-avatar [size]=\"48\" [userId]=\"(user$ | async)?.id!\"></axp-user-avatar>\n </div>\n @if (!isCompactMode()) {\n <div class=\"flex flex-col\">\n <ax-title class=\"text-sm font-medium px-3\">{{ (user$ | async)?.title }}</ax-title>\n <axp-tenant-chooser-dropdown />\n </div>\n }\n</div>\n}\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1580
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserProfileCardSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1581
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMUserProfileCardSlotComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "profilePopover", first: true, predicate: ["profilePopover"], descendants: true }], ngImport: i0, template: "@if((isAuthenticated$ | async)) {\n<div class=\"p-3 flex items-center gap-1 border-b border-border-lighter\" [class.justify-center]=\"isCompactMode()\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"48\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"false\"\n ></axp-user-avatar>\n </div>\n @if (!isCompactMode()) {\n <div class=\"flex flex-col\">\n <ax-title class=\"text-sm font-medium px-3\">{{ (user$ | async)?.title }}</ax-title>\n <axp-tenant-chooser-dropdown />\n </div>\n }\n</div>\n}\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1533
1582
  //
1534
1583
  AXImageModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.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: "component", type:
1535
1584
  //
1536
- AXPTenantChooserDropdownComponent, selector: "axp-tenant-chooser-dropdown" }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
1585
+ AXPTenantChooserDropdownComponent, selector: "axp-tenant-chooser-dropdown" }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId", "showPresence", "displayName", "displayAvatar"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
1537
1586
  }
1538
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMUserProfileCardSlotComponent, decorators: [{
1587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserProfileCardSlotComponent, decorators: [{
1539
1588
  type: Component,
1540
- args: [{ imports: [
1589
+ args: [{ changeDetection: ChangeDetectionStrategy.Eager, imports: [
1541
1590
  RouterModule,
1542
1591
  //
1543
1592
  AXImageModule,
@@ -1551,7 +1600,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1551
1600
  AXPTenantChooserDropdownComponent,
1552
1601
  AsyncPipe,
1553
1602
  AXPUserAvatarComponent,
1554
- ], template: "@if((isAuthenticated$ | async)) {\n<div class=\"p-3 flex items-center gap-1 border-b border-border-lighter\" [class.justify-center]=\"isCompactMode()\">\n <div #avatar>\n <axp-user-avatar [size]=\"48\" [userId]=\"(user$ | async)?.id!\"></axp-user-avatar>\n </div>\n @if (!isCompactMode()) {\n <div class=\"flex flex-col\">\n <ax-title class=\"text-sm font-medium px-3\">{{ (user$ | async)?.title }}</ax-title>\n <axp-tenant-chooser-dropdown />\n </div>\n }\n</div>\n}\n" }]
1603
+ ], template: "@if((isAuthenticated$ | async)) {\n<div class=\"p-3 flex items-center gap-1 border-b border-border-lighter\" [class.justify-center]=\"isCompactMode()\">\n <div #avatar>\n <axp-user-avatar\n [size]=\"48\"\n [userId]=\"$safeNavigationMigration((user$ | async)?.id)!\"\n [showPresence]=\"false\"\n ></axp-user-avatar>\n </div>\n @if (!isCompactMode()) {\n <div class=\"flex flex-col\">\n <ax-title class=\"text-sm font-medium px-3\">{{ (user$ | async)?.title }}</ax-title>\n <axp-tenant-chooser-dropdown />\n </div>\n }\n</div>\n}\n" }]
1555
1604
  }], ctorParameters: () => [], propDecorators: { profilePopover: [{
1556
1605
  type: ViewChild,
1557
1606
  args: ['profilePopover']
@@ -1566,7 +1615,7 @@ class AXMUserDeviceSessionsServiceImp extends AXMUserDeviceSessionsService {
1566
1615
  this.sessionService = inject(AXPSessionService);
1567
1616
  this.entityService = inject(AXPEntityService);
1568
1617
  this.deviceSessionsDataAccessor = this.entityService
1569
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.deviceSessions.name)
1618
+ .withEntity(RootConfig.module.name, RootConfig.entities.deviceSessions.name)
1570
1619
  .data();
1571
1620
  this.deviceSessionsService = inject(AXMDeviceSessionsService);
1572
1621
  this.settingsService = inject(AXPSettingsService);
@@ -1602,7 +1651,11 @@ class AXMUserDeviceSessionsServiceImp extends AXMUserDeviceSessionsService {
1602
1651
  return mostRecentSession;
1603
1652
  }
1604
1653
  async terminateSession(sessionId) {
1605
- await this.deviceSessionsDataAccessor.update(sessionId, { status: 'revoked' });
1654
+ await this.deviceSessionsDataAccessor.update(sessionId, {
1655
+ status: 'revoked',
1656
+ loggedOutAt: new Date(),
1657
+ isActiveSession: false,
1658
+ });
1606
1659
  await this.showTerminateSuccessToast();
1607
1660
  }
1608
1661
  async terminateAllSession() {
@@ -1628,53 +1681,73 @@ class AXMUserDeviceSessionsServiceImp extends AXMUserDeviceSessionsService {
1628
1681
  timeOutProgress: true,
1629
1682
  });
1630
1683
  }
1631
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMUserDeviceSessionsServiceImp, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
1632
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMUserDeviceSessionsServiceImp }); }
1684
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserDeviceSessionsServiceImp, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
1685
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserDeviceSessionsServiceImp }); }
1633
1686
  }
1634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMUserDeviceSessionsServiceImp, decorators: [{
1687
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserDeviceSessionsServiceImp, decorators: [{
1635
1688
  type: Injectable
1636
1689
  }] });
1637
1690
 
1638
- const canActivateTenantChooser = async (route, state) => {
1691
+ //#region ----- Tenant chooser guard -----
1692
+ const canActivateTenantChooser = async (_route, _state) => {
1639
1693
  const sessionService = inject(AXPSessionService);
1640
1694
  const authStrategyRegistry = inject(AXPAuthStrategyRegistryService);
1641
1695
  const router = inject(Router);
1642
1696
  const strategyName = sessionService.getSessionData()?.strategy;
1643
1697
  const strategy = authStrategyRegistry.get(strategyName);
1644
1698
  if (!sessionService.user?.id) {
1699
+ traceAuthGuard('Tenant chooser → login (no user)');
1700
+ return router.createUrlTree(['/auth/login']);
1701
+ }
1702
+ if (!sessionService.hasSessionCredentials()) {
1703
+ traceAuthGuard('Tenant chooser → login (no credentials)');
1645
1704
  return router.createUrlTree(['/auth/login']);
1646
1705
  }
1647
- const tenants = await firstValueFrom(sessionService.tenants$);
1706
+ // Shared session cache — same ListTenants as tenants$ / chooser list.
1707
+ const tenants = await sessionService.getTenantsList();
1708
+ traceAuthGuard('Tenant chooser catalog', () => ({ count: tenants.length }));
1648
1709
  if (tenants.length === 0) {
1649
- await sessionService.signout();
1650
1710
  window.alert('You do not have any tenant assigned to your account and cannot use the site. Please contact your administrator.');
1651
- return router.createUrlTree(['/auth/login']);
1711
+ // Stay on chooser rather than return false (cancels nav and sticks on prior login URL).
1712
+ return true;
1652
1713
  }
1653
1714
  if (tenants.length === 1) {
1654
1715
  if (strategy && typeof strategy.updateToken === 'function') {
1655
- const updateContext = {
1716
+ await sessionService.updateToken({
1656
1717
  user: sessionService.user,
1657
1718
  tenant: tenants[0],
1658
- };
1659
- await sessionService.updateToken(updateContext);
1719
+ });
1720
+ traceAuthGuard('Tenant chooser auto-bound single tenant → app chooser');
1660
1721
  return router.createUrlTree(['/auth/account/app-chooser']);
1661
1722
  }
1662
- return false;
1723
+ return true;
1663
1724
  }
1664
1725
  return true;
1665
1726
  };
1727
+ //#endregion
1666
1728
 
1667
- const canActivateAppChooser = async (route, state) => {
1729
+ //#region ----- App chooser guard -----
1730
+ const canActivateAppChooser = async (_route, _state) => {
1668
1731
  const sessionService = inject(AXPSessionService);
1669
1732
  const authStrategyRegistry = inject(AXPAuthStrategyRegistryService);
1670
1733
  const homePageService = inject(AXPHomePageService);
1671
1734
  const router = inject(Router);
1672
1735
  const strategyName = sessionService.getSessionData()?.strategy;
1673
1736
  const strategy = authStrategyRegistry.get(strategyName);
1674
- const apps = await firstValueFrom(sessionService.applications$);
1737
+ if (!sessionService.tenant?.id) {
1738
+ traceAuthGuard('App chooser → tenant chooser (no tenant)');
1739
+ return router.createUrlTree(['/auth/account/tenant-chooser']);
1740
+ }
1741
+ if (!sessionService.hasSessionCredentials()) {
1742
+ traceAuthGuard('App chooser → login (no credentials)');
1743
+ return router.createUrlTree(['/auth/login']);
1744
+ }
1745
+ // Shared session cache — same ListApplications as applications$ / chooser list.
1746
+ const apps = await sessionService.getApplicationsList();
1747
+ traceAuthGuard('App chooser catalog', () => ({ count: apps.length }));
1675
1748
  if (apps.length === 0) {
1676
- await router.navigate(['/auth/login']);
1677
- return false;
1749
+ // Show the chooser empty state instead of cancelling navigation (return false sticks on login).
1750
+ return true;
1678
1751
  }
1679
1752
  if (apps.length === 1) {
1680
1753
  const tenantId = sessionService.tenant?.id;
@@ -1682,39 +1755,44 @@ const canActivateAppChooser = async (route, state) => {
1682
1755
  throw new Error('Tenant ID is missing. Please contact support.');
1683
1756
  }
1684
1757
  if (strategy && typeof strategy.updateToken === 'function') {
1685
- const updateContext = {
1758
+ await sessionService.updateToken({
1686
1759
  user: sessionService.user,
1687
1760
  tenant: sessionService.tenant,
1688
1761
  application: apps[0],
1689
- };
1690
- await sessionService.updateToken(updateContext);
1691
- return router.createUrlTree([homePageService.getCurrent().path]);
1762
+ });
1763
+ // Return UrlTree — never await router.navigate inside canActivate (deadlocks).
1764
+ traceAuthGuard('App chooser auto-bound single app → home');
1765
+ return homePageService.resolveAuthorizedHomeUrlTree();
1692
1766
  }
1693
- return false;
1767
+ return true;
1694
1768
  }
1769
+ // Stale application from a prior session must not mark the user Authorized on this screen.
1770
+ sessionService.clearApplicationSelection();
1771
+ traceAuthGuard('App chooser showing multi-app UI');
1695
1772
  return true;
1696
1773
  };
1774
+ //#endregion
1697
1775
 
1698
1776
  function routesFacory() {
1699
1777
  let routes = [];
1700
1778
  routes = [
1701
1779
  {
1702
1780
  path: 'tenant-chooser',
1703
- loadComponent: () => import('./acorex-platform-module-auth-client-tenant-chooser.component-B_9s4F36.mjs').then((c) => c.AXPAuthTenantChooserComponent),
1781
+ loadComponent: () => import('./acorex-platform-module-auth-client-tenant-chooser.component-CHmg7D5H.mjs').then((c) => c.AXPAuthTenantChooserComponent),
1704
1782
  canActivate: [AXPAuthGuard, canActivateTenantChooser],
1705
1783
  },
1706
1784
  {
1707
1785
  path: 'app-chooser',
1708
- loadComponent: () => import('./acorex-platform-module-auth-client-app-chooser.component-IPLp1kVv.mjs').then((c) => c.AXPAuthAppChooserComponent),
1786
+ loadComponent: () => import('./acorex-platform-module-auth-client-app-chooser.component-BVbu-f8h.mjs').then((c) => c.AXPAuthAppChooserComponent),
1709
1787
  canActivate: [AXPAuthGuard, canActivateAppChooser],
1710
1788
  },
1711
1789
  ];
1712
1790
  return routes;
1713
1791
  }
1714
1792
  class AXPAccountModule {
1715
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAccountModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1716
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPAccountModule, imports: [RouterModule, i1$3.AXPComponentSlotModule] }); }
1717
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAccountModule, providers: [
1793
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAccountModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1794
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXPAccountModule, imports: [RouterModule, i1$4.AXPComponentSlotModule] }); }
1795
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAccountModule, providers: [
1718
1796
  {
1719
1797
  provide: ROUTES,
1720
1798
  multi: true,
@@ -1748,7 +1826,7 @@ class AXPAccountModule {
1748
1826
  ],
1749
1827
  })] }); }
1750
1828
  }
1751
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAccountModule, decorators: [{
1829
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAccountModule, decorators: [{
1752
1830
  type: NgModule,
1753
1831
  args: [{
1754
1832
  declarations: [],
@@ -1814,18 +1892,23 @@ class AXPIdleLockService {
1814
1892
  //#region ---- Constructor ----
1815
1893
  constructor() {
1816
1894
  //#region ---- State ----
1817
- this.locked = signal(false, ...(ngDevMode ? [{ debugName: "locked" }] : /* istanbul ignore next */ []));
1818
- this.idleTimeoutMs = signal(DEFAULT_LOCK_WHEN_IDLE_MINUTES * 60_000, ...(ngDevMode ? [{ debugName: "idleTimeoutMs" }] : /* istanbul ignore next */ []));
1819
- this.enabled = signal(false, ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
1895
+ this.locked = signal(false, /* @ts-ignore */
1896
+ ...(ngDevMode ? [{ debugName: "locked" }] : /* istanbul ignore next */ []));
1897
+ this.idleTimeoutMs = signal(DEFAULT_LOCK_WHEN_IDLE_MINUTES * 60_000, /* @ts-ignore */
1898
+ ...(ngDevMode ? [{ debugName: "idleTimeoutMs" }] : /* istanbul ignore next */ []));
1899
+ this.enabled = signal(false, /* @ts-ignore */
1900
+ ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
1820
1901
  /** Whether manual or idle lock is available (Lock When Idle setting is enabled). */
1821
1902
  this.canLock = this.enabled.asReadonly();
1822
- this.storedPinCode = signal('', ...(ngDevMode ? [{ debugName: "storedPinCode" }] : /* istanbul ignore next */ []));
1903
+ this.storedPinCode = signal('', /* @ts-ignore */
1904
+ ...(ngDevMode ? [{ debugName: "storedPinCode" }] : /* istanbul ignore next */ []));
1823
1905
  this.lastActivityAt = Date.now();
1824
1906
  this.lastMouseMoveAt = 0;
1825
1907
  this.idleCheckTimerId = null;
1826
1908
  this.overlayRef = null;
1827
1909
  this.overlayOpening = false;
1828
1910
  this.enableTask = Promise.resolve();
1911
+ this.pendingLockScreenOffer = false;
1829
1912
  //#endregion
1830
1913
  //#region ---- Services & Dependencies ----
1831
1914
  this.sessionService = inject(AXPSessionService);
@@ -1848,20 +1931,18 @@ class AXPIdleLockService {
1848
1931
  this.recordActivity();
1849
1932
  };
1850
1933
  this.sessionService.status$
1851
- .pipe(filter((status) => status === AXPSessionStatus.Authenticated ||
1852
- status === AXPSessionStatus.Authorized ||
1934
+ .pipe(filter((status) => status === AXPSessionStatus.Authorized ||
1853
1935
  status === AXPSessionStatus.SignedOut ||
1854
1936
  status === AXPSessionStatus.Expired), takeUntilDestroyed(this.destroyRef))
1855
1937
  .subscribe((status) => {
1856
- const isActiveSession = status === AXPSessionStatus.Authenticated || status === AXPSessionStatus.Authorized;
1857
- if (isActiveSession) {
1938
+ if (status === AXPSessionStatus.Authorized) {
1858
1939
  void this.scheduleEnable();
1859
1940
  return;
1860
1941
  }
1861
1942
  void this.handleInactiveSession(status);
1862
1943
  });
1863
1944
  afterNextRender(() => {
1864
- if (this.sessionService.isLocked()) {
1945
+ if (this.sessionService.isLocked() && this.sessionService.isAuthorized) {
1865
1946
  void this.scheduleEnable();
1866
1947
  }
1867
1948
  }, { injector: this.injector });
@@ -1883,7 +1964,7 @@ class AXPIdleLockService {
1883
1964
  }
1884
1965
  async verifyPassword(password) {
1885
1966
  const userId = this.sessionService.user?.id;
1886
- if (isNil(userId) || isEmpty(password)) {
1967
+ if (isNil(userId) || isEmpty(password) || !this.canLoadUserSecurityFields()) {
1887
1968
  return false;
1888
1969
  }
1889
1970
  try {
@@ -1908,11 +1989,25 @@ class AXPIdleLockService {
1908
1989
  lockScreen() {
1909
1990
  this.lock();
1910
1991
  }
1992
+ /** Marks that PIN setup succeeded so the caller can offer lock-screen activation. */
1993
+ requestLockScreenOffer() {
1994
+ this.pendingLockScreenOffer = true;
1995
+ }
1996
+ /** Returns whether PIN setup requested a lock-screen offer, then clears the flag. */
1997
+ consumeLockScreenOffer() {
1998
+ const pending = this.pendingLockScreenOffer;
1999
+ this.pendingLockScreenOffer = false;
2000
+ return pending;
2001
+ }
1911
2002
  async refreshPinState() {
1912
2003
  if (!this.isOperational()) {
1913
2004
  this.storedPinCode.set('');
1914
2005
  return;
1915
2006
  }
2007
+ if (!this.canLoadUserSecurityFields()) {
2008
+ this.storedPinCode.set('');
2009
+ return;
2010
+ }
1916
2011
  const userId = this.sessionService.user?.id;
1917
2012
  if (isNil(userId)) {
1918
2013
  this.storedPinCode.set('');
@@ -1931,13 +2026,17 @@ class AXPIdleLockService {
1931
2026
  this.storedPinCode.set('');
1932
2027
  }
1933
2028
  }
2029
+ /** Refreshes lock-when-idle settings only (no User entity fetch). Used by profile menu hooks. */
2030
+ async refreshLockMenuState() {
2031
+ await this.refreshConfiguration();
2032
+ }
1934
2033
  /** Refreshes lock settings and PIN state for menu/commands. */
1935
2034
  async refreshLockState() {
1936
2035
  await this.refreshConfiguration();
1937
2036
  if (!this.isOperational()) {
1938
2037
  return;
1939
2038
  }
1940
- await this.refreshPinState();
2039
+ await this.ensurePinStateLoaded();
1941
2040
  }
1942
2041
  /** Restores the lock overlay when the persisted session is locked. */
1943
2042
  restoreFromPersistedSession() {
@@ -1953,13 +2052,26 @@ class AXPIdleLockService {
1953
2052
  return;
1954
2053
  }
1955
2054
  const status = await firstValueFrom(this.sessionService.status$);
1956
- const isActiveSession = status === AXPSessionStatus.Authenticated || status === AXPSessionStatus.Authorized;
1957
- if (isActiveSession) {
2055
+ if (status === AXPSessionStatus.Authorized) {
1958
2056
  await this.scheduleEnable();
1959
2057
  }
1960
2058
  }
1961
2059
  //#endregion
1962
2060
  //#region ---- Private Methods ----
2061
+ /** PIN/password entity reads require a fully authorized app context, except when restoring a lock overlay. */
2062
+ canLoadUserSecurityFields() {
2063
+ return this.sessionService.isReadyForAppScopedApi || this.sessionService.isLocked();
2064
+ }
2065
+ async ensurePinStateLoaded() {
2066
+ if (!this.isOperational()) {
2067
+ this.storedPinCode.set('');
2068
+ return;
2069
+ }
2070
+ if (!this.canLoadUserSecurityFields()) {
2071
+ await firstValueFrom(this.sessionService.isReadyForAppScopedApi$.pipe(filter((ready) => ready), take(1)));
2072
+ }
2073
+ await this.refreshPinState();
2074
+ }
1963
2075
  scheduleEnable() {
1964
2076
  this.enableTask = this.enableTask.then(() => this.runEnable());
1965
2077
  return this.enableTask;
@@ -1967,7 +2079,7 @@ class AXPIdleLockService {
1967
2079
  async runEnable() {
1968
2080
  await this.refreshConfiguration();
1969
2081
  if (this.sessionService.isLocked()) {
1970
- await this.refreshPinState();
2082
+ await this.ensurePinStateLoaded();
1971
2083
  this.restoreLockedSession();
1972
2084
  return;
1973
2085
  }
@@ -1975,7 +2087,7 @@ class AXPIdleLockService {
1975
2087
  this.disable(false);
1976
2088
  return;
1977
2089
  }
1978
- await this.refreshPinState();
2090
+ await this.ensurePinStateLoaded();
1979
2091
  this.resetUnlockedRuntimeState();
1980
2092
  this.attachActivityListeners();
1981
2093
  this.startIdleCheck();
@@ -2026,8 +2138,7 @@ class AXPIdleLockService {
2026
2138
  }
2027
2139
  async applyLockWhenIdleSettingChange() {
2028
2140
  const status = await firstValueFrom(this.sessionService.status$);
2029
- const isActiveSession = status === AXPSessionStatus.Authenticated || status === AXPSessionStatus.Authorized;
2030
- if (!isActiveSession) {
2141
+ if (status !== AXPSessionStatus.Authorized) {
2031
2142
  return;
2032
2143
  }
2033
2144
  await this.scheduleEnable();
@@ -2064,7 +2175,7 @@ class AXPIdleLockService {
2064
2175
  this.overlayOpening = true;
2065
2176
  this.locked.set(true);
2066
2177
  try {
2067
- const { AXMSessionLockOverlayComponent: overlayComponent } = await import('./acorex-platform-module-auth-client-session-lock-overlay.component-CN1JqPBW.mjs');
2178
+ const { AXMSessionLockOverlayComponent: overlayComponent } = await import('./acorex-platform-module-auth-client-session-lock-overlay.component-BhsTAmVe.mjs');
2068
2179
  const panelClasses = ['axm-session-lock-overlay-shell'];
2069
2180
  if (this.platform.isDark()) {
2070
2181
  panelClasses.push('ax-dark');
@@ -2138,10 +2249,10 @@ class AXPIdleLockService {
2138
2249
  events.forEach((eventName) => document.removeEventListener(eventName, this.onActivity, true));
2139
2250
  document.removeEventListener('mousemove', this.onMouseMove, true);
2140
2251
  }
2141
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIdleLockService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2142
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIdleLockService, providedIn: 'root' }); }
2252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPIdleLockService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2253
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPIdleLockService, providedIn: 'root' }); }
2143
2254
  }
2144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIdleLockService, decorators: [{
2255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPIdleLockService, decorators: [{
2145
2256
  type: Injectable,
2146
2257
  args: [{ providedIn: 'root' }]
2147
2258
  }], ctorParameters: () => [] });
@@ -2152,12 +2263,27 @@ class AXPLogoEntitySyncService {
2152
2263
  constructor() {
2153
2264
  this.session = inject(AXPSessionService);
2154
2265
  this.logoRegistration = inject(AXPEntityLogoRegistrationService);
2266
+ this.destroyRef = inject(DestroyRef);
2267
+ this.syncGeneration = 0;
2155
2268
  combineLatest([this.session.isAuthorized$, this.session.tenant$])
2156
- .pipe(filter(([authorized]) => authorized), switchMap(() => from(this.syncEntityLogos())))
2269
+ .pipe(distinctUntilChanged(([authorized, tenant], [previousAuthorized, previousTenant]) => authorized === previousAuthorized && tenant?.id === previousTenant?.id), switchMap(([authorized, tenant]) => {
2270
+ if (!authorized || !tenant?.id || !this.session.getToken()) {
2271
+ this.syncGeneration++;
2272
+ return EMPTY;
2273
+ }
2274
+ const generation = this.syncGeneration;
2275
+ return from(this.syncEntityLogos(generation));
2276
+ }), takeUntilDestroyed(this.destroyRef))
2157
2277
  .subscribe();
2158
2278
  }
2159
- async syncEntityLogos() {
2279
+ async syncEntityLogos(generation) {
2280
+ if (!this.canSyncLogos() || generation !== this.syncGeneration) {
2281
+ return;
2282
+ }
2160
2283
  const tenants = await firstValueFrom(this.session.tenants$);
2284
+ if (generation !== this.syncGeneration || !this.canSyncLogos()) {
2285
+ return;
2286
+ }
2161
2287
  this.logoRegistration.registerTenants(tenants.map((tenant) => ({
2162
2288
  id: tenant.id,
2163
2289
  title: tenant.title,
@@ -2167,16 +2293,22 @@ class AXPLogoEntitySyncService {
2167
2293
  return;
2168
2294
  }
2169
2295
  const applications = await firstValueFrom(this.session.applications$);
2296
+ if (generation !== this.syncGeneration || !this.canSyncLogos()) {
2297
+ return;
2298
+ }
2170
2299
  this.logoRegistration.registerApplications(applications.map((application) => ({
2171
2300
  id: application.id,
2172
2301
  title: application.title,
2173
2302
  logoUrl: application.logoUrl,
2174
2303
  })));
2175
2304
  }
2176
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLogoEntitySyncService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2177
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLogoEntitySyncService, providedIn: 'root' }); }
2305
+ canSyncLogos() {
2306
+ return this.session.isAuthorized && !!this.session.getToken() && !!this.session.tenant?.id;
2307
+ }
2308
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLogoEntitySyncService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2309
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLogoEntitySyncService, providedIn: 'root' }); }
2178
2310
  }
2179
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLogoEntitySyncService, decorators: [{
2311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLogoEntitySyncService, decorators: [{
2180
2312
  type: Injectable,
2181
2313
  args: [{ providedIn: 'root' }]
2182
2314
  }], ctorParameters: () => [] });
@@ -2240,10 +2372,8 @@ const CoreProfileGroupsHookProvider = {
2240
2372
  const CoreProfileSectionsHookProvider = {
2241
2373
  key: PROFILE_PAGE_SECTIONS_HOOK,
2242
2374
  priority: 0,
2243
- execute: (payload) => ({
2244
- ...payload,
2245
- sections: [
2246
- ...payload.sections,
2375
+ execute: (payload) => {
2376
+ const contributed = [
2247
2377
  {
2248
2378
  id: 'basic-info',
2249
2379
  groupId: 'account',
@@ -2274,7 +2404,7 @@ const CoreProfileSectionsHookProvider = {
2274
2404
  name: 'change-profile-photo',
2275
2405
  title: '@auth:profile-page.sections.profile-photo.actions.manage',
2276
2406
  icon: 'far fa-pen',
2277
- command: { name: AXMAuthCommandKeys.Profile.ChangePhoto, options: { mode: 'manage' } },
2407
+ command: { name: AXMAuthCommandKeys.Profile.ChangePhoto },
2278
2408
  },
2279
2409
  ],
2280
2410
  },
@@ -2365,23 +2495,33 @@ const CoreProfileSectionsHookProvider = {
2365
2495
  },
2366
2496
  layout: { colSpan: 12 },
2367
2497
  },
2368
- ],
2369
- }),
2498
+ ];
2499
+ const matching = payload.groupId
2500
+ ? contributed.filter((section) => section.groupId === payload.groupId)
2501
+ : contributed;
2502
+ return {
2503
+ ...payload,
2504
+ sections: [...payload.sections, ...matching],
2505
+ };
2506
+ },
2370
2507
  };
2371
2508
  //#endregion
2372
2509
 
2373
2510
  //#region ---- Security PIN section hook ----
2374
- const SECURITY_PIN_SECTION_ID = 'security-pin';
2511
+ const SECURITY_PIN_SECTION_ID$1 = 'security-pin';
2375
2512
  /** Enriches the security PIN section with change/remove actions when a PIN exists. */
2376
2513
  const SecurityPinSectionHookProvider = {
2377
2514
  key: PROFILE_PAGE_SECTIONS_HOOK,
2378
2515
  priority: 10,
2379
2516
  execute: async (payload) => {
2517
+ if (!isUserProfileSectionsGroupRequested(payload, 'security')) {
2518
+ return payload;
2519
+ }
2380
2520
  const hasPinCode = await loadHasPinCode();
2381
2521
  return {
2382
2522
  ...payload,
2383
2523
  sections: payload.sections.map((section) => {
2384
- if (section.id !== SECURITY_PIN_SECTION_ID) {
2524
+ if (section.id !== SECURITY_PIN_SECTION_ID$1) {
2385
2525
  return section;
2386
2526
  }
2387
2527
  return {
@@ -2422,7 +2562,7 @@ async function loadHasPinCode() {
2422
2562
  }
2423
2563
  try {
2424
2564
  const user = await entityService
2425
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.users.name)
2565
+ .withEntity(RootConfig.module.name, RootConfig.entities.users.name)
2426
2566
  .data()
2427
2567
  .byKey(userId);
2428
2568
  return !isEmpty(defaultTo(get(user, 'pinCode'), ''));
@@ -2468,16 +2608,34 @@ class AXPAuthPasswordChangeTrackingService {
2468
2608
  buildStorageKey(userId) {
2469
2609
  return `${STORAGE_KEY_PREFIX}${userId}`;
2470
2610
  }
2471
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2472
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, providedIn: 'root' }); }
2611
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2612
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, providedIn: 'root' }); }
2473
2613
  }
2474
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, decorators: [{
2614
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthPasswordChangeTrackingService, decorators: [{
2475
2615
  type: Injectable,
2476
2616
  args: [{ providedIn: 'root' }]
2477
2617
  }] });
2478
2618
 
2479
- //#region ---- Section ids ----
2619
+ //#region ----- Constants -----
2480
2620
  const CHANGE_PASSWORD_SECTION_ID = 'change-password';
2621
+ const PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY = 'profileSectionInsightsPatch';
2622
+ //#endregion
2623
+ //#region ----- Password insight -----
2624
+ /** Builds the last-changed insight shown on the Change Password profile card. */
2625
+ function buildPasswordLastChangedInsights(lastChangedAt) {
2626
+ return [
2627
+ {
2628
+ id: 'last-password-change',
2629
+ icon: 'fa-light fa-fw fa-clock',
2630
+ date: lastChangedAt,
2631
+ datePrefix: '@auth:profile-page.sections.change-password.insights.last-changed',
2632
+ },
2633
+ ];
2634
+ }
2635
+ //#endregion
2636
+
2637
+ //#region ---- Section ids ----
2638
+ const SECURITY_PIN_SECTION_ID = 'security-pin';
2481
2639
  const ACTIVE_SESSIONS_SECTION_ID = 'active-sessions';
2482
2640
  const LOGIN_HISTORY_SECTION_ID = 'login-history';
2483
2641
  //#endregion
@@ -2498,12 +2656,19 @@ class AXPUserProfileSecurityInsightsService {
2498
2656
  if (!userId) {
2499
2657
  return {};
2500
2658
  }
2501
- const sessions = await this.loadUserSessions(userId);
2659
+ const [sessions, user] = await Promise.all([
2660
+ this.loadUserSessions(userId),
2661
+ this.loadCurrentUser(userId),
2662
+ ]);
2502
2663
  const insightsBySectionId = {};
2503
- const passwordInsights = this.buildPasswordInsights(userId);
2664
+ const passwordInsights = this.buildPasswordInsights(userId, user);
2504
2665
  if (!isEmpty(passwordInsights)) {
2505
2666
  insightsBySectionId[CHANGE_PASSWORD_SECTION_ID] = passwordInsights;
2506
2667
  }
2668
+ const pinInsights = this.buildPinInsights(user);
2669
+ if (!isEmpty(pinInsights)) {
2670
+ insightsBySectionId[SECURITY_PIN_SECTION_ID] = pinInsights;
2671
+ }
2507
2672
  const activeSessionInsights = await this.buildActiveSessionInsights(sessions);
2508
2673
  if (!isEmpty(activeSessionInsights)) {
2509
2674
  insightsBySectionId[ACTIVE_SESSIONS_SECTION_ID] = activeSessionInsights;
@@ -2516,17 +2681,40 @@ class AXPUserProfileSecurityInsightsService {
2516
2681
  }
2517
2682
  //#endregion
2518
2683
  //#region ---- Insight builders ----
2519
- buildPasswordInsights(userId) {
2520
- const lastChangedAt = this.passwordChangeTrackingService.getLastChangedAt(userId);
2521
- if (isNil(lastChangedAt)) {
2522
- return [];
2684
+ buildPasswordInsights(userId, user) {
2685
+ const lastChangedAt = this.parseValidDate(user?.passwordChangedAt) ??
2686
+ this.passwordChangeTrackingService.getLastChangedAt(userId);
2687
+ if (lastChangedAt) {
2688
+ return buildPasswordLastChangedInsights(lastChangedAt);
2523
2689
  }
2524
2690
  return [
2525
2691
  {
2526
2692
  id: 'last-password-change',
2527
2693
  icon: 'fa-light fa-fw fa-clock',
2528
- date: lastChangedAt,
2529
- datePrefix: '@auth:profile-page.sections.change-password.insights.last-changed',
2694
+ text: '@auth:profile-page.sections.change-password.insights.never-changed',
2695
+ },
2696
+ ];
2697
+ }
2698
+ buildPinInsights(user) {
2699
+ const lastChangedAt = this.parseValidDate(user?.pinChangedAt);
2700
+ if (lastChangedAt) {
2701
+ return [
2702
+ {
2703
+ id: 'last-pin-change',
2704
+ icon: 'fa-light fa-fw fa-clock',
2705
+ date: lastChangedAt,
2706
+ datePrefix: '@auth:profile-page.sections.security-pin.insights.last-changed',
2707
+ },
2708
+ ];
2709
+ }
2710
+ const hasPin = !isEmpty(defaultTo(get(user, 'pinCode'), ''));
2711
+ return [
2712
+ {
2713
+ id: 'last-pin-change',
2714
+ icon: 'fa-light fa-fw fa-clock',
2715
+ text: hasPin
2716
+ ? '@auth:profile-page.sections.security-pin.insights.never-changed'
2717
+ : '@auth:profile-page.sections.security-pin.insights.not-set',
2530
2718
  },
2531
2719
  ];
2532
2720
  }
@@ -2585,9 +2773,21 @@ class AXPUserProfileSecurityInsightsService {
2585
2773
  }
2586
2774
  //#endregion
2587
2775
  //#region ---- Data loading ----
2776
+ async loadCurrentUser(userId) {
2777
+ try {
2778
+ return await this.entityService
2779
+ .withEntity(RootConfig.module.name, RootConfig.entities.users.name)
2780
+ .data()
2781
+ .byKey(userId);
2782
+ }
2783
+ catch (error) {
2784
+ console.error('Failed to load user for profile security insights', error);
2785
+ return null;
2786
+ }
2787
+ }
2588
2788
  async loadUserSessions(userId) {
2589
2789
  const response = await this.entityService
2590
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.deviceSessions.name)
2790
+ .withEntity(RootConfig.module.name, RootConfig.entities.deviceSessions.name)
2591
2791
  .data()
2592
2792
  .query({ skip: 0, take: 1000 });
2593
2793
  return (response.items ?? []).filter((item) => item.userId === userId);
@@ -2616,20 +2816,23 @@ class AXPUserProfileSecurityInsightsService {
2616
2816
  .filter(Boolean);
2617
2817
  return parts.join(' · ');
2618
2818
  }
2619
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserProfileSecurityInsightsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2620
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserProfileSecurityInsightsService, providedIn: 'root' }); }
2819
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserProfileSecurityInsightsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2820
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserProfileSecurityInsightsService, providedIn: 'root' }); }
2621
2821
  }
2622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPUserProfileSecurityInsightsService, decorators: [{
2822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserProfileSecurityInsightsService, decorators: [{
2623
2823
  type: Injectable,
2624
2824
  args: [{ providedIn: 'root' }]
2625
2825
  }] });
2626
2826
 
2627
2827
  //#region ---- Security sections insights hook ----
2628
- /** Adds live security context (sessions, login, password) to profile section cards. */
2828
+ /** Adds live security context (sessions, login, password, PIN) to profile section cards. */
2629
2829
  const SecuritySectionsInsightsHookProvider = {
2630
2830
  key: PROFILE_PAGE_SECTIONS_HOOK,
2631
2831
  priority: 15,
2632
2832
  execute: async (payload) => {
2833
+ if (!isUserProfileSectionsGroupRequested(payload, 'security')) {
2834
+ return payload;
2835
+ }
2633
2836
  const insightsService = inject(AXPUserProfileSecurityInsightsService);
2634
2837
  const insightsBySectionId = await insightsService.loadBySectionId();
2635
2838
  return {
@@ -2694,7 +2897,7 @@ const ProfileSlotMyProfileMenuHookProvider = {
2694
2897
  command: {
2695
2898
  name: 'navigate',
2696
2899
  options: {
2697
- path: `/${appName}/profile/account`,
2900
+ path: `/${appName}/profile`,
2698
2901
  },
2699
2902
  },
2700
2903
  },
@@ -2711,7 +2914,7 @@ const ProfileSlotLockMenuHookProvider = {
2711
2914
  priority: 50,
2712
2915
  execute: async (payload) => {
2713
2916
  const idleLockService = inject(AXPIdleLockService);
2714
- await idleLockService.refreshLockState();
2917
+ await idleLockService.refreshLockMenuState();
2715
2918
  if (!idleLockService.canLock()) {
2716
2919
  return payload;
2717
2920
  }
@@ -2733,69 +2936,42 @@ const ProfileSlotLockMenuHookProvider = {
2733
2936
  };
2734
2937
  //#endregion
2735
2938
 
2736
- //#region ---- User avatar client middleware ----
2737
- const USER_ENTITY = `${RootConfig$1.module.name}.${RootConfig$1.entities.users.name}`;
2738
- const PERSON_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.person.name}`;
2739
- function collectUserRows(result) {
2740
- if (Array.isArray(result)) {
2741
- return result;
2742
- }
2743
- if (result && typeof result === 'object' && Array.isArray(result.items)) {
2744
- return result.items ?? [];
2745
- }
2746
- if (result && typeof result === 'object') {
2747
- return [result];
2748
- }
2749
- return [];
2750
- }
2751
- async function loadPersonImagesByUserIds(ctx, userIds) {
2752
- const imageByUserId = new Map();
2753
- if (!userIds.length) {
2754
- return imageByUserId;
2755
- }
2756
- try {
2757
- const response = await ctx.backend.query(PERSON_ENTITY, {
2758
- skip: 0,
2759
- take: userIds.length,
2760
- filter: { field: 'userId', operator: { type: 'in' }, value: userIds },
2761
- });
2762
- for (const item of response?.items ?? []) {
2763
- const person = item;
2764
- const userId = get(person, 'userId');
2765
- const image = normalizeAvatarRef(person['image']);
2766
- if (userId != null && image) {
2767
- imageByUserId.set(String(userId), image);
2768
- }
2769
- }
2770
- }
2771
- catch {
2772
- /* ignore hydration failures */
2773
- }
2774
- return imageByUserId;
2775
- }
2776
- /** Hydrates User.avatar from linked Person.image on read. */
2777
- const userAvatarHydrateMiddleware = {
2778
- target: { ops: ['getOne', 'getAll', 'query'], order: 13 },
2779
- execute: async (ctx, next) => {
2780
- await next();
2781
- if (ctx.entityName !== USER_ENTITY) {
2782
- return;
2783
- }
2784
- const rows = collectUserRows(ctx.result);
2785
- const userIds = Array.from(new Set(rows.map((row) => get(row, 'id')).filter((id) => id != null).map(String)));
2786
- const imageByUserId = await loadPersonImagesByUserIds(ctx, userIds);
2787
- for (const row of rows) {
2788
- const userId = get(row, 'id');
2789
- if (userId == null) {
2790
- continue;
2791
- }
2792
- const personImage = imageByUserId.get(String(userId));
2793
- if (personImage) {
2794
- row['avatar'] = personImage;
2795
- }
2796
- }
2797
- },
2939
+ //#region ---- Profile slot presence menu hook ----
2940
+ /** Registers Available / Away / Busy entries in the profile dropdown. */
2941
+ const ProfileSlotPresenceMenuHookProvider = {
2942
+ key: PROFILE_SLOT_MENU_ITEMS_HOOK,
2943
+ priority: 40,
2944
+ execute: (payload) => ({
2945
+ ...payload,
2946
+ items: [
2947
+ ...payload.items,
2948
+ {
2949
+ name: 'presence-available',
2950
+ title: '@auth:profile.presence-available',
2951
+ icon: 'fa-solid fa-circle text-success',
2952
+ break: { before: true },
2953
+ command: { name: PRESENCE_SET_AVAILABILITY, options: { status: 'online' } },
2954
+ },
2955
+ {
2956
+ name: 'presence-away',
2957
+ title: '@auth:profile.presence-away',
2958
+ icon: 'fa-solid fa-circle text-warning',
2959
+ command: { name: PRESENCE_SET_AVAILABILITY, options: { status: 'away' } },
2960
+ },
2961
+ {
2962
+ name: 'presence-busy',
2963
+ title: '@auth:profile.presence-busy',
2964
+ icon: 'fa-solid fa-circle text-danger',
2965
+ break: { after: true },
2966
+ command: { name: PRESENCE_SET_AVAILABILITY, options: { status: 'busy' } },
2967
+ },
2968
+ ],
2969
+ }),
2798
2970
  };
2971
+ //#endregion
2972
+
2973
+ //#region ---- User avatar client middleware ----
2974
+ const USER_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.users.name}`;
2799
2975
  /** Refreshes avatar cache/session after user detail saves avatar. */
2800
2976
  const userAvatarCacheRefreshMiddleware = {
2801
2977
  target: { ops: ['update'], order: 95 },
@@ -2822,6 +2998,7 @@ const userAvatarCacheRefreshMiddleware = {
2822
2998
  //#endregion
2823
2999
 
2824
3000
  function profileRoutesFactory() {
3001
+ const loadProfilePage = () => import('./acorex-platform-module-auth-client-profile-page.component-CdxseoJX.mjs').then((c) => c.AXMUserProfilePageComponent);
2825
3002
  return [
2826
3003
  {
2827
3004
  path: ':app/profile',
@@ -2831,12 +3008,12 @@ function profileRoutesFactory() {
2831
3008
  children: [
2832
3009
  {
2833
3010
  path: '',
2834
- redirectTo: 'account',
2835
- pathMatch: 'full',
3011
+ loadComponent: loadProfilePage,
3012
+ data: { reuse: true },
2836
3013
  },
2837
3014
  {
2838
3015
  path: ':groupId',
2839
- loadComponent: () => import('./acorex-platform-module-auth-client-profile-page.component-CJ9AA3ZN.mjs').then((c) => c.AXMUserProfilePageComponent),
3016
+ loadComponent: loadProfilePage,
2840
3017
  data: { reuse: true },
2841
3018
  },
2842
3019
  ],
@@ -2848,35 +3025,107 @@ class AXMAuthModule {
2848
3025
  inject(AXPIdleLockService);
2849
3026
  inject(AXPLogoEntitySyncService);
2850
3027
  }
2851
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2852
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthModule, imports: [CommonModule, i1$4.AXPCommonModule, i1$5.RouterModule, AXPAccountModule,
3028
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3029
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthModule, imports: [CommonModule, i1$5.AXPCommonModule, i1$6.RouterModule, AXPAccountModule,
2853
3030
  AXMAuthValidationRulesModule] }); }
2854
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthModule, providers: [
2855
- provideAppInitializer(() => {
3031
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthModule, providers: [
3032
+ provideAppStartUpTask(() => {
2856
3033
  const sessionService = inject(AXPSessionService);
2857
3034
  const idleLockService = inject(AXPIdleLockService);
2858
- return (async () => {
2859
- await firstValueFrom(sessionService.isLoading$.pipe(filter((loading) => !loading)));
2860
- if (sessionService.isLocked()) {
2861
- await idleLockService.restoreFromPersistedSession();
2862
- }
2863
- })();
3035
+ return {
3036
+ name: 'idle-lock-restore',
3037
+ priority: AXP_APP_STARTUP_PRIORITY.idleLockRestore,
3038
+ run: async () => {
3039
+ await firstValueFrom(sessionService.isLoading$.pipe(filter((loading) => !loading)));
3040
+ if (sessionService.isLocked() && sessionService.isAuthorized) {
3041
+ await idleLockService.restoreFromPersistedSession();
3042
+ }
3043
+ },
3044
+ };
3045
+ }),
3046
+ provideAppStartUpTask(() => {
3047
+ const loadState = inject(AXPPlatformSettingsLoadState);
3048
+ const offlineBootstrap = inject(AXPPlatformSettingsOfflineBootstrapService);
3049
+ const router = inject(Router);
3050
+ const location = inject(Location);
3051
+ const appRef = inject(ApplicationRef);
3052
+ return {
3053
+ name: 'platform-settings-failure-redirect',
3054
+ priority: AXP_APP_STARTUP_PRIORITY.platformSettingsFailureRedirect,
3055
+ run: async () => {
3056
+ if (!loadState.hasFailure() && !loadState.hasPendingOfflineContinue()) {
3057
+ return;
3058
+ }
3059
+ const goUnavailable = () => {
3060
+ if (!loadState.hasFailure()) {
3061
+ return;
3062
+ }
3063
+ if (router.url.startsWith('/auth/unavailable')) {
3064
+ return;
3065
+ }
3066
+ void router.navigateByUrl('/auth/unavailable', { replaceUrl: true });
3067
+ };
3068
+ const whenStable = () => firstValueFrom(appRef.isStable.pipe(filter((stable) => stable), take(1), timeout({ first: 10_000 }))).catch(() => undefined);
3069
+ // Never await router.navigate during APP_INITIALIZER — it does not resolve and freezes splash.
3070
+ if (loadState.hasFailure()) {
3071
+ location.replaceState('/auth/unavailable');
3072
+ const navGuard = router.events
3073
+ .pipe(filter((event) => event instanceof NavigationStart))
3074
+ .subscribe((event) => {
3075
+ if (!loadState.hasFailure()) {
3076
+ navGuard.unsubscribe();
3077
+ return;
3078
+ }
3079
+ if (!event.url.startsWith('/auth/unavailable')) {
3080
+ goUnavailable();
3081
+ }
3082
+ });
3083
+ queueMicrotask(goUnavailable);
3084
+ void whenStable().then(() => {
3085
+ navGuard.unsubscribe();
3086
+ goUnavailable();
3087
+ });
3088
+ return;
3089
+ }
3090
+ // Offline confirm needs the root ViewContainerRef — confirmAndContinueOffline waits for that
3091
+ // (not full isStable, which delays the dialog while the zone stays busy).
3092
+ queueMicrotask(() => {
3093
+ void (async () => {
3094
+ if (!loadState.hasPendingOfflineContinue()) {
3095
+ return;
3096
+ }
3097
+ let continued = false;
3098
+ try {
3099
+ continued = await offlineBootstrap.confirmAndContinueOffline();
3100
+ }
3101
+ catch (error) {
3102
+ console.error('Offline continue confirm failed', error);
3103
+ }
3104
+ if (!continued) {
3105
+ loadState.setFailure(loadState.consumePendingBootstrapError() ?? 'Platform settings unavailable');
3106
+ location.replaceState('/auth/unavailable');
3107
+ goUnavailable();
3108
+ }
3109
+ })();
3110
+ });
3111
+ },
3112
+ };
2864
3113
  }),
2865
3114
  AXMAuthErrorHandler,
2866
3115
  provideLazyProvider(AXP_MENU_PROVIDER, () => import('./acorex-platform-module-auth-client-menu.provider-Bz-kRip4.mjs').then(m => m.AXMSecurityManagementModuleMenuProvider)),
2867
- provideLazyProvider(AXP_SETTING_DEFINITION_PROVIDER, () => import('./acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs').then(m => m.AXMSettingProvider)),
2868
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs').then((module) => module.AXMProfilePageComponentProvider)),
2869
- provideLazyProvider(AXP_DATASOURCE_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return datasource_provider; }).then((m) => m.AXMAuthDataSourceProvider)),
3116
+ provideLazyProvider(AXP_SETTING_DEFINITION_PROVIDER, () => import('./acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs').then(m => m.AXMSettingProvider)),
3117
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs').then((module) => module.AXMProfilePageComponentProvider)),
3118
+ provideQuerySetups([
3119
+ {
3120
+ key: 'Auth:GetUserActivity',
3121
+ loader: () => import('./acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs').then((c) => c.AXMGetUserActivityQuery),
3122
+ },
3123
+ ]),
2870
3124
  {
2871
3125
  provide: ROUTES,
2872
3126
  multi: true,
2873
3127
  useFactory: profileRoutesFactory,
2874
3128
  },
2875
- {
2876
- provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
2877
- multi: true,
2878
- useValue: userAvatarHydrateMiddleware,
2879
- },
2880
3129
  {
2881
3130
  provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
2882
3131
  multi: true,
@@ -2885,51 +3134,51 @@ class AXMAuthModule {
2885
3134
  provideCommandSetups([
2886
3135
  {
2887
3136
  key: AXMAuthCommandKeys.Profile.Show,
2888
- command: () => import('./acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs').then((c) => c.AXPShowProfileCommand),
3137
+ command: () => import('./acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs').then((c) => c.AXPShowProfileCommand),
2889
3138
  },
2890
3139
  {
2891
3140
  key: AXMAuthCommandKeys.Session.Signout,
2892
- command: () => import('./acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs').then((c) => c.AXPSignoutCommand),
3141
+ command: () => import('./acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs').then((c) => c.AXPSignoutCommand),
2893
3142
  },
2894
3143
  {
2895
3144
  key: AXMAuthCommandKeys.Session.OpenSessions,
2896
- command: () => import('./acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs').then((c) => c.AXPOpenSessionsCommand),
3145
+ command: () => import('./acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs').then((c) => c.AXPOpenSessionsCommand),
2897
3146
  },
2898
3147
  {
2899
3148
  key: AXMAuthCommandKeys.Session.LockScreen,
2900
- command: () => import('./acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs').then((c) => c.AXPLockScreenCommand),
3149
+ command: () => import('./acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs').then((c) => c.AXPLockScreenCommand),
2901
3150
  },
2902
3151
  {
2903
3152
  key: AXMAuthCommandKeys.Profile.ChangePhoto,
2904
- command: () => import('./acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs').then((c) => c.AXPChangePhotoCommand),
3153
+ command: () => import('./acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs').then((c) => c.AXPChangePhotoCommand),
2905
3154
  },
2906
3155
  {
2907
3156
  key: AXMAuthCommandKeys.Profile.EditAccountInfo,
2908
- command: () => import('./acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs').then((c) => c.AXPEditAccountInfoCommand),
3157
+ command: () => import('./acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs').then((c) => c.AXPEditAccountInfoCommand),
2909
3158
  },
2910
3159
  {
2911
3160
  key: AXMAuthCommandKeys.Security.ChangePassword,
2912
- command: () => import('./acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs').then((c) => c.AXPChangePasswordCommand),
3161
+ command: () => import('./acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs').then((c) => c.AXPChangePasswordCommand),
2913
3162
  },
2914
3163
  {
2915
3164
  key: AXMAuthCommandKeys.Security.SetPinCode,
2916
- command: () => import('./acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs').then((c) => c.AXPSetPinCodeCommand),
3165
+ command: () => import('./acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs').then((c) => c.AXPSetPinCodeCommand),
2917
3166
  },
2918
3167
  {
2919
3168
  key: AXMAuthCommandKeys.Security.RemovePinCode,
2920
- command: () => import('./acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs').then((c) => c.AXPRemovePinCodeCommand),
3169
+ command: () => import('./acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs').then((c) => c.AXPRemovePinCodeCommand),
2921
3170
  },
2922
3171
  {
2923
3172
  key: AXMAuthCommandKeys.Security.ViewLoginHistory,
2924
- command: () => import('./acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs').then((c) => c.AXPViewLoginHistoryCommand),
3173
+ command: () => import('./acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs').then((c) => c.AXPViewLoginHistoryCommand),
2925
3174
  },
2926
3175
  {
2927
3176
  key: AXMAuthCommandKeys.Security.EditSignature,
2928
- command: () => import('./acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs').then((c) => c.AXPEditSignatureCommand),
3177
+ command: () => import('./acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs').then((c) => c.AXPEditSignatureCommand),
2929
3178
  },
2930
3179
  {
2931
3180
  key: AXMAuthCommandKeys.Profile.ComingSoon,
2932
- command: () => import('./acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs').then((c) => c.AXPProfileComingSoonCommand),
3181
+ command: () => import('./acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs').then((c) => c.AXPProfileComingSoonCommand),
2933
3182
  },
2934
3183
  ]),
2935
3184
  {
@@ -2947,6 +3196,11 @@ class AXMAuthModule {
2947
3196
  useValue: ProfileSlotLockMenuHookProvider,
2948
3197
  multi: true,
2949
3198
  },
3199
+ {
3200
+ provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
3201
+ useValue: ProfileSlotPresenceMenuHookProvider,
3202
+ multi: true,
3203
+ },
2950
3204
  {
2951
3205
  provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
2952
3206
  useValue: CoreProfileGroupsHookProvider,
@@ -2973,7 +3227,7 @@ class AXMAuthModule {
2973
3227
  AXPAccountModule,
2974
3228
  AXMAuthValidationRulesModule] }); }
2975
3229
  }
2976
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAuthModule, decorators: [{
3230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAuthModule, decorators: [{
2977
3231
  type: NgModule,
2978
3232
  args: [{
2979
3233
  imports: [
@@ -2984,31 +3238,103 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2984
3238
  AXMAuthValidationRulesModule,
2985
3239
  ],
2986
3240
  providers: [
2987
- provideAppInitializer(() => {
3241
+ provideAppStartUpTask(() => {
2988
3242
  const sessionService = inject(AXPSessionService);
2989
3243
  const idleLockService = inject(AXPIdleLockService);
2990
- return (async () => {
2991
- await firstValueFrom(sessionService.isLoading$.pipe(filter((loading) => !loading)));
2992
- if (sessionService.isLocked()) {
2993
- await idleLockService.restoreFromPersistedSession();
2994
- }
2995
- })();
3244
+ return {
3245
+ name: 'idle-lock-restore',
3246
+ priority: AXP_APP_STARTUP_PRIORITY.idleLockRestore,
3247
+ run: async () => {
3248
+ await firstValueFrom(sessionService.isLoading$.pipe(filter((loading) => !loading)));
3249
+ if (sessionService.isLocked() && sessionService.isAuthorized) {
3250
+ await idleLockService.restoreFromPersistedSession();
3251
+ }
3252
+ },
3253
+ };
3254
+ }),
3255
+ provideAppStartUpTask(() => {
3256
+ const loadState = inject(AXPPlatformSettingsLoadState);
3257
+ const offlineBootstrap = inject(AXPPlatformSettingsOfflineBootstrapService);
3258
+ const router = inject(Router);
3259
+ const location = inject(Location);
3260
+ const appRef = inject(ApplicationRef);
3261
+ return {
3262
+ name: 'platform-settings-failure-redirect',
3263
+ priority: AXP_APP_STARTUP_PRIORITY.platformSettingsFailureRedirect,
3264
+ run: async () => {
3265
+ if (!loadState.hasFailure() && !loadState.hasPendingOfflineContinue()) {
3266
+ return;
3267
+ }
3268
+ const goUnavailable = () => {
3269
+ if (!loadState.hasFailure()) {
3270
+ return;
3271
+ }
3272
+ if (router.url.startsWith('/auth/unavailable')) {
3273
+ return;
3274
+ }
3275
+ void router.navigateByUrl('/auth/unavailable', { replaceUrl: true });
3276
+ };
3277
+ const whenStable = () => firstValueFrom(appRef.isStable.pipe(filter((stable) => stable), take(1), timeout({ first: 10_000 }))).catch(() => undefined);
3278
+ // Never await router.navigate during APP_INITIALIZER — it does not resolve and freezes splash.
3279
+ if (loadState.hasFailure()) {
3280
+ location.replaceState('/auth/unavailable');
3281
+ const navGuard = router.events
3282
+ .pipe(filter((event) => event instanceof NavigationStart))
3283
+ .subscribe((event) => {
3284
+ if (!loadState.hasFailure()) {
3285
+ navGuard.unsubscribe();
3286
+ return;
3287
+ }
3288
+ if (!event.url.startsWith('/auth/unavailable')) {
3289
+ goUnavailable();
3290
+ }
3291
+ });
3292
+ queueMicrotask(goUnavailable);
3293
+ void whenStable().then(() => {
3294
+ navGuard.unsubscribe();
3295
+ goUnavailable();
3296
+ });
3297
+ return;
3298
+ }
3299
+ // Offline confirm needs the root ViewContainerRef — confirmAndContinueOffline waits for that
3300
+ // (not full isStable, which delays the dialog while the zone stays busy).
3301
+ queueMicrotask(() => {
3302
+ void (async () => {
3303
+ if (!loadState.hasPendingOfflineContinue()) {
3304
+ return;
3305
+ }
3306
+ let continued = false;
3307
+ try {
3308
+ continued = await offlineBootstrap.confirmAndContinueOffline();
3309
+ }
3310
+ catch (error) {
3311
+ console.error('Offline continue confirm failed', error);
3312
+ }
3313
+ if (!continued) {
3314
+ loadState.setFailure(loadState.consumePendingBootstrapError() ?? 'Platform settings unavailable');
3315
+ location.replaceState('/auth/unavailable');
3316
+ goUnavailable();
3317
+ }
3318
+ })();
3319
+ });
3320
+ },
3321
+ };
2996
3322
  }),
2997
3323
  AXMAuthErrorHandler,
2998
3324
  provideLazyProvider(AXP_MENU_PROVIDER, () => import('./acorex-platform-module-auth-client-menu.provider-Bz-kRip4.mjs').then(m => m.AXMSecurityManagementModuleMenuProvider)),
2999
- provideLazyProvider(AXP_SETTING_DEFINITION_PROVIDER, () => import('./acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs').then(m => m.AXMSettingProvider)),
3000
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs').then((module) => module.AXMProfilePageComponentProvider)),
3001
- provideLazyProvider(AXP_DATASOURCE_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return datasource_provider; }).then((m) => m.AXMAuthDataSourceProvider)),
3325
+ provideLazyProvider(AXP_SETTING_DEFINITION_PROVIDER, () => import('./acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs').then(m => m.AXMSettingProvider)),
3326
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs').then((module) => module.AXMProfilePageComponentProvider)),
3327
+ provideQuerySetups([
3328
+ {
3329
+ key: 'Auth:GetUserActivity',
3330
+ loader: () => import('./acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs').then((c) => c.AXMGetUserActivityQuery),
3331
+ },
3332
+ ]),
3002
3333
  {
3003
3334
  provide: ROUTES,
3004
3335
  multi: true,
3005
3336
  useFactory: profileRoutesFactory,
3006
3337
  },
3007
- {
3008
- provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
3009
- multi: true,
3010
- useValue: userAvatarHydrateMiddleware,
3011
- },
3012
3338
  {
3013
3339
  provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
3014
3340
  multi: true,
@@ -3017,51 +3343,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3017
3343
  provideCommandSetups([
3018
3344
  {
3019
3345
  key: AXMAuthCommandKeys.Profile.Show,
3020
- command: () => import('./acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs').then((c) => c.AXPShowProfileCommand),
3346
+ command: () => import('./acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs').then((c) => c.AXPShowProfileCommand),
3021
3347
  },
3022
3348
  {
3023
3349
  key: AXMAuthCommandKeys.Session.Signout,
3024
- command: () => import('./acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs').then((c) => c.AXPSignoutCommand),
3350
+ command: () => import('./acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs').then((c) => c.AXPSignoutCommand),
3025
3351
  },
3026
3352
  {
3027
3353
  key: AXMAuthCommandKeys.Session.OpenSessions,
3028
- command: () => import('./acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs').then((c) => c.AXPOpenSessionsCommand),
3354
+ command: () => import('./acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs').then((c) => c.AXPOpenSessionsCommand),
3029
3355
  },
3030
3356
  {
3031
3357
  key: AXMAuthCommandKeys.Session.LockScreen,
3032
- command: () => import('./acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs').then((c) => c.AXPLockScreenCommand),
3358
+ command: () => import('./acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs').then((c) => c.AXPLockScreenCommand),
3033
3359
  },
3034
3360
  {
3035
3361
  key: AXMAuthCommandKeys.Profile.ChangePhoto,
3036
- command: () => import('./acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs').then((c) => c.AXPChangePhotoCommand),
3362
+ command: () => import('./acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs').then((c) => c.AXPChangePhotoCommand),
3037
3363
  },
3038
3364
  {
3039
3365
  key: AXMAuthCommandKeys.Profile.EditAccountInfo,
3040
- command: () => import('./acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs').then((c) => c.AXPEditAccountInfoCommand),
3366
+ command: () => import('./acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs').then((c) => c.AXPEditAccountInfoCommand),
3041
3367
  },
3042
3368
  {
3043
3369
  key: AXMAuthCommandKeys.Security.ChangePassword,
3044
- command: () => import('./acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs').then((c) => c.AXPChangePasswordCommand),
3370
+ command: () => import('./acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs').then((c) => c.AXPChangePasswordCommand),
3045
3371
  },
3046
3372
  {
3047
3373
  key: AXMAuthCommandKeys.Security.SetPinCode,
3048
- command: () => import('./acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs').then((c) => c.AXPSetPinCodeCommand),
3374
+ command: () => import('./acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs').then((c) => c.AXPSetPinCodeCommand),
3049
3375
  },
3050
3376
  {
3051
3377
  key: AXMAuthCommandKeys.Security.RemovePinCode,
3052
- command: () => import('./acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs').then((c) => c.AXPRemovePinCodeCommand),
3378
+ command: () => import('./acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs').then((c) => c.AXPRemovePinCodeCommand),
3053
3379
  },
3054
3380
  {
3055
3381
  key: AXMAuthCommandKeys.Security.ViewLoginHistory,
3056
- command: () => import('./acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs').then((c) => c.AXPViewLoginHistoryCommand),
3382
+ command: () => import('./acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs').then((c) => c.AXPViewLoginHistoryCommand),
3057
3383
  },
3058
3384
  {
3059
3385
  key: AXMAuthCommandKeys.Security.EditSignature,
3060
- command: () => import('./acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs').then((c) => c.AXPEditSignatureCommand),
3386
+ command: () => import('./acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs').then((c) => c.AXPEditSignatureCommand),
3061
3387
  },
3062
3388
  {
3063
3389
  key: AXMAuthCommandKeys.Profile.ComingSoon,
3064
- command: () => import('./acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs').then((c) => c.AXPProfileComingSoonCommand),
3390
+ command: () => import('./acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs').then((c) => c.AXPProfileComingSoonCommand),
3065
3391
  },
3066
3392
  ]),
3067
3393
  {
@@ -3079,6 +3405,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3079
3405
  useValue: ProfileSlotLockMenuHookProvider,
3080
3406
  multi: true,
3081
3407
  },
3408
+ {
3409
+ provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
3410
+ useValue: ProfileSlotPresenceMenuHookProvider,
3411
+ multi: true,
3412
+ },
3082
3413
  {
3083
3414
  provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
3084
3415
  useValue: CoreProfileGroupsHookProvider,
@@ -3111,18 +3442,19 @@ const AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT = 'auth-login-external-providers';
3111
3442
  class AXPLoginExternalProvidersComponent {
3112
3443
  constructor() {
3113
3444
  this.slotName = AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT;
3114
- this.slot = viewChild(AXPComponentSlotDirective, ...(ngDevMode ? [{ debugName: "slot" }] : /* istanbul ignore next */ []));
3445
+ this.slot = viewChild(AXPComponentSlotDirective, /* @ts-ignore */
3446
+ ...(ngDevMode ? [{ debugName: "slot" }] : /* istanbul ignore next */ []));
3115
3447
  }
3116
3448
  hasContent() {
3117
3449
  const slot = this.slot();
3118
3450
  return !!slot && !slot.isEmpty();
3119
3451
  }
3120
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLoginExternalProvidersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3121
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.9", type: AXPLoginExternalProvidersComponent, isStandalone: true, selector: "axm-login-external-providers", viewQueries: [{ propertyName: "slot", first: true, predicate: AXPComponentSlotDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<axp-component-slot\n class=\"flex flex-col gap-2 w-full mt-6\"\n #slot=\"slot\"\n [name]=\"slotName\"\n [host]=\"this\"\n></axp-component-slot>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$3.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }] }); }
3452
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLoginExternalProvidersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3453
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.8", type: AXPLoginExternalProvidersComponent, isStandalone: true, selector: "axm-login-external-providers", viewQueries: [{ propertyName: "slot", first: true, predicate: AXPComponentSlotDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<axp-component-slot\n class=\"flex flex-col gap-2 w-full mt-0 lg:mt-2\"\n #slot=\"slot\"\n [name]=\"slotName\"\n [host]=\"this\"\n></axp-component-slot>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$4.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
3122
3454
  }
3123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLoginExternalProvidersComponent, decorators: [{
3455
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLoginExternalProvidersComponent, decorators: [{
3124
3456
  type: Component,
3125
- args: [{ selector: 'axm-login-external-providers', imports: [AXPComponentSlotModule], template: "<axp-component-slot\n class=\"flex flex-col gap-2 w-full mt-6\"\n #slot=\"slot\"\n [name]=\"slotName\"\n [host]=\"this\"\n></axp-component-slot>\n" }]
3457
+ args: [{ selector: 'axm-login-external-providers', changeDetection: ChangeDetectionStrategy.Eager, imports: [AXPComponentSlotModule], template: "<axp-component-slot\n class=\"flex flex-col gap-2 w-full mt-0 lg:mt-2\"\n #slot=\"slot\"\n [name]=\"slotName\"\n [host]=\"this\"\n></axp-component-slot>\n" }]
3126
3458
  }], propDecorators: { slot: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPComponentSlotDirective), { isSignal: true }] }] } });
3127
3459
 
3128
3460
  //#endregion
@@ -3142,7 +3474,7 @@ class AXPLoginHistoryService {
3142
3474
  return [];
3143
3475
  }
3144
3476
  const response = await this.entityService
3145
- .withEntity(RootConfig$1.module.name, RootConfig$1.entities.deviceSessions.name)
3477
+ .withEntity(RootConfig.module.name, RootConfig.entities.deviceSessions.name)
3146
3478
  .data()
3147
3479
  .query({ skip: 0, take: 1000 });
3148
3480
  const items = response.items ?? [];
@@ -3158,10 +3490,10 @@ class AXPLoginHistoryService {
3158
3490
  lastLoginDate: item.lastLoginDate,
3159
3491
  })), [(entry) => new Date(entry.lastLoginDate).getTime()], ['desc']);
3160
3492
  }
3161
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLoginHistoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3162
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLoginHistoryService, providedIn: 'root' }); }
3493
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLoginHistoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3494
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLoginHistoryService, providedIn: 'root' }); }
3163
3495
  }
3164
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLoginHistoryService, decorators: [{
3496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLoginHistoryService, decorators: [{
3165
3497
  type: Injectable,
3166
3498
  args: [{ providedIn: 'root' }]
3167
3499
  }] });
@@ -3170,5 +3502,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3170
3502
  * Generated bundle index. Do not edit.
3171
3503
  */
3172
3504
 
3173
- export { AXMUserDeviceSessionsService as A, AXMAuthDataSourceProvider as B, AXMAuthErrorHandler as C, AXMAuthModule as D, AXMDefaultAuthConfigs as E, AXMUserActivityDataSourceDefinition as F, aggregateDailySessionCounts as G, buildUserActivityDataSourceItem as H, buildUserActivityWeeks as I, canActivateLogin as J, computeUserActivityStats as K, configAuthModule as L, countToActivityLevel as M, extractUserActivityEndDate as N, extractUserActivityStartDate as O, PROFILE_PAGE_GROUPS_HOOK as P, extractUserActivityUserId as Q, isUserProfileGroupComponent as R, PROFILE_PAGE_SECTIONS_HOOK as a, PROFILE_PAGE_HEADER_META_HOOK as b, resolveUserProfileSectionContent as c, PROFILE_ACTIVITY_CHART_COMPONENT_KEY as d, PROFILE_DELETE_ACCOUNT_DANGER_ZONE_COMPONENT_KEY as e, AXPIdleLockService as f, AXPUserAvatarSyncService as g, AXPAuthPasswordComplexityService as h, AXPAuthPasswordChangeTrackingService as i, getPasswordComplexityHintKey as j, getPasswordComplexityValidationMessageKey as k, validatePasswordAgainstComplexity as l, AXPLoginHistoryService as m, AXM_AUTH_CONFIG_TOKEN as n, AXM_LOGIN_GUARD_TOKEN as o, AXMAuthenticationTypes as p, AXPTenantChooserListComponent as q, resolveDefaultUserProfileSectionAction as r, AXPTenantChooserDropdownComponent as s, AXPAppChooserListComponent as t, resolveDefaultUserActivityDateRange as u, visibleUserProfileSectionActions as v, formatCompactActivityCount as w, AXPLoginExternalProvidersComponent as x, AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT as y, AUTH_USER_ACTIVITY_DEFAULT_WEEKS as z };
3174
- //# sourceMappingURL=acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs.map
3505
+ export { AXMUserDeviceSessionsService as A, AXMAuthenticationTypes as B, CHANGE_PASSWORD_SECTION_ID as C, AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT as D, AUTH_USER_ACTIVITY_DEFAULT_WEEKS as E, AXMAuthErrorHandler as F, AXMAuthModule as G, AXMDefaultAuthConfigs as H, AXM_AUTH_CONFIG_TOKEN as I, aggregateDailySessionCounts as J, buildUserActivityWeeks as K, canActivateLogin as L, computeUserActivityStats as M, configAuthModule as N, countToActivityLevel as O, PROFILE_PAGE_GROUPS_HOOK as P, extractUserActivityEndDate as Q, extractUserActivityStartDate as R, extractUserActivityUserId as S, isUserProfileGroupComponent as T, isUserProfileSectionsGroupRequested as U, parseAuthCredentialType as V, PROFILE_PAGE_SECTIONS_HOOK as a, PROFILE_PAGE_HEADER_META_HOOK as b, resolveUserProfileSectionContent as c, PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY as d, PROFILE_ACTIVITY_CHART_COMPONENT_KEY as e, PROFILE_DELETE_ACCOUNT_DANGER_ZONE_COMPONENT_KEY as f, resolveDefaultUserActivityDateRange as g, buildUserActivityDataSourceItem as h, AXPIdleLockService as i, AXPUserAvatarSyncService as j, AXPAuthPasswordComplexityService as k, AXPAuthPasswordChangeTrackingService as l, getPasswordComplexityHintKey as m, getPasswordComplexityValidationMessageKey as n, validatePasswordAgainstComplexity as o, buildPasswordLastChangedInsights as p, AXPLoginHistoryService as q, resolveDefaultUserProfileSectionAction as r, AXMAuthPlatformSettingsService as s, AXM_LOGIN_GUARD_TOKEN as t, AXPTenantChooserListComponent as u, visibleUserProfileSectionActions as v, AXPTenantChooserDropdownComponent as w, AXPAppChooserListComponent as x, formatCompactActivityCount as y, AXPLoginExternalProvidersComponent as z };
3506
+ //# sourceMappingURL=acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs.map