@memberjunction/ng-conversations 6.1.4 → 6.2.0-edge.1
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.
- package/README.md +36 -3
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +19 -3
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +39 -7
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts +74 -6
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts.map +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.js +111 -21
- package/dist/lib/components/agent/active-agent-indicator.component.js.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.d.ts +31 -5
- package/dist/lib/components/agent/agent-process-panel.component.d.ts.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.js +71 -15
- package/dist/lib/components/agent/agent-process-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +65 -9
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +169 -57
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts +77 -11
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +181 -47
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts +129 -19
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +350 -116
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts +60 -8
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +130 -46
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts +63 -3
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.js +113 -19
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts +54 -8
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +130 -46
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +70 -10
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +175 -53
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +89 -9
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +220 -70
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +89 -11
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +154 -40
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +390 -38
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +951 -367
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +213 -18
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.js +388 -44
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +12 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +26 -4
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +1090 -123
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +2407 -731
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +139 -19
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +296 -59
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +579 -78
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +2322 -823
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts +40 -4
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +72 -14
- package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.d.ts +57 -11
- package/dist/lib/components/dialogs/input-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.js +128 -16
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.d.ts +68 -10
- package/dist/lib/components/dialogs/rating-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.js +151 -27
- package/dist/lib/components/dialogs/rating-dialog.component.js.map +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts +84 -10
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +173 -49
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts +29 -3
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +58 -12
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/library/library-full-view.component.d.ts +57 -8
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/library/library-full-view.component.js +119 -35
- package/dist/lib/components/library/library-full-view.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts +76 -10
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +164 -50
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.d.ts +37 -5
- package/dist/lib/components/message/actionable-commands.component.d.ts.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.js +82 -16
- package/dist/lib/components/message/actionable-commands.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts +46 -10
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +120 -36
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +549 -74
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +1250 -421
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +411 -29
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +896 -222
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +288 -29
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +561 -123
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts +64 -5
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +101 -11
- package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -1
- package/dist/lib/components/notification/activity-indicator.component.d.ts +6 -2
- package/dist/lib/components/notification/activity-indicator.component.d.ts.map +1 -1
- package/dist/lib/components/notification/activity-indicator.component.js +13 -3
- package/dist/lib/components/notification/activity-indicator.component.js.map +1 -1
- package/dist/lib/components/notification/notification-badge.component.d.ts +15 -3
- package/dist/lib/components/notification/notification-badge.component.d.ts.map +1 -1
- package/dist/lib/components/notification/notification-badge.component.js +36 -8
- package/dist/lib/components/notification/notification-badge.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +4 -4
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts +93 -11
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +348 -87
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts +78 -8
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-selector.component.js +177 -46
- package/dist/lib/components/project/project-selector.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +3 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts +2 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.js +1 -1
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +2 -2
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +3 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +26 -8
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +2 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +4 -4
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +19 -19
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +2 -3
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js +3 -2
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +17 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.js +122 -45
- package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +47 -31
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +138 -124
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +4 -4
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +4 -4
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +3 -3
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +13 -11
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.js +29 -25
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +4 -2
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +7 -3
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- package/dist/lib/components/search/search-panel.component.d.ts +133 -22
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +312 -83
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts +69 -9
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +139 -31
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts +48 -8
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
- package/dist/lib/components/shared/user-picker.component.js +110 -30
- package/dist/lib/components/shared/user-picker.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +114 -11
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +199 -21
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts +20 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +25 -5
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/slots/slot-interfaces.d.ts +19 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -1
- package/dist/lib/components/slots/slot-interfaces.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +95 -13
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +223 -75
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/task-widget.component.d.ts +46 -6
- package/dist/lib/components/tasks/task-widget.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/task-widget.component.js +100 -16
- package/dist/lib/components/tasks/task-widget.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +64 -7
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +127 -27
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.d.ts +66 -8
- package/dist/lib/components/thread/thread-panel.component.d.ts.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +146 -36
- package/dist/lib/components/thread/thread-panel.component.js.map +1 -1
- package/dist/lib/components/toast/toast.component.d.ts +11 -1
- package/dist/lib/components/toast/toast.component.d.ts.map +1 -1
- package/dist/lib/components/toast/toast.component.js +25 -5
- package/dist/lib/components/toast/toast.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +385 -42
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +887 -291
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +8 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +8 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/directives/chat-slot.directive.d.ts +5 -1
- package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -1
- package/dist/lib/directives/chat-slot.directive.js.map +1 -1
- package/dist/lib/directives/search-shortcut.directive.d.ts +9 -1
- package/dist/lib/directives/search-shortcut.directive.d.ts.map +1 -1
- package/dist/lib/directives/search-shortcut.directive.js +14 -4
- package/dist/lib/directives/search-shortcut.directive.js.map +1 -1
- package/dist/lib/events/chat-events.d.ts +34 -7
- package/dist/lib/events/chat-events.d.ts.map +1 -1
- package/dist/lib/events/chat-events.js +37 -7
- package/dist/lib/events/chat-events.js.map +1 -1
- package/dist/lib/models/agent-turn.model.d.ts +103 -0
- package/dist/lib/models/agent-turn.model.d.ts.map +1 -0
- package/dist/lib/models/agent-turn.model.js +12 -0
- package/dist/lib/models/agent-turn.model.js.map +1 -0
- package/dist/lib/models/collection-view.model.js.map +1 -1
- package/dist/lib/models/conversation-state.model.d.ts +8 -0
- package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
- package/dist/lib/models/conversation-state.model.js.map +1 -1
- package/dist/lib/models/lazy-artifact-info.d.ts +44 -12
- package/dist/lib/models/lazy-artifact-info.d.ts.map +1 -1
- package/dist/lib/models/lazy-artifact-info.js +98 -34
- package/dist/lib/models/lazy-artifact-info.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +30 -4
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +71 -19
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +17 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +48 -16
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts +39 -0
- package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-permission.service.js +152 -17
- package/dist/lib/services/artifact-permission.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts +58 -5
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +135 -35
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +24 -0
- package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -0
- package/dist/lib/services/browser-realtime-media-host.js +95 -0
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -0
- package/dist/lib/services/collection-permission.service.d.ts +28 -0
- package/dist/lib/services/collection-permission.service.d.ts.map +1 -1
- package/dist/lib/services/collection-permission.service.js +88 -32
- package/dist/lib/services/collection-permission.service.js.map +1 -1
- package/dist/lib/services/collection-state.service.d.ts +11 -1
- package/dist/lib/services/collection-state.service.d.ts.map +1 -1
- package/dist/lib/services/collection-state.service.js +25 -5
- package/dist/lib/services/collection-state.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +26 -4
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +57 -18
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts +41 -2
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js +80 -13
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/conversation-streaming.service.d.ts +22 -0
- package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-streaming.service.js +50 -10
- package/dist/lib/services/conversation-streaming.service.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts +31 -0
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +71 -15
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/dist/lib/services/dialog.service.d.ts +13 -0
- package/dist/lib/services/dialog.service.d.ts.map +1 -1
- package/dist/lib/services/dialog.service.js +25 -5
- package/dist/lib/services/dialog.service.js.map +1 -1
- package/dist/lib/services/export.service.d.ts +2 -0
- package/dist/lib/services/export.service.d.ts.map +1 -1
- package/dist/lib/services/export.service.js +5 -1
- package/dist/lib/services/export.service.js.map +1 -1
- package/dist/lib/services/graphql-attachment-blob-store.d.ts +44 -0
- package/dist/lib/services/graphql-attachment-blob-store.d.ts.map +1 -0
- package/dist/lib/services/graphql-attachment-blob-store.js +113 -0
- package/dist/lib/services/graphql-attachment-blob-store.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +17 -141
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +15 -460
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +10 -0
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +25 -5
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/notification.service.d.ts +54 -6
- package/dist/lib/services/notification.service.d.ts.map +1 -1
- package/dist/lib/services/notification.service.js +123 -27
- package/dist/lib/services/notification.service.js.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.d.ts +4 -4
- package/dist/lib/services/realtime-audio-recorder.js +12 -12
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-pcm-wav.d.ts +4 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -1
- package/dist/lib/services/realtime-pcm-wav.js +10 -2
- package/dist/lib/services/realtime-pcm-wav.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +1 -1
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +16 -1150
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +28 -2430
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/search.service.d.ts +42 -9
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +103 -23
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/services/toast.service.d.ts +19 -1
- package/dist/lib/services/toast.service.d.ts.map +1 -1
- package/dist/lib/services/toast.service.js +45 -9
- package/dist/lib/services/toast.service.js.map +1 -1
- package/dist/lib/services/ui-command-handler.service.d.ts +16 -2
- package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
- package/dist/lib/services/ui-command-handler.service.js +36 -8
- package/dist/lib/services/ui-command-handler.service.js.map +1 -1
- package/dist/lib/utils/agent-artifact-summary.d.ts +2 -2
- package/dist/lib/utils/agent-artifact-summary.js +3 -3
- package/dist/lib/utils/agent-artifact-summary.js.map +1 -1
- package/dist/lib/utils/agent-turn-routing.d.ts +69 -0
- package/dist/lib/utils/agent-turn-routing.d.ts.map +1 -0
- package/dist/lib/utils/agent-turn-routing.js +96 -0
- package/dist/lib/utils/agent-turn-routing.js.map +1 -0
- package/dist/lib/utils/artifact-panel-action.d.ts +15 -4
- package/dist/lib/utils/artifact-panel-action.d.ts.map +1 -1
- package/dist/lib/utils/artifact-panel-action.js +10 -2
- package/dist/lib/utils/artifact-panel-action.js.map +1 -1
- package/dist/lib/utils/distinct-artifacts.d.ts +2 -0
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +5 -1
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/dist/lib/utils/plan-mode-preference.d.ts +2 -2
- package/dist/lib/utils/plan-mode-preference.js +6 -6
- package/dist/lib/utils/plan-mode-preference.js.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.d.ts +8 -79
- package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.js +8 -89
- package/dist/lib/utils/realtime-session-timeline.js.map +1 -1
- package/dist/public-api.d.ts +5 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +9 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +33 -32
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +0 -384
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +0 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +0 -231
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +0 -1
- package/dist/lib/services/delegation-result-parser.d.ts +0 -50
- package/dist/lib/services/delegation-result-parser.d.ts.map +0 -1
- package/dist/lib/services/delegation-result-parser.js +0 -60
- package/dist/lib/services/delegation-result-parser.js.map +0 -1
- package/dist/lib/services/narration-template.d.ts +0 -42
- package/dist/lib/services/narration-template.d.ts.map +0 -1
- package/dist/lib/services/narration-template.js +0 -73
- package/dist/lib/services/narration-template.js.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.d.ts +0 -13
- package/dist/lib/services/skill-picker-narrowing.d.ts.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.js +0 -13
- package/dist/lib/services/skill-picker-narrowing.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
|
|
1
|
+
import { Component, Input, Output, EventEmitter, HostListener, ViewChild } from '@angular/core';
|
|
2
2
|
import { ConversationEngine, UserInfoEngine } from '@memberjunction/core-entities';
|
|
3
3
|
import { ProjectFormModalComponent } from '../project/project-form-modal.component';
|
|
4
|
+
import { MJResourcePermissionShareAdapter } from '@memberjunction/ng-resource-permissions';
|
|
4
5
|
import { Subject } from 'rxjs';
|
|
5
6
|
import { takeUntil } from 'rxjs/operators';
|
|
6
7
|
import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
|
|
@@ -11,578 +12,724 @@ import * as i3 from "../../services/active-tasks.service";
|
|
|
11
12
|
import * as i4 from "@memberjunction/ng-ui-components";
|
|
12
13
|
import * as i5 from "@angular/common";
|
|
13
14
|
import * as i6 from "@angular/forms";
|
|
14
|
-
import * as i7 from "
|
|
15
|
-
|
|
16
|
-
const
|
|
15
|
+
import * as i7 from "@memberjunction/ng-resource-permissions";
|
|
16
|
+
import * as i8 from "../notification/notification-badge.component";
|
|
17
|
+
const _c0 = ["searchInput"];
|
|
18
|
+
const _c1 = ["contextMenuEl"];
|
|
19
|
+
const _c2 = a0 => ({ $implicit: a0 });
|
|
20
|
+
const _c3 = (a0, a1) => ({ $implicit: a0, depth: a1 });
|
|
17
21
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
18
22
|
const _forTrack1 = ($index, $item) => $item.project.ID;
|
|
19
23
|
function ConversationListComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
20
24
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
21
|
-
i0.ɵɵelementStart(0, "
|
|
22
|
-
i0.ɵɵ
|
|
25
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "button", 16);
|
|
26
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearSelection()); });
|
|
27
|
+
i0.ɵɵelement(2, "i", 17);
|
|
28
|
+
i0.ɵɵelementEnd();
|
|
29
|
+
i0.ɵɵelementStart(3, "span", 18);
|
|
30
|
+
i0.ɵɵtext(4);
|
|
31
|
+
i0.ɵɵelementEnd();
|
|
32
|
+
i0.ɵɵelementStart(5, "button", 19);
|
|
33
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.BarSetPinned()); });
|
|
34
|
+
i0.ɵɵelement(6, "i", 20);
|
|
23
35
|
i0.ɵɵelementEnd();
|
|
36
|
+
i0.ɵɵelementStart(7, "button", 21);
|
|
37
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_2_Template_button_click_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.BarOpenMoveMenu($event)); });
|
|
38
|
+
i0.ɵɵelement(8, "i", 22);
|
|
39
|
+
i0.ɵɵelementEnd();
|
|
40
|
+
i0.ɵɵelementStart(9, "button", 23);
|
|
41
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.BarShare()); });
|
|
42
|
+
i0.ɵɵelement(10, "i", 24);
|
|
43
|
+
i0.ɵɵelementEnd();
|
|
44
|
+
i0.ɵɵelementStart(11, "button", 25);
|
|
45
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.BarDelete()); });
|
|
46
|
+
i0.ɵɵelement(12, "i", 26);
|
|
47
|
+
i0.ɵɵelementEnd()();
|
|
24
48
|
} if (rf & 2) {
|
|
25
49
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
26
|
-
i0.ɵɵ
|
|
50
|
+
i0.ɵɵadvance(4);
|
|
51
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.SelectedConversationIds.size, " selected");
|
|
52
|
+
i0.ɵɵadvance();
|
|
53
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.SelectedIds))("title", ctx_r1.CanChangeAny(ctx_r1.SelectedIds) ? ctx_r1.SelectionHasUnpinned() ? "Pin" : "Unpin" : ctx_r1.ChangeRefusedReason);
|
|
54
|
+
i0.ɵɵattribute("aria-label", ctx_r1.SelectionHasUnpinned() ? "Pin" : "Unpin");
|
|
55
|
+
i0.ɵɵadvance();
|
|
56
|
+
i0.ɵɵclassProp("fa-rotate-90", !ctx_r1.SelectionHasUnpinned());
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.SelectedIds))("title", ctx_r1.CanChangeAny(ctx_r1.SelectedIds) ? "Move to folder" : ctx_r1.ChangeRefusedReason);
|
|
59
|
+
i0.ɵɵadvance(2);
|
|
60
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanShareAny(ctx_r1.SelectedIds))("title", ctx_r1.CanShareAny(ctx_r1.SelectedIds) ? "Share" : ctx_r1.ShareRefusedReason);
|
|
27
61
|
} }
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
i0.ɵɵelementStart(0, "button",
|
|
31
|
-
i0.ɵɵlistener("click", function
|
|
32
|
-
i0.ɵɵelement(1, "i",
|
|
62
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
63
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
64
|
+
i0.ɵɵelementStart(0, "button", 31);
|
|
65
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
|
|
66
|
+
i0.ɵɵelement(1, "i", 17);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
} }
|
|
69
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
70
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
71
|
+
i0.ɵɵelementStart(0, "div", 27)(1, "input", 29, 2);
|
|
72
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.SearchQuery, $event) || (ctx_r1.SearchQuery = $event); return i0.ɵɵresetView($event); });
|
|
73
|
+
i0.ɵɵlistener("keydown", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Template_input_keydown_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSearchKeydown($event)); });
|
|
74
|
+
i0.ɵɵelementEnd();
|
|
75
|
+
i0.ɵɵconditionalCreate(3, ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Conditional_3_Template, 2, 0, "button", 30);
|
|
76
|
+
i0.ɵɵelementEnd();
|
|
77
|
+
} if (rf & 2) {
|
|
78
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
79
|
+
i0.ɵɵadvance();
|
|
80
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SearchQuery);
|
|
81
|
+
i0.ɵɵadvance(2);
|
|
82
|
+
i0.ɵɵconditional(ctx_r1.IsSearching ? 3 : -1);
|
|
83
|
+
} }
|
|
84
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
85
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
86
|
+
i0.ɵɵelementStart(0, "button", 37);
|
|
87
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Conditional_9_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.OnUnpinSidebarClick($event)); });
|
|
88
|
+
i0.ɵɵelement(1, "i", 40);
|
|
33
89
|
i0.ɵɵelementStart(2, "span");
|
|
34
90
|
i0.ɵɵtext(3, "Hide Sidebar");
|
|
35
91
|
i0.ɵɵelementEnd()();
|
|
36
92
|
} }
|
|
37
|
-
function
|
|
38
|
-
const
|
|
39
|
-
i0.ɵɵelementStart(0, "div",
|
|
40
|
-
i0.ɵɵlistener("click", function
|
|
41
|
-
i0.ɵɵelement(2, "i",
|
|
93
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
95
|
+
i0.ɵɵelementStart(0, "div", 34)(1, "button", 35);
|
|
96
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnRefreshConversationsClick($event)); });
|
|
97
|
+
i0.ɵɵelement(2, "i", 36);
|
|
42
98
|
i0.ɵɵelementStart(3, "span");
|
|
43
99
|
i0.ɵɵtext(4);
|
|
44
100
|
i0.ɵɵelementEnd()();
|
|
45
|
-
i0.ɵɵelementStart(5, "button",
|
|
46
|
-
i0.ɵɵlistener("click", function
|
|
47
|
-
i0.ɵɵelement(6, "i",
|
|
101
|
+
i0.ɵɵelementStart(5, "button", 37);
|
|
102
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Template_button_click_5_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnToggleGroupByClick($event)); });
|
|
103
|
+
i0.ɵɵelement(6, "i", 38);
|
|
48
104
|
i0.ɵɵelementStart(7, "span");
|
|
49
|
-
i0.ɵɵtext(8
|
|
50
|
-
i0.ɵɵelementEnd()();
|
|
51
|
-
i0.ɵɵelementStart(9, "button", 18);
|
|
52
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_3_Template_button_click_9_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onToggleGroupByClick($event)); });
|
|
53
|
-
i0.ɵɵelement(10, "i", 20);
|
|
54
|
-
i0.ɵɵelementStart(11, "span");
|
|
55
|
-
i0.ɵɵtext(12);
|
|
105
|
+
i0.ɵɵtext(8);
|
|
56
106
|
i0.ɵɵelementEnd()();
|
|
57
|
-
i0.ɵɵconditionalCreate(
|
|
107
|
+
i0.ɵɵconditionalCreate(9, ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Conditional_9_Template, 4, 0, "button", 39);
|
|
58
108
|
i0.ɵɵelementEnd();
|
|
59
109
|
} if (rf & 2) {
|
|
60
|
-
const ctx_r1 = i0.ɵɵnextContext(
|
|
110
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
61
111
|
i0.ɵɵadvance();
|
|
62
|
-
i0.ɵɵproperty("disabled", ctx_r1.
|
|
112
|
+
i0.ɵɵproperty("disabled", ctx_r1.IsRefreshing);
|
|
63
113
|
i0.ɵɵadvance();
|
|
64
|
-
i0.ɵɵclassProp("fa-spin", ctx_r1.
|
|
114
|
+
i0.ɵɵclassProp("fa-spin", ctx_r1.IsRefreshing);
|
|
65
115
|
i0.ɵɵadvance(2);
|
|
66
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
67
|
-
i0.ɵɵadvance(6);
|
|
68
|
-
i0.ɵɵclassProp("fa-folder-tree", ctx_r1.groupBy !== "project")("fa-list", ctx_r1.groupBy === "project");
|
|
116
|
+
i0.ɵɵtextInterpolate(ctx_r1.IsRefreshing ? "Refreshing..." : "Refresh");
|
|
69
117
|
i0.ɵɵadvance(2);
|
|
70
|
-
i0.ɵɵ
|
|
118
|
+
i0.ɵɵclassProp("fa-folder-tree", ctx_r1.GroupBy !== "project")("fa-list", ctx_r1.GroupBy === "project");
|
|
119
|
+
i0.ɵɵadvance(2);
|
|
120
|
+
i0.ɵɵtextInterpolate(ctx_r1.GroupBy === "project" ? "Show as flat list" : "Group by folder");
|
|
71
121
|
i0.ɵɵadvance();
|
|
72
|
-
i0.ɵɵconditional(!ctx_r1.
|
|
122
|
+
i0.ɵɵconditional(!ctx_r1.IsMobileView ? 9 : -1);
|
|
73
123
|
} }
|
|
74
|
-
function
|
|
75
|
-
const
|
|
76
|
-
i0.ɵɵelementStart(0, "div",
|
|
77
|
-
i0.ɵɵlistener("click", function
|
|
78
|
-
i0.ɵɵelement(2, "i",
|
|
124
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
125
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
126
|
+
i0.ɵɵelementStart(0, "div", 28)(1, "button", 32);
|
|
127
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleHeaderMenu($event)); });
|
|
128
|
+
i0.ɵɵelement(2, "i", 33);
|
|
79
129
|
i0.ɵɵelementEnd();
|
|
80
|
-
i0.ɵɵconditionalCreate(3,
|
|
130
|
+
i0.ɵɵconditionalCreate(3, ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Conditional_3_Template, 10, 10, "div", 34);
|
|
81
131
|
i0.ɵɵelementEnd();
|
|
132
|
+
} if (rf & 2) {
|
|
133
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
134
|
+
i0.ɵɵadvance(3);
|
|
135
|
+
i0.ɵɵconditional(ctx_r1.IsHeaderMenuOpen ? 3 : -1);
|
|
136
|
+
} }
|
|
137
|
+
function ConversationListComponent_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_1_Conditional_3_Conditional_0_Template, 4, 2, "div", 27);
|
|
139
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_1_Conditional_3_Conditional_1_Template, 4, 1, "div", 28);
|
|
140
|
+
} if (rf & 2) {
|
|
141
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
142
|
+
i0.ɵɵconditional(ctx_r1.showSearch ? 0 : -1);
|
|
143
|
+
i0.ɵɵadvance();
|
|
144
|
+
i0.ɵɵconditional(ctx_r1.ShowHeaderMenu ? 1 : -1);
|
|
145
|
+
} }
|
|
146
|
+
function ConversationListComponent_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
147
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
148
|
+
i0.ɵɵelementStart(0, "div", 15)(1, "button", 41);
|
|
149
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_4_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetSort("date")); });
|
|
150
|
+
i0.ɵɵelement(2, "i", 42);
|
|
151
|
+
i0.ɵɵelementStart(3, "span");
|
|
152
|
+
i0.ɵɵtext(4, "Date");
|
|
153
|
+
i0.ɵɵelementEnd()();
|
|
154
|
+
i0.ɵɵelementStart(5, "button", 41);
|
|
155
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_1_Conditional_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetSort("name")); });
|
|
156
|
+
i0.ɵɵelement(6, "i", 42);
|
|
157
|
+
i0.ɵɵelementStart(7, "span");
|
|
158
|
+
i0.ɵɵtext(8, "Name");
|
|
159
|
+
i0.ɵɵelementEnd()()();
|
|
82
160
|
} if (rf & 2) {
|
|
83
161
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
162
|
+
i0.ɵɵadvance();
|
|
163
|
+
i0.ɵɵclassProp("active", ctx_r1.SortBy === "date");
|
|
164
|
+
i0.ɵɵproperty("title", ctx_r1.SortBy === "date" ? ctx_r1.SortDirection === "asc" ? "Oldest first" : "Newest first" : "Sort by date");
|
|
165
|
+
i0.ɵɵadvance();
|
|
166
|
+
i0.ɵɵproperty("ngClass", ctx_r1.SortIcon("date"));
|
|
84
167
|
i0.ɵɵadvance(3);
|
|
85
|
-
i0.ɵɵ
|
|
168
|
+
i0.ɵɵclassProp("active", ctx_r1.SortBy === "name");
|
|
169
|
+
i0.ɵɵproperty("title", ctx_r1.SortBy === "name" ? ctx_r1.SortDirection === "asc" ? "A to Z" : "Z to A" : "Sort by name");
|
|
170
|
+
i0.ɵɵadvance();
|
|
171
|
+
i0.ɵɵproperty("ngClass", ctx_r1.SortIcon("name"));
|
|
86
172
|
} }
|
|
87
173
|
function ConversationListComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
-
i0.ɵɵelementStart(0, "div",
|
|
89
|
-
i0.ɵɵconditionalCreate(2, ConversationListComponent_Conditional_1_Conditional_2_Template,
|
|
90
|
-
i0.ɵɵ
|
|
91
|
-
i0.ɵɵ
|
|
174
|
+
i0.ɵɵelementStart(0, "div", 5)(1, "div", 13);
|
|
175
|
+
i0.ɵɵconditionalCreate(2, ConversationListComponent_Conditional_1_Conditional_2_Template, 13, 10, "div", 14)(3, ConversationListComponent_Conditional_1_Conditional_3_Template, 2, 2);
|
|
176
|
+
i0.ɵɵelementEnd();
|
|
177
|
+
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_1_Conditional_4_Template, 9, 8, "div", 15);
|
|
178
|
+
i0.ɵɵelementEnd();
|
|
92
179
|
} if (rf & 2) {
|
|
93
180
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
94
181
|
i0.ɵɵadvance(2);
|
|
95
|
-
i0.ɵɵconditional(ctx_r1.
|
|
96
|
-
i0.ɵɵadvance();
|
|
97
|
-
i0.ɵɵconditional(ctx_r1.
|
|
182
|
+
i0.ɵɵconditional(ctx_r1.IsSelectionMode ? 2 : 3);
|
|
183
|
+
i0.ɵɵadvance(2);
|
|
184
|
+
i0.ɵɵconditional(ctx_r1.showSearch || ctx_r1.ShowHeaderMenu ? 4 : -1);
|
|
98
185
|
} }
|
|
99
186
|
function ConversationListComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
100
|
-
const
|
|
101
|
-
i0.ɵɵelementStart(0, "button",
|
|
102
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
103
|
-
i0.ɵɵelement(1, "i",
|
|
187
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
188
|
+
i0.ɵɵelementStart(0, "button", 43);
|
|
189
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CreateNewConversation()); });
|
|
190
|
+
i0.ɵɵelement(1, "i", 44);
|
|
104
191
|
i0.ɵɵelementStart(2, "span");
|
|
105
192
|
i0.ɵɵtext(3, "New Conversation");
|
|
106
193
|
i0.ɵɵelementEnd()();
|
|
107
194
|
} }
|
|
108
195
|
function ConversationListComponent_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
109
|
-
const
|
|
110
|
-
i0.ɵɵelementStart(0, "div",
|
|
111
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
112
|
-
i0.ɵɵelementStart(1, "div",
|
|
113
|
-
i0.ɵɵelement(2, "i",
|
|
196
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
197
|
+
i0.ɵɵelementStart(0, "div", 48);
|
|
198
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.TogglePinned()); });
|
|
199
|
+
i0.ɵɵelementStart(1, "div", 49);
|
|
200
|
+
i0.ɵɵelement(2, "i", 50)(3, "i", 51);
|
|
114
201
|
i0.ɵɵelementStart(4, "span");
|
|
115
202
|
i0.ɵɵtext(5, "Pinned");
|
|
116
203
|
i0.ɵɵelementEnd()()();
|
|
117
204
|
} if (rf & 2) {
|
|
118
205
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
119
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
206
|
+
i0.ɵɵclassProp("expanded", ctx_r1.PinnedExpanded);
|
|
120
207
|
} }
|
|
121
208
|
function ConversationListComponent_Conditional_4_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
122
|
-
i0.ɵɵelementContainer(0,
|
|
209
|
+
i0.ɵɵelementContainer(0, 47);
|
|
123
210
|
} if (rf & 2) {
|
|
124
|
-
const
|
|
211
|
+
const conversation_r11 = ctx.$implicit;
|
|
125
212
|
i0.ɵɵnextContext(2);
|
|
126
|
-
const
|
|
127
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
213
|
+
const conversationItem_r12 = i0.ɵɵreference(11);
|
|
214
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, conversation_r11));
|
|
128
215
|
} }
|
|
129
216
|
function ConversationListComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
-
i0.ɵɵelementStart(0, "div",
|
|
131
|
-
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_4_Conditional_1_Template, 6, 2, "div",
|
|
132
|
-
i0.ɵɵelementStart(2, "div",
|
|
133
|
-
i0.ɵɵrepeaterCreate(3, ConversationListComponent_Conditional_4_For_4_Template, 1, 4, "ng-container",
|
|
217
|
+
i0.ɵɵelementStart(0, "div", 8);
|
|
218
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_4_Conditional_1_Template, 6, 2, "div", 45);
|
|
219
|
+
i0.ɵɵelementStart(2, "div", 46);
|
|
220
|
+
i0.ɵɵrepeaterCreate(3, ConversationListComponent_Conditional_4_For_4_Template, 1, 4, "ng-container", 47, _forTrack0);
|
|
134
221
|
i0.ɵɵelementEnd()();
|
|
135
222
|
} if (rf & 2) {
|
|
136
223
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
137
224
|
i0.ɵɵadvance();
|
|
138
|
-
i0.ɵɵconditional(ctx_r1.
|
|
225
|
+
i0.ɵɵconditional(ctx_r1.ShowSectionHeaders ? 1 : -1);
|
|
139
226
|
i0.ɵɵadvance();
|
|
140
|
-
i0.ɵɵclassProp("expanded", !ctx_r1.
|
|
227
|
+
i0.ɵɵclassProp("expanded", !ctx_r1.ShowSectionHeaders || ctx_r1.PinnedExpanded);
|
|
141
228
|
i0.ɵɵadvance();
|
|
142
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
229
|
+
i0.ɵɵrepeater(ctx_r1.PinnedConversations);
|
|
143
230
|
} }
|
|
144
231
|
function ConversationListComponent_Conditional_5_For_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
145
|
-
i0.ɵɵelementContainer(0,
|
|
232
|
+
i0.ɵɵelementContainer(0, 47);
|
|
146
233
|
} if (rf & 2) {
|
|
147
|
-
const
|
|
234
|
+
const node_r14 = i0.ɵɵnextContext().$implicit;
|
|
148
235
|
i0.ɵɵnextContext(2);
|
|
149
|
-
const
|
|
150
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
236
|
+
const folderNode_r15 = i0.ɵɵreference(9);
|
|
237
|
+
i0.ɵɵproperty("ngTemplateOutlet", folderNode_r15)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, node_r14));
|
|
151
238
|
} }
|
|
152
239
|
function ConversationListComponent_Conditional_5_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
153
|
-
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_5_For_10_Conditional_0_Template, 1, 4, "ng-container",
|
|
240
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_5_For_10_Conditional_0_Template, 1, 4, "ng-container", 47);
|
|
154
241
|
} if (rf & 2) {
|
|
155
|
-
const
|
|
242
|
+
const node_r14 = ctx.$implicit;
|
|
156
243
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
157
|
-
i0.ɵɵconditional(!ctx_r1.
|
|
244
|
+
i0.ɵɵconditional(!ctx_r1.IsSearching || node_r14.hasContent ? 0 : -1);
|
|
158
245
|
} }
|
|
159
246
|
function ConversationListComponent_Conditional_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
160
|
-
i0.ɵɵelementStart(0, "div",
|
|
247
|
+
i0.ɵɵelementStart(0, "div", 56);
|
|
161
248
|
i0.ɵɵtext(1, "No folders yet \u2014 create one to organize conversations.");
|
|
162
249
|
i0.ɵɵelementEnd();
|
|
163
250
|
} }
|
|
164
251
|
function ConversationListComponent_Conditional_5_For_20_Template(rf, ctx) { if (rf & 1) {
|
|
165
|
-
i0.ɵɵelementContainer(0,
|
|
252
|
+
i0.ɵɵelementContainer(0, 47);
|
|
166
253
|
} if (rf & 2) {
|
|
167
|
-
const
|
|
254
|
+
const conversation_r16 = ctx.$implicit;
|
|
168
255
|
i0.ɵɵnextContext(2);
|
|
169
|
-
const
|
|
170
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
256
|
+
const conversationItem_r12 = i0.ɵɵreference(11);
|
|
257
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, conversation_r16));
|
|
171
258
|
} }
|
|
172
259
|
function ConversationListComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
173
|
-
const
|
|
174
|
-
i0.ɵɵelementStart(0, "div",
|
|
175
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_div_click_1_listener() { i0.ɵɵrestoreView(
|
|
176
|
-
i0.ɵɵelementStart(2, "div",
|
|
177
|
-
i0.ɵɵelement(3, "i",
|
|
260
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
261
|
+
i0.ɵɵelementStart(0, "div", 52)(1, "div", 53);
|
|
262
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleFolders()); })("dragover", function ConversationListComponent_Conditional_5_Template_div_dragover_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFoldersRootDragOver($event)); })("dragleave", function ConversationListComponent_Conditional_5_Template_div_dragleave_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave("folders-root")); })("drop", function ConversationListComponent_Conditional_5_Template_div_drop_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFoldersRootDrop($event)); });
|
|
263
|
+
i0.ɵɵelementStart(2, "div", 49);
|
|
264
|
+
i0.ɵɵelement(3, "i", 50);
|
|
178
265
|
i0.ɵɵelementStart(4, "span");
|
|
179
266
|
i0.ɵɵtext(5, "Folders");
|
|
180
267
|
i0.ɵɵelementEnd()();
|
|
181
|
-
i0.ɵɵelementStart(6, "button",
|
|
182
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(
|
|
183
|
-
i0.ɵɵelement(7, "i",
|
|
268
|
+
i0.ɵɵelementStart(6, "button", 54);
|
|
269
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CreateFolder(null, $event)); });
|
|
270
|
+
i0.ɵɵelement(7, "i", 55);
|
|
184
271
|
i0.ɵɵelementEnd()();
|
|
185
|
-
i0.ɵɵelementStart(8, "div",
|
|
272
|
+
i0.ɵɵelementStart(8, "div", 46);
|
|
186
273
|
i0.ɵɵrepeaterCreate(9, ConversationListComponent_Conditional_5_For_10_Template, 1, 1, null, null, _forTrack1);
|
|
187
|
-
i0.ɵɵconditionalCreate(11, ConversationListComponent_Conditional_5_Conditional_11_Template, 2, 0, "div",
|
|
274
|
+
i0.ɵɵconditionalCreate(11, ConversationListComponent_Conditional_5_Conditional_11_Template, 2, 0, "div", 56);
|
|
188
275
|
i0.ɵɵelementEnd()();
|
|
189
|
-
i0.ɵɵelementStart(12, "div",
|
|
190
|
-
i0.ɵɵlistener("dragover", function ConversationListComponent_Conditional_5_Template_div_dragover_12_listener($event) { i0.ɵɵrestoreView(
|
|
191
|
-
i0.ɵɵelementStart(13, "div",
|
|
192
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_div_click_13_listener() { i0.ɵɵrestoreView(
|
|
193
|
-
i0.ɵɵelementStart(14, "div",
|
|
194
|
-
i0.ɵɵelement(15, "i",
|
|
276
|
+
i0.ɵɵelementStart(12, "div", 57);
|
|
277
|
+
i0.ɵɵlistener("dragover", function ConversationListComponent_Conditional_5_Template_div_dragover_12_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnUngroupedDragOver($event)); })("dragleave", function ConversationListComponent_Conditional_5_Template_div_dragleave_12_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave("ungrouped")); })("drop", function ConversationListComponent_Conditional_5_Template_div_drop_12_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnUngroupedDrop($event)); });
|
|
278
|
+
i0.ɵɵelementStart(13, "div", 48);
|
|
279
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_5_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleUngrouped()); });
|
|
280
|
+
i0.ɵɵelementStart(14, "div", 49);
|
|
281
|
+
i0.ɵɵelement(15, "i", 50);
|
|
195
282
|
i0.ɵɵelementStart(16, "span");
|
|
196
283
|
i0.ɵɵtext(17);
|
|
197
284
|
i0.ɵɵelementEnd()()();
|
|
198
|
-
i0.ɵɵelementStart(18, "div",
|
|
199
|
-
i0.ɵɵrepeaterCreate(19, ConversationListComponent_Conditional_5_For_20_Template, 1, 4, "ng-container",
|
|
285
|
+
i0.ɵɵelementStart(18, "div", 46);
|
|
286
|
+
i0.ɵɵrepeaterCreate(19, ConversationListComponent_Conditional_5_For_20_Template, 1, 4, "ng-container", 47, _forTrack0);
|
|
200
287
|
i0.ɵɵelementEnd()();
|
|
201
288
|
} if (rf & 2) {
|
|
202
289
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
203
290
|
i0.ɵɵadvance();
|
|
204
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
291
|
+
i0.ɵɵclassProp("expanded", ctx_r1.FoldersExpanded)("drag-over", ctx_r1.DragOverTargetId === "folders-root");
|
|
205
292
|
i0.ɵɵadvance(7);
|
|
206
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
293
|
+
i0.ɵɵclassProp("expanded", ctx_r1.FoldersExpanded);
|
|
207
294
|
i0.ɵɵadvance();
|
|
208
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
295
|
+
i0.ɵɵrepeater(ctx_r1.FolderTree);
|
|
209
296
|
i0.ɵɵadvance(2);
|
|
210
|
-
i0.ɵɵconditional(ctx_r1.
|
|
297
|
+
i0.ɵɵconditional(ctx_r1.FolderTree.length === 0 ? 11 : -1);
|
|
211
298
|
i0.ɵɵadvance();
|
|
212
|
-
i0.ɵɵclassProp("drag-over", ctx_r1.
|
|
299
|
+
i0.ɵɵclassProp("drag-over", ctx_r1.DragOverTargetId === "ungrouped");
|
|
213
300
|
i0.ɵɵadvance();
|
|
214
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
301
|
+
i0.ɵɵclassProp("expanded", ctx_r1.UngroupedExpanded);
|
|
215
302
|
i0.ɵɵadvance(4);
|
|
216
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
303
|
+
i0.ɵɵtextInterpolate(ctx_r1.FolderTree.length > 0 ? "Ungrouped" : "Messages");
|
|
217
304
|
i0.ɵɵadvance();
|
|
218
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
305
|
+
i0.ɵɵclassProp("expanded", ctx_r1.UngroupedExpanded);
|
|
219
306
|
i0.ɵɵadvance();
|
|
220
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
307
|
+
i0.ɵɵrepeater(ctx_r1.UngroupedConversations);
|
|
221
308
|
} }
|
|
222
309
|
function ConversationListComponent_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
223
|
-
const
|
|
224
|
-
i0.ɵɵelementStart(0, "div",
|
|
225
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_6_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
226
|
-
i0.ɵɵelementStart(1, "div",
|
|
227
|
-
i0.ɵɵelement(2, "i",
|
|
310
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
311
|
+
i0.ɵɵelementStart(0, "div", 48);
|
|
312
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_6_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleDirectMessages()); });
|
|
313
|
+
i0.ɵɵelementStart(1, "div", 49);
|
|
314
|
+
i0.ɵɵelement(2, "i", 50);
|
|
228
315
|
i0.ɵɵelementStart(3, "span");
|
|
229
316
|
i0.ɵɵtext(4, "Messages");
|
|
230
317
|
i0.ɵɵelementEnd()()();
|
|
231
318
|
} if (rf & 2) {
|
|
232
319
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
233
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
320
|
+
i0.ɵɵclassProp("expanded", ctx_r1.DirectMessagesExpanded);
|
|
234
321
|
} }
|
|
235
322
|
function ConversationListComponent_Conditional_6_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
236
|
-
i0.ɵɵelementContainer(0,
|
|
323
|
+
i0.ɵɵelementContainer(0, 47);
|
|
237
324
|
} if (rf & 2) {
|
|
238
|
-
const
|
|
325
|
+
const conversation_r18 = ctx.$implicit;
|
|
239
326
|
i0.ɵɵnextContext(2);
|
|
240
|
-
const
|
|
241
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
327
|
+
const conversationItem_r12 = i0.ɵɵreference(11);
|
|
328
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, conversation_r18));
|
|
242
329
|
} }
|
|
243
330
|
function ConversationListComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
244
|
-
i0.ɵɵelementStart(0, "div",
|
|
245
|
-
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_6_Conditional_1_Template, 5, 2, "div",
|
|
246
|
-
i0.ɵɵelementStart(2, "div",
|
|
247
|
-
i0.ɵɵrepeaterCreate(3, ConversationListComponent_Conditional_6_For_4_Template, 1, 4, "ng-container",
|
|
331
|
+
i0.ɵɵelementStart(0, "div", 9);
|
|
332
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_6_Conditional_1_Template, 5, 2, "div", 45);
|
|
333
|
+
i0.ɵɵelementStart(2, "div", 46);
|
|
334
|
+
i0.ɵɵrepeaterCreate(3, ConversationListComponent_Conditional_6_For_4_Template, 1, 4, "ng-container", 47, _forTrack0);
|
|
248
335
|
i0.ɵɵelementEnd()();
|
|
249
336
|
} if (rf & 2) {
|
|
250
337
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
251
338
|
i0.ɵɵadvance();
|
|
252
|
-
i0.ɵɵconditional(ctx_r1.
|
|
339
|
+
i0.ɵɵconditional(ctx_r1.ShowSectionHeaders ? 1 : -1);
|
|
253
340
|
i0.ɵɵadvance();
|
|
254
|
-
i0.ɵɵclassProp("expanded", !ctx_r1.
|
|
341
|
+
i0.ɵɵclassProp("expanded", !ctx_r1.ShowSectionHeaders || ctx_r1.DirectMessagesExpanded);
|
|
255
342
|
i0.ɵɵadvance();
|
|
256
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
257
|
-
} }
|
|
258
|
-
function ConversationListComponent_Conditional_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
259
|
-
const _r17 = i0.ɵɵgetCurrentView();
|
|
260
|
-
i0.ɵɵelementStart(0, "button", 45);
|
|
261
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_7_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectAll()); });
|
|
262
|
-
i0.ɵɵtext(1, "Select All");
|
|
263
|
-
i0.ɵɵelementEnd();
|
|
264
|
-
} }
|
|
265
|
-
function ConversationListComponent_Conditional_7_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
266
|
-
const _r18 = i0.ɵɵgetCurrentView();
|
|
267
|
-
i0.ɵɵelementStart(0, "button", 45);
|
|
268
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_7_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.deselectAll()); });
|
|
269
|
-
i0.ɵɵtext(1, "Deselect All");
|
|
270
|
-
i0.ɵɵelementEnd();
|
|
343
|
+
i0.ɵɵrepeater(ctx_r1.UnpinnedConversations);
|
|
271
344
|
} }
|
|
272
345
|
function ConversationListComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
273
|
-
const
|
|
274
|
-
i0.ɵɵelementStart(0, "
|
|
346
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
347
|
+
i0.ɵɵelementStart(0, "button", 58);
|
|
348
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.EscalateSearch()); });
|
|
349
|
+
i0.ɵɵelement(1, "i", 59);
|
|
350
|
+
i0.ɵɵelementStart(2, "span", 60);
|
|
275
351
|
i0.ɵɵtext(3);
|
|
276
352
|
i0.ɵɵelementEnd();
|
|
277
|
-
i0.ɵɵ
|
|
278
|
-
i0.ɵɵelementEnd();
|
|
279
|
-
i0.ɵɵelementStart(6, "div", 41)(7, "button", 42);
|
|
280
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_7_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.bulkDeleteConversations()); });
|
|
281
|
-
i0.ɵɵelement(8, "i", 43);
|
|
282
|
-
i0.ɵɵtext(9);
|
|
353
|
+
i0.ɵɵelement(4, "i", 61);
|
|
283
354
|
i0.ɵɵelementEnd();
|
|
284
|
-
i0.ɵɵelementStart(10, "button", 44);
|
|
285
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_7_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSelectionMode()); });
|
|
286
|
-
i0.ɵɵtext(11, " Cancel ");
|
|
287
|
-
i0.ɵɵelementEnd()()();
|
|
288
355
|
} if (rf & 2) {
|
|
289
356
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
290
357
|
i0.ɵɵadvance(3);
|
|
291
|
-
i0.ɵɵtextInterpolate1("", ctx_r1.
|
|
292
|
-
i0.ɵɵadvance();
|
|
293
|
-
i0.ɵɵconditional(ctx_r1.selectedConversationIds.size < ctx_r1.filteredConversations.length ? 4 : 5);
|
|
294
|
-
i0.ɵɵadvance(3);
|
|
295
|
-
i0.ɵɵproperty("disabled", ctx_r1.selectedConversationIds.size === 0);
|
|
296
|
-
i0.ɵɵadvance(2);
|
|
297
|
-
i0.ɵɵtextInterpolate1(" Delete (", ctx_r1.selectedConversationIds.size, ") ");
|
|
358
|
+
i0.ɵɵtextInterpolate1("Search all of Chat for \u201C", ctx_r1.SearchQuery, "\u201D");
|
|
298
359
|
} }
|
|
299
|
-
function
|
|
300
|
-
i0.ɵɵ
|
|
360
|
+
function ConversationListComponent_ng_template_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
361
|
+
i0.ɵɵelementStart(0, "span", 65);
|
|
362
|
+
i0.ɵɵelement(1, "i", 69);
|
|
363
|
+
i0.ɵɵelementEnd();
|
|
364
|
+
} }
|
|
365
|
+
function ConversationListComponent_ng_template_8_Conditional_9_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
366
|
+
i0.ɵɵelementContainer(0, 47);
|
|
301
367
|
} if (rf & 2) {
|
|
302
|
-
const
|
|
368
|
+
const child_r22 = i0.ɵɵnextContext().$implicit;
|
|
303
369
|
i0.ɵɵnextContext(3);
|
|
304
|
-
const
|
|
305
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
370
|
+
const folderNode_r15 = i0.ɵɵreference(9);
|
|
371
|
+
i0.ɵɵproperty("ngTemplateOutlet", folderNode_r15)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, child_r22));
|
|
306
372
|
} }
|
|
307
|
-
function
|
|
308
|
-
i0.ɵɵconditionalCreate(0,
|
|
373
|
+
function ConversationListComponent_ng_template_8_Conditional_9_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
374
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_ng_template_8_Conditional_9_For_2_Conditional_0_Template, 1, 4, "ng-container", 47);
|
|
309
375
|
} if (rf & 2) {
|
|
310
|
-
const
|
|
376
|
+
const child_r22 = ctx.$implicit;
|
|
311
377
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
312
|
-
i0.ɵɵconditional(!ctx_r1.
|
|
378
|
+
i0.ɵɵconditional(!ctx_r1.IsSearching || child_r22.hasContent ? 0 : -1);
|
|
313
379
|
} }
|
|
314
|
-
function
|
|
315
|
-
i0.ɵɵelementContainer(0,
|
|
380
|
+
function ConversationListComponent_ng_template_8_Conditional_9_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
381
|
+
i0.ɵɵelementContainer(0, 47);
|
|
316
382
|
} if (rf & 2) {
|
|
317
|
-
const
|
|
318
|
-
const
|
|
383
|
+
const conversation_r23 = ctx.$implicit;
|
|
384
|
+
const node_r21 = i0.ɵɵnextContext(2).$implicit;
|
|
319
385
|
i0.ɵɵnextContext();
|
|
320
|
-
const
|
|
321
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
386
|
+
const conversationItem_r12 = i0.ɵɵreference(11);
|
|
387
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction2(2, _c3, conversation_r23, node_r21.depth + 1));
|
|
322
388
|
} }
|
|
323
|
-
function
|
|
324
|
-
i0.ɵɵelementStart(0, "div",
|
|
389
|
+
function ConversationListComponent_ng_template_8_Conditional_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
390
|
+
i0.ɵɵelementStart(0, "div", 56);
|
|
325
391
|
i0.ɵɵtext(1, "Empty \u2014 drop a conversation here");
|
|
326
392
|
i0.ɵɵelementEnd();
|
|
327
393
|
} if (rf & 2) {
|
|
328
|
-
const
|
|
329
|
-
i0.ɵɵstyleProp("padding-left", 26 +
|
|
394
|
+
const node_r21 = i0.ɵɵnextContext(2).$implicit;
|
|
395
|
+
i0.ɵɵstyleProp("padding-left", 26 + node_r21.depth * 14, "px");
|
|
330
396
|
} }
|
|
331
|
-
function
|
|
332
|
-
i0.ɵɵelementStart(0, "div",
|
|
333
|
-
i0.ɵɵrepeaterCreate(1,
|
|
334
|
-
i0.ɵɵrepeaterCreate(3,
|
|
335
|
-
i0.ɵɵconditionalCreate(5,
|
|
397
|
+
function ConversationListComponent_ng_template_8_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
398
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
399
|
+
i0.ɵɵrepeaterCreate(1, ConversationListComponent_ng_template_8_Conditional_9_For_2_Template, 1, 1, null, null, _forTrack1);
|
|
400
|
+
i0.ɵɵrepeaterCreate(3, ConversationListComponent_ng_template_8_Conditional_9_For_4_Template, 1, 5, "ng-container", 47, _forTrack0);
|
|
401
|
+
i0.ɵɵconditionalCreate(5, ConversationListComponent_ng_template_8_Conditional_9_Conditional_5_Template, 2, 2, "div", 70);
|
|
336
402
|
i0.ɵɵelementEnd();
|
|
337
403
|
} if (rf & 2) {
|
|
338
|
-
const
|
|
404
|
+
const node_r21 = i0.ɵɵnextContext().$implicit;
|
|
339
405
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
340
406
|
i0.ɵɵadvance();
|
|
341
|
-
i0.ɵɵrepeater(
|
|
407
|
+
i0.ɵɵrepeater(node_r21.children);
|
|
342
408
|
i0.ɵɵadvance(2);
|
|
343
|
-
i0.ɵɵrepeater(
|
|
409
|
+
i0.ɵɵrepeater(node_r21.conversations);
|
|
344
410
|
i0.ɵɵadvance(2);
|
|
345
|
-
i0.ɵɵconditional(
|
|
411
|
+
i0.ɵɵconditional(node_r21.totalCount === 0 && !ctx_r1.IsSearching ? 5 : -1);
|
|
346
412
|
} }
|
|
347
413
|
function ConversationListComponent_ng_template_8_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
-
const
|
|
349
|
-
i0.ɵɵelementStart(0, "div",
|
|
350
|
-
i0.ɵɵlistener("dragstart", function ConversationListComponent_ng_template_8_Template_div_dragstart_0_listener($event) { const
|
|
351
|
-
i0.ɵɵelement(1, "i",
|
|
352
|
-
i0.ɵɵelementStart(3, "span",
|
|
414
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
415
|
+
i0.ɵɵelementStart(0, "div", 62);
|
|
416
|
+
i0.ɵɵlistener("dragstart", function ConversationListComponent_ng_template_8_Template_div_dragstart_0_listener($event) { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFolderDragStart(node_r21, $event)); })("dragend", function ConversationListComponent_ng_template_8_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFolderDragEnd()); })("click", function ConversationListComponent_ng_template_8_Template_div_click_0_listener() { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleFolder(node_r21.project.ID)); })("dragover", function ConversationListComponent_ng_template_8_Template_div_dragover_0_listener($event) { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFolderDragOver(node_r21.project.ID, $event)); })("dragleave", function ConversationListComponent_ng_template_8_Template_div_dragleave_0_listener() { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave(node_r21.project.ID)); })("drop", function ConversationListComponent_ng_template_8_Template_div_drop_0_listener($event) { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFolderDrop(node_r21.project, $event)); })("contextmenu", function ConversationListComponent_ng_template_8_Template_div_contextmenu_0_listener($event) { const node_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFolderContextMenu(node_r21.project, $event)); });
|
|
417
|
+
i0.ɵɵelement(1, "i", 63)(2, "i");
|
|
418
|
+
i0.ɵɵelementStart(3, "span", 64);
|
|
353
419
|
i0.ɵɵtext(4);
|
|
354
420
|
i0.ɵɵelementEnd();
|
|
355
|
-
i0.ɵɵ
|
|
356
|
-
i0.ɵɵ
|
|
357
|
-
i0.ɵɵ
|
|
358
|
-
i0.ɵɵ
|
|
359
|
-
i0.ɵɵ
|
|
360
|
-
i0.ɵɵ
|
|
361
|
-
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_8_Template_button_click_8_listener($event) { const node_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.createFolder(node_r20.project.ID, $event)); });
|
|
362
|
-
i0.ɵɵelement(9, "i", 35);
|
|
363
|
-
i0.ɵɵelementEnd();
|
|
364
|
-
i0.ɵɵelementStart(10, "button", 52);
|
|
365
|
-
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_8_Template_button_click_10_listener($event) { const node_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.editFolder(node_r20.project, $event)); });
|
|
366
|
-
i0.ɵɵelement(11, "i", 53);
|
|
367
|
-
i0.ɵɵelementEnd();
|
|
368
|
-
i0.ɵɵelementStart(12, "button", 54);
|
|
369
|
-
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_8_Template_button_click_12_listener($event) { const node_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.deleteFolder(node_r20.project, $event)); });
|
|
370
|
-
i0.ɵɵelement(13, "i", 43);
|
|
371
|
-
i0.ɵɵelementEnd()()();
|
|
372
|
-
i0.ɵɵconditionalCreate(14, ConversationListComponent_ng_template_8_Conditional_14_Template, 6, 1, "div", 55);
|
|
421
|
+
i0.ɵɵconditionalCreate(5, ConversationListComponent_ng_template_8_Conditional_5_Template, 2, 0, "span", 65);
|
|
422
|
+
i0.ɵɵelement(6, "span", 66);
|
|
423
|
+
i0.ɵɵelementStart(7, "span", 67);
|
|
424
|
+
i0.ɵɵtext(8);
|
|
425
|
+
i0.ɵɵelementEnd()();
|
|
426
|
+
i0.ɵɵconditionalCreate(9, ConversationListComponent_ng_template_8_Conditional_9_Template, 6, 1, "div", 68);
|
|
373
427
|
} if (rf & 2) {
|
|
374
|
-
const
|
|
428
|
+
const node_r21 = ctx.$implicit;
|
|
375
429
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
376
|
-
i0.ɵɵstyleProp("padding-left", 12 +
|
|
377
|
-
i0.ɵɵclassProp("drag-over", ctx_r1.
|
|
378
|
-
i0.ɵɵproperty("draggable", true)("title",
|
|
430
|
+
i0.ɵɵstyleProp("padding-left", 12 + node_r21.depth * 14, "px");
|
|
431
|
+
i0.ɵɵclassProp("drag-over", ctx_r1.DragOverTargetId === node_r21.project.ID)("dragging", ctx_r1.DraggedFolderId === node_r21.project.ID);
|
|
432
|
+
i0.ɵɵproperty("draggable", true)("title", node_r21.project.Name);
|
|
379
433
|
i0.ɵɵadvance();
|
|
380
|
-
i0.ɵɵclassProp("expanded", ctx_r1.
|
|
434
|
+
i0.ɵɵclassProp("expanded", ctx_r1.IsFolderExpanded(node_r21.project.ID));
|
|
381
435
|
i0.ɵɵadvance();
|
|
382
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ",
|
|
383
|
-
i0.ɵɵstyleProp("color",
|
|
436
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ", node_r21.project.Icon || "fa-folder", " folder-icon"));
|
|
437
|
+
i0.ɵɵstyleProp("color", node_r21.project.Color || null);
|
|
384
438
|
i0.ɵɵadvance(2);
|
|
385
|
-
i0.ɵɵtextInterpolate(
|
|
386
|
-
i0.ɵɵadvance(
|
|
387
|
-
i0.ɵɵ
|
|
388
|
-
i0.ɵɵadvance(
|
|
389
|
-
i0.ɵɵ
|
|
439
|
+
i0.ɵɵtextInterpolate(node_r21.project.Name);
|
|
440
|
+
i0.ɵɵadvance();
|
|
441
|
+
i0.ɵɵconditional(!node_r21.project.OwnerUserID ? 5 : -1);
|
|
442
|
+
i0.ɵɵadvance(3);
|
|
443
|
+
i0.ɵɵtextInterpolate(node_r21.totalCount);
|
|
444
|
+
i0.ɵɵadvance();
|
|
445
|
+
i0.ɵɵconditional(ctx_r1.IsFolderExpanded(node_r21.project.ID) ? 9 : -1);
|
|
390
446
|
} }
|
|
391
|
-
function
|
|
392
|
-
|
|
393
|
-
i0.ɵɵ
|
|
394
|
-
i0.ɵɵ
|
|
395
|
-
|
|
447
|
+
function ConversationListComponent_ng_template_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
448
|
+
i0.ɵɵelementStart(0, "div", 75);
|
|
449
|
+
i0.ɵɵelement(1, "i", 85);
|
|
450
|
+
i0.ɵɵelementEnd();
|
|
451
|
+
} }
|
|
452
|
+
function ConversationListComponent_ng_template_10_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
453
|
+
i0.ɵɵelement(0, "i", 80);
|
|
396
454
|
} if (rf & 2) {
|
|
397
|
-
const
|
|
455
|
+
const conversation_r25 = i0.ɵɵnextContext().$implicit;
|
|
398
456
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
399
|
-
i0.ɵɵ
|
|
400
|
-
i0.ɵɵproperty("checked", ctx_r1.selectedConversationIds.has(conversation_r24.ID));
|
|
457
|
+
i0.ɵɵproperty("title", ctx_r1.SharedWithMeTooltip(conversation_r25));
|
|
401
458
|
} }
|
|
402
|
-
function
|
|
403
|
-
i0.ɵɵ
|
|
404
|
-
i0.ɵɵ
|
|
459
|
+
function ConversationListComponent_ng_template_10_Template(rf, ctx) { if (rf & 1) {
|
|
460
|
+
const _r24 = i0.ɵɵgetCurrentView();
|
|
461
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
462
|
+
i0.ɵɵlistener("dragstart", function ConversationListComponent_ng_template_10_Template_div_dragstart_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationDragStart(conversation_r25, $event)); })("dragend", function ConversationListComponent_ng_template_10_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationDragEnd()); })("dragover", function ConversationListComponent_ng_template_10_Template_div_dragover_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationRowDragOver(conversation_r25, $event)); })("dragleave", function ConversationListComponent_ng_template_10_Template_div_dragleave_0_listener() { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave(ctx_r1.ConversationDropTargetId(conversation_r25))); })("drop", function ConversationListComponent_ng_template_10_Template_div_drop_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationRowDrop(conversation_r25, $event)); })("pointerdown", function ConversationListComponent_ng_template_10_Template_div_pointerdown_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRowPointerDown(conversation_r25, $event)); })("pointermove", function ConversationListComponent_ng_template_10_Template_div_pointermove_0_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRowPointerMove($event)); })("pointerup", function ConversationListComponent_ng_template_10_Template_div_pointerup_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelLongPress()); })("pointercancel", function ConversationListComponent_ng_template_10_Template_div_pointercancel_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelLongPress()); })("click", function ConversationListComponent_ng_template_10_Template_div_click_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.HandleConversationClick(conversation_r25, $event)); })("contextmenu", function ConversationListComponent_ng_template_10_Template_div_contextmenu_0_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationContextMenu(conversation_r25, $event)); });
|
|
463
|
+
i0.ɵɵelementStart(1, "button", 72);
|
|
464
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_10_Template_button_click_1_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRowCheckboxClick(conversation_r25, $event)); });
|
|
465
|
+
i0.ɵɵelement(2, "i", 73);
|
|
405
466
|
i0.ɵɵelementEnd();
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
i0.ɵɵ
|
|
467
|
+
i0.ɵɵelementStart(3, "div", 74);
|
|
468
|
+
i0.ɵɵconditionalCreate(4, ConversationListComponent_ng_template_10_Conditional_4_Template, 2, 0, "div", 75);
|
|
469
|
+
i0.ɵɵelementStart(5, "div", 76);
|
|
470
|
+
i0.ɵɵelement(6, "mj-notification-badge", 77);
|
|
471
|
+
i0.ɵɵelementEnd()();
|
|
472
|
+
i0.ɵɵelementStart(7, "div", 78)(8, "div", 79);
|
|
473
|
+
i0.ɵɵtext(9);
|
|
474
|
+
i0.ɵɵconditionalCreate(10, ConversationListComponent_ng_template_10_Conditional_10_Template, 1, 1, "i", 80);
|
|
475
|
+
i0.ɵɵelementEnd();
|
|
476
|
+
i0.ɵɵelementStart(11, "div", 81);
|
|
477
|
+
i0.ɵɵtext(12);
|
|
478
|
+
i0.ɵɵelementEnd()();
|
|
479
|
+
i0.ɵɵelementStart(13, "div", 82)(14, "button", 83);
|
|
480
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_10_Template_button_click_14_listener($event) { const conversation_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenRowMenu(conversation_r25, $event)); });
|
|
481
|
+
i0.ɵɵelement(15, "i", 84);
|
|
482
|
+
i0.ɵɵelementEnd()()();
|
|
409
483
|
} if (rf & 2) {
|
|
410
|
-
const
|
|
484
|
+
const conversation_r25 = ctx.$implicit;
|
|
485
|
+
const depth_r26 = ctx.depth;
|
|
411
486
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
412
|
-
i0.ɵɵ
|
|
487
|
+
i0.ɵɵstyleProp("padding-left", depth_r26 ? 16 + depth_r26 * 14 : 16, "px");
|
|
488
|
+
i0.ɵɵclassProp("active", ctx_r1.IsConversationActive(conversation_r25))("selected", ctx_r1.IsConversationSelected(conversation_r25))("renamed", ctx_r1.IsConversationRenamed(conversation_r25))("dragging", ctx_r1.IsConversationDragging(conversation_r25));
|
|
489
|
+
i0.ɵɵproperty("draggable", ctx_r1.CanChange(conversation_r25));
|
|
490
|
+
i0.ɵɵadvance();
|
|
491
|
+
i0.ɵɵstyleProp("left", (depth_r26 || 0) * 14 + 4, "px");
|
|
492
|
+
i0.ɵɵclassProp("checked", ctx_r1.IsConversationSelected(conversation_r25));
|
|
493
|
+
i0.ɵɵattribute("aria-checked", ctx_r1.IsConversationSelected(conversation_r25))("aria-label", "Select " + (conversation_r25.Name || "conversation"));
|
|
494
|
+
i0.ɵɵadvance(3);
|
|
495
|
+
i0.ɵɵconditional(ctx_r1.HasActiveTasks(conversation_r25.ID) ? 4 : -1);
|
|
496
|
+
i0.ɵɵadvance(2);
|
|
497
|
+
i0.ɵɵproperty("conversationId", conversation_r25.ID);
|
|
498
|
+
i0.ɵɵadvance();
|
|
499
|
+
i0.ɵɵproperty("title", conversation_r25.Name + (conversation_r25.Description ? "\n" + conversation_r25.Description : ""));
|
|
500
|
+
i0.ɵɵadvance(2);
|
|
501
|
+
i0.ɵɵtextInterpolate1(" ", conversation_r25.Name, " ");
|
|
502
|
+
i0.ɵɵadvance();
|
|
503
|
+
i0.ɵɵconditional(ctx_r1.IsSharedWithMe(conversation_r25) ? 10 : -1);
|
|
504
|
+
i0.ɵɵadvance(2);
|
|
505
|
+
i0.ɵɵtextInterpolate(conversation_r25.Description);
|
|
413
506
|
} }
|
|
414
|
-
function
|
|
415
|
-
const
|
|
416
|
-
i0.ɵɵelementStart(0, "button",
|
|
417
|
-
i0.ɵɵlistener("click", function
|
|
507
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_0_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
508
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
509
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
510
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_0_For_11_Template_button_click_0_listener() { const f_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ContextMoveToFolder(f_r30.project.ID)); });
|
|
418
511
|
i0.ɵɵelement(1, "i");
|
|
419
512
|
i0.ɵɵelementStart(2, "span");
|
|
420
513
|
i0.ɵɵtext(3);
|
|
421
514
|
i0.ɵɵelementEnd()();
|
|
422
515
|
} if (rf & 2) {
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
i0.ɵɵ
|
|
427
|
-
i0.ɵɵclassProp("current", ctx_r1.IsInFolder(conversation_r24, f_r29.project.ID));
|
|
516
|
+
const f_r30 = ctx.$implicit;
|
|
517
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
518
|
+
i0.ɵɵstyleProp("padding-left", 14 + f_r30.depth * 12, "px");
|
|
519
|
+
i0.ɵɵclassProp("current", ctx_r1.IsSingleTargetInFolder(f_r30.project.ID));
|
|
428
520
|
i0.ɵɵadvance();
|
|
429
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ",
|
|
430
|
-
i0.ɵɵstyleProp("color",
|
|
521
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ", f_r30.project.Icon || "fa-folder"));
|
|
522
|
+
i0.ɵɵstyleProp("color", f_r30.project.Color || null);
|
|
431
523
|
i0.ɵɵadvance(2);
|
|
432
|
-
i0.ɵɵtextInterpolate(
|
|
524
|
+
i0.ɵɵtextInterpolate(f_r30.project.Name);
|
|
433
525
|
} }
|
|
434
|
-
function
|
|
435
|
-
const
|
|
436
|
-
i0.ɵɵelementStart(0, "button",
|
|
437
|
-
i0.ɵɵlistener("click", function
|
|
438
|
-
i0.ɵɵelement(1, "i",
|
|
526
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
527
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
528
|
+
i0.ɵɵelementStart(0, "button", 87);
|
|
529
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_0_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseMoveSubmenu($event)); });
|
|
530
|
+
i0.ɵɵelement(1, "i", 88);
|
|
439
531
|
i0.ɵɵelementStart(2, "span");
|
|
440
532
|
i0.ɵɵtext(3, "Move to folder");
|
|
441
533
|
i0.ɵɵelementEnd()();
|
|
442
|
-
i0.ɵɵelement(4, "div",
|
|
443
|
-
i0.ɵɵelementStart(5, "div",
|
|
444
|
-
i0.ɵɵlistener("click", function
|
|
445
|
-
i0.ɵɵelement(7, "i",
|
|
534
|
+
i0.ɵɵelement(4, "div", 89);
|
|
535
|
+
i0.ɵɵelementStart(5, "div", 90)(6, "button", 91);
|
|
536
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ContextMoveToFolder(null)); });
|
|
537
|
+
i0.ɵɵelement(7, "i", 92);
|
|
446
538
|
i0.ɵɵelementStart(8, "span");
|
|
447
539
|
i0.ɵɵtext(9, "No folder");
|
|
448
540
|
i0.ɵɵelementEnd()();
|
|
449
|
-
i0.ɵɵrepeaterCreate(10,
|
|
541
|
+
i0.ɵɵrepeaterCreate(10, ConversationListComponent_Conditional_13_Case_2_Conditional_0_For_11_Template, 4, 10, "button", 93, _forTrack1);
|
|
450
542
|
i0.ɵɵelementEnd();
|
|
451
|
-
i0.ɵɵelement(12, "div",
|
|
452
|
-
i0.ɵɵelementStart(13, "button",
|
|
453
|
-
i0.ɵɵlistener("click", function
|
|
454
|
-
i0.ɵɵelement(14, "i",
|
|
543
|
+
i0.ɵɵelement(12, "div", 89);
|
|
544
|
+
i0.ɵɵelementStart(13, "button", 91);
|
|
545
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_0_Template_button_click_13_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ContextMoveToNewFolder($event)); });
|
|
546
|
+
i0.ɵɵelement(14, "i", 55);
|
|
455
547
|
i0.ɵɵelementStart(15, "span");
|
|
456
548
|
i0.ɵɵtext(16, "New folder\u2026");
|
|
457
549
|
i0.ɵɵelementEnd()();
|
|
458
550
|
} if (rf & 2) {
|
|
459
|
-
const
|
|
460
|
-
const ctx_r1 = i0.ɵɵnextContext();
|
|
551
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
461
552
|
i0.ɵɵadvance(6);
|
|
462
|
-
i0.ɵɵclassProp("current",
|
|
553
|
+
i0.ɵɵclassProp("current", ctx_r1.IsSingleTargetInFolder(null));
|
|
554
|
+
i0.ɵɵadvance(4);
|
|
555
|
+
i0.ɵɵrepeater(ctx_r1.FlatFolders);
|
|
556
|
+
} }
|
|
557
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
558
|
+
const _r32 = i0.ɵɵgetCurrentView();
|
|
559
|
+
i0.ɵɵelementStart(0, "div", 99);
|
|
560
|
+
i0.ɵɵtext(1);
|
|
561
|
+
i0.ɵɵelementEnd();
|
|
562
|
+
i0.ɵɵelementStart(2, "button", 95);
|
|
563
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_0_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ContextSetPinned(true)); });
|
|
564
|
+
i0.ɵɵelement(3, "i", 20);
|
|
565
|
+
i0.ɵɵelementStart(4, "span");
|
|
566
|
+
i0.ɵɵtext(5, "Pin");
|
|
567
|
+
i0.ɵɵelementEnd()();
|
|
568
|
+
i0.ɵɵelementStart(6, "button", 95);
|
|
569
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ContextSetPinned(false)); });
|
|
570
|
+
i0.ɵɵelement(7, "i", 100);
|
|
571
|
+
i0.ɵɵelementStart(8, "span");
|
|
572
|
+
i0.ɵɵtext(9, "Unpin");
|
|
573
|
+
i0.ɵɵelementEnd()();
|
|
574
|
+
} if (rf & 2) {
|
|
575
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
576
|
+
i0.ɵɵadvance();
|
|
577
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.ContextMenu.targets.length, " selected");
|
|
578
|
+
i0.ɵɵadvance();
|
|
579
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets));
|
|
580
|
+
i0.ɵɵattribute("title", ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets) ? null : ctx_r1.ChangeRefusedReason);
|
|
463
581
|
i0.ɵɵadvance(4);
|
|
464
|
-
i0.ɵɵ
|
|
582
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets));
|
|
583
|
+
i0.ɵɵattribute("title", ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets) ? null : ctx_r1.ChangeRefusedReason);
|
|
465
584
|
} }
|
|
466
|
-
function
|
|
467
|
-
const
|
|
468
|
-
i0.ɵɵelementStart(0, "button",
|
|
469
|
-
i0.ɵɵlistener("click", function
|
|
470
|
-
i0.ɵɵelement(1, "i",
|
|
585
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
586
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
587
|
+
i0.ɵɵelementStart(0, "button", 95);
|
|
588
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ContextTogglePin()); });
|
|
589
|
+
i0.ɵɵelement(1, "i", 20);
|
|
471
590
|
i0.ɵɵelementStart(2, "span");
|
|
472
591
|
i0.ɵɵtext(3);
|
|
473
592
|
i0.ɵɵelementEnd()();
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
i0.ɵɵ
|
|
477
|
-
i0.ɵɵ
|
|
478
|
-
i0.ɵɵ
|
|
593
|
+
} if (rf & 2) {
|
|
594
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
595
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets));
|
|
596
|
+
i0.ɵɵattribute("title", ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets) ? null : ctx_r1.ChangeRefusedReason);
|
|
597
|
+
i0.ɵɵadvance(3);
|
|
598
|
+
i0.ɵɵtextInterpolate((ctx_r1.ContextMenu.conversation == null ? null : ctx_r1.ContextMenu.conversation.IsPinned) ? "Unpin" : "Pin");
|
|
599
|
+
} }
|
|
600
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
601
|
+
const _r34 = i0.ɵɵgetCurrentView();
|
|
602
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
603
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ContextRename()); });
|
|
604
|
+
i0.ɵɵelement(1, "i", 101);
|
|
605
|
+
i0.ɵɵelementStart(2, "span");
|
|
606
|
+
i0.ɵɵtext(3, "Rename");
|
|
607
|
+
i0.ɵɵelementEnd()();
|
|
608
|
+
} }
|
|
609
|
+
function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
610
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
611
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_0_Template, 10, 5)(1, ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_1_Template, 4, 3, "button", 94);
|
|
612
|
+
i0.ɵɵelementStart(2, "button", 95);
|
|
613
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Template_button_click_2_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OpenMoveSubmenu($event)); });
|
|
614
|
+
i0.ɵɵelement(3, "i", 22);
|
|
615
|
+
i0.ɵɵelementStart(4, "span");
|
|
616
|
+
i0.ɵɵtext(5, "Move to folder");
|
|
479
617
|
i0.ɵɵelementEnd();
|
|
480
|
-
i0.ɵɵelement(
|
|
618
|
+
i0.ɵɵelement(6, "i", 96);
|
|
481
619
|
i0.ɵɵelementEnd();
|
|
482
|
-
i0.ɵɵelementStart(
|
|
483
|
-
i0.ɵɵlistener("click", function
|
|
484
|
-
i0.ɵɵelement(
|
|
485
|
-
i0.ɵɵelementStart(
|
|
486
|
-
i0.ɵɵtext(
|
|
620
|
+
i0.ɵɵelementStart(7, "button", 95);
|
|
621
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ContextShare()); });
|
|
622
|
+
i0.ɵɵelement(8, "i", 24);
|
|
623
|
+
i0.ɵɵelementStart(9, "span");
|
|
624
|
+
i0.ɵɵtext(10);
|
|
487
625
|
i0.ɵɵelementEnd()();
|
|
488
|
-
i0.ɵɵ
|
|
489
|
-
i0.ɵɵ
|
|
490
|
-
i0.ɵɵ
|
|
491
|
-
i0.ɵɵ
|
|
492
|
-
i0.ɵɵ
|
|
493
|
-
i0.ɵɵ
|
|
626
|
+
i0.ɵɵconditionalCreate(11, ConversationListComponent_Conditional_13_Case_2_Conditional_1_Conditional_11_Template, 4, 0, "button", 97);
|
|
627
|
+
i0.ɵɵelement(12, "div", 89);
|
|
628
|
+
i0.ɵɵelementStart(13, "button", 98);
|
|
629
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_2_Conditional_1_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ContextDelete()); });
|
|
630
|
+
i0.ɵɵelement(14, "i", 26);
|
|
631
|
+
i0.ɵɵelementStart(15, "span");
|
|
632
|
+
i0.ɵɵtext(16);
|
|
494
633
|
i0.ɵɵelementEnd()();
|
|
495
634
|
} if (rf & 2) {
|
|
496
|
-
const
|
|
635
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
636
|
+
i0.ɵɵconditional(ctx_r1.ContextMenu.targets.length > 1 ? 0 : 1);
|
|
637
|
+
i0.ɵɵadvance(2);
|
|
638
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets));
|
|
639
|
+
i0.ɵɵattribute("title", ctx_r1.CanChangeAny(ctx_r1.ContextMenu.targets) ? null : ctx_r1.ChangeRefusedReason);
|
|
640
|
+
i0.ɵɵadvance(5);
|
|
641
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanShareAny(ctx_r1.ContextMenu.targets));
|
|
642
|
+
i0.ɵɵattribute("title", ctx_r1.CanShareAny(ctx_r1.ContextMenu.targets) ? null : ctx_r1.ShareRefusedReason);
|
|
497
643
|
i0.ɵɵadvance(3);
|
|
498
|
-
i0.ɵɵtextInterpolate(
|
|
499
|
-
} }
|
|
500
|
-
function ConversationListComponent_ng_template_10_Conditional_12_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
501
|
-
i0.ɵɵelementStart(0, "div", 73);
|
|
502
|
-
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_10_Conditional_12_Conditional_3_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
|
|
503
|
-
i0.ɵɵconditionalCreate(1, ConversationListComponent_ng_template_10_Conditional_12_Conditional_3_Conditional_1_Template, 17, 2)(2, ConversationListComponent_ng_template_10_Conditional_12_Conditional_3_Conditional_2_Template, 18, 1);
|
|
504
|
-
i0.ɵɵelementEnd();
|
|
505
|
-
} if (rf & 2) {
|
|
506
|
-
const conversation_r24 = i0.ɵɵnextContext(2).$implicit;
|
|
507
|
-
const ctx_r1 = i0.ɵɵnextContext();
|
|
644
|
+
i0.ɵɵtextInterpolate(ctx_r1.ContextMenu.targets.length > 1 ? "Share " + ctx_r1.ContextMenu.targets.length + " conversations" : "Share");
|
|
508
645
|
i0.ɵɵadvance();
|
|
509
|
-
i0.ɵɵconditional(ctx_r1.
|
|
646
|
+
i0.ɵɵconditional(ctx_r1.ContextMenu.targets.length === 1 ? 11 : -1);
|
|
647
|
+
i0.ɵɵadvance(5);
|
|
648
|
+
i0.ɵɵtextInterpolate(ctx_r1.ContextMenu.targets.length > 1 ? "Delete " + ctx_r1.ContextMenu.targets.length : "Delete");
|
|
510
649
|
} }
|
|
511
|
-
function
|
|
512
|
-
|
|
513
|
-
i0.ɵɵelementStart(0, "div", 67)(1, "button", 70);
|
|
514
|
-
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_10_Conditional_12_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r26); const conversation_r24 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleMenu(conversation_r24.ID, $event)); });
|
|
515
|
-
i0.ɵɵelement(2, "i", 71);
|
|
516
|
-
i0.ɵɵelementEnd();
|
|
517
|
-
i0.ɵɵconditionalCreate(3, ConversationListComponent_ng_template_10_Conditional_12_Conditional_3_Template, 3, 1, "div", 72);
|
|
518
|
-
i0.ɵɵelementEnd();
|
|
650
|
+
function ConversationListComponent_Conditional_13_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
651
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_13_Case_2_Conditional_0_Template, 17, 2)(1, ConversationListComponent_Conditional_13_Case_2_Conditional_1_Template, 17, 8);
|
|
519
652
|
} if (rf & 2) {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
i0.ɵɵadvance(3);
|
|
523
|
-
i0.ɵɵconditional(ctx_r1.IsMenuOpen(conversation_r24) ? 3 : -1);
|
|
653
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
654
|
+
i0.ɵɵconditional(ctx_r1.IsMoveSubmenuOpen ? 0 : 1);
|
|
524
655
|
} }
|
|
525
|
-
function
|
|
526
|
-
const
|
|
527
|
-
i0.ɵɵelementStart(0, "
|
|
528
|
-
i0.ɵɵlistener("
|
|
529
|
-
i0.ɵɵ
|
|
530
|
-
i0.ɵɵelementStart(2, "
|
|
531
|
-
i0.ɵɵ
|
|
532
|
-
i0.ɵɵelementStart(4, "div", 61);
|
|
533
|
-
i0.ɵɵelement(5, "mj-notification-badge", 62);
|
|
656
|
+
function ConversationListComponent_Conditional_13_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
657
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
658
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
659
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_3_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextCreateSubfolder($event)); });
|
|
660
|
+
i0.ɵɵelement(1, "i", 55);
|
|
661
|
+
i0.ɵɵelementStart(2, "span");
|
|
662
|
+
i0.ɵɵtext(3, "New Subfolder");
|
|
534
663
|
i0.ɵɵelementEnd()();
|
|
535
|
-
i0.ɵɵelementStart(
|
|
536
|
-
i0.ɵɵ
|
|
537
|
-
i0.ɵɵ
|
|
538
|
-
i0.ɵɵ
|
|
539
|
-
i0.ɵɵ
|
|
540
|
-
i0.ɵɵ
|
|
664
|
+
i0.ɵɵelementStart(4, "button", 91);
|
|
665
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_3_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextEditFolder($event)); });
|
|
666
|
+
i0.ɵɵelement(5, "i", 102);
|
|
667
|
+
i0.ɵɵelementStart(6, "span");
|
|
668
|
+
i0.ɵɵtext(7, "Rename");
|
|
669
|
+
i0.ɵɵelementEnd()();
|
|
670
|
+
i0.ɵɵelement(8, "div", 89);
|
|
671
|
+
i0.ɵɵelementStart(9, "button", 98);
|
|
672
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_3_Template_button_click_9_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextDeleteFolder($event)); });
|
|
673
|
+
i0.ɵɵelement(10, "i", 26);
|
|
674
|
+
i0.ɵɵelementStart(11, "span");
|
|
675
|
+
i0.ɵɵtext(12, "Delete");
|
|
676
|
+
i0.ɵɵelementEnd()();
|
|
677
|
+
} }
|
|
678
|
+
function ConversationListComponent_Conditional_13_Case_4_Template(rf, ctx) { if (rf & 1) {
|
|
679
|
+
const _r36 = i0.ɵɵgetCurrentView();
|
|
680
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
681
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r36); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextNewConversation()); });
|
|
682
|
+
i0.ɵɵelement(1, "i", 44);
|
|
683
|
+
i0.ɵɵelementStart(2, "span");
|
|
684
|
+
i0.ɵɵtext(3, "New Conversation");
|
|
685
|
+
i0.ɵɵelementEnd()();
|
|
686
|
+
i0.ɵɵelementStart(4, "button", 91);
|
|
687
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_4_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r36); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextCreateRootFolder($event)); });
|
|
688
|
+
i0.ɵɵelement(5, "i", 55);
|
|
689
|
+
i0.ɵɵelementStart(6, "span");
|
|
690
|
+
i0.ɵɵtext(7, "New Folder");
|
|
691
|
+
i0.ɵɵelementEnd()();
|
|
692
|
+
i0.ɵɵelement(8, "div", 89);
|
|
693
|
+
i0.ɵɵelementStart(9, "button", 91);
|
|
694
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Case_4_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r36); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ContextSelectAll()); });
|
|
695
|
+
i0.ɵɵelement(10, "i", 103);
|
|
696
|
+
i0.ɵɵelementStart(11, "span");
|
|
697
|
+
i0.ɵɵtext(12, "Select All");
|
|
541
698
|
i0.ɵɵelementEnd()();
|
|
542
|
-
|
|
699
|
+
} }
|
|
700
|
+
function ConversationListComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
701
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
702
|
+
i0.ɵɵelementStart(0, "div", 86, 3);
|
|
703
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Template_div_click_0_listener($event) { return $event.stopPropagation(); })("contextmenu", function ConversationListComponent_Conditional_13_Template_div_contextmenu_0_listener($event) { i0.ɵɵrestoreView(_r27); $event.preventDefault(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
704
|
+
i0.ɵɵconditionalCreate(2, ConversationListComponent_Conditional_13_Case_2_Template, 2, 1)(3, ConversationListComponent_Conditional_13_Case_3_Template, 13, 0)(4, ConversationListComponent_Conditional_13_Case_4_Template, 13, 0);
|
|
543
705
|
i0.ɵɵelementEnd();
|
|
544
706
|
} if (rf & 2) {
|
|
545
|
-
|
|
546
|
-
const depth_r31 = ctx.depth;
|
|
707
|
+
let tmp_6_0;
|
|
547
708
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
548
|
-
i0.ɵɵstyleProp("
|
|
549
|
-
i0.ɵɵclassProp("active", ctx_r1.IsConversationActive(conversation_r24))("renamed", ctx_r1.IsConversationRenamed(conversation_r24))("dragging", ctx_r1.IsConversationDragging(conversation_r24));
|
|
550
|
-
i0.ɵɵproperty("draggable", !ctx_r1.isSelectionMode);
|
|
551
|
-
i0.ɵɵadvance();
|
|
552
|
-
i0.ɵɵconditional(ctx_r1.isSelectionMode ? 1 : -1);
|
|
553
|
-
i0.ɵɵadvance(2);
|
|
554
|
-
i0.ɵɵconditional(ctx_r1.hasActiveTasks(conversation_r24.ID) ? 3 : -1);
|
|
555
|
-
i0.ɵɵadvance(2);
|
|
556
|
-
i0.ɵɵproperty("conversationId", conversation_r24.ID);
|
|
557
|
-
i0.ɵɵadvance();
|
|
558
|
-
i0.ɵɵproperty("title", conversation_r24.Name + (conversation_r24.Description ? "\n" + conversation_r24.Description : ""));
|
|
559
|
-
i0.ɵɵadvance(2);
|
|
560
|
-
i0.ɵɵtextInterpolate1(" ", conversation_r24.Name, " ");
|
|
561
|
-
i0.ɵɵadvance();
|
|
562
|
-
i0.ɵɵconditional(ctx_r1.isSharedWithMe(conversation_r24) ? 9 : -1);
|
|
709
|
+
i0.ɵɵstyleProp("left", ctx_r1.ContextMenu.x, "px")("top", ctx_r1.ContextMenu.y, "px");
|
|
563
710
|
i0.ɵɵadvance(2);
|
|
564
|
-
i0.ɵɵ
|
|
565
|
-
i0.ɵɵadvance();
|
|
566
|
-
i0.ɵɵconditional(!ctx_r1.isSelectionMode ? 12 : -1);
|
|
711
|
+
i0.ɵɵconditional((tmp_6_0 = ctx_r1.ContextMenu.kind) === "conversation" ? 2 : tmp_6_0 === "folder" ? 3 : 4);
|
|
567
712
|
} }
|
|
713
|
+
/** Resource type the conversation share rows are written against. */
|
|
714
|
+
const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
|
|
568
715
|
export class ConversationListComponent {
|
|
569
716
|
dialogService;
|
|
570
717
|
notificationService;
|
|
571
718
|
activeTasksService;
|
|
572
719
|
mjDialogService;
|
|
573
720
|
cdr;
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
721
|
+
EnvironmentId;
|
|
722
|
+
CurrentUser;
|
|
723
|
+
SelectedConversationId = null;
|
|
724
|
+
RenamedConversationId = null;
|
|
725
|
+
IsSidebarPinned = true; // Whether sidebar is pinned (stays open after selection)
|
|
726
|
+
IsMobileView = false; // Whether we're on mobile (no pin options)
|
|
580
727
|
// ── White-label chrome toggles (all default true = stock rendering) ──
|
|
581
728
|
/** Show the search box in the list header. Flipping to false clears any active
|
|
582
729
|
* search so a hidden filter can't keep silently narrowing the list. */
|
|
583
730
|
set showSearch(value) {
|
|
584
731
|
if (!value && this._searchQuery) {
|
|
585
|
-
this.
|
|
732
|
+
this.SearchQuery = ''; // setter rebuilds the groupings
|
|
586
733
|
}
|
|
587
734
|
this._showSearch = value;
|
|
588
735
|
}
|
|
@@ -591,50 +738,140 @@ export class ConversationListComponent {
|
|
|
591
738
|
}
|
|
592
739
|
_showSearch = true;
|
|
593
740
|
/** Show the "New Conversation" button. */
|
|
594
|
-
|
|
741
|
+
ShowNewConversationButton = true;
|
|
595
742
|
/** Show the ⋯ header options menu (refresh / select / group-by / hide sidebar). */
|
|
596
|
-
|
|
743
|
+
ShowHeaderMenu = true;
|
|
597
744
|
/** Show the collapsible Pinned / Folders / Messages section headers. When false,
|
|
598
745
|
* the list renders FLAT and fully expanded: folder grouping is bypassed (the
|
|
599
746
|
* folder tree's root drop-zone and New Folder action live in the section
|
|
600
747
|
* header, so a headerless tree would allow one-way folder nesting) — the
|
|
601
748
|
* chrome-less rendering for embedded hosts. */
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
749
|
+
ShowSectionHeaders = true;
|
|
750
|
+
ConversationSelected = new EventEmitter();
|
|
751
|
+
/**
|
|
752
|
+
* @deprecated Use {@link ConversationSelected}.
|
|
753
|
+
*
|
|
754
|
+
* The same emitter under the old binding name, so a template still binding
|
|
755
|
+
* (conversationSelected) keeps working. Must stay AFTER ConversationSelected: class fields
|
|
756
|
+
* initialise in order, and the other way round this captures undefined.
|
|
757
|
+
*/
|
|
758
|
+
conversationSelected = this.ConversationSelected;
|
|
759
|
+
ConversationDeleted = new EventEmitter(); // Emits the deleted conversation ID
|
|
760
|
+
/**
|
|
761
|
+
* @deprecated Use {@link ConversationDeleted}.
|
|
762
|
+
*
|
|
763
|
+
* The same emitter under the old binding name, so a template still binding
|
|
764
|
+
* (conversationDeleted) keeps working. Must stay AFTER ConversationDeleted: class fields
|
|
765
|
+
* initialise in order, and the other way round this captures undefined.
|
|
766
|
+
*/
|
|
767
|
+
conversationDeleted = this.ConversationDeleted; // Emits the deleted conversation ID
|
|
768
|
+
NewConversationRequested = new EventEmitter();
|
|
769
|
+
/**
|
|
770
|
+
* @deprecated Use {@link NewConversationRequested}.
|
|
771
|
+
*
|
|
772
|
+
* The same emitter under the old binding name, so a template still binding
|
|
773
|
+
* (newConversationRequested) keeps working. Must stay AFTER NewConversationRequested: class fields
|
|
774
|
+
* initialise in order, and the other way round this captures undefined.
|
|
775
|
+
*/
|
|
776
|
+
newConversationRequested = this.NewConversationRequested;
|
|
777
|
+
PinSidebarRequested = new EventEmitter(); // Request to pin sidebar
|
|
778
|
+
/**
|
|
779
|
+
* @deprecated Use {@link PinSidebarRequested}.
|
|
780
|
+
*
|
|
781
|
+
* The same emitter under the old binding name, so a template still binding
|
|
782
|
+
* (pinSidebarRequested) keeps working. Must stay AFTER PinSidebarRequested: class fields
|
|
783
|
+
* initialise in order, and the other way round this captures undefined.
|
|
784
|
+
*/
|
|
785
|
+
pinSidebarRequested = this.PinSidebarRequested; // Request to pin sidebar
|
|
786
|
+
UnpinSidebarRequested = new EventEmitter(); // Request to unpin (collapse) sidebar
|
|
787
|
+
/**
|
|
788
|
+
* @deprecated Use {@link UnpinSidebarRequested}.
|
|
789
|
+
*
|
|
790
|
+
* The same emitter under the old binding name, so a template still binding
|
|
791
|
+
* (unpinSidebarRequested) keeps working. Must stay AFTER UnpinSidebarRequested: class fields
|
|
792
|
+
* initialise in order, and the other way round this captures undefined.
|
|
793
|
+
*/
|
|
794
|
+
unpinSidebarRequested = this.UnpinSidebarRequested; // Request to unpin (collapse) sidebar
|
|
795
|
+
RefreshRequested = new EventEmitter(); // Emitted after list refresh so chat area can also reload
|
|
796
|
+
/**
|
|
797
|
+
* @deprecated Use {@link RefreshRequested}.
|
|
798
|
+
*
|
|
799
|
+
* The same emitter under the old binding name, so a template still binding
|
|
800
|
+
* (refreshRequested) keeps working. Must stay AFTER RefreshRequested: class fields
|
|
801
|
+
* initialise in order, and the other way round this captures undefined.
|
|
802
|
+
*/
|
|
803
|
+
refreshRequested = this.RefreshRequested; // Emitted after list refresh so chat area can also reload
|
|
804
|
+
/**
|
|
805
|
+
* The user wants the current filter term searched across all of Chat, not just this list.
|
|
806
|
+
* Emits the term. This panel filters only loaded conversations by Name/Description, so it
|
|
807
|
+
* cannot answer "where did we discuss X" — the host owns that surface and the routing to it.
|
|
808
|
+
*/
|
|
809
|
+
SearchEscalated = new EventEmitter();
|
|
810
|
+
DirectMessagesExpanded = true;
|
|
811
|
+
PinnedExpanded = true;
|
|
812
|
+
FoldersExpanded = true;
|
|
813
|
+
UngroupedExpanded = true;
|
|
814
|
+
/** The open right-click menu, or null. Positioned at the pointer. */
|
|
815
|
+
ContextMenu = null;
|
|
816
|
+
/** True while the open conversation menu is showing its folder picker. */
|
|
817
|
+
IsMoveSubmenuOpen = false;
|
|
818
|
+
/** Resources the share dialog is currently offering, one per conversation. */
|
|
819
|
+
ShareContexts = [];
|
|
820
|
+
ShareNotice = null;
|
|
821
|
+
IsShareDialogOpen = false;
|
|
822
|
+
ShareAdapter = new MJResourcePermissionShareAdapter(CONVERSATIONS_RESOURCE_TYPE_ID);
|
|
823
|
+
ConversationIdsWithTasks = new Set();
|
|
824
|
+
IsSelectionMode = false;
|
|
825
|
+
SelectedConversationIds = new Set();
|
|
826
|
+
/** Row a Shift-click ranges from — the last row picked without Shift. */
|
|
827
|
+
selectionAnchorId = null;
|
|
828
|
+
/** Why Share is unavailable, shown on its disabled button. */
|
|
829
|
+
ShareRefusedReason = 'Only the owner, or someone with Owner access, can share a conversation';
|
|
830
|
+
/** Why Move and Pin are unavailable, shown on their disabled buttons. */
|
|
831
|
+
ChangeRefusedReason = 'You need Edit access to move or pin a conversation shared with you';
|
|
832
|
+
/** How long a touch must rest on a row before it selects the row. */
|
|
833
|
+
static longPressDelayMs = 500;
|
|
834
|
+
/** How far a touch may drift, in pixels, before it counts as a scroll rather than a press. */
|
|
835
|
+
static longPressMoveTolerancePx = 10;
|
|
836
|
+
/** Space kept between the right-click menu and the edges of the window. */
|
|
837
|
+
static menuViewportMargin = 8;
|
|
838
|
+
/** The touch press waiting to become a long-press, or null. */
|
|
839
|
+
longPress = null;
|
|
840
|
+
/** Pointer type of the latest press on a row. On touch, a tap while selecting toggles the row. */
|
|
841
|
+
lastRowPointerType = 'mouse';
|
|
842
|
+
/** Set by a completed long-press, so the click that ends the same press does nothing. */
|
|
843
|
+
ignoreNextRowClick = false;
|
|
844
|
+
IsHeaderMenuOpen = false;
|
|
845
|
+
IsRefreshing = false;
|
|
846
|
+
searchInput;
|
|
847
|
+
contextMenuEl;
|
|
619
848
|
/** UserInfoEngine key for persisting folder collapse state + group-by mode. */
|
|
620
|
-
static
|
|
849
|
+
static folderPrefsKey = 'mj.conversations.folderPrefs.v1';
|
|
621
850
|
/** How the conversation list is grouped. 'project' = folders, 'none' = flat list. */
|
|
622
|
-
|
|
851
|
+
GroupBy = 'project';
|
|
852
|
+
/** Field every section of the list is sorted on. */
|
|
853
|
+
SortBy = 'date';
|
|
854
|
+
/** Direction of the current sort. */
|
|
855
|
+
SortDirection = 'desc';
|
|
856
|
+
/** Direction each field falls back to when it becomes the active sort. */
|
|
857
|
+
static defaultSortDirections = {
|
|
858
|
+
date: 'desc',
|
|
859
|
+
name: 'asc'
|
|
860
|
+
};
|
|
623
861
|
/** Precomputed groupings, rebuilt whenever conversations/projects/search change. */
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
862
|
+
PinnedConversations = [];
|
|
863
|
+
UnpinnedConversations = [];
|
|
864
|
+
UngroupedConversations = [];
|
|
865
|
+
FolderTree = [];
|
|
628
866
|
/** Flattened folder list (depth-ordered) for the "Move to folder" menu. */
|
|
629
|
-
|
|
867
|
+
FlatFolders = [];
|
|
630
868
|
/** Folder IDs (normalized) whose children are collapsed. Absent = expanded. */
|
|
631
869
|
collapsedFolderIds = new Set();
|
|
632
870
|
/** Drag-and-drop state. */
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
moveSubmenuConversationId = null;
|
|
871
|
+
/** Conversations currently being dragged — the whole selection when the grabbed row is part of it. */
|
|
872
|
+
DraggedConversationIds = [];
|
|
873
|
+
DraggedFolderId = null;
|
|
874
|
+
DragOverTargetId = null;
|
|
638
875
|
_searchQuery = '';
|
|
639
876
|
destroy$ = new Subject();
|
|
640
877
|
engine = ConversationEngine.Instance;
|
|
@@ -647,23 +884,36 @@ export class ConversationListComponent {
|
|
|
647
884
|
this.mjDialogService = mjDialogService;
|
|
648
885
|
this.cdr = cdr;
|
|
649
886
|
}
|
|
650
|
-
get
|
|
887
|
+
get SearchQuery() {
|
|
651
888
|
return this._searchQuery;
|
|
652
889
|
}
|
|
653
|
-
set
|
|
890
|
+
set SearchQuery(value) {
|
|
654
891
|
this._searchQuery = value ?? '';
|
|
655
892
|
this.rebuildGroups();
|
|
893
|
+
this.dropHiddenRowsFromSelection();
|
|
656
894
|
}
|
|
657
895
|
/** True when a search filter is active. */
|
|
658
|
-
get
|
|
896
|
+
get IsSearching() {
|
|
659
897
|
return this._searchQuery.trim().length > 0;
|
|
660
898
|
}
|
|
661
|
-
/**
|
|
662
|
-
|
|
663
|
-
|
|
899
|
+
/** Hand the current filter term to the host to search across every Chat entity. */
|
|
900
|
+
EscalateSearch() {
|
|
901
|
+
this.SearchEscalated.emit(this._searchQuery.trim());
|
|
902
|
+
}
|
|
903
|
+
/** Clears the search box and returns focus to it. */
|
|
904
|
+
ClearSearch() {
|
|
905
|
+
this.SearchQuery = '';
|
|
906
|
+
this.searchInput?.nativeElement.focus();
|
|
907
|
+
}
|
|
908
|
+
/** Escape in the search box clears it without closing any host overlay. */
|
|
909
|
+
OnSearchKeydown(event) {
|
|
910
|
+
if (event.key === 'Escape' && this.IsSearching) {
|
|
911
|
+
event.stopPropagation();
|
|
912
|
+
this.ClearSearch();
|
|
913
|
+
}
|
|
664
914
|
}
|
|
665
915
|
filterConversations(conversations) {
|
|
666
|
-
if (!this.
|
|
916
|
+
if (!this.IsSearching) {
|
|
667
917
|
return conversations;
|
|
668
918
|
}
|
|
669
919
|
const lowerQuery = this._searchQuery.toLowerCase();
|
|
@@ -674,94 +924,106 @@ export class ConversationListComponent {
|
|
|
674
924
|
// Restore persisted folder collapse state + group-by preference
|
|
675
925
|
this.loadFolderPrefs();
|
|
676
926
|
// Load conversations (and folders) on init
|
|
677
|
-
this.engine.LoadConversations(this.
|
|
927
|
+
this.engine.LoadConversations(this.EnvironmentId, this.CurrentUser, false);
|
|
678
928
|
// Rebuild the precomputed groupings whenever conversations OR projects change
|
|
679
929
|
// (pin, archive, rename, move-to-folder, folder create/rename/delete, etc.).
|
|
680
|
-
this.engine.Conversations$.pipe(takeUntil(this.destroy$)).subscribe(() =>
|
|
681
|
-
this.rebuildGroups();
|
|
682
|
-
this.cdr.detectChanges();
|
|
683
|
-
});
|
|
930
|
+
this.engine.Conversations$.pipe(takeUntil(this.destroy$)).subscribe(() => this.onConversationListChanged());
|
|
684
931
|
this.engine.Projects$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
685
932
|
this.rebuildGroups();
|
|
686
933
|
this.cdr.detectChanges();
|
|
687
934
|
});
|
|
688
935
|
// Subscribe to conversation IDs with active tasks (hot set)
|
|
689
936
|
this.activeTasksService.conversationIdsWithTasks$.pipe(takeUntil(this.destroy$)).subscribe(conversationIds => {
|
|
690
|
-
this.
|
|
937
|
+
this.ConversationIdsWithTasks = conversationIds;
|
|
691
938
|
this.cdr.detectChanges(); // Force change detection to ensure spinner icons update reliably
|
|
692
939
|
});
|
|
693
940
|
}
|
|
694
941
|
ngOnDestroy() {
|
|
942
|
+
this.CancelLongPress();
|
|
695
943
|
this.destroy$.next();
|
|
696
944
|
this.destroy$.complete();
|
|
697
945
|
}
|
|
946
|
+
/** Rebuilds the groupings from the engine's list, first dropping selected conversations that left it. */
|
|
947
|
+
onConversationListChanged() {
|
|
948
|
+
this.dropRemovedConversationsFromSelection();
|
|
949
|
+
this.rebuildGroups();
|
|
950
|
+
this.cdr.detectChanges();
|
|
951
|
+
}
|
|
698
952
|
onDocumentClick() {
|
|
699
953
|
// Close menus when clicking outside
|
|
700
|
-
if (this.
|
|
701
|
-
this.
|
|
954
|
+
if (this.ContextMenu) {
|
|
955
|
+
this.CloseContextMenu();
|
|
702
956
|
}
|
|
703
|
-
if (this.
|
|
704
|
-
this.
|
|
957
|
+
if (this.IsHeaderMenuOpen) {
|
|
958
|
+
this.CloseHeaderMenu();
|
|
705
959
|
}
|
|
706
960
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
this.
|
|
961
|
+
onDocumentEscape() {
|
|
962
|
+
if (this.ContextMenu) {
|
|
963
|
+
this.CloseContextMenu();
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if (this.IsSelectionMode) {
|
|
967
|
+
this.exitSelectionMode();
|
|
968
|
+
}
|
|
713
969
|
}
|
|
714
|
-
|
|
970
|
+
ToggleHeaderMenu(event) {
|
|
715
971
|
event.stopPropagation();
|
|
716
|
-
this.
|
|
717
|
-
this.closeHeaderMenu();
|
|
972
|
+
this.IsHeaderMenuOpen = !this.IsHeaderMenuOpen;
|
|
718
973
|
}
|
|
719
|
-
|
|
974
|
+
CloseHeaderMenu() {
|
|
975
|
+
this.IsHeaderMenuOpen = false;
|
|
976
|
+
}
|
|
977
|
+
OnToggleGroupByClick(event) {
|
|
720
978
|
event.stopPropagation();
|
|
721
|
-
this.
|
|
722
|
-
this.
|
|
979
|
+
this.ToggleGroupBy();
|
|
980
|
+
this.CloseHeaderMenu();
|
|
723
981
|
}
|
|
724
|
-
async
|
|
982
|
+
async OnRefreshConversationsClick(event) {
|
|
725
983
|
event.stopPropagation();
|
|
726
|
-
if (this.
|
|
984
|
+
if (this.IsRefreshing)
|
|
727
985
|
return;
|
|
728
|
-
this.
|
|
986
|
+
this.IsRefreshing = true;
|
|
729
987
|
try {
|
|
730
|
-
await this.engine.LoadConversations(this.
|
|
988
|
+
await this.engine.LoadConversations(this.EnvironmentId, this.CurrentUser, true);
|
|
731
989
|
// Signal parent to also reload messages in the active conversation
|
|
732
|
-
this.
|
|
990
|
+
this.RefreshRequested.emit();
|
|
733
991
|
}
|
|
734
992
|
catch (error) {
|
|
735
993
|
console.error('Error refreshing conversations:', error);
|
|
736
994
|
await this.dialogService.alert('Error', 'Failed to refresh conversations. Please try again.');
|
|
737
995
|
}
|
|
738
996
|
finally {
|
|
739
|
-
this.
|
|
997
|
+
this.IsRefreshing = false;
|
|
740
998
|
this.cdr.detectChanges();
|
|
741
|
-
this.
|
|
999
|
+
this.CloseHeaderMenu();
|
|
742
1000
|
}
|
|
743
1001
|
}
|
|
744
|
-
|
|
1002
|
+
OnPinSidebarClick(event) {
|
|
745
1003
|
event.stopPropagation();
|
|
746
|
-
this.
|
|
747
|
-
this.
|
|
1004
|
+
this.CloseHeaderMenu();
|
|
1005
|
+
this.PinSidebarRequested.emit();
|
|
748
1006
|
}
|
|
749
|
-
|
|
1007
|
+
OnUnpinSidebarClick(event) {
|
|
750
1008
|
event.stopPropagation();
|
|
751
|
-
this.
|
|
752
|
-
this.
|
|
1009
|
+
this.CloseHeaderMenu();
|
|
1010
|
+
this.UnpinSidebarRequested.emit();
|
|
753
1011
|
}
|
|
754
|
-
|
|
755
|
-
this.
|
|
1012
|
+
ToggleDirectMessages() {
|
|
1013
|
+
this.DirectMessagesExpanded = !this.DirectMessagesExpanded;
|
|
1014
|
+
this.dropHiddenRowsFromSelection();
|
|
756
1015
|
}
|
|
757
|
-
|
|
758
|
-
this.
|
|
1016
|
+
TogglePinned() {
|
|
1017
|
+
this.PinnedExpanded = !this.PinnedExpanded;
|
|
1018
|
+
this.dropHiddenRowsFromSelection();
|
|
759
1019
|
}
|
|
760
|
-
|
|
761
|
-
this.
|
|
1020
|
+
ToggleFolders() {
|
|
1021
|
+
this.FoldersExpanded = !this.FoldersExpanded;
|
|
1022
|
+
this.dropHiddenRowsFromSelection();
|
|
762
1023
|
}
|
|
763
|
-
|
|
764
|
-
this.
|
|
1024
|
+
ToggleUngrouped() {
|
|
1025
|
+
this.UngroupedExpanded = !this.UngroupedExpanded;
|
|
1026
|
+
this.dropHiddenRowsFromSelection();
|
|
765
1027
|
}
|
|
766
1028
|
// ========================================================================
|
|
767
1029
|
// FOLDER GROUPING
|
|
@@ -770,17 +1032,71 @@ export class ConversationListComponent {
|
|
|
770
1032
|
* Recomputes pinned/unpinned/ungrouped lists and the folder tree from the
|
|
771
1033
|
* engine's conversation + project caches and the current search filter.
|
|
772
1034
|
*/
|
|
1035
|
+
/**
|
|
1036
|
+
* Makes `field` the active sort. Choosing the field that is already active
|
|
1037
|
+
* flips the direction; switching fields starts from that field's natural
|
|
1038
|
+
* direction (newest first for date, A-Z for name).
|
|
1039
|
+
*/
|
|
1040
|
+
SetSort(field) {
|
|
1041
|
+
if (this.SortBy === field) {
|
|
1042
|
+
this.SortDirection = this.SortDirection === 'asc' ? 'desc' : 'asc';
|
|
1043
|
+
}
|
|
1044
|
+
else {
|
|
1045
|
+
this.SortBy = field;
|
|
1046
|
+
this.SortDirection = ConversationListComponent.defaultSortDirections[field];
|
|
1047
|
+
}
|
|
1048
|
+
this.saveFolderPrefs();
|
|
1049
|
+
this.rebuildGroups();
|
|
1050
|
+
}
|
|
1051
|
+
/** Icon for a sort button: direction arrow when active, plain field icon otherwise. */
|
|
1052
|
+
SortIcon(field) {
|
|
1053
|
+
if (this.SortBy !== field) {
|
|
1054
|
+
return field === 'date' ? 'fa-clock' : 'fa-font';
|
|
1055
|
+
}
|
|
1056
|
+
if (field === 'date') {
|
|
1057
|
+
return this.SortDirection === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1';
|
|
1058
|
+
}
|
|
1059
|
+
return this.SortDirection === 'asc' ? 'fa-arrow-up-a-z' : 'fa-arrow-down-z-a';
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Orders conversations by the active sort. Returns a new array so the caller's
|
|
1063
|
+
* source list is never mutated. Conversations with no name sort last.
|
|
1064
|
+
*/
|
|
1065
|
+
sortConversations(conversations) {
|
|
1066
|
+
const factor = this.SortDirection === 'asc' ? 1 : -1;
|
|
1067
|
+
return [...conversations].sort((a, b) => {
|
|
1068
|
+
if (this.SortBy === 'name') {
|
|
1069
|
+
const aName = a.Name?.trim() ?? '';
|
|
1070
|
+
const bName = b.Name?.trim() ?? '';
|
|
1071
|
+
if (!aName || !bName) {
|
|
1072
|
+
return aName === bName ? 0 : (aName ? -1 : 1);
|
|
1073
|
+
}
|
|
1074
|
+
return aName.localeCompare(bName, undefined, { sensitivity: 'base' }) * factor;
|
|
1075
|
+
}
|
|
1076
|
+
return (this.updatedTime(a) - this.updatedTime(b)) * factor;
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
/** Position of a conversation in a rendered-order list, or -1. Case-insensitive on the ID. */
|
|
1080
|
+
indexOfConversation(order, conversationId) {
|
|
1081
|
+
if (!conversationId)
|
|
1082
|
+
return -1;
|
|
1083
|
+
return order.findIndex(id => UUIDsEqual(id, conversationId));
|
|
1084
|
+
}
|
|
1085
|
+
updatedTime(conversation) {
|
|
1086
|
+
const updatedAt = conversation.__mj_UpdatedAt;
|
|
1087
|
+
return updatedAt ? new Date(updatedAt).getTime() : 0;
|
|
1088
|
+
}
|
|
773
1089
|
rebuildGroups() {
|
|
774
|
-
const matching = this.filterConversations(this.engine.Conversations);
|
|
775
|
-
this.
|
|
776
|
-
this.
|
|
1090
|
+
const matching = this.sortConversations(this.filterConversations(this.engine.Conversations));
|
|
1091
|
+
this.PinnedConversations = matching.filter(c => c.IsPinned);
|
|
1092
|
+
this.UnpinnedConversations = matching.filter(c => !c.IsPinned);
|
|
777
1093
|
const projects = this.engine.Projects;
|
|
778
1094
|
const projectIds = new Set(projects.map(p => NormalizeUUID(p.ID)));
|
|
779
1095
|
// Bucket unpinned conversations by their folder (pinned ones live in the
|
|
780
1096
|
// Pinned section). Conversations with no/unknown folder are "ungrouped".
|
|
781
1097
|
const conversationsByProject = new Map();
|
|
782
1098
|
const ungrouped = [];
|
|
783
|
-
for (const c of this.
|
|
1099
|
+
for (const c of this.UnpinnedConversations) {
|
|
784
1100
|
const pid = c.ProjectID ? NormalizeUUID(c.ProjectID) : null;
|
|
785
1101
|
if (pid && projectIds.has(pid)) {
|
|
786
1102
|
const arr = conversationsByProject.get(pid) ?? [];
|
|
@@ -791,7 +1107,7 @@ export class ConversationListComponent {
|
|
|
791
1107
|
ungrouped.push(c);
|
|
792
1108
|
}
|
|
793
1109
|
}
|
|
794
|
-
this.
|
|
1110
|
+
this.UngroupedConversations = ungrouped;
|
|
795
1111
|
// Index projects by parent. A project whose parent isn't loaded is treated
|
|
796
1112
|
// as a root so it never disappears from the tree.
|
|
797
1113
|
const childrenByParent = new Map();
|
|
@@ -812,8 +1128,8 @@ export class ConversationListComponent {
|
|
|
812
1128
|
return { project: p, depth, conversations, children, totalCount, hasContent };
|
|
813
1129
|
});
|
|
814
1130
|
};
|
|
815
|
-
this.
|
|
816
|
-
this.
|
|
1131
|
+
this.FolderTree = build(null, 0);
|
|
1132
|
+
this.FlatFolders = this.flattenFolders(this.FolderTree);
|
|
817
1133
|
}
|
|
818
1134
|
flattenFolders(nodes) {
|
|
819
1135
|
const out = [];
|
|
@@ -833,10 +1149,10 @@ export class ConversationListComponent {
|
|
|
833
1149
|
}
|
|
834
1150
|
return null;
|
|
835
1151
|
}
|
|
836
|
-
|
|
1152
|
+
IsFolderExpanded(projectId) {
|
|
837
1153
|
return !this.collapsedFolderIds.has(NormalizeUUID(projectId));
|
|
838
1154
|
}
|
|
839
|
-
|
|
1155
|
+
ToggleFolder(projectId) {
|
|
840
1156
|
const key = NormalizeUUID(projectId);
|
|
841
1157
|
if (this.collapsedFolderIds.has(key)) {
|
|
842
1158
|
this.collapsedFolderIds.delete(key);
|
|
@@ -845,21 +1161,29 @@ export class ConversationListComponent {
|
|
|
845
1161
|
this.collapsedFolderIds.add(key);
|
|
846
1162
|
}
|
|
847
1163
|
this.saveFolderPrefs();
|
|
1164
|
+
this.dropHiddenRowsFromSelection();
|
|
848
1165
|
}
|
|
849
|
-
|
|
850
|
-
this.
|
|
1166
|
+
ToggleGroupBy() {
|
|
1167
|
+
this.GroupBy = this.GroupBy === 'project' ? 'none' : 'project';
|
|
851
1168
|
this.saveFolderPrefs();
|
|
852
1169
|
this.rebuildGroups();
|
|
1170
|
+
this.dropHiddenRowsFromSelection();
|
|
853
1171
|
}
|
|
854
1172
|
loadFolderPrefs() {
|
|
855
1173
|
try {
|
|
856
|
-
const raw = UserInfoEngine.Instance.GetSetting(ConversationListComponent.
|
|
1174
|
+
const raw = UserInfoEngine.Instance.GetSetting(ConversationListComponent.folderPrefsKey);
|
|
857
1175
|
if (!raw)
|
|
858
1176
|
return;
|
|
859
1177
|
const parsed = JSON.parse(raw);
|
|
860
1178
|
this.collapsedFolderIds = new Set((parsed.collapsed ?? []).map(id => NormalizeUUID(id)));
|
|
861
1179
|
if (parsed.groupBy === 'none' || parsed.groupBy === 'project') {
|
|
862
|
-
this.
|
|
1180
|
+
this.GroupBy = parsed.groupBy;
|
|
1181
|
+
}
|
|
1182
|
+
if (parsed.sortBy === 'date' || parsed.sortBy === 'name') {
|
|
1183
|
+
this.SortBy = parsed.sortBy;
|
|
1184
|
+
}
|
|
1185
|
+
if (parsed.sortDirection === 'asc' || parsed.sortDirection === 'desc') {
|
|
1186
|
+
this.SortDirection = parsed.sortDirection;
|
|
863
1187
|
}
|
|
864
1188
|
}
|
|
865
1189
|
catch {
|
|
@@ -869,46 +1193,59 @@ export class ConversationListComponent {
|
|
|
869
1193
|
saveFolderPrefs() {
|
|
870
1194
|
const payload = JSON.stringify({
|
|
871
1195
|
collapsed: Array.from(this.collapsedFolderIds),
|
|
872
|
-
groupBy: this.
|
|
1196
|
+
groupBy: this.GroupBy,
|
|
1197
|
+
sortBy: this.SortBy,
|
|
1198
|
+
sortDirection: this.SortDirection
|
|
873
1199
|
});
|
|
874
|
-
UserInfoEngine.Instance.SetSettingDebounced(ConversationListComponent.
|
|
1200
|
+
UserInfoEngine.Instance.SetSettingDebounced(ConversationListComponent.folderPrefsKey, payload);
|
|
875
1201
|
}
|
|
876
1202
|
// ========================================================================
|
|
877
1203
|
// DRAG & DROP (move conversation into/out of a folder)
|
|
878
1204
|
// ========================================================================
|
|
879
|
-
|
|
880
|
-
|
|
1205
|
+
/**
|
|
1206
|
+
* Starts a conversation drag. Grabbing a row that is part of the current
|
|
1207
|
+
* selection drags the whole selection; grabbing any other row drags that row
|
|
1208
|
+
* alone and leaves the selection untouched. A touch press that lifts the row
|
|
1209
|
+
* selects it instead, since on touch a long-press means select.
|
|
1210
|
+
*/
|
|
1211
|
+
OnConversationDragStart(conversation, event) {
|
|
1212
|
+
if (this.lastRowPointerType === 'touch') {
|
|
1213
|
+
event.preventDefault();
|
|
1214
|
+
this.completeLongPress();
|
|
881
1215
|
return;
|
|
882
|
-
|
|
883
|
-
this.
|
|
1216
|
+
}
|
|
1217
|
+
this.DraggedFolderId = null;
|
|
1218
|
+
this.DraggedConversationIds = this.SelectedConversationIds.has(conversation.ID)
|
|
1219
|
+
? Array.from(this.SelectedConversationIds)
|
|
1220
|
+
: [conversation.ID];
|
|
884
1221
|
if (event.dataTransfer) {
|
|
885
1222
|
event.dataTransfer.effectAllowed = 'move';
|
|
886
|
-
event.dataTransfer.setData('text/plain',
|
|
1223
|
+
event.dataTransfer.setData('text/plain', this.DraggedConversationIds.join(','));
|
|
887
1224
|
}
|
|
888
1225
|
}
|
|
889
|
-
|
|
890
|
-
this.
|
|
891
|
-
this.
|
|
1226
|
+
OnConversationDragEnd() {
|
|
1227
|
+
this.DraggedConversationIds = [];
|
|
1228
|
+
this.DragOverTargetId = null;
|
|
892
1229
|
}
|
|
893
|
-
|
|
1230
|
+
OnFolderDragStart(node, event) {
|
|
894
1231
|
event.stopPropagation();
|
|
895
|
-
this.
|
|
896
|
-
this.
|
|
1232
|
+
this.DraggedConversationIds = [];
|
|
1233
|
+
this.DraggedFolderId = node.project.ID;
|
|
897
1234
|
if (event.dataTransfer) {
|
|
898
1235
|
event.dataTransfer.effectAllowed = 'move';
|
|
899
1236
|
event.dataTransfer.setData('text/plain', node.project.ID);
|
|
900
1237
|
}
|
|
901
1238
|
}
|
|
902
|
-
|
|
903
|
-
this.
|
|
904
|
-
this.
|
|
1239
|
+
OnFolderDragEnd() {
|
|
1240
|
+
this.DraggedFolderId = null;
|
|
1241
|
+
this.DragOverTargetId = null;
|
|
905
1242
|
}
|
|
906
|
-
|
|
1243
|
+
OnFolderDragOver(projectId, event) {
|
|
907
1244
|
// A conversation can drop onto any folder; a folder can drop onto any folder
|
|
908
1245
|
// that isn't itself or one of its own descendants (which would create a cycle).
|
|
909
|
-
const accepts = this.
|
|
1246
|
+
const accepts = this.DraggedConversationIds.length > 0
|
|
910
1247
|
? true
|
|
911
|
-
: this.
|
|
1248
|
+
: this.DraggedFolderId
|
|
912
1249
|
? this.isValidFolderDropTarget(projectId)
|
|
913
1250
|
: false;
|
|
914
1251
|
if (!accepts)
|
|
@@ -916,58 +1253,95 @@ export class ConversationListComponent {
|
|
|
916
1253
|
event.preventDefault();
|
|
917
1254
|
if (event.dataTransfer)
|
|
918
1255
|
event.dataTransfer.dropEffect = 'move';
|
|
919
|
-
this.
|
|
1256
|
+
this.DragOverTargetId = projectId;
|
|
920
1257
|
}
|
|
921
|
-
|
|
922
|
-
|
|
1258
|
+
/**
|
|
1259
|
+
* Drop target id for a conversation row: its folder, or the Ungrouped section
|
|
1260
|
+
* when it has none. Resolved through the folder tree so the highlight matches
|
|
1261
|
+
* the folder row's own ID regardless of how the conversation stores it.
|
|
1262
|
+
*/
|
|
1263
|
+
ConversationDropTargetId(conversation) {
|
|
1264
|
+
if (!conversation.ProjectID)
|
|
1265
|
+
return 'ungrouped';
|
|
1266
|
+
const node = this.FlatFolders.find(f => UUIDsEqual(f.project.ID, conversation.ProjectID));
|
|
1267
|
+
return node ? node.project.ID : 'ungrouped';
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* A conversation row accepts a conversation drag and stands in for its folder,
|
|
1271
|
+
* so dropping onto the rows inside a folder files the drag there too. A row
|
|
1272
|
+
* that is part of the drag itself is not a target.
|
|
1273
|
+
*/
|
|
1274
|
+
OnConversationRowDragOver(conversation, event) {
|
|
1275
|
+
if (this.DraggedConversationIds.length === 0)
|
|
1276
|
+
return;
|
|
1277
|
+
if (this.DraggedConversationIds.some(id => UUIDsEqual(id, conversation.ID)))
|
|
923
1278
|
return;
|
|
924
1279
|
event.preventDefault();
|
|
1280
|
+
event.stopPropagation();
|
|
925
1281
|
if (event.dataTransfer)
|
|
926
1282
|
event.dataTransfer.dropEffect = 'move';
|
|
927
|
-
this.
|
|
1283
|
+
this.DragOverTargetId = this.ConversationDropTargetId(conversation);
|
|
928
1284
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1285
|
+
async OnConversationRowDrop(conversation, event) {
|
|
1286
|
+
event.preventDefault();
|
|
1287
|
+
event.stopPropagation();
|
|
1288
|
+
const conversationIds = this.DraggedConversationIds.filter(id => !UUIDsEqual(id, conversation.ID));
|
|
1289
|
+
this.DragOverTargetId = null;
|
|
1290
|
+
this.DraggedConversationIds = [];
|
|
1291
|
+
if (conversationIds.length > 0) {
|
|
1292
|
+
await this.moveConversations(conversationIds, conversation.ProjectID ?? null);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
OnUngroupedDragOver(event) {
|
|
1296
|
+
if (this.DraggedConversationIds.length === 0)
|
|
1297
|
+
return;
|
|
933
1298
|
event.preventDefault();
|
|
934
1299
|
if (event.dataTransfer)
|
|
935
1300
|
event.dataTransfer.dropEffect = 'move';
|
|
936
|
-
this.
|
|
1301
|
+
this.DragOverTargetId = 'ungrouped';
|
|
937
1302
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1303
|
+
/** The Folders section header accepts a dragged folder to move it back to the top level. */
|
|
1304
|
+
OnFoldersRootDragOver(event) {
|
|
1305
|
+
if (!this.DraggedFolderId)
|
|
1306
|
+
return;
|
|
1307
|
+
event.preventDefault();
|
|
1308
|
+
if (event.dataTransfer)
|
|
1309
|
+
event.dataTransfer.dropEffect = 'move';
|
|
1310
|
+
this.DragOverTargetId = 'folders-root';
|
|
1311
|
+
}
|
|
1312
|
+
OnDragLeave(targetId) {
|
|
1313
|
+
if (this.DragOverTargetId === targetId) {
|
|
1314
|
+
this.DragOverTargetId = null;
|
|
941
1315
|
}
|
|
942
1316
|
}
|
|
943
|
-
|
|
1317
|
+
async OnFolderDrop(project, event) {
|
|
944
1318
|
event.preventDefault();
|
|
945
|
-
const
|
|
946
|
-
const folderId = this.
|
|
947
|
-
this.
|
|
948
|
-
this.
|
|
949
|
-
this.
|
|
950
|
-
if (
|
|
951
|
-
this.
|
|
1319
|
+
const conversationIds = this.DraggedConversationIds;
|
|
1320
|
+
const folderId = this.DraggedFolderId;
|
|
1321
|
+
this.DragOverTargetId = null;
|
|
1322
|
+
this.DraggedConversationIds = [];
|
|
1323
|
+
this.DraggedFolderId = null;
|
|
1324
|
+
if (conversationIds.length > 0) {
|
|
1325
|
+
await this.moveConversations(conversationIds, project.ID);
|
|
952
1326
|
}
|
|
953
1327
|
else if (folderId && this.isValidFolderDropTarget(project.ID, folderId)) {
|
|
954
|
-
this.moveFolder(folderId, project.ID);
|
|
1328
|
+
await this.moveFolder(folderId, project.ID);
|
|
955
1329
|
}
|
|
956
1330
|
}
|
|
957
|
-
|
|
1331
|
+
async OnUngroupedDrop(event) {
|
|
958
1332
|
event.preventDefault();
|
|
959
|
-
const
|
|
960
|
-
this.
|
|
961
|
-
this.
|
|
962
|
-
if (
|
|
963
|
-
this.
|
|
1333
|
+
const conversationIds = this.DraggedConversationIds;
|
|
1334
|
+
this.DragOverTargetId = null;
|
|
1335
|
+
this.DraggedConversationIds = [];
|
|
1336
|
+
if (conversationIds.length > 0) {
|
|
1337
|
+
await this.moveConversations(conversationIds, null);
|
|
964
1338
|
}
|
|
965
1339
|
}
|
|
966
|
-
|
|
1340
|
+
OnFoldersRootDrop(event) {
|
|
967
1341
|
event.preventDefault();
|
|
968
|
-
const folderId = this.
|
|
969
|
-
this.
|
|
970
|
-
this.
|
|
1342
|
+
const folderId = this.DraggedFolderId;
|
|
1343
|
+
this.DragOverTargetId = null;
|
|
1344
|
+
this.DraggedFolderId = null;
|
|
971
1345
|
if (folderId) {
|
|
972
1346
|
this.moveFolder(folderId, null);
|
|
973
1347
|
}
|
|
@@ -976,7 +1350,7 @@ export class ConversationListComponent {
|
|
|
976
1350
|
* A folder can be dropped onto a target folder only if the target isn't the dragged
|
|
977
1351
|
* folder itself and isn't one of its descendants (otherwise we'd create a cycle).
|
|
978
1352
|
*/
|
|
979
|
-
isValidFolderDropTarget(targetId, draggedId = this.
|
|
1353
|
+
isValidFolderDropTarget(targetId, draggedId = this.DraggedFolderId) {
|
|
980
1354
|
if (!draggedId)
|
|
981
1355
|
return false;
|
|
982
1356
|
if (UUIDsEqual(targetId, draggedId))
|
|
@@ -1001,20 +1375,41 @@ export class ConversationListComponent {
|
|
|
1001
1375
|
}
|
|
1002
1376
|
/** Assigns a conversation to a folder (or null to ungroup) and refreshes the view. */
|
|
1003
1377
|
async moveConversation(conversationId, projectId) {
|
|
1378
|
+
await this.moveConversations([conversationId], projectId);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Assigns several conversations to a folder (or null to ungroup) in one batch,
|
|
1382
|
+
* reveals the destination folder, and refreshes the view.
|
|
1383
|
+
*/
|
|
1384
|
+
async moveConversations(conversationIds, projectId) {
|
|
1385
|
+
// Dropping onto a folder's own contents is easy to do by accident — skip the
|
|
1386
|
+
// conversations that already live there rather than re-saving them.
|
|
1387
|
+
const toMove = conversationIds.filter(id => !this.isInProject(id, projectId));
|
|
1388
|
+
if (toMove.length === 0)
|
|
1389
|
+
return;
|
|
1004
1390
|
try {
|
|
1005
|
-
await this.engine.
|
|
1006
|
-
// Reveal the destination folder so the user sees where
|
|
1391
|
+
const result = await this.engine.MoveMultipleConversationsToProject(toMove, projectId, this.CurrentUser);
|
|
1392
|
+
// Reveal the destination folder so the user sees where they landed
|
|
1007
1393
|
if (projectId) {
|
|
1008
1394
|
this.collapsedFolderIds.delete(NormalizeUUID(projectId));
|
|
1009
1395
|
}
|
|
1396
|
+
await this.reportBulkOutcome(result, 'moved');
|
|
1010
1397
|
this.rebuildGroups();
|
|
1011
1398
|
this.cdr.detectChanges();
|
|
1012
1399
|
}
|
|
1013
1400
|
catch (error) {
|
|
1014
|
-
console.error('Error moving
|
|
1015
|
-
await this.dialogService.alert('Error',
|
|
1401
|
+
console.error('Error moving conversations:', error);
|
|
1402
|
+
await this.dialogService.alert('Error', `Failed to move the selected conversation${toMove.length === 1 ? '' : 's'}. Please try again.`);
|
|
1016
1403
|
}
|
|
1017
1404
|
}
|
|
1405
|
+
/** True when a conversation already sits in the given folder (or in no folder). */
|
|
1406
|
+
isInProject(conversationId, projectId) {
|
|
1407
|
+
const conversation = this.engine.GetConversation(conversationId);
|
|
1408
|
+
if (!conversation)
|
|
1409
|
+
return false;
|
|
1410
|
+
const current = conversation.ProjectID ?? null;
|
|
1411
|
+
return projectId ? !!current && UUIDsEqual(current, projectId) : !current;
|
|
1412
|
+
}
|
|
1018
1413
|
/** Reparents a folder under another folder (or to the top level when projectId is null). */
|
|
1019
1414
|
async moveFolder(folderId, parentId) {
|
|
1020
1415
|
// No-op if it's already under that parent
|
|
@@ -1025,7 +1420,7 @@ export class ConversationListComponent {
|
|
|
1025
1420
|
if (sameParent)
|
|
1026
1421
|
return;
|
|
1027
1422
|
try {
|
|
1028
|
-
await this.engine.MoveProjectToParent(folderId, parentId, this.
|
|
1423
|
+
await this.engine.MoveProjectToParent(folderId, parentId, this.CurrentUser);
|
|
1029
1424
|
// Reveal the new parent so the moved folder is visible
|
|
1030
1425
|
if (parentId) {
|
|
1031
1426
|
this.collapsedFolderIds.delete(NormalizeUUID(parentId));
|
|
@@ -1039,42 +1434,246 @@ export class ConversationListComponent {
|
|
|
1039
1434
|
}
|
|
1040
1435
|
}
|
|
1041
1436
|
// ========================================================================
|
|
1042
|
-
//
|
|
1437
|
+
// RIGHT-CLICK MENU — one menu for rows, folders and empty space
|
|
1043
1438
|
// ========================================================================
|
|
1044
|
-
|
|
1439
|
+
/**
|
|
1440
|
+
* Opens the conversation menu. It acts on the whole selection when the clicked
|
|
1441
|
+
* row is part of it, and on that row alone otherwise — so right-clicking
|
|
1442
|
+
* something you had not selected never disturbs the selection.
|
|
1443
|
+
*/
|
|
1444
|
+
OnConversationContextMenu(conversation, event) {
|
|
1445
|
+
event.preventDefault();
|
|
1446
|
+
event.stopPropagation();
|
|
1447
|
+
if (this.lastRowPointerType === 'touch') {
|
|
1448
|
+
// Some touch browsers report a long-press as a right-click; it selects instead.
|
|
1449
|
+
this.completeLongPress();
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
const targets = this.SelectedConversationIds.has(conversation.ID)
|
|
1453
|
+
? Array.from(this.SelectedConversationIds)
|
|
1454
|
+
: [conversation.ID];
|
|
1455
|
+
this.openContextMenu({ kind: 'conversation', conversation, folder: null, targets }, this.pointerAnchor(event));
|
|
1456
|
+
}
|
|
1457
|
+
/** The row's ⋯ button opens the same menu, anchored under the button. */
|
|
1458
|
+
OpenRowMenu(conversation, event) {
|
|
1045
1459
|
event.stopPropagation();
|
|
1046
|
-
|
|
1460
|
+
const targets = this.SelectedConversationIds.has(conversation.ID)
|
|
1461
|
+
? Array.from(this.SelectedConversationIds)
|
|
1462
|
+
: [conversation.ID];
|
|
1463
|
+
this.openContextMenu({ kind: 'conversation', conversation, folder: null, targets }, this.buttonAnchor(event));
|
|
1047
1464
|
}
|
|
1048
|
-
|
|
1465
|
+
OnFolderContextMenu(project, event) {
|
|
1466
|
+
event.preventDefault();
|
|
1467
|
+
event.stopPropagation();
|
|
1468
|
+
this.openContextMenu({ kind: 'folder', conversation: null, folder: project, targets: [] }, this.pointerAnchor(event));
|
|
1469
|
+
}
|
|
1470
|
+
/** Empty space: a click that landed on a row or folder is theirs, not the list's. */
|
|
1471
|
+
OnBackgroundContextMenu(event) {
|
|
1472
|
+
const target = event.target;
|
|
1473
|
+
if (target?.closest('.conversation-item, .folder-row'))
|
|
1474
|
+
return;
|
|
1475
|
+
event.preventDefault();
|
|
1476
|
+
this.openContextMenu({ kind: 'background', conversation: null, folder: null, targets: [] }, this.pointerAnchor(event));
|
|
1477
|
+
}
|
|
1478
|
+
/** A menu opened at the pointer opens upward from the pointer when it must. */
|
|
1479
|
+
pointerAnchor(event) {
|
|
1480
|
+
return { x: event.clientX, y: event.clientY, flipBottom: event.clientY };
|
|
1481
|
+
}
|
|
1482
|
+
/** A menu opened from a button sits under it, or above it when there is no room below. */
|
|
1483
|
+
buttonAnchor(event) {
|
|
1484
|
+
const rect = event.currentTarget?.getBoundingClientRect();
|
|
1485
|
+
if (!rect)
|
|
1486
|
+
return this.pointerAnchor(event);
|
|
1487
|
+
return { x: rect.left, y: rect.bottom + 2, flipBottom: rect.top - 2 };
|
|
1488
|
+
}
|
|
1489
|
+
openContextMenu(menu, anchor, showFolderPicker = false) {
|
|
1490
|
+
this.IsMoveSubmenuOpen = showFolderPicker;
|
|
1491
|
+
this.ContextMenu = { ...menu, anchor, x: anchor.x, y: anchor.y };
|
|
1492
|
+
this.fitContextMenuInViewport();
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Keeps the open menu inside the window: it opens upward from its anchor when
|
|
1496
|
+
* there is no room below, and moves left when there is no room to the right.
|
|
1497
|
+
* Runs again whenever the folder picker changes the menu's height.
|
|
1498
|
+
*/
|
|
1499
|
+
fitContextMenuInViewport() {
|
|
1500
|
+
if (!this.ContextMenu)
|
|
1501
|
+
return;
|
|
1502
|
+
this.cdr.detectChanges(); // render the menu so it can be measured
|
|
1503
|
+
const menuElement = this.contextMenuEl?.nativeElement;
|
|
1504
|
+
if (!menuElement)
|
|
1505
|
+
return;
|
|
1506
|
+
const { width, height } = menuElement.getBoundingClientRect();
|
|
1507
|
+
const { anchor } = this.ContextMenu;
|
|
1508
|
+
const margin = ConversationListComponent.menuViewportMargin;
|
|
1509
|
+
let y = anchor.y;
|
|
1510
|
+
if (y + height > window.innerHeight - margin) {
|
|
1511
|
+
const above = anchor.flipBottom - height;
|
|
1512
|
+
y = above >= margin ? above : Math.max(margin, window.innerHeight - margin - height);
|
|
1513
|
+
}
|
|
1514
|
+
const x = Math.max(margin, Math.min(anchor.x, window.innerWidth - margin - width));
|
|
1515
|
+
this.ContextMenu = { ...this.ContextMenu, x, y };
|
|
1516
|
+
this.cdr.detectChanges();
|
|
1517
|
+
}
|
|
1518
|
+
CloseContextMenu() {
|
|
1519
|
+
this.ContextMenu = null;
|
|
1520
|
+
this.IsMoveSubmenuOpen = false;
|
|
1521
|
+
}
|
|
1522
|
+
OpenMoveSubmenu(event) {
|
|
1523
|
+
event.stopPropagation();
|
|
1524
|
+
this.IsMoveSubmenuOpen = true;
|
|
1525
|
+
this.fitContextMenuInViewport();
|
|
1526
|
+
}
|
|
1527
|
+
CloseMoveSubmenu(event) {
|
|
1528
|
+
event.stopPropagation();
|
|
1529
|
+
this.IsMoveSubmenuOpen = false;
|
|
1530
|
+
this.fitContextMenuInViewport();
|
|
1531
|
+
}
|
|
1532
|
+
/** Marks the folder a single conversation already sits in. Never marks a multi-target menu. */
|
|
1533
|
+
IsSingleTargetInFolder(projectId) {
|
|
1534
|
+
const conversation = this.ContextMenu?.conversation;
|
|
1535
|
+
if (!conversation || this.ContextMenu?.targets.length !== 1)
|
|
1536
|
+
return false;
|
|
1537
|
+
return projectId
|
|
1538
|
+
? !!conversation.ProjectID && UUIDsEqual(conversation.ProjectID, projectId)
|
|
1539
|
+
: !conversation.ProjectID;
|
|
1540
|
+
}
|
|
1541
|
+
/** Conversations the menu's actions apply to — its targets, or the selection. */
|
|
1542
|
+
actionTargetIds() {
|
|
1543
|
+
const targets = this.ContextMenu?.targets ?? [];
|
|
1544
|
+
return targets.length > 0 ? targets : Array.from(this.SelectedConversationIds);
|
|
1545
|
+
}
|
|
1546
|
+
ContextMoveToFolder(projectId) {
|
|
1547
|
+
void this.BulkMoveToFolder(projectId);
|
|
1548
|
+
}
|
|
1549
|
+
ContextMoveToNewFolder(event) {
|
|
1049
1550
|
event.stopPropagation();
|
|
1050
|
-
|
|
1551
|
+
const ids = this.actionTargetIds();
|
|
1552
|
+
this.CloseContextMenu();
|
|
1553
|
+
this.openFolderModal(null, null, (created) => this.moveConversations(ids, created.ID));
|
|
1554
|
+
}
|
|
1555
|
+
ContextSetPinned(isPinned) {
|
|
1556
|
+
void this.BulkSetPinned(isPinned);
|
|
1557
|
+
}
|
|
1558
|
+
ContextTogglePin() {
|
|
1559
|
+
const conversation = this.ContextMenu?.conversation;
|
|
1560
|
+
if (!conversation)
|
|
1561
|
+
return;
|
|
1562
|
+
void this.BulkSetPinned(!conversation.IsPinned);
|
|
1051
1563
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1564
|
+
/** Shares the menu's targets — the whole selection, or just the clicked row. */
|
|
1565
|
+
ContextShare() {
|
|
1566
|
+
const ids = this.actionTargetIds();
|
|
1567
|
+
this.CloseContextMenu();
|
|
1568
|
+
this.shareConversations(ids);
|
|
1054
1569
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1570
|
+
/**
|
|
1571
|
+
* Opens the dialog the chat header uses for the conversations the user may
|
|
1572
|
+
* share, and reports how many were left out. Says why when there are none.
|
|
1573
|
+
*/
|
|
1574
|
+
shareConversations(ids) {
|
|
1575
|
+
const conversations = ids
|
|
1576
|
+
.map(id => this.engine.GetConversation(id))
|
|
1577
|
+
.filter((c) => !!c);
|
|
1578
|
+
const shareable = conversations.filter(c => this.canShare(c));
|
|
1579
|
+
if (shareable.length === 0) {
|
|
1580
|
+
void this.dialogService.alert('Cannot Share', `${this.ShareRefusedReason}.`);
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
const skipped = conversations.length - shareable.length;
|
|
1584
|
+
this.ShareContexts = shareable.map(c => ({
|
|
1585
|
+
ResourceID: c.ID,
|
|
1586
|
+
ResourceName: c.Name ?? 'Conversation',
|
|
1587
|
+
OwnerUserID: c.UserID ?? null,
|
|
1588
|
+
OwnerDisplayName: c.User ?? 'You',
|
|
1589
|
+
CurrentUserID: this.CurrentUser?.ID ?? null
|
|
1590
|
+
}));
|
|
1591
|
+
this.ShareNotice = skipped > 0
|
|
1592
|
+
? `${skipped} of ${conversations.length} left out — ${this.ShareRefusedReason.toLowerCase()}.`
|
|
1593
|
+
: null;
|
|
1594
|
+
this.IsShareDialogOpen = true;
|
|
1595
|
+
}
|
|
1596
|
+
/** True when at least one of the conversations can be shared by the current user. */
|
|
1597
|
+
CanShareAny(ids) {
|
|
1598
|
+
return ids.some(id => this.canShare(this.engine.GetConversation(id)));
|
|
1599
|
+
}
|
|
1600
|
+
canShare(conversation) {
|
|
1601
|
+
if (!conversation || !this.CurrentUser)
|
|
1602
|
+
return false;
|
|
1603
|
+
return this.engine.CanShareConversation(conversation, this.CurrentUser.ID);
|
|
1604
|
+
}
|
|
1605
|
+
/** True when at least one of the conversations can be moved or pinned by the current user. */
|
|
1606
|
+
CanChangeAny(ids) {
|
|
1607
|
+
return ids.some(id => {
|
|
1608
|
+
const conversation = this.engine.GetConversation(id);
|
|
1609
|
+
return !!conversation && this.CanChange(conversation);
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
/** True when the user may move or pin the conversation: they own it, or hold Edit or Owner access. */
|
|
1613
|
+
CanChange(conversation) {
|
|
1614
|
+
if (!this.CurrentUser)
|
|
1615
|
+
return false;
|
|
1616
|
+
return this.engine.CanEditConversation(conversation, this.CurrentUser.ID);
|
|
1617
|
+
}
|
|
1618
|
+
OnShareDialogResult(_result) {
|
|
1619
|
+
this.IsShareDialogOpen = false;
|
|
1620
|
+
this.ShareContexts = [];
|
|
1621
|
+
this.ShareNotice = null;
|
|
1622
|
+
this.cdr.detectChanges();
|
|
1623
|
+
}
|
|
1624
|
+
ContextRename() {
|
|
1625
|
+
const conversation = this.ContextMenu?.conversation;
|
|
1626
|
+
this.CloseContextMenu();
|
|
1627
|
+
if (conversation)
|
|
1628
|
+
this.RenameConversation(conversation);
|
|
1629
|
+
}
|
|
1630
|
+
ContextDelete() {
|
|
1631
|
+
void this.BulkDeleteConversations();
|
|
1632
|
+
}
|
|
1633
|
+
ContextCreateSubfolder(event) {
|
|
1634
|
+
const folder = this.ContextMenu?.folder;
|
|
1635
|
+
this.CloseContextMenu();
|
|
1636
|
+
if (folder)
|
|
1637
|
+
this.CreateFolder(folder.ID, event);
|
|
1638
|
+
}
|
|
1639
|
+
ContextEditFolder(event) {
|
|
1640
|
+
const folder = this.ContextMenu?.folder;
|
|
1641
|
+
this.CloseContextMenu();
|
|
1642
|
+
if (folder)
|
|
1643
|
+
this.EditFolder(folder, event);
|
|
1644
|
+
}
|
|
1645
|
+
ContextDeleteFolder(event) {
|
|
1646
|
+
const folder = this.ContextMenu?.folder;
|
|
1647
|
+
this.CloseContextMenu();
|
|
1648
|
+
if (folder)
|
|
1649
|
+
void this.DeleteFolder(folder, event);
|
|
1650
|
+
}
|
|
1651
|
+
ContextNewConversation() {
|
|
1652
|
+
this.CloseContextMenu();
|
|
1653
|
+
this.CreateNewConversation();
|
|
1654
|
+
}
|
|
1655
|
+
ContextCreateRootFolder(event) {
|
|
1656
|
+
this.CloseContextMenu();
|
|
1657
|
+
this.CreateFolder(null, event);
|
|
1658
|
+
}
|
|
1659
|
+
ContextSelectAll() {
|
|
1660
|
+
this.CloseContextMenu();
|
|
1661
|
+
this.IsSelectionMode = true;
|
|
1662
|
+
this.SelectAll();
|
|
1058
1663
|
}
|
|
1059
1664
|
// ========================================================================
|
|
1060
1665
|
// FOLDER CRUD (reuses the existing project form modal)
|
|
1061
1666
|
// ========================================================================
|
|
1062
|
-
|
|
1667
|
+
CreateFolder(parentId, event) {
|
|
1063
1668
|
if (event)
|
|
1064
1669
|
event.stopPropagation();
|
|
1065
1670
|
this.openFolderModal(null, parentId);
|
|
1066
1671
|
}
|
|
1067
|
-
|
|
1672
|
+
EditFolder(project, event) {
|
|
1068
1673
|
if (event)
|
|
1069
1674
|
event.stopPropagation();
|
|
1070
1675
|
this.openFolderModal(project, null);
|
|
1071
1676
|
}
|
|
1072
|
-
createFolderForConversation(conversation, event) {
|
|
1073
|
-
event.stopPropagation();
|
|
1074
|
-
const conversationId = conversation.ID;
|
|
1075
|
-
this.closeMenu();
|
|
1076
|
-
this.openFolderModal(null, null, (created) => this.moveConversation(conversationId, created.ID));
|
|
1077
|
-
}
|
|
1078
1677
|
openFolderModal(project, parentId, onCreated) {
|
|
1079
1678
|
const dialogRef = this.mjDialogService.open({
|
|
1080
1679
|
content: ProjectFormModalComponent,
|
|
@@ -1083,8 +1682,8 @@ export class ConversationListComponent {
|
|
|
1083
1682
|
});
|
|
1084
1683
|
const instance = dialogRef.Content.instance;
|
|
1085
1684
|
instance.dialogRef = dialogRef;
|
|
1086
|
-
instance.environmentId = this.
|
|
1087
|
-
instance.currentUser = this.
|
|
1685
|
+
instance.environmentId = this.EnvironmentId;
|
|
1686
|
+
instance.currentUser = this.CurrentUser;
|
|
1088
1687
|
if (project)
|
|
1089
1688
|
instance.project = project;
|
|
1090
1689
|
if (parentId)
|
|
@@ -1101,10 +1700,10 @@ export class ConversationListComponent {
|
|
|
1101
1700
|
onCreated(saved);
|
|
1102
1701
|
});
|
|
1103
1702
|
}
|
|
1104
|
-
async
|
|
1703
|
+
async DeleteFolder(project, event) {
|
|
1105
1704
|
if (event)
|
|
1106
1705
|
event.stopPropagation();
|
|
1107
|
-
const node = this.findFolderNode(this.
|
|
1706
|
+
const node = this.findFolderNode(this.FolderTree, project.ID);
|
|
1108
1707
|
const total = node?.totalCount ?? 0;
|
|
1109
1708
|
const childCount = node?.children.length ?? 0;
|
|
1110
1709
|
let message = `Are you sure you want to delete the folder "${project.Name}"?`;
|
|
@@ -1123,7 +1722,7 @@ export class ConversationListComponent {
|
|
|
1123
1722
|
if (!confirmed)
|
|
1124
1723
|
return;
|
|
1125
1724
|
try {
|
|
1126
|
-
await this.engine.DeleteProject(project.ID, this.
|
|
1725
|
+
await this.engine.DeleteProject(project.ID, this.CurrentUser);
|
|
1127
1726
|
this.collapsedFolderIds.delete(NormalizeUUID(project.ID));
|
|
1128
1727
|
this.rebuildGroups();
|
|
1129
1728
|
this.cdr.detectChanges();
|
|
@@ -1134,31 +1733,29 @@ export class ConversationListComponent {
|
|
|
1134
1733
|
}
|
|
1135
1734
|
}
|
|
1136
1735
|
IsConversationActive(conversation) {
|
|
1137
|
-
return UUIDsEqual(conversation.ID, this.
|
|
1736
|
+
return UUIDsEqual(conversation.ID, this.SelectedConversationId);
|
|
1138
1737
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1738
|
+
/** True when this conversation is part of the current multi-selection. */
|
|
1739
|
+
IsConversationSelected(conversation) {
|
|
1740
|
+
return this.IsSelectionMode && this.SelectedConversationIds.has(conversation.ID);
|
|
1141
1741
|
}
|
|
1142
|
-
|
|
1143
|
-
return UUIDsEqual(
|
|
1742
|
+
IsConversationRenamed(conversation) {
|
|
1743
|
+
return UUIDsEqual(conversation.ID, this.RenamedConversationId);
|
|
1144
1744
|
}
|
|
1145
1745
|
IsConversationDragging(conversation) {
|
|
1146
|
-
return UUIDsEqual(
|
|
1147
|
-
}
|
|
1148
|
-
IsMoveSubmenuOpen(conversation) {
|
|
1149
|
-
return UUIDsEqual(this.moveSubmenuConversationId, conversation.ID);
|
|
1746
|
+
return this.DraggedConversationIds.some(id => UUIDsEqual(id, conversation.ID));
|
|
1150
1747
|
}
|
|
1151
|
-
|
|
1152
|
-
this.
|
|
1748
|
+
SelectConversation(conversation) {
|
|
1749
|
+
this.ConversationSelected.emit(conversation.ID);
|
|
1153
1750
|
// Clear unread notifications when conversation is opened
|
|
1154
1751
|
this.notificationService.markConversationAsRead(conversation.ID);
|
|
1155
1752
|
}
|
|
1156
|
-
async
|
|
1753
|
+
async CreateNewConversation() {
|
|
1157
1754
|
// Don't create DB record yet - just show the welcome screen
|
|
1158
1755
|
// Conversation will be created when user sends first message
|
|
1159
|
-
this.
|
|
1756
|
+
this.NewConversationRequested.emit();
|
|
1160
1757
|
}
|
|
1161
|
-
async
|
|
1758
|
+
async RenameConversation(conversation) {
|
|
1162
1759
|
try {
|
|
1163
1760
|
const result = await this.dialogService.input({
|
|
1164
1761
|
title: 'Edit Conversation',
|
|
@@ -1178,7 +1775,7 @@ export class ConversationListComponent {
|
|
|
1178
1775
|
const newName = typeof result === 'string' ? result : result.value;
|
|
1179
1776
|
const newDescription = typeof result === 'string' ? conversation.Description : result.secondValue;
|
|
1180
1777
|
if (newName !== conversation.Name || newDescription !== conversation.Description) {
|
|
1181
|
-
await this.engine.SaveConversation(conversation.ID, { Name: newName, Description: newDescription || '' }, this.
|
|
1778
|
+
await this.engine.SaveConversation(conversation.ID, { Name: newName, Description: newDescription || '' }, this.CurrentUser);
|
|
1182
1779
|
}
|
|
1183
1780
|
}
|
|
1184
1781
|
}
|
|
@@ -1187,7 +1784,7 @@ export class ConversationListComponent {
|
|
|
1187
1784
|
await this.dialogService.alert('Error', 'Failed to update conversation. Please try again.');
|
|
1188
1785
|
}
|
|
1189
1786
|
}
|
|
1190
|
-
async
|
|
1787
|
+
async DeleteConversation(conversation) {
|
|
1191
1788
|
try {
|
|
1192
1789
|
const confirmed = await this.dialogService.confirm({
|
|
1193
1790
|
title: 'Delete Conversation',
|
|
@@ -1197,9 +1794,9 @@ export class ConversationListComponent {
|
|
|
1197
1794
|
});
|
|
1198
1795
|
if (confirmed) {
|
|
1199
1796
|
const deletedId = conversation.ID;
|
|
1200
|
-
await this.engine.DeleteConversation(deletedId, this.
|
|
1797
|
+
await this.engine.DeleteConversation(deletedId, this.CurrentUser);
|
|
1201
1798
|
this.cdr.detectChanges();
|
|
1202
|
-
this.
|
|
1799
|
+
this.ConversationDeleted.emit(deletedId);
|
|
1203
1800
|
}
|
|
1204
1801
|
}
|
|
1205
1802
|
catch (error) {
|
|
@@ -1207,64 +1804,238 @@ export class ConversationListComponent {
|
|
|
1207
1804
|
await this.dialogService.alert('Error', 'Failed to delete conversation. Please try again.');
|
|
1208
1805
|
}
|
|
1209
1806
|
}
|
|
1210
|
-
|
|
1211
|
-
event.stopPropagation();
|
|
1212
|
-
this.openMenuConversationId = this.openMenuConversationId === conversationId ? null : conversationId;
|
|
1213
|
-
}
|
|
1214
|
-
closeMenu() {
|
|
1215
|
-
this.openMenuConversationId = null;
|
|
1216
|
-
this.moveSubmenuConversationId = null;
|
|
1217
|
-
}
|
|
1218
|
-
async togglePin(conversation, event) {
|
|
1807
|
+
async TogglePin(conversation, event) {
|
|
1219
1808
|
if (event)
|
|
1220
1809
|
event.stopPropagation();
|
|
1221
|
-
this.
|
|
1810
|
+
this.CloseContextMenu(); // Close immediately on user action — don't wait for the async op
|
|
1222
1811
|
try {
|
|
1223
|
-
await this.engine.PinConversation(conversation.ID, !conversation.IsPinned, this.
|
|
1812
|
+
await this.engine.PinConversation(conversation.ID, !conversation.IsPinned, this.CurrentUser);
|
|
1224
1813
|
}
|
|
1225
1814
|
catch (error) {
|
|
1226
1815
|
console.error('Error toggling pin:', error);
|
|
1227
1816
|
await this.dialogService.alert('Error', 'Failed to pin/unpin conversation. Please try again.');
|
|
1228
1817
|
}
|
|
1229
1818
|
}
|
|
1230
|
-
|
|
1231
|
-
return this.
|
|
1819
|
+
HasActiveTasks(conversationId) {
|
|
1820
|
+
return this.ConversationIdsWithTasks.has(conversationId);
|
|
1232
1821
|
}
|
|
1233
1822
|
/** True when this conversation was shared with the current user by someone else. */
|
|
1234
|
-
|
|
1823
|
+
IsSharedWithMe(conversation) {
|
|
1235
1824
|
return this.engine.GetSharedByInfo(conversation.ID) !== null;
|
|
1236
1825
|
}
|
|
1237
1826
|
/** Tooltip for the sidebar share icon: "Shared by {email or name}". */
|
|
1238
|
-
|
|
1827
|
+
SharedWithMeTooltip(conversation) {
|
|
1239
1828
|
const info = this.engine.GetSharedByInfo(conversation.ID);
|
|
1240
1829
|
if (!info)
|
|
1241
1830
|
return 'Shared with you';
|
|
1242
1831
|
return `Shared by ${info.Email ?? info.Name ?? 'another user'}`;
|
|
1243
1832
|
}
|
|
1244
|
-
|
|
1245
|
-
this.
|
|
1246
|
-
|
|
1247
|
-
|
|
1833
|
+
ToggleSelectionMode() {
|
|
1834
|
+
if (this.IsSelectionMode) {
|
|
1835
|
+
this.exitSelectionMode();
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
this.IsSelectionMode = true;
|
|
1248
1839
|
}
|
|
1249
1840
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1841
|
+
/**
|
|
1842
|
+
* Clicking the empty space of the list drops the selection, the way clicking
|
|
1843
|
+
* blank space in a file browser does. A click that landed on a row, folder,
|
|
1844
|
+
* section header or button is handled by that element instead.
|
|
1845
|
+
*/
|
|
1846
|
+
OnListBackgroundClick(event) {
|
|
1847
|
+
if (!this.IsSelectionMode)
|
|
1848
|
+
return;
|
|
1849
|
+
const target = event.target;
|
|
1850
|
+
if (target?.closest('.conversation-item, .folder-row, .section-header, button'))
|
|
1851
|
+
return;
|
|
1852
|
+
this.exitSelectionMode();
|
|
1853
|
+
}
|
|
1854
|
+
exitSelectionMode() {
|
|
1855
|
+
this.IsSelectionMode = false;
|
|
1856
|
+
this.SelectedConversationIds.clear();
|
|
1857
|
+
this.selectionAnchorId = null;
|
|
1858
|
+
}
|
|
1859
|
+
/** Ends selection mode from the selection bar's clear button. */
|
|
1860
|
+
ClearSelection() {
|
|
1861
|
+
this.exitSelectionMode();
|
|
1862
|
+
}
|
|
1863
|
+
/** Selection mode closes itself once the last row is deselected. */
|
|
1864
|
+
exitSelectionModeIfEmpty() {
|
|
1865
|
+
if (this.SelectedConversationIds.size === 0) {
|
|
1866
|
+
this.exitSelectionMode();
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
/** Adds or removes one row and makes it the range anchor, ending the mode when nothing is left. */
|
|
1870
|
+
toggleRowSelection(conversationId) {
|
|
1871
|
+
this.ToggleConversationSelection(conversationId);
|
|
1872
|
+
this.selectionAnchorId = conversationId;
|
|
1873
|
+
this.exitSelectionModeIfEmpty();
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Drops selected rows the view no longer shows — after a search edit, a
|
|
1877
|
+
* collapse, or a grouping change — so no action can reach a row the user
|
|
1878
|
+
* cannot see. A list rebuild alone does not call this: a move into a
|
|
1879
|
+
* collapsed folder keeps its rows selected for a follow-up action.
|
|
1880
|
+
*/
|
|
1881
|
+
dropHiddenRowsFromSelection() {
|
|
1882
|
+
if (this.SelectedConversationIds.size === 0)
|
|
1883
|
+
return;
|
|
1884
|
+
const visible = new Set(this.visibleConversationIds().map(id => NormalizeUUID(id)));
|
|
1885
|
+
this.removeFromSelection(id => !visible.has(NormalizeUUID(id)));
|
|
1886
|
+
}
|
|
1887
|
+
/** Drops selected conversations that are no longer in the engine's list at all. */
|
|
1888
|
+
dropRemovedConversationsFromSelection() {
|
|
1889
|
+
if (this.SelectedConversationIds.size === 0)
|
|
1890
|
+
return;
|
|
1891
|
+
const listed = new Set(this.engine.Conversations.map(c => NormalizeUUID(c.ID)));
|
|
1892
|
+
this.removeFromSelection(id => !listed.has(NormalizeUUID(id)));
|
|
1893
|
+
}
|
|
1894
|
+
/** Removes the selected IDs that match, and ends selection mode if none remain. */
|
|
1895
|
+
removeFromSelection(shouldRemove) {
|
|
1896
|
+
for (const id of Array.from(this.SelectedConversationIds)) {
|
|
1897
|
+
if (shouldRemove(id)) {
|
|
1898
|
+
this.SelectedConversationIds.delete(id);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
this.exitSelectionModeIfEmpty();
|
|
1902
|
+
}
|
|
1903
|
+
/**
|
|
1904
|
+
* Adds the open conversation to a selection that is just starting, so it moves
|
|
1905
|
+
* with the rows picked alongside it. Returns the id added, or null when nothing
|
|
1906
|
+
* is open or it is hidden inside a collapsed folder or section.
|
|
1907
|
+
*/
|
|
1908
|
+
seedSelectionWithOpenConversation() {
|
|
1909
|
+
const openId = this.SelectedConversationId;
|
|
1910
|
+
if (!openId)
|
|
1911
|
+
return null;
|
|
1912
|
+
const visibleId = this.visibleConversationIds().find(id => UUIDsEqual(id, openId));
|
|
1913
|
+
if (!visibleId)
|
|
1914
|
+
return null;
|
|
1915
|
+
this.SelectedConversationIds.add(visibleId);
|
|
1916
|
+
return visibleId;
|
|
1917
|
+
}
|
|
1918
|
+
/** Conversation IDs in the order the list renders them, skipping collapsed sections and folders. */
|
|
1919
|
+
visibleConversationIds() {
|
|
1920
|
+
const ids = [];
|
|
1921
|
+
const sectionOpen = (expanded) => !this.ShowSectionHeaders || expanded;
|
|
1922
|
+
if (sectionOpen(this.PinnedExpanded)) {
|
|
1923
|
+
ids.push(...this.PinnedConversations.map(c => c.ID));
|
|
1924
|
+
}
|
|
1925
|
+
if (this.ShowSectionHeaders && this.GroupBy === 'project') {
|
|
1926
|
+
if (this.FoldersExpanded) {
|
|
1927
|
+
// Subfolders render above their parent folder's own conversations.
|
|
1928
|
+
const walk = (nodes) => {
|
|
1929
|
+
for (const node of nodes) {
|
|
1930
|
+
if (!this.IsFolderExpanded(node.project.ID))
|
|
1931
|
+
continue;
|
|
1932
|
+
walk(node.children);
|
|
1933
|
+
ids.push(...node.conversations.map(c => c.ID));
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
walk(this.FolderTree);
|
|
1937
|
+
}
|
|
1938
|
+
if (this.UngroupedExpanded) {
|
|
1939
|
+
ids.push(...this.UngroupedConversations.map(c => c.ID));
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
else if (sectionOpen(this.DirectMessagesExpanded)) {
|
|
1943
|
+
ids.push(...this.UnpinnedConversations.map(c => c.ID));
|
|
1944
|
+
}
|
|
1945
|
+
return ids;
|
|
1946
|
+
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Adds every row between the anchor and `conversationId` to the selection.
|
|
1949
|
+
* Rows already picked stay picked — a range never takes a selection away.
|
|
1950
|
+
*
|
|
1951
|
+
* With nothing picked yet the open conversation stands in as the anchor, so a
|
|
1952
|
+
* single Shift-click highlights the span from it rather than one lone row.
|
|
1953
|
+
*/
|
|
1954
|
+
selectRangeTo(conversationId) {
|
|
1955
|
+
const order = this.visibleConversationIds();
|
|
1956
|
+
const end = this.indexOfConversation(order, conversationId);
|
|
1957
|
+
if (end < 0)
|
|
1958
|
+
return;
|
|
1959
|
+
const anchorId = this.selectionAnchorId ?? this.SelectedConversationId;
|
|
1960
|
+
const start = this.indexOfConversation(order, anchorId);
|
|
1961
|
+
if (start < 0) {
|
|
1962
|
+
// No anchor and no open conversation on screen — pick this row alone.
|
|
1963
|
+
this.SelectedConversationIds.add(conversationId);
|
|
1964
|
+
this.selectionAnchorId = conversationId;
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
this.selectionAnchorId = order[start];
|
|
1968
|
+
const [from, to] = start <= end ? [start, end] : [end, start];
|
|
1969
|
+
for (let i = from; i <= to; i++) {
|
|
1970
|
+
this.SelectedConversationIds.add(order[i]);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
ToggleConversationSelection(conversationId) {
|
|
1974
|
+
if (this.SelectedConversationIds.has(conversationId)) {
|
|
1975
|
+
this.SelectedConversationIds.delete(conversationId);
|
|
1253
1976
|
}
|
|
1254
1977
|
else {
|
|
1255
|
-
this.
|
|
1978
|
+
this.SelectedConversationIds.add(conversationId);
|
|
1256
1979
|
}
|
|
1257
1980
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1981
|
+
/** Selects every row on screen — never rows hidden by the search or a collapsed folder or section. */
|
|
1982
|
+
SelectAll() {
|
|
1983
|
+
this.visibleConversationIds().forEach(id => {
|
|
1984
|
+
this.SelectedConversationIds.add(id);
|
|
1261
1985
|
});
|
|
1262
1986
|
}
|
|
1263
|
-
|
|
1264
|
-
this.
|
|
1987
|
+
DeselectAll() {
|
|
1988
|
+
this.SelectedConversationIds.clear();
|
|
1989
|
+
}
|
|
1990
|
+
/**
|
|
1991
|
+
* Moves the conversations into one folder, or out of all folders when projectId
|
|
1992
|
+
* is null. The selection survives so a second bulk action can follow.
|
|
1993
|
+
*/
|
|
1994
|
+
async BulkMoveToFolder(projectId, ids = this.actionTargetIds()) {
|
|
1995
|
+
this.CloseContextMenu();
|
|
1996
|
+
if (ids.length === 0)
|
|
1997
|
+
return;
|
|
1998
|
+
try {
|
|
1999
|
+
const result = await this.engine.MoveMultipleConversationsToProject(ids, projectId, this.CurrentUser);
|
|
2000
|
+
await this.reportBulkOutcome(result, 'moved');
|
|
2001
|
+
}
|
|
2002
|
+
catch (error) {
|
|
2003
|
+
console.error('Error moving conversations:', error);
|
|
2004
|
+
await this.dialogService.alert('Error', 'Failed to move the selected conversations. Please try again.');
|
|
2005
|
+
}
|
|
2006
|
+
this.cdr.detectChanges();
|
|
2007
|
+
}
|
|
2008
|
+
/** Pins or unpins the conversations, keeping the selection. */
|
|
2009
|
+
async BulkSetPinned(isPinned, ids = this.actionTargetIds()) {
|
|
2010
|
+
this.CloseContextMenu();
|
|
2011
|
+
if (ids.length === 0)
|
|
2012
|
+
return;
|
|
2013
|
+
try {
|
|
2014
|
+
const result = await this.engine.PinMultipleConversations(ids, isPinned, this.CurrentUser);
|
|
2015
|
+
await this.reportBulkOutcome(result, isPinned ? 'pinned' : 'unpinned');
|
|
2016
|
+
}
|
|
2017
|
+
catch (error) {
|
|
2018
|
+
console.error('Error pinning conversations:', error);
|
|
2019
|
+
await this.dialogService.alert('Error', `Failed to ${isPinned ? 'pin' : 'unpin'} the selected conversations. Please try again.`);
|
|
2020
|
+
}
|
|
2021
|
+
this.cdr.detectChanges();
|
|
1265
2022
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
2023
|
+
/** Reports the conversations a bulk action could not change. Silent on full success. */
|
|
2024
|
+
async reportBulkOutcome(result, verb) {
|
|
2025
|
+
if (result.Failed.length === 0)
|
|
2026
|
+
return;
|
|
2027
|
+
const failedNames = result.Failed.map(f => `"${f.Name}" (${f.Error})`).join(', ');
|
|
2028
|
+
await this.dialogService.alert('Partial Success', `${result.Successful.length} conversation${result.Successful.length === 1 ? '' : 's'} ${verb}.\n\n` +
|
|
2029
|
+
`${result.Failed.length} could not be ${verb}: ${failedNames}`);
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* Deletes the conversations after confirmation. Only the deleted ones leave the
|
|
2033
|
+
* selection: deleting a row outside it leaves it alone, and rows that failed
|
|
2034
|
+
* stay selected so the user can try again.
|
|
2035
|
+
*/
|
|
2036
|
+
async BulkDeleteConversations(ids = this.actionTargetIds()) {
|
|
2037
|
+
const count = ids.length;
|
|
2038
|
+
this.CloseContextMenu();
|
|
1268
2039
|
if (count === 0)
|
|
1269
2040
|
return;
|
|
1270
2041
|
const confirmed = await this.dialogService.confirm({
|
|
@@ -1273,132 +2044,734 @@ export class ConversationListComponent {
|
|
|
1273
2044
|
okText: 'Delete',
|
|
1274
2045
|
cancelText: 'Cancel'
|
|
1275
2046
|
});
|
|
1276
|
-
if (confirmed)
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
`${result.Failed.length} could not be deleted: ${failedNames}`);
|
|
1284
|
-
}
|
|
1285
|
-
else if (result.Failed.length > 0 && result.Successful.length === 0) {
|
|
1286
|
-
// All failed
|
|
1287
|
-
await this.dialogService.alert('Delete Failed', `None of the ${count} conversations could be deleted. They may have already been removed.`);
|
|
1288
|
-
}
|
|
1289
|
-
// Emit deleted events for successful deletions
|
|
1290
|
-
for (const id of result.Successful) {
|
|
1291
|
-
this.conversationDeleted.emit(id);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
catch (error) {
|
|
1295
|
-
console.error('Error deleting conversations:', error);
|
|
1296
|
-
await this.dialogService.alert('Error', 'Failed to delete conversations. Please try again.');
|
|
1297
|
-
}
|
|
1298
|
-
finally {
|
|
1299
|
-
// Always exit selection mode after an attempt, whether success or failure
|
|
1300
|
-
this.selectedConversationIds.clear();
|
|
1301
|
-
this.isSelectionMode = false;
|
|
1302
|
-
this.cdr.detectChanges();
|
|
2047
|
+
if (!confirmed)
|
|
2048
|
+
return;
|
|
2049
|
+
try {
|
|
2050
|
+
const result = await this.engine.DeleteMultipleConversations(ids, this.CurrentUser);
|
|
2051
|
+
await this.reportDeleteOutcome(result, count);
|
|
2052
|
+
for (const id of result.Successful) {
|
|
2053
|
+
this.ConversationDeleted.emit(id);
|
|
1303
2054
|
}
|
|
2055
|
+
const deleted = new Set(result.Successful.map(id => NormalizeUUID(id)));
|
|
2056
|
+
this.removeFromSelection(id => deleted.has(NormalizeUUID(id)));
|
|
2057
|
+
}
|
|
2058
|
+
catch (error) {
|
|
2059
|
+
console.error('Error deleting conversations:', error);
|
|
2060
|
+
await this.dialogService.alert('Error', 'Failed to delete conversations. Please try again.');
|
|
2061
|
+
}
|
|
2062
|
+
finally {
|
|
2063
|
+
this.cdr.detectChanges();
|
|
1304
2064
|
}
|
|
1305
2065
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
2066
|
+
/** Reports the conversations a bulk delete could not remove. Silent on full success. */
|
|
2067
|
+
async reportDeleteOutcome(result, count) {
|
|
2068
|
+
if (result.Failed.length === 0)
|
|
2069
|
+
return;
|
|
2070
|
+
if (result.Successful.length === 0) {
|
|
2071
|
+
await this.dialogService.alert('Delete Failed', `None of the ${count} conversations could be deleted. They may have already been removed.`);
|
|
2072
|
+
return;
|
|
1309
2073
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
2074
|
+
const failedNames = result.Failed.map(f => `"${f.Name}"`).join(', ');
|
|
2075
|
+
await this.dialogService.alert('Partial Success', `Deleted ${result.Successful.length} of ${count} conversations.\n\n` +
|
|
2076
|
+
`${result.Failed.length} could not be deleted: ${failedNames}`);
|
|
2077
|
+
}
|
|
2078
|
+
// ========================================================================
|
|
2079
|
+
// SELECTION BAR — stands in for the search row while a selection exists
|
|
2080
|
+
// ========================================================================
|
|
2081
|
+
/** The selected conversation IDs, in the order they were picked. */
|
|
2082
|
+
get SelectedIds() {
|
|
2083
|
+
return Array.from(this.SelectedConversationIds);
|
|
2084
|
+
}
|
|
2085
|
+
/** True when any selected conversation is unpinned, so the bar's pin button pins rather than unpins. */
|
|
2086
|
+
SelectionHasUnpinned() {
|
|
2087
|
+
return this.SelectedIds.some(id => !this.engine.GetConversation(id)?.IsPinned);
|
|
2088
|
+
}
|
|
2089
|
+
/** The bar acts on the selection even while a menu for another row is open. */
|
|
2090
|
+
BarSetPinned() {
|
|
2091
|
+
void this.BulkSetPinned(this.SelectionHasUnpinned(), this.SelectedIds);
|
|
2092
|
+
}
|
|
2093
|
+
BarShare() {
|
|
2094
|
+
this.CloseContextMenu();
|
|
2095
|
+
this.shareConversations(this.SelectedIds);
|
|
2096
|
+
}
|
|
2097
|
+
BarDelete() {
|
|
2098
|
+
void this.BulkDeleteConversations(this.SelectedIds);
|
|
2099
|
+
}
|
|
2100
|
+
/** Opens the folder picker for the selection, under the bar's Move button. */
|
|
2101
|
+
BarOpenMoveMenu(event) {
|
|
2102
|
+
event.stopPropagation(); // the document click would close the picker straight away
|
|
2103
|
+
const ids = this.SelectedIds;
|
|
2104
|
+
const conversation = ids.length === 1 ? this.engine.GetConversation(ids[0]) ?? null : null;
|
|
2105
|
+
this.openContextMenu({ kind: 'conversation', conversation, folder: null, targets: ids }, this.buttonAnchor(event), true);
|
|
2106
|
+
}
|
|
2107
|
+
// ========================================================================
|
|
2108
|
+
// ROW CLICKS, CHECKBOXES AND TOUCH PRESSES
|
|
2109
|
+
// ========================================================================
|
|
2110
|
+
/**
|
|
2111
|
+
* The row checkbox adds or removes its row without opening it — the mouse
|
|
2112
|
+
* route to a selection that needs no keyboard. Shift-click extends a range.
|
|
2113
|
+
* Unlike a Ctrl-click it never takes the open conversation along, so the
|
|
2114
|
+
* checkboxes show exactly what is picked.
|
|
2115
|
+
*/
|
|
2116
|
+
OnRowCheckboxClick(conversation, event) {
|
|
2117
|
+
event.stopPropagation();
|
|
2118
|
+
this.IsSelectionMode = true;
|
|
2119
|
+
if (event.shiftKey) {
|
|
2120
|
+
this.selectRangeTo(conversation.ID);
|
|
2121
|
+
return;
|
|
1312
2122
|
}
|
|
2123
|
+
this.toggleRowSelection(conversation.ID);
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Starts timing a touch press on a row; held long enough, it selects the row.
|
|
2127
|
+
* Presses on the row's own buttons (the checkbox and ⋯) are theirs to handle.
|
|
2128
|
+
*/
|
|
2129
|
+
OnRowPointerDown(conversation, event) {
|
|
2130
|
+
this.lastRowPointerType = event.pointerType;
|
|
2131
|
+
this.ignoreNextRowClick = false;
|
|
2132
|
+
this.CancelLongPress();
|
|
2133
|
+
if (event.pointerType !== 'touch')
|
|
2134
|
+
return;
|
|
2135
|
+
if (event.target?.closest('button'))
|
|
2136
|
+
return;
|
|
2137
|
+
this.longPress = {
|
|
2138
|
+
conversation,
|
|
2139
|
+
x: event.clientX,
|
|
2140
|
+
y: event.clientY,
|
|
2141
|
+
timer: setTimeout(() => this.completeLongPress(), ConversationListComponent.longPressDelayMs)
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
/** A touch that drifts is a scroll, not a press. */
|
|
2145
|
+
OnRowPointerMove(event) {
|
|
2146
|
+
if (!this.longPress)
|
|
2147
|
+
return;
|
|
2148
|
+
const distance = Math.hypot(event.clientX - this.longPress.x, event.clientY - this.longPress.y);
|
|
2149
|
+
if (distance > ConversationListComponent.longPressMoveTolerancePx) {
|
|
2150
|
+
this.CancelLongPress();
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
CancelLongPress() {
|
|
2154
|
+
if (this.longPress) {
|
|
2155
|
+
clearTimeout(this.longPress.timer);
|
|
2156
|
+
this.longPress = null;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Completes the press in progress, if any: selects its row and starts
|
|
2161
|
+
* selection mode, as a long-press does in Gmail. The click that ends the same
|
|
2162
|
+
* press is then ignored, so it does not undo the selection.
|
|
2163
|
+
*/
|
|
2164
|
+
completeLongPress() {
|
|
2165
|
+
const press = this.longPress;
|
|
2166
|
+
if (!press)
|
|
2167
|
+
return;
|
|
2168
|
+
this.CancelLongPress();
|
|
2169
|
+
this.ignoreNextRowClick = true;
|
|
2170
|
+
this.IsSelectionMode = true;
|
|
2171
|
+
this.SelectedConversationIds.add(press.conversation.ID);
|
|
2172
|
+
this.selectionAnchorId = press.conversation.ID;
|
|
2173
|
+
this.cdr.detectChanges();
|
|
2174
|
+
}
|
|
2175
|
+
/**
|
|
2176
|
+
* Routes a row click. Ctrl/Cmd toggles one row and Shift extends from the
|
|
2177
|
+
* anchor, either one starting selection mode. On touch, while selecting, a tap
|
|
2178
|
+
* adds or removes the row. Any other click collapses the selection and opens
|
|
2179
|
+
* the conversation.
|
|
2180
|
+
*/
|
|
2181
|
+
HandleConversationClick(conversation, event) {
|
|
2182
|
+
if (this.ignoreNextRowClick) {
|
|
2183
|
+
this.ignoreNextRowClick = false;
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2186
|
+
if (this.IsSelectionMode && this.lastRowPointerType === 'touch') {
|
|
2187
|
+
this.toggleRowSelection(conversation.ID);
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
const isRangeClick = !!event?.shiftKey;
|
|
2191
|
+
const isToggleClick = !!event && (event.ctrlKey || event.metaKey);
|
|
2192
|
+
if (isRangeClick || isToggleClick) {
|
|
2193
|
+
event?.preventDefault(); // a Shift-click would otherwise paint a text selection
|
|
2194
|
+
const entering = !this.IsSelectionMode;
|
|
2195
|
+
if (entering) {
|
|
2196
|
+
this.IsSelectionMode = true;
|
|
2197
|
+
}
|
|
2198
|
+
if (isRangeClick) {
|
|
2199
|
+
this.selectRangeTo(conversation.ID);
|
|
2200
|
+
}
|
|
2201
|
+
else {
|
|
2202
|
+
// The open conversation reads as picked, so a Ctrl-click that starts a
|
|
2203
|
+
// selection takes it along; a Shift-click already ranges from it.
|
|
2204
|
+
const seeded = entering ? this.seedSelectionWithOpenConversation() : null;
|
|
2205
|
+
if (!seeded || !UUIDsEqual(seeded, conversation.ID)) {
|
|
2206
|
+
this.ToggleConversationSelection(conversation.ID);
|
|
2207
|
+
}
|
|
2208
|
+
this.selectionAnchorId = conversation.ID;
|
|
2209
|
+
this.exitSelectionModeIfEmpty();
|
|
2210
|
+
}
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
// A plain click collapses the selection down to this one conversation, the
|
|
2214
|
+
// way a file browser does.
|
|
2215
|
+
if (this.IsSelectionMode) {
|
|
2216
|
+
this.exitSelectionMode();
|
|
2217
|
+
}
|
|
2218
|
+
this.SelectConversation(conversation);
|
|
2219
|
+
}
|
|
2220
|
+
/** @deprecated Use {@link EnvironmentId}. */
|
|
2221
|
+
set environmentId(value) {
|
|
2222
|
+
this.EnvironmentId = value;
|
|
2223
|
+
}
|
|
2224
|
+
/** @deprecated Use {@link EnvironmentId}. */
|
|
2225
|
+
get environmentId() {
|
|
2226
|
+
return this.EnvironmentId;
|
|
2227
|
+
}
|
|
2228
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
2229
|
+
set currentUser(value) {
|
|
2230
|
+
this.CurrentUser = value;
|
|
2231
|
+
}
|
|
2232
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
2233
|
+
get currentUser() {
|
|
2234
|
+
return this.CurrentUser;
|
|
2235
|
+
}
|
|
2236
|
+
/** @deprecated Use {@link SelectedConversationId}. */
|
|
2237
|
+
set selectedConversationId(value) {
|
|
2238
|
+
this.SelectedConversationId = value;
|
|
2239
|
+
}
|
|
2240
|
+
/** @deprecated Use {@link SelectedConversationId}. */
|
|
2241
|
+
get selectedConversationId() {
|
|
2242
|
+
return this.SelectedConversationId;
|
|
2243
|
+
}
|
|
2244
|
+
/** @deprecated Use {@link RenamedConversationId}. */
|
|
2245
|
+
set renamedConversationId(value) {
|
|
2246
|
+
this.RenamedConversationId = value;
|
|
2247
|
+
}
|
|
2248
|
+
/** @deprecated Use {@link RenamedConversationId}. */
|
|
2249
|
+
get renamedConversationId() {
|
|
2250
|
+
return this.RenamedConversationId;
|
|
2251
|
+
}
|
|
2252
|
+
/** @deprecated Use {@link IsSidebarPinned}. */
|
|
2253
|
+
set isSidebarPinned(value) {
|
|
2254
|
+
this.IsSidebarPinned = value;
|
|
2255
|
+
}
|
|
2256
|
+
/** @deprecated Use {@link IsSidebarPinned}. */
|
|
2257
|
+
get isSidebarPinned() {
|
|
2258
|
+
return this.IsSidebarPinned;
|
|
2259
|
+
} // Whether sidebar is pinned (stays open after selection)
|
|
2260
|
+
/** @deprecated Use {@link IsMobileView}. */
|
|
2261
|
+
set isMobileView(value) {
|
|
2262
|
+
this.IsMobileView = value;
|
|
2263
|
+
}
|
|
2264
|
+
/** @deprecated Use {@link IsMobileView}. */
|
|
2265
|
+
get isMobileView() {
|
|
2266
|
+
return this.IsMobileView;
|
|
2267
|
+
} // Whether we're on mobile (no pin options)
|
|
2268
|
+
/** @deprecated Use {@link ShowNewConversationButton}. */
|
|
2269
|
+
set showNewConversationButton(value) {
|
|
2270
|
+
this.ShowNewConversationButton = value;
|
|
2271
|
+
}
|
|
2272
|
+
/** @deprecated Use {@link ShowNewConversationButton}. */
|
|
2273
|
+
get showNewConversationButton() {
|
|
2274
|
+
return this.ShowNewConversationButton;
|
|
2275
|
+
}
|
|
2276
|
+
/** @deprecated Use {@link ShowHeaderMenu}. */
|
|
2277
|
+
set showHeaderMenu(value) {
|
|
2278
|
+
this.ShowHeaderMenu = value;
|
|
2279
|
+
}
|
|
2280
|
+
/** @deprecated Use {@link ShowHeaderMenu}. */
|
|
2281
|
+
get showHeaderMenu() {
|
|
2282
|
+
return this.ShowHeaderMenu;
|
|
2283
|
+
}
|
|
2284
|
+
/** @deprecated Use {@link ShowSectionHeaders}. */
|
|
2285
|
+
set showSectionHeaders(value) {
|
|
2286
|
+
this.ShowSectionHeaders = value;
|
|
2287
|
+
}
|
|
2288
|
+
/** @deprecated Use {@link ShowSectionHeaders}. */
|
|
2289
|
+
get showSectionHeaders() {
|
|
2290
|
+
return this.ShowSectionHeaders;
|
|
2291
|
+
}
|
|
2292
|
+
/** @deprecated Use {@link DirectMessagesExpanded}. */
|
|
2293
|
+
get directMessagesExpanded() {
|
|
2294
|
+
return this.DirectMessagesExpanded;
|
|
2295
|
+
}
|
|
2296
|
+
/** @deprecated Use {@link DirectMessagesExpanded}. */
|
|
2297
|
+
set directMessagesExpanded(value) {
|
|
2298
|
+
this.DirectMessagesExpanded = value;
|
|
2299
|
+
}
|
|
2300
|
+
/** @deprecated Use {@link PinnedExpanded}. */
|
|
2301
|
+
get pinnedExpanded() {
|
|
2302
|
+
return this.PinnedExpanded;
|
|
2303
|
+
}
|
|
2304
|
+
/** @deprecated Use {@link PinnedExpanded}. */
|
|
2305
|
+
set pinnedExpanded(value) {
|
|
2306
|
+
this.PinnedExpanded = value;
|
|
2307
|
+
}
|
|
2308
|
+
/** @deprecated Use {@link FoldersExpanded}. */
|
|
2309
|
+
get foldersExpanded() {
|
|
2310
|
+
return this.FoldersExpanded;
|
|
2311
|
+
}
|
|
2312
|
+
/** @deprecated Use {@link FoldersExpanded}. */
|
|
2313
|
+
set foldersExpanded(value) {
|
|
2314
|
+
this.FoldersExpanded = value;
|
|
2315
|
+
}
|
|
2316
|
+
/** @deprecated Use {@link UngroupedExpanded}. */
|
|
2317
|
+
get ungroupedExpanded() {
|
|
2318
|
+
return this.UngroupedExpanded;
|
|
2319
|
+
}
|
|
2320
|
+
/** @deprecated Use {@link UngroupedExpanded}. */
|
|
2321
|
+
set ungroupedExpanded(value) {
|
|
2322
|
+
this.UngroupedExpanded = value;
|
|
2323
|
+
}
|
|
2324
|
+
/** @deprecated Use {@link ConversationIdsWithTasks}. */
|
|
2325
|
+
get conversationIdsWithTasks() {
|
|
2326
|
+
return this.ConversationIdsWithTasks;
|
|
2327
|
+
}
|
|
2328
|
+
/** @deprecated Use {@link ConversationIdsWithTasks}. */
|
|
2329
|
+
set conversationIdsWithTasks(value) {
|
|
2330
|
+
this.ConversationIdsWithTasks = value;
|
|
2331
|
+
}
|
|
2332
|
+
/** @deprecated Use {@link IsSelectionMode}. */
|
|
2333
|
+
get isSelectionMode() {
|
|
2334
|
+
return this.IsSelectionMode;
|
|
2335
|
+
}
|
|
2336
|
+
/** @deprecated Use {@link IsSelectionMode}. */
|
|
2337
|
+
set isSelectionMode(value) {
|
|
2338
|
+
this.IsSelectionMode = value;
|
|
2339
|
+
}
|
|
2340
|
+
/** @deprecated Use {@link SelectedConversationIds}. */
|
|
2341
|
+
get selectedConversationIds() {
|
|
2342
|
+
return this.SelectedConversationIds;
|
|
2343
|
+
}
|
|
2344
|
+
/** @deprecated Use {@link SelectedConversationIds}. */
|
|
2345
|
+
set selectedConversationIds(value) {
|
|
2346
|
+
this.SelectedConversationIds = value;
|
|
2347
|
+
}
|
|
2348
|
+
/** @deprecated Use {@link IsHeaderMenuOpen}. */
|
|
2349
|
+
get isHeaderMenuOpen() {
|
|
2350
|
+
return this.IsHeaderMenuOpen;
|
|
2351
|
+
}
|
|
2352
|
+
/** @deprecated Use {@link IsHeaderMenuOpen}. */
|
|
2353
|
+
set isHeaderMenuOpen(value) {
|
|
2354
|
+
this.IsHeaderMenuOpen = value;
|
|
2355
|
+
}
|
|
2356
|
+
/** @deprecated Use {@link IsRefreshing}. */
|
|
2357
|
+
get isRefreshing() {
|
|
2358
|
+
return this.IsRefreshing;
|
|
2359
|
+
}
|
|
2360
|
+
/** @deprecated Use {@link IsRefreshing}. */
|
|
2361
|
+
set isRefreshing(value) {
|
|
2362
|
+
this.IsRefreshing = value;
|
|
2363
|
+
}
|
|
2364
|
+
/** @deprecated Use {@link GroupBy}. */
|
|
2365
|
+
get groupBy() {
|
|
2366
|
+
return this.GroupBy;
|
|
2367
|
+
}
|
|
2368
|
+
/** @deprecated Use {@link GroupBy}. */
|
|
2369
|
+
set groupBy(value) {
|
|
2370
|
+
this.GroupBy = value;
|
|
2371
|
+
}
|
|
2372
|
+
/** @deprecated Use {@link PinnedConversations}. */
|
|
2373
|
+
get pinnedConversations() {
|
|
2374
|
+
return this.PinnedConversations;
|
|
2375
|
+
}
|
|
2376
|
+
/** @deprecated Use {@link PinnedConversations}. */
|
|
2377
|
+
set pinnedConversations(value) {
|
|
2378
|
+
this.PinnedConversations = value;
|
|
2379
|
+
}
|
|
2380
|
+
/** @deprecated Use {@link UnpinnedConversations}. */
|
|
2381
|
+
get unpinnedConversations() {
|
|
2382
|
+
return this.UnpinnedConversations;
|
|
2383
|
+
}
|
|
2384
|
+
/** @deprecated Use {@link UnpinnedConversations}. */
|
|
2385
|
+
set unpinnedConversations(value) {
|
|
2386
|
+
this.UnpinnedConversations = value;
|
|
2387
|
+
}
|
|
2388
|
+
/** @deprecated Use {@link UngroupedConversations}. */
|
|
2389
|
+
get ungroupedConversations() {
|
|
2390
|
+
return this.UngroupedConversations;
|
|
2391
|
+
}
|
|
2392
|
+
/** @deprecated Use {@link UngroupedConversations}. */
|
|
2393
|
+
set ungroupedConversations(value) {
|
|
2394
|
+
this.UngroupedConversations = value;
|
|
2395
|
+
}
|
|
2396
|
+
/** @deprecated Use {@link FolderTree}. */
|
|
2397
|
+
get folderTree() {
|
|
2398
|
+
return this.FolderTree;
|
|
2399
|
+
}
|
|
2400
|
+
/** @deprecated Use {@link FolderTree}. */
|
|
2401
|
+
set folderTree(value) {
|
|
2402
|
+
this.FolderTree = value;
|
|
2403
|
+
}
|
|
2404
|
+
/** @deprecated Use {@link FlatFolders}. */
|
|
2405
|
+
get flatFolders() {
|
|
2406
|
+
return this.FlatFolders;
|
|
2407
|
+
}
|
|
2408
|
+
/** @deprecated Use {@link FlatFolders}. */
|
|
2409
|
+
set flatFolders(value) {
|
|
2410
|
+
this.FlatFolders = value;
|
|
2411
|
+
}
|
|
2412
|
+
/** @deprecated Use {@link DraggedFolderId}. */
|
|
2413
|
+
get draggedFolderId() {
|
|
2414
|
+
return this.DraggedFolderId;
|
|
2415
|
+
}
|
|
2416
|
+
/** @deprecated Use {@link DraggedFolderId}. */
|
|
2417
|
+
set draggedFolderId(value) {
|
|
2418
|
+
this.DraggedFolderId = value;
|
|
2419
|
+
}
|
|
2420
|
+
/** @deprecated Use {@link DragOverTargetId}. */
|
|
2421
|
+
get dragOverTargetId() {
|
|
2422
|
+
return this.DragOverTargetId;
|
|
2423
|
+
}
|
|
2424
|
+
/** @deprecated Use {@link DragOverTargetId}. */
|
|
2425
|
+
set dragOverTargetId(value) {
|
|
2426
|
+
this.DragOverTargetId = value;
|
|
2427
|
+
}
|
|
2428
|
+
/** @deprecated Use {@link SearchQuery}. */
|
|
2429
|
+
get searchQuery() {
|
|
2430
|
+
return this.SearchQuery;
|
|
2431
|
+
}
|
|
2432
|
+
/** @deprecated Use {@link SearchQuery}. */
|
|
2433
|
+
set searchQuery(value) {
|
|
2434
|
+
this.SearchQuery = value;
|
|
2435
|
+
}
|
|
2436
|
+
/** @deprecated Use {@link IsSearching}. */
|
|
2437
|
+
get isSearching() {
|
|
2438
|
+
return this.IsSearching;
|
|
2439
|
+
}
|
|
2440
|
+
/** @deprecated Use {@link ToggleHeaderMenu}. */
|
|
2441
|
+
toggleHeaderMenu(event) {
|
|
2442
|
+
return this.ToggleHeaderMenu(event);
|
|
2443
|
+
}
|
|
2444
|
+
/** @deprecated Use {@link CloseHeaderMenu}. */
|
|
2445
|
+
closeHeaderMenu() {
|
|
2446
|
+
return this.CloseHeaderMenu();
|
|
2447
|
+
}
|
|
2448
|
+
/** @deprecated Use {@link OnToggleGroupByClick}. */
|
|
2449
|
+
onToggleGroupByClick(event) {
|
|
2450
|
+
return this.OnToggleGroupByClick(event);
|
|
2451
|
+
}
|
|
2452
|
+
/** @deprecated Use {@link OnRefreshConversationsClick}. */
|
|
2453
|
+
onRefreshConversationsClick(event) {
|
|
2454
|
+
return this.OnRefreshConversationsClick(event);
|
|
2455
|
+
}
|
|
2456
|
+
/** @deprecated Use {@link OnPinSidebarClick}. */
|
|
2457
|
+
onPinSidebarClick(event) {
|
|
2458
|
+
return this.OnPinSidebarClick(event);
|
|
2459
|
+
}
|
|
2460
|
+
/** @deprecated Use {@link OnUnpinSidebarClick}. */
|
|
2461
|
+
onUnpinSidebarClick(event) {
|
|
2462
|
+
return this.OnUnpinSidebarClick(event);
|
|
2463
|
+
}
|
|
2464
|
+
/** @deprecated Use {@link ToggleDirectMessages}. */
|
|
2465
|
+
toggleDirectMessages() {
|
|
2466
|
+
return this.ToggleDirectMessages();
|
|
2467
|
+
}
|
|
2468
|
+
/** @deprecated Use {@link TogglePinned}. */
|
|
2469
|
+
togglePinned() {
|
|
2470
|
+
return this.TogglePinned();
|
|
2471
|
+
}
|
|
2472
|
+
/** @deprecated Use {@link ToggleFolders}. */
|
|
2473
|
+
toggleFolders() {
|
|
2474
|
+
return this.ToggleFolders();
|
|
2475
|
+
}
|
|
2476
|
+
/** @deprecated Use {@link ToggleUngrouped}. */
|
|
2477
|
+
toggleUngrouped() {
|
|
2478
|
+
return this.ToggleUngrouped();
|
|
2479
|
+
}
|
|
2480
|
+
/** @deprecated Use {@link IsFolderExpanded}. */
|
|
2481
|
+
isFolderExpanded(projectId) {
|
|
2482
|
+
return this.IsFolderExpanded(projectId);
|
|
2483
|
+
}
|
|
2484
|
+
/** @deprecated Use {@link ToggleFolder}. */
|
|
2485
|
+
toggleFolder(projectId) {
|
|
2486
|
+
return this.ToggleFolder(projectId);
|
|
2487
|
+
}
|
|
2488
|
+
/** @deprecated Use {@link ToggleGroupBy}. */
|
|
2489
|
+
toggleGroupBy() {
|
|
2490
|
+
return this.ToggleGroupBy();
|
|
2491
|
+
}
|
|
2492
|
+
/** @deprecated Use {@link OnConversationDragStart}. */
|
|
2493
|
+
onConversationDragStart(conversation, event) {
|
|
2494
|
+
return this.OnConversationDragStart(conversation, event);
|
|
2495
|
+
}
|
|
2496
|
+
/** @deprecated Use {@link OnConversationDragEnd}. */
|
|
2497
|
+
onConversationDragEnd() {
|
|
2498
|
+
return this.OnConversationDragEnd();
|
|
2499
|
+
}
|
|
2500
|
+
/** @deprecated Use {@link OnFolderDragStart}. */
|
|
2501
|
+
onFolderDragStart(node, event) {
|
|
2502
|
+
return this.OnFolderDragStart(node, event);
|
|
2503
|
+
}
|
|
2504
|
+
/** @deprecated Use {@link OnFolderDragEnd}. */
|
|
2505
|
+
onFolderDragEnd() {
|
|
2506
|
+
return this.OnFolderDragEnd();
|
|
2507
|
+
}
|
|
2508
|
+
/** @deprecated Use {@link OnFolderDragOver}. */
|
|
2509
|
+
onFolderDragOver(projectId, event) {
|
|
2510
|
+
return this.OnFolderDragOver(projectId, event);
|
|
2511
|
+
}
|
|
2512
|
+
/** @deprecated Use {@link OnUngroupedDragOver}. */
|
|
2513
|
+
onUngroupedDragOver(event) {
|
|
2514
|
+
return this.OnUngroupedDragOver(event);
|
|
2515
|
+
}
|
|
2516
|
+
/** @deprecated Use {@link OnFoldersRootDragOver}. */
|
|
2517
|
+
onFoldersRootDragOver(event) {
|
|
2518
|
+
return this.OnFoldersRootDragOver(event);
|
|
2519
|
+
}
|
|
2520
|
+
/** @deprecated Use {@link OnDragLeave}. */
|
|
2521
|
+
onDragLeave(targetId) {
|
|
2522
|
+
return this.OnDragLeave(targetId);
|
|
2523
|
+
}
|
|
2524
|
+
/** @deprecated Use {@link OnFolderDrop}. */
|
|
2525
|
+
onFolderDrop(project, event) {
|
|
2526
|
+
return this.OnFolderDrop(project, event);
|
|
2527
|
+
}
|
|
2528
|
+
/** @deprecated Use {@link OnUngroupedDrop}. */
|
|
2529
|
+
onUngroupedDrop(event) {
|
|
2530
|
+
return this.OnUngroupedDrop(event);
|
|
2531
|
+
}
|
|
2532
|
+
/** @deprecated Use {@link OnFoldersRootDrop}. */
|
|
2533
|
+
onFoldersRootDrop(event) {
|
|
2534
|
+
return this.OnFoldersRootDrop(event);
|
|
2535
|
+
}
|
|
2536
|
+
/** @deprecated Use {@link OpenMoveSubmenu}. */
|
|
2537
|
+
openMoveSubmenu(event) {
|
|
2538
|
+
return this.OpenMoveSubmenu(event);
|
|
2539
|
+
}
|
|
2540
|
+
/** @deprecated Use {@link CloseMoveSubmenu}. */
|
|
2541
|
+
closeMoveSubmenu(event) {
|
|
2542
|
+
return this.CloseMoveSubmenu(event);
|
|
2543
|
+
}
|
|
2544
|
+
/** @deprecated Use {@link CreateFolder}. */
|
|
2545
|
+
createFolder(parentId, event) {
|
|
2546
|
+
return this.CreateFolder(parentId, event);
|
|
2547
|
+
}
|
|
2548
|
+
/** @deprecated Use {@link EditFolder}. */
|
|
2549
|
+
editFolder(project, event) {
|
|
2550
|
+
return this.EditFolder(project, event);
|
|
2551
|
+
}
|
|
2552
|
+
/** @deprecated Use {@link DeleteFolder}. */
|
|
2553
|
+
deleteFolder(project, event) {
|
|
2554
|
+
return this.DeleteFolder(project, event);
|
|
2555
|
+
}
|
|
2556
|
+
/** @deprecated Use {@link SelectConversation}. */
|
|
2557
|
+
selectConversation(conversation) {
|
|
2558
|
+
return this.SelectConversation(conversation);
|
|
2559
|
+
}
|
|
2560
|
+
/** @deprecated Use {@link CreateNewConversation}. */
|
|
2561
|
+
createNewConversation() {
|
|
2562
|
+
return this.CreateNewConversation();
|
|
2563
|
+
}
|
|
2564
|
+
/** @deprecated Use {@link RenameConversation}. */
|
|
2565
|
+
renameConversation(conversation) {
|
|
2566
|
+
return this.RenameConversation(conversation);
|
|
2567
|
+
}
|
|
2568
|
+
/** @deprecated Use {@link DeleteConversation}. */
|
|
2569
|
+
deleteConversation(conversation) {
|
|
2570
|
+
return this.DeleteConversation(conversation);
|
|
2571
|
+
}
|
|
2572
|
+
/** @deprecated Use {@link TogglePin}. */
|
|
2573
|
+
togglePin(conversation, event) {
|
|
2574
|
+
return this.TogglePin(conversation, event);
|
|
2575
|
+
}
|
|
2576
|
+
/** @deprecated Use {@link HasActiveTasks}. */
|
|
2577
|
+
hasActiveTasks(conversationId) {
|
|
2578
|
+
return this.HasActiveTasks(conversationId);
|
|
2579
|
+
}
|
|
2580
|
+
/** @deprecated Use {@link IsSharedWithMe}. */
|
|
2581
|
+
isSharedWithMe(conversation) {
|
|
2582
|
+
return this.IsSharedWithMe(conversation);
|
|
2583
|
+
}
|
|
2584
|
+
/** @deprecated Use {@link SharedWithMeTooltip}. */
|
|
2585
|
+
sharedWithMeTooltip(conversation) {
|
|
2586
|
+
return this.SharedWithMeTooltip(conversation);
|
|
2587
|
+
}
|
|
2588
|
+
/** @deprecated Use {@link ToggleSelectionMode}. */
|
|
2589
|
+
toggleSelectionMode() {
|
|
2590
|
+
return this.ToggleSelectionMode();
|
|
2591
|
+
}
|
|
2592
|
+
/** @deprecated Use {@link ToggleConversationSelection}. */
|
|
2593
|
+
toggleConversationSelection(conversationId) {
|
|
2594
|
+
return this.ToggleConversationSelection(conversationId);
|
|
2595
|
+
}
|
|
2596
|
+
/** @deprecated Use {@link SelectAll}. */
|
|
2597
|
+
selectAll() {
|
|
2598
|
+
return this.SelectAll();
|
|
2599
|
+
}
|
|
2600
|
+
/** @deprecated Use {@link DeselectAll}. */
|
|
2601
|
+
deselectAll() {
|
|
2602
|
+
return this.DeselectAll();
|
|
2603
|
+
}
|
|
2604
|
+
/** @deprecated Use {@link BulkDeleteConversations}. */
|
|
2605
|
+
bulkDeleteConversations(ids) {
|
|
2606
|
+
return this.BulkDeleteConversations(ids);
|
|
2607
|
+
}
|
|
2608
|
+
/** @deprecated Use {@link HandleConversationClick}. */
|
|
2609
|
+
handleConversationClick(conversation, event) {
|
|
2610
|
+
return this.HandleConversationClick(conversation, event);
|
|
1313
2611
|
}
|
|
1314
2612
|
static ɵfac = function ConversationListComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ConversationListComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.NotificationService), i0.ɵɵdirectiveInject(i3.ActiveTasksService), i0.ɵɵdirectiveInject(i4.MJDialogService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
1315
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationListComponent, selectors: [["mj-conversation-list"]],
|
|
1316
|
-
i0.ɵɵ
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
i0.ɵɵ
|
|
1320
|
-
i0.ɵɵ
|
|
1321
|
-
|
|
1322
|
-
i0.ɵɵ
|
|
1323
|
-
|
|
2613
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationListComponent, selectors: [["mj-conversation-list"]], viewQuery: function ConversationListComponent_Query(rf, ctx) { if (rf & 1) {
|
|
2614
|
+
i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
|
|
2615
|
+
} if (rf & 2) {
|
|
2616
|
+
let _t;
|
|
2617
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchInput = _t.first);
|
|
2618
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.contextMenuEl = _t.first);
|
|
2619
|
+
} }, hostBindings: function ConversationListComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2620
|
+
i0.ɵɵlistener("click", function ConversationListComponent_click_HostBindingHandler() { return ctx.onDocumentClick(); }, i0.ɵɵresolveDocument)("keydown.escape", function ConversationListComponent_keydown_escape_HostBindingHandler() { return ctx.onDocumentEscape(); }, i0.ɵɵresolveDocument);
|
|
2621
|
+
} }, inputs: { EnvironmentId: "EnvironmentId", CurrentUser: "CurrentUser", SelectedConversationId: "SelectedConversationId", RenamedConversationId: "RenamedConversationId", IsSidebarPinned: "IsSidebarPinned", IsMobileView: "IsMobileView", showSearch: "showSearch", ShowNewConversationButton: "ShowNewConversationButton", ShowHeaderMenu: "ShowHeaderMenu", ShowSectionHeaders: "ShowSectionHeaders", environmentId: "environmentId", currentUser: "currentUser", selectedConversationId: "selectedConversationId", renamedConversationId: "renamedConversationId", isSidebarPinned: "isSidebarPinned", isMobileView: "isMobileView", showNewConversationButton: "showNewConversationButton", showHeaderMenu: "showHeaderMenu", showSectionHeaders: "showSectionHeaders" }, outputs: { ConversationSelected: "ConversationSelected", conversationSelected: "conversationSelected", ConversationDeleted: "ConversationDeleted", conversationDeleted: "conversationDeleted", NewConversationRequested: "NewConversationRequested", newConversationRequested: "newConversationRequested", PinSidebarRequested: "PinSidebarRequested", pinSidebarRequested: "pinSidebarRequested", UnpinSidebarRequested: "UnpinSidebarRequested", unpinSidebarRequested: "unpinSidebarRequested", RefreshRequested: "RefreshRequested", refreshRequested: "refreshRequested", SearchEscalated: "SearchEscalated" }, standalone: false, decls: 14, vars: 12, consts: [["folderNode", ""], ["conversationItem", ""], ["searchInput", ""], ["contextMenuEl", ""], [1, "conversation-list"], [1, "list-header"], ["title", "New Conversation", 1, "btn-new-conversation"], [1, "list-content", 3, "click", "contextmenu"], [1, "sidebar-section", "pinned-section"], [1, "sidebar-section"], [1, "search-escalate"], ["ResourceLabel", "conversation", 3, "Result", "Visible", "Contexts", "Adapter", "Notice"], [1, "list-context-menu", 3, "left", "top"], [1, "header-top"], ["role", "toolbar", "aria-label", "Selected conversations", 1, "selection-bar"], [1, "sort-row"], ["title", "Clear selection", "aria-label", "Clear selection", 1, "selection-bar-btn", 3, "click"], [1, "fas", "fa-xmark"], [1, "selection-count"], [1, "selection-bar-btn", 3, "click", "disabled", "title"], [1, "fas", "fa-thumbtack"], ["aria-label", "Move to folder", 1, "selection-bar-btn", 3, "click", "disabled", "title"], [1, "fas", "fa-folder-tree"], ["aria-label", "Share", 1, "selection-bar-btn", 3, "click", "disabled", "title"], [1, "fas", "fa-user-plus"], ["title", "Delete", "aria-label", "Delete", 1, "selection-bar-btn", "danger", 3, "click"], [1, "fas", "fa-trash"], [1, "search-box"], [1, "header-menu-container"], ["type", "text", "placeholder", "Search conversations...", 1, "search-input", 3, "ngModelChange", "keydown", "ngModel"], ["title", "Clear search", 1, "search-clear"], ["title", "Clear search", 1, "search-clear", 3, "click"], ["title", "Options", 1, "btn-menu", 3, "click"], [1, "fas", "fa-ellipsis-v"], [1, "header-dropdown-menu"], [1, "dropdown-item", 3, "click", "disabled"], [1, "fas", "fa-sync-alt"], [1, "dropdown-item", 3, "click"], [1, "fas"], [1, "dropdown-item"], [1, "fas", "fa-table-columns"], [1, "sort-btn", 3, "click", "title"], [1, "fas", 3, "ngClass"], ["title", "New Conversation", 1, "btn-new-conversation", 3, "click"], [1, "fas", "fa-plus"], [1, "section-header", 3, "expanded"], [1, "chat-list"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "section-header", 3, "click"], [1, "section-title"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-thumbtack", "section-icon"], [1, "sidebar-section", "folders-section"], [1, "section-header", 3, "click", "dragover", "dragleave", "drop"], ["title", "New Folder", 1, "section-action-btn", 3, "click"], [1, "fas", "fa-folder-plus"], [1, "folder-empty-hint"], [1, "sidebar-section", "ungrouped-section", 3, "dragover", "dragleave", "drop"], [1, "search-escalate", 3, "click"], [1, "fa-solid", "fa-magnifying-glass"], [1, "search-escalate-label"], [1, "fa-solid", "fa-arrow-right", "search-escalate-go"], [1, "folder-row", 3, "dragstart", "dragend", "click", "dragover", "dragleave", "drop", "contextmenu", "draggable", "title"], [1, "fas", "fa-chevron-right", "folder-chevron"], [1, "folder-name"], ["role", "img", "title", "Shared \u2014 everyone can see this folder and its name, but not the conversations in it", "aria-label", "Shared folder", 1, "folder-shared"], [1, "folder-spacer"], [1, "folder-count"], [1, "folder-children"], ["aria-hidden", "true", 1, "fas", "fa-users"], [1, "folder-empty-hint", 3, "paddingLeft"], [1, "conversation-item", 3, "dragstart", "dragend", "dragover", "dragleave", "drop", "pointerdown", "pointermove", "pointerup", "pointercancel", "click", "contextmenu", "draggable"], ["role", "checkbox", 1, "row-check", 3, "click"], [1, "fas", "fa-check"], [1, "conversation-icon-wrapper"], [1, "conversation-icon", "has-tasks"], [1, "badge-overlay"], [3, "conversationId"], [1, "conversation-info", 3, "title"], [1, "conversation-name"], [1, "fas", "fa-share-nodes", "shared-indicator", 3, "title"], [1, "conversation-preview"], [1, "conversation-actions"], ["title", "More options", 1, "menu-btn", 3, "click"], [1, "fas", "fa-ellipsis"], [1, "fas", "fa-spinner", "fa-pulse"], [1, "list-context-menu", 3, "click", "contextmenu"], [1, "menu-item", "back", 3, "click"], [1, "fas", "fa-chevron-left"], [1, "menu-divider"], [1, "move-folder-list"], [1, "menu-item", 3, "click"], [1, "fas", "fa-inbox"], [1, "menu-item", 3, "current", "paddingLeft"], [1, "menu-item", 3, "disabled"], [1, "menu-item", 3, "click", "disabled"], [1, "fas", "fa-chevron-right", "submenu-arrow"], [1, "menu-item"], [1, "menu-item", "danger", 3, "click"], [1, "context-menu-header"], [1, "fas", "fa-thumbtack", "fa-rotate-90"], [1, "fas", "fa-edit"], [1, "fas", "fa-pen"], [1, "fas", "fa-check-double"]], template: function ConversationListComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2622
|
+
i0.ɵɵelementStart(0, "div", 4);
|
|
2623
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_Conditional_1_Template, 5, 2, "div", 5);
|
|
2624
|
+
i0.ɵɵconditionalCreate(2, ConversationListComponent_Conditional_2_Template, 4, 0, "button", 6);
|
|
2625
|
+
i0.ɵɵelementStart(3, "div", 7);
|
|
2626
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Template_div_click_3_listener($event) { return ctx.OnListBackgroundClick($event); })("contextmenu", function ConversationListComponent_Template_div_contextmenu_3_listener($event) { return ctx.OnBackgroundContextMenu($event); });
|
|
2627
|
+
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_4_Template, 5, 3, "div", 8);
|
|
2628
|
+
i0.ɵɵconditionalCreate(5, ConversationListComponent_Conditional_5_Template, 21, 14)(6, ConversationListComponent_Conditional_6_Template, 5, 3, "div", 9);
|
|
2629
|
+
i0.ɵɵelementEnd();
|
|
2630
|
+
i0.ɵɵconditionalCreate(7, ConversationListComponent_Conditional_7_Template, 5, 1, "button", 10);
|
|
1324
2631
|
i0.ɵɵelementEnd();
|
|
1325
|
-
i0.ɵɵ
|
|
2632
|
+
i0.ɵɵtemplate(8, ConversationListComponent_ng_template_8_Template, 10, 19, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(10, ConversationListComponent_ng_template_10_Template, 16, 23, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
2633
|
+
i0.ɵɵelementStart(12, "mj-resource-share-dialog", 11);
|
|
2634
|
+
i0.ɵɵlistener("Result", function ConversationListComponent_Template_mj_resource_share_dialog_Result_12_listener($event) { return ctx.OnShareDialogResult($event); });
|
|
1326
2635
|
i0.ɵɵelementEnd();
|
|
1327
|
-
i0.ɵɵ
|
|
2636
|
+
i0.ɵɵconditionalCreate(13, ConversationListComponent_Conditional_13_Template, 5, 5, "div", 12);
|
|
1328
2637
|
} if (rf & 2) {
|
|
2638
|
+
i0.ɵɵclassProp("is-selecting", ctx.IsSelectionMode);
|
|
1329
2639
|
i0.ɵɵadvance();
|
|
1330
|
-
i0.ɵɵconditional(ctx.showSearch || ctx.
|
|
2640
|
+
i0.ɵɵconditional(ctx.showSearch || ctx.ShowHeaderMenu || ctx.IsSelectionMode ? 1 : -1);
|
|
1331
2641
|
i0.ɵɵadvance();
|
|
1332
|
-
i0.ɵɵconditional(ctx.
|
|
2642
|
+
i0.ɵɵconditional(ctx.ShowNewConversationButton ? 2 : -1);
|
|
1333
2643
|
i0.ɵɵadvance(2);
|
|
1334
|
-
i0.ɵɵconditional(ctx.
|
|
2644
|
+
i0.ɵɵconditional(ctx.PinnedConversations.length > 0 ? 4 : -1);
|
|
1335
2645
|
i0.ɵɵadvance();
|
|
1336
|
-
i0.ɵɵconditional(ctx.
|
|
2646
|
+
i0.ɵɵconditional(ctx.ShowSectionHeaders && ctx.GroupBy === "project" ? 5 : 6);
|
|
1337
2647
|
i0.ɵɵadvance(2);
|
|
1338
|
-
i0.ɵɵconditional(ctx.
|
|
1339
|
-
} }, dependencies: [i5.NgTemplateOutlet, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, i7.NotificationBadgeComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n --conv-list-bg: var(--mj-chat-list-bg, var(--mj-brand-secondary));\n --conv-list-ink: var(--mj-chat-list-ink, var(--mj-brand-on-secondary));\n --conv-list-active-bg: var(--mj-chat-list-active-bg, var(--mj-brand-primary));\n --conv-list-active-ink: var(--mj-chat-list-active-ink, var(--mj-brand-on-secondary));\n --conv-list-active-hover-bg: var(--mj-chat-list-active-hover-bg, var(--mj-brand-primary-hover));\n --conv-list-accent: var(--mj-chat-list-accent, var(--mj-brand-primary));\n --conv-list-accent-ink: var(--mj-chat-list-accent-ink, var(--mj-text-inverse));\n --conv-list-accent-hover: var(--mj-chat-list-accent-hover, var(--mj-brand-primary-hover));\n --conv-list-hover-bg: var(--mj-chat-list-hover-bg, color-mix(in srgb, var(--conv-list-ink) 8%, transparent));\n }\n .conversation-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; height: 100%; background: var(--conv-list-bg); }\n .list-header[_ngcontent-%COMP%] { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent); }\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input[_ngcontent-%COMP%]::placeholder { color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); }\n .search-input[_ngcontent-%COMP%]:focus { outline: none; background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent); border-color: var(--conv-list-accent); }\n .btn-new-conversation[_ngcontent-%COMP%] {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation[_ngcontent-%COMP%]:hover { background: var(--conv-list-accent-hover); }\n .btn-new-conversation[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 14px; }\n .list-content[_ngcontent-%COMP%] { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n \n .sidebar-section[_ngcontent-%COMP%] { margin-bottom: 20px; }\n .pinned-section[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] .section-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header[_ngcontent-%COMP%] {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:not(.section-icon) { transform: rotate(90deg); }\n .chat-list[_ngcontent-%COMP%] {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded[_ngcontent-%COMP%] { display: block; }\n\n .conversation-item[_ngcontent-%COMP%] {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item[_ngcontent-%COMP%]:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; }\n .conversation-item.active[_ngcontent-%COMP%] { background: var(--conv-list-active-bg); color: var(--conv-list-active-ink); }\n .conversation-icon-wrapper[_ngcontent-%COMP%] { position: relative; flex-shrink: 0; }\n .conversation-icon[_ngcontent-%COMP%] { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .badge-overlay[_ngcontent-%COMP%] { position: absolute; top: -4px; right: -4px; }\n .conversation-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .conversation-name[_ngcontent-%COMP%] { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator[_ngcontent-%COMP%] { font-size: 10px; color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--conv-list-active-ink) 85%, transparent); }\n .conversation-preview[_ngcontent-%COMP%] { font-size: 12px; color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active[_ngcontent-%COMP%] .conversation-preview[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--conv-list-active-ink) 80%, transparent); }\n .conversation-meta[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n \n .project-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item[_ngcontent-%COMP%]:hover .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n }\n .conversation-item.active[_ngcontent-%COMP%] .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--conv-list-active-ink) 20%, transparent);\n color: var(--conv-list-active-ink);\n }\n\n .conversation-actions[_ngcontent-%COMP%] {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n .conversation-item.active[_ngcontent-%COMP%] .conversation-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n .conversation-actions[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] { pointer-events: auto; }\n .pinned-icon[_ngcontent-%COMP%] { color: var(--mj-brand-accent); font-size: 12px; }\n\n \n .task-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_pulse-glow 2s ease-in-out infinite;\n }\n @keyframes _ngcontent-%COMP%_pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active[_ngcontent-%COMP%] .task-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n }\n\n .menu-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n background: var(--conv-list-bg) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent) !important;\n color: var(--conv-list-ink);\n }\n .conversation-item.active[_ngcontent-%COMP%] .menu-btn[_ngcontent-%COMP%] {\n background: var(--conv-list-active-hover-bg) !important;\n color: var(--conv-list-active-ink);\n }\n .menu-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 14px; }\n\n .context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n pointer-events: auto;\n }\n\n .menu-item[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .menu-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--conv-list-ink);\n }\n\n .menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin: 4px 0;\n }\n\n \n .conversation-item.renamed[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n \n\n\n @keyframes _ngcontent-%COMP%_renameHighlight {\n 0% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 40%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 40%, transparent));\n transform: scale(1.03);\n box-shadow: 0 0 20px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n 25% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 35%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 35%, transparent));\n box-shadow: 0 0 15px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n 50% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 30%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 30%, transparent));\n transform: scale(1.02);\n box-shadow: 0 0 10px color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n 75% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 20%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 20%, transparent));\n box-shadow: 0 0 5px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n \n .header-top[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n \n .header-menu-container[_ngcontent-%COMP%] {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] .shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--conv-list-ink) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .conversation-checkbox[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-right: 8px;\n flex-shrink: 0;\n }\n\n .conversation-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--conv-list-accent);\n }\n\n .selection-action-bar[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--conv-list-bg);\n border-top: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n gap: 12px;\n flex-wrap: wrap;\n flex-shrink: 0;\n }\n\n .selection-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n color: color-mix(in srgb, var(--conv-list-ink) 90%, transparent);\n font-size: 14px;\n font-weight: 500;\n flex: 1 1 auto;\n min-width: 150px;\n }\n\n .selection-count[_ngcontent-%COMP%] {\n color: var(--conv-list-ink);\n }\n\n .link-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-brand-accent);\n cursor: pointer;\n font-size: 13px;\n text-decoration: underline;\n padding: 0;\n transition: color 0.2s;\n }\n\n .link-btn[_ngcontent-%COMP%]:hover {\n color: var(--conv-list-ink);\n }\n\n .selection-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex: 0 0 auto;\n }\n\n .btn-cancel[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n }\n\n .btn-cancel[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .btn-delete-bulk[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-error);\n border: none;\n border-radius: 6px;\n \n\n\n color: var(--mj-brand-on-secondary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: all 0.2s;\n }\n\n .btn-delete-bulk[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 80%, black);\n }\n\n .btn-delete-bulk[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .btn-delete-bulk[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n \n .section-action-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: var(--conv-list-ink);\n }\n .section-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 12px; }\n\n .folder-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n cursor: pointer;\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n font-size: 13px;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n }\n .folder-row[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .folder-row.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n }\n .folder-row.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n .section-header.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n .folder-chevron[_ngcontent-%COMP%] {\n font-size: 9px;\n width: 10px;\n flex-shrink: 0;\n transition: transform 0.2s;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n }\n .folder-chevron.expanded[_ngcontent-%COMP%] { transform: rotate(90deg); }\n .folder-icon[_ngcontent-%COMP%] { font-size: 12px; width: 16px; text-align: center; flex-shrink: 0; }\n .folder-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 600;\n }\n .folder-count[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n flex-shrink: 0;\n margin-left: auto;\n padding-left: 6px;\n text-align: right;\n }\n .folder-actions[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n gap: 2px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 5;\n }\n .folder-row[_ngcontent-%COMP%]:hover .folder-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n .folder-row[_ngcontent-%COMP%]:hover .folder-count[_ngcontent-%COMP%] { opacity: 0; }\n .folder-action-btn[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.15s;\n }\n .folder-action-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 18%, transparent);\n color: var(--conv-list-ink);\n }\n .folder-action-btn.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 18%, transparent);\n color: var(--mj-status-error);\n }\n .folder-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 11px; }\n .folder-children[_ngcontent-%COMP%] { display: block; }\n .folder-empty-hint[_ngcontent-%COMP%] {\n padding: 6px 16px;\n font-size: 11px;\n font-style: italic;\n color: color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n }\n .ungrouped-section.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n\n \n .conversation-item[_ngcontent-%COMP%] { user-select: none; }\n .conversation-item.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n\n \n .menu-item.back[_ngcontent-%COMP%] { font-weight: 600; }\n .menu-item[_ngcontent-%COMP%] .submenu-arrow[_ngcontent-%COMP%] { margin-left: auto; font-size: 10px; }\n .menu-item.current[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent); }\n .move-folder-list[_ngcontent-%COMP%] { max-height: 240px; overflow-y: auto; }"] });
|
|
2648
|
+
i0.ɵɵconditional(ctx.IsSearching && !ctx.IsSelectionMode ? 7 : -1);
|
|
2649
|
+
i0.ɵɵadvance(5);
|
|
2650
|
+
i0.ɵɵproperty("Visible", ctx.IsShareDialogOpen)("Contexts", ctx.ShareContexts)("Adapter", ctx.ShareAdapter)("Notice", ctx.ShareNotice);
|
|
2651
|
+
i0.ɵɵadvance();
|
|
2652
|
+
i0.ɵɵconditional(ctx.ContextMenu ? 13 : -1);
|
|
2653
|
+
} }, dependencies: [i5.NgClass, i5.NgTemplateOutlet, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, i7.GenericShareDialogComponent, i8.NotificationBadgeComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n --conv-list-bg: var(--mj-chat-list-bg, var(--mj-brand-secondary));\n --conv-list-ink: var(--mj-chat-list-ink, var(--mj-brand-on-secondary));\n --conv-list-active-bg: var(--mj-chat-list-active-bg, var(--mj-brand-primary));\n --conv-list-active-ink: var(--mj-chat-list-active-ink, var(--mj-brand-on-secondary));\n --conv-list-active-hover-bg: var(--mj-chat-list-active-hover-bg, var(--mj-brand-primary-hover));\n --conv-list-accent: var(--mj-chat-list-accent, var(--mj-brand-primary));\n --conv-list-accent-ink: var(--mj-chat-list-accent-ink, var(--mj-text-inverse));\n --conv-list-accent-hover: var(--mj-chat-list-accent-hover, var(--mj-brand-primary-hover));\n --conv-list-hover-bg: var(--mj-chat-list-hover-bg, color-mix(in srgb, var(--conv-list-ink) 8%, transparent));\n }\n .conversation-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; height: 100%; background: var(--conv-list-bg); }\n .list-header[_ngcontent-%COMP%] { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent); }\n .search-box[_ngcontent-%COMP%] { position: relative; flex: 1; min-width: 0; display: flex; }\n .search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .sort-row[_ngcontent-%COMP%] { display: flex; gap: 6px; margin-top: 8px; }\n .sort-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .sort-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 11px; }\n .sort-btn[_ngcontent-%COMP%]:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .sort-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n border-color: var(--conv-list-accent);\n color: var(--conv-list-ink);\n font-weight: 600;\n }\n .search-clear[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-ink) 12%, transparent); color: var(--conv-list-ink); }\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 28px 8px 12px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input[_ngcontent-%COMP%]::placeholder { color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); }\n .search-input[_ngcontent-%COMP%]:focus { outline: none; background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent); border-color: var(--conv-list-accent); }\n .btn-new-conversation[_ngcontent-%COMP%] {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation[_ngcontent-%COMP%]:hover { background: var(--conv-list-accent-hover); }\n .btn-new-conversation[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 14px; }\n .list-content[_ngcontent-%COMP%] { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n \n .sidebar-section[_ngcontent-%COMP%] { margin-bottom: 20px; }\n\n \n\n .search-escalate[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n border-top: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n background: transparent;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: background 0.2s;\n }\n\n .search-escalate[_ngcontent-%COMP%]:hover {\n background: var(--conv-list-hover-bg);\n color: var(--conv-list-ink);\n }\n\n \n .search-escalate-label[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .search-escalate-go[_ngcontent-%COMP%] { opacity: 0.6; }\n .pinned-section[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] .section-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header[_ngcontent-%COMP%] {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:not(.section-icon) { transform: rotate(90deg); }\n .chat-list[_ngcontent-%COMP%] {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded[_ngcontent-%COMP%] { display: block; }\n\n .conversation-item[_ngcontent-%COMP%] {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item[_ngcontent-%COMP%]:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; }\n .conversation-item.active[_ngcontent-%COMP%] { background: var(--conv-list-active-bg); color: var(--conv-list-active-ink); }\n \n\n\n .conversation-item.selected[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--conv-list-accent) 16%, transparent); }\n .conversation-item.selected[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-accent) 24%, transparent); }\n .conversation-item.active.selected[_ngcontent-%COMP%] { background: var(--conv-list-active-bg); }\n \n\n\n .row-check[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 14px;\n height: 14px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1.5px solid color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n border-radius: 3px;\n color: transparent;\n cursor: pointer;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n z-index: 2;\n }\n .row-check[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 8px; }\n .conversation-list.is-selecting[_ngcontent-%COMP%] .row-check[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n @media (hover: hover) {\n .conversation-item[_ngcontent-%COMP%]:hover .row-check[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n }\n .row-check.checked[_ngcontent-%COMP%] {\n background: var(--conv-list-accent);\n border-color: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n }\n .conversation-item.active[_ngcontent-%COMP%] .row-check[_ngcontent-%COMP%]:not(.checked) {\n border-color: color-mix(in srgb, var(--conv-list-active-ink) 70%, transparent);\n }\n .conversation-icon-wrapper[_ngcontent-%COMP%] { position: relative; flex-shrink: 0; }\n .conversation-icon[_ngcontent-%COMP%] { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .badge-overlay[_ngcontent-%COMP%] { position: absolute; top: -4px; right: -4px; }\n .conversation-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .conversation-name[_ngcontent-%COMP%] { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator[_ngcontent-%COMP%] { font-size: 10px; color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--conv-list-active-ink) 85%, transparent); }\n .conversation-preview[_ngcontent-%COMP%] { font-size: 12px; color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active[_ngcontent-%COMP%] .conversation-preview[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--conv-list-active-ink) 80%, transparent); }\n .conversation-meta[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n \n .project-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item[_ngcontent-%COMP%]:hover .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n }\n .conversation-item.active[_ngcontent-%COMP%] .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--conv-list-active-ink) 20%, transparent);\n color: var(--conv-list-active-ink);\n }\n\n .conversation-actions[_ngcontent-%COMP%] {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n .conversation-item.active[_ngcontent-%COMP%] .conversation-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n .conversation-actions[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] { pointer-events: auto; }\n \n @media (hover: none) {\n .conversation-actions[_ngcontent-%COMP%] { opacity: 1; pointer-events: auto; }\n }\n .pinned-icon[_ngcontent-%COMP%] { color: var(--mj-brand-accent); font-size: 12px; }\n\n \n .task-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_pulse-glow 2s ease-in-out infinite;\n }\n @keyframes _ngcontent-%COMP%_pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active[_ngcontent-%COMP%] .task-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n }\n\n .menu-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n background: var(--conv-list-bg) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent) !important;\n color: var(--conv-list-ink);\n }\n .conversation-item.active[_ngcontent-%COMP%] .menu-btn[_ngcontent-%COMP%] {\n background: var(--conv-list-active-hover-bg) !important;\n color: var(--conv-list-active-ink);\n }\n .menu-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 14px; }\n\n \n\n .list-context-menu[_ngcontent-%COMP%] {\n position: fixed;\n min-width: 190px;\n max-height: 70vh;\n overflow-y: auto;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n padding: 4px 0;\n }\n\n .context-menu-header[_ngcontent-%COMP%] {\n padding: 6px 14px 8px;\n font-size: 12px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin-bottom: 4px;\n }\n\n .menu-item[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .menu-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--conv-list-ink);\n }\n\n .menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin: 4px 0;\n }\n\n \n .conversation-item.renamed[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n \n\n\n @keyframes _ngcontent-%COMP%_renameHighlight {\n 0% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 40%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 40%, transparent));\n transform: scale(1.03);\n box-shadow: 0 0 20px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n 25% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 35%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 35%, transparent));\n box-shadow: 0 0 15px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n 50% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 30%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 30%, transparent));\n transform: scale(1.02);\n box-shadow: 0 0 10px color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n 75% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 20%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 20%, transparent));\n box-shadow: 0 0 5px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n \n\n\n .header-top[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n min-height: 36px;\n }\n\n .selection-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .selection-count[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n padding: 0 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .selection-bar-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 75%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .selection-bar-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 13px; }\n .selection-bar-btn[_ngcontent-%COMP%]:hover:not(:disabled) { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .selection-bar-btn[_ngcontent-%COMP%]:disabled { opacity: 0.4; cursor: not-allowed; }\n .selection-bar-btn.danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n \n .header-menu-container[_ngcontent-%COMP%] {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%] .shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--conv-list-ink) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n\n \n .section-action-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: var(--conv-list-ink);\n }\n .section-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 12px; }\n\n .folder-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n cursor: pointer;\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n font-size: 13px;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n }\n .folder-row[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .folder-row.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n }\n .folder-row.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n .section-header.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n .folder-chevron[_ngcontent-%COMP%] {\n font-size: 9px;\n width: 10px;\n flex-shrink: 0;\n transition: transform 0.2s;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n }\n .folder-chevron.expanded[_ngcontent-%COMP%] { transform: rotate(90deg); }\n .folder-icon[_ngcontent-%COMP%] { font-size: 12px; width: 16px; text-align: center; flex-shrink: 0; }\n .folder-name[_ngcontent-%COMP%] {\n \n\n\n\n flex: 0 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 600;\n }\n .folder-count[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n flex-shrink: 0;\n margin-left: auto;\n padding-left: 6px;\n text-align: right;\n }\n .folder-spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n }\n .folder-shared[_ngcontent-%COMP%] {\n flex-shrink: 0;\n margin-left: 6px;\n font-size: 10px;\n line-height: 1;\n \n\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n }\n .folder-children[_ngcontent-%COMP%] { display: block; }\n .folder-empty-hint[_ngcontent-%COMP%] {\n padding: 6px 16px;\n font-size: 11px;\n font-style: italic;\n color: color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n }\n .ungrouped-section.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--conv-list-accent) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n\n \n\n .conversation-item[_ngcontent-%COMP%] { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }\n .conversation-item.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n\n \n .menu-item.back[_ngcontent-%COMP%] { font-weight: 600; }\n .menu-item[_ngcontent-%COMP%] .submenu-arrow[_ngcontent-%COMP%] { margin-left: auto; font-size: 10px; }\n .menu-item.current[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent); }\n .move-folder-list[_ngcontent-%COMP%] { max-height: 240px; overflow-y: auto; }"] });
|
|
1340
2654
|
}
|
|
1341
2655
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationListComponent, [{
|
|
1342
2656
|
type: Component,
|
|
1343
2657
|
args: [{ standalone: false, selector: 'mj-conversation-list', template: `
|
|
1344
|
-
<div class="conversation-list">
|
|
1345
|
-
<!-- Header strip gated as a whole so an empty bordered band never renders
|
|
1346
|
-
|
|
1347
|
-
the
|
|
1348
|
-
@if (showSearch ||
|
|
2658
|
+
<div class="conversation-list" [class.is-selecting]="IsSelectionMode">
|
|
2659
|
+
<!-- Header strip gated as a whole so an empty bordered band never renders.
|
|
2660
|
+
While a selection exists its top row becomes the selection bar, which
|
|
2661
|
+
shows even for a host that hides the rest of the chrome. -->
|
|
2662
|
+
@if (showSearch || ShowHeaderMenu || IsSelectionMode) {
|
|
1349
2663
|
<div class="list-header">
|
|
1350
2664
|
<div class="header-top">
|
|
1351
|
-
@if (
|
|
1352
|
-
<
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
placeholder="Search conversations..."
|
|
1356
|
-
[(ngModel)]="searchQuery">
|
|
1357
|
-
}
|
|
1358
|
-
@if (showHeaderMenu && !isSelectionMode) {
|
|
1359
|
-
<div class="header-menu-container">
|
|
1360
|
-
<button class="btn-menu" (click)="toggleHeaderMenu($event)" title="Options">
|
|
1361
|
-
<i class="fas fa-ellipsis-v"></i>
|
|
2665
|
+
@if (IsSelectionMode) {
|
|
2666
|
+
<div class="selection-bar" role="toolbar" aria-label="Selected conversations">
|
|
2667
|
+
<button class="selection-bar-btn" (click)="ClearSelection()" title="Clear selection" aria-label="Clear selection">
|
|
2668
|
+
<i class="fas fa-xmark"></i>
|
|
1362
2669
|
</button>
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
2670
|
+
<span class="selection-count">{{ SelectedConversationIds.size }} selected</span>
|
|
2671
|
+
<button class="selection-bar-btn"
|
|
2672
|
+
(click)="BarSetPinned()"
|
|
2673
|
+
[disabled]="!CanChangeAny(SelectedIds)"
|
|
2674
|
+
[title]="CanChangeAny(SelectedIds) ? (SelectionHasUnpinned() ? 'Pin' : 'Unpin') : ChangeRefusedReason"
|
|
2675
|
+
[attr.aria-label]="SelectionHasUnpinned() ? 'Pin' : 'Unpin'">
|
|
2676
|
+
<i class="fas fa-thumbtack" [class.fa-rotate-90]="!SelectionHasUnpinned()"></i>
|
|
2677
|
+
</button>
|
|
2678
|
+
<button class="selection-bar-btn"
|
|
2679
|
+
(click)="BarOpenMoveMenu($event)"
|
|
2680
|
+
[disabled]="!CanChangeAny(SelectedIds)"
|
|
2681
|
+
[title]="CanChangeAny(SelectedIds) ? 'Move to folder' : ChangeRefusedReason"
|
|
2682
|
+
aria-label="Move to folder">
|
|
2683
|
+
<i class="fas fa-folder-tree"></i>
|
|
2684
|
+
</button>
|
|
2685
|
+
<button class="selection-bar-btn"
|
|
2686
|
+
(click)="BarShare()"
|
|
2687
|
+
[disabled]="!CanShareAny(SelectedIds)"
|
|
2688
|
+
[title]="CanShareAny(SelectedIds) ? 'Share' : ShareRefusedReason"
|
|
2689
|
+
aria-label="Share">
|
|
2690
|
+
<i class="fas fa-user-plus"></i>
|
|
2691
|
+
</button>
|
|
2692
|
+
<button class="selection-bar-btn danger" (click)="BarDelete()" title="Delete" aria-label="Delete">
|
|
2693
|
+
<i class="fas fa-trash"></i>
|
|
2694
|
+
</button>
|
|
2695
|
+
</div>
|
|
2696
|
+
} @else {
|
|
2697
|
+
@if (showSearch) {
|
|
2698
|
+
<div class="search-box">
|
|
2699
|
+
<input
|
|
2700
|
+
#searchInput
|
|
2701
|
+
type="text"
|
|
2702
|
+
class="search-input"
|
|
2703
|
+
placeholder="Search conversations..."
|
|
2704
|
+
[(ngModel)]="SearchQuery"
|
|
2705
|
+
(keydown)="OnSearchKeydown($event)">
|
|
2706
|
+
@if (IsSearching) {
|
|
2707
|
+
<button class="search-clear" (click)="ClearSearch()" title="Clear search">
|
|
2708
|
+
<i class="fas fa-xmark"></i>
|
|
1376
2709
|
</button>
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
2710
|
+
}
|
|
2711
|
+
</div>
|
|
2712
|
+
}
|
|
2713
|
+
@if (ShowHeaderMenu) {
|
|
2714
|
+
<div class="header-menu-container">
|
|
2715
|
+
<button class="btn-menu" (click)="ToggleHeaderMenu($event)" title="Options">
|
|
2716
|
+
<i class="fas fa-ellipsis-v"></i>
|
|
2717
|
+
</button>
|
|
2718
|
+
@if (IsHeaderMenuOpen) {
|
|
2719
|
+
<div class="header-dropdown-menu">
|
|
2720
|
+
<button class="dropdown-item" (click)="OnRefreshConversationsClick($event)" [disabled]="IsRefreshing">
|
|
2721
|
+
<i class="fas fa-sync-alt" [class.fa-spin]="IsRefreshing"></i>
|
|
2722
|
+
<span>{{ IsRefreshing ? 'Refreshing...' : 'Refresh' }}</span>
|
|
1381
2723
|
</button>
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
2724
|
+
<button class="dropdown-item" (click)="OnToggleGroupByClick($event)">
|
|
2725
|
+
<i class="fas" [class.fa-folder-tree]="GroupBy !== 'project'" [class.fa-list]="GroupBy === 'project'"></i>
|
|
2726
|
+
<span>{{ GroupBy === 'project' ? 'Show as flat list' : 'Group by folder' }}</span>
|
|
2727
|
+
</button>
|
|
2728
|
+
@if (!IsMobileView) {
|
|
2729
|
+
<button class="dropdown-item" (click)="OnUnpinSidebarClick($event)">
|
|
2730
|
+
<i class="fas fa-table-columns"></i>
|
|
2731
|
+
<span>Hide Sidebar</span>
|
|
2732
|
+
</button>
|
|
2733
|
+
}
|
|
2734
|
+
</div>
|
|
2735
|
+
}
|
|
2736
|
+
</div>
|
|
2737
|
+
}
|
|
1386
2738
|
}
|
|
1387
2739
|
</div>
|
|
2740
|
+
<!-- Sort controls. Live in the header strip, so a host that hides all
|
|
2741
|
+
chrome (showSearch + ShowHeaderMenu both false) gets no sort row.
|
|
2742
|
+
They stay put while selecting, so the list does not jump. -->
|
|
2743
|
+
@if (showSearch || ShowHeaderMenu) {
|
|
2744
|
+
<div class="sort-row">
|
|
2745
|
+
<button class="sort-btn" [class.active]="SortBy === 'date'"
|
|
2746
|
+
(click)="SetSort('date')"
|
|
2747
|
+
[title]="SortBy === 'date' ? (SortDirection === 'asc' ? 'Oldest first' : 'Newest first') : 'Sort by date'">
|
|
2748
|
+
<i class="fas" [ngClass]="SortIcon('date')"></i>
|
|
2749
|
+
<span>Date</span>
|
|
2750
|
+
</button>
|
|
2751
|
+
<button class="sort-btn" [class.active]="SortBy === 'name'"
|
|
2752
|
+
(click)="SetSort('name')"
|
|
2753
|
+
[title]="SortBy === 'name' ? (SortDirection === 'asc' ? 'A to Z' : 'Z to A') : 'Sort by name'">
|
|
2754
|
+
<i class="fas" [ngClass]="SortIcon('name')"></i>
|
|
2755
|
+
<span>Name</span>
|
|
2756
|
+
</button>
|
|
2757
|
+
</div>
|
|
2758
|
+
}
|
|
1388
2759
|
</div>
|
|
1389
2760
|
}
|
|
1390
|
-
@if (
|
|
1391
|
-
<button class="btn-new-conversation" (click)="
|
|
2761
|
+
@if (ShowNewConversationButton) {
|
|
2762
|
+
<button class="btn-new-conversation" (click)="CreateNewConversation()" title="New Conversation">
|
|
1392
2763
|
<i class="fas fa-plus"></i>
|
|
1393
2764
|
<span>New Conversation</span>
|
|
1394
2765
|
</button>
|
|
1395
2766
|
}
|
|
1396
|
-
<div class="list-content"
|
|
2767
|
+
<div class="list-content"
|
|
2768
|
+
(click)="OnListBackgroundClick($event)"
|
|
2769
|
+
(contextmenu)="OnBackgroundContextMenu($event)">
|
|
1397
2770
|
<!-- Pinned Section (only show if there are pinned conversations) -->
|
|
1398
|
-
@if (
|
|
2771
|
+
@if (PinnedConversations.length > 0) {
|
|
1399
2772
|
<div class="sidebar-section pinned-section">
|
|
1400
|
-
@if (
|
|
1401
|
-
<div class="section-header" [class.expanded]="
|
|
2773
|
+
@if (ShowSectionHeaders) {
|
|
2774
|
+
<div class="section-header" [class.expanded]="PinnedExpanded" (click)="TogglePinned()">
|
|
1402
2775
|
<div class="section-title">
|
|
1403
2776
|
<i class="fas fa-chevron-right"></i>
|
|
1404
2777
|
<i class="fas fa-thumbtack section-icon"></i>
|
|
@@ -1406,46 +2779,46 @@ export class ConversationListComponent {
|
|
|
1406
2779
|
</div>
|
|
1407
2780
|
</div>
|
|
1408
2781
|
}
|
|
1409
|
-
<div class="chat-list" [class.expanded]="!
|
|
1410
|
-
@for (conversation of
|
|
2782
|
+
<div class="chat-list" [class.expanded]="!ShowSectionHeaders || PinnedExpanded">
|
|
2783
|
+
@for (conversation of PinnedConversations; track conversation.ID) {
|
|
1411
2784
|
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
1412
2785
|
}
|
|
1413
2786
|
</div>
|
|
1414
2787
|
</div>
|
|
1415
2788
|
}
|
|
1416
2789
|
|
|
1417
|
-
<!--
|
|
2790
|
+
<!-- ShowSectionHeaders=false forces the FLAT branch even in project
|
|
1418
2791
|
grouping: the folder tree's root drop-zone and New Folder action
|
|
1419
2792
|
live in the section header, so rendering the tree without headers
|
|
1420
2793
|
would let a user drag a folder INTO another folder with no way to
|
|
1421
2794
|
ever drag it back out (a one-way door). Flat + headerless is the
|
|
1422
2795
|
coherent chrome-less rendering. -->
|
|
1423
|
-
@if (
|
|
2796
|
+
@if (ShowSectionHeaders && GroupBy === 'project') {
|
|
1424
2797
|
<!-- Folders Section. NOTE: this whole branch is already gated on
|
|
1425
|
-
|
|
2798
|
+
ShowSectionHeaders above, so the header + collapse state here are
|
|
1426
2799
|
unconditional — a headerless folder tree never renders. -->
|
|
1427
2800
|
<div class="sidebar-section folders-section">
|
|
1428
|
-
<div class="section-header" [class.expanded]="
|
|
1429
|
-
[class.drag-over]="
|
|
1430
|
-
(click)="
|
|
1431
|
-
(dragover)="
|
|
1432
|
-
(dragleave)="
|
|
1433
|
-
(drop)="
|
|
2801
|
+
<div class="section-header" [class.expanded]="FoldersExpanded"
|
|
2802
|
+
[class.drag-over]="DragOverTargetId === 'folders-root'"
|
|
2803
|
+
(click)="ToggleFolders()"
|
|
2804
|
+
(dragover)="OnFoldersRootDragOver($event)"
|
|
2805
|
+
(dragleave)="OnDragLeave('folders-root')"
|
|
2806
|
+
(drop)="OnFoldersRootDrop($event)">
|
|
1434
2807
|
<div class="section-title">
|
|
1435
2808
|
<i class="fas fa-chevron-right"></i>
|
|
1436
2809
|
<span>Folders</span>
|
|
1437
2810
|
</div>
|
|
1438
|
-
<button class="section-action-btn" (click)="
|
|
2811
|
+
<button class="section-action-btn" (click)="CreateFolder(null, $event)" title="New Folder">
|
|
1439
2812
|
<i class="fas fa-folder-plus"></i>
|
|
1440
2813
|
</button>
|
|
1441
2814
|
</div>
|
|
1442
|
-
<div class="chat-list" [class.expanded]="
|
|
1443
|
-
@for (node of
|
|
1444
|
-
@if (!
|
|
2815
|
+
<div class="chat-list" [class.expanded]="FoldersExpanded">
|
|
2816
|
+
@for (node of FolderTree; track node.project.ID) {
|
|
2817
|
+
@if (!IsSearching || node.hasContent) {
|
|
1445
2818
|
<ng-container [ngTemplateOutlet]="folderNode" [ngTemplateOutletContext]="{ $implicit: node }"></ng-container>
|
|
1446
2819
|
}
|
|
1447
2820
|
}
|
|
1448
|
-
@if (
|
|
2821
|
+
@if (FolderTree.length === 0) {
|
|
1449
2822
|
<div class="folder-empty-hint">No folders yet — create one to organize conversations.</div>
|
|
1450
2823
|
}
|
|
1451
2824
|
</div>
|
|
@@ -1453,19 +2826,19 @@ export class ConversationListComponent {
|
|
|
1453
2826
|
|
|
1454
2827
|
<!-- Ungrouped Section (drop target to remove from folder) -->
|
|
1455
2828
|
<div class="sidebar-section ungrouped-section"
|
|
1456
|
-
[class.drag-over]="
|
|
1457
|
-
(dragover)="
|
|
1458
|
-
(dragleave)="
|
|
1459
|
-
(drop)="
|
|
1460
|
-
<!-- Same as Folders above: reached only when
|
|
1461
|
-
<div class="section-header" [class.expanded]="
|
|
2829
|
+
[class.drag-over]="DragOverTargetId === 'ungrouped'"
|
|
2830
|
+
(dragover)="OnUngroupedDragOver($event)"
|
|
2831
|
+
(dragleave)="OnDragLeave('ungrouped')"
|
|
2832
|
+
(drop)="OnUngroupedDrop($event)">
|
|
2833
|
+
<!-- Same as Folders above: reached only when ShowSectionHeaders is true. -->
|
|
2834
|
+
<div class="section-header" [class.expanded]="UngroupedExpanded" (click)="ToggleUngrouped()">
|
|
1462
2835
|
<div class="section-title">
|
|
1463
2836
|
<i class="fas fa-chevron-right"></i>
|
|
1464
|
-
<span>{{
|
|
2837
|
+
<span>{{ FolderTree.length > 0 ? 'Ungrouped' : 'Messages' }}</span>
|
|
1465
2838
|
</div>
|
|
1466
2839
|
</div>
|
|
1467
|
-
<div class="chat-list" [class.expanded]="
|
|
1468
|
-
@for (conversation of
|
|
2840
|
+
<div class="chat-list" [class.expanded]="UngroupedExpanded">
|
|
2841
|
+
@for (conversation of UngroupedConversations; track conversation.ID) {
|
|
1469
2842
|
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
1470
2843
|
}
|
|
1471
2844
|
</div>
|
|
@@ -1473,16 +2846,16 @@ export class ConversationListComponent {
|
|
|
1473
2846
|
} @else {
|
|
1474
2847
|
<!-- Flat Messages Section -->
|
|
1475
2848
|
<div class="sidebar-section">
|
|
1476
|
-
@if (
|
|
1477
|
-
<div class="section-header" [class.expanded]="
|
|
2849
|
+
@if (ShowSectionHeaders) {
|
|
2850
|
+
<div class="section-header" [class.expanded]="DirectMessagesExpanded" (click)="ToggleDirectMessages()">
|
|
1478
2851
|
<div class="section-title">
|
|
1479
2852
|
<i class="fas fa-chevron-right"></i>
|
|
1480
2853
|
<span>Messages</span>
|
|
1481
2854
|
</div>
|
|
1482
2855
|
</div>
|
|
1483
2856
|
}
|
|
1484
|
-
<div class="chat-list" [class.expanded]="!
|
|
1485
|
-
@for (conversation of
|
|
2857
|
+
<div class="chat-list" [class.expanded]="!ShowSectionHeaders || DirectMessagesExpanded">
|
|
2858
|
+
@for (conversation of UnpinnedConversations; track conversation.ID) {
|
|
1486
2859
|
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
1487
2860
|
}
|
|
1488
2861
|
</div>
|
|
@@ -1490,73 +2863,68 @@ export class ConversationListComponent {
|
|
|
1490
2863
|
}
|
|
1491
2864
|
</div>
|
|
1492
2865
|
|
|
1493
|
-
<!--
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
}
|
|
1503
|
-
</div>
|
|
1504
|
-
<div class="selection-actions">
|
|
1505
|
-
<button class="btn-delete-bulk"
|
|
1506
|
-
(click)="bulkDeleteConversations()"
|
|
1507
|
-
[disabled]="selectedConversationIds.size === 0">
|
|
1508
|
-
<i class="fas fa-trash"></i>
|
|
1509
|
-
Delete ({{ selectedConversationIds.size }})
|
|
1510
|
-
</button>
|
|
1511
|
-
<button class="btn-cancel" (click)="toggleSelectionMode()">
|
|
1512
|
-
Cancel
|
|
1513
|
-
</button>
|
|
1514
|
-
</div>
|
|
1515
|
-
</div>
|
|
2866
|
+
<!-- Escalate the in-place filter to a full cross-entity search. Pinned below the
|
|
2867
|
+
scroll region rather than appended to the results so it stays reachable without
|
|
2868
|
+
scrolling past every match. Only meaningful while filtering. -->
|
|
2869
|
+
@if (IsSearching && !IsSelectionMode) {
|
|
2870
|
+
<button class="search-escalate" (click)="EscalateSearch()">
|
|
2871
|
+
<i class="fa-solid fa-magnifying-glass"></i>
|
|
2872
|
+
<span class="search-escalate-label">Search all of Chat for “{{ SearchQuery }}”</span>
|
|
2873
|
+
<i class="fa-solid fa-arrow-right search-escalate-go"></i>
|
|
2874
|
+
</button>
|
|
1516
2875
|
}
|
|
1517
2876
|
</div>
|
|
1518
2877
|
|
|
1519
2878
|
<!-- Recursive folder node: header + nested children + direct conversations -->
|
|
1520
2879
|
<ng-template #folderNode let-node>
|
|
1521
2880
|
<div class="folder-row"
|
|
1522
|
-
[class.drag-over]="
|
|
1523
|
-
[class.dragging]="
|
|
2881
|
+
[class.drag-over]="DragOverTargetId === node.project.ID"
|
|
2882
|
+
[class.dragging]="DraggedFolderId === node.project.ID"
|
|
1524
2883
|
[style.paddingLeft.px]="12 + node.depth * 14"
|
|
1525
2884
|
[draggable]="true"
|
|
1526
|
-
(dragstart)="
|
|
1527
|
-
(dragend)="
|
|
1528
|
-
(click)="
|
|
1529
|
-
(dragover)="
|
|
1530
|
-
(dragleave)="
|
|
1531
|
-
(drop)="
|
|
2885
|
+
(dragstart)="OnFolderDragStart(node, $event)"
|
|
2886
|
+
(dragend)="OnFolderDragEnd()"
|
|
2887
|
+
(click)="ToggleFolder(node.project.ID)"
|
|
2888
|
+
(dragover)="OnFolderDragOver(node.project.ID, $event)"
|
|
2889
|
+
(dragleave)="OnDragLeave(node.project.ID)"
|
|
2890
|
+
(drop)="OnFolderDrop(node.project, $event)"
|
|
2891
|
+
(contextmenu)="OnFolderContextMenu(node.project, $event)"
|
|
1532
2892
|
[title]="node.project.Name">
|
|
1533
|
-
<i class="fas fa-chevron-right folder-chevron" [class.expanded]="
|
|
2893
|
+
<i class="fas fa-chevron-right folder-chevron" [class.expanded]="IsFolderExpanded(node.project.ID)"></i>
|
|
1534
2894
|
<i class="fas {{ node.project.Icon || 'fa-folder' }} folder-icon" [style.color]="node.project.Color || null"></i>
|
|
1535
2895
|
<span class="folder-name">{{ node.project.Name }}</span>
|
|
2896
|
+
<!-- SHARED is the marked state, not personal. Two reasons: it is the state with
|
|
2897
|
+
consequences for other people ("anyone here can read this folder's name"),
|
|
2898
|
+
and personal is the create-time default, so marking personal would badge
|
|
2899
|
+
nearly every row in steady state while marking shared thins out over time.
|
|
2900
|
+
On an environment upgrading to this column every existing folder is shared
|
|
2901
|
+
and so every row is badged — which is exactly the disclosure people need at
|
|
2902
|
+
that moment. Sits beside the name it describes rather than at the right
|
|
2903
|
+
edge, which belongs to the count. -->
|
|
2904
|
+
@if (!node.project.OwnerUserID) {
|
|
2905
|
+
<!-- role="img" so the aria-label is actually announced: on a bare span with no
|
|
2906
|
+
role, an aria-label is not reliably exposed, and the <i> carrying the glyph
|
|
2907
|
+
is aria-hidden. -->
|
|
2908
|
+
<span class="folder-shared" role="img"
|
|
2909
|
+
title="Shared — everyone can see this folder and its name, but not the conversations in it"
|
|
2910
|
+
aria-label="Shared folder">
|
|
2911
|
+
<i class="fas fa-users" aria-hidden="true"></i>
|
|
2912
|
+
</span>
|
|
2913
|
+
}
|
|
2914
|
+
<span class="folder-spacer"></span>
|
|
1536
2915
|
<span class="folder-count">{{ node.totalCount }}</span>
|
|
1537
|
-
<div class="folder-actions" (click)="$event.stopPropagation()">
|
|
1538
|
-
<button class="folder-action-btn" (click)="createFolder(node.project.ID, $event)" title="New Subfolder">
|
|
1539
|
-
<i class="fas fa-folder-plus"></i>
|
|
1540
|
-
</button>
|
|
1541
|
-
<button class="folder-action-btn" (click)="editFolder(node.project, $event)" title="Edit Folder">
|
|
1542
|
-
<i class="fas fa-pen"></i>
|
|
1543
|
-
</button>
|
|
1544
|
-
<button class="folder-action-btn danger" (click)="deleteFolder(node.project, $event)" title="Delete Folder">
|
|
1545
|
-
<i class="fas fa-trash"></i>
|
|
1546
|
-
</button>
|
|
1547
|
-
</div>
|
|
1548
2916
|
</div>
|
|
1549
|
-
@if (
|
|
2917
|
+
@if (IsFolderExpanded(node.project.ID)) {
|
|
1550
2918
|
<div class="folder-children">
|
|
1551
2919
|
@for (child of node.children; track child.project.ID) {
|
|
1552
|
-
@if (!
|
|
2920
|
+
@if (!IsSearching || child.hasContent) {
|
|
1553
2921
|
<ng-container [ngTemplateOutlet]="folderNode" [ngTemplateOutletContext]="{ $implicit: child }"></ng-container>
|
|
1554
2922
|
}
|
|
1555
2923
|
}
|
|
1556
2924
|
@for (conversation of node.conversations; track conversation.ID) {
|
|
1557
2925
|
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation, depth: node.depth + 1 }"></ng-container>
|
|
1558
2926
|
}
|
|
1559
|
-
@if (node.totalCount === 0 && !
|
|
2927
|
+
@if (node.totalCount === 0 && !IsSearching) {
|
|
1560
2928
|
<div class="folder-empty-hint" [style.paddingLeft.px]="26 + node.depth * 14">Empty — drop a conversation here</div>
|
|
1561
2929
|
}
|
|
1562
2930
|
</div>
|
|
@@ -1567,22 +2935,33 @@ export class ConversationListComponent {
|
|
|
1567
2935
|
<ng-template #conversationItem let-conversation let-depth="depth">
|
|
1568
2936
|
<div class="conversation-item"
|
|
1569
2937
|
[class.active]="IsConversationActive(conversation)"
|
|
2938
|
+
[class.selected]="IsConversationSelected(conversation)"
|
|
1570
2939
|
[class.renamed]="IsConversationRenamed(conversation)"
|
|
1571
2940
|
[class.dragging]="IsConversationDragging(conversation)"
|
|
1572
2941
|
[style.paddingLeft.px]="depth ? 16 + depth * 14 : 16"
|
|
1573
|
-
[draggable]="
|
|
1574
|
-
(dragstart)="
|
|
1575
|
-
(dragend)="
|
|
1576
|
-
(
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
2942
|
+
[draggable]="CanChange(conversation)"
|
|
2943
|
+
(dragstart)="OnConversationDragStart(conversation, $event)"
|
|
2944
|
+
(dragend)="OnConversationDragEnd()"
|
|
2945
|
+
(dragover)="OnConversationRowDragOver(conversation, $event)"
|
|
2946
|
+
(dragleave)="OnDragLeave(ConversationDropTargetId(conversation))"
|
|
2947
|
+
(drop)="OnConversationRowDrop(conversation, $event)"
|
|
2948
|
+
(pointerdown)="OnRowPointerDown(conversation, $event)"
|
|
2949
|
+
(pointermove)="OnRowPointerMove($event)"
|
|
2950
|
+
(pointerup)="CancelLongPress()"
|
|
2951
|
+
(pointercancel)="CancelLongPress()"
|
|
2952
|
+
(click)="HandleConversationClick(conversation, $event)"
|
|
2953
|
+
(contextmenu)="OnConversationContextMenu(conversation, $event)">
|
|
2954
|
+
<button class="row-check"
|
|
2955
|
+
role="checkbox"
|
|
2956
|
+
[class.checked]="IsConversationSelected(conversation)"
|
|
2957
|
+
[attr.aria-checked]="IsConversationSelected(conversation)"
|
|
2958
|
+
[attr.aria-label]="'Select ' + (conversation.Name || 'conversation')"
|
|
2959
|
+
[style.left.px]="(depth || 0) * 14 + 4"
|
|
2960
|
+
(click)="OnRowCheckboxClick(conversation, $event)">
|
|
2961
|
+
<i class="fas fa-check"></i>
|
|
2962
|
+
</button>
|
|
1584
2963
|
<div class="conversation-icon-wrapper">
|
|
1585
|
-
@if (
|
|
2964
|
+
@if (HasActiveTasks(conversation.ID)) {
|
|
1586
2965
|
<div class="conversation-icon has-tasks">
|
|
1587
2966
|
<i class="fas fa-spinner fa-pulse"></i>
|
|
1588
2967
|
</div>
|
|
@@ -1594,107 +2973,227 @@ export class ConversationListComponent {
|
|
|
1594
2973
|
<div class="conversation-info" [title]="conversation.Name + (conversation.Description ? '\n' + conversation.Description : '')">
|
|
1595
2974
|
<div class="conversation-name">
|
|
1596
2975
|
{{ conversation.Name }}
|
|
1597
|
-
@if (
|
|
2976
|
+
@if (IsSharedWithMe(conversation)) {
|
|
1598
2977
|
<i class="fas fa-share-nodes shared-indicator"
|
|
1599
|
-
[title]="
|
|
2978
|
+
[title]="SharedWithMeTooltip(conversation)"></i>
|
|
1600
2979
|
}
|
|
1601
2980
|
</div>
|
|
1602
2981
|
<div class="conversation-preview">{{ conversation.Description }}</div>
|
|
1603
2982
|
</div>
|
|
1604
|
-
|
|
1605
|
-
<
|
|
1606
|
-
<
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
<
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
<
|
|
1649
|
-
|
|
1650
|
-
<div class="menu-divider"></div>
|
|
1651
|
-
<button class="menu-item danger" (click)="deleteConversation(conversation); closeMenu()">
|
|
1652
|
-
<i class="fas fa-trash"></i>
|
|
1653
|
-
<span>Delete</span>
|
|
2983
|
+
<div class="conversation-actions">
|
|
2984
|
+
<button class="menu-btn" (click)="OpenRowMenu(conversation, $event)" title="More options">
|
|
2985
|
+
<i class="fas fa-ellipsis"></i>
|
|
2986
|
+
</button>
|
|
2987
|
+
</div>
|
|
2988
|
+
</div>
|
|
2989
|
+
</ng-template>
|
|
2990
|
+
|
|
2991
|
+
<mj-resource-share-dialog
|
|
2992
|
+
[Visible]="IsShareDialogOpen"
|
|
2993
|
+
[Contexts]="ShareContexts"
|
|
2994
|
+
[Adapter]="ShareAdapter"
|
|
2995
|
+
[Notice]="ShareNotice"
|
|
2996
|
+
ResourceLabel="conversation"
|
|
2997
|
+
(Result)="OnShareDialogResult($event)">
|
|
2998
|
+
</mj-resource-share-dialog>
|
|
2999
|
+
|
|
3000
|
+
<!-- One menu for every right-click target: a conversation row (the clicked
|
|
3001
|
+
row, or the whole selection when it is part of it), a folder row, or the
|
|
3002
|
+
empty space of the list. Fixed-positioned at the pointer, and moved as
|
|
3003
|
+
needed to stay inside the window. -->
|
|
3004
|
+
@if (ContextMenu) {
|
|
3005
|
+
<div class="list-context-menu" #contextMenuEl
|
|
3006
|
+
[style.left.px]="ContextMenu.x"
|
|
3007
|
+
[style.top.px]="ContextMenu.y"
|
|
3008
|
+
(click)="$event.stopPropagation()"
|
|
3009
|
+
(contextmenu)="$event.preventDefault(); $event.stopPropagation()">
|
|
3010
|
+
@switch (ContextMenu.kind) {
|
|
3011
|
+
@case ('conversation') {
|
|
3012
|
+
@if (IsMoveSubmenuOpen) {
|
|
3013
|
+
<button class="menu-item back" (click)="CloseMoveSubmenu($event)">
|
|
3014
|
+
<i class="fas fa-chevron-left"></i>
|
|
3015
|
+
<span>Move to folder</span>
|
|
3016
|
+
</button>
|
|
3017
|
+
<div class="menu-divider"></div>
|
|
3018
|
+
<div class="move-folder-list">
|
|
3019
|
+
<button class="menu-item" [class.current]="IsSingleTargetInFolder(null)" (click)="ContextMoveToFolder(null)">
|
|
3020
|
+
<i class="fas fa-inbox"></i>
|
|
3021
|
+
<span>No folder</span>
|
|
3022
|
+
</button>
|
|
3023
|
+
@for (f of FlatFolders; track f.project.ID) {
|
|
3024
|
+
<button class="menu-item" [class.current]="IsSingleTargetInFolder(f.project.ID)"
|
|
3025
|
+
[style.paddingLeft.px]="14 + f.depth * 12"
|
|
3026
|
+
(click)="ContextMoveToFolder(f.project.ID)">
|
|
3027
|
+
<i class="fas {{ f.project.Icon || 'fa-folder' }}" [style.color]="f.project.Color || null"></i>
|
|
3028
|
+
<span>{{ f.project.Name }}</span>
|
|
1654
3029
|
</button>
|
|
1655
3030
|
}
|
|
1656
3031
|
</div>
|
|
3032
|
+
<div class="menu-divider"></div>
|
|
3033
|
+
<button class="menu-item" (click)="ContextMoveToNewFolder($event)">
|
|
3034
|
+
<i class="fas fa-folder-plus"></i>
|
|
3035
|
+
<span>New folder…</span>
|
|
3036
|
+
</button>
|
|
3037
|
+
} @else {
|
|
3038
|
+
@if (ContextMenu.targets.length > 1) {
|
|
3039
|
+
<div class="context-menu-header">{{ ContextMenu.targets.length }} selected</div>
|
|
3040
|
+
<button class="menu-item" (click)="ContextSetPinned(true)"
|
|
3041
|
+
[disabled]="!CanChangeAny(ContextMenu.targets)"
|
|
3042
|
+
[attr.title]="CanChangeAny(ContextMenu.targets) ? null : ChangeRefusedReason">
|
|
3043
|
+
<i class="fas fa-thumbtack"></i>
|
|
3044
|
+
<span>Pin</span>
|
|
3045
|
+
</button>
|
|
3046
|
+
<button class="menu-item" (click)="ContextSetPinned(false)"
|
|
3047
|
+
[disabled]="!CanChangeAny(ContextMenu.targets)"
|
|
3048
|
+
[attr.title]="CanChangeAny(ContextMenu.targets) ? null : ChangeRefusedReason">
|
|
3049
|
+
<i class="fas fa-thumbtack fa-rotate-90"></i>
|
|
3050
|
+
<span>Unpin</span>
|
|
3051
|
+
</button>
|
|
3052
|
+
} @else {
|
|
3053
|
+
<button class="menu-item" (click)="ContextTogglePin()"
|
|
3054
|
+
[disabled]="!CanChangeAny(ContextMenu.targets)"
|
|
3055
|
+
[attr.title]="CanChangeAny(ContextMenu.targets) ? null : ChangeRefusedReason">
|
|
3056
|
+
<i class="fas fa-thumbtack"></i>
|
|
3057
|
+
<span>{{ ContextMenu.conversation?.IsPinned ? 'Unpin' : 'Pin' }}</span>
|
|
3058
|
+
</button>
|
|
3059
|
+
}
|
|
3060
|
+
<button class="menu-item" (click)="OpenMoveSubmenu($event)"
|
|
3061
|
+
[disabled]="!CanChangeAny(ContextMenu.targets)"
|
|
3062
|
+
[attr.title]="CanChangeAny(ContextMenu.targets) ? null : ChangeRefusedReason">
|
|
3063
|
+
<i class="fas fa-folder-tree"></i>
|
|
3064
|
+
<span>Move to folder</span>
|
|
3065
|
+
<i class="fas fa-chevron-right submenu-arrow"></i>
|
|
3066
|
+
</button>
|
|
3067
|
+
<button class="menu-item"
|
|
3068
|
+
(click)="ContextShare()"
|
|
3069
|
+
[disabled]="!CanShareAny(ContextMenu.targets)"
|
|
3070
|
+
[attr.title]="CanShareAny(ContextMenu.targets) ? null : ShareRefusedReason">
|
|
3071
|
+
<i class="fas fa-user-plus"></i>
|
|
3072
|
+
<span>{{ ContextMenu.targets.length > 1 ? 'Share ' + ContextMenu.targets.length + ' conversations' : 'Share' }}</span>
|
|
3073
|
+
</button>
|
|
3074
|
+
@if (ContextMenu.targets.length === 1) {
|
|
3075
|
+
<button class="menu-item" (click)="ContextRename()">
|
|
3076
|
+
<i class="fas fa-edit"></i>
|
|
3077
|
+
<span>Rename</span>
|
|
3078
|
+
</button>
|
|
3079
|
+
}
|
|
3080
|
+
<div class="menu-divider"></div>
|
|
3081
|
+
<button class="menu-item danger" (click)="ContextDelete()">
|
|
3082
|
+
<i class="fas fa-trash"></i>
|
|
3083
|
+
<span>{{ ContextMenu.targets.length > 1 ? 'Delete ' + ContextMenu.targets.length : 'Delete' }}</span>
|
|
3084
|
+
</button>
|
|
1657
3085
|
}
|
|
1658
|
-
|
|
3086
|
+
}
|
|
3087
|
+
@case ('folder') {
|
|
3088
|
+
<button class="menu-item" (click)="ContextCreateSubfolder($event)">
|
|
3089
|
+
<i class="fas fa-folder-plus"></i>
|
|
3090
|
+
<span>New Subfolder</span>
|
|
3091
|
+
</button>
|
|
3092
|
+
<button class="menu-item" (click)="ContextEditFolder($event)">
|
|
3093
|
+
<i class="fas fa-pen"></i>
|
|
3094
|
+
<span>Rename</span>
|
|
3095
|
+
</button>
|
|
3096
|
+
<div class="menu-divider"></div>
|
|
3097
|
+
<button class="menu-item danger" (click)="ContextDeleteFolder($event)">
|
|
3098
|
+
<i class="fas fa-trash"></i>
|
|
3099
|
+
<span>Delete</span>
|
|
3100
|
+
</button>
|
|
3101
|
+
}
|
|
3102
|
+
@default {
|
|
3103
|
+
<button class="menu-item" (click)="ContextNewConversation()">
|
|
3104
|
+
<i class="fas fa-plus"></i>
|
|
3105
|
+
<span>New Conversation</span>
|
|
3106
|
+
</button>
|
|
3107
|
+
<button class="menu-item" (click)="ContextCreateRootFolder($event)">
|
|
3108
|
+
<i class="fas fa-folder-plus"></i>
|
|
3109
|
+
<span>New Folder</span>
|
|
3110
|
+
</button>
|
|
3111
|
+
<div class="menu-divider"></div>
|
|
3112
|
+
<button class="menu-item" (click)="ContextSelectAll()">
|
|
3113
|
+
<i class="fas fa-check-double"></i>
|
|
3114
|
+
<span>Select All</span>
|
|
3115
|
+
</button>
|
|
3116
|
+
}
|
|
1659
3117
|
}
|
|
1660
3118
|
</div>
|
|
1661
|
-
|
|
1662
|
-
`, styles: ["\n :host {\n display: block;\n height: 100%;\n /* White-label theming tokens for the list panel. The public\n --mj-chat-list-* custom properties are host-overridable (set\n them at :root or on any ancestor); the private --conv-list-* names\n resolve the fallback ONCE here so the 70+ usages below stay simple.\n (A self-referential var() fallback would be a custom-property cycle,\n so the two-name indirection is required, not stylistic.) Defaults\n preserve the stock look exactly: a brand-secondary panel with\n on-secondary ink. Hover/border/divider states derive from the ink via\n color-mix, so they follow automatically when the ink is remapped.\n The accent trio drives the panel's ACTION surfaces (New Conversation\n button, search-focus ring, checkbox tick, drag-over highlights) \u2014\n independent of the active-row pair so a host can tint actions on their\n own; defaults to the brand-primary action color, unchanged.\n --conv-list-hover-bg is the row-hover wash: it defaults to the same\n ink-derived tint as before (so a bg/ink remap still gives a neutral\n hover), but a host can point it at a brand tint to make hover an accent\n cue while keeping the panel itself on a neutral surface. */\n --conv-list-bg: var(--mj-chat-list-bg, var(--mj-brand-secondary));\n --conv-list-ink: var(--mj-chat-list-ink, var(--mj-brand-on-secondary));\n --conv-list-active-bg: var(--mj-chat-list-active-bg, var(--mj-brand-primary));\n --conv-list-active-ink: var(--mj-chat-list-active-ink, var(--mj-brand-on-secondary));\n --conv-list-active-hover-bg: var(--mj-chat-list-active-hover-bg, var(--mj-brand-primary-hover));\n --conv-list-accent: var(--mj-chat-list-accent, var(--mj-brand-primary));\n --conv-list-accent-ink: var(--mj-chat-list-accent-ink, var(--mj-text-inverse));\n --conv-list-accent-hover: var(--mj-chat-list-accent-hover, var(--mj-brand-primary-hover));\n --conv-list-hover-bg: var(--mj-chat-list-hover-bg, color-mix(in srgb, var(--conv-list-ink) 8%, transparent));\n }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--conv-list-bg); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent); }\n .search-input {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent); border-color: var(--conv-list-accent); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation:hover { background: var(--conv-list-accent-hover); }\n .btn-new-conversation i { font-size: 14px; }\n .list-content { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n /* Collapsible Sections */\n .sidebar-section { margin-bottom: 20px; }\n .pinned-section .section-title .section-icon {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .section-title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title i {\n font-size: 10px;\n }\n .section-title i:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded .section-title i:not(.section-icon) { transform: rotate(90deg); }\n .chat-list {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded { display: block; }\n\n .conversation-item {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--conv-list-active-bg); color: var(--conv-list-active-ink); }\n .conversation-icon-wrapper { position: relative; flex-shrink: 0; }\n .conversation-icon { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks { color: var(--mj-status-warning); }\n .badge-overlay { position: absolute; top: -4px; right: -4px; }\n .conversation-info { flex: 1; min-width: 0; }\n .conversation-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator { font-size: 10px; color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--conv-list-active-ink) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--conv-list-active-ink) 80%, transparent); }\n .conversation-meta { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n /* Project Badge */\n .project-badge {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item:hover .project-badge {\n background-color: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--conv-list-active-ink) 20%, transparent);\n color: var(--conv-list-active-ink);\n }\n\n .conversation-actions {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item:hover .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-item.active .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-actions > * { pointer-events: auto; }\n .pinned-icon { color: var(--mj-brand-accent); font-size: 12px; }\n\n /* Task Indicator */\n .task-indicator {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: pulse-glow 2s ease-in-out infinite;\n }\n @keyframes pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active .task-indicator {\n color: var(--mj-status-warning);\n }\n\n .menu-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n background: var(--conv-list-bg) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent) !important;\n color: var(--conv-list-ink);\n }\n .conversation-item.active .menu-btn {\n background: var(--conv-list-active-hover-bg) !important;\n color: var(--conv-list-active-ink);\n }\n .menu-btn i { font-size: 14px; }\n\n .context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n pointer-events: auto;\n }\n\n .menu-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--conv-list-ink);\n }\n\n .menu-item.danger {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger i {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover i {\n color: var(--mj-status-error);\n }\n\n .menu-divider {\n height: 1px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin: 4px 0;\n }\n\n /* Rename Animation */\n .conversation-item.renamed {\n animation: renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* Brand-token ramp (was hardcoded tailwind blue/purple/emerald rgba values,\n which ignored theming): primary/accent open the flash, success/primary\n carry the fade, at the original alpha ramp (40/35/30/20; glows 50-20). */\n @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 40%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 40%, transparent));\n transform: scale(1.03);\n box-shadow: 0 0 20px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n 25% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 35%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 35%, transparent));\n box-shadow: 0 0 15px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n 50% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 30%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 30%, transparent));\n transform: scale(1.02);\n box-shadow: 0 0 10px color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n 75% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 20%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 20%, transparent));\n box-shadow: 0 0 5px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n /* Selection Mode Styles */\n .header-top {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n /* Header menu button and dropdown */\n .header-menu-container {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .header-dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu .dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu .dropdown-item:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--conv-list-ink) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .conversation-checkbox {\n display: flex;\n align-items: center;\n margin-right: 8px;\n flex-shrink: 0;\n }\n\n .conversation-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--conv-list-accent);\n }\n\n .selection-action-bar {\n position: sticky;\n bottom: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--conv-list-bg);\n border-top: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n gap: 12px;\n flex-wrap: wrap;\n flex-shrink: 0;\n }\n\n .selection-info {\n display: flex;\n align-items: center;\n gap: 12px;\n color: color-mix(in srgb, var(--conv-list-ink) 90%, transparent);\n font-size: 14px;\n font-weight: 500;\n flex: 1 1 auto;\n min-width: 150px;\n }\n\n .selection-count {\n color: var(--conv-list-ink);\n }\n\n .link-btn {\n background: none;\n border: none;\n color: var(--mj-brand-accent);\n cursor: pointer;\n font-size: 13px;\n text-decoration: underline;\n padding: 0;\n transition: color 0.2s;\n }\n\n .link-btn:hover {\n color: var(--conv-list-ink);\n }\n\n .selection-actions {\n display: flex;\n gap: 8px;\n flex: 0 0 auto;\n }\n\n .btn-cancel {\n padding: 8px 16px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n }\n\n .btn-cancel:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .btn-delete-bulk {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-error);\n border: none;\n border-radius: 6px;\n /* Deliberately NOT --conv-list-ink: this ink sits on the error-red button,\n not the panel, so it must not follow a panel remap. (brand-on-secondary\n stays light in both modes; text-inverse flips dark in dark mode.) */\n color: var(--mj-brand-on-secondary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: all 0.2s;\n }\n\n .btn-delete-bulk:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 80%, black);\n }\n\n .btn-delete-bulk:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .btn-delete-bulk i {\n font-size: 12px;\n }\n\n /* Folders */\n .section-action-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: var(--conv-list-ink);\n }\n .section-action-btn i { font-size: 12px; }\n\n .folder-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n cursor: pointer;\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n font-size: 13px;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n }\n .folder-row:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .folder-row.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n }\n .folder-row.dragging { opacity: 0.4; }\n .section-header.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n .folder-chevron {\n font-size: 9px;\n width: 10px;\n flex-shrink: 0;\n transition: transform 0.2s;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n }\n .folder-chevron.expanded { transform: rotate(90deg); }\n .folder-icon { font-size: 12px; width: 16px; text-align: center; flex-shrink: 0; }\n .folder-name {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 600;\n }\n .folder-count {\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n flex-shrink: 0;\n margin-left: auto;\n padding-left: 6px;\n text-align: right;\n }\n .folder-actions {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n gap: 2px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 5;\n }\n .folder-row:hover .folder-actions { opacity: 1; pointer-events: auto; }\n .folder-row:hover .folder-count { opacity: 0; }\n .folder-action-btn {\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.15s;\n }\n .folder-action-btn:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 18%, transparent);\n color: var(--conv-list-ink);\n }\n .folder-action-btn.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 18%, transparent);\n color: var(--mj-status-error);\n }\n .folder-action-btn i { font-size: 11px; }\n .folder-children { display: block; }\n .folder-empty-hint {\n padding: 6px 16px;\n font-size: 11px;\n font-style: italic;\n color: color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n }\n .ungrouped-section.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n\n /* Dragging state */\n .conversation-item { user-select: none; }\n .conversation-item.dragging { opacity: 0.4; }\n\n /* Move-to-folder submenu */\n .menu-item.back { font-weight: 600; }\n .menu-item .submenu-arrow { margin-left: auto; font-size: 10px; }\n .menu-item.current { background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent); }\n .move-folder-list { max-height: 240px; overflow-y: auto; }\n "] }]
|
|
1663
|
-
}], () => [{ type: i1.DialogService }, { type: i2.NotificationService }, { type: i3.ActiveTasksService }, { type: i4.MJDialogService }, { type: i0.ChangeDetectorRef }], {
|
|
3119
|
+
}
|
|
3120
|
+
`, styles: ["\n :host {\n display: block;\n height: 100%;\n /* White-label theming tokens for the list panel. The public\n --mj-chat-list-* custom properties are host-overridable (set\n them at :root or on any ancestor); the private --conv-list-* names\n resolve the fallback ONCE here so the 70+ usages below stay simple.\n (A self-referential var() fallback would be a custom-property cycle,\n so the two-name indirection is required, not stylistic.) Defaults\n preserve the stock look exactly: a brand-secondary panel with\n on-secondary ink. Hover/border/divider states derive from the ink via\n color-mix, so they follow automatically when the ink is remapped.\n The accent trio drives the panel's ACTION surfaces (New Conversation\n button, search-focus ring, checkbox tick, drag-over highlights) \u2014\n independent of the active-row pair so a host can tint actions on their\n own; defaults to the brand-primary action color, unchanged.\n --conv-list-hover-bg is the row-hover wash: it defaults to the same\n ink-derived tint as before (so a bg/ink remap still gives a neutral\n hover), but a host can point it at a brand tint to make hover an accent\n cue while keeping the panel itself on a neutral surface. */\n --conv-list-bg: var(--mj-chat-list-bg, var(--mj-brand-secondary));\n --conv-list-ink: var(--mj-chat-list-ink, var(--mj-brand-on-secondary));\n --conv-list-active-bg: var(--mj-chat-list-active-bg, var(--mj-brand-primary));\n --conv-list-active-ink: var(--mj-chat-list-active-ink, var(--mj-brand-on-secondary));\n --conv-list-active-hover-bg: var(--mj-chat-list-active-hover-bg, var(--mj-brand-primary-hover));\n --conv-list-accent: var(--mj-chat-list-accent, var(--mj-brand-primary));\n --conv-list-accent-ink: var(--mj-chat-list-accent-ink, var(--mj-text-inverse));\n --conv-list-accent-hover: var(--mj-chat-list-accent-hover, var(--mj-brand-primary-hover));\n --conv-list-hover-bg: var(--mj-chat-list-hover-bg, color-mix(in srgb, var(--conv-list-ink) 8%, transparent));\n }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--conv-list-bg); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent); }\n .search-box { position: relative; flex: 1; min-width: 0; display: flex; }\n .search-clear {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .sort-row { display: flex; gap: 6px; margin-top: 8px; }\n .sort-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .sort-btn i { font-size: 11px; }\n .sort-btn:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .sort-btn.active {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n border-color: var(--conv-list-accent);\n color: var(--conv-list-ink);\n font-weight: 600;\n }\n .search-clear:hover { background: color-mix(in srgb, var(--conv-list-ink) 12%, transparent); color: var(--conv-list-ink); }\n .search-input {\n width: 100%;\n padding: 8px 28px 8px 12px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent); border-color: var(--conv-list-accent); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation:hover { background: var(--conv-list-accent-hover); }\n .btn-new-conversation i { font-size: 14px; }\n .list-content { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n /* Collapsible Sections */\n .sidebar-section { margin-bottom: 20px; }\n\n /* Reads as a continuation of the list rather than a second control: full-width row,\n ink-derived like every other affordance in this panel, no input styling. */\n .search-escalate {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n border-top: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n background: transparent;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: background 0.2s;\n }\n\n .search-escalate:hover {\n background: var(--conv-list-hover-bg);\n color: var(--conv-list-ink);\n }\n\n /* Truncate rather than wrap \u2014 the query is user text of unbounded length. */\n .search-escalate-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .search-escalate-go { opacity: 0.6; }\n .pinned-section .section-title .section-icon {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .section-title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title i {\n font-size: 10px;\n }\n .section-title i:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded .section-title i:not(.section-icon) { transform: rotate(90deg); }\n .chat-list {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded { display: block; }\n\n .conversation-item {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--conv-list-active-bg); color: var(--conv-list-active-ink); }\n /* A selected row is marked by its ticked checkbox and an accent tint. The\n open conversation keeps its solid .active fill, so a row that is both\n still reads as the open one. */\n .conversation-item.selected { background: color-mix(in srgb, var(--conv-list-accent) 16%, transparent); }\n .conversation-item.selected:hover { background: color-mix(in srgb, var(--conv-list-accent) 24%, transparent); }\n .conversation-item.active.selected { background: var(--conv-list-active-bg); }\n /* Row checkbox: the mouse route to a selection. It sits in the row's left\n padding, hidden until the row is hovered, and shows on every row while a\n selection exists (on touch too, where there is no hover). */\n .row-check {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 14px;\n height: 14px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1.5px solid color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n border-radius: 3px;\n color: transparent;\n cursor: pointer;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n z-index: 2;\n }\n .row-check i { font-size: 8px; }\n .conversation-list.is-selecting .row-check { opacity: 1; pointer-events: auto; }\n @media (hover: hover) {\n .conversation-item:hover .row-check { opacity: 1; pointer-events: auto; }\n }\n .row-check.checked {\n background: var(--conv-list-accent);\n border-color: var(--conv-list-accent);\n color: var(--conv-list-accent-ink);\n }\n .conversation-item.active .row-check:not(.checked) {\n border-color: color-mix(in srgb, var(--conv-list-active-ink) 70%, transparent);\n }\n .conversation-icon-wrapper { position: relative; flex-shrink: 0; }\n .conversation-icon { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks { color: var(--mj-status-warning); }\n .badge-overlay { position: absolute; top: -4px; right: -4px; }\n .conversation-info { flex: 1; min-width: 0; }\n .conversation-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator { font-size: 10px; color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--conv-list-active-ink) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--conv-list-active-ink) 80%, transparent); }\n .conversation-meta { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n /* Project Badge */\n .project-badge {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item:hover .project-badge {\n background-color: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--conv-list-active-ink) 20%, transparent);\n color: var(--conv-list-active-ink);\n }\n\n .conversation-actions {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item:hover .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-item.active .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-actions > * { pointer-events: auto; }\n /* No hover on touch, so the \u22EF button is always shown there. */\n @media (hover: none) {\n .conversation-actions { opacity: 1; pointer-events: auto; }\n }\n .pinned-icon { color: var(--mj-brand-accent); font-size: 12px; }\n\n /* Task Indicator */\n .task-indicator {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: pulse-glow 2s ease-in-out infinite;\n }\n @keyframes pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active .task-indicator {\n color: var(--mj-status-warning);\n }\n\n .menu-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n background: var(--conv-list-bg) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent) !important;\n color: var(--conv-list-ink);\n }\n .conversation-item.active .menu-btn {\n background: var(--conv-list-active-hover-bg) !important;\n color: var(--conv-list-active-ink);\n }\n .menu-btn i { font-size: 14px; }\n\n /* The one right-click menu. Fixed to the viewport so it escapes the list's\n scroll container and is never clipped by a row. */\n .list-context-menu {\n position: fixed;\n min-width: 190px;\n max-height: 70vh;\n overflow-y: auto;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n padding: 4px 0;\n }\n\n .context-menu-header {\n padding: 6px 14px 8px;\n font-size: 12px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin-bottom: 4px;\n }\n\n .menu-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--conv-list-ink);\n }\n\n .menu-item.danger {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger i {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover i {\n color: var(--mj-status-error);\n }\n\n .menu-divider {\n height: 1px;\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n margin: 4px 0;\n }\n\n /* Rename Animation */\n .conversation-item.renamed {\n animation: renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* Brand-token ramp (was hardcoded tailwind blue/purple/emerald rgba values,\n which ignored theming): primary/accent open the flash, success/primary\n carry the fade, at the original alpha ramp (40/35/30/20; glows 50-20). */\n @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 40%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 40%, transparent));\n transform: scale(1.03);\n box-shadow: 0 0 20px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n 25% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-brand-primary) 35%, transparent),\n color-mix(in srgb, var(--mj-brand-accent) 35%, transparent));\n box-shadow: 0 0 15px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n 50% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 30%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 30%, transparent));\n transform: scale(1.02);\n box-shadow: 0 0 10px color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n 75% {\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-success) 20%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 20%, transparent));\n box-shadow: 0 0 5px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n /* Header top row: the search box and \u22EF menu, or the selection bar while a\n selection exists. A fixed minimum height keeps the list from jumping\n when one replaces the other. */\n .header-top {\n display: flex;\n gap: 8px;\n align-items: center;\n min-height: 36px;\n }\n\n .selection-bar {\n display: flex;\n align-items: center;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .selection-count {\n flex: 1;\n min-width: 0;\n padding: 0 6px;\n color: var(--conv-list-ink);\n font-size: 13px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .selection-bar-btn {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 75%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .selection-bar-btn i { font-size: 13px; }\n .selection-bar-btn:hover:not(:disabled) { background: var(--conv-list-hover-bg); color: var(--conv-list-ink); }\n .selection-bar-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n .selection-bar-btn.danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n /* Header menu button and dropdown */\n .header-menu-container {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n .header-dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--conv-list-bg);\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu .dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--conv-list-ink) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu .dropdown-item:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--conv-list-ink);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--conv-list-ink) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--conv-list-ink) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--conv-list-ink) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 10%, transparent);\n color: var(--conv-list-ink);\n border-color: color-mix(in srgb, var(--conv-list-ink) 30%, transparent);\n }\n\n\n /* Folders */\n .section-action-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--conv-list-ink) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn:hover {\n background: color-mix(in srgb, var(--conv-list-ink) 15%, transparent);\n color: var(--conv-list-ink);\n }\n .section-action-btn i { font-size: 12px; }\n\n .folder-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n cursor: pointer;\n color: color-mix(in srgb, var(--conv-list-ink) 80%, transparent);\n font-size: 13px;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n }\n .folder-row:hover { background: color-mix(in srgb, var(--conv-list-ink) 8%, transparent); }\n .folder-row.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n }\n .folder-row.dragging { opacity: 0.4; }\n .section-header.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n .folder-chevron {\n font-size: 9px;\n width: 10px;\n flex-shrink: 0;\n transition: transform 0.2s;\n color: color-mix(in srgb, var(--conv-list-ink) 55%, transparent);\n }\n .folder-chevron.expanded { transform: rotate(90deg); }\n .folder-icon { font-size: 12px; width: 16px; text-align: center; flex-shrink: 0; }\n .folder-name {\n /* NOT flex: 1. Growing to fill the row would push the shared badge to the right\n edge, beside the count, instead of beside the name it describes. The\n .folder-spacer after the badge takes the slack instead. Shrink + min-width:0\n keeps the ellipsis behaviour on a long name. */\n flex: 0 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 600;\n }\n .folder-count {\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n flex-shrink: 0;\n margin-left: auto;\n padding-left: 6px;\n text-align: right;\n }\n .folder-spacer {\n flex: 1 1 auto;\n min-width: 0;\n }\n .folder-shared {\n flex-shrink: 0;\n margin-left: 6px;\n font-size: 10px;\n line-height: 1;\n /* Same muted treatment as .folder-count, so it reads as metadata and does not\n compete with the folder's own colour. */\n color: color-mix(in srgb, var(--conv-list-ink) 50%, transparent);\n }\n .folder-children { display: block; }\n .folder-empty-hint {\n padding: 6px 16px;\n font-size: 11px;\n font-style: italic;\n color: color-mix(in srgb, var(--conv-list-ink) 45%, transparent);\n }\n .ungrouped-section.drag-over {\n background: color-mix(in srgb, var(--conv-list-accent) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--conv-list-accent);\n border-radius: 6px;\n }\n\n /* Dragging state. Rows never select text or raise the touch callout, so a\n long-press can select the row instead. */\n .conversation-item { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }\n .conversation-item.dragging { opacity: 0.4; }\n\n /* Move-to-folder submenu */\n .menu-item.back { font-weight: 600; }\n .menu-item .submenu-arrow { margin-left: auto; font-size: 10px; }\n .menu-item.current { background: color-mix(in srgb, var(--conv-list-accent) 18%, transparent); }\n .move-folder-list { max-height: 240px; overflow-y: auto; }\n "] }]
|
|
3121
|
+
}], () => [{ type: i1.DialogService }, { type: i2.NotificationService }, { type: i3.ActiveTasksService }, { type: i4.MJDialogService }, { type: i0.ChangeDetectorRef }], { EnvironmentId: [{
|
|
1664
3122
|
type: Input
|
|
1665
|
-
}],
|
|
3123
|
+
}], CurrentUser: [{
|
|
1666
3124
|
type: Input
|
|
1667
|
-
}],
|
|
3125
|
+
}], SelectedConversationId: [{
|
|
1668
3126
|
type: Input
|
|
1669
|
-
}],
|
|
3127
|
+
}], RenamedConversationId: [{
|
|
1670
3128
|
type: Input
|
|
1671
|
-
}],
|
|
3129
|
+
}], IsSidebarPinned: [{
|
|
1672
3130
|
type: Input
|
|
1673
|
-
}],
|
|
3131
|
+
}], IsMobileView: [{
|
|
1674
3132
|
type: Input
|
|
1675
3133
|
}], showSearch: [{
|
|
1676
3134
|
type: Input
|
|
1677
|
-
}],
|
|
3135
|
+
}], ShowNewConversationButton: [{
|
|
1678
3136
|
type: Input
|
|
1679
|
-
}],
|
|
3137
|
+
}], ShowHeaderMenu: [{
|
|
1680
3138
|
type: Input
|
|
1681
|
-
}],
|
|
3139
|
+
}], ShowSectionHeaders: [{
|
|
1682
3140
|
type: Input
|
|
3141
|
+
}], ConversationSelected: [{
|
|
3142
|
+
type: Output
|
|
1683
3143
|
}], conversationSelected: [{
|
|
1684
3144
|
type: Output
|
|
3145
|
+
}], ConversationDeleted: [{
|
|
3146
|
+
type: Output
|
|
1685
3147
|
}], conversationDeleted: [{
|
|
1686
3148
|
type: Output
|
|
3149
|
+
}], NewConversationRequested: [{
|
|
3150
|
+
type: Output
|
|
1687
3151
|
}], newConversationRequested: [{
|
|
1688
3152
|
type: Output
|
|
3153
|
+
}], PinSidebarRequested: [{
|
|
3154
|
+
type: Output
|
|
1689
3155
|
}], pinSidebarRequested: [{
|
|
1690
3156
|
type: Output
|
|
3157
|
+
}], UnpinSidebarRequested: [{
|
|
3158
|
+
type: Output
|
|
1691
3159
|
}], unpinSidebarRequested: [{
|
|
1692
3160
|
type: Output
|
|
3161
|
+
}], RefreshRequested: [{
|
|
3162
|
+
type: Output
|
|
1693
3163
|
}], refreshRequested: [{
|
|
1694
3164
|
type: Output
|
|
3165
|
+
}], SearchEscalated: [{
|
|
3166
|
+
type: Output
|
|
3167
|
+
}], searchInput: [{
|
|
3168
|
+
type: ViewChild,
|
|
3169
|
+
args: ['searchInput']
|
|
3170
|
+
}], contextMenuEl: [{
|
|
3171
|
+
type: ViewChild,
|
|
3172
|
+
args: ['contextMenuEl']
|
|
1695
3173
|
}], onDocumentClick: [{
|
|
1696
3174
|
type: HostListener,
|
|
1697
3175
|
args: ['document:click']
|
|
3176
|
+
}], onDocumentEscape: [{
|
|
3177
|
+
type: HostListener,
|
|
3178
|
+
args: ['document:keydown.escape']
|
|
3179
|
+
}], environmentId: [{
|
|
3180
|
+
type: Input
|
|
3181
|
+
}], currentUser: [{
|
|
3182
|
+
type: Input
|
|
3183
|
+
}], selectedConversationId: [{
|
|
3184
|
+
type: Input
|
|
3185
|
+
}], renamedConversationId: [{
|
|
3186
|
+
type: Input
|
|
3187
|
+
}], isSidebarPinned: [{
|
|
3188
|
+
type: Input
|
|
3189
|
+
}], isMobileView: [{
|
|
3190
|
+
type: Input
|
|
3191
|
+
}], showNewConversationButton: [{
|
|
3192
|
+
type: Input
|
|
3193
|
+
}], showHeaderMenu: [{
|
|
3194
|
+
type: Input
|
|
3195
|
+
}], showSectionHeaders: [{
|
|
3196
|
+
type: Input
|
|
1698
3197
|
}] }); })();
|
|
1699
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationListComponent, { className: "ConversationListComponent", filePath: "src/lib/components/conversation/conversation-list.component.ts", lineNumber:
|
|
3198
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationListComponent, { className: "ConversationListComponent", filePath: "src/lib/components/conversation/conversation-list.component.ts", lineNumber: 1260 }); })();
|
|
1700
3199
|
//# sourceMappingURL=conversation-list.component.js.map
|