@acorex-platform/module-conversation-client 0.0.46 → 0.0.49

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 (32) hide show
  1. package/fesm2022/{acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DUR2oyfP.mjs → acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DcdPViNy.mjs} +1677 -515
  2. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DcdPViNy.mjs.map +1 -0
  3. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-qTWATpgC.mjs → acorex-platform-module-conversation-client-after-message-sent.command-Cf1zPn3u.mjs} +2 -2
  4. package/fesm2022/{acorex-platform-module-conversation-client-after-message-sent.command-qTWATpgC.mjs.map → acorex-platform-module-conversation-client-after-message-sent.command-Cf1zPn3u.mjs.map} +1 -1
  5. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-DQWhOmBE.mjs → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-R40vR1C3.mjs} +5 -5
  6. package/fesm2022/{acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-DQWhOmBE.mjs.map → acorex-platform-module-conversation-client-assist-delegated-agent-detail-popup.component-R40vR1C3.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-DyVepuaW.mjs → acorex-platform-module-conversation-client-assist-message-renderer.component-CUlLCsF6.mjs} +6 -6
  8. package/fesm2022/{acorex-platform-module-conversation-client-assist-message-renderer.component-DyVepuaW.mjs.map → acorex-platform-module-conversation-client-assist-message-renderer.component-CUlLCsF6.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-module-conversation-client-assist-tool-detail-popup.component-D8na_1QJ.mjs → acorex-platform-module-conversation-client-assist-tool-detail-popup.component-B7LW5ie9.mjs} +3 -3
  10. package/fesm2022/{acorex-platform-module-conversation-client-assist-tool-detail-popup.component-D8na_1QJ.mjs.map → acorex-platform-module-conversation-client-assist-tool-detail-popup.component-B7LW5ie9.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-BeS4Duip.mjs → acorex-platform-module-conversation-client-chat-call-session-page.component-DiA01mpJ.mjs} +3 -3
  12. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-session-page.component-BeS4Duip.mjs.map → acorex-platform-module-conversation-client-chat-call-session-page.component-DiA01mpJ.mjs.map} +1 -1
  13. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-BbEhkLLh.mjs → acorex-platform-module-conversation-client-chat-call-start-popup.component-nLVRg9HK.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-module-conversation-client-chat-call-start-popup.component-BbEhkLLh.mjs.map → acorex-platform-module-conversation-client-chat-call-start-popup.component-nLVRg9HK.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BxUz9jTX.mjs → acorex-platform-module-conversation-client-comments-page.component-C0JLE_oX.mjs} +2 -2
  16. package/fesm2022/{acorex-platform-module-conversation-client-comments-page.component-BxUz9jTX.mjs.map → acorex-platform-module-conversation-client-comments-page.component-C0JLE_oX.mjs.map} +1 -1
  17. package/fesm2022/acorex-platform-module-conversation-client-contracts.mjs +15 -1
  18. package/fesm2022/acorex-platform-module-conversation-client-contracts.mjs.map +1 -1
  19. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-juoWxu7I.mjs → acorex-platform-module-conversation-client-mark-conversation-unread.command-CIT6UHfK.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-module-conversation-client-mark-conversation-unread.command-juoWxu7I.mjs.map → acorex-platform-module-conversation-client-mark-conversation-unread.command-CIT6UHfK.mjs.map} +1 -1
  21. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-ridcdmj7.mjs → acorex-platform-module-conversation-client-open-chat.command-kTWhndd2.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-conversation-client-open-chat.command-ridcdmj7.mjs.map → acorex-platform-module-conversation-client-open-chat.command-kTWhndd2.mjs.map} +1 -1
  23. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-BsYxaH3g.mjs → acorex-platform-module-conversation-client-retry-assist-response.command-pKO5UqyB.mjs} +2 -2
  24. package/fesm2022/{acorex-platform-module-conversation-client-retry-assist-response.command-BsYxaH3g.mjs.map → acorex-platform-module-conversation-client-retry-assist-response.command-pKO5UqyB.mjs.map} +1 -1
  25. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-DsCyIdEk.mjs → acorex-platform-module-conversation-client-sync-read-state.command-BbQHG28M.mjs} +2 -2
  26. package/fesm2022/{acorex-platform-module-conversation-client-sync-read-state.command-DsCyIdEk.mjs.map → acorex-platform-module-conversation-client-sync-read-state.command-BbQHG28M.mjs.map} +1 -1
  27. package/fesm2022/acorex-platform-module-conversation-client.mjs +2 -1
  28. package/fesm2022/acorex-platform-module-conversation-client.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/types/acorex-platform-module-conversation-client-contracts.d.ts +21 -2
  31. package/types/acorex-platform-module-conversation-client.d.ts +356 -184
  32. package/fesm2022/acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DUR2oyfP.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
2
- import { AXPFilterOperatorMiddlewareService, AXPSearchCommandProvider, createEntityCommandOptions, AXP_PROTECTED_ROUTE_GUARDS, AXPBackgroundOperationHandler, AXP_BACKGROUND_OPERATION_HANDLERS, AXPSettingsService, AXPCommonSettings, AXP_IN_APP_NOTIFICATION_SERVICE, AXPFileStorageService, AXP_MENU_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
2
+ import { AXPFilterOperatorMiddlewareService, AXPSearchCommandProvider, createEntityCommandOptions, AXP_PROTECTED_ROUTE_GUARDS, AXPBackgroundOperationHandler, AXP_BACKGROUND_OPERATION_HANDLERS, AXPSettingsService, AXPCommonSettings, AXP_IN_APP_NOTIFICATION_SERVICE, AXPFileStorageService, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
3
3
  import { AXPEntityBroadcastService, AXPTagService, AXPPageContextRegistry, AXPDeviceService, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, AXP_HOOK_PROVIDER } from '@acorex-platform/framework-client/core';
4
4
  import { USER_CARD_ITEMS_HOOK, AXPTaskBadgeProvider, AXPFileViewerService, AXPUserAvatarService, AXPUserAvatarComponent, AXPUserCardDirective, mergeInfiniteScrollPage, AXPThemeLayoutBlockComponent, AXPInfiniteScrollDirective, AXPStateMessageComponent, AXPAvatarComponent, AXPMarkdownViewerComponent, AXPTaskBadgeService, AXPThemeLayoutStartSideComponent, AXP_PAGE_COMPONENT_PROVIDER, AXP_TASK_BADGE_PROVIDERS } from '@acorex-platform/framework-client/layout/components';
5
5
  import { AXPEntityService, AXPFileListComponent, AXPEntityDefinitionRegistryService, cloneLayoutArrays, ensureLayoutSection, ensureLayoutPropertyView, resolveEntityPluginDetailPageOrder, ensureListActions, actionExists, AXP_ENTITY_ACTION_PLUGIN } from '@acorex-platform/framework-client/layout/entity';
@@ -12,10 +12,10 @@ import { CommonModule, DOCUMENT, AsyncPipe, NgTemplateOutlet, isPlatformBrowser,
12
12
  import * as i0 from '@angular/core';
13
13
  import { inject, Injectable, signal, DestroyRef, input, computed, ChangeDetectionStrategy, Component, ElementRef, Injector, output, viewChild, afterNextRender, effect, untracked, InjectionToken, Directive, ViewContainerRef, EnvironmentInjector, ViewEncapsulation, PLATFORM_ID, NgZone, NgModule } from '@angular/core';
14
14
  import { Router, ActivatedRoute, NavigationEnd, ROUTES } from '@angular/router';
15
- import { RootConfig, axmIsCommentRoom, AXPCollaborationPermissionKeys, AXPConversationMenuKeys, AXPConversationQueryKeys, AXPConversationCommandKeys, AXM_COMMENT_LIKE_EMOJI, CHANNEL_POST_ENTITY_NAME, axmIsChannelRoom, AXM_CONVERSATION_ANNOUNCEMENT_FEED_ITEM_META_KEY, AXM_CONVERSATION_ANNOUNCEMENT_MESSAGE_TYPE, AXM_CONVERSATION_CHANNEL_POST_ID_META_KEY, axmIsAnnouncementChannel, axmAnnouncementChannelMetadata, AXM_CONVERSATION_ANNOUNCEMENT_CHANNEL_NAME, axmAiChatConversationUiMetadata as axmAiChatConversationUiMetadata$1, axmMessagesAfterId, axmChannelPostIdFromMessage, extractMessageTextFromPayload, AXMPermissionsKeys } from '@acorex-platform/module-conversation-client/contracts';
15
+ import { RootConfig, axmIsCommentRoom, AXPCollaborationPermissionKeys, AXPConversationMenuKeys, AXMMiniChatSettings, AXPConversationQueryKeys, AXPConversationCommandKeys, AXM_COMMENT_LIKE_EMOJI, CHANNEL_POST_ENTITY_NAME, axmIsChannelRoom, AXM_CONVERSATION_ANNOUNCEMENT_FEED_ITEM_META_KEY, AXM_CONVERSATION_ANNOUNCEMENT_MESSAGE_TYPE, AXM_CONVERSATION_CHANNEL_POST_ID_META_KEY, axmIsAnnouncementChannel, axmAnnouncementChannelMetadata, AXM_CONVERSATION_ANNOUNCEMENT_CHANNEL_NAME, axmAiChatConversationUiMetadata as axmAiChatConversationUiMetadata$1, axmMessagesAfterId, axmChannelPostIdFromMessage, extractMessageTextFromPayload, AXMPermissionsKeys } from '@acorex-platform/module-conversation-client/contracts';
16
16
  import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
17
17
  import { axmAiChatConversationUiMetadata, axmBuildHeuristicConversationTitleFallback, axmCompareMessagesChronologically, AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD, AXM_ASSIST_LAUNCH_CONTEXT_METADATA_KEY, axmExtractAssistLaunchContextFromMetadata, axmSanitizeContextualAssistContext, AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD, RootConfig as RootConfig$1 } from '@acorex-platform/module-conversation-client/contracts';
18
- import { coerceUnknownToTrimmedString, runtimeQueryCollectionData, runtimeQueryObjectData, resolveMultiLanguageString, coerceUnknownToMultiLanguageString, AXP_QUERY_QUICK_SEARCH_FIELD, AXPPlatformScope, AXPFileStorageStatus, runtimeCommandPayloadData, createRandomUuid, AXPRegionalSetting } from '@acorex-platform/framework-shared/core';
18
+ import { coerceUnknownToTrimmedString, runtimeQueryCollectionData, AXPWidgetsList, runtimeQueryObjectData, resolveMultiLanguageString, coerceUnknownToMultiLanguageString, AXP_QUERY_QUICK_SEARCH_FIELD, AXPPlatformScope, AXPFileStorageStatus, runtimeCommandPayloadData, createRandomUuid, AXPRegionalSetting } from '@acorex-platform/framework-shared/core';
19
19
  import { trim, isEmpty, get, isNil, isString, orderBy } from 'lodash';
20
20
  import { AXConversationUserApi, AXConversationApi, AXConversationMessageApi, AXConversationRealtimeApi, AX_CONVERSATION_DEFAULT_ROOM_PREFERENCES, AXConversationService, AXConversationComposerService, AXConversationContainerDirective, AXConversationInfoBarComponent, AXConversationMessageListComponent, AXConversationComposerComponent, AXConversationNewDialogComponent, AXConversationInfoBarService, AXConversationSidebarComponent, AXConversationComposerGenerationStateService, AX_CONVERSATION_ERROR_HANDLER_CONFIG, provideConversation, AX_CONVERSATION_ITEM_MUTE_ACTION, AX_CONVERSATION_ITEM_PIN_ACTION, AX_CONVERSATION_ITEM_MARK_READ_ACTION, AX_CONVERSATION_ITEM_DIVIDER, AX_CONVERSATION_ITEM_DELETE_ACTION, AX_CONVERSATION_INFO_BAR_SEARCH_ACTION, AX_CONVERSATION_INFO_BAR_MUTE_ACTION, AX_CONVERSATION_INFO_BAR_DIVIDER, AX_CONVERSATION_INFO_BAR_DELETE_ACTION, AX_CONVERSATION_TAB_ALL, AX_CONVERSATION_TAB_PRIVATE, AX_CONVERSATION_TAB_GROUPS, AX_CONVERSATION_MESSAGE_REPLY_ACTION, AX_CONVERSATION_MESSAGE_FORWARD_ACTION, AX_CONVERSATION_MESSAGE_EDIT_ACTION, AX_CONVERSATION_MESSAGE_DELETE_ACTION, AX_CONVERSATION_IMAGE_RENDERER, AX_CONVERSATION_VIDEO_RENDERER, AX_CONVERSATION_AUDIO_RENDERER, AX_CONVERSATION_VOICE_RENDERER, AX_CONVERSATION_FILE_RENDERER, AX_CONVERSATION_LOCATION_RENDERER, AX_CONVERSATION_STICKER_RENDERER } from '@acorex/components/conversation';
21
21
  import { isWatchablePresenceUserId, AXPUserPresenceService, AXPRealtimeConnectionService, AXPRealtimeConnectionPort, AXPRealtimeDispatcherService, AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE, AXP_REALTIME_TOPIC_CONVERSATION_TYPING, AXP_REALTIME_TOPIC_ENTITY_MUTATION, AXP_REALTIME_TOPIC_CONVERSATION_CALL } from '@acorex-platform/framework-client/realtime';
@@ -2640,6 +2640,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2640
2640
  type: Injectable
2641
2641
  }] });
2642
2642
 
2643
+ //#endregion
2644
+ //#region ----- Constants -----
2645
+ const I18N = `@${RootConfig.config.i18n}:user-settings.mini-chat`;
2646
+ //#endregion
2647
+ //#region ----- Settings Provider -----
2648
+ class AXMSettingProvider {
2649
+ async provide(context) {
2650
+ context
2651
+ .addGroup('conversation', `${I18N}.group.nav-title`, `${I18N}.group.description`, RootConfig.module.icon, `${I18N}.group.title`)
2652
+ .addSection('mini-chat-window', `${I18N}.window.title`, `${I18N}.window.description`)
2653
+ .addSetting({
2654
+ key: AXMMiniChatSettings.Position,
2655
+ title: `${I18N}.position.title`,
2656
+ description: `${I18N}.position.description`,
2657
+ scope: 'U',
2658
+ overridableAt: [],
2659
+ isInherited: false,
2660
+ defaultValue: null,
2661
+ widget: {
2662
+ type: AXPWidgetsList.Editors.TextBox,
2663
+ options: { visibility: false },
2664
+ },
2665
+ })
2666
+ .addSetting({
2667
+ key: AXMMiniChatSettings.Size,
2668
+ title: `${I18N}.size.title`,
2669
+ description: `${I18N}.size.description`,
2670
+ scope: 'U',
2671
+ overridableAt: [],
2672
+ isInherited: false,
2673
+ defaultValue: null,
2674
+ widget: {
2675
+ type: AXPWidgetsList.Editors.TextBox,
2676
+ options: { visibility: false },
2677
+ },
2678
+ })
2679
+ .endSection()
2680
+ .endGroup();
2681
+ }
2682
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSettingProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2683
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSettingProvider }); }
2684
+ }
2685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSettingProvider, decorators: [{
2686
+ type: Injectable
2687
+ }] });
2688
+
2643
2689
  //#endregion
2644
2690
  //#region ----- Permission Definition Provider -----
2645
2691
  /**
@@ -4204,15 +4250,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4204
4250
  args: [{ providedIn: 'root' }]
4205
4251
  }] });
4206
4252
 
4207
- //#region ---- Mini chat panel open options ----
4208
- /** Session key used for the global inbox mini chat (non-entity conversations). */
4209
- const AXM_MINI_CHAT_INBOX_SESSION_KEY = '__inbox__';
4210
- /** Popup dock name for minimized mini-chat tabs in the root footer. */
4211
- const AXM_MINI_CHAT_POPUP_DOCK = 'mini-chat';
4212
- //#endregion
4213
-
4214
- const AXM_ASSIST_DEFAULT_RESOLVER_PORT = new InjectionToken('AXM_ASSIST_DEFAULT_RESOLVER_PORT');
4215
-
4216
4253
  //#region ----- Imports -----
4217
4254
  //#endregion
4218
4255
  //#region ----- Constants -----
@@ -4374,6 +4411,13 @@ function readMetadataString(metadata, key) {
4374
4411
  }
4375
4412
  return undefined;
4376
4413
  }
