@memberjunction/ng-conversations 5.40.2 → 5.42.0
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 +57 -0
- package/dist/__tests__/channel-optional-surface.test.d.ts +2 -0
- package/dist/__tests__/channel-optional-surface.test.d.ts.map +1 -0
- package/dist/__tests__/channel-optional-surface.test.js +53 -0
- package/dist/__tests__/channel-optional-surface.test.js.map +1 -0
- package/dist/__tests__/chat-events.test.d.ts +14 -0
- package/dist/__tests__/chat-events.test.d.ts.map +1 -0
- package/dist/__tests__/chat-events.test.js +109 -0
- package/dist/__tests__/chat-events.test.js.map +1 -0
- package/dist/__tests__/conversation-naming.test.d.ts +2 -0
- package/dist/__tests__/conversation-naming.test.d.ts.map +1 -0
- package/dist/__tests__/conversation-naming.test.js +110 -0
- package/dist/__tests__/conversation-naming.test.js.map +1 -0
- package/dist/__tests__/delegation-result-parser.test.d.ts +2 -0
- package/dist/__tests__/delegation-result-parser.test.d.ts.map +1 -0
- package/dist/__tests__/delegation-result-parser.test.js +107 -0
- package/dist/__tests__/delegation-result-parser.test.js.map +1 -0
- package/dist/__tests__/event-wiring.test.d.ts +15 -0
- package/dist/__tests__/event-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/event-wiring.test.js +100 -0
- package/dist/__tests__/event-wiring.test.js.map +1 -0
- package/dist/__tests__/narration-template.test.d.ts +2 -0
- package/dist/__tests__/narration-template.test.d.ts.map +1 -0
- package/dist/__tests__/narration-template.test.js +76 -0
- package/dist/__tests__/narration-template.test.js.map +1 -0
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts +2 -0
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-agent-picker-models.test.js +49 -0
- package/dist/__tests__/realtime-agent-picker-models.test.js.map +1 -0
- package/dist/__tests__/realtime-audio-visuals.test.d.ts +2 -0
- package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-audio-visuals.test.js +123 -0
- package/dist/__tests__/realtime-audio-visuals.test.js.map +1 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +2 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.js +48 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +1 -0
- package/dist/__tests__/realtime-disclosure.test.d.ts +2 -0
- package/dist/__tests__/realtime-disclosure.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-disclosure.test.js +164 -0
- package/dist/__tests__/realtime-disclosure.test.js.map +1 -0
- package/dist/__tests__/realtime-pairing.test.d.ts +2 -0
- package/dist/__tests__/realtime-pairing.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-pairing.test.js +207 -0
- package/dist/__tests__/realtime-pairing.test.js.map +1 -0
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts +2 -0
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-review-lifecycle.test.js +154 -0
- package/dist/__tests__/realtime-review-lifecycle.test.js.map +1 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.js +230 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.js.map +1 -0
- package/dist/__tests__/realtime-session-channels.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-channels.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-channels.test.js +252 -0
- package/dist/__tests__/realtime-session-channels.test.js.map +1 -0
- package/dist/__tests__/realtime-session-client-tools.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-client-tools.test.js +103 -0
- package/dist/__tests__/realtime-session-client-tools.test.js.map +1 -0
- package/dist/__tests__/realtime-session-minimized.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-minimized.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-minimized.test.js +32 -0
- package/dist/__tests__/realtime-session-minimized.test.js.map +1 -0
- package/dist/__tests__/realtime-session-mint.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-mint.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-mint.test.js +69 -0
- package/dist/__tests__/realtime-session-mint.test.js.map +1 -0
- package/dist/__tests__/realtime-session-policy.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-policy.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-policy.test.js +303 -0
- package/dist/__tests__/realtime-session-policy.test.js.map +1 -0
- package/dist/__tests__/realtime-session-review.service.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-review.service.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-review.service.test.js +743 -0
- package/dist/__tests__/realtime-session-review.service.test.js.map +1 -0
- package/dist/__tests__/realtime-session-state.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-state.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-state.test.js +83 -0
- package/dist/__tests__/realtime-session-state.test.js.map +1 -0
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-timeline-card.test.js +106 -0
- package/dist/__tests__/realtime-session-timeline-card.test.js.map +1 -0
- package/dist/__tests__/realtime-session-timeline.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-timeline.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-timeline.test.js +142 -0
- package/dist/__tests__/realtime-session-timeline.test.js.map +1 -0
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts +19 -0
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-sessions-adapter.test.js +188 -0
- package/dist/__tests__/realtime-sessions-adapter.test.js.map +1 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +2 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.js +100 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +1 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +2 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.js +193 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.js.map +1 -0
- package/dist/__tests__/remote-browser-audio-player.test.d.ts +2 -0
- package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +1 -0
- package/dist/__tests__/remote-browser-audio-player.test.js +137 -0
- package/dist/__tests__/remote-browser-audio-player.test.js.map +1 -0
- package/dist/__tests__/remote-browser-channel.test.d.ts +2 -0
- package/dist/__tests__/remote-browser-channel.test.d.ts.map +1 -0
- package/dist/__tests__/remote-browser-channel.test.js +585 -0
- package/dist/__tests__/remote-browser-channel.test.js.map +1 -0
- package/dist/__tests__/slot-defaults.test.d.ts +24 -0
- package/dist/__tests__/slot-defaults.test.d.ts.map +1 -0
- package/dist/__tests__/slot-defaults.test.js +63 -0
- package/dist/__tests__/slot-defaults.test.js.map +1 -0
- package/dist/__tests__/user-authorization.test.d.ts +2 -0
- package/dist/__tests__/user-authorization.test.d.ts.map +1 -0
- package/dist/__tests__/user-authorization.test.js +97 -0
- package/dist/__tests__/user-authorization.test.js.map +1 -0
- package/dist/__tests__/voice-session-narration.test.d.ts +2 -0
- package/dist/__tests__/voice-session-narration.test.d.ts.map +1 -0
- package/dist/__tests__/voice-session-narration.test.js +609 -0
- package/dist/__tests__/voice-session-narration.test.js.map +1 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.js +101 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +1 -0
- package/dist/__tests__/whiteboard-channel.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-channel.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-channel.test.js +260 -0
- package/dist/__tests__/whiteboard-channel.test.js.map +1 -0
- package/dist/__tests__/whiteboard-restore-state.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-restore-state.test.js +108 -0
- package/dist/__tests__/whiteboard-restore-state.test.js.map +1 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts +105 -2
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +1378 -489
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +209 -3
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +924 -350
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +98 -5
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +1102 -401
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +35 -17
- package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts +4 -0
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.js +43 -19
- package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +17 -1
- package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +73 -15
- package/dist/lib/components/message/message-input-box.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +142 -6
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +328 -82
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +28 -3
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +180 -108
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +81 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +252 -87
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts +5 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +104 -85
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +304 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +198 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +25 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +140 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +35 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +58 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +63 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +260 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +117 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +504 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +179 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +634 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +97 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.js +139 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts +29 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.js +69 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +65 -0
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +256 -0
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +71 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +324 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-disclosure.d.ts +135 -0
- package/dist/lib/components/realtime/realtime-disclosure.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-disclosure.js +188 -0
- package/dist/lib/components/realtime/realtime-disclosure.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +491 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +1274 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-state.d.ts +191 -0
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-state.js +244 -0
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +56 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.js +246 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +51 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +193 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts +77 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.js +114 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +173 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +496 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +181 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +223 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts +163 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js +309 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +201 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +681 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +379 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +914 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +87 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +223 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts +48 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js +180 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +119 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +274 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts +11 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js +98 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts +9 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js +35 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts +28 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.js +104 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.d.ts +11 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.js +103 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts +15 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js +73 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts +9 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.js +34 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.js.map +1 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts +95 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -0
- package/dist/lib/components/slots/slot-interfaces.js +18 -0
- package/dist/lib/components/slots/slot-interfaces.js.map +1 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +15 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +41 -12
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +12 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +93 -5
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/directives/chat-slot.directive.d.ts +44 -0
- package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -0
- package/dist/lib/directives/chat-slot.directive.js +54 -0
- package/dist/lib/directives/chat-slot.directive.js.map +1 -0
- package/dist/lib/events/chat-events.d.ts +137 -0
- package/dist/lib/events/chat-events.d.ts.map +1 -0
- package/dist/lib/events/chat-events.js +189 -0
- package/dist/lib/events/chat-events.js.map +1 -0
- package/dist/lib/models/conversation-state.model.d.ts +2 -1
- 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/services/artifact-state.service.d.ts +1 -1
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +29 -7
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +60 -74
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +100 -313
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-bridge.service.d.ts +11 -70
- package/dist/lib/services/conversation-bridge.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-bridge.service.js +51 -85
- package/dist/lib/services/conversation-bridge.service.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts +63 -0
- package/dist/lib/services/conversation-naming.d.ts.map +1 -0
- package/dist/lib/services/conversation-naming.js +58 -0
- package/dist/lib/services/conversation-naming.js.map +1 -0
- package/dist/lib/services/conversation-streaming.service.d.ts +24 -154
- package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-streaming.service.js +39 -361
- package/dist/lib/services/conversation-streaming.service.js.map +1 -1
- package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts +10 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts.map +1 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.js +104 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.js.map +1 -0
- package/dist/lib/services/delegation-result-parser.d.ts +45 -0
- package/dist/lib/services/delegation-result-parser.d.ts.map +1 -0
- package/dist/lib/services/delegation-result-parser.js +48 -0
- package/dist/lib/services/delegation-result-parser.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +19 -4
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +65 -4
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +8 -53
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +32 -243
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/narration-template.d.ts +42 -0
- package/dist/lib/services/narration-template.d.ts.map +1 -0
- package/dist/lib/services/narration-template.js +73 -0
- package/dist/lib/services/narration-template.js.map +1 -0
- package/dist/lib/services/realtime-pairing.d.ts +121 -0
- package/dist/lib/services/realtime-pairing.d.ts.map +1 -0
- package/dist/lib/services/realtime-pairing.js +160 -0
- package/dist/lib/services/realtime-pairing.js.map +1 -0
- package/dist/lib/services/realtime-session-review.service.d.ts +233 -0
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -0
- package/dist/lib/services/realtime-session-review.service.js +417 -0
- package/dist/lib/services/realtime-session-review.service.js.map +1 -0
- package/dist/lib/services/realtime-session.service.d.ts +739 -0
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -0
- package/dist/lib/services/realtime-session.service.js +1647 -0
- package/dist/lib/services/realtime-session.service.js.map +1 -0
- package/dist/lib/services/realtime-sessions-adapter.d.ts +54 -0
- package/dist/lib/services/realtime-sessions-adapter.d.ts.map +1 -0
- package/dist/lib/services/realtime-sessions-adapter.js +154 -0
- package/dist/lib/services/realtime-sessions-adapter.js.map +1 -0
- package/dist/lib/services/user-authorization.d.ts +67 -0
- package/dist/lib/services/user-authorization.d.ts.map +1 -0
- package/dist/lib/services/user-authorization.js +66 -0
- package/dist/lib/services/user-authorization.js.map +1 -0
- package/dist/lib/utils/realtime-session-timeline.d.ts +84 -0
- package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -0
- package/dist/lib/utils/realtime-session-timeline.js +94 -0
- package/dist/lib/utils/realtime-session-timeline.js.map +1 -0
- package/dist/public-api.d.ts +41 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +50 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +27 -24
- package/dist/__tests__/conversation-bridge.service.test.d.ts +0 -2
- package/dist/__tests__/conversation-bridge.service.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-bridge.service.test.js +0 -98
- package/dist/__tests__/conversation-bridge.service.test.js.map +0 -1
- package/dist/__tests__/mention-parser.test.d.ts +0 -2
- package/dist/__tests__/mention-parser.test.d.ts.map +0 -1
- package/dist/__tests__/mention-parser.test.js +0 -154
- package/dist/__tests__/mention-parser.test.js.map +0 -1
|
@@ -1,332 +1,532 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
|
|
2
|
-
import { ConversationEngine } from '@memberjunction/core-entities';
|
|
2
|
+
import { ConversationEngine, UserInfoEngine } from '@memberjunction/core-entities';
|
|
3
|
+
import { ProjectFormModalComponent } from '../project/project-form-modal.component';
|
|
3
4
|
import { Subject } from 'rxjs';
|
|
4
5
|
import { takeUntil } from 'rxjs/operators';
|
|
5
|
-
import { UUIDsEqual } from '@memberjunction/global';
|
|
6
|
+
import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
import * as i1 from "../../services/dialog.service";
|
|
8
9
|
import * as i2 from "../../services/notification.service";
|
|
9
10
|
import * as i3 from "../../services/active-tasks.service";
|
|
10
|
-
import * as i4 from "@
|
|
11
|
-
import * as i5 from "
|
|
11
|
+
import * as i4 from "@memberjunction/ng-ui-components";
|
|
12
|
+
import * as i5 from "@angular/common";
|
|
13
|
+
import * as i6 from "@angular/forms";
|
|
14
|
+
import * as i7 from "../notification/notification-badge.component";
|
|
15
|
+
const _c0 = a0 => ({ $implicit: a0 });
|
|
16
|
+
const _c1 = (a0, a1) => ({ $implicit: a0, depth: a1 });
|
|
12
17
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
i0.ɵɵ
|
|
16
|
-
i0.ɵɵ
|
|
17
|
-
i0.ɵɵ
|
|
18
|
+
const _forTrack1 = ($index, $item) => $item.project.ID;
|
|
19
|
+
function ConversationListComponent_Conditional_4_Conditional_3_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
20
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
21
|
+
i0.ɵɵelementStart(0, "button", 18);
|
|
22
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onUnpinSidebarClick($event)); });
|
|
23
|
+
i0.ɵɵelement(1, "i", 22);
|
|
18
24
|
i0.ɵɵelementStart(2, "span");
|
|
19
25
|
i0.ɵɵtext(3, "Hide Sidebar");
|
|
20
26
|
i0.ɵɵelementEnd()();
|
|
21
27
|
} }
|
|
22
28
|
function ConversationListComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
23
|
-
const
|
|
24
|
-
i0.ɵɵelementStart(0, "div",
|
|
25
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
26
|
-
i0.ɵɵelement(2, "i",
|
|
29
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
30
|
+
i0.ɵɵelementStart(0, "div", 15)(1, "button", 16);
|
|
31
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onRefreshConversationsClick($event)); });
|
|
32
|
+
i0.ɵɵelement(2, "i", 17);
|
|
27
33
|
i0.ɵɵelementStart(3, "span");
|
|
28
34
|
i0.ɵɵtext(4);
|
|
29
35
|
i0.ɵɵelementEnd()();
|
|
30
|
-
i0.ɵɵelementStart(5, "button",
|
|
31
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Template_button_click_5_listener($event) { i0.ɵɵrestoreView(
|
|
32
|
-
i0.ɵɵelement(6, "i",
|
|
36
|
+
i0.ɵɵelementStart(5, "button", 18);
|
|
37
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Template_button_click_5_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onSelectConversationsClick($event)); });
|
|
38
|
+
i0.ɵɵelement(6, "i", 19);
|
|
33
39
|
i0.ɵɵelementStart(7, "span");
|
|
34
40
|
i0.ɵɵtext(8, "Select Conversations");
|
|
35
41
|
i0.ɵɵelementEnd()();
|
|
36
|
-
i0.ɵɵ
|
|
42
|
+
i0.ɵɵelementStart(9, "button", 18);
|
|
43
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Conditional_3_Template_button_click_9_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onToggleGroupByClick($event)); });
|
|
44
|
+
i0.ɵɵelement(10, "i", 20);
|
|
45
|
+
i0.ɵɵelementStart(11, "span");
|
|
46
|
+
i0.ɵɵtext(12);
|
|
47
|
+
i0.ɵɵelementEnd()();
|
|
48
|
+
i0.ɵɵconditionalCreate(13, ConversationListComponent_Conditional_4_Conditional_3_Conditional_13_Template, 4, 0, "button", 21);
|
|
37
49
|
i0.ɵɵelementEnd();
|
|
38
50
|
} if (rf & 2) {
|
|
39
|
-
const
|
|
51
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
40
52
|
i0.ɵɵadvance();
|
|
41
|
-
i0.ɵɵproperty("disabled",
|
|
53
|
+
i0.ɵɵproperty("disabled", ctx_r2.isRefreshing);
|
|
42
54
|
i0.ɵɵadvance();
|
|
43
|
-
i0.ɵɵclassProp("fa-spin",
|
|
55
|
+
i0.ɵɵclassProp("fa-spin", ctx_r2.isRefreshing);
|
|
44
56
|
i0.ɵɵadvance(2);
|
|
45
|
-
i0.ɵɵtextInterpolate(
|
|
46
|
-
i0.ɵɵadvance(
|
|
47
|
-
i0.ɵɵ
|
|
57
|
+
i0.ɵɵtextInterpolate(ctx_r2.isRefreshing ? "Refreshing..." : "Refresh");
|
|
58
|
+
i0.ɵɵadvance(6);
|
|
59
|
+
i0.ɵɵclassProp("fa-folder-tree", ctx_r2.groupBy !== "project")("fa-list", ctx_r2.groupBy === "project");
|
|
60
|
+
i0.ɵɵadvance(2);
|
|
61
|
+
i0.ɵɵtextInterpolate(ctx_r2.groupBy === "project" ? "Show as flat list" : "Group by folder");
|
|
62
|
+
i0.ɵɵadvance();
|
|
63
|
+
i0.ɵɵconditional(!ctx_r2.isMobileView ? 13 : -1);
|
|
48
64
|
} }
|
|
49
65
|
function ConversationListComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
50
|
-
const
|
|
51
|
-
i0.ɵɵelementStart(0, "div",
|
|
52
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
53
|
-
i0.ɵɵelement(2, "i",
|
|
66
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
67
|
+
i0.ɵɵelementStart(0, "div", 6)(1, "button", 13);
|
|
68
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_4_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleHeaderMenu($event)); });
|
|
69
|
+
i0.ɵɵelement(2, "i", 14);
|
|
54
70
|
i0.ɵɵelementEnd();
|
|
55
|
-
i0.ɵɵconditionalCreate(3, ConversationListComponent_Conditional_4_Conditional_3_Template,
|
|
71
|
+
i0.ɵɵconditionalCreate(3, ConversationListComponent_Conditional_4_Conditional_3_Template, 14, 10, "div", 15);
|
|
56
72
|
i0.ɵɵelementEnd();
|
|
57
73
|
} if (rf & 2) {
|
|
58
|
-
const
|
|
74
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
59
75
|
i0.ɵɵadvance(3);
|
|
60
|
-
i0.ɵɵconditional(
|
|
76
|
+
i0.ɵɵconditional(ctx_r2.isHeaderMenuOpen ? 3 : -1);
|
|
77
|
+
} }
|
|
78
|
+
function ConversationListComponent_Conditional_10_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
i0.ɵɵelementContainer(0, 28);
|
|
80
|
+
} if (rf & 2) {
|
|
81
|
+
const conversation_r7 = ctx.$implicit;
|
|
82
|
+
i0.ɵɵnextContext(2);
|
|
83
|
+
const conversationItem_r8 = i0.ɵɵreference(17);
|
|
84
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r8)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, conversation_r7));
|
|
61
85
|
} }
|
|
62
|
-
function
|
|
63
|
-
const
|
|
64
|
-
i0.ɵɵelementStart(0, "div",
|
|
65
|
-
i0.ɵɵlistener("click", function
|
|
86
|
+
function ConversationListComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
87
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
88
|
+
i0.ɵɵelementStart(0, "div", 10)(1, "div", 23);
|
|
89
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_10_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.togglePinned()); });
|
|
90
|
+
i0.ɵɵelementStart(2, "div", 24);
|
|
91
|
+
i0.ɵɵelement(3, "i", 25)(4, "i", 26);
|
|
92
|
+
i0.ɵɵelementStart(5, "span");
|
|
93
|
+
i0.ɵɵtext(6, "Pinned");
|
|
94
|
+
i0.ɵɵelementEnd()()();
|
|
95
|
+
i0.ɵɵelementStart(7, "div", 27);
|
|
96
|
+
i0.ɵɵrepeaterCreate(8, ConversationListComponent_Conditional_10_For_9_Template, 1, 4, "ng-container", 28, _forTrack0);
|
|
66
97
|
i0.ɵɵelementEnd()();
|
|
67
98
|
} if (rf & 2) {
|
|
68
|
-
const
|
|
69
|
-
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
99
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
70
100
|
i0.ɵɵadvance();
|
|
71
|
-
i0.ɵɵ
|
|
101
|
+
i0.ɵɵclassProp("expanded", ctx_r2.pinnedExpanded);
|
|
102
|
+
i0.ɵɵadvance(6);
|
|
103
|
+
i0.ɵɵclassProp("expanded", ctx_r2.pinnedExpanded);
|
|
104
|
+
i0.ɵɵadvance();
|
|
105
|
+
i0.ɵɵrepeater(ctx_r2.pinnedConversations);
|
|
106
|
+
} }
|
|
107
|
+
function ConversationListComponent_Conditional_11_For_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
108
|
+
i0.ɵɵelementContainer(0, 28);
|
|
109
|
+
} if (rf & 2) {
|
|
110
|
+
const node_r10 = i0.ɵɵnextContext().$implicit;
|
|
111
|
+
i0.ɵɵnextContext(2);
|
|
112
|
+
const folderNode_r11 = i0.ɵɵreference(15);
|
|
113
|
+
i0.ɵɵproperty("ngTemplateOutlet", folderNode_r11)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, node_r10));
|
|
114
|
+
} }
|
|
115
|
+
function ConversationListComponent_Conditional_11_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
116
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_Conditional_11_For_10_Conditional_0_Template, 1, 4, "ng-container", 28);
|
|
117
|
+
} if (rf & 2) {
|
|
118
|
+
const node_r10 = ctx.$implicit;
|
|
119
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
120
|
+
i0.ɵɵconditional(!ctx_r2.isSearching || node_r10.hasContent ? 0 : -1);
|
|
72
121
|
} }
|
|
73
|
-
function
|
|
74
|
-
i0.ɵɵelementStart(0, "div",
|
|
75
|
-
i0.ɵɵ
|
|
122
|
+
function ConversationListComponent_Conditional_11_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
123
|
+
i0.ɵɵelementStart(0, "div", 33);
|
|
124
|
+
i0.ɵɵtext(1, "No folders yet \u2014 create one to organize conversations.");
|
|
76
125
|
i0.ɵɵelementEnd();
|
|
77
126
|
} }
|
|
78
|
-
function
|
|
79
|
-
i0.ɵɵ
|
|
127
|
+
function ConversationListComponent_Conditional_11_For_20_Template(rf, ctx) { if (rf & 1) {
|
|
128
|
+
i0.ɵɵelementContainer(0, 28);
|
|
80
129
|
} if (rf & 2) {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
i0.ɵɵ
|
|
130
|
+
const conversation_r12 = ctx.$implicit;
|
|
131
|
+
i0.ɵɵnextContext(2);
|
|
132
|
+
const conversationItem_r8 = i0.ɵɵreference(17);
|
|
133
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r8)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, conversation_r12));
|
|
84
134
|
} }
|
|
85
|
-
function
|
|
86
|
-
const
|
|
87
|
-
i0.ɵɵelementStart(0, "div",
|
|
88
|
-
i0.ɵɵlistener("click", function
|
|
89
|
-
i0.ɵɵelementStart(
|
|
90
|
-
i0.ɵɵ
|
|
91
|
-
i0.ɵɵ
|
|
92
|
-
i0.ɵɵ
|
|
93
|
-
i0.ɵɵtext(4, "Unpin");
|
|
135
|
+
function ConversationListComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
136
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
137
|
+
i0.ɵɵelementStart(0, "div", 29)(1, "div", 30);
|
|
138
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_11_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleFolders()); })("dragover", function ConversationListComponent_Conditional_11_Template_div_dragover_1_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFoldersRootDragOver($event)); })("dragleave", function ConversationListComponent_Conditional_11_Template_div_dragleave_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDragLeave("folders-root")); })("drop", function ConversationListComponent_Conditional_11_Template_div_drop_1_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFoldersRootDrop($event)); });
|
|
139
|
+
i0.ɵɵelementStart(2, "div", 24);
|
|
140
|
+
i0.ɵɵelement(3, "i", 25);
|
|
141
|
+
i0.ɵɵelementStart(4, "span");
|
|
142
|
+
i0.ɵɵtext(5, "Folders");
|
|
94
143
|
i0.ɵɵelementEnd()();
|
|
95
|
-
i0.ɵɵelementStart(
|
|
96
|
-
i0.ɵɵlistener("click", function
|
|
97
|
-
i0.ɵɵelement(
|
|
98
|
-
i0.ɵɵ
|
|
99
|
-
i0.ɵɵ
|
|
144
|
+
i0.ɵɵelementStart(6, "button", 31);
|
|
145
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_11_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.createFolder(null, $event)); });
|
|
146
|
+
i0.ɵɵelement(7, "i", 32);
|
|
147
|
+
i0.ɵɵelementEnd()();
|
|
148
|
+
i0.ɵɵelementStart(8, "div", 27);
|
|
149
|
+
i0.ɵɵrepeaterCreate(9, ConversationListComponent_Conditional_11_For_10_Template, 1, 1, null, null, _forTrack1);
|
|
150
|
+
i0.ɵɵconditionalCreate(11, ConversationListComponent_Conditional_11_Conditional_11_Template, 2, 0, "div", 33);
|
|
100
151
|
i0.ɵɵelementEnd()();
|
|
101
|
-
i0.ɵɵ
|
|
102
|
-
i0.ɵɵ
|
|
103
|
-
i0.ɵɵ
|
|
104
|
-
i0.ɵɵ
|
|
105
|
-
i0.ɵɵelementStart(
|
|
106
|
-
i0.ɵɵ
|
|
152
|
+
i0.ɵɵelementStart(12, "div", 34);
|
|
153
|
+
i0.ɵɵlistener("dragover", function ConversationListComponent_Conditional_11_Template_div_dragover_12_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onUngroupedDragOver($event)); })("dragleave", function ConversationListComponent_Conditional_11_Template_div_dragleave_12_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDragLeave("ungrouped")); })("drop", function ConversationListComponent_Conditional_11_Template_div_drop_12_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onUngroupedDrop($event)); });
|
|
154
|
+
i0.ɵɵelementStart(13, "div", 23);
|
|
155
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_11_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleUngrouped()); });
|
|
156
|
+
i0.ɵɵelementStart(14, "div", 24);
|
|
157
|
+
i0.ɵɵelement(15, "i", 25);
|
|
158
|
+
i0.ɵɵelementStart(16, "span");
|
|
159
|
+
i0.ɵɵtext(17);
|
|
107
160
|
i0.ɵɵelementEnd()()();
|
|
161
|
+
i0.ɵɵelementStart(18, "div", 27);
|
|
162
|
+
i0.ɵɵrepeaterCreate(19, ConversationListComponent_Conditional_11_For_20_Template, 1, 4, "ng-container", 28, _forTrack0);
|
|
163
|
+
i0.ɵɵelementEnd()();
|
|
164
|
+
} if (rf & 2) {
|
|
165
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
166
|
+
i0.ɵɵadvance();
|
|
167
|
+
i0.ɵɵclassProp("expanded", ctx_r2.foldersExpanded)("drag-over", ctx_r2.dragOverTargetId === "folders-root");
|
|
168
|
+
i0.ɵɵadvance(7);
|
|
169
|
+
i0.ɵɵclassProp("expanded", ctx_r2.foldersExpanded);
|
|
170
|
+
i0.ɵɵadvance();
|
|
171
|
+
i0.ɵɵrepeater(ctx_r2.folderTree);
|
|
172
|
+
i0.ɵɵadvance(2);
|
|
173
|
+
i0.ɵɵconditional(ctx_r2.folderTree.length === 0 ? 11 : -1);
|
|
174
|
+
i0.ɵɵadvance();
|
|
175
|
+
i0.ɵɵclassProp("drag-over", ctx_r2.dragOverTargetId === "ungrouped");
|
|
176
|
+
i0.ɵɵadvance();
|
|
177
|
+
i0.ɵɵclassProp("expanded", ctx_r2.ungroupedExpanded);
|
|
178
|
+
i0.ɵɵadvance(4);
|
|
179
|
+
i0.ɵɵtextInterpolate(ctx_r2.folderTree.length > 0 ? "Ungrouped" : "Messages");
|
|
180
|
+
i0.ɵɵadvance();
|
|
181
|
+
i0.ɵɵclassProp("expanded", ctx_r2.ungroupedExpanded);
|
|
182
|
+
i0.ɵɵadvance();
|
|
183
|
+
i0.ɵɵrepeater(ctx_r2.ungroupedConversations);
|
|
108
184
|
} }
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
i0.ɵɵ
|
|
185
|
+
function ConversationListComponent_Conditional_12_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
186
|
+
i0.ɵɵelementContainer(0, 28);
|
|
187
|
+
} if (rf & 2) {
|
|
188
|
+
const conversation_r14 = ctx.$implicit;
|
|
189
|
+
i0.ɵɵnextContext(2);
|
|
190
|
+
const conversationItem_r8 = i0.ɵɵreference(17);
|
|
191
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r8)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, conversation_r14));
|
|
192
|
+
} }
|
|
193
|
+
function ConversationListComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
194
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
195
|
+
i0.ɵɵelementStart(0, "div", 11)(1, "div", 23);
|
|
196
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_12_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleDirectMessages()); });
|
|
197
|
+
i0.ɵɵelementStart(2, "div", 24);
|
|
198
|
+
i0.ɵɵelement(3, "i", 25);
|
|
199
|
+
i0.ɵɵelementStart(4, "span");
|
|
200
|
+
i0.ɵɵtext(5, "Messages");
|
|
201
|
+
i0.ɵɵelementEnd()()();
|
|
202
|
+
i0.ɵɵelementStart(6, "div", 27);
|
|
203
|
+
i0.ɵɵrepeaterCreate(7, ConversationListComponent_Conditional_12_For_8_Template, 1, 4, "ng-container", 28, _forTrack0);
|
|
204
|
+
i0.ɵɵelementEnd()();
|
|
205
|
+
} if (rf & 2) {
|
|
206
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
207
|
+
i0.ɵɵadvance();
|
|
208
|
+
i0.ɵɵclassProp("expanded", ctx_r2.directMessagesExpanded);
|
|
209
|
+
i0.ɵɵadvance(5);
|
|
210
|
+
i0.ɵɵclassProp("expanded", ctx_r2.directMessagesExpanded);
|
|
211
|
+
i0.ɵɵadvance();
|
|
212
|
+
i0.ɵɵrepeater(ctx_r2.unpinnedConversations);
|
|
213
|
+
} }
|
|
214
|
+
function ConversationListComponent_Conditional_13_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
215
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
216
|
+
i0.ɵɵelementStart(0, "button", 42);
|
|
217
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.selectAll()); });
|
|
218
|
+
i0.ɵɵtext(1, "Select All");
|
|
219
|
+
i0.ɵɵelementEnd();
|
|
220
|
+
} }
|
|
221
|
+
function ConversationListComponent_Conditional_13_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
222
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
223
|
+
i0.ɵɵelementStart(0, "button", 42);
|
|
224
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.deselectAll()); });
|
|
225
|
+
i0.ɵɵtext(1, "Deselect All");
|
|
226
|
+
i0.ɵɵelementEnd();
|
|
227
|
+
} }
|
|
228
|
+
function ConversationListComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
229
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
230
|
+
i0.ɵɵelementStart(0, "div", 12)(1, "div", 35)(2, "span", 36);
|
|
231
|
+
i0.ɵɵtext(3);
|
|
114
232
|
i0.ɵɵelementEnd();
|
|
115
|
-
i0.ɵɵconditionalCreate(
|
|
233
|
+
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_13_Conditional_4_Template, 2, 0, "button", 37)(5, ConversationListComponent_Conditional_13_Conditional_5_Template, 2, 0, "button", 37);
|
|
116
234
|
i0.ɵɵelementEnd();
|
|
235
|
+
i0.ɵɵelementStart(6, "div", 38)(7, "button", 39);
|
|
236
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.bulkDeleteConversations()); });
|
|
237
|
+
i0.ɵɵelement(8, "i", 40);
|
|
238
|
+
i0.ɵɵtext(9);
|
|
239
|
+
i0.ɵɵelementEnd();
|
|
240
|
+
i0.ɵɵelementStart(10, "button", 41);
|
|
241
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_13_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleSelectionMode()); });
|
|
242
|
+
i0.ɵɵtext(11, " Cancel ");
|
|
243
|
+
i0.ɵɵelementEnd()()();
|
|
117
244
|
} if (rf & 2) {
|
|
118
|
-
const
|
|
119
|
-
|
|
245
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
246
|
+
i0.ɵɵadvance(3);
|
|
247
|
+
i0.ɵɵtextInterpolate1("", ctx_r2.selectedConversationIds.size, " selected");
|
|
248
|
+
i0.ɵɵadvance();
|
|
249
|
+
i0.ɵɵconditional(ctx_r2.selectedConversationIds.size < ctx_r2.filteredConversations.length ? 4 : 5);
|
|
120
250
|
i0.ɵɵadvance(3);
|
|
121
|
-
i0.ɵɵ
|
|
251
|
+
i0.ɵɵproperty("disabled", ctx_r2.selectedConversationIds.size === 0);
|
|
252
|
+
i0.ɵɵadvance(2);
|
|
253
|
+
i0.ɵɵtextInterpolate1(" Delete (", ctx_r2.selectedConversationIds.size, ") ");
|
|
122
254
|
} }
|
|
123
|
-
function
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
i0.ɵɵ
|
|
128
|
-
i0.ɵɵ
|
|
129
|
-
i0.ɵɵ
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
i0.ɵɵ
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
i0.ɵɵ
|
|
255
|
+
function ConversationListComponent_ng_template_14_Conditional_14_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
256
|
+
i0.ɵɵelementContainer(0, 28);
|
|
257
|
+
} if (rf & 2) {
|
|
258
|
+
const child_r20 = i0.ɵɵnextContext().$implicit;
|
|
259
|
+
i0.ɵɵnextContext(3);
|
|
260
|
+
const folderNode_r11 = i0.ɵɵreference(15);
|
|
261
|
+
i0.ɵɵproperty("ngTemplateOutlet", folderNode_r11)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r20));
|
|
262
|
+
} }
|
|
263
|
+
function ConversationListComponent_ng_template_14_Conditional_14_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
+
i0.ɵɵconditionalCreate(0, ConversationListComponent_ng_template_14_Conditional_14_For_2_Conditional_0_Template, 1, 4, "ng-container", 28);
|
|
265
|
+
} if (rf & 2) {
|
|
266
|
+
const child_r20 = ctx.$implicit;
|
|
267
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
268
|
+
i0.ɵɵconditional(!ctx_r2.isSearching || child_r20.hasContent ? 0 : -1);
|
|
269
|
+
} }
|
|
270
|
+
function ConversationListComponent_ng_template_14_Conditional_14_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
271
|
+
i0.ɵɵelementContainer(0, 28);
|
|
272
|
+
} if (rf & 2) {
|
|
273
|
+
const conversation_r21 = ctx.$implicit;
|
|
274
|
+
const node_r19 = i0.ɵɵnextContext(2).$implicit;
|
|
275
|
+
i0.ɵɵnextContext();
|
|
276
|
+
const conversationItem_r8 = i0.ɵɵreference(17);
|
|
277
|
+
i0.ɵɵproperty("ngTemplateOutlet", conversationItem_r8)("ngTemplateOutletContext", i0.ɵɵpureFunction2(2, _c1, conversation_r21, node_r19.depth + 1));
|
|
278
|
+
} }
|
|
279
|
+
function ConversationListComponent_ng_template_14_Conditional_14_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
280
|
+
i0.ɵɵelementStart(0, "div", 33);
|
|
281
|
+
i0.ɵɵtext(1, "Empty \u2014 drop a conversation here");
|
|
136
282
|
i0.ɵɵelementEnd();
|
|
137
|
-
|
|
138
|
-
i0.ɵɵ
|
|
139
|
-
i0.ɵɵ
|
|
140
|
-
|
|
283
|
+
} if (rf & 2) {
|
|
284
|
+
const node_r19 = i0.ɵɵnextContext(2).$implicit;
|
|
285
|
+
i0.ɵɵstyleProp("padding-left", 26 + node_r19.depth * 14, "px");
|
|
286
|
+
} }
|
|
287
|
+
function ConversationListComponent_ng_template_14_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
288
|
+
i0.ɵɵelementStart(0, "div", 52);
|
|
289
|
+
i0.ɵɵrepeaterCreate(1, ConversationListComponent_ng_template_14_Conditional_14_For_2_Template, 1, 1, null, null, _forTrack1);
|
|
290
|
+
i0.ɵɵrepeaterCreate(3, ConversationListComponent_ng_template_14_Conditional_14_For_4_Template, 1, 5, "ng-container", 28, _forTrack0);
|
|
291
|
+
i0.ɵɵconditionalCreate(5, ConversationListComponent_ng_template_14_Conditional_14_Conditional_5_Template, 2, 2, "div", 53);
|
|
141
292
|
i0.ɵɵelementEnd();
|
|
142
293
|
} if (rf & 2) {
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
i0.ɵɵclassProp("active", ctx_r1.IsConversationActive(conversation_r7))("renamed", ctx_r1.IsConversationRenamed(conversation_r7));
|
|
294
|
+
const node_r19 = i0.ɵɵnextContext().$implicit;
|
|
295
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
146
296
|
i0.ɵɵadvance();
|
|
147
|
-
i0.ɵɵ
|
|
297
|
+
i0.ɵɵrepeater(node_r19.children);
|
|
148
298
|
i0.ɵɵadvance(2);
|
|
149
|
-
i0.ɵɵ
|
|
299
|
+
i0.ɵɵrepeater(node_r19.conversations);
|
|
150
300
|
i0.ɵɵadvance(2);
|
|
151
|
-
i0.ɵɵ
|
|
301
|
+
i0.ɵɵconditional(node_r19.totalCount === 0 && !ctx_r2.isSearching ? 5 : -1);
|
|
302
|
+
} }
|
|
303
|
+
function ConversationListComponent_ng_template_14_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
305
|
+
i0.ɵɵelementStart(0, "div", 43);
|
|
306
|
+
i0.ɵɵlistener("dragstart", function ConversationListComponent_ng_template_14_Template_div_dragstart_0_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFolderDragStart(node_r19, $event)); })("dragend", function ConversationListComponent_ng_template_14_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFolderDragEnd()); })("click", function ConversationListComponent_ng_template_14_Template_div_click_0_listener() { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleFolder(node_r19.project.ID)); })("dragover", function ConversationListComponent_ng_template_14_Template_div_dragover_0_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFolderDragOver(node_r19.project.ID, $event)); })("dragleave", function ConversationListComponent_ng_template_14_Template_div_dragleave_0_listener() { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDragLeave(node_r19.project.ID)); })("drop", function ConversationListComponent_ng_template_14_Template_div_drop_0_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFolderDrop(node_r19.project, $event)); });
|
|
307
|
+
i0.ɵɵelement(1, "i", 44)(2, "i");
|
|
308
|
+
i0.ɵɵelementStart(3, "span", 45);
|
|
309
|
+
i0.ɵɵtext(4);
|
|
310
|
+
i0.ɵɵelementEnd();
|
|
311
|
+
i0.ɵɵelementStart(5, "span", 46);
|
|
312
|
+
i0.ɵɵtext(6);
|
|
313
|
+
i0.ɵɵelementEnd();
|
|
314
|
+
i0.ɵɵelementStart(7, "div", 47);
|
|
315
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_14_Template_div_click_7_listener($event) { i0.ɵɵrestoreView(_r18); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
316
|
+
i0.ɵɵelementStart(8, "button", 48);
|
|
317
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_14_Template_button_click_8_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.createFolder(node_r19.project.ID, $event)); });
|
|
318
|
+
i0.ɵɵelement(9, "i", 32);
|
|
319
|
+
i0.ɵɵelementEnd();
|
|
320
|
+
i0.ɵɵelementStart(10, "button", 49);
|
|
321
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_14_Template_button_click_10_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.editFolder(node_r19.project, $event)); });
|
|
322
|
+
i0.ɵɵelement(11, "i", 50);
|
|
323
|
+
i0.ɵɵelementEnd();
|
|
324
|
+
i0.ɵɵelementStart(12, "button", 51);
|
|
325
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_14_Template_button_click_12_listener($event) { const node_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.deleteFolder(node_r19.project, $event)); });
|
|
326
|
+
i0.ɵɵelement(13, "i", 40);
|
|
327
|
+
i0.ɵɵelementEnd()()();
|
|
328
|
+
i0.ɵɵconditionalCreate(14, ConversationListComponent_ng_template_14_Conditional_14_Template, 6, 1, "div", 52);
|
|
329
|
+
} if (rf & 2) {
|
|
330
|
+
const node_r19 = ctx.$implicit;
|
|
331
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
332
|
+
i0.ɵɵstyleProp("padding-left", 12 + node_r19.depth * 14, "px");
|
|
333
|
+
i0.ɵɵclassProp("drag-over", ctx_r2.dragOverTargetId === node_r19.project.ID)("dragging", ctx_r2.draggedFolderId === node_r19.project.ID);
|
|
334
|
+
i0.ɵɵproperty("draggable", true)("title", node_r19.project.Name);
|
|
152
335
|
i0.ɵɵadvance();
|
|
153
|
-
i0.ɵɵ
|
|
154
|
-
i0.ɵɵadvance(2);
|
|
155
|
-
i0.ɵɵtextInterpolate1(" ", conversation_r7.Name, " ");
|
|
336
|
+
i0.ɵɵclassProp("expanded", ctx_r2.isFolderExpanded(node_r19.project.ID));
|
|
156
337
|
i0.ɵɵadvance();
|
|
157
|
-
i0.ɵɵ
|
|
338
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ", node_r19.project.Icon || "fa-folder", " folder-icon"));
|
|
339
|
+
i0.ɵɵstyleProp("color", node_r19.project.Color || null);
|
|
158
340
|
i0.ɵɵadvance(2);
|
|
159
|
-
i0.ɵɵtextInterpolate(
|
|
160
|
-
i0.ɵɵadvance();
|
|
161
|
-
i0.ɵɵ
|
|
341
|
+
i0.ɵɵtextInterpolate(node_r19.project.Name);
|
|
342
|
+
i0.ɵɵadvance(2);
|
|
343
|
+
i0.ɵɵtextInterpolate(node_r19.totalCount);
|
|
344
|
+
i0.ɵɵadvance(8);
|
|
345
|
+
i0.ɵɵconditional(ctx_r2.isFolderExpanded(node_r19.project.ID) ? 14 : -1);
|
|
162
346
|
} }
|
|
163
|
-
function
|
|
164
|
-
const
|
|
165
|
-
i0.ɵɵelementStart(0, "div",
|
|
166
|
-
i0.ɵɵlistener("click", function
|
|
167
|
-
i0.ɵɵelementStart(2, "div", 11);
|
|
168
|
-
i0.ɵɵelement(3, "i", 12)(4, "i", 25);
|
|
169
|
-
i0.ɵɵelementStart(5, "span");
|
|
170
|
-
i0.ɵɵtext(6, "Pinned");
|
|
171
|
-
i0.ɵɵelementEnd()()();
|
|
172
|
-
i0.ɵɵelementStart(7, "div", 13);
|
|
173
|
-
i0.ɵɵrepeaterCreate(8, ConversationListComponent_Conditional_10_For_9_Template, 13, 12, "div", 14, _forTrack0);
|
|
347
|
+
function ConversationListComponent_ng_template_16_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
+
const _r24 = i0.ɵɵgetCurrentView();
|
|
349
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "input", 65);
|
|
350
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_1_Template_input_click_1_listener($event) { i0.ɵɵrestoreView(_r24); const conversation_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r2.toggleConversationSelection(conversation_r23.ID)); });
|
|
174
351
|
i0.ɵɵelementEnd()();
|
|
175
352
|
} if (rf & 2) {
|
|
176
|
-
const
|
|
177
|
-
i0.ɵɵ
|
|
178
|
-
i0.ɵɵclassProp("expanded", ctx_r1.pinnedExpanded);
|
|
179
|
-
i0.ɵɵadvance(6);
|
|
180
|
-
i0.ɵɵclassProp("expanded", ctx_r1.pinnedExpanded);
|
|
353
|
+
const conversation_r23 = i0.ɵɵnextContext().$implicit;
|
|
354
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
181
355
|
i0.ɵɵadvance();
|
|
182
|
-
i0.ɵɵ
|
|
356
|
+
i0.ɵɵproperty("checked", ctx_r2.selectedConversationIds.has(conversation_r23.ID));
|
|
183
357
|
} }
|
|
184
|
-
function
|
|
185
|
-
|
|
186
|
-
i0.ɵɵ
|
|
187
|
-
i0.ɵɵ
|
|
358
|
+
function ConversationListComponent_ng_template_16_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
359
|
+
i0.ɵɵelementStart(0, "div", 57);
|
|
360
|
+
i0.ɵɵelement(1, "i", 66);
|
|
361
|
+
i0.ɵɵelementEnd();
|
|
362
|
+
} }
|
|
363
|
+
function ConversationListComponent_ng_template_16_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
364
|
+
i0.ɵɵelement(0, "i", 62);
|
|
365
|
+
} if (rf & 2) {
|
|
366
|
+
const conversation_r23 = i0.ɵɵnextContext().$implicit;
|
|
367
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
368
|
+
i0.ɵɵproperty("title", ctx_r2.sharedWithMeTooltip(conversation_r23));
|
|
369
|
+
} }
|
|
370
|
+
function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
371
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
372
|
+
i0.ɵɵelementStart(0, "button", 75);
|
|
373
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_For_11_Template_button_click_0_listener() { const f_r29 = i0.ɵɵrestoreView(_r28).$implicit; const conversation_r23 = i0.ɵɵnextContext(4).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.selectMoveTarget(conversation_r23, f_r29.project.ID)); });
|
|
374
|
+
i0.ɵɵelement(1, "i");
|
|
375
|
+
i0.ɵɵelementStart(2, "span");
|
|
376
|
+
i0.ɵɵtext(3);
|
|
188
377
|
i0.ɵɵelementEnd()();
|
|
189
378
|
} if (rf & 2) {
|
|
190
|
-
const
|
|
191
|
-
const
|
|
379
|
+
const f_r29 = ctx.$implicit;
|
|
380
|
+
const conversation_r23 = i0.ɵɵnextContext(4).$implicit;
|
|
381
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
382
|
+
i0.ɵɵstyleProp("padding-left", 14 + f_r29.depth * 12, "px");
|
|
383
|
+
i0.ɵɵclassProp("current", ctx_r2.IsInFolder(conversation_r23, f_r29.project.ID));
|
|
192
384
|
i0.ɵɵadvance();
|
|
193
|
-
i0.ɵɵ
|
|
385
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fas ", f_r29.project.Icon || "fa-folder"));
|
|
386
|
+
i0.ɵɵstyleProp("color", f_r29.project.Color || null);
|
|
387
|
+
i0.ɵɵadvance(2);
|
|
388
|
+
i0.ɵɵtextInterpolate(f_r29.project.Name);
|
|
194
389
|
} }
|
|
195
|
-
function
|
|
196
|
-
i0.ɵɵ
|
|
197
|
-
i0.ɵɵ
|
|
390
|
+
function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
391
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
392
|
+
i0.ɵɵelementStart(0, "button", 71);
|
|
393
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.closeMoveSubmenu($event)); });
|
|
394
|
+
i0.ɵɵelement(1, "i", 72);
|
|
395
|
+
i0.ɵɵelementStart(2, "span");
|
|
396
|
+
i0.ɵɵtext(3, "Move to folder");
|
|
397
|
+
i0.ɵɵelementEnd()();
|
|
398
|
+
i0.ɵɵelement(4, "div", 73);
|
|
399
|
+
i0.ɵɵelementStart(5, "div", 74)(6, "button", 75);
|
|
400
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r27); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.selectMoveTarget(conversation_r23, null)); });
|
|
401
|
+
i0.ɵɵelement(7, "i", 76);
|
|
402
|
+
i0.ɵɵelementStart(8, "span");
|
|
403
|
+
i0.ɵɵtext(9, "No folder");
|
|
404
|
+
i0.ɵɵelementEnd()();
|
|
405
|
+
i0.ɵɵrepeaterCreate(10, ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_For_11_Template, 4, 10, "button", 77, _forTrack1);
|
|
198
406
|
i0.ɵɵelementEnd();
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
i0.ɵɵ
|
|
407
|
+
i0.ɵɵelement(12, "div", 73);
|
|
408
|
+
i0.ɵɵelementStart(13, "button", 75);
|
|
409
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_Template_button_click_13_listener($event) { i0.ɵɵrestoreView(_r27); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.createFolderForConversation(conversation_r23, $event)); });
|
|
410
|
+
i0.ɵɵelement(14, "i", 32);
|
|
411
|
+
i0.ɵɵelementStart(15, "span");
|
|
412
|
+
i0.ɵɵtext(16, "New folder\u2026");
|
|
413
|
+
i0.ɵɵelementEnd()();
|
|
202
414
|
} if (rf & 2) {
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
i0.ɵɵ
|
|
415
|
+
const conversation_r23 = i0.ɵɵnextContext(3).$implicit;
|
|
416
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
417
|
+
i0.ɵɵadvance(6);
|
|
418
|
+
i0.ɵɵclassProp("current", !conversation_r23.ProjectID);
|
|
419
|
+
i0.ɵɵadvance(4);
|
|
420
|
+
i0.ɵɵrepeater(ctx_r2.flatFolders);
|
|
206
421
|
} }
|
|
207
|
-
function
|
|
208
|
-
const
|
|
209
|
-
i0.ɵɵelementStart(0, "
|
|
210
|
-
i0.ɵɵlistener("click", function
|
|
211
|
-
i0.ɵɵ
|
|
212
|
-
i0.ɵɵ
|
|
213
|
-
i0.ɵɵ
|
|
214
|
-
i0.ɵɵelementStart(3, "span");
|
|
215
|
-
i0.ɵɵtext(4, "Pin");
|
|
422
|
+
function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
423
|
+
const _r30 = i0.ɵɵgetCurrentView();
|
|
424
|
+
i0.ɵɵelementStart(0, "button", 75);
|
|
425
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r30); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.togglePin(conversation_r23, $event)); });
|
|
426
|
+
i0.ɵɵelement(1, "i", 78);
|
|
427
|
+
i0.ɵɵelementStart(2, "span");
|
|
428
|
+
i0.ɵɵtext(3);
|
|
216
429
|
i0.ɵɵelementEnd()();
|
|
217
|
-
i0.ɵɵelementStart(
|
|
218
|
-
i0.ɵɵlistener("click", function
|
|
219
|
-
i0.ɵɵelement(
|
|
220
|
-
i0.ɵɵelementStart(
|
|
221
|
-
i0.ɵɵtext(
|
|
430
|
+
i0.ɵɵelementStart(4, "button", 75);
|
|
431
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r30); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.openMoveSubmenu(conversation_r23.ID, $event)); });
|
|
432
|
+
i0.ɵɵelement(5, "i", 79);
|
|
433
|
+
i0.ɵɵelementStart(6, "span");
|
|
434
|
+
i0.ɵɵtext(7, "Move to folder");
|
|
435
|
+
i0.ɵɵelementEnd();
|
|
436
|
+
i0.ɵɵelement(8, "i", 80);
|
|
437
|
+
i0.ɵɵelementEnd();
|
|
438
|
+
i0.ɵɵelementStart(9, "button", 75);
|
|
439
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r30); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); ctx_r2.renameConversation(conversation_r23); return i0.ɵɵresetView(ctx_r2.closeMenu()); });
|
|
440
|
+
i0.ɵɵelement(10, "i", 81);
|
|
441
|
+
i0.ɵɵelementStart(11, "span");
|
|
442
|
+
i0.ɵɵtext(12, "Rename");
|
|
222
443
|
i0.ɵɵelementEnd()();
|
|
223
|
-
i0.ɵɵelement(
|
|
224
|
-
i0.ɵɵelementStart(
|
|
225
|
-
i0.ɵɵlistener("click", function
|
|
226
|
-
i0.ɵɵelement(
|
|
227
|
-
i0.ɵɵelementStart(
|
|
228
|
-
i0.ɵɵtext(
|
|
229
|
-
i0.ɵɵelementEnd()()
|
|
444
|
+
i0.ɵɵelement(13, "div", 73);
|
|
445
|
+
i0.ɵɵelementStart(14, "button", 82);
|
|
446
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r30); const conversation_r23 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); ctx_r2.deleteConversation(conversation_r23); return i0.ɵɵresetView(ctx_r2.closeMenu()); });
|
|
447
|
+
i0.ɵɵelement(15, "i", 40);
|
|
448
|
+
i0.ɵɵelementStart(16, "span");
|
|
449
|
+
i0.ɵɵtext(17, "Delete");
|
|
450
|
+
i0.ɵɵelementEnd()();
|
|
451
|
+
} if (rf & 2) {
|
|
452
|
+
const conversation_r23 = i0.ɵɵnextContext(3).$implicit;
|
|
453
|
+
i0.ɵɵadvance(3);
|
|
454
|
+
i0.ɵɵtextInterpolate(conversation_r23.IsPinned ? "Unpin" : "Pin");
|
|
455
|
+
} }
|
|
456
|
+
function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
457
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
458
|
+
i0.ɵɵelementStart(0, "div", 70);
|
|
459
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r26); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
460
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_1_Template, 17, 2)(2, ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Conditional_2_Template, 18, 1);
|
|
461
|
+
i0.ɵɵelementEnd();
|
|
462
|
+
} if (rf & 2) {
|
|
463
|
+
const conversation_r23 = i0.ɵɵnextContext(2).$implicit;
|
|
464
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
465
|
+
i0.ɵɵadvance();
|
|
466
|
+
i0.ɵɵconditional(ctx_r2.IsMoveSubmenuOpen(conversation_r23) ? 1 : 2);
|
|
230
467
|
} }
|
|
231
|
-
function
|
|
232
|
-
const
|
|
233
|
-
i0.ɵɵelementStart(0, "div",
|
|
234
|
-
i0.ɵɵlistener("click", function
|
|
235
|
-
i0.ɵɵelement(2, "i",
|
|
468
|
+
function ConversationListComponent_ng_template_16_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
469
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
470
|
+
i0.ɵɵelementStart(0, "div", 64)(1, "button", 67);
|
|
471
|
+
i0.ɵɵlistener("click", function ConversationListComponent_ng_template_16_Conditional_12_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r25); const conversation_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMenu(conversation_r23.ID, $event)); });
|
|
472
|
+
i0.ɵɵelement(2, "i", 68);
|
|
236
473
|
i0.ɵɵelementEnd();
|
|
237
|
-
i0.ɵɵconditionalCreate(3,
|
|
474
|
+
i0.ɵɵconditionalCreate(3, ConversationListComponent_ng_template_16_Conditional_12_Conditional_3_Template, 3, 1, "div", 69);
|
|
238
475
|
i0.ɵɵelementEnd();
|
|
239
476
|
} if (rf & 2) {
|
|
240
|
-
const
|
|
241
|
-
const
|
|
477
|
+
const conversation_r23 = i0.ɵɵnextContext().$implicit;
|
|
478
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
242
479
|
i0.ɵɵadvance(3);
|
|
243
|
-
i0.ɵɵconditional(
|
|
480
|
+
i0.ɵɵconditional(ctx_r2.IsMenuOpen(conversation_r23) ? 3 : -1);
|
|
244
481
|
} }
|
|
245
|
-
function
|
|
246
|
-
const
|
|
247
|
-
i0.ɵɵelementStart(0, "div",
|
|
248
|
-
i0.ɵɵlistener("click", function
|
|
249
|
-
i0.ɵɵconditionalCreate(1,
|
|
250
|
-
i0.ɵɵelementStart(2, "div",
|
|
251
|
-
i0.ɵɵconditionalCreate(3,
|
|
252
|
-
i0.ɵɵelementStart(4, "div",
|
|
253
|
-
i0.ɵɵelement(5, "mj-notification-badge",
|
|
482
|
+
function ConversationListComponent_ng_template_16_Template(rf, ctx) { if (rf & 1) {
|
|
483
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
484
|
+
i0.ɵɵelementStart(0, "div", 54);
|
|
485
|
+
i0.ɵɵlistener("dragstart", function ConversationListComponent_ng_template_16_Template_div_dragstart_0_listener($event) { const conversation_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConversationDragStart(conversation_r23, $event)); })("dragend", function ConversationListComponent_ng_template_16_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConversationDragEnd()); })("click", function ConversationListComponent_ng_template_16_Template_div_click_0_listener() { const conversation_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.handleConversationClick(conversation_r23)); });
|
|
486
|
+
i0.ɵɵconditionalCreate(1, ConversationListComponent_ng_template_16_Conditional_1_Template, 2, 1, "div", 55);
|
|
487
|
+
i0.ɵɵelementStart(2, "div", 56);
|
|
488
|
+
i0.ɵɵconditionalCreate(3, ConversationListComponent_ng_template_16_Conditional_3_Template, 2, 0, "div", 57);
|
|
489
|
+
i0.ɵɵelementStart(4, "div", 58);
|
|
490
|
+
i0.ɵɵelement(5, "mj-notification-badge", 59);
|
|
254
491
|
i0.ɵɵelementEnd()();
|
|
255
|
-
i0.ɵɵelementStart(6, "div",
|
|
492
|
+
i0.ɵɵelementStart(6, "div", 60)(7, "div", 61);
|
|
256
493
|
i0.ɵɵtext(8);
|
|
257
|
-
i0.ɵɵconditionalCreate(9,
|
|
494
|
+
i0.ɵɵconditionalCreate(9, ConversationListComponent_ng_template_16_Conditional_9_Template, 1, 1, "i", 62);
|
|
258
495
|
i0.ɵɵelementEnd();
|
|
259
|
-
i0.ɵɵelementStart(10, "div",
|
|
496
|
+
i0.ɵɵelementStart(10, "div", 63);
|
|
260
497
|
i0.ɵɵtext(11);
|
|
261
498
|
i0.ɵɵelementEnd()();
|
|
262
|
-
i0.ɵɵconditionalCreate(12,
|
|
499
|
+
i0.ɵɵconditionalCreate(12, ConversationListComponent_ng_template_16_Conditional_12_Template, 4, 1, "div", 64);
|
|
263
500
|
i0.ɵɵelementEnd();
|
|
264
501
|
} if (rf & 2) {
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
i0.ɵɵ
|
|
502
|
+
const conversation_r23 = ctx.$implicit;
|
|
503
|
+
const depth_r31 = ctx.depth;
|
|
504
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
505
|
+
i0.ɵɵstyleProp("padding-left", depth_r31 ? 16 + depth_r31 * 14 : 16, "px");
|
|
506
|
+
i0.ɵɵclassProp("active", ctx_r2.IsConversationActive(conversation_r23))("renamed", ctx_r2.IsConversationRenamed(conversation_r23))("dragging", ctx_r2.IsConversationDragging(conversation_r23));
|
|
507
|
+
i0.ɵɵproperty("draggable", !ctx_r2.isSelectionMode);
|
|
268
508
|
i0.ɵɵadvance();
|
|
269
|
-
i0.ɵɵconditional(
|
|
509
|
+
i0.ɵɵconditional(ctx_r2.isSelectionMode ? 1 : -1);
|
|
270
510
|
i0.ɵɵadvance(2);
|
|
271
|
-
i0.ɵɵconditional(
|
|
511
|
+
i0.ɵɵconditional(ctx_r2.hasActiveTasks(conversation_r23.ID) ? 3 : -1);
|
|
272
512
|
i0.ɵɵadvance(2);
|
|
273
|
-
i0.ɵɵproperty("conversationId",
|
|
513
|
+
i0.ɵɵproperty("conversationId", conversation_r23.ID);
|
|
274
514
|
i0.ɵɵadvance();
|
|
275
|
-
i0.ɵɵproperty("title",
|
|
515
|
+
i0.ɵɵproperty("title", conversation_r23.Name + (conversation_r23.Description ? "\n" + conversation_r23.Description : ""));
|
|
276
516
|
i0.ɵɵadvance(2);
|
|
277
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
517
|
+
i0.ɵɵtextInterpolate1(" ", conversation_r23.Name, " ");
|
|
278
518
|
i0.ɵɵadvance();
|
|
279
|
-
i0.ɵɵconditional(
|
|
519
|
+
i0.ɵɵconditional(ctx_r2.isSharedWithMe(conversation_r23) ? 9 : -1);
|
|
280
520
|
i0.ɵɵadvance(2);
|
|
281
|
-
i0.ɵɵtextInterpolate(
|
|
521
|
+
i0.ɵɵtextInterpolate(conversation_r23.Description);
|
|
282
522
|
i0.ɵɵadvance();
|
|
283
|
-
i0.ɵɵconditional(!
|
|
284
|
-
} }
|
|
285
|
-
function ConversationListComponent_Conditional_20_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
286
|
-
const _r17 = i0.ɵɵgetCurrentView();
|
|
287
|
-
i0.ɵɵelementStart(0, "button", 55);
|
|
288
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_20_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectAll()); });
|
|
289
|
-
i0.ɵɵtext(1, "Select All");
|
|
290
|
-
i0.ɵɵelementEnd();
|
|
291
|
-
} }
|
|
292
|
-
function ConversationListComponent_Conditional_20_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
293
|
-
const _r18 = i0.ɵɵgetCurrentView();
|
|
294
|
-
i0.ɵɵelementStart(0, "button", 55);
|
|
295
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_20_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.deselectAll()); });
|
|
296
|
-
i0.ɵɵtext(1, "Deselect All");
|
|
297
|
-
i0.ɵɵelementEnd();
|
|
298
|
-
} }
|
|
299
|
-
function ConversationListComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
300
|
-
const _r16 = i0.ɵɵgetCurrentView();
|
|
301
|
-
i0.ɵɵelementStart(0, "div", 15)(1, "div", 49)(2, "span", 50);
|
|
302
|
-
i0.ɵɵtext(3);
|
|
303
|
-
i0.ɵɵelementEnd();
|
|
304
|
-
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_20_Conditional_4_Template, 2, 0, "button", 51)(5, ConversationListComponent_Conditional_20_Conditional_5_Template, 2, 0, "button", 51);
|
|
305
|
-
i0.ɵɵelementEnd();
|
|
306
|
-
i0.ɵɵelementStart(6, "div", 52)(7, "button", 53);
|
|
307
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_20_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.bulkDeleteConversations()); });
|
|
308
|
-
i0.ɵɵelement(8, "i", 48);
|
|
309
|
-
i0.ɵɵtext(9);
|
|
310
|
-
i0.ɵɵelementEnd();
|
|
311
|
-
i0.ɵɵelementStart(10, "button", 54);
|
|
312
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Conditional_20_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSelectionMode()); });
|
|
313
|
-
i0.ɵɵtext(11, " Cancel ");
|
|
314
|
-
i0.ɵɵelementEnd()()();
|
|
315
|
-
} if (rf & 2) {
|
|
316
|
-
const ctx_r1 = i0.ɵɵnextContext();
|
|
317
|
-
i0.ɵɵadvance(3);
|
|
318
|
-
i0.ɵɵtextInterpolate1("", ctx_r1.selectedConversationIds.size, " selected");
|
|
319
|
-
i0.ɵɵadvance();
|
|
320
|
-
i0.ɵɵconditional(ctx_r1.selectedConversationIds.size < ctx_r1.filteredConversations.length ? 4 : 5);
|
|
321
|
-
i0.ɵɵadvance(3);
|
|
322
|
-
i0.ɵɵproperty("disabled", ctx_r1.selectedConversationIds.size === 0);
|
|
323
|
-
i0.ɵɵadvance(2);
|
|
324
|
-
i0.ɵɵtextInterpolate1(" Delete (", ctx_r1.selectedConversationIds.size, ") ");
|
|
523
|
+
i0.ɵɵconditional(!ctx_r2.isSelectionMode ? 12 : -1);
|
|
325
524
|
} }
|
|
326
525
|
export class ConversationListComponent {
|
|
327
526
|
dialogService;
|
|
328
527
|
notificationService;
|
|
329
528
|
activeTasksService;
|
|
529
|
+
mjDialogService;
|
|
330
530
|
cdr;
|
|
331
531
|
environmentId;
|
|
332
532
|
currentUser;
|
|
@@ -342,45 +542,81 @@ export class ConversationListComponent {
|
|
|
342
542
|
refreshRequested = new EventEmitter(); // Emitted after list refresh so chat area can also reload
|
|
343
543
|
directMessagesExpanded = true;
|
|
344
544
|
pinnedExpanded = true;
|
|
545
|
+
foldersExpanded = true;
|
|
546
|
+
ungroupedExpanded = true;
|
|
345
547
|
openMenuConversationId = null;
|
|
346
548
|
conversationIdsWithTasks = new Set();
|
|
347
549
|
isSelectionMode = false;
|
|
348
550
|
selectedConversationIds = new Set();
|
|
349
|
-
searchQuery = '';
|
|
350
551
|
isHeaderMenuOpen = false;
|
|
351
552
|
isRefreshing = false;
|
|
553
|
+
/** UserInfoEngine key for persisting folder collapse state + group-by mode. */
|
|
554
|
+
static FolderPrefsKey = 'mj.conversations.folderPrefs.v1';
|
|
555
|
+
/** How the conversation list is grouped. 'project' = folders, 'none' = flat list. */
|
|
556
|
+
groupBy = 'project';
|
|
557
|
+
/** Precomputed groupings, rebuilt whenever conversations/projects/search change. */
|
|
558
|
+
pinnedConversations = [];
|
|
559
|
+
unpinnedConversations = [];
|
|
560
|
+
ungroupedConversations = [];
|
|
561
|
+
folderTree = [];
|
|
562
|
+
/** Flattened folder list (depth-ordered) for the "Move to folder" menu. */
|
|
563
|
+
flatFolders = [];
|
|
564
|
+
/** Folder IDs (normalized) whose children are collapsed. Absent = expanded. */
|
|
565
|
+
collapsedFolderIds = new Set();
|
|
566
|
+
/** Drag-and-drop state. */
|
|
567
|
+
draggedConversationId = null;
|
|
568
|
+
draggedFolderId = null;
|
|
569
|
+
dragOverTargetId = null;
|
|
570
|
+
/** When set, the open conversation menu is showing its "Move to folder" picker. */
|
|
571
|
+
moveSubmenuConversationId = null;
|
|
572
|
+
_searchQuery = '';
|
|
352
573
|
destroy$ = new Subject();
|
|
353
574
|
engine = ConversationEngine.Instance;
|
|
354
575
|
// Local UI state for loading/refreshing
|
|
355
576
|
IsLoading = false;
|
|
356
|
-
constructor(dialogService, notificationService, activeTasksService, cdr) {
|
|
577
|
+
constructor(dialogService, notificationService, activeTasksService, mjDialogService, cdr) {
|
|
357
578
|
this.dialogService = dialogService;
|
|
358
579
|
this.notificationService = notificationService;
|
|
359
580
|
this.activeTasksService = activeTasksService;
|
|
581
|
+
this.mjDialogService = mjDialogService;
|
|
360
582
|
this.cdr = cdr;
|
|
361
583
|
}
|
|
584
|
+
get searchQuery() {
|
|
585
|
+
return this._searchQuery;
|
|
586
|
+
}
|
|
587
|
+
set searchQuery(value) {
|
|
588
|
+
this._searchQuery = value ?? '';
|
|
589
|
+
this.rebuildGroups();
|
|
590
|
+
}
|
|
591
|
+
/** True when a search filter is active. */
|
|
592
|
+
get isSearching() {
|
|
593
|
+
return this._searchQuery.trim().length > 0;
|
|
594
|
+
}
|
|
595
|
+
/** Conversations matching the current search (used by selection-mode helpers). */
|
|
362
596
|
get filteredConversations() {
|
|
363
|
-
|
|
364
|
-
|
|
597
|
+
return this.filterConversations(this.engine.Conversations);
|
|
598
|
+
}
|
|
599
|
+
filterConversations(conversations) {
|
|
600
|
+
if (!this.isSearching) {
|
|
601
|
+
return conversations;
|
|
365
602
|
}
|
|
366
|
-
const lowerQuery = this.
|
|
367
|
-
return
|
|
603
|
+
const lowerQuery = this._searchQuery.toLowerCase();
|
|
604
|
+
return conversations.filter(c => (c.Name?.toLowerCase().includes(lowerQuery)) ||
|
|
368
605
|
(c.Description?.toLowerCase().includes(lowerQuery)));
|
|
369
606
|
}
|
|
370
|
-
get pinnedConversations() {
|
|
371
|
-
return this.filteredConversations.filter(c => c.IsPinned);
|
|
372
|
-
}
|
|
373
|
-
get unpinnedConversations() {
|
|
374
|
-
return this.filteredConversations.filter(c => !c.IsPinned);
|
|
375
|
-
}
|
|
376
607
|
ngOnInit() {
|
|
377
|
-
//
|
|
608
|
+
// Restore persisted folder collapse state + group-by preference
|
|
609
|
+
this.loadFolderPrefs();
|
|
610
|
+
// Load conversations (and folders) on init
|
|
378
611
|
this.engine.LoadConversations(this.environmentId, this.currentUser, false);
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
// engine.Conversations directly, so Angular doesn't know to re-evaluate them unless
|
|
382
|
-
// we explicitly trigger a check here.
|
|
612
|
+
// Rebuild the precomputed groupings whenever conversations OR projects change
|
|
613
|
+
// (pin, archive, rename, move-to-folder, folder create/rename/delete, etc.).
|
|
383
614
|
this.engine.Conversations$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
615
|
+
this.rebuildGroups();
|
|
616
|
+
this.cdr.detectChanges();
|
|
617
|
+
});
|
|
618
|
+
this.engine.Projects$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
619
|
+
this.rebuildGroups();
|
|
384
620
|
this.cdr.detectChanges();
|
|
385
621
|
});
|
|
386
622
|
// Subscribe to conversation IDs with active tasks (hot set)
|
|
@@ -414,6 +650,11 @@ export class ConversationListComponent {
|
|
|
414
650
|
this.toggleSelectionMode();
|
|
415
651
|
this.closeHeaderMenu();
|
|
416
652
|
}
|
|
653
|
+
onToggleGroupByClick(event) {
|
|
654
|
+
event.stopPropagation();
|
|
655
|
+
this.toggleGroupBy();
|
|
656
|
+
this.closeHeaderMenu();
|
|
657
|
+
}
|
|
417
658
|
async onRefreshConversationsClick(event) {
|
|
418
659
|
event.stopPropagation();
|
|
419
660
|
if (this.isRefreshing)
|
|
@@ -450,6 +691,382 @@ export class ConversationListComponent {
|
|
|
450
691
|
togglePinned() {
|
|
451
692
|
this.pinnedExpanded = !this.pinnedExpanded;
|
|
452
693
|
}
|
|
694
|
+
toggleFolders() {
|
|
695
|
+
this.foldersExpanded = !this.foldersExpanded;
|
|
696
|
+
}
|
|
697
|
+
toggleUngrouped() {
|
|
698
|
+
this.ungroupedExpanded = !this.ungroupedExpanded;
|
|
699
|
+
}
|
|
700
|
+
// ========================================================================
|
|
701
|
+
// FOLDER GROUPING
|
|
702
|
+
// ========================================================================
|
|
703
|
+
/**
|
|
704
|
+
* Recomputes pinned/unpinned/ungrouped lists and the folder tree from the
|
|
705
|
+
* engine's conversation + project caches and the current search filter.
|
|
706
|
+
*/
|
|
707
|
+
rebuildGroups() {
|
|
708
|
+
const matching = this.filterConversations(this.engine.Conversations);
|
|
709
|
+
this.pinnedConversations = matching.filter(c => c.IsPinned);
|
|
710
|
+
this.unpinnedConversations = matching.filter(c => !c.IsPinned);
|
|
711
|
+
const projects = this.engine.Projects;
|
|
712
|
+
const projectIds = new Set(projects.map(p => NormalizeUUID(p.ID)));
|
|
713
|
+
// Bucket unpinned conversations by their folder (pinned ones live in the
|
|
714
|
+
// Pinned section). Conversations with no/unknown folder are "ungrouped".
|
|
715
|
+
const conversationsByProject = new Map();
|
|
716
|
+
const ungrouped = [];
|
|
717
|
+
for (const c of this.unpinnedConversations) {
|
|
718
|
+
const pid = c.ProjectID ? NormalizeUUID(c.ProjectID) : null;
|
|
719
|
+
if (pid && projectIds.has(pid)) {
|
|
720
|
+
const arr = conversationsByProject.get(pid) ?? [];
|
|
721
|
+
arr.push(c);
|
|
722
|
+
conversationsByProject.set(pid, arr);
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
ungrouped.push(c);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
this.ungroupedConversations = ungrouped;
|
|
729
|
+
// Index projects by parent. A project whose parent isn't loaded is treated
|
|
730
|
+
// as a root so it never disappears from the tree.
|
|
731
|
+
const childrenByParent = new Map();
|
|
732
|
+
for (const p of projects) {
|
|
733
|
+
const parentId = p.ParentID ? NormalizeUUID(p.ParentID) : null;
|
|
734
|
+
const key = parentId && projectIds.has(parentId) ? parentId : null;
|
|
735
|
+
const arr = childrenByParent.get(key) ?? [];
|
|
736
|
+
arr.push(p);
|
|
737
|
+
childrenByParent.set(key, arr);
|
|
738
|
+
}
|
|
739
|
+
const build = (parentKey, depth) => {
|
|
740
|
+
const projectsAtLevel = childrenByParent.get(parentKey) ?? [];
|
|
741
|
+
return projectsAtLevel.map(p => {
|
|
742
|
+
const children = build(NormalizeUUID(p.ID), depth + 1);
|
|
743
|
+
const conversations = conversationsByProject.get(NormalizeUUID(p.ID)) ?? [];
|
|
744
|
+
const totalCount = conversations.length + children.reduce((sum, ch) => sum + ch.totalCount, 0);
|
|
745
|
+
const hasContent = conversations.length > 0 || children.some(ch => ch.hasContent);
|
|
746
|
+
return { project: p, depth, conversations, children, totalCount, hasContent };
|
|
747
|
+
});
|
|
748
|
+
};
|
|
749
|
+
this.folderTree = build(null, 0);
|
|
750
|
+
this.flatFolders = this.flattenFolders(this.folderTree);
|
|
751
|
+
}
|
|
752
|
+
flattenFolders(nodes) {
|
|
753
|
+
const out = [];
|
|
754
|
+
for (const node of nodes) {
|
|
755
|
+
out.push(node);
|
|
756
|
+
out.push(...this.flattenFolders(node.children));
|
|
757
|
+
}
|
|
758
|
+
return out;
|
|
759
|
+
}
|
|
760
|
+
findFolderNode(nodes, projectId) {
|
|
761
|
+
for (const node of nodes) {
|
|
762
|
+
if (UUIDsEqual(node.project.ID, projectId))
|
|
763
|
+
return node;
|
|
764
|
+
const found = this.findFolderNode(node.children, projectId);
|
|
765
|
+
if (found)
|
|
766
|
+
return found;
|
|
767
|
+
}
|
|
768
|
+
return null;
|
|
769
|
+
}
|
|
770
|
+
isFolderExpanded(projectId) {
|
|
771
|
+
return !this.collapsedFolderIds.has(NormalizeUUID(projectId));
|
|
772
|
+
}
|
|
773
|
+
toggleFolder(projectId) {
|
|
774
|
+
const key = NormalizeUUID(projectId);
|
|
775
|
+
if (this.collapsedFolderIds.has(key)) {
|
|
776
|
+
this.collapsedFolderIds.delete(key);
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
this.collapsedFolderIds.add(key);
|
|
780
|
+
}
|
|
781
|
+
this.saveFolderPrefs();
|
|
782
|
+
}
|
|
783
|
+
toggleGroupBy() {
|
|
784
|
+
this.groupBy = this.groupBy === 'project' ? 'none' : 'project';
|
|
785
|
+
this.saveFolderPrefs();
|
|
786
|
+
this.rebuildGroups();
|
|
787
|
+
}
|
|
788
|
+
loadFolderPrefs() {
|
|
789
|
+
try {
|
|
790
|
+
const raw = UserInfoEngine.Instance.GetSetting(ConversationListComponent.FolderPrefsKey);
|
|
791
|
+
if (!raw)
|
|
792
|
+
return;
|
|
793
|
+
const parsed = JSON.parse(raw);
|
|
794
|
+
this.collapsedFolderIds = new Set((parsed.collapsed ?? []).map(id => NormalizeUUID(id)));
|
|
795
|
+
if (parsed.groupBy === 'none' || parsed.groupBy === 'project') {
|
|
796
|
+
this.groupBy = parsed.groupBy;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
catch {
|
|
800
|
+
// Corrupt/legacy value — ignore and use defaults
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
saveFolderPrefs() {
|
|
804
|
+
const payload = JSON.stringify({
|
|
805
|
+
collapsed: Array.from(this.collapsedFolderIds),
|
|
806
|
+
groupBy: this.groupBy
|
|
807
|
+
});
|
|
808
|
+
UserInfoEngine.Instance.SetSettingDebounced(ConversationListComponent.FolderPrefsKey, payload);
|
|
809
|
+
}
|
|
810
|
+
// ========================================================================
|
|
811
|
+
// DRAG & DROP (move conversation into/out of a folder)
|
|
812
|
+
// ========================================================================
|
|
813
|
+
onConversationDragStart(conversation, event) {
|
|
814
|
+
if (this.isSelectionMode)
|
|
815
|
+
return;
|
|
816
|
+
this.draggedFolderId = null;
|
|
817
|
+
this.draggedConversationId = conversation.ID;
|
|
818
|
+
if (event.dataTransfer) {
|
|
819
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
820
|
+
event.dataTransfer.setData('text/plain', conversation.ID);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
onConversationDragEnd() {
|
|
824
|
+
this.draggedConversationId = null;
|
|
825
|
+
this.dragOverTargetId = null;
|
|
826
|
+
}
|
|
827
|
+
onFolderDragStart(node, event) {
|
|
828
|
+
event.stopPropagation();
|
|
829
|
+
this.draggedConversationId = null;
|
|
830
|
+
this.draggedFolderId = node.project.ID;
|
|
831
|
+
if (event.dataTransfer) {
|
|
832
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
833
|
+
event.dataTransfer.setData('text/plain', node.project.ID);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
onFolderDragEnd() {
|
|
837
|
+
this.draggedFolderId = null;
|
|
838
|
+
this.dragOverTargetId = null;
|
|
839
|
+
}
|
|
840
|
+
onFolderDragOver(projectId, event) {
|
|
841
|
+
// A conversation can drop onto any folder; a folder can drop onto any folder
|
|
842
|
+
// that isn't itself or one of its own descendants (which would create a cycle).
|
|
843
|
+
const accepts = this.draggedConversationId
|
|
844
|
+
? true
|
|
845
|
+
: this.draggedFolderId
|
|
846
|
+
? this.isValidFolderDropTarget(projectId)
|
|
847
|
+
: false;
|
|
848
|
+
if (!accepts)
|
|
849
|
+
return;
|
|
850
|
+
event.preventDefault();
|
|
851
|
+
if (event.dataTransfer)
|
|
852
|
+
event.dataTransfer.dropEffect = 'move';
|
|
853
|
+
this.dragOverTargetId = projectId;
|
|
854
|
+
}
|
|
855
|
+
onUngroupedDragOver(event) {
|
|
856
|
+
if (!this.draggedConversationId)
|
|
857
|
+
return;
|
|
858
|
+
event.preventDefault();
|
|
859
|
+
if (event.dataTransfer)
|
|
860
|
+
event.dataTransfer.dropEffect = 'move';
|
|
861
|
+
this.dragOverTargetId = 'ungrouped';
|
|
862
|
+
}
|
|
863
|
+
/** The Folders section header accepts a dragged folder to move it back to the top level. */
|
|
864
|
+
onFoldersRootDragOver(event) {
|
|
865
|
+
if (!this.draggedFolderId)
|
|
866
|
+
return;
|
|
867
|
+
event.preventDefault();
|
|
868
|
+
if (event.dataTransfer)
|
|
869
|
+
event.dataTransfer.dropEffect = 'move';
|
|
870
|
+
this.dragOverTargetId = 'folders-root';
|
|
871
|
+
}
|
|
872
|
+
onDragLeave(targetId) {
|
|
873
|
+
if (this.dragOverTargetId === targetId) {
|
|
874
|
+
this.dragOverTargetId = null;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
onFolderDrop(project, event) {
|
|
878
|
+
event.preventDefault();
|
|
879
|
+
const conversationId = this.draggedConversationId;
|
|
880
|
+
const folderId = this.draggedFolderId;
|
|
881
|
+
this.dragOverTargetId = null;
|
|
882
|
+
this.draggedConversationId = null;
|
|
883
|
+
this.draggedFolderId = null;
|
|
884
|
+
if (conversationId) {
|
|
885
|
+
this.moveConversation(conversationId, project.ID);
|
|
886
|
+
}
|
|
887
|
+
else if (folderId && this.isValidFolderDropTarget(project.ID, folderId)) {
|
|
888
|
+
this.moveFolder(folderId, project.ID);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
onUngroupedDrop(event) {
|
|
892
|
+
event.preventDefault();
|
|
893
|
+
const conversationId = this.draggedConversationId;
|
|
894
|
+
this.dragOverTargetId = null;
|
|
895
|
+
this.draggedConversationId = null;
|
|
896
|
+
if (conversationId) {
|
|
897
|
+
this.moveConversation(conversationId, null);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
onFoldersRootDrop(event) {
|
|
901
|
+
event.preventDefault();
|
|
902
|
+
const folderId = this.draggedFolderId;
|
|
903
|
+
this.dragOverTargetId = null;
|
|
904
|
+
this.draggedFolderId = null;
|
|
905
|
+
if (folderId) {
|
|
906
|
+
this.moveFolder(folderId, null);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* A folder can be dropped onto a target folder only if the target isn't the dragged
|
|
911
|
+
* folder itself and isn't one of its descendants (otherwise we'd create a cycle).
|
|
912
|
+
*/
|
|
913
|
+
isValidFolderDropTarget(targetId, draggedId = this.draggedFolderId) {
|
|
914
|
+
if (!draggedId)
|
|
915
|
+
return false;
|
|
916
|
+
if (UUIDsEqual(targetId, draggedId))
|
|
917
|
+
return false;
|
|
918
|
+
return !this.isDescendantOf(targetId, draggedId);
|
|
919
|
+
}
|
|
920
|
+
/** True when `nodeId` is a descendant of `ancestorId` in the folder tree. */
|
|
921
|
+
isDescendantOf(nodeId, ancestorId) {
|
|
922
|
+
const byId = new Map(this.engine.Projects.map(p => [NormalizeUUID(p.ID), p]));
|
|
923
|
+
const visited = new Set();
|
|
924
|
+
let current = byId.get(NormalizeUUID(nodeId));
|
|
925
|
+
while (current?.ParentID) {
|
|
926
|
+
const parentKey = NormalizeUUID(current.ParentID);
|
|
927
|
+
if (visited.has(parentKey))
|
|
928
|
+
break; // guard against malformed cycles
|
|
929
|
+
visited.add(parentKey);
|
|
930
|
+
if (UUIDsEqual(parentKey, ancestorId))
|
|
931
|
+
return true;
|
|
932
|
+
current = byId.get(parentKey);
|
|
933
|
+
}
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
/** Assigns a conversation to a folder (or null to ungroup) and refreshes the view. */
|
|
937
|
+
async moveConversation(conversationId, projectId) {
|
|
938
|
+
try {
|
|
939
|
+
await this.engine.MoveConversationToProject(conversationId, projectId, this.currentUser);
|
|
940
|
+
// Reveal the destination folder so the user sees where it landed
|
|
941
|
+
if (projectId) {
|
|
942
|
+
this.collapsedFolderIds.delete(NormalizeUUID(projectId));
|
|
943
|
+
}
|
|
944
|
+
this.rebuildGroups();
|
|
945
|
+
this.cdr.detectChanges();
|
|
946
|
+
}
|
|
947
|
+
catch (error) {
|
|
948
|
+
console.error('Error moving conversation:', error);
|
|
949
|
+
await this.dialogService.alert('Error', 'Failed to move conversation. Please try again.');
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
/** Reparents a folder under another folder (or to the top level when projectId is null). */
|
|
953
|
+
async moveFolder(folderId, parentId) {
|
|
954
|
+
// No-op if it's already under that parent
|
|
955
|
+
const folder = this.engine.Projects.find(p => UUIDsEqual(p.ID, folderId));
|
|
956
|
+
const currentParent = folder?.ParentID ?? null;
|
|
957
|
+
const sameParent = (currentParent === null && parentId === null) ||
|
|
958
|
+
(!!currentParent && !!parentId && UUIDsEqual(currentParent, parentId));
|
|
959
|
+
if (sameParent)
|
|
960
|
+
return;
|
|
961
|
+
try {
|
|
962
|
+
await this.engine.MoveProjectToParent(folderId, parentId, this.currentUser);
|
|
963
|
+
// Reveal the new parent so the moved folder is visible
|
|
964
|
+
if (parentId) {
|
|
965
|
+
this.collapsedFolderIds.delete(NormalizeUUID(parentId));
|
|
966
|
+
}
|
|
967
|
+
this.rebuildGroups();
|
|
968
|
+
this.cdr.detectChanges();
|
|
969
|
+
}
|
|
970
|
+
catch (error) {
|
|
971
|
+
console.error('Error moving folder:', error);
|
|
972
|
+
await this.dialogService.alert('Error', 'Failed to move folder. Please try again.');
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
// ========================================================================
|
|
976
|
+
// MOVE-TO-FOLDER MENU
|
|
977
|
+
// ========================================================================
|
|
978
|
+
openMoveSubmenu(conversationId, event) {
|
|
979
|
+
event.stopPropagation();
|
|
980
|
+
this.moveSubmenuConversationId = conversationId;
|
|
981
|
+
}
|
|
982
|
+
closeMoveSubmenu(event) {
|
|
983
|
+
event.stopPropagation();
|
|
984
|
+
this.moveSubmenuConversationId = null;
|
|
985
|
+
}
|
|
986
|
+
IsInFolder(conversation, projectId) {
|
|
987
|
+
return !!conversation.ProjectID && UUIDsEqual(conversation.ProjectID, projectId);
|
|
988
|
+
}
|
|
989
|
+
selectMoveTarget(conversation, projectId) {
|
|
990
|
+
this.moveConversation(conversation.ID, projectId);
|
|
991
|
+
this.closeMenu();
|
|
992
|
+
}
|
|
993
|
+
// ========================================================================
|
|
994
|
+
// FOLDER CRUD (reuses the existing project form modal)
|
|
995
|
+
// ========================================================================
|
|
996
|
+
createFolder(parentId, event) {
|
|
997
|
+
if (event)
|
|
998
|
+
event.stopPropagation();
|
|
999
|
+
this.openFolderModal(null, parentId);
|
|
1000
|
+
}
|
|
1001
|
+
editFolder(project, event) {
|
|
1002
|
+
if (event)
|
|
1003
|
+
event.stopPropagation();
|
|
1004
|
+
this.openFolderModal(project, null);
|
|
1005
|
+
}
|
|
1006
|
+
createFolderForConversation(conversation, event) {
|
|
1007
|
+
event.stopPropagation();
|
|
1008
|
+
const conversationId = conversation.ID;
|
|
1009
|
+
this.closeMenu();
|
|
1010
|
+
this.openFolderModal(null, null, (created) => this.moveConversation(conversationId, created.ID));
|
|
1011
|
+
}
|
|
1012
|
+
openFolderModal(project, parentId, onCreated) {
|
|
1013
|
+
const dialogRef = this.mjDialogService.open({
|
|
1014
|
+
content: ProjectFormModalComponent,
|
|
1015
|
+
width: 600,
|
|
1016
|
+
minWidth: 400
|
|
1017
|
+
});
|
|
1018
|
+
const instance = dialogRef.Content.instance;
|
|
1019
|
+
instance.dialogRef = dialogRef;
|
|
1020
|
+
instance.environmentId = this.environmentId;
|
|
1021
|
+
instance.currentUser = this.currentUser;
|
|
1022
|
+
if (project)
|
|
1023
|
+
instance.project = project;
|
|
1024
|
+
if (parentId)
|
|
1025
|
+
instance.parentId = parentId;
|
|
1026
|
+
instance.projectSaved.subscribe((saved) => {
|
|
1027
|
+
// The engine's entity-event handler keeps the projects cache in sync; we
|
|
1028
|
+
// just reveal the parent and refresh, then run any post-create action.
|
|
1029
|
+
if (parentId) {
|
|
1030
|
+
this.collapsedFolderIds.delete(NormalizeUUID(parentId));
|
|
1031
|
+
}
|
|
1032
|
+
this.rebuildGroups();
|
|
1033
|
+
this.cdr.detectChanges();
|
|
1034
|
+
if (onCreated)
|
|
1035
|
+
onCreated(saved);
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
async deleteFolder(project, event) {
|
|
1039
|
+
if (event)
|
|
1040
|
+
event.stopPropagation();
|
|
1041
|
+
const node = this.findFolderNode(this.folderTree, project.ID);
|
|
1042
|
+
const total = node?.totalCount ?? 0;
|
|
1043
|
+
const childCount = node?.children.length ?? 0;
|
|
1044
|
+
let message = `Are you sure you want to delete the folder "${project.Name}"?`;
|
|
1045
|
+
if (total > 0 || childCount > 0) {
|
|
1046
|
+
message += `\n\nConversations inside will be moved out of the folder`;
|
|
1047
|
+
message += childCount > 0 ? ` and subfolders will move up one level.` : `.`;
|
|
1048
|
+
message += ` Nothing is deleted.`;
|
|
1049
|
+
}
|
|
1050
|
+
const confirmed = await this.dialogService.confirm({
|
|
1051
|
+
title: 'Delete Folder',
|
|
1052
|
+
message,
|
|
1053
|
+
okText: 'Delete',
|
|
1054
|
+
cancelText: 'Cancel',
|
|
1055
|
+
dangerous: true
|
|
1056
|
+
});
|
|
1057
|
+
if (!confirmed)
|
|
1058
|
+
return;
|
|
1059
|
+
try {
|
|
1060
|
+
await this.engine.DeleteProject(project.ID, this.currentUser);
|
|
1061
|
+
this.collapsedFolderIds.delete(NormalizeUUID(project.ID));
|
|
1062
|
+
this.rebuildGroups();
|
|
1063
|
+
this.cdr.detectChanges();
|
|
1064
|
+
}
|
|
1065
|
+
catch (error) {
|
|
1066
|
+
console.error('Error deleting folder:', error);
|
|
1067
|
+
await this.dialogService.alert('Error', error instanceof Error ? error.message : 'Failed to delete folder. Please try again.');
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
453
1070
|
IsConversationActive(conversation) {
|
|
454
1071
|
return UUIDsEqual(conversation.ID, this.selectedConversationId);
|
|
455
1072
|
}
|
|
@@ -459,6 +1076,12 @@ export class ConversationListComponent {
|
|
|
459
1076
|
IsMenuOpen(conversation) {
|
|
460
1077
|
return UUIDsEqual(this.openMenuConversationId, conversation.ID);
|
|
461
1078
|
}
|
|
1079
|
+
IsConversationDragging(conversation) {
|
|
1080
|
+
return UUIDsEqual(this.draggedConversationId, conversation.ID);
|
|
1081
|
+
}
|
|
1082
|
+
IsMoveSubmenuOpen(conversation) {
|
|
1083
|
+
return UUIDsEqual(this.moveSubmenuConversationId, conversation.ID);
|
|
1084
|
+
}
|
|
462
1085
|
selectConversation(conversation) {
|
|
463
1086
|
this.conversationSelected.emit(conversation.ID);
|
|
464
1087
|
// Clear unread notifications when conversation is opened
|
|
@@ -524,6 +1147,7 @@ export class ConversationListComponent {
|
|
|
524
1147
|
}
|
|
525
1148
|
closeMenu() {
|
|
526
1149
|
this.openMenuConversationId = null;
|
|
1150
|
+
this.moveSubmenuConversationId = null;
|
|
527
1151
|
}
|
|
528
1152
|
async togglePin(conversation, event) {
|
|
529
1153
|
if (event)
|
|
@@ -621,35 +1245,29 @@ export class ConversationListComponent {
|
|
|
621
1245
|
this.selectConversation(conversation);
|
|
622
1246
|
}
|
|
623
1247
|
}
|
|
624
|
-
static ɵfac = function ConversationListComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ConversationListComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.NotificationService), i0.ɵɵdirectiveInject(i3.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
1248
|
+
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)); };
|
|
625
1249
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationListComponent, selectors: [["mj-conversation-list"]], hostBindings: function ConversationListComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
626
1250
|
i0.ɵɵlistener("click", function ConversationListComponent_click_HostBindingHandler() { return ctx.onDocumentClick(); }, i0.ɵɵresolveDocument);
|
|
627
|
-
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", selectedConversationId: "selectedConversationId", renamedConversationId: "renamedConversationId", isSidebarPinned: "isSidebarPinned", isMobileView: "isMobileView" }, outputs: { conversationSelected: "conversationSelected", conversationDeleted: "conversationDeleted", newConversationRequested: "newConversationRequested", pinSidebarRequested: "pinSidebarRequested", unpinSidebarRequested: "unpinSidebarRequested", refreshRequested: "refreshRequested" }, standalone: false, decls:
|
|
628
|
-
|
|
629
|
-
i0.ɵɵ
|
|
1251
|
+
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", selectedConversationId: "selectedConversationId", renamedConversationId: "renamedConversationId", isSidebarPinned: "isSidebarPinned", isMobileView: "isMobileView" }, outputs: { conversationSelected: "conversationSelected", conversationDeleted: "conversationDeleted", newConversationRequested: "newConversationRequested", pinSidebarRequested: "pinSidebarRequested", unpinSidebarRequested: "unpinSidebarRequested", refreshRequested: "refreshRequested" }, standalone: false, decls: 18, vars: 5, consts: [["folderNode", ""], ["conversationItem", ""], [1, "conversation-list"], [1, "list-header"], [1, "header-top"], ["type", "text", "placeholder", "Search conversations...", 1, "search-input", 3, "ngModelChange", "ngModel"], [1, "header-menu-container"], ["title", "New Conversation", 1, "btn-new-conversation", 3, "click"], [1, "fas", "fa-plus"], [1, "list-content"], [1, "sidebar-section", "pinned-section"], [1, "sidebar-section"], [1, "selection-action-bar"], ["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", "fa-check-square"], [1, "fas"], [1, "dropdown-item"], [1, "fas", "fa-table-columns"], [1, "section-header", 3, "click"], [1, "section-title"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-thumbtack", "section-icon"], [1, "chat-list"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], [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, "selection-info"], [1, "selection-count"], [1, "link-btn"], [1, "selection-actions"], [1, "btn-delete-bulk", 3, "click", "disabled"], [1, "fas", "fa-trash"], [1, "btn-cancel", 3, "click"], [1, "link-btn", 3, "click"], [1, "folder-row", 3, "dragstart", "dragend", "click", "dragover", "dragleave", "drop", "draggable", "title"], [1, "fas", "fa-chevron-right", "folder-chevron"], [1, "folder-name"], [1, "folder-count"], [1, "folder-actions", 3, "click"], ["title", "New Subfolder", 1, "folder-action-btn", 3, "click"], ["title", "Edit Folder", 1, "folder-action-btn", 3, "click"], [1, "fas", "fa-pen"], ["title", "Delete Folder", 1, "folder-action-btn", "danger", 3, "click"], [1, "folder-children"], [1, "folder-empty-hint", 3, "paddingLeft"], [1, "conversation-item", 3, "dragstart", "dragend", "click", "draggable"], [1, "conversation-checkbox"], [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"], ["type", "checkbox", 3, "click", "checked"], [1, "fas", "fa-spinner", "fa-pulse"], ["title", "More options", 1, "menu-btn", 3, "click"], [1, "fas", "fa-ellipsis"], [1, "context-menu"], [1, "context-menu", 3, "click"], [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, "fas", "fa-thumbtack"], [1, "fas", "fa-folder-tree"], [1, "fas", "fa-chevron-right", "submenu-arrow"], [1, "fas", "fa-edit"], [1, "menu-item", "danger", 3, "click"]], template: function ConversationListComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1252
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
1253
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 3)(2, "div", 4)(3, "input", 5);
|
|
1254
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ConversationListComponent_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.searchQuery, $event) || (ctx.searchQuery = $event); return i0.ɵɵresetView($event); });
|
|
630
1255
|
i0.ɵɵelementEnd();
|
|
631
|
-
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_4_Template, 4, 1, "div",
|
|
1256
|
+
i0.ɵɵconditionalCreate(4, ConversationListComponent_Conditional_4_Template, 4, 1, "div", 6);
|
|
632
1257
|
i0.ɵɵelementEnd()();
|
|
633
|
-
i0.ɵɵelementStart(5, "button",
|
|
634
|
-
i0.ɵɵlistener("click", function ConversationListComponent_Template_button_click_5_listener() { return ctx.createNewConversation(); });
|
|
635
|
-
i0.ɵɵelement(6, "i",
|
|
1258
|
+
i0.ɵɵelementStart(5, "button", 7);
|
|
1259
|
+
i0.ɵɵlistener("click", function ConversationListComponent_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.createNewConversation()); });
|
|
1260
|
+
i0.ɵɵelement(6, "i", 8);
|
|
636
1261
|
i0.ɵɵelementStart(7, "span");
|
|
637
1262
|
i0.ɵɵtext(8, "New Conversation");
|
|
638
1263
|
i0.ɵɵelementEnd()();
|
|
639
|
-
i0.ɵɵelementStart(9, "div",
|
|
640
|
-
i0.ɵɵconditionalCreate(10, ConversationListComponent_Conditional_10_Template, 10, 4, "div",
|
|
641
|
-
i0.ɵɵ
|
|
642
|
-
i0.ɵɵ
|
|
643
|
-
i0.ɵɵ
|
|
644
|
-
i0.ɵɵelement(14, "i", 12);
|
|
645
|
-
i0.ɵɵelementStart(15, "span");
|
|
646
|
-
i0.ɵɵtext(16, "Messages");
|
|
647
|
-
i0.ɵɵelementEnd()()();
|
|
648
|
-
i0.ɵɵelementStart(17, "div", 13);
|
|
649
|
-
i0.ɵɵrepeaterCreate(18, ConversationListComponent_For_19_Template, 13, 12, "div", 14, _forTrack0);
|
|
650
|
-
i0.ɵɵelementEnd()()();
|
|
651
|
-
i0.ɵɵconditionalCreate(20, ConversationListComponent_Conditional_20_Template, 12, 4, "div", 15);
|
|
1264
|
+
i0.ɵɵelementStart(9, "div", 9);
|
|
1265
|
+
i0.ɵɵconditionalCreate(10, ConversationListComponent_Conditional_10_Template, 10, 4, "div", 10);
|
|
1266
|
+
i0.ɵɵconditionalCreate(11, ConversationListComponent_Conditional_11_Template, 21, 14)(12, ConversationListComponent_Conditional_12_Template, 9, 4, "div", 11);
|
|
1267
|
+
i0.ɵɵelementEnd();
|
|
1268
|
+
i0.ɵɵconditionalCreate(13, ConversationListComponent_Conditional_13_Template, 12, 4, "div", 12);
|
|
652
1269
|
i0.ɵɵelementEnd();
|
|
1270
|
+
i0.ɵɵtemplate(14, ConversationListComponent_ng_template_14_Template, 15, 18, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(16, ConversationListComponent_ng_template_16_Template, 13, 17, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
653
1271
|
} if (rf & 2) {
|
|
654
1272
|
i0.ɵɵadvance(3);
|
|
655
1273
|
i0.ɵɵtwoWayProperty("ngModel", ctx.searchQuery);
|
|
@@ -657,15 +1275,11 @@ export class ConversationListComponent {
|
|
|
657
1275
|
i0.ɵɵconditional(!ctx.isSelectionMode ? 4 : -1);
|
|
658
1276
|
i0.ɵɵadvance(6);
|
|
659
1277
|
i0.ɵɵconditional(ctx.pinnedConversations.length > 0 ? 10 : -1);
|
|
660
|
-
i0.ɵɵadvance(2);
|
|
661
|
-
i0.ɵɵclassProp("expanded", ctx.directMessagesExpanded);
|
|
662
|
-
i0.ɵɵadvance(5);
|
|
663
|
-
i0.ɵɵclassProp("expanded", ctx.directMessagesExpanded);
|
|
664
1278
|
i0.ɵɵadvance();
|
|
665
|
-
i0.ɵɵ
|
|
1279
|
+
i0.ɵɵconditional(ctx.groupBy === "project" ? 11 : 12);
|
|
666
1280
|
i0.ɵɵadvance(2);
|
|
667
|
-
i0.ɵɵconditional(ctx.isSelectionMode ?
|
|
668
|
-
} }, dependencies: [i4.DefaultValueAccessor, i4.NgControlStatus, i4.NgModel, i5.NotificationBadgeComponent], styles: ["[_nghost-%COMP%] { display: block; height: 100%; }\n .conversation-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header[_ngcontent-%COMP%] { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input[_ngcontent-%COMP%]::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input[_ngcontent-%COMP%]:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation[_ngcontent-%COMP%] {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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(--mj-brand-primary-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\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; }\n .conversation-item.active[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\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(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview[_ngcontent-%COMP%] { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 80%, transparent); }\n .conversation-meta[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\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(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active[_ngcontent-%COMP%] .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\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\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(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !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(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active[_ngcontent-%COMP%] .menu-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 10%, transparent);\n margin: 4px 0;\n }\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 @keyframes _ngcontent-%COMP%_renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n \n\n .header-top[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n }\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-primary);\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(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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 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 }"] });
|
|
1281
|
+
i0.ɵɵconditional(ctx.isSelectionMode ? 13 : -1);
|
|
1282
|
+
} }, dependencies: [i5.NgTemplateOutlet, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, i7.NotificationBadgeComponent], styles: ["[_nghost-%COMP%] { display: block; height: 100%; }\n .conversation-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header[_ngcontent-%COMP%] { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input[_ngcontent-%COMP%]::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input[_ngcontent-%COMP%]:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation[_ngcontent-%COMP%] {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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(--mj-brand-primary-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\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item[_ngcontent-%COMP%]:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item[_ngcontent-%COMP%]:hover .conversation-actions[_ngcontent-%COMP%] { opacity: 1; }\n .conversation-item.active[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\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(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview[_ngcontent-%COMP%] { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 80%, transparent); }\n .conversation-meta[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\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(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active[_ngcontent-%COMP%] .project-badge[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\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\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(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !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(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active[_ngcontent-%COMP%] .menu-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 10%, transparent);\n margin: 4px 0;\n }\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 @keyframes _ngcontent-%COMP%_renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n \n\n .header-top[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n }\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu[_ngcontent-%COMP%] .dropdown-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-primary);\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(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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 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\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 15%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 8%, transparent); }\n .folder-row.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n }\n .folder-row.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n .section-header.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 18%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 45%, transparent);\n }\n .ungrouped-section.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n border-radius: 6px;\n }\n\n \n\n .conversation-item[_ngcontent-%COMP%] { user-select: none; }\n .conversation-item.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n\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(--mj-brand-primary) 18%, transparent); }\n .move-folder-list[_ngcontent-%COMP%] { max-height: 240px; overflow-y: auto; }"] });
|
|
669
1283
|
}
|
|
670
1284
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationListComponent, [{
|
|
671
1285
|
type: Component,
|
|
@@ -693,6 +1307,10 @@ export class ConversationListComponent {
|
|
|
693
1307
|
<i class="fas fa-check-square"></i>
|
|
694
1308
|
<span>Select Conversations</span>
|
|
695
1309
|
</button>
|
|
1310
|
+
<button class="dropdown-item" (click)="onToggleGroupByClick($event)">
|
|
1311
|
+
<i class="fas" [class.fa-folder-tree]="groupBy !== 'project'" [class.fa-list]="groupBy === 'project'"></i>
|
|
1312
|
+
<span>{{ groupBy === 'project' ? 'Show as flat list' : 'Group by folder' }}</span>
|
|
1313
|
+
</button>
|
|
696
1314
|
@if (!isMobileView) {
|
|
697
1315
|
<button class="dropdown-item" (click)="onUnpinSidebarClick($event)">
|
|
698
1316
|
<i class="fas fa-table-columns"></i>
|
|
@@ -722,136 +1340,75 @@ export class ConversationListComponent {
|
|
|
722
1340
|
</div>
|
|
723
1341
|
<div class="chat-list" [class.expanded]="pinnedExpanded">
|
|
724
1342
|
@for (conversation of pinnedConversations; track conversation.ID) {
|
|
725
|
-
<
|
|
726
|
-
[class.active]="IsConversationActive(conversation)"
|
|
727
|
-
[class.renamed]="IsConversationRenamed(conversation)"
|
|
728
|
-
(click)="handleConversationClick(conversation)">
|
|
729
|
-
@if (isSelectionMode) {
|
|
730
|
-
<div class="conversation-checkbox">
|
|
731
|
-
<input type="checkbox"
|
|
732
|
-
[checked]="selectedConversationIds.has(conversation.ID)"
|
|
733
|
-
(click)="$event.stopPropagation(); toggleConversationSelection(conversation.ID)">
|
|
734
|
-
</div>
|
|
735
|
-
}
|
|
736
|
-
<div class="conversation-icon-wrapper">
|
|
737
|
-
@if (hasActiveTasks(conversation.ID)) {
|
|
738
|
-
<div class="conversation-icon has-tasks">
|
|
739
|
-
<i class="fas fa-spinner fa-pulse"></i>
|
|
740
|
-
</div>
|
|
741
|
-
}
|
|
742
|
-
<div class="badge-overlay">
|
|
743
|
-
<mj-notification-badge [conversationId]="conversation.ID"></mj-notification-badge>
|
|
744
|
-
</div>
|
|
745
|
-
</div>
|
|
746
|
-
<div class="conversation-info" [title]="conversation.Name + (conversation.Description ? '\n' + conversation.Description : '')">
|
|
747
|
-
<div class="conversation-name">
|
|
748
|
-
{{ conversation.Name }}
|
|
749
|
-
@if (isSharedWithMe(conversation)) {
|
|
750
|
-
<i class="fas fa-share-nodes shared-indicator"
|
|
751
|
-
[title]="sharedWithMeTooltip(conversation)"></i>
|
|
752
|
-
}
|
|
753
|
-
</div>
|
|
754
|
-
<div class="conversation-preview">{{ conversation.Description }}</div>
|
|
755
|
-
</div>
|
|
756
|
-
@if (!isSelectionMode) {
|
|
757
|
-
<div class="conversation-actions">
|
|
758
|
-
<button class="menu-btn" (click)="toggleMenu(conversation.ID, $event)" title="More options">
|
|
759
|
-
<i class="fas fa-ellipsis"></i>
|
|
760
|
-
</button>
|
|
761
|
-
@if (IsMenuOpen(conversation)) {
|
|
762
|
-
<div class="context-menu" (click)="$event.stopPropagation()">
|
|
763
|
-
<button class="menu-item" (click)="togglePin(conversation, $event)">
|
|
764
|
-
<i class="fas fa-thumbtack"></i>
|
|
765
|
-
<span>Unpin</span>
|
|
766
|
-
</button>
|
|
767
|
-
<button class="menu-item" (click)="renameConversation(conversation); closeMenu()">
|
|
768
|
-
<i class="fas fa-edit"></i>
|
|
769
|
-
<span>Rename</span>
|
|
770
|
-
</button>
|
|
771
|
-
<div class="menu-divider"></div>
|
|
772
|
-
<button class="menu-item danger" (click)="deleteConversation(conversation); closeMenu()">
|
|
773
|
-
<i class="fas fa-trash"></i>
|
|
774
|
-
<span>Delete</span>
|
|
775
|
-
</button>
|
|
776
|
-
</div>
|
|
777
|
-
}
|
|
778
|
-
</div>
|
|
779
|
-
}
|
|
780
|
-
</div>
|
|
1343
|
+
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
781
1344
|
}
|
|
782
1345
|
</div>
|
|
783
1346
|
</div>
|
|
784
1347
|
}
|
|
785
1348
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
<div class="section-
|
|
789
|
-
<div class="section-
|
|
790
|
-
|
|
791
|
-
|
|
1349
|
+
@if (groupBy === 'project') {
|
|
1350
|
+
<!-- Folders Section -->
|
|
1351
|
+
<div class="sidebar-section folders-section">
|
|
1352
|
+
<div class="section-header" [class.expanded]="foldersExpanded"
|
|
1353
|
+
[class.drag-over]="dragOverTargetId === 'folders-root'"
|
|
1354
|
+
(click)="toggleFolders()"
|
|
1355
|
+
(dragover)="onFoldersRootDragOver($event)"
|
|
1356
|
+
(dragleave)="onDragLeave('folders-root')"
|
|
1357
|
+
(drop)="onFoldersRootDrop($event)">
|
|
1358
|
+
<div class="section-title">
|
|
1359
|
+
<i class="fas fa-chevron-right"></i>
|
|
1360
|
+
<span>Folders</span>
|
|
1361
|
+
</div>
|
|
1362
|
+
<button class="section-action-btn" (click)="createFolder(null, $event)" title="New Folder">
|
|
1363
|
+
<i class="fas fa-folder-plus"></i>
|
|
1364
|
+
</button>
|
|
792
1365
|
</div>
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
[class.active]="IsConversationActive(conversation)"
|
|
798
|
-
[class.renamed]="IsConversationRenamed(conversation)"
|
|
799
|
-
(click)="handleConversationClick(conversation)">
|
|
800
|
-
@if (isSelectionMode) {
|
|
801
|
-
<div class="conversation-checkbox">
|
|
802
|
-
<input type="checkbox"
|
|
803
|
-
[checked]="selectedConversationIds.has(conversation.ID)"
|
|
804
|
-
(click)="$event.stopPropagation(); toggleConversationSelection(conversation.ID)">
|
|
805
|
-
</div>
|
|
806
|
-
}
|
|
807
|
-
<div class="conversation-icon-wrapper">
|
|
808
|
-
@if (hasActiveTasks(conversation.ID)) {
|
|
809
|
-
<div class="conversation-icon has-tasks">
|
|
810
|
-
<i class="fas fa-spinner fa-pulse"></i>
|
|
811
|
-
</div>
|
|
812
|
-
}
|
|
813
|
-
<div class="badge-overlay">
|
|
814
|
-
<mj-notification-badge [conversationId]="conversation.ID"></mj-notification-badge>
|
|
815
|
-
</div>
|
|
816
|
-
</div>
|
|
817
|
-
<div class="conversation-info" [title]="conversation.Name + (conversation.Description ? '\n' + conversation.Description : '')">
|
|
818
|
-
<div class="conversation-name">
|
|
819
|
-
{{ conversation.Name }}
|
|
820
|
-
@if (isSharedWithMe(conversation)) {
|
|
821
|
-
<i class="fas fa-share-nodes shared-indicator"
|
|
822
|
-
[title]="sharedWithMeTooltip(conversation)"></i>
|
|
823
|
-
}
|
|
824
|
-
</div>
|
|
825
|
-
<div class="conversation-preview">{{ conversation.Description }}</div>
|
|
826
|
-
</div>
|
|
827
|
-
@if (!isSelectionMode) {
|
|
828
|
-
<div class="conversation-actions">
|
|
829
|
-
<button class="menu-btn" (click)="toggleMenu(conversation.ID, $event)" title="More options">
|
|
830
|
-
<i class="fas fa-ellipsis"></i>
|
|
831
|
-
</button>
|
|
832
|
-
@if (IsMenuOpen(conversation)) {
|
|
833
|
-
<div class="context-menu" (click)="$event.stopPropagation()">
|
|
834
|
-
<button class="menu-item" (click)="togglePin(conversation, $event)">
|
|
835
|
-
<i class="fas fa-thumbtack"></i>
|
|
836
|
-
<span>Pin</span>
|
|
837
|
-
</button>
|
|
838
|
-
<button class="menu-item" (click)="renameConversation(conversation); closeMenu()">
|
|
839
|
-
<i class="fas fa-edit"></i>
|
|
840
|
-
<span>Rename</span>
|
|
841
|
-
</button>
|
|
842
|
-
<div class="menu-divider"></div>
|
|
843
|
-
<button class="menu-item danger" (click)="deleteConversation(conversation); closeMenu()">
|
|
844
|
-
<i class="fas fa-trash"></i>
|
|
845
|
-
<span>Delete</span>
|
|
846
|
-
</button>
|
|
847
|
-
</div>
|
|
848
|
-
}
|
|
849
|
-
</div>
|
|
1366
|
+
<div class="chat-list" [class.expanded]="foldersExpanded">
|
|
1367
|
+
@for (node of folderTree; track node.project.ID) {
|
|
1368
|
+
@if (!isSearching || node.hasContent) {
|
|
1369
|
+
<ng-container [ngTemplateOutlet]="folderNode" [ngTemplateOutletContext]="{ $implicit: node }"></ng-container>
|
|
850
1370
|
}
|
|
1371
|
+
}
|
|
1372
|
+
@if (folderTree.length === 0) {
|
|
1373
|
+
<div class="folder-empty-hint">No folders yet — create one to organize conversations.</div>
|
|
1374
|
+
}
|
|
1375
|
+
</div>
|
|
1376
|
+
</div>
|
|
1377
|
+
|
|
1378
|
+
<!-- Ungrouped Section (drop target to remove from folder) -->
|
|
1379
|
+
<div class="sidebar-section ungrouped-section"
|
|
1380
|
+
[class.drag-over]="dragOverTargetId === 'ungrouped'"
|
|
1381
|
+
(dragover)="onUngroupedDragOver($event)"
|
|
1382
|
+
(dragleave)="onDragLeave('ungrouped')"
|
|
1383
|
+
(drop)="onUngroupedDrop($event)">
|
|
1384
|
+
<div class="section-header" [class.expanded]="ungroupedExpanded" (click)="toggleUngrouped()">
|
|
1385
|
+
<div class="section-title">
|
|
1386
|
+
<i class="fas fa-chevron-right"></i>
|
|
1387
|
+
<span>{{ folderTree.length > 0 ? 'Ungrouped' : 'Messages' }}</span>
|
|
851
1388
|
</div>
|
|
852
|
-
|
|
1389
|
+
</div>
|
|
1390
|
+
<div class="chat-list" [class.expanded]="ungroupedExpanded">
|
|
1391
|
+
@for (conversation of ungroupedConversations; track conversation.ID) {
|
|
1392
|
+
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
1393
|
+
}
|
|
1394
|
+
</div>
|
|
853
1395
|
</div>
|
|
854
|
-
|
|
1396
|
+
} @else {
|
|
1397
|
+
<!-- Flat Messages Section -->
|
|
1398
|
+
<div class="sidebar-section">
|
|
1399
|
+
<div class="section-header" [class.expanded]="directMessagesExpanded" (click)="toggleDirectMessages()">
|
|
1400
|
+
<div class="section-title">
|
|
1401
|
+
<i class="fas fa-chevron-right"></i>
|
|
1402
|
+
<span>Messages</span>
|
|
1403
|
+
</div>
|
|
1404
|
+
</div>
|
|
1405
|
+
<div class="chat-list" [class.expanded]="directMessagesExpanded">
|
|
1406
|
+
@for (conversation of unpinnedConversations; track conversation.ID) {
|
|
1407
|
+
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation }"></ng-container>
|
|
1408
|
+
}
|
|
1409
|
+
</div>
|
|
1410
|
+
</div>
|
|
1411
|
+
}
|
|
855
1412
|
</div>
|
|
856
1413
|
|
|
857
1414
|
<!-- Selection Action Bar -->
|
|
@@ -879,8 +1436,152 @@ export class ConversationListComponent {
|
|
|
879
1436
|
</div>
|
|
880
1437
|
}
|
|
881
1438
|
</div>
|
|
882
|
-
`, styles: ["\n :host { display: block; height: 100%; }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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(--mj-brand-primary-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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\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(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active .menu-btn {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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 @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-primary);\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(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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 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 "] }]
|
|
883
|
-
|
|
1439
|
+
|
|
1440
|
+
<!-- Recursive folder node: header + nested children + direct conversations -->
|
|
1441
|
+
<ng-template #folderNode let-node>
|
|
1442
|
+
<div class="folder-row"
|
|
1443
|
+
[class.drag-over]="dragOverTargetId === node.project.ID"
|
|
1444
|
+
[class.dragging]="draggedFolderId === node.project.ID"
|
|
1445
|
+
[style.paddingLeft.px]="12 + node.depth * 14"
|
|
1446
|
+
[draggable]="true"
|
|
1447
|
+
(dragstart)="onFolderDragStart(node, $event)"
|
|
1448
|
+
(dragend)="onFolderDragEnd()"
|
|
1449
|
+
(click)="toggleFolder(node.project.ID)"
|
|
1450
|
+
(dragover)="onFolderDragOver(node.project.ID, $event)"
|
|
1451
|
+
(dragleave)="onDragLeave(node.project.ID)"
|
|
1452
|
+
(drop)="onFolderDrop(node.project, $event)"
|
|
1453
|
+
[title]="node.project.Name">
|
|
1454
|
+
<i class="fas fa-chevron-right folder-chevron" [class.expanded]="isFolderExpanded(node.project.ID)"></i>
|
|
1455
|
+
<i class="fas {{ node.project.Icon || 'fa-folder' }} folder-icon" [style.color]="node.project.Color || null"></i>
|
|
1456
|
+
<span class="folder-name">{{ node.project.Name }}</span>
|
|
1457
|
+
<span class="folder-count">{{ node.totalCount }}</span>
|
|
1458
|
+
<div class="folder-actions" (click)="$event.stopPropagation()">
|
|
1459
|
+
<button class="folder-action-btn" (click)="createFolder(node.project.ID, $event)" title="New Subfolder">
|
|
1460
|
+
<i class="fas fa-folder-plus"></i>
|
|
1461
|
+
</button>
|
|
1462
|
+
<button class="folder-action-btn" (click)="editFolder(node.project, $event)" title="Edit Folder">
|
|
1463
|
+
<i class="fas fa-pen"></i>
|
|
1464
|
+
</button>
|
|
1465
|
+
<button class="folder-action-btn danger" (click)="deleteFolder(node.project, $event)" title="Delete Folder">
|
|
1466
|
+
<i class="fas fa-trash"></i>
|
|
1467
|
+
</button>
|
|
1468
|
+
</div>
|
|
1469
|
+
</div>
|
|
1470
|
+
@if (isFolderExpanded(node.project.ID)) {
|
|
1471
|
+
<div class="folder-children">
|
|
1472
|
+
@for (child of node.children; track child.project.ID) {
|
|
1473
|
+
@if (!isSearching || child.hasContent) {
|
|
1474
|
+
<ng-container [ngTemplateOutlet]="folderNode" [ngTemplateOutletContext]="{ $implicit: child }"></ng-container>
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
@for (conversation of node.conversations; track conversation.ID) {
|
|
1478
|
+
<ng-container [ngTemplateOutlet]="conversationItem" [ngTemplateOutletContext]="{ $implicit: conversation, depth: node.depth + 1 }"></ng-container>
|
|
1479
|
+
}
|
|
1480
|
+
@if (node.totalCount === 0 && !isSearching) {
|
|
1481
|
+
<div class="folder-empty-hint" [style.paddingLeft.px]="26 + node.depth * 14">Empty — drop a conversation here</div>
|
|
1482
|
+
}
|
|
1483
|
+
</div>
|
|
1484
|
+
}
|
|
1485
|
+
</ng-template>
|
|
1486
|
+
|
|
1487
|
+
<!-- Shared conversation row used by Pinned, folders, and Ungrouped/Messages -->
|
|
1488
|
+
<ng-template #conversationItem let-conversation let-depth="depth">
|
|
1489
|
+
<div class="conversation-item"
|
|
1490
|
+
[class.active]="IsConversationActive(conversation)"
|
|
1491
|
+
[class.renamed]="IsConversationRenamed(conversation)"
|
|
1492
|
+
[class.dragging]="IsConversationDragging(conversation)"
|
|
1493
|
+
[style.paddingLeft.px]="depth ? 16 + depth * 14 : 16"
|
|
1494
|
+
[draggable]="!isSelectionMode"
|
|
1495
|
+
(dragstart)="onConversationDragStart(conversation, $event)"
|
|
1496
|
+
(dragend)="onConversationDragEnd()"
|
|
1497
|
+
(click)="handleConversationClick(conversation)">
|
|
1498
|
+
@if (isSelectionMode) {
|
|
1499
|
+
<div class="conversation-checkbox">
|
|
1500
|
+
<input type="checkbox"
|
|
1501
|
+
[checked]="selectedConversationIds.has(conversation.ID)"
|
|
1502
|
+
(click)="$event.stopPropagation(); toggleConversationSelection(conversation.ID)">
|
|
1503
|
+
</div>
|
|
1504
|
+
}
|
|
1505
|
+
<div class="conversation-icon-wrapper">
|
|
1506
|
+
@if (hasActiveTasks(conversation.ID)) {
|
|
1507
|
+
<div class="conversation-icon has-tasks">
|
|
1508
|
+
<i class="fas fa-spinner fa-pulse"></i>
|
|
1509
|
+
</div>
|
|
1510
|
+
}
|
|
1511
|
+
<div class="badge-overlay">
|
|
1512
|
+
<mj-notification-badge [conversationId]="conversation.ID"></mj-notification-badge>
|
|
1513
|
+
</div>
|
|
1514
|
+
</div>
|
|
1515
|
+
<div class="conversation-info" [title]="conversation.Name + (conversation.Description ? '\n' + conversation.Description : '')">
|
|
1516
|
+
<div class="conversation-name">
|
|
1517
|
+
{{ conversation.Name }}
|
|
1518
|
+
@if (isSharedWithMe(conversation)) {
|
|
1519
|
+
<i class="fas fa-share-nodes shared-indicator"
|
|
1520
|
+
[title]="sharedWithMeTooltip(conversation)"></i>
|
|
1521
|
+
}
|
|
1522
|
+
</div>
|
|
1523
|
+
<div class="conversation-preview">{{ conversation.Description }}</div>
|
|
1524
|
+
</div>
|
|
1525
|
+
@if (!isSelectionMode) {
|
|
1526
|
+
<div class="conversation-actions">
|
|
1527
|
+
<button class="menu-btn" (click)="toggleMenu(conversation.ID, $event)" title="More options">
|
|
1528
|
+
<i class="fas fa-ellipsis"></i>
|
|
1529
|
+
</button>
|
|
1530
|
+
@if (IsMenuOpen(conversation)) {
|
|
1531
|
+
<div class="context-menu" (click)="$event.stopPropagation()">
|
|
1532
|
+
@if (IsMoveSubmenuOpen(conversation)) {
|
|
1533
|
+
<button class="menu-item back" (click)="closeMoveSubmenu($event)">
|
|
1534
|
+
<i class="fas fa-chevron-left"></i>
|
|
1535
|
+
<span>Move to folder</span>
|
|
1536
|
+
</button>
|
|
1537
|
+
<div class="menu-divider"></div>
|
|
1538
|
+
<div class="move-folder-list">
|
|
1539
|
+
<button class="menu-item" [class.current]="!conversation.ProjectID" (click)="selectMoveTarget(conversation, null)">
|
|
1540
|
+
<i class="fas fa-inbox"></i>
|
|
1541
|
+
<span>No folder</span>
|
|
1542
|
+
</button>
|
|
1543
|
+
@for (f of flatFolders; track f.project.ID) {
|
|
1544
|
+
<button class="menu-item" [class.current]="IsInFolder(conversation, f.project.ID)"
|
|
1545
|
+
[style.paddingLeft.px]="14 + f.depth * 12"
|
|
1546
|
+
(click)="selectMoveTarget(conversation, f.project.ID)">
|
|
1547
|
+
<i class="fas {{ f.project.Icon || 'fa-folder' }}" [style.color]="f.project.Color || null"></i>
|
|
1548
|
+
<span>{{ f.project.Name }}</span>
|
|
1549
|
+
</button>
|
|
1550
|
+
}
|
|
1551
|
+
</div>
|
|
1552
|
+
<div class="menu-divider"></div>
|
|
1553
|
+
<button class="menu-item" (click)="createFolderForConversation(conversation, $event)">
|
|
1554
|
+
<i class="fas fa-folder-plus"></i>
|
|
1555
|
+
<span>New folder…</span>
|
|
1556
|
+
</button>
|
|
1557
|
+
} @else {
|
|
1558
|
+
<button class="menu-item" (click)="togglePin(conversation, $event)">
|
|
1559
|
+
<i class="fas fa-thumbtack"></i>
|
|
1560
|
+
<span>{{ conversation.IsPinned ? 'Unpin' : 'Pin' }}</span>
|
|
1561
|
+
</button>
|
|
1562
|
+
<button class="menu-item" (click)="openMoveSubmenu(conversation.ID, $event)">
|
|
1563
|
+
<i class="fas fa-folder-tree"></i>
|
|
1564
|
+
<span>Move to folder</span>
|
|
1565
|
+
<i class="fas fa-chevron-right submenu-arrow"></i>
|
|
1566
|
+
</button>
|
|
1567
|
+
<button class="menu-item" (click)="renameConversation(conversation); closeMenu()">
|
|
1568
|
+
<i class="fas fa-edit"></i>
|
|
1569
|
+
<span>Rename</span>
|
|
1570
|
+
</button>
|
|
1571
|
+
<div class="menu-divider"></div>
|
|
1572
|
+
<button class="menu-item danger" (click)="deleteConversation(conversation); closeMenu()">
|
|
1573
|
+
<i class="fas fa-trash"></i>
|
|
1574
|
+
<span>Delete</span>
|
|
1575
|
+
</button>
|
|
1576
|
+
}
|
|
1577
|
+
</div>
|
|
1578
|
+
}
|
|
1579
|
+
</div>
|
|
1580
|
+
}
|
|
1581
|
+
</div>
|
|
1582
|
+
</ng-template>
|
|
1583
|
+
`, styles: ["\n :host { display: block; height: 100%; }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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(--mj-brand-primary-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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\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(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active .menu-btn {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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 @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-primary);\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(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\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 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(--mj-brand-on-secondary) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 8%, transparent); }\n .folder-row.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n }\n .folder-row.dragging { opacity: 0.4; }\n .section-header.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 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(--mj-brand-on-secondary) 60%, transparent);\n cursor: pointer;\n transition: all 0.15s;\n }\n .folder-action-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 18%, transparent);\n color: var(--mj-brand-on-secondary);\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(--mj-brand-on-secondary) 45%, transparent);\n }\n .ungrouped-section.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\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(--mj-brand-primary) 18%, transparent); }\n .move-folder-list { max-height: 240px; overflow-y: auto; }\n "] }]
|
|
1584
|
+
}], () => [{ type: i1.DialogService }, { type: i2.NotificationService }, { type: i3.ActiveTasksService }, { type: i4.MJDialogService }, { type: i0.ChangeDetectorRef }], { environmentId: [{
|
|
884
1585
|
type: Input
|
|
885
1586
|
}], currentUser: [{
|
|
886
1587
|
type: Input
|
|
@@ -908,5 +1609,5 @@ export class ConversationListComponent {
|
|
|
908
1609
|
type: HostListener,
|
|
909
1610
|
args: ['document:click']
|
|
910
1611
|
}] }); })();
|
|
911
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationListComponent, { className: "ConversationListComponent", filePath: "src/lib/components/conversation/conversation-list.component.ts", lineNumber:
|
|
1612
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationListComponent, { className: "ConversationListComponent", filePath: "src/lib/components/conversation/conversation-list.component.ts", lineNumber: 964 }); })();
|
|
912
1613
|
//# sourceMappingURL=conversation-list.component.js.map
|