4414
+ /** Launch context stored on a chat room, including the nested metadata shape. */
4415
+ function axmRoomLaunchContext(room) {
4416
+ if (!room?.metadata) {
4417
+ return undefined;
4418
+ }
4419
+ return readLaunchContext(room.metadata);
4420
+ }
4377
4421
  function readLaunchContext(metadata) {
4378
4422
  const direct = metadata[AXM_ASSIST_LAUNCH_CONTEXT_METADATA_KEY];
4379
4423
  if (isLaunchContext(direct)) {
@@ -4397,163 +4441,991 @@ function isLaunchContext(value) {
4397
4441
  }
4398
4442
  //#endregion
4399
4443
 
4400
- //#region ---- Imports ----
4444
+ //#region ----- Imports -----
4401
4445
  //#endregion
4402
- //#region ---- Service ----
4403
- /**
4404
- * Backing service for the entity-scoped mini chat: finds the conversations bound to an entity
4405
- * (an entity may have several) and prepares the create payload for a new entity assist chat.
4406
- *
4407
- * Conversation creation/selection is performed by the caller using its own
4408
- * {@link AXConversationService} instance so the mini chat keeps its active-selection state
4409
- * isolated from the main chat page.
4410
- */
4411
- class AXMEntityChatService {
4412
- constructor() {
4413
- //#region ---- Services & Dependencies ----
4414
- this.injector = inject(Injector);
4415
- this.conversationService = inject(AXConversationService);
4416
- this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
4417
- this.translationService = inject(AXTranslationService);
4418
- this.defaultAssistResolver = inject(AXM_ASSIST_DEFAULT_RESOLVER_PORT, { optional: true });
4419
- }
4420
- //#endregion
4421
- //#region ---- Lazy dependencies ----
4422
- /**
4423
- * Resolved lazily: this service is `providedIn: 'root'` but depends on module-scoped chat APIs
4424
- * and optional AI services that must not be requested during the same hydration pass as chat UI.
4425
- */
4426
- get conversationApi() {
4427
- return this.injector.get(AXMChatConversationApi);
4428
- }
4429
- //#endregion
4430
- //#region ---- Public Methods ----
4431
- /** Returns every conversation bound to the given entity reference. */
4432
- findEntityConversations(ref) {
4433
- return this.conversationApi.findEntityConversations(ref.entityType.trim(), ref.entityId.trim());
4446
+ //#region ----- Constants -----
4447
+ /** Launch kind stored on a header mini-chat room after the first message. */
4448
+ const AXM_MINI_CHAT_PAGE_CONTEXT_KIND = 'entity-page';
4449
+ /** Action name paired with {@link AXM_MINI_CHAT_PAGE_CONTEXT_KIND}. */
4450
+ const AXM_MINI_CHAT_PAGE_CONTEXT_ACTION = 'entity.page.context';
4451
+ const AXM_MINI_CHAT_ENTITY_CHIP_ID = 'entity';
4452
+ const AXM_MINI_CHAT_VIEW_CHIP_ID = 'view';
4453
+ //#endregion
4454
+ //#region ----- Chips -----
4455
+ function axmMiniChatRecordChipId(recordId) {
4456
+ return `record:${recordId}`;
4457
+ }
4458
+ function axmMiniChatContextChipIcon(kind) {
4459
+ if (kind === 'record') {
4460
+ return 'fa-light fa-file-lines';
4434
4461
  }
4435
- /**
4436
- * Creates a new entity-scoped assist conversation and selects it.
4437
- * Must go through {@link AXConversationService.createConversation} so the open mini-chat
4438
- * instance owns the thread; the inbox tab filter hides entity rooms from `/chat/`.
4439
- */
4440
- async createEntityChat(ref, assistId, extraMetadata) {
4441
- const createData = await this.buildEntityChatCreateData(ref, assistId, extraMetadata);
4442
- const conversation = await this.conversationService.createConversation(createData.participantIds, createData.type, createData.options);
4443
- await this.conversationService.selectConversation(conversation.id);
4444
- this.conversationApi.reportFocusedConversation(conversation.id);
4445
- return conversation;
4462
+ if (kind === 'view') {
4463
+ return 'fa-light fa-layer-group';
4446
4464
  }
4447
- /**
4448
- * Builds the `createConversation` payload for a new entity assist chat.
4449
- * Uses `assistId` when provided, otherwise the tenant default assist.
4450
- */
4451
- async buildEntityChatCreateData(ref, assistId, extraMetadata) {
4452
- const row = await this.resolveAssistRow(assistId);
4453
- const avatar = axmChatAiTargetAvatarUrl(row);
4454
- return {
4455
- participantIds: [axmChatAiPeerParticipantId(row.id)],
4456
- type: 'bot',
4457
- options: {
4458
- title: this.resolveTitle(row),
4459
- ...(avatar ? { avatar } : {}),
4460
- icon: 'fa-solid fa-robot',
4461
- metadata: {
4462
- ...extraMetadata,
4463
- ...axmBuildEntityChatConversationMetadata({
4464
- entityId: ref.entityId,
4465
- entityType: ref.entityType,
4466
- assistId: row.id,
4467
- }),
4468
- },
4469
- },
4470
- };
4465
+ return 'fa-light fa-cube';
4466
+ }
4467
+ function axmMiniChatChipsFromDraft(draft, dismissed) {
4468
+ const chips = [];
4469
+ if (draft.entityTitle && !dismissed.has(AXM_MINI_CHAT_ENTITY_CHIP_ID)) {
4470
+ chips.push({
4471
+ id: AXM_MINI_CHAT_ENTITY_CHIP_ID,
4472
+ kind: 'entity',
4473
+ label: draft.entityTitle,
4474
+ });
4471
4475
  }
4472
- //#endregion
4473
- //#region ---- Utility Methods ----
4474
- /** Resolves the assist catalog row to chat with (explicit id → tenant default → first row). */
4475
- async resolveAssistRow(assistId) {
4476
- const rows = await axmLoadChatAiTargets(this.entityRegistry);
4477
- if (!rows.length) {
4478
- throw new Error('No assist targets are available to start an entity chat.');
4479
- }
4480
- const requestedId = assistId?.trim() || (await this.resolveDefaultAssistId());
4481
- const match = requestedId ? rows.find((row) => row.id === requestedId) : undefined;
4482
- return match ?? rows[0];
4476
+ if (draft.includeView && draft.viewTitle && !dismissed.has(AXM_MINI_CHAT_VIEW_CHIP_ID)) {
4477
+ chips.push({
4478
+ id: AXM_MINI_CHAT_VIEW_CHIP_ID,
4479
+ kind: 'view',
4480
+ label: draft.viewTitle,
4481
+ });
4483
4482
  }
4484
- async resolveDefaultAssistId() {
4485
- if (!this.defaultAssistResolver) {
4486
- return undefined;
4487
- }
4488
- try {
4489
- return await this.defaultAssistResolver.getDefaultAssistId();
4490
- }
4491
- catch (error) {
4492
- console.warn('Failed to resolve default assist for entity mini chat:', error);
4493
- return undefined;
4483
+ for (const record of draft.records) {
4484
+ const id = axmMiniChatRecordChipId(record.id);
4485
+ if (dismissed.has(id)) {
4486
+ continue;
4494
4487
  }
4488
+ chips.push({
4489
+ id,
4490
+ kind: 'record',
4491
+ label: record.title || record.id,
4492
+ });
4495
4493
  }
4496
- resolveTitle(row) {
4497
- return this.translationService.resolve(row.title) ?? row.name;
4498
- }
4499
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4500
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, providedIn: 'root' }); }
4501
- }
4502
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, decorators: [{
4503
- type: Injectable,
4504
- args: [{ providedIn: 'root' }]
4505
- }] });
4506
-
4507
- //#region ---- Conversation list sort ----
4508
- /** Pinned flag on room or legacy mock metadata (`metadata.isPinned`). */
4509
- function axmIsConversationPinned(conversation) {
4510
- return Boolean(conversation.pinned) || conversation.metadata?.['isPinned'] === true;
4511
- }
4512
- /** Latest activity time from embedded last message or `lastMessageAt`. */
4513
- function axmConversationLastMessageMs(conversation) {
4514
- const ts = conversation.lastMessage?.timestamp ?? conversation.lastMessageAt;
4515
- return axmCoerceTimestampMs(ts);
4494
+ return chips;
4516
4495
  }
4517
- /** Pinned conversations first, then most recent `lastMessageAt` (mock inbox parity). */
4518
- function axmSortConversationsByPinAndRecency(conversations) {
4519
- return [...conversations].sort((a, b) => {
4520
- const aPinned = axmIsConversationPinned(a);
4521
- const bPinned = axmIsConversationPinned(b);
4522
- if (aPinned !== bPinned) {
4523
- return aPinned ? -1 : 1;
4524
- }
4525
- return axmConversationLastMessageMs(b) - axmConversationLastMessageMs(a);
4496
+ function axmMiniChatSameChips(left, right) {
4497
+ if (left.length !== right.length) {
4498
+ return false;
4499
+ }
4500
+ return left.every((chip, index) => {
4501
+ const other = right[index];
4502
+ return other != null && chip.id === other.id && chip.kind === other.kind && chip.label === other.label;
4526
4503
  });
4527
4504
  }
4528
4505
  //#endregion
4529
-
4530
- //#region ----- Imports -----
4531
- //#endregion
4532
- //#region ----- History list patches -----
4533
- /** Inserts or replaces a conversation in a mini-chat history list, then re-sorts. */
4534
- function axmUpsertMiniChatHistoryItem(items, next, matches) {
4535
- if (!matches(next)) {
4536
- return items.filter((item) => item.id !== next.id);
4506
+ //#region ----- Launch context -----
4507
+ function axmMiniChatLaunchContextFromDraft(draft, chips) {
4508
+ const visible = new Set(chips.map((chip) => chip.id));
4509
+ const entity = visible.has(AXM_MINI_CHAT_ENTITY_CHIP_ID) && draft.moduleName && draft.entityName
4510
+ ? {
4511
+ moduleName: draft.moduleName,
4512
+ entityName: draft.entityName,
4513
+ title: draft.entityTitle,
4514
+ }
4515
+ : undefined;
4516
+ const view = visible.has(AXM_MINI_CHAT_VIEW_CHIP_ID) && draft.viewName && draft.viewTitle
4517
+ ? { name: draft.viewName, title: draft.viewTitle }
4518
+ : undefined;
4519
+ const records = draft.records
4520
+ .filter((record) => visible.has(axmMiniChatRecordChipId(record.id)))
4521
+ .map((record) => ({
4522
+ id: record.id,
4523
+ title: record.title || record.id,
4524
+ moduleName: draft.moduleName,
4525
+ entityName: draft.entityName,
4526
+ }));
4527
+ if (!entity && !view && records.length === 0) {
4528
+ return undefined;
4537
4529
  }
4538
- return axmSortConversationsByPinAndRecency([next, ...items.filter((item) => item.id !== next.id)]);
4530
+ const payload = {
4531
+ guidance: 'Answer using this entity page context for the whole conversation. Use only the entity, view, and records listed here.',
4532
+ ...(entity ? { entity } : {}),
4533
+ ...(view ? { view } : {}),
4534
+ ...(records.length ? { records } : {}),
4535
+ };
4536
+ return {
4537
+ kind: AXM_MINI_CHAT_PAGE_CONTEXT_KIND,
4538
+ actionName: AXM_MINI_CHAT_PAGE_CONTEXT_ACTION,
4539
+ ...(entity?.title ? { title: entity.title } : {}),
4540
+ payload: { ...payload },
4541
+ };
4539
4542
  }
4540
- /** Removes a conversation from a mini-chat history list. */
4541
- function axmRemoveMiniChatHistoryItem(items, conversationId) {
4542
- const scoped = conversationId.trim();
4543
- if (!scoped) {
4544
- return items;
4543
+ function axmMiniChatChipsFromLaunchContext(context) {
4544
+ if (!context || context.kind !== AXM_MINI_CHAT_PAGE_CONTEXT_KIND) {
4545
+ return [];
4545
4546
  }
4546
- return items.filter((item) => item.id !== scoped);
4547
- }
4548
- //#endregion
4549
-
4550
- //#endregion
4551
- //#region ---- Component ----
4552
- /**
4553
- * Scrollable list of entity-scoped conversations for the mini chat panel.
4547
+ const payload = context.payload;
4548
+ const chips = [];
4549
+ const entity = readEntity$1(payload['entity']);
4550
+ if (entity?.title) {
4551
+ chips.push({
4552
+ id: AXM_MINI_CHAT_ENTITY_CHIP_ID,
4553
+ kind: 'entity',
4554
+ label: entity.title,
4555
+ });
4556
+ }
4557
+ const view = readView(payload['view']);
4558
+ if (view?.title) {
4559
+ chips.push({
4560
+ id: AXM_MINI_CHAT_VIEW_CHIP_ID,
4561
+ kind: 'view',
4562
+ label: view.title,
4563
+ });
4564
+ }
4565
+ const records = readRecords$1(payload['records']);
4566
+ for (const record of records) {
4567
+ chips.push({
4568
+ id: axmMiniChatRecordChipId(record.id),
4569
+ kind: 'record',
4570
+ label: record.title || record.id,
4571
+ });
4572
+ }
4573
+ return chips;
4574
+ }
4575
+ //#endregion
4576
+ //#region ----- Payload readers -----
4577
+ function readEntity$1(value) {
4578
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
4579
+ return undefined;
4580
+ }
4581
+ const row = value;
4582
+ const moduleName = readText$1(row['moduleName']);
4583
+ const entityName = readText$1(row['entityName']);
4584
+ const title = readText$1(row['title']);
4585
+ if (!moduleName || !entityName || !title) {
4586
+ return undefined;
4587
+ }
4588
+ return { moduleName, entityName, title };
4589
+ }
4590
+ function readView(value) {
4591
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
4592
+ return undefined;
4593
+ }
4594
+ const row = value;
4595
+ const name = readText$1(row['name']);
4596
+ const title = readText$1(row['title']);
4597
+ if (!name || !title) {
4598
+ return undefined;
4599
+ }
4600
+ return { name, title };
4601
+ }
4602
+ function readRecords$1(value) {
4603
+ if (!Array.isArray(value)) {
4604
+ return [];
4605
+ }
4606
+ const records = [];
4607
+ for (const item of value) {
4608
+ if (!item || typeof item !== 'object' || Array.isArray(item)) {
4609
+ continue;
4610
+ }
4611
+ const row = item;
4612
+ const id = readText$1(row['id']);
4613
+ const moduleName = readText$1(row['moduleName']);
4614
+ const entityName = readText$1(row['entityName']);
4615
+ if (!id || !moduleName || !entityName) {
4616
+ continue;
4617
+ }
4618
+ records.push({
4619
+ id,
4620
+ title: readText$1(row['title']) || id,
4621
+ moduleName,
4622
+ entityName,
4623
+ });
4624
+ }
4625
+ return records;
4626
+ }
4627
+ function readText$1(value) {
4628
+ return typeof value === 'string' ? value.trim() : '';
4629
+ }
4630
+ //#endregion
4631
+
4632
+ //#region ----- Imports -----
4633
+ //#endregion
4634
+ //#region ----- Scope builders -----
4635
+ /** Header chips: a record chip binds that record, an entity chip binds the list, neither is global. */
4636
+ function axmMiniChatHistoryScopeFromDraft(draft, chips) {
4637
+ if (!draft?.moduleName || !draft.entityName) {
4638
+ return { mode: 'global' };
4639
+ }
4640
+ const visible = new Set(chips.map((chip) => chip.id));
4641
+ const entityType = `${draft.moduleName}.${draft.entityName}`;
4642
+ const recordIds = draft.records
4643
+ .map((record) => record.id.trim())
4644
+ .filter((id) => id.length > 0 && visible.has(axmMiniChatRecordChipId(id)));
4645
+ if (recordIds.length > 0) {
4646
+ return { mode: 'entity', entityType, entityIds: recordIds };
4647
+ }
4648
+ if (visible.has(AXM_MINI_CHAT_ENTITY_CHIP_ID)) {
4649
+ return { mode: 'entity', entityType, entityIds: [AXM_ENTITY_LIST_CHAT_ID] };
4650
+ }
4651
+ return { mode: 'global' };
4652
+ }
4653
+ /**
4654
+ * Fixed surfaces (form designer, entity window).
4655
+ * Plain header inbox returns null so the live chips decide.
4656
+ */
4657
+ function axmMiniChatHistoryScopeFromOpen(options) {
4658
+ const launch = options.launchContext;
4659
+ if (launch && !isPageOrRecordLaunch(launch)) {
4660
+ return {
4661
+ mode: 'launch',
4662
+ kind: launch.kind,
4663
+ actionName: launch.actionName,
4664
+ recordId: readText(launch.payload?.['recordId']),
4665
+ };
4666
+ }
4667
+ if (options.scope === 'entity') {
4668
+ const entityType = options.entityType?.trim() ?? '';
4669
+ const entityId = options.entityId?.trim() ?? '';
4670
+ if (entityType && entityId) {
4671
+ return { mode: 'entity', entityType, entityIds: [entityId] };
4672
+ }
4673
+ }
4674
+ return null;
4675
+ }
4676
+ /** Entity binding stamped on a new header chat so it stays out of global history. */
4677
+ function axmEntityRefForMiniChatPageContext(launch) {
4678
+ if (!launch || launch.kind !== AXM_MINI_CHAT_PAGE_CONTEXT_KIND) {
4679
+ return undefined;
4680
+ }
4681
+ const records = readRecords(launch.payload);
4682
+ if (records.length === 1) {
4683
+ const record = records[0];
4684
+ return { entityId: record.id, entityType: `${record.moduleName}.${record.entityName}` };
4685
+ }
4686
+ if (records.length > 1) {
4687
+ return undefined;
4688
+ }
4689
+ const entity = readEntity(launch.payload);
4690
+ if (!entity) {
4691
+ return undefined;
4692
+ }
4693
+ return { entityId: AXM_ENTITY_LIST_CHAT_ID, entityType: `${entity.moduleName}.${entity.entityName}` };
4694
+ }
4695
+ function axmMiniChatHistoryScopeKey(scope) {
4696
+ if (scope.mode === 'global') {
4697
+ return 'global';
4698
+ }
4699
+ if (scope.mode === 'launch') {
4700
+ return `launch:${scope.kind}:${scope.actionName}:${scope.recordId}`;
4701
+ }
4702
+ return `entity:${scope.entityType}:${[...scope.entityIds].sort().join(',')}`;
4703
+ }
4704
+ //#endregion
4705
+ //#region ----- Room matching -----
4706
+ /** Chats with no entity and no surface context. These are the only rooms on `/chat/`. */
4707
+ function axmConversationIsGlobalChat(room) {
4708
+ if (!room || axmRoomIsEntityChat(room)) {
4709
+ return false;
4710
+ }
4711
+ const launch = readLaunch(room);
4712
+ if (!launch) {
4713
+ return true;
4714
+ }
4715
+ if (launch.kind !== AXM_MINI_CHAT_PAGE_CONTEXT_KIND) {
4716
+ return false;
4717
+ }
4718
+ return readRecords(launch.payload).length === 0 && !readEntity(launch.payload);
4719
+ }
4720
+ function axmConversationMatchesHistoryScope(room, scope) {
4721
+ if (!room) {
4722
+ return false;
4723
+ }
4724
+ if (scope.mode === 'global') {
4725
+ return axmConversationIsGlobalChat(room);
4726
+ }
4727
+ if (scope.mode === 'launch') {
4728
+ return matchesLaunch(room, scope);
4729
+ }
4730
+ return matchesEntity(room, scope.entityType, scope.entityIds);
4731
+ }
4732
+ //#endregion
4733
+ //#region ----- Route ownership -----
4734
+ /** True when this open window still belongs to the route the user is on. Header inbox follows every route. */
4735
+ function axmMiniChatWindowOwnsRoute(options, params) {
4736
+ const launch = options.launchContext;
4737
+ if (launch && !isPageOrRecordLaunch(launch)) {
4738
+ const recordId = readText(launch.payload?.['recordId']);
4739
+ if (!recordId || recordId === 'draft') {
4740
+ return false;
4741
+ }
4742
+ return params['id'] === recordId;
4743
+ }
4744
+ if ((options.scope ?? 'inbox') === 'inbox') {
4745
+ return true;
4746
+ }
4747
+ const entityType = options.entityType?.trim() ?? '';
4748
+ const separator = entityType.lastIndexOf('.');
4749
+ if (separator <= 0) {
4750
+ return false;
4751
+ }
4752
+ if (params['module'] !== entityType.slice(0, separator) || params['entity'] !== entityType.slice(separator + 1)) {
4753
+ return false;
4754
+ }
4755
+ const entityId = options.entityId?.trim() ?? '';
4756
+ if (!entityId || entityId === AXM_ENTITY_LIST_CHAT_ID) {
4757
+ return !params['id'];
4758
+ }
4759
+ return params['id'] === entityId;
4760
+ }
4761
+ //#endregion
4762
+ //#region ----- Helpers -----
4763
+ function isPageOrRecordLaunch(launch) {
4764
+ return launch.kind === AXM_MINI_CHAT_PAGE_CONTEXT_KIND || launch.kind === AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD;
4765
+ }
4766
+ function matchesLaunch(room, scope) {
4767
+ const launch = readLaunch(room);
4768
+ if (!launch || launch.kind !== scope.kind) {
4769
+ return false;
4770
+ }
4771
+ if (scope.actionName && launch.actionName !== scope.actionName) {
4772
+ return false;
4773
+ }
4774
+ return readText(launch.payload?.['recordId']) === scope.recordId;
4775
+ }
4776
+ function matchesEntity(room, entityType, entityIds) {
4777
+ const launch = readLaunch(room);
4778
+ if (launch && !isPageOrRecordLaunch(launch)) {
4779
+ return false;
4780
+ }
4781
+ const type = entityType.trim();
4782
+ for (const entityId of entityIds) {
4783
+ if (axmRoomMatchesEntity(room, { entityType: type, entityId })) {
4784
+ return true;
4785
+ }
4786
+ }
4787
+ if (!launch || launch.kind !== AXM_MINI_CHAT_PAGE_CONTEXT_KIND) {
4788
+ return false;
4789
+ }
4790
+ const records = readRecords(launch.payload).filter((record) => `${record.moduleName}.${record.entityName}` === type);
4791
+ const entity = readEntity(launch.payload);
4792
+ const pageType = entity ? `${entity.moduleName}.${entity.entityName}` : records[0] ? `${records[0].moduleName}.${records[0].entityName}` : '';
4793
+ if (pageType !== type) {
4794
+ return false;
4795
+ }
4796
+ if (entityIds.includes(AXM_ENTITY_LIST_CHAT_ID) && records.length === 0) {
4797
+ return true;
4798
+ }
4799
+ return entityIds.some((id) => id !== AXM_ENTITY_LIST_CHAT_ID && records.some((record) => record.id === id));
4800
+ }
4801
+ function readLaunch(room) {
4802
+ return axmRoomLaunchContext(room);
4803
+ }
4804
+ function readEntity(payload) {
4805
+ const value = payload?.['entity'];
4806
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
4807
+ return undefined;
4808
+ }
4809
+ const row = value;
4810
+ const moduleName = readText(row['moduleName']);
4811
+ const entityName = readText(row['entityName']);
4812
+ if (!moduleName || !entityName) {
4813
+ return undefined;
4814
+ }
4815
+ return { moduleName, entityName };
4816
+ }
4817
+ function readRecords(payload) {
4818
+ const value = payload?.['records'];
4819
+ if (!Array.isArray(value)) {
4820
+ return [];
4821
+ }
4822
+ const records = [];
4823
+ for (const item of value) {
4824
+ if (!item || typeof item !== 'object' || Array.isArray(item)) {
4825
+ continue;
4826
+ }
4827
+ const row = item;
4828
+ const id = readText(row['id']);
4829
+ const moduleName = readText(row['moduleName']);
4830
+ const entityName = readText(row['entityName']);
4831
+ if (id && moduleName && entityName) {
4832
+ records.push({ id, moduleName, entityName });
4833
+ }
4834
+ }
4835
+ return records;
4836
+ }
4837
+ function readText(value) {
4838
+ return typeof value === 'string' ? value.trim() : '';
4839
+ }
4840
+ //#endregion
4841
+
4842
+ //#region ---- Mini chat panel open options ----
4843
+ /** Session key used for the global inbox mini chat (non-entity conversations). */
4844
+ const AXM_MINI_CHAT_INBOX_SESSION_KEY = '__inbox__';
4845
+ /** Popup dock name for minimized mini-chat tabs in the root footer. */
4846
+ const AXM_MINI_CHAT_POPUP_DOCK = 'mini-chat';
4847
+ //#endregion
4848
+
4849
+ //#region ----- Imports -----
4850
+ //#endregion
4851
+ //#region ----- Constants -----
4852
+ const POPUP_CONTAINER_SELECTOR = '.axm-mini-chat-popup.ax-overlay-container';
4853
+ const OVERLAY_CONTENT_SELECTOR = ':scope > .ax-overlay-content';
4854
+ const POPUP_HOST_SELECTOR = 'ax-popup.ax-popup-host';
4855
+ const VIEWPORT_MARGIN_PX = 12;
4856
+ const MIN_SIDE_PX = 280;
4857
+ const MIN_POPUP_WIDTH_PX = 320;
4858
+ const MIN_POPUP_HEIGHT_PX = 280;
4859
+ const MOBILE_MAX_WIDTH_PX = 600;
4860
+ /** Previous browser-only store. Read once, then dropped after the frame moves to user settings. */
4861
+ const LEGACY_POSITION_STORAGE_KEY = 'axm-mini-chat-popup-position';
4862
+ //#endregion
4863
+ //#region ----- Anchor -----
4864
+ /** Resolves an overlay anchor to a live element. */
4865
+ function resolveMiniChatAnchorElement(anchor) {
4866
+ if (!anchor) {
4867
+ return null;
4868
+ }
4869
+ const element = anchor instanceof ElementRef ? anchor.nativeElement : anchor;
4870
+ return element instanceof HTMLElement ? element : null;
4871
+ }
4872
+ /**
4873
+ * Pins the open mini-chat popup beside its anchor (header button, page action, FAB).
4874
+ * Returns false while the popup host is not in the document yet.
4875
+ */
4876
+ function placeMiniChatPopupBesideAnchor(doc, options) {
4877
+ const view = doc.defaultView;
4878
+ const anchor = resolveMiniChatAnchorElement(options.anchor);
4879
+ if (!view || !anchor) {
4880
+ return false;
4881
+ }
4882
+ if (view.innerWidth <= MOBILE_MAX_WIDTH_PX) {
4883
+ return true;
4884
+ }
4885
+ const container = doc.querySelector(POPUP_CONTAINER_SELECTOR);
4886
+ const content = container?.querySelector(OVERLAY_CONTENT_SELECTOR);
4887
+ const host = container?.querySelector(POPUP_HOST_SELECTOR);
4888
+ const popup = host?.querySelector('.ax-popup');
4889
+ if (!container || !content || !host || !popup) {
4890
+ return false;
4891
+ }
4892
+ if (popup.classList.contains('ax-popup-fullscreen') || popup.classList.contains('ax-popup-minimized')) {
4893
+ return true;
4894
+ }
4895
+ const anchorRect = anchor.getBoundingClientRect();
4896
+ const popupRect = host.getBoundingClientRect();
4897
+ if (popupRect.height < 1 || popupRect.width < 1) {
4898
+ return false;
4899
+ }
4900
+ const viewportWidth = doc.documentElement.clientWidth;
4901
+ const viewportHeight = doc.documentElement.clientHeight;
4902
+ const isRtl = view.getComputedStyle(doc.documentElement).direction === 'rtl';
4903
+ const offsetX = options.offsetX ?? 0;
4904
+ const offsetY = options.offsetY ?? 0;
4905
+ const placement = resolvePlacement(options.placement, anchorRect, viewportHeight, offsetY, options.autoFlip !== false);
4906
+ const savedSize = readSavedPopupSize();
4907
+ let popupWidth = popupRect.width;
4908
+ const inlineEndGap = (isRtl ? anchorRect.left : viewportWidth - anchorRect.right) + offsetX;
4909
+ const inlineStartGap = (isRtl ? viewportWidth - anchorRect.right : anchorRect.left) + offsetX;
4910
+ if (savedSize) {
4911
+ const sizeLimit = placement.axis === 'bottom'
4912
+ ? viewportHeight - anchorRect.bottom - offsetY - VIEWPORT_MARGIN_PX
4913
+ : anchorRect.top - offsetY - VIEWPORT_MARGIN_PX;
4914
+ const size = clampPopupSize(savedSize.width, savedSize.height, viewportWidth - VIEWPORT_MARGIN_PX * 2, sizeLimit);
4915
+ applyPopupSize(popup, size);
4916
+ popupWidth = size.width;
4917
+ }
4918
+ let paddingInlineEnd = 0;
4919
+ let paddingInlineStart = 0;
4920
+ if (placement.align === 'end') {
4921
+ paddingInlineEnd = clampInlinePadding(inlineEndGap, popupWidth, viewportWidth);
4922
+ }
4923
+ else if (placement.align === 'start') {
4924
+ paddingInlineStart = clampInlinePadding(inlineStartGap, popupWidth, viewportWidth);
4925
+ }
4926
+ const availableHeight = placement.axis === 'bottom'
4927
+ ? viewportHeight - anchorRect.bottom - offsetY - VIEWPORT_MARGIN_PX
4928
+ : anchorRect.top - offsetY - VIEWPORT_MARGIN_PX;
4929
+ container.classList.add('axm-mini-chat-popup--anchored');
4930
+ container.style.setProperty('--axm-mini-chat-available-height', `${Math.max(MIN_SIDE_PX, availableHeight)}px`);
4931
+ content.style.justifyContent = placement.axis === 'bottom' ? 'flex-start' : 'flex-end';
4932
+ content.style.alignItems = toFlexAlign(placement.align);
4933
+ content.style.paddingTop = placement.axis === 'bottom' ? `${Math.max(0, anchorRect.bottom + offsetY)}px` : '0px';
4934
+ content.style.paddingBottom = placement.axis === 'top' ? `${Math.max(0, viewportHeight - anchorRect.top + offsetY)}px` : '0px';
4935
+ content.style.paddingInlineEnd = `${paddingInlineEnd}px`;
4936
+ content.style.paddingInlineStart = `${paddingInlineStart}px`;
4937
+ host.style.alignSelf = toFlexAlign(placement.align);
4938
+ return true;
4939
+ }
4940
+ /** True after the user has dragged the window away from its layout origin. */
4941
+ function miniChatPopupWasDragged(doc) {
4942
+ const popup = doc.querySelector(`${POPUP_CONTAINER_SELECTOR} .ax-popup`);
4943
+ return readDragOffset(popup) != null;
4944
+ }
4945
+ /** Remembers header-drag position and resize size when the pointer is released. */
4946
+ function captureMiniChatPopupPosition(doc) {
4947
+ const view = doc.defaultView;
4948
+ const nodes = queryMiniChatPopupNodes(doc);
4949
+ if (!view || !nodes || view.innerWidth <= MOBILE_MAX_WIDTH_PX) {
4950
+ return null;
4951
+ }
4952
+ if (nodes.popup.classList.contains('ax-popup-fullscreen') || nodes.popup.classList.contains('ax-popup-minimized')) {
4953
+ return null;
4954
+ }
4955
+ const dragged = readDragOffset(nodes.popup) != null;
4956
+ const resized = readInlinePopupSize(nodes.popup);
4957
+ if (!dragged && !resized) {
4958
+ return null;
4959
+ }
4960
+ const rect = nodes.popup.getBoundingClientRect();
4961
+ if (rect.width < 1 || rect.height < 1) {
4962
+ return null;
4963
+ }
4964
+ const next = { ...readMiniChatPopupPosition() };
4965
+ if (dragged) {
4966
+ const point = clampPopupPoint(doc, { x: rect.left, y: rect.top }, rect.width, rect.height);
4967
+ next.x = point.x;
4968
+ next.y = point.y;
4969
+ }
4970
+ if (resized) {
4971
+ next.width = Math.round(resized.width);
4972
+ next.height = Math.round(resized.height);
4973
+ }
4974
+ writeMiniChatPopupPosition(next);
4975
+ return next;
4976
+ }
4977
+ /**
4978
+ * Loads the window frame from user settings. A leftover local store is used only when both settings are empty.
4979
+ */
4980
+ function seedMiniChatPopupFrame(position, size) {
4981
+ if (frameHydrated) {
4982
+ return { frame: memoryPosition, migratedFromLocalStorage: false };
4983
+ }
4984
+ frameHydrated = true;
4985
+ const fromSettings = readSettingsFrame(position, size);
4986
+ if (fromSettings) {
4987
+ memoryPosition = fromSettings;
4988
+ return { frame: memoryPosition, migratedFromLocalStorage: false };
4989
+ }
4990
+ const legacy = readLegacyStoredPopupPosition();
4991
+ if (!legacy) {
4992
+ return { frame: null, migratedFromLocalStorage: false };
4993
+ }
4994
+ memoryPosition = legacy;
4995
+ return { frame: memoryPosition, migratedFromLocalStorage: true };
4996
+ }
4997
+ /** Drops the old browser-only frame after it has been written to user settings. */
4998
+ function clearLegacyMiniChatPopupFrame() {
4999
+ clearLegacyStoredPopupPosition();
5000
+ }
5001
+ /** Last header-drag position, or null when the window should stay beside its opener. */
5002
+ function readMiniChatPopupPosition() {
5003
+ return memoryPosition;
5004
+ }
5005
+ /**
5006
+ * Places the open popup at a saved viewport point.
5007
+ * Returns false while the popup host is not in the document yet.
5008
+ */
5009
+ function placeMiniChatPopupAtPoint(doc, point) {
5010
+ const view = doc.defaultView;
5011
+ if (!view) {
5012
+ return false;
5013
+ }
5014
+ if (view.innerWidth <= MOBILE_MAX_WIDTH_PX) {
5015
+ return true;
5016
+ }
5017
+ const nodes = queryMiniChatPopupNodes(doc);
5018
+ if (!nodes) {
5019
+ return false;
5020
+ }
5021
+ if (nodes.popup.classList.contains('ax-popup-fullscreen') || nodes.popup.classList.contains('ax-popup-minimized')) {
5022
+ return true;
5023
+ }
5024
+ const rect = nodes.host.getBoundingClientRect();
5025
+ if (rect.width < 1 || rect.height < 1) {
5026
+ return false;
5027
+ }
5028
+ const width = point.width ?? rect.width;
5029
+ const height = point.height ?? rect.height;
5030
+ const clamped = clampPopupPoint(doc, { x: point.x ?? 0, y: point.y ?? 0 }, width, height);
5031
+ if (point.width != null && point.height != null) {
5032
+ const maxHeight = doc.documentElement.clientHeight - clamped.y - VIEWPORT_MARGIN_PX;
5033
+ applyPopupSize(nodes.popup, clampPopupSize(point.width, point.height, doc.documentElement.clientWidth - VIEWPORT_MARGIN_PX * 2, maxHeight));
5034
+ }
5035
+ const availableHeight = doc.documentElement.clientHeight - clamped.y - VIEWPORT_MARGIN_PX;
5036
+ nodes.container.classList.add('axm-mini-chat-popup--anchored');
5037
+ nodes.container.style.setProperty('--axm-mini-chat-available-height', `${Math.max(MIN_SIDE_PX, availableHeight)}px`);
5038
+ nodes.content.style.position = 'relative';
5039
+ nodes.content.style.justifyContent = 'flex-start';
5040
+ nodes.content.style.alignItems = 'flex-start';
5041
+ nodes.content.style.padding = '0px';
5042
+ nodes.host.style.position = 'absolute';
5043
+ nodes.host.style.top = `${clamped.y}px`;
5044
+ nodes.host.style.left = `${clamped.x}px`;
5045
+ nodes.host.style.right = 'auto';
5046
+ nodes.host.style.margin = '0';
5047
+ nodes.host.style.alignSelf = 'flex-start';
5048
+ return true;
5049
+ }
5050
+ //#endregion
5051
+ //#region ----- Placement -----
5052
+ function resolvePlacement(placement, anchorRect, viewportHeight, offsetY, autoFlip) {
5053
+ const normalized = normalizePlacement(placement ?? 'bottom-end');
5054
+ if (!autoFlip) {
5055
+ return normalized;
5056
+ }
5057
+ const spaceBelow = viewportHeight - anchorRect.bottom - offsetY - VIEWPORT_MARGIN_PX;
5058
+ const spaceAbove = anchorRect.top - offsetY - VIEWPORT_MARGIN_PX;
5059
+ if (normalized.axis === 'bottom' && spaceBelow < MIN_SIDE_PX && spaceAbove > spaceBelow) {
5060
+ return { ...normalized, axis: 'top' };
5061
+ }
5062
+ if (normalized.axis === 'top' && spaceAbove < MIN_SIDE_PX && spaceBelow > spaceAbove) {
5063
+ return { ...normalized, axis: 'bottom' };
5064
+ }
5065
+ return normalized;
5066
+ }
5067
+ function normalizePlacement(placement) {
5068
+ const aliases = {
5069
+ 'top-left': 'top-start',
5070
+ 'top-right': 'top-end',
5071
+ 'bottom-left': 'bottom-start',
5072
+ 'bottom-right': 'bottom-end',
5073
+ left: 'start',
5074
+ right: 'end',
5075
+ };
5076
+ const value = aliases[placement] ?? placement;
5077
+ const [primary, align] = value.split('-');
5078
+ if (primary === 'top' || primary === 'bottom') {
5079
+ return {
5080
+ axis: primary,
5081
+ align: align === 'start' || align === 'end' ? align : 'center',
5082
+ };
5083
+ }
5084
+ return { axis: 'bottom', align: 'end' };
5085
+ }
5086
+ function toFlexAlign(align) {
5087
+ if (align === 'start') {
5088
+ return 'flex-start';
5089
+ }
5090
+ if (align === 'end') {
5091
+ return 'flex-end';
5092
+ }
5093
+ return 'center';
5094
+ }
5095
+ function clampInlinePadding(gap, popupWidth, viewportWidth) {
5096
+ const maxPad = Math.max(0, viewportWidth - popupWidth - VIEWPORT_MARGIN_PX);
5097
+ return Math.min(Math.max(0, gap), maxPad);
5098
+ }
5099
+ function queryMiniChatPopupNodes(doc) {
5100
+ const container = doc.querySelector(POPUP_CONTAINER_SELECTOR);
5101
+ const content = container?.querySelector(OVERLAY_CONTENT_SELECTOR) ?? null;
5102
+ const host = container?.querySelector(POPUP_HOST_SELECTOR) ?? null;
5103
+ const popup = host?.querySelector('.ax-popup') ?? null;
5104
+ if (!container || !content || !host || !popup) {
5105
+ return null;
5106
+ }
5107
+ return { container, content, host, popup };
5108
+ }
5109
+ function readDragOffset(popup) {
5110
+ if (!popup) {
5111
+ return null;
5112
+ }
5113
+ const raw = popup.style.translate.trim() || popup.style.transform.trim();
5114
+ if (!raw || raw === 'none') {
5115
+ return null;
5116
+ }
5117
+ const match = /(-?\d+(?:\.\d+)?)px\s+(-?\d+(?:\.\d+)?)px/.exec(raw);
5118
+ if (!match) {
5119
+ return null;
5120
+ }
5121
+ const x = Number.parseFloat(match[1] ?? '');
5122
+ const y = Number.parseFloat(match[2] ?? '');
5123
+ if (!Number.isFinite(x) || !Number.isFinite(y) || (Math.abs(x) < 1 && Math.abs(y) < 1)) {
5124
+ return null;
5125
+ }
5126
+ return { x, y };
5127
+ }
5128
+ function clampPopupPoint(doc, point, width, height) {
5129
+ const viewportWidth = doc.documentElement.clientWidth;
5130
+ const viewportHeight = doc.documentElement.clientHeight;
5131
+ const maxX = Math.max(VIEWPORT_MARGIN_PX, viewportWidth - width - VIEWPORT_MARGIN_PX);
5132
+ const maxY = Math.max(VIEWPORT_MARGIN_PX, viewportHeight - Math.min(height, viewportHeight - VIEWPORT_MARGIN_PX * 2) - VIEWPORT_MARGIN_PX);
5133
+ return {
5134
+ x: Math.min(Math.max(point.x, VIEWPORT_MARGIN_PX), maxX),
5135
+ y: Math.min(Math.max(point.y, VIEWPORT_MARGIN_PX), maxY),
5136
+ };
5137
+ }
5138
+ let memoryPosition = null;
5139
+ let frameHydrated = false;
5140
+ function readSavedPopupSize() {
5141
+ const saved = readMiniChatPopupPosition();
5142
+ if (saved?.width == null || saved.height == null) {
5143
+ return null;
5144
+ }
5145
+ return { width: saved.width, height: saved.height };
5146
+ }
5147
+ function readInlinePopupSize(popup) {
5148
+ const width = parsePx(popup.style.width);
5149
+ const height = parsePx(popup.style.height);
5150
+ if (width == null || height == null) {
5151
+ return null;
5152
+ }
5153
+ return { width, height };
5154
+ }
5155
+ function parsePx(value) {
5156
+ const match = /^(\d+(?:\.\d+)?)px$/.exec(value.trim());
5157
+ if (!match) {
5158
+ return null;
5159
+ }
5160
+ const parsed = Number.parseFloat(match[1] ?? '');
5161
+ return Number.isFinite(parsed) ? parsed : null;
5162
+ }
5163
+ function applyPopupSize(popup, size) {
5164
+ popup.style.width = `${Math.round(size.width)}px`;
5165
+ popup.style.height = `${Math.round(size.height)}px`;
5166
+ popup.style.maxWidth = 'none';
5167
+ popup.style.maxHeight = 'none';
5168
+ }
5169
+ function clampPopupSize(width, height, maxWidth, maxHeight) {
5170
+ return {
5171
+ width: Math.min(Math.max(width, MIN_POPUP_WIDTH_PX), Math.max(MIN_POPUP_WIDTH_PX, maxWidth)),
5172
+ height: Math.min(Math.max(height, MIN_POPUP_HEIGHT_PX), Math.max(MIN_POPUP_HEIGHT_PX, maxHeight)),
5173
+ };
5174
+ }
5175
+ function readSettingsFrame(position, size) {
5176
+ const point = readPointSetting(position);
5177
+ const popupSize = readSizeSetting(size);
5178
+ if (!point && !popupSize) {
5179
+ return null;
5180
+ }
5181
+ return {
5182
+ ...(point ?? {}),
5183
+ ...(popupSize ?? {}),
5184
+ };
5185
+ }
5186
+ function readPointSetting(value) {
5187
+ const record = readSettingRecord(value);
5188
+ if (!record) {
5189
+ return null;
5190
+ }
5191
+ const x = readFinite(record['x']);
5192
+ const y = readFinite(record['y']);
5193
+ if (x == null || y == null) {
5194
+ return null;
5195
+ }
5196
+ return { x, y };
5197
+ }
5198
+ function readSizeSetting(value) {
5199
+ const record = readSettingRecord(value);
5200
+ if (!record) {
5201
+ return null;
5202
+ }
5203
+ const width = readFinite(record['width']);
5204
+ const height = readFinite(record['height']);
5205
+ if (width == null || height == null || width < MIN_POPUP_WIDTH_PX || height < MIN_POPUP_HEIGHT_PX) {
5206
+ return null;
5207
+ }
5208
+ return { width, height };
5209
+ }
5210
+ function readSettingRecord(value) {
5211
+ const unwrapped = unwrapSettingValue(value);
5212
+ if (!unwrapped || typeof unwrapped !== 'object') {
5213
+ return null;
5214
+ }
5215
+ return unwrapped;
5216
+ }
5217
+ function unwrapSettingValue(value) {
5218
+ if (typeof value === 'string') {
5219
+ const trimmed = value.trim();
5220
+ if (!trimmed) {
5221
+ return null;
5222
+ }
5223
+ try {
5224
+ return unwrapSettingValue(JSON.parse(trimmed));
5225
+ }
5226
+ catch {
5227
+ return null;
5228
+ }
5229
+ }
5230
+ if (value && typeof value === 'object' && 'value' in value) {
5231
+ return unwrapSettingValue(value.value);
5232
+ }
5233
+ return value;
5234
+ }
5235
+ function readLegacyStoredPopupPosition() {
5236
+ try {
5237
+ const raw = localStorage.getItem(LEGACY_POSITION_STORAGE_KEY);
5238
+ if (!raw) {
5239
+ return null;
5240
+ }
5241
+ return readSettingsFrame(JSON.parse(raw), JSON.parse(raw));
5242
+ }
5243
+ catch {
5244
+ return null;
5245
+ }
5246
+ }
5247
+ function clearLegacyStoredPopupPosition() {
5248
+ try {
5249
+ localStorage.removeItem(LEGACY_POSITION_STORAGE_KEY);
5250
+ }
5251
+ catch {
5252
+ // The in-memory frame is already loaded; a blocked store can stay until the next visit.
5253
+ }
5254
+ }
5255
+ function readFinite(value) {
5256
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
5257
+ }
5258
+ function writeMiniChatPopupPosition(point) {
5259
+ frameHydrated = true;
5260
+ memoryPosition = point;
5261
+ }
5262
+ //#endregion
5263
+
5264
+ const AXM_ASSIST_DEFAULT_RESOLVER_PORT = new InjectionToken('AXM_ASSIST_DEFAULT_RESOLVER_PORT');
5265
+
5266
+ //#region ---- Imports ----
5267
+ //#endregion
5268
+ //#region ---- Service ----
5269
+ /**
5270
+ * Backing service for the entity-scoped mini chat: finds the conversations bound to an entity
5271
+ * (an entity may have several) and prepares the create payload for a new entity assist chat.
5272
+ *
5273
+ * Conversation creation/selection is performed by the caller using its own
5274
+ * {@link AXConversationService} instance so the mini chat keeps its active-selection state
5275
+ * isolated from the main chat page.
5276
+ */
5277
+ class AXMEntityChatService {
5278
+ constructor() {
5279
+ //#region ---- Services & Dependencies ----
5280
+ this.injector = inject(Injector);
5281
+ this.conversationService = inject(AXConversationService);
5282
+ this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
5283
+ this.translationService = inject(AXTranslationService);
5284
+ this.defaultAssistResolver = inject(AXM_ASSIST_DEFAULT_RESOLVER_PORT, { optional: true });
5285
+ }
5286
+ //#endregion
5287
+ //#region ---- Lazy dependencies ----
5288
+ /**
5289
+ * Resolved lazily: this service is `providedIn: 'root'` but depends on module-scoped chat APIs
5290
+ * and optional AI services that must not be requested during the same hydration pass as chat UI.
5291
+ */
5292
+ get conversationApi() {
5293
+ return this.injector.get(AXMChatConversationApi);
5294
+ }
5295
+ //#endregion
5296
+ //#region ---- Public Methods ----
5297
+ /** Returns every conversation bound to the given entity reference. */
5298
+ findEntityConversations(ref) {
5299
+ return this.conversationApi.findEntityConversations(ref.entityType.trim(), ref.entityId.trim());
5300
+ }
5301
+ /** History for one mini-chat surface: global, an entity or record, or a launch such as form designer. */
5302
+ findHistoryConversations(scope) {
5303
+ return this.conversationApi.findHistoryConversations(scope);
5304
+ }
5305
+ /**
5306
+ * Creates a new entity-scoped assist conversation and selects it.
5307
+ * Must go through {@link AXConversationService.createConversation} so the open mini-chat
5308
+ * instance owns the thread; the inbox tab filter hides entity rooms from `/chat/`.
5309
+ */
5310
+ async createEntityChat(ref, assistId, extraMetadata) {
5311
+ const createData = await this.buildEntityChatCreateData(ref, assistId, extraMetadata);
5312
+ const conversation = await this.conversationService.createConversation(createData.participantIds, createData.type, createData.options);
5313
+ await this.conversationService.selectConversation(conversation.id);
5314
+ this.conversationApi.reportFocusedConversation(conversation.id);
5315
+ return conversation;
5316
+ }
5317
+ /**
5318
+ * Builds the `createConversation` payload for a new entity assist chat.
5319
+ * Uses `assistId` when provided, otherwise the tenant default assist.
5320
+ */
5321
+ async buildEntityChatCreateData(ref, assistId, extraMetadata) {
5322
+ const row = await this.resolveAssistRow(assistId);
5323
+ const avatar = axmChatAiTargetAvatarUrl(row);
5324
+ return {
5325
+ participantIds: [axmChatAiPeerParticipantId(row.id)],
5326
+ type: 'bot',
5327
+ options: {
5328
+ title: this.resolveTitle(row),
5329
+ ...(avatar ? { avatar } : {}),
5330
+ icon: 'fa-solid fa-robot',
5331
+ metadata: {
5332
+ ...extraMetadata,
5333
+ ...axmBuildEntityChatConversationMetadata({
5334
+ entityId: ref.entityId,
5335
+ entityType: ref.entityType,
5336
+ assistId: row.id,
5337
+ }),
5338
+ },
5339
+ },
5340
+ };
5341
+ }
5342
+ //#endregion
5343
+ //#region ---- Utility Methods ----
5344
+ /** Resolves the assist catalog row to chat with (explicit id → tenant default → first row). */
5345
+ async resolveAssistRow(assistId) {
5346
+ const rows = await axmLoadChatAiTargets(this.entityRegistry);
5347
+ if (!rows.length) {
5348
+ throw new Error('No assist targets are available to start an entity chat.');
5349
+ }
5350
+ const requestedId = assistId?.trim() || (await this.resolveDefaultAssistId());
5351
+ const match = requestedId ? rows.find((row) => row.id === requestedId) : undefined;
5352
+ return match ?? rows[0];
5353
+ }
5354
+ async resolveDefaultAssistId() {
5355
+ if (!this.defaultAssistResolver) {
5356
+ return undefined;
5357
+ }
5358
+ try {
5359
+ return await this.defaultAssistResolver.getDefaultAssistId();
5360
+ }
5361
+ catch (error) {
5362
+ console.warn('Failed to resolve default assist for entity mini chat:', error);
5363
+ return undefined;
5364
+ }
5365
+ }
5366
+ resolveTitle(row) {
5367
+ return this.translationService.resolve(row.title) ?? row.name;
5368
+ }
5369
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5370
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, providedIn: 'root' }); }
5371
+ }
5372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMEntityChatService, decorators: [{
5373
+ type: Injectable,
5374
+ args: [{ providedIn: 'root' }]
5375
+ }] });
5376
+
5377
+ //#region ---- Conversation list sort ----
5378
+ /** Pinned flag on room or legacy mock metadata (`metadata.isPinned`). */
5379
+ function axmIsConversationPinned(conversation) {
5380
+ return Boolean(conversation.pinned) || conversation.metadata?.['isPinned'] === true;
5381
+ }
5382
+ /** Latest activity time from embedded last message or `lastMessageAt`. */
5383
+ function axmConversationLastMessageMs(conversation) {
5384
+ const ts = conversation.lastMessage?.timestamp ?? conversation.lastMessageAt;
5385
+ return axmCoerceTimestampMs(ts);
5386
+ }
5387
+ /** Pinned conversations first, then most recent `lastMessageAt` (mock inbox parity). */
5388
+ function axmSortConversationsByPinAndRecency(conversations) {
5389
+ return [...conversations].sort((a, b) => {
5390
+ const aPinned = axmIsConversationPinned(a);
5391
+ const bPinned = axmIsConversationPinned(b);
5392
+ if (aPinned !== bPinned) {
5393
+ return aPinned ? -1 : 1;
5394
+ }
5395
+ return axmConversationLastMessageMs(b) - axmConversationLastMessageMs(a);
5396
+ });
5397
+ }
5398
+ //#endregion
5399
+
5400
+ //#region ----- Imports -----
5401
+ //#endregion
5402
+ //#region ----- History list patches -----
5403
+ /** Inserts or replaces a conversation in a mini-chat history list, then re-sorts. */
5404
+ function axmUpsertMiniChatHistoryItem(items, next, matches) {
5405
+ if (!matches(next)) {
5406
+ return items.filter((item) => item.id !== next.id);
5407
+ }
5408
+ return axmSortConversationsByPinAndRecency([next, ...items.filter((item) => item.id !== next.id)]);
5409
+ }
5410
+ /** Removes a conversation from a mini-chat history list. */
5411
+ function axmRemoveMiniChatHistoryItem(items, conversationId) {
5412
+ const scoped = conversationId.trim();
5413
+ if (!scoped) {
5414
+ return items;
5415
+ }
5416
+ return items.filter((item) => item.id !== scoped);
5417
+ }
5418
+ //#endregion
5419
+
5420
+ //#endregion
5421
+ //#region ---- Component ----
5422
+ /**
5423
+ * Scrollable list of entity-scoped conversations for the mini chat panel.
4554
5424
  * Loads chats via {@link AXMEntityChatService.findEntityConversations}.
4555
5425
  */
4556
5426
  class AXMMiniChatHistoryComponent {
5427
+ //#endregion
5428
+ //#region ---- Lifecycle ----
4557
5429
  constructor() {
4558
5430
  //#region ---- Services & Dependencies ----
4559
5431
  this.entityChatService = inject(AXMEntityChatService);
@@ -4575,33 +5447,46 @@ class AXMMiniChatHistoryComponent {
4575
5447
  ...(ngDevMode ? [{ debugName: "conversations" }] : /* istanbul ignore next */ []));
4576
5448
  this.loading = signal(false, /* @ts-ignore */
4577
5449
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
5450
+ this.refreshGeneration = 0;
5451
+ effect(() => {
5452
+ const entityId = this.entityId();
5453
+ const entityType = this.entityType();
5454
+ untracked(() => void this.refresh(entityId, entityType));
5455
+ });
4578
5456
  }
4579
- //#endregion
4580
- //#region ---- Lifecycle ----
4581
5457
  ngOnInit() {
4582
5458
  this.bindRealtimeHistory();
4583
- void this.refresh();
4584
5459
  }
4585
5460
  //#endregion
4586
5461
  //#region ---- Public Methods ----
4587
5462
  /** Reloads the entity conversation list (call when the history panel becomes visible). */
4588
- async refresh() {
5463
+ async refresh(entityId = this.entityId(), entityType = this.entityType()) {
5464
+ const generation = ++this.refreshGeneration;
4589
5465
  this.loading.set(true);
4590
5466
  try {
4591
- const items = await this.entityChatService.findEntityConversations({
4592
- entityId: this.entityId(),
4593
- entityType: this.entityType(),
5467
+ const items = await this.entityChatService.findHistoryConversations({
5468
+ mode: 'entity',
5469
+ entityType,
5470
+ entityIds: [entityId],
4594
5471
  });
5472
+ if (generation !== this.refreshGeneration) {
5473
+ return;
5474
+ }
4595
5475
  this.conversations.set(items);
4596
5476
  this.hasConversationsChange.emit(items.length > 0);
4597
5477
  }
4598
5478
  catch (error) {
5479
+ if (generation !== this.refreshGeneration) {
5480
+ return;
5481
+ }
4599
5482
  console.error('Failed to load entity mini chat history:', error);
4600
5483
  this.conversations.set([]);
4601
5484
  this.hasConversationsChange.emit(false);
4602
5485
  }
4603
5486
  finally {
4604
- this.loading.set(false);
5487
+ if (generation === this.refreshGeneration) {
5488
+ this.loading.set(false);
5489
+ }
4605
5490
  }
4606
5491
  }
4607
5492
  //#endregion
@@ -4610,9 +5495,10 @@ class AXMMiniChatHistoryComponent {
4610
5495
  merge(this.realtimeBus.conversationCreated$, this.realtimeBus.conversationUpdates$)
4611
5496
  .pipe(takeUntilDestroyed(this.destroyRef))
4612
5497
  .subscribe((conversation) => {
4613
- const next = axmUpsertMiniChatHistoryItem(this.conversations(), conversation, (item) => axmConversationMatchesEntity(item.metadata, {
4614
- entityId: this.entityId(),
5498
+ const next = axmUpsertMiniChatHistoryItem(this.conversations(), conversation, (item) => axmConversationMatchesHistoryScope(item, {
5499
+ mode: 'entity',
4615
5500
  entityType: this.entityType(),
5501
+ entityIds: [this.entityId()],
4616
5502
  }));
4617
5503
  this.conversations.set(next);
4618
5504
  this.hasConversationsChange.emit(next.length > 0);
@@ -4722,7 +5608,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4722
5608
  </div>
4723
5609
  </div>
4724
5610
  `, styles: [":host{display:flex;min-height:0;flex:1;flex-direction:column}.axm-mini-chat-history__item{color:inherit}\n"] }]
4725
- }], propDecorators: { entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: true }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: true }] }], conversationSelected: [{ type: i0.Output, args: ["conversationSelected"] }], hasConversationsChange: [{ type: i0.Output, args: ["hasConversationsChange"] }] } });
5611
+ }], ctorParameters: () => [], propDecorators: { entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: true }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: true }] }], conversationSelected: [{ type: i0.Output, args: ["conversationSelected"] }], hasConversationsChange: [{ type: i0.Output, args: ["hasConversationsChange"] }] } });
4726
5612
 
4727
5613
  const AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER = new InjectionToken('AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER');
4728
5614
 
@@ -4733,14 +5619,19 @@ const AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER = new InjectionToken('AXM_MINI_CHA
4733
5619
  * Compact scrollable list of inbox AI-assist chats (non-entity bot / assist conversations).
4734
5620
  */
4735
5621
  class AXMMiniChatInboxHistoryComponent {
5622
+ //#endregion
5623
+ //#region ---- Lifecycle ----
4736
5624
  constructor() {
4737
5625
  //#region ---- Services & Dependencies ----
4738
- this.conversationApi = inject(AXMChatConversationApi);
5626
+ this.entityChatService = inject(AXMEntityChatService);
4739
5627
  this.conversationFilter = inject(AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER, { optional: true });
4740
5628
  this.realtimeBus = inject(AXMConversationRealtimeBus);
4741
5629
  this.destroyRef = inject(DestroyRef);
4742
5630
  //#endregion
4743
- //#region ---- Outputs ----
5631
+ //#region ---- Inputs / Outputs ----
5632
+ /** Which chats to list. Defaults to global (no entity and no surface). */
5633
+ this.scope = input({ mode: 'global' }, /* @ts-ignore */
5634
+ ...(ngDevMode ? [{ debugName: "scope" }] : /* istanbul ignore next */ []));
4744
5635
  /** Emits when the user picks a conversation from the list. */
4745
5636
  this.conversationSelected = output();
4746
5637
  /** Emits whether the loaded history contains at least one conversation. */
@@ -4751,31 +5642,42 @@ class AXMMiniChatInboxHistoryComponent {
4751
5642
  ...(ngDevMode ? [{ debugName: "conversations" }] : /* istanbul ignore next */ []));
4752
5643
  this.loading = signal(false, /* @ts-ignore */
4753
5644
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
5645
+ this.refreshGeneration = 0;
5646
+ effect(() => {
5647
+ const scope = this.scope();
5648
+ untracked(() => void this.refresh(scope));
5649
+ });
4754
5650
  }
4755
- //#endregion
4756
- //#region ---- Lifecycle ----
4757
5651
  ngOnInit() {
4758
5652
  this.bindRealtimeHistory();
4759
- void this.refresh();
4760
5653
  }
4761
5654
  //#endregion
4762
5655
  //#region ---- Public Methods ----
4763
- /** Reloads AI-assist inbox conversations. */
4764
- async refresh() {
5656
+ /** Reloads conversations for the current history scope. */
5657
+ async refresh(scope = this.scope()) {
5658
+ const generation = ++this.refreshGeneration;
4765
5659
  this.loading.set(true);
4766
5660
  try {
4767
- const result = await this.conversationApi.getConversations({ page: 0, pageSize: 100 });
4768
- const items = (result.items ?? []).filter((conversation) => !axmRoomIsEntityChat(conversation) && (this.conversationFilter ? this.conversationFilter(conversation) : true));
5661
+ const loaded = await this.entityChatService.findHistoryConversations(scope);
5662
+ if (generation !== this.refreshGeneration) {
5663
+ return;
5664
+ }
5665
+ const items = loaded.filter((conversation) => (this.conversationFilter ? this.conversationFilter(conversation) : true));
4769
5666
  this.conversations.set(items);
4770
5667
  this.hasConversationsChange.emit(items.length > 0);
4771
5668
  }
4772
5669
  catch (error) {
4773
- console.error('Failed to load inbox AI assist mini chat history:', error);
5670
+ if (generation !== this.refreshGeneration) {
5671
+ return;
5672
+ }
5673
+ console.error('Failed to load mini chat history:', error);
4774
5674
  this.conversations.set([]);
4775
5675
  this.hasConversationsChange.emit(false);
4776
5676
  }
4777
5677
  finally {
4778
- this.loading.set(false);
5678
+ if (generation === this.refreshGeneration) {
5679
+ this.loading.set(false);
5680
+ }
4779
5681
  }
4780
5682
  }
4781
5683
  //#endregion
@@ -4795,7 +5697,8 @@ class AXMMiniChatInboxHistoryComponent {
4795
5697
  });
4796
5698
  }
4797
5699
  matchesInbox(conversation) {
4798
- return !axmRoomIsEntityChat(conversation) && (this.conversationFilter ? this.conversationFilter(conversation) : true);
5700
+ return (axmConversationMatchesHistoryScope(conversation, this.scope()) &&
5701
+ (this.conversationFilter ? this.conversationFilter(conversation) : true));
4799
5702
  }
4800
5703
  //#endregion
4801
5704
  //#region ---- UI Handlers ----
@@ -4806,7 +5709,7 @@ class AXMMiniChatInboxHistoryComponent {
4806
5709
  this.conversationSelected.emit(conversationId);
4807
5710
  }
4808
5711
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatInboxHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4809
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatInboxHistoryComponent, isStandalone: true, selector: "axm-mini-chat-inbox-history", outputs: { conversationSelected: "conversationSelected", hasConversationsChange: "hasConversationsChange" }, ngImport: i0, template: `
5712
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatInboxHistoryComponent, isStandalone: true, selector: "axm-mini-chat-inbox-history", inputs: { scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationSelected: "conversationSelected", hasConversationsChange: "hasConversationsChange" }, ngImport: i0, template: `
4810
5713
  <div class="axm-mini-chat-inbox-history flex min-h-0 flex-1 flex-col">
4811
5714
  <div class="min-h-0 flex-1 overflow-auto px-2 py-2">
4812
5715
  @if (loading()) {
@@ -4855,7 +5758,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4855
5758
  </div>
4856
5759
  </div>
4857
5760
  `, styles: [":host{display:flex;min-height:0;flex:1;flex-direction:column}.axm-mini-chat-inbox-history__item{color:inherit}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
4858
- }], propDecorators: { conversationSelected: [{ type: i0.Output, args: ["conversationSelected"] }], hasConversationsChange: [{ type: i0.Output, args: ["hasConversationsChange"] }] } });
5761
+ }], ctorParameters: () => [], propDecorators: { scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }], conversationSelected: [{ type: i0.Output, args: ["conversationSelected"] }], hasConversationsChange: [{ type: i0.Output, args: ["hasConversationsChange"] }] } });
5762
+
5763
+ //#region ----- Imports -----
5764
+ //#endregion
5765
+ //#region ----- Service -----
5766
+ /**
5767
+ * Lets the mini-chat window add files to the empty-state composer
5768
+ * the same way its attachment button does.
5769
+ */
5770
+ class AXMMiniChatFileDropService {
5771
+ constructor() {
5772
+ //#region ----- State -----
5773
+ this.emptyDraftAdder = null;
5774
+ this.pendingEmptyDraft = [];
5775
+ }
5776
+ //#endregion
5777
+ //#region ----- Public API -----
5778
+ /** Compact empty composer registers while it is the visible new-chat surface. */
5779
+ registerEmptyDraftAdder(add) {
5780
+ this.emptyDraftAdder = add;
5781
+ if (this.pendingEmptyDraft.length > 0) {
5782
+ const queued = this.pendingEmptyDraft;
5783
+ this.pendingEmptyDraft = [];
5784
+ add(queued);
5785
+ }
5786
+ return () => {
5787
+ if (this.emptyDraftAdder === add) {
5788
+ this.emptyDraftAdder = null;
5789
+ }
5790
+ };
5791
+ }
5792
+ /**
5793
+ * Adds files to the empty composer when it is mounted.
5794
+ * Queues them when the thread is about to show that composer.
5795
+ */
5796
+ addEmptyDraftFiles(files) {
5797
+ if (files.length === 0) {
5798
+ return;
5799
+ }
5800
+ const adder = this.emptyDraftAdder;
5801
+ if (adder) {
5802
+ adder(files);
5803
+ return;
5804
+ }
5805
+ this.pendingEmptyDraft.push(...files);
5806
+ }
5807
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatFileDropService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5808
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatFileDropService, providedIn: 'root' }); }
5809
+ }
5810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatFileDropService, decorators: [{
5811
+ type: Injectable,
5812
+ args: [{ providedIn: 'root' }]
5813
+ }] });
4859
5814
 
4860
5815
  const ASSIST_INITIAL_MESSAGES_MAX_LENGTH = 16_000;
4861
5816
  function stripAssistInitialHtmlToPlain(raw) {
@@ -4876,240 +5831,52 @@ function stripAssistInitialHtmlToPlain(raw) {
4876
5831
  if (s.length > ASSIST_INITIAL_MESSAGES_MAX_LENGTH) {
4877
5832
  s = s.slice(0, ASSIST_INITIAL_MESSAGES_MAX_LENGTH).trimEnd() + '…';
4878
5833
  }
4879
- return s;
4880
- }
4881
- function aiChatTextMessage(role, text) {
4882
- return {
4883
- role,
4884
- responses: [{ type: 'text', content: text }],
4885
- };
4886
- }
4887
- function axmAssistInitialMessagesToTranscriptLite(raw) {
4888
- const trimmed = raw?.trim() ?? '';
4889
- if (!trimmed) {
4890
- return [];
4891
- }
4892
- const plain = stripAssistInitialHtmlToPlain(trimmed);
4893
- if (!plain) {
4894
- return [];
4895
- }
4896
- const blocks = plain
4897
- .split(/\n{2,}/)
4898
- .map((b) => b.replace(/\n+/g, ' ').trim())
4899
- .filter((b) => b.length > 0);
4900
- if (blocks.length === 0) {
4901
- return [];
4902
- }
4903
- return blocks.map((text) => aiChatTextMessage('assistant', text));
4904
- }
4905
- function axmAiChatMessageGetTextLite(message) {
4906
- const parts = [];
4907
- for (const r of message.responses) {
4908
- if (r.type === 'text') {
4909
- parts.push(r.content);
4910
- }
4911
- else if (r.type === 'node' || r.type === 'followUp') {
4912
- try {
4913
- parts.push(JSON.stringify({ type: r.type, content: r.content }));
4914
- }
4915
- catch {
4916
- parts.push(`[${r.type}]`);
4917
- }
4918
- }
4919
- }
4920
- return parts.join('\n\n');
4921
- }
4922
-
4923
- //#region ---- Imports ----
4924
- const AXM_CHAT_ASSIST_CATALOG_PORT = new InjectionToken('AXM_CHAT_ASSIST_CATALOG_PORT');
4925
- //#endregion
4926
-
4927
- //#region ----- Imports -----
4928
- //#endregion
4929
- //#region ----- Constants -----
4930
- /** Launch kind stored on a header mini-chat room after the first message. */
4931
- const AXM_MINI_CHAT_PAGE_CONTEXT_KIND = 'entity-page';
4932
- /** Action name paired with {@link AXM_MINI_CHAT_PAGE_CONTEXT_KIND}. */
4933
- const AXM_MINI_CHAT_PAGE_CONTEXT_ACTION = 'entity.page.context';
4934
- const AXM_MINI_CHAT_ENTITY_CHIP_ID = 'entity';
4935
- const AXM_MINI_CHAT_VIEW_CHIP_ID = 'view';
4936
- //#endregion
4937
- //#region ----- Chips -----
4938
- function axmMiniChatRecordChipId(recordId) {
4939
- return `record:${recordId}`;
4940
- }
4941
- function axmMiniChatContextChipIcon(kind) {
4942
- if (kind === 'record') {
4943
- return 'fa-light fa-file-lines';
4944
- }
4945
- if (kind === 'view') {
4946
- return 'fa-light fa-layer-group';
4947
- }
4948
- return 'fa-light fa-cube';
4949
- }
4950
- function axmMiniChatChipsFromDraft(draft, dismissed) {
4951
- const chips = [];
4952
- if (draft.entityTitle && !dismissed.has(AXM_MINI_CHAT_ENTITY_CHIP_ID)) {
4953
- chips.push({
4954
- id: AXM_MINI_CHAT_ENTITY_CHIP_ID,
4955
- kind: 'entity',
4956
- label: draft.entityTitle,
4957
- });
4958
- }
4959
- if (draft.includeView && draft.viewTitle && !dismissed.has(AXM_MINI_CHAT_VIEW_CHIP_ID)) {
4960
- chips.push({
4961
- id: AXM_MINI_CHAT_VIEW_CHIP_ID,
4962
- kind: 'view',
4963
- label: draft.viewTitle,
4964
- });
4965
- }
4966
- for (const record of draft.records) {
4967
- const id = axmMiniChatRecordChipId(record.id);
4968
- if (dismissed.has(id)) {
4969
- continue;
4970
- }
4971
- chips.push({
4972
- id,
4973
- kind: 'record',
4974
- label: record.title || record.id,
4975
- });
4976
- }
4977
- return chips;
4978
- }
4979
- function axmMiniChatSameChips(left, right) {
4980
- if (left.length !== right.length) {
4981
- return false;
4982
- }
4983
- return left.every((chip, index) => {
4984
- const other = right[index];
4985
- return other != null && chip.id === other.id && chip.kind === other.kind && chip.label === other.label;
4986
- });
4987
- }
4988
- //#endregion
4989
- //#region ----- Launch context -----
4990
- function axmMiniChatLaunchContextFromDraft(draft, chips) {
4991
- const visible = new Set(chips.map((chip) => chip.id));
4992
- const entity = visible.has(AXM_MINI_CHAT_ENTITY_CHIP_ID) && draft.moduleName && draft.entityName
4993
- ? {
4994
- moduleName: draft.moduleName,
4995
- entityName: draft.entityName,
4996
- title: draft.entityTitle,
4997
- }
4998
- : undefined;
4999
- const view = visible.has(AXM_MINI_CHAT_VIEW_CHIP_ID) && draft.viewName && draft.viewTitle
5000
- ? { name: draft.viewName, title: draft.viewTitle }
5001
- : undefined;
5002
- const records = draft.records
5003
- .filter((record) => visible.has(axmMiniChatRecordChipId(record.id)))
5004
- .map((record) => ({
5005
- id: record.id,
5006
- title: record.title || record.id,
5007
- moduleName: draft.moduleName,
5008
- entityName: draft.entityName,
5009
- }));
5010
- if (!entity && !view && records.length === 0) {
5011
- return undefined;
5012
- }
5013
- const payload = {
5014
- guidance: 'Answer using this entity page context for the whole conversation. Use only the entity, view, and records listed here.',
5015
- ...(entity ? { entity } : {}),
5016
- ...(view ? { view } : {}),
5017
- ...(records.length ? { records } : {}),
5018
- };
5019
- return {
5020
- kind: AXM_MINI_CHAT_PAGE_CONTEXT_KIND,
5021
- actionName: AXM_MINI_CHAT_PAGE_CONTEXT_ACTION,
5022
- ...(entity?.title ? { title: entity.title } : {}),
5023
- payload: { ...payload },
5024
- };
5025
- }
5026
- function axmMiniChatChipsFromLaunchContext(context) {
5027
- if (!context || context.kind !== AXM_MINI_CHAT_PAGE_CONTEXT_KIND) {
5028
- return [];
5029
- }
5030
- const payload = context.payload;
5031
- const chips = [];
5032
- const entity = readEntity(payload['entity']);
5033
- if (entity?.title) {
5034
- chips.push({
5035
- id: AXM_MINI_CHAT_ENTITY_CHIP_ID,
5036
- kind: 'entity',
5037
- label: entity.title,
5038
- });
5039
- }
5040
- const view = readView(payload['view']);
5041
- if (view?.title) {
5042
- chips.push({
5043
- id: AXM_MINI_CHAT_VIEW_CHIP_ID,
5044
- kind: 'view',
5045
- label: view.title,
5046
- });
5047
- }
5048
- const records = readRecords(payload['records']);
5049
- for (const record of records) {
5050
- chips.push({
5051
- id: axmMiniChatRecordChipId(record.id),
5052
- kind: 'record',
5053
- label: record.title || record.id,
5054
- });
5055
- }
5056
- return chips;
5057
- }
5058
- //#endregion
5059
- //#region ----- Payload readers -----
5060
- function readEntity(value) {
5061
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
5062
- return undefined;
5063
- }
5064
- const row = value;
5065
- const moduleName = readText(row['moduleName']);
5066
- const entityName = readText(row['entityName']);
5067
- const title = readText(row['title']);
5068
- if (!moduleName || !entityName || !title) {
5069
- return undefined;
5070
- }
5071
- return { moduleName, entityName, title };
5834
+ return s;
5072
5835
  }
5073
- function readView(value) {
5074
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
5075
- return undefined;
5836
+ function aiChatTextMessage(role, text) {
5837
+ return {
5838
+ role,
5839
+ responses: [{ type: 'text', content: text }],
5840
+ };
5841
+ }
5842
+ function axmAssistInitialMessagesToTranscriptLite(raw) {
5843
+ const trimmed = raw?.trim() ?? '';
5844
+ if (!trimmed) {
5845
+ return [];
5076
5846
  }
5077
- const row = value;
5078
- const name = readText(row['name']);
5079
- const title = readText(row['title']);
5080
- if (!name || !title) {
5081
- return undefined;
5847
+ const plain = stripAssistInitialHtmlToPlain(trimmed);
5848
+ if (!plain) {
5849
+ return [];
5082
5850
  }
5083
- return { name, title };
5084
- }
5085
- function readRecords(value) {
5086
- if (!Array.isArray(value)) {
5851
+ const blocks = plain
5852
+ .split(/\n{2,}/)
5853
+ .map((b) => b.replace(/\n+/g, ' ').trim())
5854
+ .filter((b) => b.length > 0);
5855
+ if (blocks.length === 0) {
5087
5856
  return [];
5088
5857
  }
5089
- const records = [];
5090
- for (const item of value) {
5091
- if (!item || typeof item !== 'object' || Array.isArray(item)) {
5092
- continue;
5858
+ return blocks.map((text) => aiChatTextMessage('assistant', text));
5859
+ }
5860
+ function axmAiChatMessageGetTextLite(message) {
5861
+ const parts = [];
5862
+ for (const r of message.responses) {
5863
+ if (r.type === 'text') {
5864
+ parts.push(r.content);
5093
5865
  }
5094
- const row = item;
5095
- const id = readText(row['id']);
5096
- const moduleName = readText(row['moduleName']);
5097
- const entityName = readText(row['entityName']);
5098
- if (!id || !moduleName || !entityName) {
5099
- continue;
5866
+ else if (r.type === 'node' || r.type === 'followUp') {
5867
+ try {
5868
+ parts.push(JSON.stringify({ type: r.type, content: r.content }));
5869
+ }
5870
+ catch {
5871
+ parts.push(`[${r.type}]`);
5872
+ }
5100
5873
  }
5101
- records.push({
5102
- id,
5103
- title: readText(row['title']) || id,
5104
- moduleName,
5105
- entityName,
5106
- });
5107
5874
  }
5108
- return records;
5109
- }
5110
- function readText(value) {
5111
- return typeof value === 'string' ? value.trim() : '';
5875
+ return parts.join('\n\n');
5112
5876
  }
5877
+
5878
+ //#region ---- Imports ----
5879
+ const AXM_CHAT_ASSIST_CATALOG_PORT = new InjectionToken('AXM_CHAT_ASSIST_CATALOG_PORT');
5113
5880
  //#endregion
5114
5881
 
5115
5882
  //#region ----- Imports -----
@@ -5133,6 +5900,8 @@ class AXMMiniChatPageContextChipsService {
5133
5900
  ...(ngDevMode ? [{ debugName: "chips" }] : /* istanbul ignore next */ []));
5134
5901
  this.locked = signal(false, /* @ts-ignore */
5135
5902
  ...(ngDevMode ? [{ debugName: "locked" }] : /* istanbul ignore next */ []));
5903
+ this.historyScope = signal({ mode: 'global' }, /* @ts-ignore */
5904
+ ...(ngDevMode ? [{ debugName: "historyScope" }] : /* istanbul ignore next */ []));
5136
5905
  this.capturing = false;
5137
5906
  this.pinnedId = null;
5138
5907
  this.dismissed = new Set();
@@ -5182,6 +5951,7 @@ class AXMMiniChatPageContextChipsService {
5182
5951
  this.loadedDetailKey = '';
5183
5952
  this.detailSeq += 1;
5184
5953
  this.detailPending = null;
5954
+ this.publishHistoryScope();
5185
5955
  this.refreshLive();
5186
5956
  }
5187
5957
  /** Stops live updates while a saved conversation is opening. */
@@ -5214,9 +5984,11 @@ class AXMMiniChatPageContextChipsService {
5214
5984
  this.dismissed.add(chipId);
5215
5985
  if (!this.draft) {
5216
5986
  this.chips.set([]);
5987
+ this.publishHistoryScope();
5217
5988
  return;
5218
5989
  }
5219
5990
  this.chips.set(axmMiniChatChipsFromDraft(this.draft, this.dismissed));
5991
+ this.publishHistoryScope();
5220
5992
  }
5221
5993
  /**
5222
5994
  * Context for the conversation created by the first mini-chat message.
@@ -5264,6 +6036,7 @@ class AXMMiniChatPageContextChipsService {
5264
6036
  if (this.chips().length > 0) {
5265
6037
  this.chips.set([]);
5266
6038
  }
6039
+ this.publishHistoryScope();
5267
6040
  }
5268
6041
  draftFromList(page) {
5269
6042
  const fullName = page.entity?.fullName?.trim() ?? '';
@@ -5354,6 +6127,7 @@ class AXMMiniChatPageContextChipsService {
5354
6127
  if (this.chips().length > 0) {
5355
6128
  this.chips.set([]);
5356
6129
  }
6130
+ this.publishHistoryScope();
5357
6131
  return;
5358
6132
  }
5359
6133
  if (draft.entityKey !== this.entityKey) {
@@ -5377,6 +6151,13 @@ class AXMMiniChatPageContextChipsService {
5377
6151
  if (!axmMiniChatSameChips(this.chips(), next)) {
5378
6152
  this.chips.set(next);
5379
6153
  }
6154
+ this.publishHistoryScope();
6155
+ }
6156
+ publishHistoryScope() {
6157
+ const scope = axmMiniChatHistoryScopeFromDraft(this.draft, this.chips());
6158
+ if (axmMiniChatHistoryScopeKey(scope) !== axmMiniChatHistoryScopeKey(this.historyScope())) {
6159
+ this.historyScope.set(scope);
6160
+ }
5380
6161
  }
5381
6162
  //#endregion
5382
6163
  //#region ----- Route & Titles -----
@@ -5605,7 +6386,7 @@ const ASSIST_SUGGESTION_ICON_RULES = [
5605
6386
  { icon: 'fa-light fa-file-lines', keywords: ['summar', 'explain', 'overview', 'describe', 'خلاصه', 'توضیح'] },
5606
6387
  { icon: 'fa-light fa-magnifying-glass', keywords: ['find', 'search', 'where', 'locate', 'look', 'جستجو', 'پیدا', 'کجا'] },
5607
6388
  { icon: 'fa-light fa-circle-plus', keywords: ['create', 'add', 'new', 'ایجاد', 'ساخت'] },
5608
- { icon: 'fa-light fa-circle-question', keywords: ['help', 'how', 'کمک', 'چطور'] },
6389
+ { icon: 'fa-light fa-circle-question', keywords: ['help', 'how', 'کمک', 'چطور', 'چگونه'] },
5609
6390
  ];
5610
6391
  const ASSIST_SUGGESTION_ICON_FALLBACK = [
5611
6392
  'fa-light fa-comment-dots',
@@ -5847,70 +6628,46 @@ class AXMAssistSuggestionChipsComponent {
5847
6628
  @if (normalizedItems().length > 0) {
5848
6629
  <div class="axm-assist-suggestion-chips" role="list" [attr.aria-label]="('@conversation:chat.starter-prompts.list-aria' | translate | async) ?? ''">
5849
6630
  @for (item of normalizedItems(); track $index) {
5850
- @if (compact()) {
5851
- <button
5852
- type="button"
5853
- class="axm-assist-suggestion-chips__row"
5854
- role="listitem"
5855
- [disabled]="isInteractionBlocked()"
5856
- (click)="onChipClick(item)"
5857
- >
5858
- <i class="{{ chipIcons()[$index] }}" aria-hidden="true"></i>
5859
- <span class="axm-assist-suggestion-chips__row-text">{{ (resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item) }}</span>
5860
- <i class="fa-light fa-arrow-right axm-assist-suggestion-chips__row-arrow" aria-hidden="true"></i>
5861
- </button>
5862
- }
5863
- <!-- ----- Full-page starter / follow-up chips ----- -->
5864
- @else {
5865
- <ax-button
5866
- class="axm-assist-suggestion-chips__chip rounded-full"
5867
- look="twotone"
5868
- [text]="(resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item)"
5869
- [disabled]="isInteractionBlocked()"
5870
- (onClick)="onChipClick(item)"
5871
- ></ax-button>
5872
- }
6631
+ <button
6632
+ type="button"
6633
+ class="axm-assist-suggestion-chips__row"
6634
+ role="listitem"
6635
+ [disabled]="isInteractionBlocked()"
6636
+ (click)="onChipClick(item)"
6637
+ >
6638
+ <i class="{{ chipIcons()[$index] }}" aria-hidden="true"></i>
6639
+ <span class="axm-assist-suggestion-chips__row-text">{{ (resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item) }}</span>
6640
+ <i class="fa-light fa-arrow-right axm-assist-suggestion-chips__row-arrow" aria-hidden="true"></i>
6641
+ </button>
5873
6642
  }
5874
6643
  </div>
5875
6644
  }
5876
- `, isInline: true, styles: [":host{display:block;width:100%}:host(.axm-assist-suggestion-chips-host--compact){display:flex;flex-direction:column;min-height:0;height:auto;overflow:hidden}.axm-assist-suggestion-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:.75rem;padding:2rem}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips{flex:0 0 auto;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:.625rem;padding:0;min-height:0;overflow-y:auto;overscroll-behavior:contain}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row{display:flex;align-items:center;gap:.75rem;width:100%;min-height:2.75rem;padding:.625rem .875rem;border-radius:.875rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-surface));text-align:start;font-size:.8125rem;font-weight:500;line-height:1.35;cursor:pointer;transition:background-color .16s ease,border-color .16s ease}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row:hover:not(:disabled){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.06)}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row:disabled{opacity:.55;cursor:default}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row>i:first-child{color:rgb(var(--ax-sys-color-primary-600));font-size:.875rem;width:1rem;text-align:center;flex-shrink:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row-text{flex:1;min-width:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row-arrow{opacity:.4;font-size:.75rem;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6645
+ `, isInline: true, styles: [":host{display:block;width:100%}:host(.axm-assist-suggestion-chips-host--compact){display:flex;flex-direction:column;min-height:0;height:auto;overflow:hidden}.axm-assist-suggestion-chips{display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:.625rem;padding:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips{flex:0 0 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.axm-assist-suggestion-chips__row{display:flex;align-items:center;gap:.75rem;width:100%;min-height:2.75rem;padding:.625rem .875rem;border-radius:.875rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-surface));text-align:start;font-size:.8125rem;font-weight:500;line-height:1.35;cursor:pointer;transition:background-color .16s ease,border-color .16s ease}.axm-assist-suggestion-chips__row:hover:not(:disabled){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.06)}.axm-assist-suggestion-chips__row:disabled{opacity:.55;cursor:default}.axm-assist-suggestion-chips__row>i:first-child{color:rgb(var(--ax-sys-color-primary-600));font-size:.875rem;width:1rem;text-align:center;flex-shrink:0}.axm-assist-suggestion-chips__row-text{flex:1;min-width:0}.axm-assist-suggestion-chips__row-arrow{opacity:.4;font-size:.75rem;flex-shrink:0}:host-context([dir=\"rtl\"]) .axm-assist-suggestion-chips__row-arrow{transform:scaleX(-1)}\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5877
6646
  }
5878
6647
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssistSuggestionChipsComponent, decorators: [{
5879
6648
  type: Component,
5880
6649
  args: [{ selector: 'axm-assist-suggestion-chips', changeDetection: ChangeDetectionStrategy.OnPush, host: {
5881
6650
  class: 'axm-assist-suggestion-chips-host',
5882
6651
  '[class.axm-assist-suggestion-chips-host--compact]': 'compact()',
5883
- }, imports: [AsyncPipe, AXButtonModule, AXTranslationModule], template: `
6652
+ }, imports: [AsyncPipe, AXTranslationModule], template: `
5884
6653
  @if (normalizedItems().length > 0) {
5885
6654
  <div class="axm-assist-suggestion-chips" role="list" [attr.aria-label]="('@conversation:chat.starter-prompts.list-aria' | translate | async) ?? ''">
5886
6655
  @for (item of normalizedItems(); track $index) {
5887
- @if (compact()) {
5888
- <button
5889
- type="button"
5890
- class="axm-assist-suggestion-chips__row"
5891
- role="listitem"
5892
- [disabled]="isInteractionBlocked()"
5893
- (click)="onChipClick(item)"
5894
- >
5895
- <i class="{{ chipIcons()[$index] }}" aria-hidden="true"></i>
5896
- <span class="axm-assist-suggestion-chips__row-text">{{ (resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item) }}</span>
5897
- <i class="fa-light fa-arrow-right axm-assist-suggestion-chips__row-arrow" aria-hidden="true"></i>
5898
- </button>
5899
- }
5900
- <!-- ----- Full-page starter / follow-up chips ----- -->
5901
- @else {
5902
- <ax-button
5903
- class="axm-assist-suggestion-chips__chip rounded-full"
5904
- look="twotone"
5905
- [text]="(resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item)"
5906
- [disabled]="isInteractionBlocked()"
5907
- (onClick)="onChipClick(item)"
5908
- ></ax-button>
5909
- }
6656
+ <button
6657
+ type="button"
6658
+ class="axm-assist-suggestion-chips__row"
6659
+ role="listitem"
6660
+ [disabled]="isInteractionBlocked()"
6661
+ (click)="onChipClick(item)"
6662
+ >
6663
+ <i class="{{ chipIcons()[$index] }}" aria-hidden="true"></i>
6664
+ <span class="axm-assist-suggestion-chips__row-text">{{ (resolveChipLabel(item) | translate | async) ?? resolveChipLabel(item) }}</span>
6665
+ <i class="fa-light fa-arrow-right axm-assist-suggestion-chips__row-arrow" aria-hidden="true"></i>
6666
+ </button>
5910
6667
  }
5911
6668
  </div>
5912
6669
  }
5913
- `, styles: [":host{display:block;width:100%}:host(.axm-assist-suggestion-chips-host--compact){display:flex;flex-direction:column;min-height:0;height:auto;overflow:hidden}.axm-assist-suggestion-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:.75rem;padding:2rem}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips{flex:0 0 auto;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:.625rem;padding:0;min-height:0;overflow-y:auto;overscroll-behavior:contain}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row{display:flex;align-items:center;gap:.75rem;width:100%;min-height:2.75rem;padding:.625rem .875rem;border-radius:.875rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-surface));text-align:start;font-size:.8125rem;font-weight:500;line-height:1.35;cursor:pointer;transition:background-color .16s ease,border-color .16s ease}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row:hover:not(:disabled){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.06)}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row:disabled{opacity:.55;cursor:default}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row>i:first-child{color:rgb(var(--ax-sys-color-primary-600));font-size:.875rem;width:1rem;text-align:center;flex-shrink:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row-text{flex:1;min-width:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips__row-arrow{opacity:.4;font-size:.75rem;flex-shrink:0}\n"] }]
6670
+ `, styles: [":host{display:block;width:100%}:host(.axm-assist-suggestion-chips-host--compact){display:flex;flex-direction:column;min-height:0;height:auto;overflow:hidden}.axm-assist-suggestion-chips{display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:.625rem;padding:0}:host(.axm-assist-suggestion-chips-host--compact) .axm-assist-suggestion-chips{flex:0 0 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.axm-assist-suggestion-chips__row{display:flex;align-items:center;gap:.75rem;width:100%;min-height:2.75rem;padding:.625rem .875rem;border-radius:.875rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-surface));text-align:start;font-size:.8125rem;font-weight:500;line-height:1.35;cursor:pointer;transition:background-color .16s ease,border-color .16s ease}.axm-assist-suggestion-chips__row:hover:not(:disabled){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.06)}.axm-assist-suggestion-chips__row:disabled{opacity:.55;cursor:default}.axm-assist-suggestion-chips__row>i:first-child{color:rgb(var(--ax-sys-color-primary-600));font-size:.875rem;width:1rem;text-align:center;flex-shrink:0}.axm-assist-suggestion-chips__row-text{flex:1;min-width:0}.axm-assist-suggestion-chips__row-arrow{opacity:.4;font-size:.75rem;flex-shrink:0}:host-context([dir=\"rtl\"]) .axm-assist-suggestion-chips__row-arrow{transform:scaleX(-1)}\n"] }]
5914
6671
  }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], sendInPlace: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendInPlace", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], conversationCreated: [{ type: i0.Output, args: ["conversationCreated"] }] } });
5915
6672
 
5916
6673
  //#region ---- Imports ----
@@ -6345,6 +7102,8 @@ class AXMChatEmptyAssistSessionService {
6345
7102
  ...(ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []));
6346
7103
  this.launchContext = signal(undefined, /* @ts-ignore */
6347
7104
  ...(ngDevMode ? [{ debugName: "launchContext" }] : /* istanbul ignore next */ []));
7105
+ this.assistSelection = signal('optional', /* @ts-ignore */
7106
+ ...(ngDevMode ? [{ debugName: "assistSelection" }] : /* istanbul ignore next */ []));
6348
7107
  this.assistPickerOpen = signal(false, /* @ts-ignore */
6349
7108
  ...(ngDevMode ? [{ debugName: "assistPickerOpen" }] : /* istanbul ignore next */ []));
6350
7109
  this.ensurePromise = null;
@@ -6367,6 +7126,7 @@ class AXMChatEmptyAssistSessionService {
6367
7126
  this.entityId.set(input.entityId?.trim() || undefined);
6368
7127
  this.entityType.set(input.entityType?.trim() || undefined);
6369
7128
  this.launchContext.set(input.launchContext);
7129
+ this.assistSelection.set(input.assistSelection ?? 'optional');
6370
7130
  }
6371
7131
  setSelectedAssistId(assistId) {
6372
7132
  this.selectedAssistId.set(assistId?.trim() || undefined);
@@ -6669,6 +7429,10 @@ class AXMChatEmptyStateFallbackComponent {
6669
7429
  ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
6670
7430
  this.initialAssistId = input(undefined, /* @ts-ignore */
6671
7431
  ...(ngDevMode ? [{ debugName: "initialAssistId" }] : /* istanbul ignore next */ []));
7432
+ this.assistSelection = input('optional', /* @ts-ignore */
7433
+ ...(ngDevMode ? [{ debugName: "assistSelection" }] : /* istanbul ignore next */ []));
7434
+ this.acceptExternalFileDrop = input(false, /* @ts-ignore */
7435
+ ...(ngDevMode ? [{ debugName: "acceptExternalFileDrop" }] : /* istanbul ignore next */ []));
6672
7436
  this.entityId = input(undefined, /* @ts-ignore */
6673
7437
  ...(ngDevMode ? [{ debugName: "entityId" }] : /* istanbul ignore next */ []));
6674
7438
  this.entityType = input(undefined, /* @ts-ignore */
@@ -6682,7 +7446,7 @@ class AXMChatEmptyStateFallbackComponent {
6682
7446
  this.conversationCreated = output();
6683
7447
  }
6684
7448
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatEmptyStateFallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6685
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXMChatEmptyStateFallbackComponent, isStandalone: true, selector: "axm-chat-empty-state-fallback", inputs: { compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, sendStarterPromptsInPlace: { classPropertyName: "sendStarterPromptsInPlace", publicName: "sendStarterPromptsInPlace", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, assistConversationCreated: { classPropertyName: "assistConversationCreated", publicName: "assistConversationCreated", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationCreated: "conversationCreated" }, host: { properties: { "class.ax-message-empty-host--compact": "compact()" }, classAttribute: "ax-message-empty-host" }, ngImport: i0, template: `
7449
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXMChatEmptyStateFallbackComponent, isStandalone: true, selector: "axm-chat-empty-state-fallback", inputs: { compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, assistSelection: { classPropertyName: "assistSelection", publicName: "assistSelection", isSignal: true, isRequired: false, transformFunction: null }, acceptExternalFileDrop: { classPropertyName: "acceptExternalFileDrop", publicName: "acceptExternalFileDrop", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, sendStarterPromptsInPlace: { classPropertyName: "sendStarterPromptsInPlace", publicName: "sendStarterPromptsInPlace", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, assistConversationCreated: { classPropertyName: "assistConversationCreated", publicName: "assistConversationCreated", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationCreated: "conversationCreated" }, host: { properties: { "class.ax-message-empty-host--compact": "compact()" }, classAttribute: "ax-message-empty-host" }, ngImport: i0, template: `
6686
7450
  <div class="ax-message-empty" role="status" aria-live="polite">
6687
7451
  <div class="ax-message-empty__ambient" aria-hidden="true">
6688
7452
  <span class="ax-message-empty__grid"></span>
@@ -6740,7 +7504,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6740
7504
  </div>
6741
7505
  </div>
6742
7506
  `, styles: [":host.ax-message-empty-host{display:flex;width:100%;min-height:100%;align-items:center;justify-content:center;padding:1rem}.ax-message-empty{position:relative;isolation:isolate;width:100%;max-width:min(24rem,100%);margin-inline:auto;padding:.25rem}.ax-message-empty__ambient{position:absolute;inset:-2rem -1rem -1rem;z-index:0;pointer-events:none;overflow:hidden;border-radius:2rem}.ax-message-empty__grid{position:absolute;inset:0;background-image:linear-gradient(rgba(var(--ax-sys-color-on-surface),.04) 1px,transparent 1px),linear-gradient(90deg,rgba(var(--ax-sys-color-on-surface),.04) 1px,transparent 1px);background-size:24px 24px;-webkit-mask-image:radial-gradient(ellipse 80% 70% at 50% 45%,black 20%,transparent 75%);mask-image:radial-gradient(ellipse 80% 70% at 50% 45%,black 20%,transparent 75%);opacity:.5}.ax-message-empty__card{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;text-align:center;padding:2rem 1.75rem 2.125rem;border-radius:1.25rem;border:1px solid rgba(var(--ax-sys-color-border-light-surface),.85);background:linear-gradient(165deg,rgba(var(--ax-sys-color-lightest-surface),.72),rgba(var(--ax-sys-color-surface),.55))}.ax-message-empty__icon-stack{position:relative;display:grid;place-items:center;margin-bottom:1.25rem}.ax-message-empty__pulse{position:absolute;width:5.5rem;height:5.5rem;border-radius:50%;background:radial-gradient(circle,rgba(var(--ax-sys-color-primary-500),.22),transparent 70%);animation:axm-empty-pulse 3.2s ease-in-out infinite}.ax-message-empty__icon-bg{position:relative;display:grid;place-items:center;width:4.25rem;height:4.25rem;border-radius:1.125rem;background:linear-gradient(145deg,rgba(var(--ax-sys-color-primary-500),.16),rgba(var(--ax-sys-color-primary-600),.06));border:1px solid rgba(var(--ax-sys-color-primary-500),.22);box-shadow:0 1px rgba(var(--ax-sys-color-on-primary-surface),.06) inset,0 12px 28px -16px rgba(var(--ax-sys-color-primary-600),.45)}.ax-message-empty__icon-bg i{font-size:1.875rem;line-height:1;color:rgb(var(--ax-sys-color-primary-600));opacity:.92}.ax-message-empty__eyebrow{margin:0 0 .35rem;font-size:.6875rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:rgb(var(--ax-sys-color-primary-600));opacity:.85}.ax-message-empty__title{margin:0 0 .65rem;font-size:1.375rem;font-weight:600;letter-spacing:-.03em;line-height:1.25;color:rgb(var(--ax-sys-color-on-surface))}.ax-message-empty__desc{margin:0;font-size:.9375rem;line-height:1.65;color:rgb(var(--ax-sys-color-on-surface));opacity:.62;max-width:20rem}:host(.ax-message-empty-host--compact){padding:.75rem}:host(.ax-message-empty-host--compact) .ax-message-empty__card{padding:1.25rem 1.25rem 1.375rem;border-radius:1rem}:host(.ax-message-empty-host--compact) .ax-message-empty__icon-stack{margin-bottom:.875rem}:host(.ax-message-empty-host--compact) .ax-message-empty__pulse{width:4.25rem;height:4.25rem}:host(.ax-message-empty-host--compact) .ax-message-empty__icon-bg{width:3.25rem;height:3.25rem;border-radius:.875rem}:host(.ax-message-empty-host--compact) .ax-message-empty__icon-bg i{font-size:1.375rem}:host(.ax-message-empty-host--compact) .ax-message-empty__title{font-size:1.125rem}:host(.ax-message-empty-host--compact) .ax-message-empty__desc{font-size:.8125rem}@keyframes axm-empty-pulse{0%,to{transform:scale(.92);opacity:.55}50%{transform:scale(1.06);opacity:.85}}@media(prefers-reduced-motion:reduce){.ax-message-empty__pulse{animation:none}}\n"] }]
6743
- }], propDecorators: { compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], sendStarterPromptsInPlace: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendStarterPromptsInPlace", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], assistConversationCreated: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistConversationCreated", required: false }] }], conversationCreated: [{ type: i0.Output, args: ["conversationCreated"] }] } });
7507
+ }], propDecorators: { compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], assistSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistSelection", required: false }] }], acceptExternalFileDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptExternalFileDrop", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], sendStarterPromptsInPlace: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendStarterPromptsInPlace", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], assistConversationCreated: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistConversationCreated", required: false }] }], conversationCreated: [{ type: i0.Output, args: ["conversationCreated"] }] } });
6744
7508
 
6745
7509
  class AXMChatEmptyStateHostComponent {
6746
7510
  constructor() {
@@ -6748,6 +7512,10 @@ class AXMChatEmptyStateHostComponent {
6748
7512
  ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
6749
7513
  this.initialAssistId = input(undefined, /* @ts-ignore */
6750
7514
  ...(ngDevMode ? [{ debugName: "initialAssistId" }] : /* istanbul ignore next */ []));
7515
+ this.assistSelection = input('optional', /* @ts-ignore */
7516
+ ...(ngDevMode ? [{ debugName: "assistSelection" }] : /* istanbul ignore next */ []));
7517
+ this.acceptExternalFileDrop = input(false, /* @ts-ignore */
7518
+ ...(ngDevMode ? [{ debugName: "acceptExternalFileDrop" }] : /* istanbul ignore next */ []));
6751
7519
  this.entityId = input(undefined, /* @ts-ignore */
6752
7520
  ...(ngDevMode ? [{ debugName: "entityId" }] : /* istanbul ignore next */ []));
6753
7521
  this.entityType = input(undefined, /* @ts-ignore */
@@ -6778,6 +7546,8 @@ class AXMChatEmptyStateHostComponent {
6778
7546
  }
6779
7547
  ref.setInput('compact', this.compact());
6780
7548
  ref.setInput('initialAssistId', this.initialAssistId());
7549
+ ref.setInput('assistSelection', this.assistSelection());
7550
+ ref.setInput('acceptExternalFileDrop', this.acceptExternalFileDrop());
6781
7551
  ref.setInput('entityId', this.entityId());
6782
7552
  ref.setInput('entityType', this.entityType());
6783
7553
  ref.setInput('sendStarterPromptsInPlace', this.sendStarterPromptsInPlace());
@@ -6800,7 +7570,7 @@ class AXMChatEmptyStateHostComponent {
6800
7570
  }
6801
7571
  }
6802
7572
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatEmptyStateHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6803
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.8", type: AXMChatEmptyStateHostComponent, isStandalone: true, selector: "axm-chat-empty-state-host", inputs: { compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, sendStarterPromptsInPlace: { classPropertyName: "sendStarterPromptsInPlace", publicName: "sendStarterPromptsInPlace", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, assistConversationCreated: { classPropertyName: "assistConversationCreated", publicName: "assistConversationCreated", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationCreated: "conversationCreated" }, viewQueries: [{ propertyName: "host", first: true, predicate: ["host"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: ` <ng-container #host></ng-container> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7573
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.8", type: AXMChatEmptyStateHostComponent, isStandalone: true, selector: "axm-chat-empty-state-host", inputs: { compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, assistSelection: { classPropertyName: "assistSelection", publicName: "assistSelection", isSignal: true, isRequired: false, transformFunction: null }, acceptExternalFileDrop: { classPropertyName: "acceptExternalFileDrop", publicName: "acceptExternalFileDrop", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, sendStarterPromptsInPlace: { classPropertyName: "sendStarterPromptsInPlace", publicName: "sendStarterPromptsInPlace", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, assistConversationCreated: { classPropertyName: "assistConversationCreated", publicName: "assistConversationCreated", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationCreated: "conversationCreated" }, viewQueries: [{ propertyName: "host", first: true, predicate: ["host"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: ` <ng-container #host></ng-container> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6804
7574
  }
6805
7575
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatEmptyStateHostComponent, decorators: [{
6806
7576
  type: Component,
@@ -6810,7 +7580,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6810
7580
  imports: [],
6811
7581
  template: ` <ng-container #host></ng-container> `,
6812
7582
  }]
6813
- }], ctorParameters: () => [], propDecorators: { compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], sendStarterPromptsInPlace: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendStarterPromptsInPlace", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], assistConversationCreated: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistConversationCreated", required: false }] }], conversationCreated: [{ type: i0.Output, args: ["conversationCreated"] }], host: [{ type: i0.ViewChild, args: ['host', { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
7583
+ }], ctorParameters: () => [], propDecorators: { compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], assistSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistSelection", required: false }] }], acceptExternalFileDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptExternalFileDrop", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], sendStarterPromptsInPlace: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendStarterPromptsInPlace", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], assistConversationCreated: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistConversationCreated", required: false }] }], conversationCreated: [{ type: i0.Output, args: ["conversationCreated"] }], host: [{ type: i0.ViewChild, args: ['host', { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
6814
7584
 
6815
7585
  //#region ----- Imports -----
6816
7586
  //#endregion
@@ -6978,6 +7748,9 @@ class AXMMiniChatComponent {
6978
7748
  /** Assist used as the bot peer when creating a new entity chat (falls back to the tenant default). */
6979
7749
  this.assistId = input(undefined, /* @ts-ignore */
6980
7750
  ...(ngDevMode ? [{ debugName: "assistId" }] : /* istanbul ignore next */ []));
7751
+ /** `ask` prompts in the header inbox. `locked` hides the picker (form designer). */
7752
+ this.assistSelection = input('optional', /* @ts-ignore */
7753
+ ...(ngDevMode ? [{ debugName: "assistSelection" }] : /* istanbul ignore next */ []));
6981
7754
  /** Surface context for a new assist thread (entity-row assist chips and room metadata). */
6982
7755
  this.launchContext = input(undefined, /* @ts-ignore */
6983
7756
  ...(ngDevMode ? [{ debugName: "launchContext" }] : /* istanbul ignore next */ []));
@@ -7052,7 +7825,7 @@ class AXMMiniChatComponent {
7052
7825
  axmCancelAssistComposerGeneration(this.conversationService, this.assistResponse);
7053
7826
  }
7054
7827
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7055
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatComponent, isStandalone: true, selector: "axm-mini-chat", inputs: { chatId: { classPropertyName: "chatId", publicName: "chatId", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, assistId: { classPropertyName: "assistId", publicName: "assistId", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, showInfoBar: { classPropertyName: "showInfoBar", publicName: "showInfoBar", isSignal: true, isRequired: false, transformFunction: null }, showComposer: { classPropertyName: "showComposer", publicName: "showComposer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationOpened: "conversationOpened" }, ngImport: i0, template: "<div axConversationContainer class=\"axm-mini-chat flex h-full min-h-0 flex-col\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <!---->\n <!-- ----- Mini-chat widgets remount after platform locale/theme change ----- -->\n @if (showInfoBar() && hasActiveConversation()) {\n <ax-conversation-info-bar class=\"axm-mini-chat__info-bar shrink-0 shadow-sm\" (infoClick)=\"onInfoBarClick()\"></ax-conversation-info-bar>\n }\n\n <ax-conversation-message-list class=\"axm-mini-chat__messages min-h-0 flex-1 overflow-hidden\" style=\"direction: ltr\">\n <div ax-conversation-message-list-no-active class=\"axm-mini-chat__no-active block\">\n <axm-chat-empty-state-host\n [compact]=\"true\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [initialAssistId]=\"assistId()\"\n [launchContext]=\"launchContext()\"\n [sendStarterPromptsInPlace]=\"true\"\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationCreated($event)\"\n />\n </div>\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty [compact]=\"true\" [sendStarterPromptsInPlace]=\"true\" />\n </ax-conversation-message-list>\n\n @if (showComposer()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n class=\"axm-mini-chat__composer shrink-0\"\n [hidden]=\"!hasActiveConversation()\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n }\n</div>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}.axm-mini-chat ax-conversation-message-list .message-list--conversation-surface{background:transparent!important;--ax-comp-message-list-surface-bg: transparent !important}.axm-mini-chat ax-conversation-message-list .message-list--default-wallpaper:before{content:none!important;background:none!important;opacity:0!important}.axm-mini-chat .axm-mini-chat__info-bar{border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat .axm-mini-chat__composer{border-top:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat .axm-mini-chat__composer[hidden]{display:none!important}.axm-mini-chat .axm-mini-chat__messages{background:radial-gradient(ellipse 120% 80% at 50% -20%,rgba(var(--ax-sys-color-primary-500),.07),transparent 55%),rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat ax-conversation-message-list.axm-mini-chat__messages{display:flex;flex-direction:column;min-height:0}.axm-mini-chat axm-chat-empty-state-host{display:flex;flex-direction:column;flex:1 1 auto;width:100%;height:100%;min-height:0;overflow:hidden}.axm-mini-chat .axm-mini-chat__no-active{width:100%;max-width:none;padding:0;margin:0;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}.axm-mini-chat ax-conversation-message-list .list-no-active{justify-content:stretch;align-items:stretch;min-height:100%;height:100%;overflow:hidden;padding:.625rem 1rem .875rem;gap:0;text-align:start;animation:none}.axm-mini-chat ax-conversation-message-list .list-empty{justify-content:flex-start;align-items:stretch;min-height:0;padding:.75rem .875rem 1rem;gap:0;text-align:start;animation:none}.axm-mini-chat .axm-chat-assist-composer-starter-prompts-host--compact .axm-chat-assist-welcome-empty{padding:0;gap:.5rem}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{border-color:rgba(var(--ax-sys-color-border-light-surface),.95);background:rgba(var(--ax-sys-color-surface),.55);color:rgb(var(--ax-sys-color-on-surface));transition:background-color .16s ease,border-color .16s ease,transform .16s ease}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.08);transform:translateY(-1px)}.axm-mini-chat .axm-assist-suggestion-chips{justify-content:flex-start;padding:.5rem 0 0;gap:.5rem}.axm-mini-chat .axm-assist-renderer__entity-cards{max-width:100%}@media(prefers-reduced-motion:reduce){.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{transition:none}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){transform:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: AXConversationContainerDirective, selector: "[axConversationContainer]" }, { kind: "component", type: AXConversationInfoBarComponent, selector: "ax-conversation-info-bar", outputs: ["infoClick", "searchClick", "searchQuery", "menuItemAction"] }, { kind: "component", type: AXConversationMessageListComponent, selector: "ax-conversation-message-list", outputs: ["messageAction"] }, { kind: "component", type: AXConversationComposerComponent, selector: "ax-conversation-composer", outputs: ["messageSent", "generationCancelled", "emojiClick", "attachClick", "voiceClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXMChatEmptyStateHostComponent, selector: "axm-chat-empty-state-host", inputs: ["compact", "initialAssistId", "entityId", "entityType", "sendStarterPromptsInPlace", "launchContext", "assistConversationCreated"], outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatAssistComposerStarterPromptsComponent, selector: "axm-chat-assist-composer-starter-prompts", inputs: ["sendStarterPromptsInPlace", "compact"] }, { kind: "directive", type: AXMChatComposerEnsureAssistConversationDirective, selector: "ax-conversation-composer[axmEnsureAssistConversation]", inputs: ["axmAssistConversationCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
7828
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatComponent, isStandalone: true, selector: "axm-mini-chat", inputs: { chatId: { classPropertyName: "chatId", publicName: "chatId", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, assistId: { classPropertyName: "assistId", publicName: "assistId", isSignal: true, isRequired: false, transformFunction: null }, assistSelection: { classPropertyName: "assistSelection", publicName: "assistSelection", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, showInfoBar: { classPropertyName: "showInfoBar", publicName: "showInfoBar", isSignal: true, isRequired: false, transformFunction: null }, showComposer: { classPropertyName: "showComposer", publicName: "showComposer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { conversationOpened: "conversationOpened" }, ngImport: i0, template: "<div axConversationContainer class=\"axm-mini-chat flex h-full min-h-0 flex-col\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <!---->\n <!-- ----- Mini-chat widgets remount after platform locale/theme change ----- -->\n @if (showInfoBar() && hasActiveConversation()) {\n <ax-conversation-info-bar class=\"axm-mini-chat__info-bar shrink-0 shadow-sm\" (infoClick)=\"onInfoBarClick()\"></ax-conversation-info-bar>\n }\n\n <ax-conversation-message-list class=\"axm-mini-chat__messages min-h-0 flex-1 overflow-hidden\" style=\"direction: ltr\">\n <div ax-conversation-message-list-no-active class=\"axm-mini-chat__no-active block\">\n <axm-chat-empty-state-host\n [compact]=\"true\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [initialAssistId]=\"assistId()\"\n [assistSelection]=\"assistSelection()\"\n [launchContext]=\"launchContext()\"\n [sendStarterPromptsInPlace]=\"true\"\n [acceptExternalFileDrop]=\"true\"\n [acceptExternalFileDrop]=\"true\"\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationCreated($event)\"\n />\n </div>\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty [compact]=\"true\" [sendStarterPromptsInPlace]=\"true\" />\n </ax-conversation-message-list>\n\n @if (showComposer()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n class=\"axm-mini-chat__composer shrink-0\"\n [hidden]=\"!hasActiveConversation()\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n }\n</div>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}.axm-mini-chat ax-conversation-message-list .message-list--conversation-surface{background:transparent!important;--ax-comp-message-list-surface-bg: transparent !important}.axm-mini-chat ax-conversation-message-list .message-list--default-wallpaper:before{content:none!important;background:none!important;opacity:0!important}.axm-mini-chat .axm-mini-chat__info-bar{border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat .axm-mini-chat__composer{border-top:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat .axm-mini-chat__composer[hidden]{display:none!important}.axm-mini-chat .axm-mini-chat__messages{background:radial-gradient(ellipse 120% 80% at 50% -20%,rgba(var(--ax-sys-color-primary-500),.07),transparent 55%),rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat ax-conversation-message-list.axm-mini-chat__messages{display:flex;flex-direction:column;min-height:0}.axm-mini-chat axm-chat-empty-state-host{display:flex;flex-direction:column;flex:1 1 auto;width:100%;height:100%;min-height:0;overflow:hidden}.axm-mini-chat .axm-mini-chat__no-active{width:100%;max-width:none;padding:0;margin:0;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}.axm-mini-chat ax-conversation-message-list .list-no-active{justify-content:stretch;align-items:stretch;min-height:100%;height:100%;overflow:hidden;padding:.625rem 1rem .875rem;gap:0;text-align:start;animation:none}.axm-mini-chat ax-conversation-message-list .list-empty{justify-content:flex-start;align-items:stretch;min-height:0;padding:.75rem .875rem 1rem;gap:0;text-align:start;animation:none}.axm-mini-chat .axm-chat-assist-composer-starter-prompts-host--compact .axm-chat-assist-welcome-empty{padding:0;gap:.5rem}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{border-color:rgba(var(--ax-sys-color-border-light-surface),.95);background:rgba(var(--ax-sys-color-surface),.55);color:rgb(var(--ax-sys-color-on-surface));transition:background-color .16s ease,border-color .16s ease,transform .16s ease}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.08);transform:translateY(-1px)}.axm-mini-chat .axm-assist-suggestion-chips{justify-content:flex-start;padding:.5rem 0 0;gap:.5rem}.axm-mini-chat .axm-assist-renderer__entity-cards{max-width:100%}@media(prefers-reduced-motion:reduce){.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{transition:none}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){transform:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: AXConversationContainerDirective, selector: "[axConversationContainer]" }, { kind: "component", type: AXConversationInfoBarComponent, selector: "ax-conversation-info-bar", outputs: ["infoClick", "searchClick", "searchQuery", "menuItemAction"] }, { kind: "component", type: AXConversationMessageListComponent, selector: "ax-conversation-message-list", outputs: ["messageAction"] }, { kind: "component", type: AXConversationComposerComponent, selector: "ax-conversation-composer", outputs: ["messageSent", "generationCancelled", "emojiClick", "attachClick", "voiceClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXMChatEmptyStateHostComponent, selector: "axm-chat-empty-state-host", inputs: ["compact", "initialAssistId", "assistSelection", "acceptExternalFileDrop", "entityId", "entityType", "sendStarterPromptsInPlace", "launchContext", "assistConversationCreated"], outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatAssistComposerStarterPromptsComponent, selector: "axm-chat-assist-composer-starter-prompts", inputs: ["sendStarterPromptsInPlace", "compact"] }, { kind: "directive", type: AXMChatComposerEnsureAssistConversationDirective, selector: "ax-conversation-composer[axmEnsureAssistConversation]", inputs: ["axmAssistConversationCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
7056
7829
  }
7057
7830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatComponent, decorators: [{
7058
7831
  type: Component,
@@ -7066,8 +7839,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7066
7839
  AXMChatEmptyStateHostComponent,
7067
7840
  AXMChatAssistComposerStarterPromptsComponent,
7068
7841
  AXMChatComposerEnsureAssistConversationDirective,
7069
- ], template: "<div axConversationContainer class=\"axm-mini-chat flex h-full min-h-0 flex-col\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <!---->\n <!-- ----- Mini-chat widgets remount after platform locale/theme change ----- -->\n @if (showInfoBar() && hasActiveConversation()) {\n <ax-conversation-info-bar class=\"axm-mini-chat__info-bar shrink-0 shadow-sm\" (infoClick)=\"onInfoBarClick()\"></ax-conversation-info-bar>\n }\n\n <ax-conversation-message-list class=\"axm-mini-chat__messages min-h-0 flex-1 overflow-hidden\" style=\"direction: ltr\">\n <div ax-conversation-message-list-no-active class=\"axm-mini-chat__no-active block\">\n <axm-chat-empty-state-host\n [compact]=\"true\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [initialAssistId]=\"assistId()\"\n [launchContext]=\"launchContext()\"\n [sendStarterPromptsInPlace]=\"true\"\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationCreated($event)\"\n />\n </div>\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty [compact]=\"true\" [sendStarterPromptsInPlace]=\"true\" />\n </ax-conversation-message-list>\n\n @if (showComposer()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n class=\"axm-mini-chat__composer shrink-0\"\n [hidden]=\"!hasActiveConversation()\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n }\n</div>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}.axm-mini-chat ax-conversation-message-list .message-list--conversation-surface{background:transparent!important;--ax-comp-message-list-surface-bg: transparent !important}.axm-mini-chat ax-conversation-message-list .message-list--default-wallpaper:before{content:none!important;background:none!important;opacity:0!important}.axm-mini-chat .axm-mini-chat__info-bar{border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat .axm-mini-chat__composer{border-top:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat .axm-mini-chat__composer[hidden]{display:none!important}.axm-mini-chat .axm-mini-chat__messages{background:radial-gradient(ellipse 120% 80% at 50% -20%,rgba(var(--ax-sys-color-primary-500),.07),transparent 55%),rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat ax-conversation-message-list.axm-mini-chat__messages{display:flex;flex-direction:column;min-height:0}.axm-mini-chat axm-chat-empty-state-host{display:flex;flex-direction:column;flex:1 1 auto;width:100%;height:100%;min-height:0;overflow:hidden}.axm-mini-chat .axm-mini-chat__no-active{width:100%;max-width:none;padding:0;margin:0;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}.axm-mini-chat ax-conversation-message-list .list-no-active{justify-content:stretch;align-items:stretch;min-height:100%;height:100%;overflow:hidden;padding:.625rem 1rem .875rem;gap:0;text-align:start;animation:none}.axm-mini-chat ax-conversation-message-list .list-empty{justify-content:flex-start;align-items:stretch;min-height:0;padding:.75rem .875rem 1rem;gap:0;text-align:start;animation:none}.axm-mini-chat .axm-chat-assist-composer-starter-prompts-host--compact .axm-chat-assist-welcome-empty{padding:0;gap:.5rem}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{border-color:rgba(var(--ax-sys-color-border-light-surface),.95);background:rgba(var(--ax-sys-color-surface),.55);color:rgb(var(--ax-sys-color-on-surface));transition:background-color .16s ease,border-color .16s ease,transform .16s ease}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.08);transform:translateY(-1px)}.axm-mini-chat .axm-assist-suggestion-chips{justify-content:flex-start;padding:.5rem 0 0;gap:.5rem}.axm-mini-chat .axm-assist-renderer__entity-cards{max-width:100%}@media(prefers-reduced-motion:reduce){.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{transition:none}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){transform:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7070
- }], ctorParameters: () => [], propDecorators: { chatId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatId", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], assistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistId", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], showInfoBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInfoBar", required: false }] }], showComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "showComposer", required: false }] }], conversationOpened: [{ type: i0.Output, args: ["conversationOpened"] }] } });
7842
+ ], template: "<div axConversationContainer class=\"axm-mini-chat flex h-full min-h-0 flex-col\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <!---->\n <!-- ----- Mini-chat widgets remount after platform locale/theme change ----- -->\n @if (showInfoBar() && hasActiveConversation()) {\n <ax-conversation-info-bar class=\"axm-mini-chat__info-bar shrink-0 shadow-sm\" (infoClick)=\"onInfoBarClick()\"></ax-conversation-info-bar>\n }\n\n <ax-conversation-message-list class=\"axm-mini-chat__messages min-h-0 flex-1 overflow-hidden\" style=\"direction: ltr\">\n <div ax-conversation-message-list-no-active class=\"axm-mini-chat__no-active block\">\n <axm-chat-empty-state-host\n [compact]=\"true\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [initialAssistId]=\"assistId()\"\n [assistSelection]=\"assistSelection()\"\n [launchContext]=\"launchContext()\"\n [sendStarterPromptsInPlace]=\"true\"\n [acceptExternalFileDrop]=\"true\"\n [acceptExternalFileDrop]=\"true\"\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationCreated($event)\"\n />\n </div>\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty [compact]=\"true\" [sendStarterPromptsInPlace]=\"true\" />\n </ax-conversation-message-list>\n\n @if (showComposer()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n class=\"axm-mini-chat__composer shrink-0\"\n [hidden]=\"!hasActiveConversation()\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n }\n</div>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}.axm-mini-chat ax-conversation-message-list .message-list--conversation-surface{background:transparent!important;--ax-comp-message-list-surface-bg: transparent !important}.axm-mini-chat ax-conversation-message-list .message-list--default-wallpaper:before{content:none!important;background:none!important;opacity:0!important}.axm-mini-chat .axm-mini-chat__info-bar{border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat .axm-mini-chat__composer{border-top:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat .axm-mini-chat__composer[hidden]{display:none!important}.axm-mini-chat .axm-mini-chat__messages{background:radial-gradient(ellipse 120% 80% at 50% -20%,rgba(var(--ax-sys-color-primary-500),.07),transparent 55%),rgb(var(--ax-sys-color-lightest-surface))}.axm-mini-chat ax-conversation-message-list.axm-mini-chat__messages{display:flex;flex-direction:column;min-height:0}.axm-mini-chat axm-chat-empty-state-host{display:flex;flex-direction:column;flex:1 1 auto;width:100%;height:100%;min-height:0;overflow:hidden}.axm-mini-chat .axm-mini-chat__no-active{width:100%;max-width:none;padding:0;margin:0;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}.axm-mini-chat ax-conversation-message-list .list-no-active{justify-content:stretch;align-items:stretch;min-height:100%;height:100%;overflow:hidden;padding:.625rem 1rem .875rem;gap:0;text-align:start;animation:none}.axm-mini-chat ax-conversation-message-list .list-empty{justify-content:flex-start;align-items:stretch;min-height:0;padding:.75rem .875rem 1rem;gap:0;text-align:start;animation:none}.axm-mini-chat .axm-chat-assist-composer-starter-prompts-host--compact .axm-chat-assist-welcome-empty{padding:0;gap:.5rem}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{border-color:rgba(var(--ax-sys-color-border-light-surface),.95);background:rgba(var(--ax-sys-color-surface),.55);color:rgb(var(--ax-sys-color-on-surface));transition:background-color .16s ease,border-color .16s ease,transform .16s ease}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){border-color:rgba(var(--ax-sys-color-primary-500),.35);background:rgba(var(--ax-sys-color-primary-500),.08);transform:translateY(-1px)}.axm-mini-chat .axm-assist-suggestion-chips{justify-content:flex-start;padding:.5rem 0 0;gap:.5rem}.axm-mini-chat .axm-assist-renderer__entity-cards{max-width:100%}@media(prefers-reduced-motion:reduce){.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip{transition:none}.axm-mini-chat .axm-assist-suggestion-chips-host--compact .axm-assist-suggestion-chips__chip:hover:not([disabled]){transform:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7843
+ }], ctorParameters: () => [], propDecorators: { chatId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatId", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], assistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistId", required: false }] }], assistSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistSelection", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], showInfoBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInfoBar", required: false }] }], showComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "showComposer", required: false }] }], conversationOpened: [{ type: i0.Output, args: ["conversationOpened"] }] } });
7844
+
7845
+ //#region ----- Imports -----
7846
+ //#endregion
7847
+ //#region ----- Service -----
7848
+ /** Asks the open header mini chat to drop the current thread and show the page home. */
7849
+ class AXMMiniChatRouteHomeBus {
7850
+ constructor() {
7851
+ //#region ----- State -----
7852
+ this.home = new Subject();
7853
+ this.home$ = this.home.asObservable();
7854
+ }
7855
+ //#endregion
7856
+ //#region ----- Public API -----
7857
+ requestHome() {
7858
+ this.home.next();
7859
+ }
7860
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatRouteHomeBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7861
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatRouteHomeBus, providedIn: 'root' }); }
7862
+ }
7863
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatRouteHomeBus, decorators: [{
7864
+ type: Injectable,
7865
+ args: [{ providedIn: 'root' }]
7866
+ }] });
7867
+ //#endregion
7868
+ //#region ----- Helpers -----
7869
+ function axmMiniChatPathKey(url) {
7870
+ return url.split('?')[0].split('#')[0];
7871
+ }
7872
+ function axmMiniChatCollectRouteParams(root) {
7873
+ const params = {};
7874
+ const visit = (node) => {
7875
+ for (const key of node.paramMap.keys) {
7876
+ const value = node.paramMap.get(key);
7877
+ if (value) {
7878
+ params[key] = value;
7879
+ }
7880
+ }
7881
+ for (const child of node.children) {
7882
+ visit(child);
7883
+ }
7884
+ };
7885
+ visit(root);
7886
+ return params;
7887
+ }
7071
7888
 
7072
7889
  //#region ----- Imports -----
7073
7890
  //#endregion
@@ -7080,12 +7897,16 @@ class AXMMiniChatPanelComponent {
7080
7897
  constructor() {
7081
7898
  //#region ----- Services & Dependencies -----
7082
7899
  this.conversationService = inject(AXConversationService);
7900
+ this.composerService = inject(AXConversationComposerService);
7901
+ this.fileDrop = inject(AXMMiniChatFileDropService);
7902
+ this.fileDragDepth = 0;
7083
7903
  this.conversationApi = inject(AXMChatConversationApi);
7084
7904
  this.pageContext = inject(AXPPageContextRegistry);
7085
7905
  this.localeService = inject(AXLocaleService);
7086
7906
  this.device = inject(AXPDeviceService);
7087
7907
  this.destroyRef = inject(DestroyRef);
7088
7908
  this.pageContextChips = inject(AXMMiniChatPageContextChipsService);
7909
+ this.routeHome = inject(AXMMiniChatRouteHomeBus);
7089
7910
  this.localeProfile = toSignal(this.localeService.profileChanged$, {
7090
7911
  initialValue: this.localeService.activeProfile(),
7091
7912
  });
@@ -7101,6 +7922,8 @@ class AXMMiniChatPanelComponent {
7101
7922
  ...(ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []));
7102
7923
  this.assistId = input(undefined, /* @ts-ignore */
7103
7924
  ...(ngDevMode ? [{ debugName: "assistId" }] : /* istanbul ignore next */ []));
7925
+ this.assistSelection = input('optional', /* @ts-ignore */
7926
+ ...(ngDevMode ? [{ debugName: "assistSelection" }] : /* istanbul ignore next */ []));
7104
7927
  this.title = input(undefined, /* @ts-ignore */
7105
7928
  ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
7106
7929
  this.showInfoBar = input(false, /* @ts-ignore */
@@ -7133,10 +7956,20 @@ class AXMMiniChatPanelComponent {
7133
7956
  ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
7134
7957
  this.selectedChatId = signal(undefined, /* @ts-ignore */
7135
7958
  ...(ngDevMode ? [{ debugName: "selectedChatId" }] : /* istanbul ignore next */ []));
7959
+ this.fileDragOver = signal(false, /* @ts-ignore */
7960
+ ...(ngDevMode ? [{ debugName: "fileDragOver" }] : /* istanbul ignore next */ []));
7136
7961
  //#endregion
7137
7962
  //#region ----- Computed Properties -----
7138
- this.isInboxScope = computed(() => this.scope() === 'inbox', /* @ts-ignore */
7139
- ...(ngDevMode ? [{ debugName: "isInboxScope" }] : /* istanbul ignore next */ []));
7963
+ this.historyScope = computed(() => {
7964
+ const fixed = axmMiniChatHistoryScopeFromOpen({
7965
+ scope: this.scope(),
7966
+ entityId: this.entityId(),
7967
+ entityType: this.entityType(),
7968
+ launchContext: this.launchContext(),
7969
+ });
7970
+ return fixed ?? this.pageContextChips.historyScope();
7971
+ }, /* @ts-ignore */
7972
+ ...(ngDevMode ? [{ debugName: "historyScope" }] : /* istanbul ignore next */ []));
7140
7973
  this.isEmbedded = computed(() => this.presentation() === 'embedded', /* @ts-ignore */
7141
7974
  ...(ngDevMode ? [{ debugName: "isEmbedded" }] : /* istanbul ignore next */ []));
7142
7975
  this.isRtl = computed(() => this.localeProfile()?.i18nMeta?.rtl === true, /* @ts-ignore */
@@ -7149,6 +7982,9 @@ class AXMMiniChatPanelComponent {
7149
7982
  ...(ngDevMode ? [{ debugName: "canMaximize" }] : /* istanbul ignore next */ []));
7150
7983
  this.canClose = computed(() => !this.isEmbedded(), /* @ts-ignore */
7151
7984
  ...(ngDevMode ? [{ debugName: "canClose" }] : /* istanbul ignore next */ []));
7985
+ /** Home is already a new chat; the plus action is for history and open threads. */
7986
+ this.showNewChatAction = computed(() => this.view() === 'history' || Boolean(this.selectedChatId()?.trim()), /* @ts-ignore */
7987
+ ...(ngDevMode ? [{ debugName: "showNewChatAction" }] : /* istanbul ignore next */ []));
7152
7988
  this.isRecordAssist = computed(() => {
7153
7989
  const launch = this.launchContext();
7154
7990
  return launch?.kind === AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD;
@@ -7211,6 +8047,9 @@ class AXMMiniChatPanelComponent {
7211
8047
  //#endregion
7212
8048
  //#region ----- Lifecycle -----
7213
8049
  ngOnInit() {
8050
+ this.routeHome.home$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
8051
+ void this.startNewChat();
8052
+ });
7214
8053
  this.view.set(this.initialView());
7215
8054
  const conversationId = this.initialConversationId()?.trim();
7216
8055
  this.bindPageContextChips(conversationId);
@@ -7245,6 +8084,55 @@ class AXMMiniChatPanelComponent {
7245
8084
  }
7246
8085
  this.requestMaximize()?.();
7247
8086
  }
8087
+ onFileDragEnter(event) {
8088
+ if (!this.canAcceptFileDrop(event)) {
8089
+ return;
8090
+ }
8091
+ event.preventDefault();
8092
+ this.fileDragDepth += 1;
8093
+ this.fileDragOver.set(true);
8094
+ }
8095
+ onFileDragOver(event) {
8096
+ if (!this.canAcceptFileDrop(event)) {
8097
+ return;
8098
+ }
8099
+ event.preventDefault();
8100
+ if (event.dataTransfer) {
8101
+ event.dataTransfer.dropEffect = 'copy';
8102
+ }
8103
+ }
8104
+ onFileDragLeave(event) {
8105
+ if (!this.isFileDrag(event)) {
8106
+ return;
8107
+ }
8108
+ event.preventDefault();
8109
+ this.fileDragDepth = Math.max(0, this.fileDragDepth - 1);
8110
+ this.fileDragOver.set(this.fileDragDepth > 0);
8111
+ }
8112
+ onFileDragEnd() {
8113
+ this.resetFileDrag();
8114
+ }
8115
+ async onFileDrop(event) {
8116
+ if (!this.canAcceptFileDrop(event)) {
8117
+ this.resetFileDrag();
8118
+ return;
8119
+ }
8120
+ event.preventDefault();
8121
+ event.stopPropagation();
8122
+ this.resetFileDrag();
8123
+ const files = Array.from(event.dataTransfer?.files ?? []);
8124
+ if (files.length === 0) {
8125
+ return;
8126
+ }
8127
+ if (this.view() === 'history') {
8128
+ this.backToThread();
8129
+ }
8130
+ if (this.conversationService.activeConversationId()?.trim()) {
8131
+ await this.composerService.addDraftAttachments(files);
8132
+ return;
8133
+ }
8134
+ this.fileDrop.addEmptyDraftFiles(files);
8135
+ }
7248
8136
  backToThread() {
7249
8137
  this.view.set('thread');
7250
8138
  this.syncSession();
@@ -7341,6 +8229,20 @@ class AXMMiniChatPanelComponent {
7341
8229
  }
7342
8230
  //#endregion
7343
8231
  //#region ----- Utility Methods -----
8232
+ canAcceptFileDrop(event) {
8233
+ return this.showComposer() && this.isFileDrag(event);
8234
+ }
8235
+ isFileDrag(event) {
8236
+ const types = event.dataTransfer?.types;
8237
+ if (!types) {
8238
+ return false;
8239
+ }
8240
+ return Array.from(types).includes('Files');
8241
+ }
8242
+ resetFileDrag() {
8243
+ this.fileDragDepth = 0;
8244
+ this.fileDragOver.set(false);
8245
+ }
7344
8246
  syncSession() {
7345
8247
  this.onSessionChange()?.({
7346
8248
  view: this.view(),
@@ -7348,7 +8250,7 @@ class AXMMiniChatPanelComponent {
7348
8250
  });
7349
8251
  }
7350
8252
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7351
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatPanelComponent, isStandalone: true, selector: "axm-mini-chat-panel", inputs: { scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null }, presentation: { classPropertyName: "presentation", publicName: "presentation", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, assistId: { classPropertyName: "assistId", publicName: "assistId", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showInfoBar: { classPropertyName: "showInfoBar", publicName: "showInfoBar", isSignal: true, isRequired: false, transformFunction: null }, showComposer: { classPropertyName: "showComposer", publicName: "showComposer", isSignal: true, isRequired: false, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: true, transformFunction: null }, requestMinimize: { classPropertyName: "requestMinimize", publicName: "requestMinimize", isSignal: true, isRequired: false, transformFunction: null }, requestMaximize: { classPropertyName: "requestMaximize", publicName: "requestMaximize", isSignal: true, isRequired: false, transformFunction: null }, requestRestore: { classPropertyName: "requestRestore", publicName: "requestRestore", isSignal: true, isRequired: false, transformFunction: null }, isMaximized: { classPropertyName: "isMaximized", publicName: "isMaximized", isSignal: true, isRequired: false, transformFunction: null }, initialView: { classPropertyName: "initialView", publicName: "initialView", isSignal: true, isRequired: false, transformFunction: null }, initialConversationId: { classPropertyName: "initialConversationId", publicName: "initialConversationId", isSignal: true, isRequired: false, transformFunction: null }, startWithNewChat: { classPropertyName: "startWithNewChat", publicName: "startWithNewChat", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, onSessionChange: { classPropertyName: "onSessionChange", publicName: "onSessionChange", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.axm-mini-chat-panel--embedded": "isEmbedded()" } }, ngImport: i0, template: "<div class=\"axm-mini-chat-panel flex h-full min-h-0 flex-col\" [class.axm-mini-chat-panel--embedded]=\"isEmbedded()\">\n <div class=\"axm-mini-chat-panel__header flex shrink-0 items-center justify-between gap-2\">\n <ng-template #brandTpl>\n @if (view() === 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"backToThread()\" [attr.aria-label]=\"('@conversation:mini-chat.back' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon [icon]=\"isRtl() ? 'fa-light fa-chevron-right' : 'fa-light fa-chevron-left'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-- ----- Brand mark on the main thread ----- -->\n @else {\n <span class=\"axm-mini-chat-panel__brand-mark shrink-0\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-regular fa-sparkles\"></ax-icon>\n </span>\n }\n <div class=\"min-w-0 flex flex-col\">\n <span class=\"axm-mini-chat-panel__brand-title truncate\">\n @if (view() === 'history') {\n {{ '@conversation:mini-chat.history-title' | translate | async }}\n } @else if (title()?.trim(); as panelTitle) {\n {{ (panelTitle | translate | async) ?? panelTitle }}\n }\n <!-- ----- Default branded title when the caller did not pass one ----- -->\n @else {\n {{ '@conversation:mini-chat.brand-title' | translate | async }}\n }\n </span>\n </div>\n </ng-template>\n @if (canDragWindow()) {\n <div axDragHandle class=\"axm-mini-chat-panel__brand axm-mini-chat-panel__brand--draggable min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <!-- ----- Brand without a window drag handle (embedded or small screens) ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__brand min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <div class=\"axm-mini-chat-panel__header-actions flex shrink-0 items-center gap-0.5\">\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"startNewChat()\" [attr.aria-label]=\"('@conversation:mini-chat.new-chat' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-plus\"></ax-icon></ax-prefix>\n </ax-button>\n @if (view() !== 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"openHistory()\" [attr.aria-label]=\"('@conversation:mini-chat.history-title' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-clock-rotate-left\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (canMinimize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"minimizePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.minimize' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"minimize\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canMaximize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"toggleMaximizePanel()\" [attr.aria-label]=\"((isMaximized() ? '@conversation:mini-chat.restore' : '@conversation:mini-chat.maximize') | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon [name]=\"isMaximized() ? 'restore' : 'maximize'\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canClose()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"closePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"close\" />\n </ax-prefix>\n </ax-button>\n }\n </div>\n </div>\n\n @if (launchContext()) {\n @if (showContextBar()) {\n <!-- ----- Current list or record the assist is working in ----- -->\n <div class=\"axm-mini-chat-panel__context shrink-0\">\n <i class=\"axm-mini-chat-panel__context-icon fa-light {{ contextBarIcon() }}\" aria-hidden=\"true\"></i>\n <span class=\"truncate\">\n <!---->\n <!-- ----- Record-scoped assist (entity row or details) ----- -->\n @if (isRecordAssist()) {\n @let recordTitle = recordTitleLabel();\n @let entityTitle = recordEntityTitle();\n @let entityLabel = entityTitle ? ((entityTitle | translate | async) ?? entityTitle) : '';\n @if (recordTitle) {\n {{ recordTitle }}\n @if (entityLabel) {\n \u00B7 {{ entityLabel }}\n }\n } @else if (entityLabel) {\n {{ entityLabel }}\n }\n }\n <!-- ----- List page: Working in Entity | View ----- -->\n @else if (workingInEntityTitle(); as entityTitle) {\n @let entityLabel = (entityTitle | translate | async) ?? entityTitle;\n @let viewTitle = workingInViewTitle();\n @let viewLabel = viewTitle ? ((viewTitle | translate | async) ?? viewTitle) : '';\n @let place = viewLabel ? entityLabel + ' | ' + viewLabel : entityLabel;\n {{ '@conversation:mini-chat.working-in' | translate: { params: { place } } | async }}\n }\n </span>\n </div>\n }\n }\n <!-- ----- Page chips when the header chat is not opened from another surface ----- -->\n @else if (view() !== 'history' && pageContextChips.chips().length > 0) {\n <!-- ----- Entity, view, and selected records for this chat ----- -->\n <div class=\"axm-mini-chat-panel__context axm-mini-chat-panel__context--chips shrink-0\">\n @for (chip of pageContextChips.chips(); track chip.id) {\n <ax-chips class=\"ax-sm\" look=\"outline\" color=\"primary\" [text]=\"chip.label\">\n <ax-prefix>\n <ax-icon [icon]=\"chipIcon(chip.kind)\"></ax-icon>\n </ax-prefix>\n <!--------------------------------------------------------------->\n <!-- ----- Remove this chip until the next page or selection change ----- -->\n @if (!pageContextChips.locked()) {\n <ax-suffix>\n <button\n type=\"button\"\n class=\"axm-mini-chat-panel__chip-close\"\n (click)=\"dismissPageContextChip(chip.id, $event)\"\n [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\"\n >\n <ax-icon icon=\"fa-light fa-xmark\"></ax-icon>\n </button>\n </ax-suffix>\n }\n </ax-chips>\n }\n </div>\n }\n\n @if (view() === 'history') {\n <div class=\"axm-mini-chat-panel__history relative flex min-h-0 flex-1 flex-col\">\n @if (isInboxScope()) {\n <axm-mini-chat-inbox-history (conversationSelected)=\"selectChat($event)\" />\n }\n <!-- ----- Entity-bound history when the panel is opened from a record ----- -->\n @else {\n <axm-mini-chat-history [entityId]=\"entityId()!\" [entityType]=\"entityType()!\" (conversationSelected)=\"selectChat($event)\" />\n }\n </div>\n }\n <!-- ----- Active thread ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__body flex min-h-0 flex-1 flex-col\">\n <axm-mini-chat\n class=\"flex min-h-0 flex-1 flex-col\"\n [chatId]=\"selectedChatId()\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [assistId]=\"assistId()\"\n [launchContext]=\"launchContext()\"\n [showInfoBar]=\"showInfoBar()\"\n [showComposer]=\"showComposer()\"\n (conversationOpened)=\"onConversationOpened($event)\"\n />\n </div>\n }\n</div>\n", styles: ["axm-mini-chat-panel{display:block;height:100%;background:transparent;border:none;box-shadow:none;overflow:visible}.axm-mini-chat-panel-shell{pointer-events:none;box-sizing:border-box;background:transparent!important;border:none!important;box-shadow:none!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell.ax-overlay-container,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{pointer-events:auto;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important;border-radius:0!important;overflow:visible!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{flex:0 0 auto;width:min(92vw,24.5rem)!important;height:min(36rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ))!important;max-width:calc(100vw - 1.5rem);max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--default{inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;padding-right:max(1.5rem,env(safe-area-inset-right,0px));padding-bottom:max(5.5rem,calc(1.5rem + env(safe-area-inset-bottom,0px)));padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--anchored,.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--fixed{inset:unset;width:auto;height:auto;display:block;padding:0}.axm-mini-chat-panel{box-sizing:border-box;display:flex;height:100%;flex-direction:column;overflow:hidden;border-radius:1rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 18px 48px -12px rgba(var(--ax-sys-color-on-surface),.2),0 6px 16px -4px rgba(var(--ax-sys-color-on-surface),.08)}.axm-mini-chat-panel.axm-mini-chat-panel--embedded{border-radius:.75rem;height:100%;min-height:22rem;box-shadow:none}.axm-mini-chat-panel .axm-mini-chat-panel__header{min-height:3rem;padding:.625rem .75rem .5rem .875rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__brand--draggable{cursor:grab;-webkit-user-select:none;user-select:none;min-width:0;flex:1 1 auto}.axm-mini-chat-panel .axm-mini-chat-panel__brand-mark{display:grid;place-items:center;width:1.75rem;height:1.75rem;border-radius:.5rem;color:rgb(var(--ax-sys-color-primary-600));background:linear-gradient(145deg,rgba(var(--ax-sys-color-primary-500),.16),rgba(var(--ax-sys-color-primary-500),.05));border:1px solid rgba(var(--ax-sys-color-primary-500),.18);font-size:.8125rem}.axm-mini-chat-panel .axm-mini-chat-panel__brand-title{font-size:.875rem;font-weight:650;line-height:1.25;color:rgb(var(--ax-sys-color-on-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button{opacity:.7;transition:opacity .16s ease}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-popup-caption-icon{display:block;width:.75rem;height:.75rem}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button:hover{opacity:1}.axm-mini-chat-panel .axm-mini-chat-panel__context{display:flex;align-items:center;gap:.5rem;min-height:2rem;padding:.375rem .875rem;font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-primary-700));background:rgba(var(--ax-sys-color-primary-500),.08);border-bottom:1px solid rgba(var(--ax-sys-color-primary-500),.1)}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips{flex-wrap:nowrap;overflow:auto}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips ax-chips{flex-shrink:0}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close{display:inline-flex;align-items:center;justify-content:center;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;line-height:1}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close ax-icon{font-size:.6875rem}.axm-mini-chat-panel .axm-mini-chat-panel__context-icon{font-size:.8125rem;opacity:.85;flex-shrink:0}@media(max-width:600px){.axm-mini-chat-panel-shell{pointer-events:auto;position:fixed;box-sizing:border-box;display:flex;flex-direction:column;inset:0!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;padding:0!important}.axm-mini-chat-panel-shell .ax-overlay-pane{pointer-events:auto;position:relative;--tw-border-style: none;border-style:none;inset:unset!important;left:unset!important;top:unset!important;right:unset!important;bottom:unset!important;transform:none!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;flex:1 1 auto!important;background:transparent!important;box-shadow:none!important;padding:0!important;border-radius:0!important}.axm-mini-chat-panel-shell .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.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: "directive", type: AXDragHandleDirective, selector: "[axDragHandle]" }, { kind: "component", type: AXPopupCaptionIconComponent, selector: "ax-popup-caption-icon", inputs: ["name"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXMMiniChatComponent, selector: "axm-mini-chat", inputs: ["chatId", "entityId", "entityType", "assistId", "launchContext", "showInfoBar", "showComposer"], outputs: ["conversationOpened"] }, { kind: "component", type: AXMMiniChatHistoryComponent, selector: "axm-mini-chat-history", inputs: ["entityId", "entityType"], outputs: ["conversationSelected", "hasConversationsChange"] }, { kind: "component", type: AXMMiniChatInboxHistoryComponent, selector: "axm-mini-chat-inbox-history", outputs: ["conversationSelected", "hasConversationsChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXChipsComponent, selector: "ax-chips", inputs: ["tabIndex", "color", "look", "text"], outputs: ["textChange"] }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8253
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMMiniChatPanelComponent, isStandalone: true, selector: "axm-mini-chat-panel", inputs: { scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null }, presentation: { classPropertyName: "presentation", publicName: "presentation", isSignal: true, isRequired: false, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, assistId: { classPropertyName: "assistId", publicName: "assistId", isSignal: true, isRequired: false, transformFunction: null }, assistSelection: { classPropertyName: "assistSelection", publicName: "assistSelection", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showInfoBar: { classPropertyName: "showInfoBar", publicName: "showInfoBar", isSignal: true, isRequired: false, transformFunction: null }, showComposer: { classPropertyName: "showComposer", publicName: "showComposer", isSignal: true, isRequired: false, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: true, transformFunction: null }, requestMinimize: { classPropertyName: "requestMinimize", publicName: "requestMinimize", isSignal: true, isRequired: false, transformFunction: null }, requestMaximize: { classPropertyName: "requestMaximize", publicName: "requestMaximize", isSignal: true, isRequired: false, transformFunction: null }, requestRestore: { classPropertyName: "requestRestore", publicName: "requestRestore", isSignal: true, isRequired: false, transformFunction: null }, isMaximized: { classPropertyName: "isMaximized", publicName: "isMaximized", isSignal: true, isRequired: false, transformFunction: null }, initialView: { classPropertyName: "initialView", publicName: "initialView", isSignal: true, isRequired: false, transformFunction: null }, initialConversationId: { classPropertyName: "initialConversationId", publicName: "initialConversationId", isSignal: true, isRequired: false, transformFunction: null }, startWithNewChat: { classPropertyName: "startWithNewChat", publicName: "startWithNewChat", isSignal: true, isRequired: false, transformFunction: null }, launchContext: { classPropertyName: "launchContext", publicName: "launchContext", isSignal: true, isRequired: false, transformFunction: null }, onSessionChange: { classPropertyName: "onSessionChange", publicName: "onSessionChange", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.axm-mini-chat-panel--embedded": "isEmbedded()" } }, ngImport: i0, template: "<div\n class=\"axm-mini-chat-panel flex h-full min-h-0 flex-col\"\n [class.axm-mini-chat-panel--embedded]=\"isEmbedded()\"\n [class.axm-mini-chat-panel--drag-over]=\"fileDragOver()\"\n (dragenter)=\"onFileDragEnter($event)\"\n (dragover)=\"onFileDragOver($event)\"\n (dragleave)=\"onFileDragLeave($event)\"\n (dragend)=\"onFileDragEnd()\"\n (drop)=\"onFileDrop($event)\"\n>\n <div class=\"axm-mini-chat-panel__header flex shrink-0 items-center justify-between gap-2\">\n <ng-template #brandTpl>\n @if (view() === 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"backToThread()\" [attr.aria-label]=\"('@conversation:mini-chat.back' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon [icon]=\"isRtl() ? 'fa-light fa-chevron-right' : 'fa-light fa-chevron-left'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-- ----- Brand mark on the main thread ----- -->\n @else {\n <span class=\"axm-mini-chat-panel__brand-mark shrink-0\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-regular fa-sparkles\"></ax-icon>\n </span>\n }\n <div class=\"min-w-0 flex flex-col\">\n <span class=\"axm-mini-chat-panel__brand-title truncate\">\n @if (view() === 'history') {\n {{ '@conversation:mini-chat.history-title' | translate | async }}\n } @else if (title()?.trim(); as panelTitle) {\n {{ (panelTitle | translate | async) ?? panelTitle }}\n }\n <!-- ----- Default branded title when the caller did not pass one ----- -->\n @else {\n {{ '@conversation:mini-chat.brand-title' | translate | async }}\n }\n </span>\n </div>\n </ng-template>\n @if (canDragWindow()) {\n <div axDragHandle class=\"axm-mini-chat-panel__brand axm-mini-chat-panel__brand--draggable min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <!-- ----- Brand without a window drag handle (embedded or small screens) ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__brand min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <div class=\"axm-mini-chat-panel__header-actions flex shrink-0 items-center gap-0.5\">\n <!-- ----- New chat is redundant on the home composer ----- -->\n @if (showNewChatAction()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"startNewChat()\" [attr.aria-label]=\"('@conversation:mini-chat.new-chat' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-plus\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (view() !== 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"openHistory()\" [attr.aria-label]=\"('@conversation:mini-chat.history-title' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-clock-rotate-left\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (canMinimize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"minimizePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.minimize' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"minimize\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canMaximize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"toggleMaximizePanel()\" [attr.aria-label]=\"((isMaximized() ? '@conversation:mini-chat.restore' : '@conversation:mini-chat.maximize') | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon [name]=\"isMaximized() ? 'restore' : 'maximize'\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canClose()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"closePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"close\" />\n </ax-prefix>\n </ax-button>\n }\n </div>\n </div>\n\n @if (launchContext()) {\n @if (showContextBar()) {\n <!-- ----- Current list or record the assist is working in ----- -->\n <div class=\"axm-mini-chat-panel__context shrink-0\">\n <i class=\"axm-mini-chat-panel__context-icon fa-light {{ contextBarIcon() }}\" aria-hidden=\"true\"></i>\n <span class=\"truncate\">\n <!---->\n <!-- ----- Record-scoped assist (entity row or details) ----- -->\n @if (isRecordAssist()) {\n @let recordTitle = recordTitleLabel();\n @let entityTitle = recordEntityTitle();\n @let entityLabel = entityTitle ? ((entityTitle | translate | async) ?? entityTitle) : '';\n @if (recordTitle) {\n {{ recordTitle }}\n @if (entityLabel) {\n \u00B7 {{ entityLabel }}\n }\n } @else if (entityLabel) {\n {{ entityLabel }}\n }\n }\n <!-- ----- List page: Working in Entity | View ----- -->\n @else if (workingInEntityTitle(); as entityTitle) {\n @let entityLabel = (entityTitle | translate | async) ?? entityTitle;\n @let viewTitle = workingInViewTitle();\n @let viewLabel = viewTitle ? ((viewTitle | translate | async) ?? viewTitle) : '';\n @let place = viewLabel ? entityLabel + ' | ' + viewLabel : entityLabel;\n {{ '@conversation:mini-chat.working-in' | translate: { params: { place } } | async }}\n }\n </span>\n </div>\n }\n }\n <!-- ----- Page chips when the header chat is not opened from another surface ----- -->\n @else if (view() !== 'history' && pageContextChips.chips().length > 0) {\n <!-- ----- Entity, view, and selected records for this chat ----- -->\n <div class=\"axm-mini-chat-panel__context axm-mini-chat-panel__context--chips shrink-0\">\n @for (chip of pageContextChips.chips(); track chip.id) {\n <ax-chips class=\"ax-sm\" look=\"outline\" color=\"primary\" [text]=\"chip.label\">\n <ax-prefix>\n <ax-icon [icon]=\"chipIcon(chip.kind)\"></ax-icon>\n </ax-prefix>\n <!--------------------------------------------------------------->\n <!-- ----- Remove this chip until the next page or selection change ----- -->\n @if (!pageContextChips.locked()) {\n <ax-suffix>\n <button\n type=\"button\"\n class=\"axm-mini-chat-panel__chip-close\"\n (click)=\"dismissPageContextChip(chip.id, $event)\"\n [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\"\n >\n <ax-icon icon=\"fa-light fa-xmark\"></ax-icon>\n </button>\n </ax-suffix>\n }\n </ax-chips>\n }\n </div>\n }\n\n @if (view() === 'history') {\n <div class=\"axm-mini-chat-panel__history relative flex min-h-0 flex-1 flex-col\">\n @if (historyScope(); as scope) {\n <!---->\n <!-- ----- One entity or one record ----- -->\n @if (scope.mode === 'entity' && scope.entityIds.length === 1) {\n <axm-mini-chat-history [entityId]=\"scope.entityIds[0]\" [entityType]=\"scope.entityType\" (conversationSelected)=\"selectChat($event)\" />\n }\n <!---->\n <!-- ----- Global, form designer, or several selected records ----- -->\n @else {\n <axm-mini-chat-inbox-history [scope]=\"scope\" (conversationSelected)=\"selectChat($event)\" />\n }\n }\n </div>\n }\n <!-- ----- Active thread ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__body flex min-h-0 flex-1 flex-col\">\n <axm-mini-chat\n class=\"flex min-h-0 flex-1 flex-col\"\n [chatId]=\"selectedChatId()\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [assistId]=\"assistId()\"\n [assistSelection]=\"assistSelection()\"\n [launchContext]=\"launchContext()\"\n [showInfoBar]=\"showInfoBar()\"\n [showComposer]=\"showComposer()\"\n (conversationOpened)=\"onConversationOpened($event)\"\n />\n </div>\n }\n <!-- ----- File drop highlight across the whole mini-chat window ----- -->\n @if (fileDragOver()) {\n <div class=\"axm-mini-chat-panel__drop-overlay\" aria-hidden=\"true\">\n <div class=\"axm-mini-chat-panel__drop-frame\">\n <span class=\"axm-mini-chat-panel__drop-label\">\n <ax-icon icon=\"fa-light fa-paperclip\"></ax-icon>\n {{ '@conversation:mini-chat.drop-files.title' | translate | async }}\n </span>\n </div>\n </div>\n }\n</div>\n", styles: ["axm-mini-chat-panel{display:block;height:100%;background:transparent;border:none;box-shadow:none;overflow:visible}.axm-mini-chat-panel-shell{pointer-events:none;box-sizing:border-box;background:transparent!important;border:none!important;box-shadow:none!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell.ax-overlay-container,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{pointer-events:auto;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important;border-radius:0!important;overflow:visible!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{flex:0 0 auto;width:min(92vw,24.5rem)!important;height:min(36rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ))!important;max-width:calc(100vw - 1.5rem);max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--default{inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;padding-right:max(1.5rem,env(safe-area-inset-right,0px));padding-bottom:max(5.5rem,calc(1.5rem + env(safe-area-inset-bottom,0px)));padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--anchored,.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--fixed{inset:unset;width:auto;height:auto;display:block;padding:0}.axm-mini-chat-panel{position:relative;box-sizing:border-box;display:flex;height:100%;flex-direction:column;overflow:hidden;border-radius:1rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 18px 48px -12px rgba(var(--ax-sys-color-on-surface),.2),0 6px 16px -4px rgba(var(--ax-sys-color-on-surface),.08)}.axm-mini-chat-panel.axm-mini-chat-panel--drag-over{border-color:rgb(var(--ax-sys-color-primary-300))}.axm-mini-chat-panel .axm-mini-chat-panel__drop-overlay{position:absolute;inset:0;z-index:20;display:grid;padding:.875rem;pointer-events:none;background:rgba(var(--ax-sys-color-lightest-surface),.82);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.axm-mini-chat-panel .axm-mini-chat-panel__drop-frame{display:grid;place-items:center;min-height:0;padding:1.25rem;border:2px dashed rgb(var(--ax-sys-color-primary-400));border-radius:.75rem;background:rgba(var(--ax-sys-color-primary-50),.55)}.axm-mini-chat-panel .axm-mini-chat-panel__drop-label{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;max-width:min(100%,16rem);padding:.625rem .875rem;border-radius:999px;background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-primary-800));box-shadow:0 10px 28px -8px rgba(var(--ax-sys-color-on-surface),.28),0 0 0 1px rgba(var(--ax-sys-color-primary-200),.9);font-size:.875rem;font-weight:600;line-height:1.3;text-align:center}.axm-mini-chat-panel .axm-mini-chat-panel__drop-label ax-icon{flex:0 0 auto;color:rgb(var(--ax-sys-color-primary-600))}.axm-mini-chat-panel.axm-mini-chat-panel--embedded{border-radius:.75rem;height:100%;min-height:22rem;box-shadow:none}.axm-mini-chat-panel .axm-mini-chat-panel__header{min-height:3rem;padding:.625rem .75rem .5rem .875rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__brand--draggable{cursor:grab;-webkit-user-select:none;user-select:none;min-width:0;flex:1 1 auto}.axm-mini-chat-panel .axm-mini-chat-panel__brand-mark{display:grid;place-items:center;width:1.75rem;height:1.75rem;border-radius:.5rem;color:rgb(var(--ax-sys-color-primary-600));background:linear-gradient(145deg,rgba(var(--ax-sys-color-primary-500),.16),rgba(var(--ax-sys-color-primary-500),.05));border:1px solid rgba(var(--ax-sys-color-primary-500),.18);font-size:.8125rem}.axm-mini-chat-panel .axm-mini-chat-panel__brand-title{font-size:.875rem;font-weight:650;line-height:1.25;color:rgb(var(--ax-sys-color-on-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button{opacity:.7;transition:opacity .16s ease}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-popup-caption-icon{display:block;width:.75rem;height:.75rem}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button:hover{opacity:1}.axm-mini-chat-panel .axm-mini-chat-panel__context{display:flex;align-items:center;gap:.5rem;min-height:2rem;padding:.375rem .875rem;font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-primary-700));background:rgba(var(--ax-sys-color-primary-500),.08);border-bottom:1px solid rgba(var(--ax-sys-color-primary-500),.1)}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips{flex-wrap:nowrap;overflow:auto}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips ax-chips{flex-shrink:0}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close{display:inline-flex;align-items:center;justify-content:center;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;line-height:1}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close ax-icon{font-size:.6875rem}.axm-mini-chat-panel .axm-mini-chat-panel__context-icon{font-size:.8125rem;opacity:.85;flex-shrink:0}@media(max-width:600px){.axm-mini-chat-panel-shell{pointer-events:auto;position:fixed;box-sizing:border-box;display:flex;flex-direction:column;inset:0!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;padding:0!important}.axm-mini-chat-panel-shell .ax-overlay-pane{pointer-events:auto;position:relative;--tw-border-style: none;border-style:none;inset:unset!important;left:unset!important;top:unset!important;right:unset!important;bottom:unset!important;transform:none!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;flex:1 1 auto!important;background:transparent!important;box-shadow:none!important;padding:0!important;border-radius:0!important}.axm-mini-chat-panel-shell .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.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: "directive", type: AXDragHandleDirective, selector: "[axDragHandle]" }, { kind: "component", type: AXPopupCaptionIconComponent, selector: "ax-popup-caption-icon", inputs: ["name"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXMMiniChatComponent, selector: "axm-mini-chat", inputs: ["chatId", "entityId", "entityType", "assistId", "assistSelection", "launchContext", "showInfoBar", "showComposer"], outputs: ["conversationOpened"] }, { kind: "component", type: AXMMiniChatHistoryComponent, selector: "axm-mini-chat-history", inputs: ["entityId", "entityType"], outputs: ["conversationSelected", "hasConversationsChange"] }, { kind: "component", type: AXMMiniChatInboxHistoryComponent, selector: "axm-mini-chat-inbox-history", inputs: ["scope"], outputs: ["conversationSelected", "hasConversationsChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXChipsComponent, selector: "ax-chips", inputs: ["tabIndex", "color", "look", "text"], outputs: ["textChange"] }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
7352
8254
  }
7353
8255
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatPanelComponent, decorators: [{
7354
8256
  type: Component,
@@ -7366,8 +8268,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7366
8268
  AsyncPipe,
7367
8269
  NgTemplateOutlet,
7368
8270
  AXChipsComponent,
7369
- ], template: "<div class=\"axm-mini-chat-panel flex h-full min-h-0 flex-col\" [class.axm-mini-chat-panel--embedded]=\"isEmbedded()\">\n <div class=\"axm-mini-chat-panel__header flex shrink-0 items-center justify-between gap-2\">\n <ng-template #brandTpl>\n @if (view() === 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"backToThread()\" [attr.aria-label]=\"('@conversation:mini-chat.back' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon [icon]=\"isRtl() ? 'fa-light fa-chevron-right' : 'fa-light fa-chevron-left'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-- ----- Brand mark on the main thread ----- -->\n @else {\n <span class=\"axm-mini-chat-panel__brand-mark shrink-0\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-regular fa-sparkles\"></ax-icon>\n </span>\n }\n <div class=\"min-w-0 flex flex-col\">\n <span class=\"axm-mini-chat-panel__brand-title truncate\">\n @if (view() === 'history') {\n {{ '@conversation:mini-chat.history-title' | translate | async }}\n } @else if (title()?.trim(); as panelTitle) {\n {{ (panelTitle | translate | async) ?? panelTitle }}\n }\n <!-- ----- Default branded title when the caller did not pass one ----- -->\n @else {\n {{ '@conversation:mini-chat.brand-title' | translate | async }}\n }\n </span>\n </div>\n </ng-template>\n @if (canDragWindow()) {\n <div axDragHandle class=\"axm-mini-chat-panel__brand axm-mini-chat-panel__brand--draggable min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <!-- ----- Brand without a window drag handle (embedded or small screens) ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__brand min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <div class=\"axm-mini-chat-panel__header-actions flex shrink-0 items-center gap-0.5\">\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"startNewChat()\" [attr.aria-label]=\"('@conversation:mini-chat.new-chat' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-plus\"></ax-icon></ax-prefix>\n </ax-button>\n @if (view() !== 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"openHistory()\" [attr.aria-label]=\"('@conversation:mini-chat.history-title' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-clock-rotate-left\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (canMinimize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"minimizePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.minimize' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"minimize\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canMaximize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"toggleMaximizePanel()\" [attr.aria-label]=\"((isMaximized() ? '@conversation:mini-chat.restore' : '@conversation:mini-chat.maximize') | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon [name]=\"isMaximized() ? 'restore' : 'maximize'\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canClose()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"closePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"close\" />\n </ax-prefix>\n </ax-button>\n }\n </div>\n </div>\n\n @if (launchContext()) {\n @if (showContextBar()) {\n <!-- ----- Current list or record the assist is working in ----- -->\n <div class=\"axm-mini-chat-panel__context shrink-0\">\n <i class=\"axm-mini-chat-panel__context-icon fa-light {{ contextBarIcon() }}\" aria-hidden=\"true\"></i>\n <span class=\"truncate\">\n <!---->\n <!-- ----- Record-scoped assist (entity row or details) ----- -->\n @if (isRecordAssist()) {\n @let recordTitle = recordTitleLabel();\n @let entityTitle = recordEntityTitle();\n @let entityLabel = entityTitle ? ((entityTitle | translate | async) ?? entityTitle) : '';\n @if (recordTitle) {\n {{ recordTitle }}\n @if (entityLabel) {\n \u00B7 {{ entityLabel }}\n }\n } @else if (entityLabel) {\n {{ entityLabel }}\n }\n }\n <!-- ----- List page: Working in Entity | View ----- -->\n @else if (workingInEntityTitle(); as entityTitle) {\n @let entityLabel = (entityTitle | translate | async) ?? entityTitle;\n @let viewTitle = workingInViewTitle();\n @let viewLabel = viewTitle ? ((viewTitle | translate | async) ?? viewTitle) : '';\n @let place = viewLabel ? entityLabel + ' | ' + viewLabel : entityLabel;\n {{ '@conversation:mini-chat.working-in' | translate: { params: { place } } | async }}\n }\n </span>\n </div>\n }\n }\n <!-- ----- Page chips when the header chat is not opened from another surface ----- -->\n @else if (view() !== 'history' && pageContextChips.chips().length > 0) {\n <!-- ----- Entity, view, and selected records for this chat ----- -->\n <div class=\"axm-mini-chat-panel__context axm-mini-chat-panel__context--chips shrink-0\">\n @for (chip of pageContextChips.chips(); track chip.id) {\n <ax-chips class=\"ax-sm\" look=\"outline\" color=\"primary\" [text]=\"chip.label\">\n <ax-prefix>\n <ax-icon [icon]=\"chipIcon(chip.kind)\"></ax-icon>\n </ax-prefix>\n <!--------------------------------------------------------------->\n <!-- ----- Remove this chip until the next page or selection change ----- -->\n @if (!pageContextChips.locked()) {\n <ax-suffix>\n <button\n type=\"button\"\n class=\"axm-mini-chat-panel__chip-close\"\n (click)=\"dismissPageContextChip(chip.id, $event)\"\n [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\"\n >\n <ax-icon icon=\"fa-light fa-xmark\"></ax-icon>\n </button>\n </ax-suffix>\n }\n </ax-chips>\n }\n </div>\n }\n\n @if (view() === 'history') {\n <div class=\"axm-mini-chat-panel__history relative flex min-h-0 flex-1 flex-col\">\n @if (isInboxScope()) {\n <axm-mini-chat-inbox-history (conversationSelected)=\"selectChat($event)\" />\n }\n <!-- ----- Entity-bound history when the panel is opened from a record ----- -->\n @else {\n <axm-mini-chat-history [entityId]=\"entityId()!\" [entityType]=\"entityType()!\" (conversationSelected)=\"selectChat($event)\" />\n }\n </div>\n }\n <!-- ----- Active thread ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__body flex min-h-0 flex-1 flex-col\">\n <axm-mini-chat\n class=\"flex min-h-0 flex-1 flex-col\"\n [chatId]=\"selectedChatId()\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [assistId]=\"assistId()\"\n [launchContext]=\"launchContext()\"\n [showInfoBar]=\"showInfoBar()\"\n [showComposer]=\"showComposer()\"\n (conversationOpened)=\"onConversationOpened($event)\"\n />\n </div>\n }\n</div>\n", styles: ["axm-mini-chat-panel{display:block;height:100%;background:transparent;border:none;box-shadow:none;overflow:visible}.axm-mini-chat-panel-shell{pointer-events:none;box-sizing:border-box;background:transparent!important;border:none!important;box-shadow:none!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell.ax-overlay-container,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{pointer-events:auto;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important;border-radius:0!important;overflow:visible!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{flex:0 0 auto;width:min(92vw,24.5rem)!important;height:min(36rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ))!important;max-width:calc(100vw - 1.5rem);max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--default{inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;padding-right:max(1.5rem,env(safe-area-inset-right,0px));padding-bottom:max(5.5rem,calc(1.5rem + env(safe-area-inset-bottom,0px)));padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--anchored,.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--fixed{inset:unset;width:auto;height:auto;display:block;padding:0}.axm-mini-chat-panel{box-sizing:border-box;display:flex;height:100%;flex-direction:column;overflow:hidden;border-radius:1rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 18px 48px -12px rgba(var(--ax-sys-color-on-surface),.2),0 6px 16px -4px rgba(var(--ax-sys-color-on-surface),.08)}.axm-mini-chat-panel.axm-mini-chat-panel--embedded{border-radius:.75rem;height:100%;min-height:22rem;box-shadow:none}.axm-mini-chat-panel .axm-mini-chat-panel__header{min-height:3rem;padding:.625rem .75rem .5rem .875rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__brand--draggable{cursor:grab;-webkit-user-select:none;user-select:none;min-width:0;flex:1 1 auto}.axm-mini-chat-panel .axm-mini-chat-panel__brand-mark{display:grid;place-items:center;width:1.75rem;height:1.75rem;border-radius:.5rem;color:rgb(var(--ax-sys-color-primary-600));background:linear-gradient(145deg,rgba(var(--ax-sys-color-primary-500),.16),rgba(var(--ax-sys-color-primary-500),.05));border:1px solid rgba(var(--ax-sys-color-primary-500),.18);font-size:.8125rem}.axm-mini-chat-panel .axm-mini-chat-panel__brand-title{font-size:.875rem;font-weight:650;line-height:1.25;color:rgb(var(--ax-sys-color-on-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button{opacity:.7;transition:opacity .16s ease}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-popup-caption-icon{display:block;width:.75rem;height:.75rem}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button:hover{opacity:1}.axm-mini-chat-panel .axm-mini-chat-panel__context{display:flex;align-items:center;gap:.5rem;min-height:2rem;padding:.375rem .875rem;font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-primary-700));background:rgba(var(--ax-sys-color-primary-500),.08);border-bottom:1px solid rgba(var(--ax-sys-color-primary-500),.1)}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips{flex-wrap:nowrap;overflow:auto}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips ax-chips{flex-shrink:0}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close{display:inline-flex;align-items:center;justify-content:center;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;line-height:1}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close ax-icon{font-size:.6875rem}.axm-mini-chat-panel .axm-mini-chat-panel__context-icon{font-size:.8125rem;opacity:.85;flex-shrink:0}@media(max-width:600px){.axm-mini-chat-panel-shell{pointer-events:auto;position:fixed;box-sizing:border-box;display:flex;flex-direction:column;inset:0!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;padding:0!important}.axm-mini-chat-panel-shell .ax-overlay-pane{pointer-events:auto;position:relative;--tw-border-style: none;border-style:none;inset:unset!important;left:unset!important;top:unset!important;right:unset!important;bottom:unset!important;transform:none!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;flex:1 1 auto!important;background:transparent!important;box-shadow:none!important;padding:0!important;border-radius:0!important}.axm-mini-chat-panel-shell .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7370
- }], propDecorators: { scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }], presentation: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentation", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], assistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistId", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showInfoBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInfoBar", required: false }] }], showComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "showComposer", required: false }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: true }] }], requestMinimize: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestMinimize", required: false }] }], requestMaximize: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestMaximize", required: false }] }], requestRestore: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestRestore", required: false }] }], isMaximized: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMaximized", required: false }] }], initialView: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialView", required: false }] }], initialConversationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialConversationId", required: false }] }], startWithNewChat: [{ type: i0.Input, args: [{ isSignal: true, alias: "startWithNewChat", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], onSessionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onSessionChange", required: false }] }] } });
8271
+ ], template: "<div\n class=\"axm-mini-chat-panel flex h-full min-h-0 flex-col\"\n [class.axm-mini-chat-panel--embedded]=\"isEmbedded()\"\n [class.axm-mini-chat-panel--drag-over]=\"fileDragOver()\"\n (dragenter)=\"onFileDragEnter($event)\"\n (dragover)=\"onFileDragOver($event)\"\n (dragleave)=\"onFileDragLeave($event)\"\n (dragend)=\"onFileDragEnd()\"\n (drop)=\"onFileDrop($event)\"\n>\n <div class=\"axm-mini-chat-panel__header flex shrink-0 items-center justify-between gap-2\">\n <ng-template #brandTpl>\n @if (view() === 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"backToThread()\" [attr.aria-label]=\"('@conversation:mini-chat.back' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon [icon]=\"isRtl() ? 'fa-light fa-chevron-right' : 'fa-light fa-chevron-left'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-- ----- Brand mark on the main thread ----- -->\n @else {\n <span class=\"axm-mini-chat-panel__brand-mark shrink-0\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-regular fa-sparkles\"></ax-icon>\n </span>\n }\n <div class=\"min-w-0 flex flex-col\">\n <span class=\"axm-mini-chat-panel__brand-title truncate\">\n @if (view() === 'history') {\n {{ '@conversation:mini-chat.history-title' | translate | async }}\n } @else if (title()?.trim(); as panelTitle) {\n {{ (panelTitle | translate | async) ?? panelTitle }}\n }\n <!-- ----- Default branded title when the caller did not pass one ----- -->\n @else {\n {{ '@conversation:mini-chat.brand-title' | translate | async }}\n }\n </span>\n </div>\n </ng-template>\n @if (canDragWindow()) {\n <div axDragHandle class=\"axm-mini-chat-panel__brand axm-mini-chat-panel__brand--draggable min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <!-- ----- Brand without a window drag handle (embedded or small screens) ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__brand min-w-0 flex items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"brandTpl\"></ng-container>\n </div>\n }\n <div class=\"axm-mini-chat-panel__header-actions flex shrink-0 items-center gap-0.5\">\n <!-- ----- New chat is redundant on the home composer ----- -->\n @if (showNewChatAction()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"startNewChat()\" [attr.aria-label]=\"('@conversation:mini-chat.new-chat' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-plus\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (view() !== 'history') {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"openHistory()\" [attr.aria-label]=\"('@conversation:mini-chat.history-title' | translate | async) ?? ''\">\n <ax-prefix><ax-icon icon=\"fa-light fa-clock-rotate-left\"></ax-icon></ax-prefix>\n </ax-button>\n }\n @if (canMinimize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"minimizePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.minimize' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"minimize\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canMaximize()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"toggleMaximizePanel()\" [attr.aria-label]=\"((isMaximized() ? '@conversation:mini-chat.restore' : '@conversation:mini-chat.maximize') | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon [name]=\"isMaximized() ? 'restore' : 'maximize'\" />\n </ax-prefix>\n </ax-button>\n }\n @if (canClose()) {\n <ax-button class=\"ax-sm\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"closePanel()\" [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\">\n <ax-prefix>\n <ax-popup-caption-icon name=\"close\" />\n </ax-prefix>\n </ax-button>\n }\n </div>\n </div>\n\n @if (launchContext()) {\n @if (showContextBar()) {\n <!-- ----- Current list or record the assist is working in ----- -->\n <div class=\"axm-mini-chat-panel__context shrink-0\">\n <i class=\"axm-mini-chat-panel__context-icon fa-light {{ contextBarIcon() }}\" aria-hidden=\"true\"></i>\n <span class=\"truncate\">\n <!---->\n <!-- ----- Record-scoped assist (entity row or details) ----- -->\n @if (isRecordAssist()) {\n @let recordTitle = recordTitleLabel();\n @let entityTitle = recordEntityTitle();\n @let entityLabel = entityTitle ? ((entityTitle | translate | async) ?? entityTitle) : '';\n @if (recordTitle) {\n {{ recordTitle }}\n @if (entityLabel) {\n \u00B7 {{ entityLabel }}\n }\n } @else if (entityLabel) {\n {{ entityLabel }}\n }\n }\n <!-- ----- List page: Working in Entity | View ----- -->\n @else if (workingInEntityTitle(); as entityTitle) {\n @let entityLabel = (entityTitle | translate | async) ?? entityTitle;\n @let viewTitle = workingInViewTitle();\n @let viewLabel = viewTitle ? ((viewTitle | translate | async) ?? viewTitle) : '';\n @let place = viewLabel ? entityLabel + ' | ' + viewLabel : entityLabel;\n {{ '@conversation:mini-chat.working-in' | translate: { params: { place } } | async }}\n }\n </span>\n </div>\n }\n }\n <!-- ----- Page chips when the header chat is not opened from another surface ----- -->\n @else if (view() !== 'history' && pageContextChips.chips().length > 0) {\n <!-- ----- Entity, view, and selected records for this chat ----- -->\n <div class=\"axm-mini-chat-panel__context axm-mini-chat-panel__context--chips shrink-0\">\n @for (chip of pageContextChips.chips(); track chip.id) {\n <ax-chips class=\"ax-sm\" look=\"outline\" color=\"primary\" [text]=\"chip.label\">\n <ax-prefix>\n <ax-icon [icon]=\"chipIcon(chip.kind)\"></ax-icon>\n </ax-prefix>\n <!--------------------------------------------------------------->\n <!-- ----- Remove this chip until the next page or selection change ----- -->\n @if (!pageContextChips.locked()) {\n <ax-suffix>\n <button\n type=\"button\"\n class=\"axm-mini-chat-panel__chip-close\"\n (click)=\"dismissPageContextChip(chip.id, $event)\"\n [attr.aria-label]=\"('@conversation:mini-chat.close' | translate | async) ?? ''\"\n >\n <ax-icon icon=\"fa-light fa-xmark\"></ax-icon>\n </button>\n </ax-suffix>\n }\n </ax-chips>\n }\n </div>\n }\n\n @if (view() === 'history') {\n <div class=\"axm-mini-chat-panel__history relative flex min-h-0 flex-1 flex-col\">\n @if (historyScope(); as scope) {\n <!---->\n <!-- ----- One entity or one record ----- -->\n @if (scope.mode === 'entity' && scope.entityIds.length === 1) {\n <axm-mini-chat-history [entityId]=\"scope.entityIds[0]\" [entityType]=\"scope.entityType\" (conversationSelected)=\"selectChat($event)\" />\n }\n <!---->\n <!-- ----- Global, form designer, or several selected records ----- -->\n @else {\n <axm-mini-chat-inbox-history [scope]=\"scope\" (conversationSelected)=\"selectChat($event)\" />\n }\n }\n </div>\n }\n <!-- ----- Active thread ----- -->\n @else {\n <div class=\"axm-mini-chat-panel__body flex min-h-0 flex-1 flex-col\">\n <axm-mini-chat\n class=\"flex min-h-0 flex-1 flex-col\"\n [chatId]=\"selectedChatId()\"\n [entityId]=\"entityId()\"\n [entityType]=\"entityType()\"\n [assistId]=\"assistId()\"\n [assistSelection]=\"assistSelection()\"\n [launchContext]=\"launchContext()\"\n [showInfoBar]=\"showInfoBar()\"\n [showComposer]=\"showComposer()\"\n (conversationOpened)=\"onConversationOpened($event)\"\n />\n </div>\n }\n <!-- ----- File drop highlight across the whole mini-chat window ----- -->\n @if (fileDragOver()) {\n <div class=\"axm-mini-chat-panel__drop-overlay\" aria-hidden=\"true\">\n <div class=\"axm-mini-chat-panel__drop-frame\">\n <span class=\"axm-mini-chat-panel__drop-label\">\n <ax-icon icon=\"fa-light fa-paperclip\"></ax-icon>\n {{ '@conversation:mini-chat.drop-files.title' | translate | async }}\n </span>\n </div>\n </div>\n }\n</div>\n", styles: ["axm-mini-chat-panel{display:block;height:100%;background:transparent;border:none;box-shadow:none;overflow:visible}.axm-mini-chat-panel-shell{pointer-events:none;box-sizing:border-box;background:transparent!important;border:none!important;box-shadow:none!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell.ax-overlay-container,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{pointer-events:auto;background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important;border-radius:0!important;overflow:visible!important}.axm-mini-chat-panel-shell.ax-overlay-pane,.axm-mini-chat-panel-shell .ax-overlay-pane,.axm-mini-chat-panel-shell .overlay-pane{flex:0 0 auto;width:min(92vw,24.5rem)!important;height:min(36rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ))!important;max-width:calc(100vw - 1.5rem);max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--default{inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;padding-right:max(1.5rem,env(safe-area-inset-right,0px));padding-bottom:max(5.5rem,calc(1.5rem + env(safe-area-inset-bottom,0px)));padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--anchored,.axm-mini-chat-panel-shell.axm-mini-chat-panel-shell--fixed{inset:unset;width:auto;height:auto;display:block;padding:0}.axm-mini-chat-panel{position:relative;box-sizing:border-box;display:flex;height:100%;flex-direction:column;overflow:hidden;border-radius:1rem;border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface));box-shadow:0 18px 48px -12px rgba(var(--ax-sys-color-on-surface),.2),0 6px 16px -4px rgba(var(--ax-sys-color-on-surface),.08)}.axm-mini-chat-panel.axm-mini-chat-panel--drag-over{border-color:rgb(var(--ax-sys-color-primary-300))}.axm-mini-chat-panel .axm-mini-chat-panel__drop-overlay{position:absolute;inset:0;z-index:20;display:grid;padding:.875rem;pointer-events:none;background:rgba(var(--ax-sys-color-lightest-surface),.82);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.axm-mini-chat-panel .axm-mini-chat-panel__drop-frame{display:grid;place-items:center;min-height:0;padding:1.25rem;border:2px dashed rgb(var(--ax-sys-color-primary-400));border-radius:.75rem;background:rgba(var(--ax-sys-color-primary-50),.55)}.axm-mini-chat-panel .axm-mini-chat-panel__drop-label{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;max-width:min(100%,16rem);padding:.625rem .875rem;border-radius:999px;background:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-primary-800));box-shadow:0 10px 28px -8px rgba(var(--ax-sys-color-on-surface),.28),0 0 0 1px rgba(var(--ax-sys-color-primary-200),.9);font-size:.875rem;font-weight:600;line-height:1.3;text-align:center}.axm-mini-chat-panel .axm-mini-chat-panel__drop-label ax-icon{flex:0 0 auto;color:rgb(var(--ax-sys-color-primary-600))}.axm-mini-chat-panel.axm-mini-chat-panel--embedded{border-radius:.75rem;height:100%;min-height:22rem;box-shadow:none}.axm-mini-chat-panel .axm-mini-chat-panel__header{min-height:3rem;padding:.625rem .75rem .5rem .875rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__brand--draggable{cursor:grab;-webkit-user-select:none;user-select:none;min-width:0;flex:1 1 auto}.axm-mini-chat-panel .axm-mini-chat-panel__brand-mark{display:grid;place-items:center;width:1.75rem;height:1.75rem;border-radius:.5rem;color:rgb(var(--ax-sys-color-primary-600));background:linear-gradient(145deg,rgba(var(--ax-sys-color-primary-500),.16),rgba(var(--ax-sys-color-primary-500),.05));border:1px solid rgba(var(--ax-sys-color-primary-500),.18);font-size:.8125rem}.axm-mini-chat-panel .axm-mini-chat-panel__brand-title{font-size:.875rem;font-weight:650;line-height:1.25;color:rgb(var(--ax-sys-color-on-surface))}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button{opacity:.7;transition:opacity .16s ease}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-popup-caption-icon{display:block;width:.75rem;height:.75rem}.axm-mini-chat-panel .axm-mini-chat-panel__header ax-button:hover{opacity:1}.axm-mini-chat-panel .axm-mini-chat-panel__context{display:flex;align-items:center;gap:.5rem;min-height:2rem;padding:.375rem .875rem;font-size:.75rem;font-weight:500;color:rgb(var(--ax-sys-color-primary-700));background:rgba(var(--ax-sys-color-primary-500),.08);border-bottom:1px solid rgba(var(--ax-sys-color-primary-500),.1)}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips{flex-wrap:nowrap;overflow:auto}.axm-mini-chat-panel .axm-mini-chat-panel__context--chips ax-chips{flex-shrink:0}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close{display:inline-flex;align-items:center;justify-content:center;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;line-height:1}.axm-mini-chat-panel .axm-mini-chat-panel__chip-close ax-icon{font-size:.6875rem}.axm-mini-chat-panel .axm-mini-chat-panel__context-icon{font-size:.8125rem;opacity:.85;flex-shrink:0}@media(max-width:600px){.axm-mini-chat-panel-shell{pointer-events:auto;position:fixed;box-sizing:border-box;display:flex;flex-direction:column;inset:0!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;padding:0!important}.axm-mini-chat-panel-shell .ax-overlay-pane{pointer-events:auto;position:relative;--tw-border-style: none;border-style:none;inset:unset!important;left:unset!important;top:unset!important;right:unset!important;bottom:unset!important;transform:none!important;width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;flex:1 1 auto!important;background:transparent!important;box-shadow:none!important;padding:0!important;border-radius:0!important}.axm-mini-chat-panel-shell .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
8272
+ }], propDecorators: { scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }], presentation: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentation", required: false }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: false }] }], entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], assistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistId", required: false }] }], assistSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "assistSelection", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showInfoBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInfoBar", required: false }] }], showComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "showComposer", required: false }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: true }] }], requestMinimize: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestMinimize", required: false }] }], requestMaximize: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestMaximize", required: false }] }], requestRestore: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestRestore", required: false }] }], isMaximized: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMaximized", required: false }] }], initialView: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialView", required: false }] }], initialConversationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialConversationId", required: false }] }], startWithNewChat: [{ type: i0.Input, args: [{ isSignal: true, alias: "startWithNewChat", required: false }] }], launchContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "launchContext", required: false }] }], onSessionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onSessionChange", required: false }] }] } });
7371
8273
 
7372
8274
  //#region ----- Imports -----
7373
8275
  //#endregion
@@ -7383,16 +8285,24 @@ class AXMMiniChatPopupWindowComponent extends AXPopupComponentBase {
7383
8285
  super();
7384
8286
  //#region ----- Services & Dependencies -----
7385
8287
  this.destroyRef = inject(DestroyRef);
8288
+ this.hostElement = inject((ElementRef));
7386
8289
  //#endregion
7387
8290
  //#region ----- Popup Data -----
7388
8291
  this.scope = 'entity';
8292
+ this.assistSelection = 'optional';
7389
8293
  this.showInfoBar = false;
7390
8294
  this.showComposer = true;
8295
+ this.minimizable = true;
8296
+ this.retainOnClose = false;
7391
8297
  this.initialView = 'thread';
7392
8298
  this.startWithNewChat = false;
7393
8299
  //#endregion
7394
8300
  //#region ----- Window API -----
7395
8301
  this.closeFn = () => {
8302
+ if (this.retainOnClose) {
8303
+ this.hideRetained();
8304
+ return;
8305
+ }
7396
8306
  this.close();
7397
8307
  };
7398
8308
  this.minimizeFn = () => {
@@ -7409,8 +8319,11 @@ class AXMMiniChatPopupWindowComponent extends AXPopupComponentBase {
7409
8319
  restore: () => this.restore(),
7410
8320
  minimize: () => this.minimize(),
7411
8321
  maximize: () => this.maximize(),
8322
+ hide: () => this.hideRetained(),
8323
+ show: () => this.showRetained(),
7412
8324
  isMinimized: () => this.isMinimized(),
7413
8325
  isMaximized: () => this.isMaximized(),
8326
+ isHidden: () => this.overlayElement()?.classList.contains('ax-popup-overlay-hidden') ?? false,
7414
8327
  };
7415
8328
  afterNextRender(() => {
7416
8329
  this.registerWindow?.(this.windowApi);
@@ -7419,14 +8332,51 @@ class AXMMiniChatPopupWindowComponent extends AXPopupComponentBase {
7419
8332
  this.registerWindow?.(null);
7420
8333
  });
7421
8334
  }
8335
+ /**
8336
+ * Escape uses the popup close path. A retained window stays mounted and only hides.
8337
+ */
8338
+ onClosing(event) {
8339
+ if (!this.retainOnClose) {
8340
+ return;
8341
+ }
8342
+ event.cancel = true;
8343
+ this.hideRetained();
8344
+ }
8345
+ //#endregion
8346
+ //#region ----- Retain -----
8347
+ hideRetained() {
8348
+ if (this.isMaximized()) {
8349
+ this.restore();
8350
+ }
8351
+ const overlay = this.overlayElement();
8352
+ if (!overlay) {
8353
+ return;
8354
+ }
8355
+ overlay.classList.add('ax-popup-overlay-hidden');
8356
+ overlay.setAttribute('aria-hidden', 'true');
8357
+ this.onVisibilityChange?.(false);
8358
+ }
8359
+ showRetained() {
8360
+ const overlay = this.overlayElement();
8361
+ if (!overlay) {
8362
+ return;
8363
+ }
8364
+ overlay.classList.remove('ax-popup-overlay-hidden');
8365
+ overlay.removeAttribute('aria-hidden');
8366
+ this.onVisibilityChange?.(true);
8367
+ }
8368
+ overlayElement() {
8369
+ const overlay = this.hostElement.nativeElement.closest('.ax-overlay-container');
8370
+ return overlay instanceof HTMLElement ? overlay : null;
8371
+ }
7422
8372
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatPopupWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7423
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXMMiniChatPopupWindowComponent, isStandalone: true, selector: "axm-mini-chat-popup-window", host: { classAttribute: "axm-mini-chat-popup-window block h-full" }, usesInheritance: true, ngImport: i0, template: "<axm-mini-chat-panel\n class=\"block h-full min-h-0\"\n [scope]=\"scope\"\n [entityId]=\"entityId\"\n [entityType]=\"entityType\"\n [assistId]=\"assistId\"\n [title]=\"panelTitle\"\n [showInfoBar]=\"showInfoBar\"\n [showComposer]=\"showComposer\"\n [presentation]=\"'overlay'\"\n [initialView]=\"initialView\"\n [initialConversationId]=\"initialConversationId\"\n [startWithNewChat]=\"startWithNewChat\"\n [launchContext]=\"launchContext\"\n [onSessionChange]=\"onSessionChange\"\n [requestClose]=\"closeFn\"\n [requestMinimize]=\"minimizeFn\"\n [requestMaximize]=\"maximizeFn\"\n [requestRestore]=\"restoreFn\"\n [isMaximized]=\"isMaximized()\"\n/>\n", styles: ["axm-mini-chat-popup-window{display:block;height:100%;min-height:0}.axm-mini-chat-popup .ax-popup-wrapper,.axm-mini-chat-popup ax-popup.ax-popup-host,.axm-mini-chat-popup .ax-popup,.axm-mini-chat-popup .ax-popup-content,.axm-mini-chat-popup .ax-popup-body,.axm-mini-chat-popup .ax-popup-main-container,.axm-mini-chat-popup .ax-popup-body-container{background:transparent!important;background-image:none!important;box-shadow:none!important;border:none!important;padding:0!important;overflow:visible!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.axm-mini-chat-popup .ax-popup{height:min(42rem,calc(100dvh - 6.5rem));max-width:calc(100vw - 1.5rem);max-height:calc(100dvh - 5.5rem);border-radius:1rem}@media(max-width:600px){.axm-mini-chat-popup .ax-popup{width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;border-radius:0!important}.axm-mini-chat-popup .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXMMiniChatPanelComponent, selector: "axm-mini-chat-panel", inputs: ["scope", "presentation", "entityId", "entityType", "assistId", "title", "showInfoBar", "showComposer", "requestClose", "requestMinimize", "requestMaximize", "requestRestore", "isMaximized", "initialView", "initialConversationId", "startWithNewChat", "launchContext", "onSessionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8373
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXMMiniChatPopupWindowComponent, isStandalone: true, selector: "axm-mini-chat-popup-window", host: { classAttribute: "axm-mini-chat-popup-window block h-full" }, usesInheritance: true, ngImport: i0, template: "<axm-mini-chat-panel\n class=\"block h-full min-h-0\"\n [scope]=\"scope\"\n [entityId]=\"entityId\"\n [entityType]=\"entityType\"\n [assistId]=\"assistId\"\n [assistSelection]=\"assistSelection\"\n [title]=\"panelTitle\"\n [showInfoBar]=\"showInfoBar\"\n [showComposer]=\"showComposer\"\n [presentation]=\"'overlay'\"\n [initialView]=\"initialView\"\n [initialConversationId]=\"initialConversationId\"\n [startWithNewChat]=\"startWithNewChat\"\n [launchContext]=\"launchContext\"\n [onSessionChange]=\"onSessionChange\"\n [requestClose]=\"closeFn\"\n [requestMinimize]=\"minimizable ? minimizeFn : undefined\"\n [requestMaximize]=\"maximizeFn\"\n [requestRestore]=\"restoreFn\"\n [isMaximized]=\"isMaximized()\"\n/>\n", styles: ["axm-mini-chat-popup-window{display:block;height:100%;min-height:0}.axm-mini-chat-popup .ax-popup-wrapper,.axm-mini-chat-popup ax-popup.ax-popup-host,.axm-mini-chat-popup .ax-popup,.axm-mini-chat-popup .ax-popup-content,.axm-mini-chat-popup .ax-popup-body,.axm-mini-chat-popup .ax-popup-main-container,.axm-mini-chat-popup .ax-popup-body-container{background:transparent!important;background-image:none!important;box-shadow:none!important;border:none!important;padding:0!important;overflow:visible!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.axm-mini-chat-popup .ax-popup{height:min(42rem,calc(100dvh - 6.5rem));max-width:calc(100vw - 1.5rem);max-height:calc(100dvh - 5.5rem);border-radius:1rem}.axm-mini-chat-popup.axm-mini-chat-popup--anchored .ax-popup:not(.ax-popup-fullscreen):not(.ax-popup-minimized){height:min(42rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ));max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}@media(max-width:600px){.axm-mini-chat-popup.ax-popup-overlay .ax-overlay-content{align-items:stretch!important;justify-content:flex-start!important;padding:0!important}.axm-mini-chat-popup.ax-popup-overlay ax-popup.ax-popup-host:not(:has(.ax-popup-minimized)){width:100%!important;height:100%!important;max-width:none!important;max-height:none!important;align-self:stretch!important}.axm-mini-chat-popup.ax-popup-overlay .ax-popup-wrapper:not(.ax-popup-minimized-host){width:100%!important;height:100%!important;max-width:none!important}.axm-mini-chat-popup.ax-popup-overlay .ax-popup:not(.ax-popup-minimized):not(.ax-popup-fit){position:fixed!important;inset:0!important;width:100%!important;height:100dvh!important;max-width:none!important;max-height:none!important;min-width:100%!important;min-height:100dvh!important;margin:0!important;border-radius:0!important;translate:none!important;transform:none!important}.axm-mini-chat-popup.ax-popup-overlay .axm-mini-chat-panel:not(.axm-mini-chat-panel--embedded){height:100%;min-height:100%;border-radius:0;border:none;box-shadow:none;padding-top:env(safe-area-inset-top,0px);padding-right:env(safe-area-inset-right,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px)}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXMMiniChatPanelComponent, selector: "axm-mini-chat-panel", inputs: ["scope", "presentation", "entityId", "entityType", "assistId", "assistSelection", "title", "showInfoBar", "showComposer", "requestClose", "requestMinimize", "requestMaximize", "requestRestore", "isMaximized", "initialView", "initialConversationId", "startWithNewChat", "launchContext", "onSessionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
7424
8374
  }
7425
8375
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatPopupWindowComponent, decorators: [{
7426
8376
  type: Component,
7427
8377
  args: [{ selector: 'axm-mini-chat-popup-window', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXMMiniChatPanelComponent], host: {
7428
8378
  class: 'axm-mini-chat-popup-window block h-full',
7429
- }, template: "<axm-mini-chat-panel\n class=\"block h-full min-h-0\"\n [scope]=\"scope\"\n [entityId]=\"entityId\"\n [entityType]=\"entityType\"\n [assistId]=\"assistId\"\n [title]=\"panelTitle\"\n [showInfoBar]=\"showInfoBar\"\n [showComposer]=\"showComposer\"\n [presentation]=\"'overlay'\"\n [initialView]=\"initialView\"\n [initialConversationId]=\"initialConversationId\"\n [startWithNewChat]=\"startWithNewChat\"\n [launchContext]=\"launchContext\"\n [onSessionChange]=\"onSessionChange\"\n [requestClose]=\"closeFn\"\n [requestMinimize]=\"minimizeFn\"\n [requestMaximize]=\"maximizeFn\"\n [requestRestore]=\"restoreFn\"\n [isMaximized]=\"isMaximized()\"\n/>\n", styles: ["axm-mini-chat-popup-window{display:block;height:100%;min-height:0}.axm-mini-chat-popup .ax-popup-wrapper,.axm-mini-chat-popup ax-popup.ax-popup-host,.axm-mini-chat-popup .ax-popup,.axm-mini-chat-popup .ax-popup-content,.axm-mini-chat-popup .ax-popup-body,.axm-mini-chat-popup .ax-popup-main-container,.axm-mini-chat-popup .ax-popup-body-container{background:transparent!important;background-image:none!important;box-shadow:none!important;border:none!important;padding:0!important;overflow:visible!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.axm-mini-chat-popup .ax-popup{height:min(42rem,calc(100dvh - 6.5rem));max-width:calc(100vw - 1.5rem);max-height:calc(100dvh - 5.5rem);border-radius:1rem}@media(max-width:600px){.axm-mini-chat-popup .ax-popup{width:100%!important;height:100%!important;max-width:100%!important;max-height:100%!important;min-height:100dvh;border-radius:0!important}.axm-mini-chat-popup .axm-mini-chat-panel{height:100%;min-height:100dvh;border-radius:0;border:none;box-shadow:none}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
8379
+ }, template: "<axm-mini-chat-panel\n class=\"block h-full min-h-0\"\n [scope]=\"scope\"\n [entityId]=\"entityId\"\n [entityType]=\"entityType\"\n [assistId]=\"assistId\"\n [assistSelection]=\"assistSelection\"\n [title]=\"panelTitle\"\n [showInfoBar]=\"showInfoBar\"\n [showComposer]=\"showComposer\"\n [presentation]=\"'overlay'\"\n [initialView]=\"initialView\"\n [initialConversationId]=\"initialConversationId\"\n [startWithNewChat]=\"startWithNewChat\"\n [launchContext]=\"launchContext\"\n [onSessionChange]=\"onSessionChange\"\n [requestClose]=\"closeFn\"\n [requestMinimize]=\"minimizable ? minimizeFn : undefined\"\n [requestMaximize]=\"maximizeFn\"\n [requestRestore]=\"restoreFn\"\n [isMaximized]=\"isMaximized()\"\n/>\n", styles: ["axm-mini-chat-popup-window{display:block;height:100%;min-height:0}.axm-mini-chat-popup .ax-popup-wrapper,.axm-mini-chat-popup ax-popup.ax-popup-host,.axm-mini-chat-popup .ax-popup,.axm-mini-chat-popup .ax-popup-content,.axm-mini-chat-popup .ax-popup-body,.axm-mini-chat-popup .ax-popup-main-container,.axm-mini-chat-popup .ax-popup-body-container{background:transparent!important;background-image:none!important;box-shadow:none!important;border:none!important;padding:0!important;overflow:visible!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.axm-mini-chat-popup .ax-popup{height:min(42rem,calc(100dvh - 6.5rem));max-width:calc(100vw - 1.5rem);max-height:calc(100dvh - 5.5rem);border-radius:1rem}.axm-mini-chat-popup.axm-mini-chat-popup--anchored .ax-popup:not(.ax-popup-fullscreen):not(.ax-popup-minimized){height:min(42rem,var(--axm-mini-chat-available-height, calc(100dvh - 6.5rem) ));max-height:var(--axm-mini-chat-available-height, calc(100dvh - 5.5rem) )}@media(max-width:600px){.axm-mini-chat-popup.ax-popup-overlay .ax-overlay-content{align-items:stretch!important;justify-content:flex-start!important;padding:0!important}.axm-mini-chat-popup.ax-popup-overlay ax-popup.ax-popup-host:not(:has(.ax-popup-minimized)){width:100%!important;height:100%!important;max-width:none!important;max-height:none!important;align-self:stretch!important}.axm-mini-chat-popup.ax-popup-overlay .ax-popup-wrapper:not(.ax-popup-minimized-host){width:100%!important;height:100%!important;max-width:none!important}.axm-mini-chat-popup.ax-popup-overlay .ax-popup:not(.ax-popup-minimized):not(.ax-popup-fit){position:fixed!important;inset:0!important;width:100%!important;height:100dvh!important;max-width:none!important;max-height:none!important;min-width:100%!important;min-height:100dvh!important;margin:0!important;border-radius:0!important;translate:none!important;transform:none!important}.axm-mini-chat-popup.ax-popup-overlay .axm-mini-chat-panel:not(.axm-mini-chat-panel--embedded){height:100%;min-height:100%;border-radius:0;border:none;box-shadow:none;padding-top:env(safe-area-inset-top,0px);padding-right:env(safe-area-inset-right,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px)}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
7430
8380
  }], ctorParameters: () => [] });
7431
8381
 
7432
8382
  //#region ---- Imports ----
@@ -7435,38 +8385,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7435
8385
  /**
7436
8386
  * Opens the shared mini chat window via {@link AXPopupService} (header inbox, entity FAB, contextual assist).
7437
8387
  * Uses the module {@link AXConversationService} so assist SSE patches stream live.
7438
- * Stays mounted across route changes; minimize hides the overlay and docks a tab in the footer.
8388
+ * Stays mounted across route changes and returns to that page's home thread.
8389
+ * Minimize hides the overlay and docks a tab in the footer.
7439
8390
  * Restores the last conversation per session on reopen; use {@link forceNewChat} for an explicit new thread.
7440
8391
  */
7441
8392
  class AXMMiniChatPanelService {
8393
+ //#endregion
8394
+ //#region ---- Lifecycle ----
7442
8395
  constructor() {
7443
8396
  //#region ---- Services & Dependencies ----
7444
8397
  this.popupService = inject(AXPopupService);
8398
+ this.settingsService = inject(AXPSettingsService);
8399
+ this.document = inject(DOCUMENT);
7445
8400
  this.translation = inject(AXTranslationService);
7446
8401
  this.conversationService = inject(AXConversationService);
7447
8402
  this.conversationApi = inject(AXMChatConversationApi);
7448
8403
  this.focusService = inject(AXMConversationFocusService);
8404
+ this.router = inject(Router);
8405
+ this.routeHome = inject(AXMMiniChatRouteHomeBus);
7449
8406
  //#endregion
7450
8407
  //#region ---- Private Properties ----
7451
8408
  this.windowApi = null;
7452
8409
  this.closePromise = null;
7453
8410
  this.windowGeneration = 0;
8411
+ this.anchorPlacementCleanup = null;
7454
8412
  /** Per-entity session (view, selected conversation) restored when the panel reopens. */
7455
8413
  this.sessions = new Map();
7456
- /** Reactive open state for launcher UI (true while the window exists, including minimized). */
8414
+ this.retainOnClose = false;
8415
+ this.retainedHidden = false;
8416
+ this.retainedSessionKey = null;
8417
+ this.activeOpenOptions = null;
8418
+ this.boundRouteKey = '';
8419
+ this.activePageKey = '';
8420
+ this.retargeting = false;
8421
+ this.popupFrameReady = null;
8422
+ /** Reactive open state for launcher UI (true while the window exists, including minimized or hidden). */
7457
8423
  this.panelOpen = signal(false, /* @ts-ignore */
7458
8424
  ...(ngDevMode ? [{ debugName: "panelOpen" }] : /* istanbul ignore next */ []));
8425
+ this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
8426
+ this.onNavigation();
8427
+ });
7459
8428
  }
7460
8429
  //#endregion
7461
8430
  //#region ---- Public Methods ----
7462
- /** True while the mini chat window is mounted (visible or minimized). */
8431
+ /** True while the mini chat window is mounted (visible, minimized, or retained-hidden). */
7463
8432
  isOpen() {
7464
8433
  return this.panelOpen();
7465
8434
  }
8435
+ /** True while the window is on screen. */
8436
+ isVisible() {
8437
+ return this.panelOpen() && !this.retainedHidden;
8438
+ }
7466
8439
  /** Closes the window when it is open. */
7467
8440
  close() {
8441
+ this.retainOnClose = false;
8442
+ this.retainedHidden = false;
8443
+ this.retainedSessionKey = null;
7468
8444
  this.windowApi?.close();
7469
8445
  }
8446
+ /** Hides a retained window. Destroys the window when retention is off. */
8447
+ dismiss() {
8448
+ if (this.retainOnClose && this.windowApi) {
8449
+ this.windowApi.hide();
8450
+ return;
8451
+ }
8452
+ this.close();
8453
+ }
7470
8454
  /** Toggles the inbox mini chat window (regular non-entity conversations). */
7471
8455
  toggleInbox(options = {}) {
7472
8456
  this.toggle({ ...options, scope: 'inbox' });
@@ -7479,7 +8463,7 @@ class AXMMiniChatPanelService {
7479
8463
  this.windowApi.restore();
7480
8464
  return;
7481
8465
  }
7482
- if (this.isOpen()) {
8466
+ if (this.isVisible()) {
7483
8467
  this.close();
7484
8468
  return;
7485
8469
  }
@@ -7490,14 +8474,27 @@ class AXMMiniChatPanelService {
7490
8474
  * Restores the last session for the entity unless {@link AXMMiniChatPanelOpenOptions.forceNewChat} is set.
7491
8475
  */
7492
8476
  async open(options) {
7493
- this.abandonOpenWindow();
7494
8477
  const scope = options.scope ?? 'entity';
8478
+ const entityKey = this.buildSessionKey(options, scope);
8479
+ if (this.retainedHidden && this.windowApi && this.retainedSessionKey === entityKey) {
8480
+ this.windowApi.show();
8481
+ return;
8482
+ }
8483
+ await this.ensurePopupFrameLoaded();
8484
+ this.abandonOpenWindow();
8485
+ this.activeOpenOptions = options;
8486
+ this.boundRouteKey = axmMiniChatPathKey(this.router.url);
8487
+ this.activePageKey = this.currentPageChatKey();
7495
8488
  const generation = this.windowGeneration;
8489
+ const retainOnClose = options.retainOnClose === true;
8490
+ this.retainOnClose = retainOnClose;
8491
+ this.retainedHidden = false;
8492
+ this.retainedSessionKey = retainOnClose ? entityKey : null;
7496
8493
  this.captureFocusedConversation();
7497
8494
  this.captureActiveConversation();
7498
- const entityKey = this.buildSessionKey(options, scope);
7499
8495
  const session = this.sessions.get(entityKey);
7500
- const restoreSession = Boolean(session?.hasOpened) && !options.forceNewChat;
8496
+ const samePage = session?.pageKey === this.activePageKey;
8497
+ const restoreSession = Boolean(session?.hasOpened) && !options.forceNewChat && samePage;
7501
8498
  const startWithNewChat = !restoreSession;
7502
8499
  const initialView = restoreSession ? session.view : 'thread';
7503
8500
  const initialConversationId = restoreSession ? session.selectedChatId : undefined;
@@ -7506,6 +8503,7 @@ class AXMMiniChatPanelService {
7506
8503
  view: state.view,
7507
8504
  selectedChatId: state.selectedChatId,
7508
8505
  hasOpened: true,
8506
+ pageKey: this.activePageKey,
7509
8507
  });
7510
8508
  };
7511
8509
  const data = {
@@ -7513,6 +8511,7 @@ class AXMMiniChatPanelService {
7513
8511
  entityId: options.entityId,
7514
8512
  entityType: options.entityType,
7515
8513
  assistId: options.assistId,
8514
+ assistSelection: options.assistSelection ?? 'optional',
7516
8515
  panelTitle: options.title,
7517
8516
  showInfoBar: options.showInfoBar ?? false,
7518
8517
  showComposer: options.showComposer ?? true,
@@ -7520,7 +8519,15 @@ class AXMMiniChatPanelService {
7520
8519
  initialConversationId,
7521
8520
  startWithNewChat,
7522
8521
  launchContext: options.launchContext ? axmSanitizeContextualAssistContext(options.launchContext) : undefined,
8522
+ minimizable: options.minimizable !== false,
8523
+ retainOnClose,
7523
8524
  onSessionChange,
8525
+ onVisibilityChange: (visible) => {
8526
+ if (!this.retainOnClose || generation !== this.windowGeneration) {
8527
+ return;
8528
+ }
8529
+ this.retainedHidden = !visible;
8530
+ },
7524
8531
  registerWindow: (api) => {
7525
8532
  this.windowApi = api;
7526
8533
  },
@@ -7539,7 +8546,7 @@ class AXMMiniChatPanelService {
7539
8546
  title,
7540
8547
  panelClass: ['axm-mini-chat-popup'],
7541
8548
  resizable: {
7542
- handles: ['top-end', 'bottom-end'],
8549
+ handles: ['top-end', 'bottom-end', 'top-start', 'bottom-start'],
7543
8550
  minWidth: 320,
7544
8551
  minHeight: 280,
7545
8552
  },
@@ -7547,7 +8554,7 @@ class AXMMiniChatPanelService {
7547
8554
  close: false,
7548
8555
  maximize: true,
7549
8556
  minimize: {
7550
- enable: true,
8557
+ enable: options.minimizable !== false,
7551
8558
  position: 'bottom-right',
7552
8559
  dock: AXM_MINI_CHAT_POPUP_DOCK,
7553
8560
  },
@@ -7556,6 +8563,7 @@ class AXMMiniChatPanelService {
7556
8563
  });
7557
8564
  this.closePromise = closed;
7558
8565
  this.panelOpen.set(true);
8566
+ this.watchAnchorPlacement(options, generation);
7559
8567
  void closed.finally(() => {
7560
8568
  if (generation !== this.windowGeneration) {
7561
8569
  return;
@@ -7597,24 +8605,166 @@ class AXMMiniChatPanelService {
7597
8605
  buildEntityKey(entityType, entityId) {
7598
8606
  return `${entityType}:${entityId}`;
7599
8607
  }
8608
+ /** List and record of the same entity are different chats. */
8609
+ currentPageChatKey() {
8610
+ const params = axmMiniChatCollectRouteParams(this.router.routerState.snapshot.root);
8611
+ const moduleName = params['module']?.trim();
8612
+ const entityName = params['entity']?.trim();
8613
+ if (!moduleName || !entityName) {
8614
+ return 'global';
8615
+ }
8616
+ const recordId = params['id']?.trim();
8617
+ return recordId ? `${moduleName}.${entityName}:${recordId}` : `${moduleName}.${entityName}:list`;
8618
+ }
7600
8619
  abandonOpenWindow() {
7601
8620
  if (!this.panelOpen() && !this.windowApi) {
7602
8621
  return;
7603
8622
  }
7604
8623
  this.windowGeneration += 1;
8624
+ this.clearAnchorPlacement();
8625
+ this.retainOnClose = false;
8626
+ this.retainedHidden = false;
8627
+ this.retainedSessionKey = null;
7605
8628
  const api = this.windowApi;
7606
8629
  this.windowApi = null;
7607
8630
  this.closePromise = null;
7608
8631
  api?.close();
7609
8632
  this.panelOpen.set(false);
7610
8633
  }
8634
+ onNavigation() {
8635
+ const options = this.activeOpenOptions;
8636
+ if (this.retargeting || !this.isOpen() || !options) {
8637
+ return;
8638
+ }
8639
+ const nextKey = axmMiniChatPathKey(this.router.url);
8640
+ if (nextKey === this.boundRouteKey) {
8641
+ return;
8642
+ }
8643
+ this.boundRouteKey = nextKey;
8644
+ this.activePageKey = this.currentPageChatKey();
8645
+ const params = axmMiniChatCollectRouteParams(this.router.routerState.snapshot.root);
8646
+ if (axmMiniChatWindowOwnsRoute(options, params)) {
8647
+ this.routeHome.requestHome();
8648
+ return;
8649
+ }
8650
+ this.retargeting = true;
8651
+ void this.open({
8652
+ scope: 'inbox',
8653
+ forceNewChat: true,
8654
+ assistSelection: 'ask',
8655
+ showComposer: true,
8656
+ showInfoBar: false,
8657
+ }).finally(() => {
8658
+ this.retargeting = false;
8659
+ });
8660
+ }
7611
8661
  finishWindowClose() {
8662
+ this.clearAnchorPlacement();
8663
+ this.activeOpenOptions = null;
8664
+ this.retainOnClose = false;
8665
+ this.retainedHidden = false;
8666
+ this.retainedSessionKey = null;
7612
8667
  if (this.savedActiveConversationId !== undefined) {
7613
8668
  this.restoreActiveConversation();
7614
8669
  }
7615
8670
  this.restoreFocusedConversation();
7616
8671
  this.panelOpen.set(false);
7617
8672
  }
8673
+ /** Pins the popup beside its opener, or restores the last header-drag position. */
8674
+ watchAnchorPlacement(options, generation) {
8675
+ const hasAnchor = Boolean(resolveMiniChatAnchorElement(options.anchor));
8676
+ if (!hasAnchor && !readMiniChatPopupPosition()) {
8677
+ return;
8678
+ }
8679
+ this.clearAnchorPlacement();
8680
+ const view = this.document.defaultView;
8681
+ if (!view) {
8682
+ return;
8683
+ }
8684
+ let frames = 0;
8685
+ const place = (allowDragged) => {
8686
+ if (generation !== this.windowGeneration) {
8687
+ return true;
8688
+ }
8689
+ if (!allowDragged && miniChatPopupWasDragged(this.document)) {
8690
+ return true;
8691
+ }
8692
+ const saved = readMiniChatPopupPosition();
8693
+ if (saved?.x != null && saved.y != null) {
8694
+ return placeMiniChatPopupAtPoint(this.document, saved);
8695
+ }
8696
+ if (!hasAnchor) {
8697
+ return true;
8698
+ }
8699
+ return placeMiniChatPopupBesideAnchor(this.document, options);
8700
+ };
8701
+ const tick = () => {
8702
+ if (generation !== this.windowGeneration) {
8703
+ return;
8704
+ }
8705
+ const settled = place(true);
8706
+ if (!settled && frames < 30) {
8707
+ frames += 1;
8708
+ view.requestAnimationFrame(tick);
8709
+ }
8710
+ };
8711
+ const onResize = () => {
8712
+ place(false);
8713
+ };
8714
+ const onPointerUp = () => {
8715
+ const frame = captureMiniChatPopupPosition(this.document);
8716
+ if (frame) {
8717
+ void this.persistPopupFrame(frame);
8718
+ }
8719
+ };
8720
+ view.addEventListener('resize', onResize);
8721
+ view.addEventListener('pointerup', onPointerUp, true);
8722
+ this.anchorPlacementCleanup = () => {
8723
+ view.removeEventListener('resize', onResize);
8724
+ view.removeEventListener('pointerup', onPointerUp, true);
8725
+ };
8726
+ view.requestAnimationFrame(tick);
8727
+ }
8728
+ ensurePopupFrameLoaded() {
8729
+ this.popupFrameReady ??= this.loadPopupFrame();
8730
+ return this.popupFrameReady;
8731
+ }
8732
+ async loadPopupFrame() {
8733
+ try {
8734
+ const userSettings = this.settingsService.scope(AXPPlatformScope.User);
8735
+ const [position, size] = await Promise.all([userSettings.get(AXMMiniChatSettings.Position), userSettings.get(AXMMiniChatSettings.Size)]);
8736
+ const seeded = seedMiniChatPopupFrame(position, size);
8737
+ if (seeded.migratedFromLocalStorage && seeded.frame && (await this.persistPopupFrame(seeded.frame))) {
8738
+ clearLegacyMiniChatPopupFrame();
8739
+ }
8740
+ }
8741
+ catch {
8742
+ this.popupFrameReady = null;
8743
+ }
8744
+ }
8745
+ async persistPopupFrame(frame) {
8746
+ const values = {};
8747
+ if (frame.x != null && frame.y != null) {
8748
+ values[AXMMiniChatSettings.Position] = { x: frame.x, y: frame.y };
8749
+ }
8750
+ if (frame.width != null && frame.height != null) {
8751
+ values[AXMMiniChatSettings.Size] = { width: frame.width, height: frame.height };
8752
+ }
8753
+ if (Object.keys(values).length === 0) {
8754
+ return false;
8755
+ }
8756
+ try {
8757
+ await this.settingsService.scope(AXPPlatformScope.User).set(values);
8758
+ return Object.keys(values).some((key) => this.settingsService.peekCached(key) !== undefined);
8759
+ }
8760
+ catch {
8761
+ return false;
8762
+ }
8763
+ }
8764
+ clearAnchorPlacement() {
8765
+ this.anchorPlacementCleanup?.();
8766
+ this.anchorPlacementCleanup = null;
8767
+ }
7618
8768
  captureActiveConversation() {
7619
8769
  this.savedActiveConversationId = this.conversationService.activeConversationId();
7620
8770
  }
@@ -7644,7 +8794,7 @@ class AXMMiniChatPanelService {
7644
8794
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMMiniChatPanelService, decorators: [{
7645
8795
  type: Injectable,
7646
8796
  args: [{ providedIn: 'root' }]
7647
- }] });
8797
+ }], ctorParameters: () => [] });
7648
8798
 
7649
8799
  //#region ----- Imports -----
7650
8800
  //#endregion
@@ -8153,7 +9303,7 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
8153
9303
  return axmIsConversationChatUrl(this.routerUrl());
8154
9304
  }
8155
9305
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8156
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMChatComponent, isStandalone: true, selector: "axm-chat", host: { listeners: { "keydown.escape": "onContainerEscape()" }, properties: { "tabindex": "\"-1\"", "class.axm-chat--announcements": "isAnnouncementChannelActive()", "class.axm-chat--composer-hidden": "hidePageComposer()" } }, usesInheritance: true, ngImport: i0, template: "<axp-page-layout #container axConversationContainer>\n <!-- ----- Desktop sidebar only; mobile uses full-screen list + back navigation ----- -->\n @if (!deviceService.isMobileDevice()) {\n <axp-layout-start-side class=\"border-e h-full\">\n <axp-layout-content class=\"flex flex-col min-h-0 max-w-80\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <div class=\"h-full flex flex-col shrink-0\">\n <ax-conversation-sidebar (conversationSelected)=\"onConversationSelected($event.id)\" class=\"group\">\n <ax-suffix>\n <div class=\"flex h-14 shrink-0 items-center justify-end overflow-hidden\">\n <axm-chat-sidebar-new-actions (conversationCreated)=\"onConversationSelected($event)\" />\n </div>\n </ax-suffix>\n </ax-conversation-sidebar>\n </div>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <!-- ----- Chat content: list on mobile when idle; conversation + back when selected ----- -->\n <axp-page-content class=\"h-full overflow-hidden p-0! flex min-h-0 flex-col\">\n @if (showChatList()) {\n <ax-conversation-sidebar (conversationSelected)=\"onConversationSelected($event.id)\" class=\"group\">\n <ax-suffix>\n <div class=\"flex h-14 shrink-0 items-center justify-end overflow-hidden\">\n <axm-chat-sidebar-new-actions class=\"group-hover:!translate-y-0 translate-y-36! transition-transform duration-200\" (conversationCreated)=\"onConversationSelected($event)\" />\n </div>\n </ax-suffix>\n </ax-conversation-sidebar>\n } @else {\n <div class=\"flex h-full min-h-0 flex-1 flex-col\">\n <ax-conversation-info-bar class=\"shadow-md cursor-pointer hover:bg-lighter transition-colors\" (infoClick)=\"onInfoBarClick()\">\n <ax-prefix>\n <!-- ----- Back to conversation list on mobile ----- -->\n @if (deviceService.isMobileDevice()) {\n <ax-button look=\"blank\" class=\"axm-chat__back\" [attr.aria-label]=\"('@conversation:chat.actions.back-to-chats' | translate | async) ?? ''\" (onClick)=\"openChatList()\">\n <ax-prefix>\n <ax-icon class=\"axm-chat__back-icon\" icon=\"fa-light fa-chevron-left\"></ax-icon>\n </ax-prefix>\n <!-- ----- Unread count from other chats ----- -->\n @if (backBadgeCount() > 0) {\n <ax-badge size=\"sm\" look=\"solid\" color=\"primary\" [text]=\"'' + backBadgeCount()\"></ax-badge>\n }\n </ax-button>\n }\n <!-- ----- Close chat on desktop ----- -->\n <!-- @else {\n <ax-button class=\"rounded-full\" look=\"blank\" (onClick)=\"onContainerEscape()\" aria-label=\"Close Chat\">\n <ax-icon icon=\"fa-light fa-xmark text-xl\"></ax-icon>\n </ax-button>\n } -->\n </ax-prefix>\n </ax-conversation-info-bar>\n <ax-conversation-message-list class=\"min-h-0 flex-1 overflow-hidden\">\n <div ax-conversation-message-list-no-active class=\"block\" style=\"width: min(95%, 50rem)\">\n <axm-chat-empty-state-host\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationSelected($event)\"\n />\n </div>\n <!-- ----- Assist starter prompts for empty chats ----- -->\n @if (!isAnnouncementChannelActive()) {\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty />\n }\n <!-- ----- Empty announcements feed ----- -->\n @else {\n <div ax-conversation-message-list-empty class=\"axm-chat-announcements-empty\">\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bullhorn\"\n title=\"@conversation:pages.feed.empty-title\"\n description=\"@conversation:pages.feed.empty-description\"\n />\n </div>\n }\n </ax-conversation-message-list>\n </div>\n }\n </axp-page-content>\n\n <!-- ----- Always project the footer so page-layout can show it; hide via host class when idle/announcements ----- -->\n <axp-page-footer class=\"block\">\n @if (!isAnnouncementChannelActive()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n </axp-page-footer>\n</axp-page-layout>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}axm-chat #axp-page-header{display:none}axm-chat #axp-page-footer-container{padding:0}axm-chat:not(.axm-chat--composer-hidden) #axp-page-footer-container{display:block!important}axm-chat.axm-chat--composer-hidden #axp-page-footer-container{display:none!important}axm-chat .date-separator{z-index:50!important}axm-chat .message-bubble:has(.axm-chat-call-log){text-align:start}axm-chat .message-bubble .axm-chat-call-log,axm-chat .message-bubble axm-chat-call-log-message-renderer{width:100%;min-width:12.5rem}axm-chat.axm-chat--announcements .date-separator,axm-chat.axm-chat--announcements .message-footer{display:none!important}axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) .message-avatar,axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) .message-sender{display:none!important}axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) ax-conversation-registry-component-outlet{display:block;max-width:100%}axm-chat .axm-chat-announcements-empty{margin-inline:auto;display:flex;width:100%;max-width:var(--container-md, 28rem);flex-direction:column;align-items:center;padding-inline:calc(var(--spacing, .25rem) * 6);padding-block:calc(var(--spacing, .25rem) * 10)}axm-chat .message-bubble-received .axm-chat-call-log:not(.axm-chat-call-log--own){--axm-call-log-callback-ring: rgb(var(--ax-sys-color-on-lightest-surface));--axm-call-log-callback-surface: rgb(var(--ax-sys-color-lightest-surface))}axm-chat .axm-chat__back{display:inline-flex;align-items:center;gap:var(--spacing, .25rem)}axm-chat .axm-chat__back-icon:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: AXConversationContainerDirective, selector: "[axConversationContainer]" }, { kind: "component", type: AXConversationSidebarComponent, selector: "ax-conversation-sidebar", outputs: ["conversationSelected"] }, { kind: "component", type: AXConversationInfoBarComponent, selector: "ax-conversation-info-bar", outputs: ["infoClick", "searchClick", "searchQuery", "menuItemAction"] }, { kind: "component", type: AXConversationMessageListComponent, selector: "ax-conversation-message-list", outputs: ["messageAction"] }, { kind: "component", type: AXConversationComposerComponent, selector: "ax-conversation-composer", outputs: ["messageSent", "generationCancelled", "emojiClick", "attachClick", "voiceClick"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXMChatSidebarNewActionsComponent, selector: "axm-chat-sidebar-new-actions", outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatEmptyStateHostComponent, selector: "axm-chat-empty-state-host", inputs: ["compact", "initialAssistId", "entityId", "entityType", "sendStarterPromptsInPlace", "launchContext", "assistConversationCreated"], outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatAssistComposerStarterPromptsComponent, selector: "axm-chat-assist-composer-starter-prompts", inputs: ["sendStarterPromptsInPlace", "compact"] }, { kind: "directive", type: AXMChatComposerEnsureAssistConversationDirective, selector: "ax-conversation-composer[axmEnsureAssistConversation]", inputs: ["axmAssistConversationCreated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
9306
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMChatComponent, isStandalone: true, selector: "axm-chat", host: { listeners: { "keydown.escape": "onContainerEscape()" }, properties: { "tabindex": "\"-1\"", "class.axm-chat--announcements": "isAnnouncementChannelActive()", "class.axm-chat--composer-hidden": "hidePageComposer()" } }, usesInheritance: true, ngImport: i0, template: "<axp-page-layout #container axConversationContainer>\n <!-- ----- Desktop sidebar only; mobile uses full-screen list + back navigation ----- -->\n @if (!deviceService.isMobileDevice()) {\n <axp-layout-start-side class=\"border-e h-full\">\n <axp-layout-content class=\"flex flex-col min-h-0 max-w-80\">\n @for (rev of appearanceSync.viewKeys(); track rev) {\n <div class=\"h-full flex flex-col shrink-0\">\n <ax-conversation-sidebar (conversationSelected)=\"onConversationSelected($event.id)\" class=\"group\">\n <ax-suffix>\n <div class=\"flex h-14 shrink-0 items-center justify-end overflow-hidden\">\n <axm-chat-sidebar-new-actions (conversationCreated)=\"onConversationSelected($event)\" />\n </div>\n </ax-suffix>\n </ax-conversation-sidebar>\n </div>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <!-- ----- Chat content: list on mobile when idle; conversation + back when selected ----- -->\n <axp-page-content class=\"h-full overflow-hidden p-0! flex min-h-0 flex-col\">\n @if (showChatList()) {\n <ax-conversation-sidebar (conversationSelected)=\"onConversationSelected($event.id)\" class=\"group\">\n <ax-suffix>\n <div class=\"flex h-14 shrink-0 items-center justify-end overflow-hidden\">\n <axm-chat-sidebar-new-actions class=\"group-hover:!translate-y-0 translate-y-36! transition-transform duration-200\" (conversationCreated)=\"onConversationSelected($event)\" />\n </div>\n </ax-suffix>\n </ax-conversation-sidebar>\n } @else {\n <div class=\"flex h-full min-h-0 flex-1 flex-col\">\n <ax-conversation-info-bar class=\"shadow-md cursor-pointer hover:bg-lighter transition-colors\" (infoClick)=\"onInfoBarClick()\">\n <ax-prefix>\n <!-- ----- Back to conversation list on mobile ----- -->\n @if (deviceService.isMobileDevice()) {\n <ax-button look=\"blank\" class=\"axm-chat__back\" [attr.aria-label]=\"('@conversation:chat.actions.back-to-chats' | translate | async) ?? ''\" (onClick)=\"openChatList()\">\n <ax-prefix>\n <ax-icon class=\"axm-chat__back-icon\" icon=\"fa-light fa-chevron-left\"></ax-icon>\n </ax-prefix>\n <!-- ----- Unread count from other chats ----- -->\n @if (backBadgeCount() > 0) {\n <ax-badge size=\"sm\" look=\"solid\" color=\"primary\" [text]=\"'' + backBadgeCount()\"></ax-badge>\n }\n </ax-button>\n }\n <!-- ----- Close chat on desktop ----- -->\n <!-- @else {\n <ax-button class=\"rounded-full\" look=\"blank\" (onClick)=\"onContainerEscape()\" aria-label=\"Close Chat\">\n <ax-icon icon=\"fa-light fa-xmark text-xl\"></ax-icon>\n </ax-button>\n } -->\n </ax-prefix>\n </ax-conversation-info-bar>\n <ax-conversation-message-list class=\"min-h-0 flex-1 overflow-hidden\">\n <div ax-conversation-message-list-no-active class=\"block\" style=\"width: min(95%, 50rem)\">\n <axm-chat-empty-state-host\n [assistConversationCreated]=\"onAssistConversationCreated\"\n (conversationCreated)=\"onConversationSelected($event)\"\n />\n </div>\n <!-- ----- Assist starter prompts for empty chats ----- -->\n @if (!isAnnouncementChannelActive()) {\n <axm-chat-assist-composer-starter-prompts ax-conversation-message-list-empty />\n }\n <!-- ----- Empty announcements feed ----- -->\n @else {\n <div ax-conversation-message-list-empty class=\"axm-chat-announcements-empty\">\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bullhorn\"\n title=\"@conversation:pages.feed.empty-title\"\n description=\"@conversation:pages.feed.empty-description\"\n />\n </div>\n }\n </ax-conversation-message-list>\n </div>\n }\n </axp-page-content>\n\n <!-- ----- Always project the footer so page-layout can show it; hide via host class when idle/announcements ----- -->\n <axp-page-footer class=\"block\">\n @if (!isAnnouncementChannelActive()) {\n <ax-conversation-composer\n axmEnsureAssistConversation\n [axmAssistConversationCreated]=\"onAssistConversationCreated\"\n (generationCancelled)=\"onComposerGenerationCancelled()\"\n />\n }\n </axp-page-footer>\n</axp-page-layout>\n", styles: ["ax-conversation-avatar .ax-conversation-avatar-status{display:none}axm-chat #axp-page-header{display:none}axm-chat #axp-page-footer-container{padding:0}axm-chat:not(.axm-chat--composer-hidden) #axp-page-footer-container{display:block!important}axm-chat.axm-chat--composer-hidden #axp-page-footer-container{display:none!important}axm-chat .date-separator{z-index:50!important}axm-chat .message-bubble:has(.axm-chat-call-log){text-align:start}axm-chat .message-bubble .axm-chat-call-log,axm-chat .message-bubble axm-chat-call-log-message-renderer{width:100%;min-width:12.5rem}axm-chat.axm-chat--announcements .date-separator,axm-chat.axm-chat--announcements .message-footer{display:none!important}axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) .message-avatar,axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) .message-sender{display:none!important}axm-chat .message-item:has(axm-bulletin-feed-item-message-renderer) ax-conversation-registry-component-outlet{display:block;max-width:100%}axm-chat .axm-chat-announcements-empty{margin-inline:auto;display:flex;width:100%;max-width:var(--container-md, 28rem);flex-direction:column;align-items:center;padding-inline:calc(var(--spacing, .25rem) * 6);padding-block:calc(var(--spacing, .25rem) * 10)}axm-chat .message-bubble-received .axm-chat-call-log:not(.axm-chat-call-log--own){--axm-call-log-callback-ring: rgb(var(--ax-sys-color-on-lightest-surface));--axm-call-log-callback-surface: rgb(var(--ax-sys-color-lightest-surface))}axm-chat .axm-chat__back{display:inline-flex;align-items:center;gap:var(--spacing, .25rem)}axm-chat .axm-chat__back-icon:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: AXConversationContainerDirective, selector: "[axConversationContainer]" }, { kind: "component", type: AXConversationSidebarComponent, selector: "ax-conversation-sidebar", outputs: ["conversationSelected"] }, { kind: "component", type: AXConversationInfoBarComponent, selector: "ax-conversation-info-bar", outputs: ["infoClick", "searchClick", "searchQuery", "menuItemAction"] }, { kind: "component", type: AXConversationMessageListComponent, selector: "ax-conversation-message-list", outputs: ["messageAction"] }, { kind: "component", type: AXConversationComposerComponent, selector: "ax-conversation-composer", outputs: ["messageSent", "generationCancelled", "emojiClick", "attachClick", "voiceClick"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXMChatSidebarNewActionsComponent, selector: "axm-chat-sidebar-new-actions", outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatEmptyStateHostComponent, selector: "axm-chat-empty-state-host", inputs: ["compact", "initialAssistId", "assistSelection", "acceptExternalFileDrop", "entityId", "entityType", "sendStarterPromptsInPlace", "launchContext", "assistConversationCreated"], outputs: ["conversationCreated"] }, { kind: "component", type: AXMChatAssistComposerStarterPromptsComponent, selector: "axm-chat-assist-composer-starter-prompts", inputs: ["sendStarterPromptsInPlace", "compact"] }, { kind: "directive", type: AXMChatComposerEnsureAssistConversationDirective, selector: "ax-conversation-composer[axmEnsureAssistConversation]", inputs: ["axmAssistConversationCreated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
8157
9307
  }
8158
9308
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMChatComponent, decorators: [{
8159
9309
  type: Component,
@@ -9020,6 +10170,11 @@ class AXMChatEntityConversationRoomQueryService {
9020
10170
  //#endregion
9021
10171
  //#region ---- Room queries ----
9022
10172
  async loadChatRooms() {
10173
+ const rooms = await this.loadAccessibleChatRooms();
10174
+ return rooms.filter((room) => axmConversationIsGlobalChat(room));
10175
+ }
10176
+ /** Every chat room the current user can open, including entity and surface mini chats. */
10177
+ async loadAccessibleChatRooms() {
9023
10178
  const currentUser = await this.userApi.getCurrentUser().catch(() => null);
9024
10179
  const currentUserId = currentUser?.id?.trim();
9025
10180
  const { items } = await this.roomData.query({
@@ -9035,9 +10190,7 @@ class AXMChatEntityConversationRoomQueryService {
9035
10190
  return [];
9036
10191
  }
9037
10192
  const canViewBulletins = this.session.authorize(AXPCollaborationPermissionKeys.ViewBulletins);
9038
- return items.filter((room) => !axmIsCommentRoom(room) &&
9039
- !axmRoomIsEntityChat(room) &&
9040
- axmCanAccessChatRoom(room, currentUserId, canViewBulletins));
10193
+ return items.filter((room) => !axmIsCommentRoom(room) && axmCanAccessChatRoom(room, currentUserId, canViewBulletins));
9041
10194
  }
9042
10195
  async enrichRoom(room, options) {
9043
10196
  const currentUserId = options?.currentUserId ?? (await this.userApi.getCurrentUser().catch(() => null))?.id;
@@ -9368,27 +10521,25 @@ class AXMChatEntityConversationApi extends AXMChatConversationApi {
9368
10521
  //#endregion
9369
10522
  //#region ---- Entity-scoped conversations ----
9370
10523
  async findEntityConversations(entityType, entityId) {
9371
- const ref = { entityType: entityType.trim(), entityId: entityId.trim() };
9372
- if (!ref.entityType || !ref.entityId) {
10524
+ const type = entityType.trim();
10525
+ const id = entityId.trim();
10526
+ if (!type || !id) {
9373
10527
  return [];
9374
10528
  }
9375
- const { items } = await this.roomData.query({
9376
- skip: 0,
9377
- take: 500,
9378
- filter: {
9379
- field: 'kind',
9380
- value: 'chat',
9381
- operator: this.filterService.getOperator('equal'),
9382
- },
9383
- });
9384
- const matched = items.filter((room) => axmRoomMatchesEntity(room, ref));
10529
+ return this.findHistoryConversations({ mode: 'entity', entityType: type, entityIds: [id] });
10530
+ }
10531
+ async findHistoryConversations(scope) {
10532
+ const rooms = await this.roomQuery.loadAccessibleChatRooms();
10533
+ const matched = rooms.filter((room) => axmConversationMatchesHistoryScope(room, scope));
9385
10534
  const currentUser = await this.userApi.getCurrentUser().catch(() => null);
9386
10535
  const currentUserId = currentUser?.id?.trim();
9387
- const enriched = await Promise.all(matched.map((r) => this.roomQuery.enrichRoom(r, {
10536
+ const enriched = await Promise.all(matched.map((room) => this.roomQuery.enrichRoom(room, {
9388
10537
  probeLastMessage: false,
9389
10538
  currentUserId,
9390
10539
  })));
9391
- const visible = currentUserId ? enriched.filter((conversation) => axmIsConversationParticipant(conversation.participants, currentUserId)) : [];
10540
+ const visible = currentUserId
10541
+ ? enriched.filter((conversation) => axmIsConversationParticipant(conversation.participants, currentUserId))
10542
+ : [];
9392
10543
  return axmSortConversationsByPinAndRecency(visible);
9393
10544
  }
9394
10545
  //#endregion
@@ -10181,10 +11332,10 @@ class AXMChatEntityRealtimeApi extends AXMChatRealtimeApi {
10181
11332
  //#endregion
10182
11333
  //#region ---- Conversation streams ----
10183
11334
  subscribeToConversationUpdates() {
10184
- return this.bus.conversationUpdates$.pipe(filter((conversation) => !axmRoomIsEntityChat(conversation)));
11335
+ return this.bus.conversationUpdates$.pipe(filter((conversation) => axmConversationIsGlobalChat(conversation)));
10185
11336
  }
10186
11337
  subscribeToConversationCreated() {
10187
- return this.bus.conversationCreated$.pipe(filter((conversation) => !axmRoomIsEntityChat(conversation)));
11338
+ return this.bus.conversationCreated$.pipe(filter((conversation) => axmConversationIsGlobalChat(conversation)));
10188
11339
  }
10189
11340
  subscribeToConversationDeleted() {
10190
11341
  return this.bus.conversationDeleted$;
@@ -10242,11 +11393,11 @@ function axmIsAssistBotConversation(conversation) {
10242
11393
  }
10243
11394
  return false;
10244
11395
  }
10245
- /** Inbox (`/chat/`) must not list entity-record mini chats. */
11396
+ /** Inbox (`/chat/`) lists only global chats: no entity, record, or surface such as form designer. */
10246
11397
  function axmExcludeEntityChatConversations(conversations) {
10247
- return conversations.filter((conversation) => !axmRoomIsEntityChat(conversation));
11398
+ return conversations.filter((conversation) => axmConversationIsGlobalChat(conversation));
10248
11399
  }
10249
- /** Wraps a sidebar tab so entity-scoped chats stay off the main chat list. */
11400
+ /** Wraps a sidebar tab so only global chats stay on the main chat list. */
10250
11401
  function axmInboxConversationTab(tab) {
10251
11402
  return {
10252
11403
  ...tab,
@@ -12052,6 +13203,7 @@ class AXMMiniChatHeaderSlotComponent {
12052
13203
  onToggleClick() {
12053
13204
  const anchor = this.chatButtonRef()?.nativeElement;
12054
13205
  this.panelService.toggleInbox({
13206
+ assistSelection: 'ask',
12055
13207
  ...(anchor
12056
13208
  ? {
12057
13209
  anchor,
@@ -13133,7 +14285,7 @@ async function axmOpenChatCallStartDialog(options) {
13133
14285
  }
13134
14286
  // Capture DI before any await (dynamic import below).
13135
14287
  const popupService = options.popupService ?? inject(AXPopupService);
13136
- const comp = (await import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-BbEhkLLh.mjs')).AXMChatCallStartPopupComponent;
14288
+ const comp = (await import('./acorex-platform-module-conversation-client-chat-call-start-popup.component-nLVRg9HK.mjs')).AXMChatCallStartPopupComponent;
13137
14289
  const data = { conversation };
13138
14290
  await popupService.open(comp, {
13139
14291
  header: false,
@@ -13412,7 +14564,7 @@ const AXM_CHAT_INFO_BAR_CALL_ACTION = {
13412
14564
  */
13413
14565
  const AXM_CONVERSATION_BOT_RENDERER = {
13414
14566
  type: 'assist-response',
13415
- componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-DyVepuaW.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
14567
+ componentLoader: () => import('./acorex-platform-module-conversation-client-assist-message-renderer.component-CUlLCsF6.mjs').then(function (n) { return n.b; }).then((m) => m.AXMAssistMessageRendererComponent),
13416
14568
  canHandle: (message) => message.type === 'assist-response' || !!message.metadata?.['isAssistResponse'],
13417
14569
  capabilities: {
13418
14570
  supportsReactions: false,
@@ -13551,7 +14703,7 @@ async function axmOpenChatCallSessionDialog(options) {
13551
14703
  }
13552
14704
  const popupService = options.popupService ?? inject(AXPopupService);
13553
14705
  const activeCallSessions = options.activeCallSessions ?? inject(AXMChatCallActiveSessionService);
13554
- const comp = (await import('./acorex-platform-module-conversation-client-chat-call-session-page.component-BeS4Duip.mjs')).AXMChatCallSessionPageComponent;
14706
+ const comp = (await import('./acorex-platform-module-conversation-client-chat-call-session-page.component-DiA01mpJ.mjs')).AXMChatCallSessionPageComponent;
13555
14707
  const scopedCallId = options.callId?.trim() || createRandomUuid();
13556
14708
  activeCallSessions.engage(scopedCallId);
13557
14709
  const data = {
@@ -15654,7 +16806,7 @@ class AXMCommentsPageComponentProvider {
15654
16806
  return [
15655
16807
  {
15656
16808
  key: COMMENTS_PAGE_COMPONENT_KEY,
15657
- loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-BxUz9jTX.mjs').then((m) => m.AXMCommentsPageComponent),
16809
+ loader: () => import('./acorex-platform-module-conversation-client-comments-page.component-C0JLE_oX.mjs').then((m) => m.AXMCommentsPageComponent),
15658
16810
  },
15659
16811
  ];
15660
16812
  }
@@ -15937,6 +17089,11 @@ class AXMConversationModule {
15937
17089
  useClass: AXMMenuProvider,
15938
17090
  multi: true,
15939
17091
  },
17092
+ {
17093
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
17094
+ useClass: AXMSettingProvider,
17095
+ multi: true,
17096
+ },
15940
17097
  {
15941
17098
  provide: AXP_SEARCH_PROVIDER,
15942
17099
  useClass: AXMChannelSearchCommandProvider,
@@ -15955,19 +17112,19 @@ class AXMConversationModule {
15955
17112
  provideCommandSetups([
15956
17113
  {
15957
17114
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
15958
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-qTWATpgC.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17115
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-Cf1zPn3u.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
15959
17116
  },
15960
17117
  {
15961
17118
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
15962
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BsYxaH3g.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17119
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-pKO5UqyB.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
15963
17120
  },
15964
17121
  {
15965
17122
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
15966
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DsCyIdEk.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17123
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BbQHG28M.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
15967
17124
  },
15968
17125
  {
15969
17126
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
15970
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-juoWxu7I.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17127
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-CIT6UHfK.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
15971
17128
  },
15972
17129
  {
15973
17130
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -15979,7 +17136,7 @@ class AXMConversationModule {
15979
17136
  },
15980
17137
  {
15981
17138
  key: CONVERSATION_OPEN_CHAT_COMMAND,
15982
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-ridcdmj7.mjs').then((m) => m.AXMConversationOpenChatCommand),
17139
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-kTWhndd2.mjs').then((m) => m.AXMConversationOpenChatCommand),
15983
17140
  },
15984
17141
  {
15985
17142
  key: 'show-comment-popup',
@@ -16075,6 +17232,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16075
17232
  useClass: AXMMenuProvider,
16076
17233
  multi: true,
16077
17234
  },
17235
+ {
17236
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
17237
+ useClass: AXMSettingProvider,
17238
+ multi: true,
17239
+ },
16078
17240
  {
16079
17241
  provide: AXP_SEARCH_PROVIDER,
16080
17242
  useClass: AXMChannelSearchCommandProvider,
@@ -16093,19 +17255,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16093
17255
  provideCommandSetups([
16094
17256
  {
16095
17257
  key: CONVERSATION_AFTER_MESSAGE_SENT_COMMAND,
16096
- command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-qTWATpgC.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
17258
+ command: () => import('./acorex-platform-module-conversation-client-after-message-sent.command-Cf1zPn3u.mjs').then((m) => m.AXMConversationAfterMessageSentCommand),
16097
17259
  },
16098
17260
  {
16099
17261
  key: CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND,
16100
- command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-BsYxaH3g.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
17262
+ command: () => import('./acorex-platform-module-conversation-client-retry-assist-response.command-pKO5UqyB.mjs').then((m) => m.AXMConversationRetryAssistResponseCommand),
16101
17263
  },
16102
17264
  {
16103
17265
  key: CONVERSATION_SYNC_READ_STATE_COMMAND,
16104
- command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-DsCyIdEk.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
17266
+ command: () => import('./acorex-platform-module-conversation-client-sync-read-state.command-BbQHG28M.mjs').then((m) => m.AXMConversationSyncReadStateCommand),
16105
17267
  },
16106
17268
  {
16107
17269
  key: CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND,
16108
- command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-juoWxu7I.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
17270
+ command: () => import('./acorex-platform-module-conversation-client-mark-conversation-unread.command-CIT6UHfK.mjs').then((m) => m.AXMConversationMarkConversationUnreadCommand),
16109
17271
  },
16110
17272
  {
16111
17273
  key: CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND,
@@ -16117,7 +17279,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16117
17279
  },
16118
17280
  {
16119
17281
  key: CONVERSATION_OPEN_CHAT_COMMAND,
16120
- command: () => import('./acorex-platform-module-conversation-client-open-chat.command-ridcdmj7.mjs').then((m) => m.AXMConversationOpenChatCommand),
17282
+ command: () => import('./acorex-platform-module-conversation-client-open-chat.command-kTWhndd2.mjs').then((m) => m.AXMConversationOpenChatCommand),
16121
17283
  },
16122
17284
  {
16123
17285
  key: 'show-comment-popup',
@@ -16152,5 +17314,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16152
17314
  * Generated bundle index. Do not edit.
16153
17315
  */
16154
17316
 
16155
- export { axmShouldForkPrivateToGroup as $, AXMConversationEntityStoreService as A, axmSanitizeAssistUserAnswerText as B, axmAssistUserVisibleItemsForLine as C, axmReadAssistFollowUpStatus as D, axmReadPlainTextMessagePayload as E, AXMNodeMessageRendererComponent as F, AXMAssistSuggestionChipsComponent as G, AXMChatCallActiveSessionService as H, axmResolveConversationListAvatar as I, axmEnsureChatCallRtcReady as J, axmOpenChatCallSessionDialog as K, axmChatCallMediaRoomName as L, axmResolveChatCallLiveKitServerUrl as M, axmChatCallRoomConnectOptions as N, loadLiveKitClient as O, AXM_CHAT_CALL_RTC_API_PROVIDERS as P, AXMConversationAppearanceSyncService as Q, axmCancelAssistComposerGeneration as R, AXMChatEmptyStateHostComponent as S, AXMChatComposerEnsureAssistConversationDirective as T, AXMChatUserApi as U, AXMChatEntityConversationApi as V, AXMChatConversationApi as W, AXMChatCallRtcSignalInboxService as X, AXMChatCallEventsService as Y, AXMConversationRealtimeBus as Z, axmReadChatCallLog as _, AXM_CONVERSATION_ASSIST_RESPONSE_PORT as a, CONVERSATION_START_ASSIST_CHAT_COMMAND as a$, axmIsConversationParticipant as a0, axmBuildChatCallLogMessage as a1, axmMatchesForkedGroupForCall as a2, axmAssistWidgetNodeFromUnknown as a3, AXMAddReactionCommand as a4, AXMChannelFeedItemComponent as a5, AXMChannelFeedPage as a6, AXMChatAnnouncementChannelService as a7, AXMChatComponent as a8, AXMChatComposerAssistPickerComponent as a9, AXMMiniChatPopupWindowComponent as aA, AXMShowCommentPopupCommand as aB, AXM_AI_MANAGEMENT_ASSIST_ENTITY_NAME as aC, AXM_ASSIST_DEFAULT_RESOLVER_PORT as aD, AXM_ASSIST_TRANSCRIPT_LINE_PAYLOAD_TYPE as aE, AXM_CHAT_ASSIST_CATALOG_PORT as aF, AXM_CHAT_EMPTY_STATE_COMPONENT as aG, AXM_CHAT_SIDEBAR_ACTION_PROVIDER as aH, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_HANDLERS as aI, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_KEY as aJ, AXM_CONVERSATION_CHAT_ATTACHMENT_CATEGORY as aK, AXM_CONVERSATION_CHAT_ATTACHMENT_REF_TYPE as aL, AXM_CONVERSATION_TAB_BOT as aM, AXM_ENTITY_LIST_CHAT_ID as aN, AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER as aO, AXM_MINI_CHAT_INBOX_SESSION_KEY as aP, AXM_MINI_CHAT_POPUP_DOCK as aQ, AXM_MINI_CHAT_SCOPE_ENTITY as aR, AXM_MINI_CHAT_SCOPE_METADATA_KEY as aS, AXPCommentWidget as aT, COMMENTS_PAGE_COMPONENT_KEY as aU, CONVERSATION_AFTER_MESSAGE_SENT_COMMAND as aV, CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND as aW, CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND as aX, CONVERSATION_OPEN_CHAT_COMMAND as aY, CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND as aZ, CONVERSATION_SEND_ASSIST_CHAT_MESSAGE_COMMAND as a_, AXMChatEmptyAssistSessionService as aa, AXMChatEntityConversationFocusHandler as ab, AXMChatEntityConversationRoomQueryService as ac, AXMChatEntityMessageApi as ad, AXMChatEntityRealtimeApi as ae, AXMChatEntityUserApi as af, AXMChatRealtimeApi as ag, AXMCommentManagementService as ah, AXMCommentPopupComponent as ai, AXMCommentRealtimeService as aj, AXMCommentRealtimeServiceImpl as ak, AXMCommentService as al, AXMCommentServiceImpl as am, AXMCommentWidgetViewComponent as an, AXMConversationAssistBackgroundOperationHandler as ao, AXMConversationModule as ap, AXMEntityChatService as aq, AXMMiniChatComponent as ar, AXMMiniChatFooterDockComponent as as, AXMMiniChatHeaderSlotComponent as at, AXMMiniChatHistoryComponent as au, AXMMiniChatInboxHistoryComponent as av, AXMMiniChatLauncherComponent as aw, AXMMiniChatPageActionComponent as ax, AXMMiniChatPanelComponent as ay, AXMMiniChatPanelService as az, AXM_CONVERSATION_REGULAR_AUTO_REPLY_PORT as b, axmSyncAssistPeerDisplayName as b$, CONVERSATION_START_DIRECT_CHAT_COMMAND as b0, CONVERSATION_SYNC_READ_STATE_COMMAND as b1, axmApplyAnswerTextToAssistPayloadLine as b2, axmAssistFollowUpItemsFromUnknown as b3, axmAssistLastTranscriptLine as b4, axmAssistNormalizeFollowUpItemForConversation as b5, axmAssistNormalizeFollowUpItemsForConversation as b6, axmAssistPersistedMessageLooksComplete as b7, axmAssistResolveFollowUpCommandName as b8, axmAssistStarterPromptChipItems as b9, axmExtractTextFromPayload as bA, axmFilterChatAiTargets as bB, axmFlattenConversationCreateMetadata as bC, axmHydrateRealtimeConversationMessage as bD, axmInboxConversationTab as bE, axmIsAssistBotConversation as bF, axmIsAssistPeerParticipant as bG, axmIsAssistResponseMessage as bH, axmIsAssistStreamingMessage as bI, axmIsAssistTerminalStatus as bJ, axmIsUnsupportedLegacyAgentAssistConversation as bK, axmLoadChatAiTargets as bL, axmMessageEntityToMessage as bM, axmNormalizeAssistTranscriptForChatUi as bN, axmNormalizeAssistTranscriptLineResponses as bO, axmPreferLocalUnreadCount as bP, axmReadReplyToUserMessageId as bQ, axmRemoveMiniChatHistoryItem as bR, axmResolveAssistFinalAnswerText as bS, axmResolveChatAiTargetText as bT, axmRoomEntityToConversation as bU, axmRoomIsEntityChat as bV, axmRoomMatchesEntity as bW, axmRoomWithAssistPeerDisplayName as bX, axmShouldPreferPersistedAssistOverLiveCache as bY, axmShowCommentPopupCommandDefinition as bZ, axmSortMessagesNewestFirst as b_, axmAssistSuggestionIconForLabel as ba, axmAssistWidgetNodeDedupeKey as bb, axmBuildAiChatConversationMetadata as bc, axmBuildAssistPeerParticipantFromCreateData as bd, axmBuildAssistPeerParticipantFromId as be, axmBuildAssistTranscriptLinePayload as bf, axmBuildAutoTitleFromUserText as bg, axmBuildEntityChatConversationMetadata as bh, axmBuildEntityChatRoomEntityRef as bi, axmChatAiPeerParticipantId as bj, axmChatAiTargetAvatarUrl as bk, axmChatAiTargetDisplayDescription as bl, axmChatAiTargetDisplayName as bm, axmChatAiTargetShortcutDescriptionKey as bn, axmCoerceDate as bo, axmCoerceTimestampMs as bp, axmComputeConversationUnreadCount as bq, axmConversationIsEntityChat as br, axmConversationMatchesEntity as bs, axmEntityRefFromLaunchContext as bt, axmExcludeEntityChatConversations as bu, axmExtractAssistIdFromMetadata as bv, axmExtractAssistSnapshotFromMetadata as bw, axmExtractDirectAgentIdFromMetadata as bx, axmExtractEntityRefFromMetadata as by, axmExtractModelEntityIdFromMetadata as bz, axmConversationHasAiChat$1 as c, axmUpsertMiniChatHistoryItem as c0, axmUserRowToParticipant as c1, channelFeedPageRoutes as c2, commentsPlugin as c3, createConversationServiceSessionAdapter as c4, persistChatAttachment as c5, AXMConversationFocusService as d, AXMConversationInAppNotificationSyncService as e, axmMessageCountsTowardUnread as f, buildConversationChatInAppCorrelationPrefix as g, AXMCommentComponent as h, axmResolveI18nLabel as i, axmSyntheticEmbedMessage as j, axmChatRenderableAssistWidgetNode as k, axmPartitionAssistAnswerText as l, axmParseAssistTranscriptTextEnvelope as m, AXMAssistChatDebugModeService as n, AXMChatMessageApi as o, AXM_AI_MANAGEMENT_MODULE_NAME as p, AXM_AI_MANAGEMENT_AGENT_ENTITY_NAME as q, axmReadAssistResponseStatus as r, axmIsAssistRetryableStatus as s, axmReadAssistResponseError as t, axmReadAssistAiTranscript as u, axmParseAssistTranscriptLinePayload as v, axmReadAssistAiTranscriptRaw as w, axmAssistUserFacingPayloadLine as x, axmIsAssistStreamingStatus as y, axmAssistHasFinalizeMetadata as z };
16156
- //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DUR2oyfP.mjs.map
17317
+ export { axmShouldForkPrivateToGroup as $, AXMConversationEntityStoreService as A, axmSanitizeAssistUserAnswerText as B, axmAssistUserVisibleItemsForLine as C, axmReadAssistFollowUpStatus as D, axmReadPlainTextMessagePayload as E, AXMNodeMessageRendererComponent as F, AXMAssistSuggestionChipsComponent as G, AXMChatCallActiveSessionService as H, axmResolveConversationListAvatar as I, axmEnsureChatCallRtcReady as J, axmOpenChatCallSessionDialog as K, axmChatCallMediaRoomName as L, axmResolveChatCallLiveKitServerUrl as M, axmChatCallRoomConnectOptions as N, loadLiveKitClient as O, AXM_CHAT_CALL_RTC_API_PROVIDERS as P, AXMConversationAppearanceSyncService as Q, axmCancelAssistComposerGeneration as R, AXMChatEmptyStateHostComponent as S, AXMChatComposerEnsureAssistConversationDirective as T, AXMChatUserApi as U, AXMChatEntityConversationApi as V, AXMChatConversationApi as W, AXMChatCallRtcSignalInboxService as X, AXMChatCallEventsService as Y, AXMConversationRealtimeBus as Z, axmReadChatCallLog as _, AXM_CONVERSATION_ASSIST_RESPONSE_PORT as a, CONVERSATION_SEND_ASSIST_CHAT_MESSAGE_COMMAND as a$, axmIsConversationParticipant as a0, axmBuildChatCallLogMessage as a1, axmMatchesForkedGroupForCall as a2, axmAssistWidgetNodeFromUnknown as a3, AXMAddReactionCommand as a4, AXMChannelFeedItemComponent as a5, AXMChannelFeedPage as a6, AXMChatAnnouncementChannelService as a7, AXMChatComponent as a8, AXMChatComposerAssistPickerComponent as a9, AXMMiniChatPanelService as aA, AXMMiniChatPopupWindowComponent as aB, AXMShowCommentPopupCommand as aC, AXM_AI_MANAGEMENT_ASSIST_ENTITY_NAME as aD, AXM_ASSIST_DEFAULT_RESOLVER_PORT as aE, AXM_ASSIST_TRANSCRIPT_LINE_PAYLOAD_TYPE as aF, AXM_CHAT_ASSIST_CATALOG_PORT as aG, AXM_CHAT_EMPTY_STATE_COMPONENT as aH, AXM_CHAT_SIDEBAR_ACTION_PROVIDER as aI, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_HANDLERS as aJ, AXM_CONVERSATION_ASSIST_BACKGROUND_OPERATION_KEY as aK, AXM_CONVERSATION_CHAT_ATTACHMENT_CATEGORY as aL, AXM_CONVERSATION_CHAT_ATTACHMENT_REF_TYPE as aM, AXM_CONVERSATION_TAB_BOT as aN, AXM_ENTITY_LIST_CHAT_ID as aO, AXM_MINI_CHAT_INBOX_CONVERSATION_FILTER as aP, AXM_MINI_CHAT_INBOX_SESSION_KEY as aQ, AXM_MINI_CHAT_POPUP_DOCK as aR, AXM_MINI_CHAT_SCOPE_ENTITY as aS, AXM_MINI_CHAT_SCOPE_METADATA_KEY as aT, AXPCommentWidget as aU, COMMENTS_PAGE_COMPONENT_KEY as aV, CONVERSATION_AFTER_MESSAGE_SENT_COMMAND as aW, CONVERSATION_EMIT_TYPING_INDICATOR_COMMAND as aX, CONVERSATION_MARK_CONVERSATION_UNREAD_COMMAND as aY, CONVERSATION_OPEN_CHAT_COMMAND as aZ, CONVERSATION_RETRY_ASSIST_RESPONSE_COMMAND as a_, AXMChatEmptyAssistSessionService as aa, AXMChatEntityConversationFocusHandler as ab, AXMChatEntityConversationRoomQueryService as ac, AXMChatEntityMessageApi as ad, AXMChatEntityRealtimeApi as ae, AXMChatEntityUserApi as af, AXMChatRealtimeApi as ag, AXMCommentManagementService as ah, AXMCommentPopupComponent as ai, AXMCommentRealtimeService as aj, AXMCommentRealtimeServiceImpl as ak, AXMCommentService as al, AXMCommentServiceImpl as am, AXMCommentWidgetViewComponent as an, AXMConversationAssistBackgroundOperationHandler as ao, AXMConversationModule as ap, AXMEntityChatService as aq, AXMMiniChatComponent as ar, AXMMiniChatFileDropService as as, AXMMiniChatFooterDockComponent as at, AXMMiniChatHeaderSlotComponent as au, AXMMiniChatHistoryComponent as av, AXMMiniChatInboxHistoryComponent as aw, AXMMiniChatLauncherComponent as ax, AXMMiniChatPageActionComponent as ay, AXMMiniChatPanelComponent as az, AXM_CONVERSATION_REGULAR_AUTO_REPLY_PORT as b, axmResolveChatAiTargetText as b$, CONVERSATION_START_ASSIST_CHAT_COMMAND as b0, CONVERSATION_START_DIRECT_CHAT_COMMAND as b1, CONVERSATION_SYNC_READ_STATE_COMMAND as b2, axmApplyAnswerTextToAssistPayloadLine as b3, axmAssistFollowUpItemsFromUnknown as b4, axmAssistLastTranscriptLine as b5, axmAssistNormalizeFollowUpItemForConversation as b6, axmAssistNormalizeFollowUpItemsForConversation as b7, axmAssistPersistedMessageLooksComplete as b8, axmAssistResolveFollowUpCommandName as b9, axmExtractAssistSnapshotFromMetadata as bA, axmExtractDirectAgentIdFromMetadata as bB, axmExtractEntityRefFromMetadata as bC, axmExtractModelEntityIdFromMetadata as bD, axmExtractTextFromPayload as bE, axmFilterChatAiTargets as bF, axmFlattenConversationCreateMetadata as bG, axmHydrateRealtimeConversationMessage as bH, axmInboxConversationTab as bI, axmIsAssistBotConversation as bJ, axmIsAssistPeerParticipant as bK, axmIsAssistResponseMessage as bL, axmIsAssistStreamingMessage as bM, axmIsAssistTerminalStatus as bN, axmIsUnsupportedLegacyAgentAssistConversation as bO, axmLoadChatAiTargets as bP, axmMessageEntityToMessage as bQ, axmMiniChatHistoryScopeFromDraft as bR, axmMiniChatHistoryScopeFromOpen as bS, axmMiniChatHistoryScopeKey as bT, axmMiniChatWindowOwnsRoute as bU, axmNormalizeAssistTranscriptForChatUi as bV, axmNormalizeAssistTranscriptLineResponses as bW, axmPreferLocalUnreadCount as bX, axmReadReplyToUserMessageId as bY, axmRemoveMiniChatHistoryItem as bZ, axmResolveAssistFinalAnswerText as b_, axmAssistStarterPromptChipItems as ba, axmAssistSuggestionIconForLabel as bb, axmAssistWidgetNodeDedupeKey as bc, axmBuildAiChatConversationMetadata as bd, axmBuildAssistPeerParticipantFromCreateData as be, axmBuildAssistPeerParticipantFromId as bf, axmBuildAssistTranscriptLinePayload as bg, axmBuildAutoTitleFromUserText as bh, axmBuildEntityChatConversationMetadata as bi, axmBuildEntityChatRoomEntityRef as bj, axmChatAiPeerParticipantId as bk, axmChatAiTargetAvatarUrl as bl, axmChatAiTargetDisplayDescription as bm, axmChatAiTargetDisplayName as bn, axmChatAiTargetShortcutDescriptionKey as bo, axmCoerceDate as bp, axmCoerceTimestampMs as bq, axmComputeConversationUnreadCount as br, axmConversationIsEntityChat as bs, axmConversationIsGlobalChat as bt, axmConversationMatchesEntity as bu, axmConversationMatchesHistoryScope as bv, axmEntityRefForMiniChatPageContext as bw, axmEntityRefFromLaunchContext as bx, axmExcludeEntityChatConversations as by, axmExtractAssistIdFromMetadata as bz, axmConversationHasAiChat$1 as c, axmRoomEntityToConversation as c0, axmRoomIsEntityChat as c1, axmRoomLaunchContext as c2, axmRoomMatchesEntity as c3, axmRoomWithAssistPeerDisplayName as c4, axmShouldPreferPersistedAssistOverLiveCache as c5, axmShowCommentPopupCommandDefinition as c6, axmSortMessagesNewestFirst as c7, axmSyncAssistPeerDisplayName as c8, axmUpsertMiniChatHistoryItem as c9, axmUserRowToParticipant as ca, channelFeedPageRoutes as cb, commentsPlugin as cc, createConversationServiceSessionAdapter as cd, persistChatAttachment as ce, AXMConversationFocusService as d, AXMConversationInAppNotificationSyncService as e, axmMessageCountsTowardUnread as f, buildConversationChatInAppCorrelationPrefix as g, AXMCommentComponent as h, axmResolveI18nLabel as i, axmSyntheticEmbedMessage as j, axmChatRenderableAssistWidgetNode as k, axmPartitionAssistAnswerText as l, axmParseAssistTranscriptTextEnvelope as m, AXMAssistChatDebugModeService as n, AXMChatMessageApi as o, AXM_AI_MANAGEMENT_MODULE_NAME as p, AXM_AI_MANAGEMENT_AGENT_ENTITY_NAME as q, axmReadAssistResponseStatus as r, axmIsAssistRetryableStatus as s, axmReadAssistResponseError as t, axmReadAssistAiTranscript as u, axmParseAssistTranscriptLinePayload as v, axmReadAssistAiTranscriptRaw as w, axmAssistUserFacingPayloadLine as x, axmIsAssistStreamingStatus as y, axmAssistHasFinalizeMetadata as z };
17318
+ //# sourceMappingURL=acorex-platform-module-conversation-client-acorex-platform-module-conversation-client-DcdPViNy.mjs.map