@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-list.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-list.component.ts","../../../../src/lib/components/message/message-list.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ViewContainerRef,\n OnInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n ChangeDetectorRef,\n ElementRef,\n AfterViewInit,\n AfterViewChecked\n} from '@angular/core';\nimport { MJConversationDetailEntity, MJConversationEntity, RatingJSON } from '@memberjunction/core-entities';\nimport { UserInfo, CompositeKey } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MessageItemComponent, MessageAttachment } from './message-item.component';\nimport { LazyArtifactInfo } from '../../models/lazy-artifact-info';\nimport { selectDistinctLatestArtifacts } from '../../utils/distinct-artifacts';\nimport { MJAIAgentRunEntityExtended } from '@memberjunction/ai-core-plus';\n\n/**\n * Container component for displaying a list of messages\n * Uses dynamic component creation (like skip-chat) to avoid Angular binding overhead\n * This dramatically improves performance when messages are added/removed\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-message-list',\n templateUrl: './message-list.component.html',\n styleUrls: ['./message-list.component.css']\n})\nexport class MessageListComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit, AfterViewChecked {\n @Input() public messages: MJConversationDetailEntity[] = [];\n @Input() public conversation!: MJConversationEntity | null;\n @Input() public currentUser!: UserInfo;\n @Input() public isProcessing: boolean = false;\n @Input() public artifactMap: Map<string, LazyArtifactInfo[]> = new Map();\n @Input() public agentRunMap: Map<string, MJAIAgentRunEntityExtended> = new Map();\n @Input() public ratingsMap: Map<string, RatingJSON[]> = new Map();\n @Input() public userAvatarMap: Map<string, {imageUrl: string | null; iconClass: string | null}> = new Map();\n @Input() public attachmentsMap: Map<string, MessageAttachment[]> = new Map();\n\n @Output() public editMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public deleteMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public retryMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public testFeedbackMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public artifactClicked = new EventEmitter<{artifactId: string; versionId?: string}>();\n @Output() public replyInThread = new EventEmitter<MJConversationDetailEntity>();\n @Output() public viewThread = new EventEmitter<MJConversationDetailEntity>();\n @Output() public messageEdited = new EventEmitter<MJConversationDetailEntity>();\n @Output() public openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() public suggestedResponseSelected = new EventEmitter<{text: string; customInput?: string}>();\n @Output() public attachmentClicked = new EventEmitter<MessageAttachment>();\n @Output() public diagnosticRequested = new EventEmitter<string>(); // emits messageId\n @Output() public messagePinToggled = new EventEmitter<MJConversationDetailEntity>();\n\n @ViewChild('messageContainer', { read: ViewContainerRef }) messageContainerRef!: ViewContainerRef;\n @ViewChild('scrollContainer') scrollContainer!: ElementRef;\n\n private _renderedMessages = new Map<string, any>();\n private _shouldScrollToBottom = false;\n private _previousMessageCount = 0; // Track previous count to detect new messages\n\n public currentDateDisplay: string = 'Today';\n public showDateNav: boolean = false;\n public shouldShowDateFilter: boolean = false;\n\n constructor(private cdRef: ChangeDetectorRef) {\n super();\n }\n\n public toggleDateNav(): void {\n this.showDateNav = !this.showDateNav;\n }\n\n public jumpToDate(period: string): void {\n // TODO: Implement date jumping logic\n console.log('Jump to date:', period);\n this.showDateNav = false;\n\n // Update display based on period\n switch(period) {\n case 'today':\n this.currentDateDisplay = 'Today';\n break;\n case 'yesterday':\n this.currentDateDisplay = 'Yesterday';\n break;\n case 'last-week':\n this.currentDateDisplay = 'Last week';\n break;\n case 'last-month':\n this.currentDateDisplay = 'Last month';\n break;\n }\n }\n\n // Track whether initial render has happened\n private _initialRenderComplete = false;\n\n ngOnInit() {\n // Initial render will happen in ngAfterViewInit when ViewContainerRef is available\n }\n\n ngAfterViewInit() {\n // ViewContainerRef is now available - perform initial render if we have messages\n if (this.messages && this.messages.length > 0 && this.messageContainerRef && !this._initialRenderComplete) {\n this._initialRenderComplete = true;\n this.updateMessages(this.messages);\n this.updateDateFilterVisibility();\n }\n }\n\n ngOnChanges(changes: SimpleChanges) {\n // React to messages array changes\n // Note: On initial load, messageContainerRef may not be available yet (ngOnChanges runs before ngAfterViewInit)\n // In that case, ngAfterViewInit will handle the initial render\n if (changes['messages'] && this.messages && this.messageContainerRef) {\n this._initialRenderComplete = true;\n this.updateMessages(this.messages);\n this.updateDateFilterVisibility();\n }\n\n // Watch for artifactMap changes to handle newly created artifacts\n // While artifacts are pre-loaded during initial peripheral data load,\n // new artifacts can be created mid-conversation (e.g., by agent runs)\n // This ensures artifact cards appear in messages immediately without requiring a refresh\n if (changes['artifactMap'] && this.messages && this.messageContainerRef) {\n this.updateMessages(this.messages);\n }\n\n // Watch for attachmentsMap changes to handle newly created attachments\n // This ensures media attachments (e.g., images generated by agents) appear\n // immediately without requiring a page refresh\n if (changes['attachmentsMap'] && this.messages && this.messageContainerRef) {\n this.updateMessages(this.messages);\n }\n }\n\n ngAfterViewChecked() {\n if (this._shouldScrollToBottom) {\n this.scrollToBottom();\n this._shouldScrollToBottom = false;\n }\n }\n\n ngOnDestroy() {\n // Clean up all dynamically created components\n this._renderedMessages.forEach((componentRef) => {\n if (componentRef) {\n componentRef.destroy();\n }\n });\n this._renderedMessages.clear();\n\n if (this.messageContainerRef) {\n this.messageContainerRef.clear();\n }\n }\n\n /**\n * Called when messages array changes\n * Efficiently updates the DOM without re-rendering everything\n */\n @Input()\n set messagesUpdate(messages: MJConversationDetailEntity[]) {\n if (messages && this.messageContainerRef) {\n this.updateMessages(messages);\n }\n }\n\n /**\n * Updates the message list using dynamic component creation\n * Only adds/removes changed messages for optimal performance\n */\n private updateMessages(messages: MJConversationDetailEntity[]): void {\n // Temporarily detach change detection for performance\n this.cdRef.detach();\n\n try {\n // Remove messages that no longer exist\n const currentIds = new Set(messages.map(m => this.getMessageKey(m)));\n this._renderedMessages.forEach((componentRef, key) => {\n if (!currentIds.has(key)) {\n componentRef.destroy();\n this._renderedMessages.delete(key);\n }\n });\n\n // Add or update messages\n messages.forEach((message, index) => {\n const key = this.getMessageKey(message);\n const existing = this._renderedMessages.get(key);\n\n if (existing) {\n // Update existing component\n const instance = existing.instance as MessageItemComponent;\n\n // Store previous message for comparison\n const previousMessage = instance.message;\n\n instance.message = message;\n instance.allMessages = messages;\n instance.isProcessing = this.isProcessing;\n instance.userAvatarMap = this.userAvatarMap;\n instance.isLastMessage = (index === messages.length - 1); // Update last message flag\n\n // Surface ALL distinct artifacts on this message (latest version each),\n // not just the most recent one. Loads lazily in the background.\n this.applyArtifactsToInstance(instance, message.ID, existing.changeDetectorRef);\n\n // Update agent run from map\n instance.agentRun = this.agentRunMap.get(message.ID) || null;\n\n // Update ratings from map\n instance.ratings = this.ratingsMap.get(message.ID);\n\n // Update attachments from map\n instance.attachments = this.attachmentsMap.get(message.ID) || [];\n\n // Manually trigger change detection in child component when message status changes\n // This is necessary because we're using OnPush change detection and direct property assignment\n // doesn't trigger ngOnChanges (only reference changes do)\n if (previousMessage && previousMessage.Status !== message.Status) {\n // Use ComponentRef.changeDetectorRef to force update on dynamic child\n existing.changeDetectorRef.markForCheck();\n }\n } else {\n // Create new component\n const componentRef = this.messageContainerRef.createComponent(MessageItemComponent);\n const instance = componentRef.instance;\n\n // Set inputs\n instance.message = message;\n instance.conversation = this.conversation;\n instance.currentUser = this.currentUser;\n instance.allMessages = messages;\n instance.isProcessing = this.isProcessing;\n instance.userAvatarMap = this.userAvatarMap;\n instance.isLastMessage = (index === messages.length - 1); // Mark last message\n\n // Surface ALL distinct artifacts on this message (latest version each).\n this.applyArtifactsToInstance(instance, message.ID, componentRef.changeDetectorRef);\n\n // Pass agent run from map (loaded once per conversation)\n instance.agentRun = this.agentRunMap.get(message.ID) || null;\n\n // Pass ratings from map (parsed once per conversation)\n instance.ratings = this.ratingsMap.get(message.ID);\n\n // Pass attachments from map\n instance.attachments = this.attachmentsMap.get(message.ID) || [];\n\n // Subscribe to outputs\n instance.editClicked.subscribe((msg: MJConversationDetailEntity) => this.editMessage.emit(msg));\n instance.deleteClicked.subscribe((msg: MJConversationDetailEntity) => this.deleteMessage.emit(msg));\n instance.retryClicked.subscribe((msg: MJConversationDetailEntity) => this.retryMessage.emit(msg));\n instance.testFeedbackClicked.subscribe((msg: MJConversationDetailEntity) => this.testFeedbackMessage.emit(msg));\n instance.artifactClicked.subscribe((data: {artifactId: string; versionId?: string}) => this.artifactClicked.emit(data));\n instance.messageEdited.subscribe((msg: MJConversationDetailEntity) => this.messageEdited.emit(msg));\n instance.openEntityRecord.subscribe((data: {entityName: string; compositeKey: CompositeKey}) => this.openEntityRecord.emit(data));\n instance.suggestedResponseSelected.subscribe((data: {text: string; customInput?: string}) => this.suggestedResponseSelected.emit(data));\n instance.attachmentClicked.subscribe((attachment: MessageAttachment) => this.attachmentClicked.emit(attachment));\n instance.diagnosticRequested.subscribe((messageId: string) => this.diagnosticRequested.emit(messageId));\n instance.messagePinToggled.subscribe((msg: MJConversationDetailEntity) => this.messagePinToggled.emit(msg));\n\n // Handle artifact actions if the output exists\n if (instance.artifactActionPerformed) {\n instance.artifactActionPerformed.subscribe((data: {action: string; artifactId: string}) => {\n // Parent can handle artifact actions (save, fork, history, share)\n console.log('Artifact action:', data);\n });\n }\n\n // Store reference\n this._renderedMessages.set(key, componentRef);\n\n // Store reference on the message entity for later access (like skip-chat pattern)\n (message as any)._componentRef = componentRef;\n }\n });\n\n // Only scroll to bottom if new messages were added (not just updates)\n // This prevents scrolling when the message list is merely refreshed (e.g., during agent run timer)\n const previousCount = this._previousMessageCount;\n this._previousMessageCount = messages.length;\n\n if (messages.length > previousCount) {\n this._shouldScrollToBottom = true;\n }\n } finally {\n // Re-attach change detection\n this.cdRef.reattach();\n this.cdRef.detectChanges();\n }\n }\n\n /**\n * Resolves the DISTINCT artifacts for a message (one entry per artifactId at its\n * latest version), lazy-loads them all, and applies them to the rendered\n * message-item. Loads in the background so the UI never blocks.\n *\n * WHY WE SURFACE THEM ALL (design rationale — see PR discussion w/ Pranav & Ethan):\n * A single message can legitimately carry more than one DISTINCT artifact — e.g. a\n * research report PLUS a *standalone* generated infographic. This is deliberately\n * NOT in conflict with the server-side consolidation in AgentRunner\n * (Pranav, 5664b86: \"keep the report's embedded image in the report, not as a\n * duplicate artifact\"): that logic only suppresses media that is *embedded inline*\n * (base64) in another artifact's payload — a true duplicate. Genuinely standalone\n * sibling artifacts (the report uses SVG charts; the infographic is a separate JPEG)\n * are correctly kept as separate artifacts, and the UI must show every one of them.\n *\n * The earlier `artifactList[length - 1]` (\"show only the most recent\") approach\n * (EL-BC, 95492622) assumed consolidation always left exactly one artifact per\n * message; when it legitimately leaves two, that silently hid the report behind the\n * image. Grouping by artifactId (latest version each) shows all distinct artifacts\n * while still collapsing multiple *versions* of the same artifact to one card.\n */\n private applyArtifactsToInstance(\n instance: MessageItemComponent,\n messageId: string,\n childCdRef: ChangeDetectorRef\n ): void {\n const infos = this.resolveDistinctArtifacts(messageId);\n if (infos.length === 0) {\n instance.artifacts = [];\n instance.artifact = undefined;\n instance.artifactVersion = undefined;\n return;\n }\n\n Promise.all(\n infos.map(info =>\n Promise.all([info.getArtifact(), info.getVersion()]).then(([artifact, version]) => ({ artifact, version }))\n )\n )\n .then(refs => {\n instance.artifacts = refs;\n // Keep the legacy single inputs pointed at the first entry for back-compat.\n instance.artifact = refs[0]?.artifact;\n instance.artifactVersion = refs[0]?.version;\n // zone.js 0.15: parent detectChanges doesn't propagate to dynamically created children\n childCdRef.detectChanges();\n this.cdRef.detectChanges();\n })\n .catch(err => {\n console.error('Failed to lazy-load artifacts:', err);\n });\n }\n\n /**\n * Groups a message's artifact list by artifactId, keeping the highest version of\n * each. Multiple versions of the SAME artifact collapse to one card (latest wins),\n * while genuinely distinct artifacts are all retained.\n */\n private resolveDistinctArtifacts(messageId: string): LazyArtifactInfo[] {\n const list = this.artifactMap.get(messageId);\n if (!list || list.length === 0) {\n return [];\n }\n return selectDistinctLatestArtifacts(list);\n }\n\n /**\n * Generates a unique key for a message\n * Uses ID if available, otherwise uses a temporary key\n */\n private getMessageKey(message: MJConversationDetailEntity): string {\n return message.ID && message.ID.length > 0\n ? message.ID\n : `temp_${message.__mj_CreatedAt?.getTime() || Date.now()}`;\n }\n\n /**\n * Determines whether to show the date filter dropdown\n * Only show if conversation is long and spans multiple days\n */\n private updateDateFilterVisibility(): void {\n if (!this.messages || this.messages.length < 20) {\n this.shouldShowDateFilter = false;\n return;\n }\n\n // Check if messages span more than 2 days\n const dates = this.messages\n .map(m => m.__mj_CreatedAt)\n .filter(d => d != null)\n .map(d => new Date(d!).setHours(0, 0, 0, 0));\n\n if (dates.length === 0) {\n this.shouldShowDateFilter = false;\n return;\n }\n\n const uniqueDates = new Set(dates);\n const daySpan = uniqueDates.size;\n\n // Show filter if conversation has 20+ messages and spans 3+ days\n this.shouldShowDateFilter = daySpan >= 3;\n }\n\n /**\n * Scrolls the message list to the bottom\n */\n private scrollToBottom(): void {\n if (this.scrollContainer && this.scrollContainer.nativeElement) {\n Promise.resolve().then(() => {\n const element = this.scrollContainer.nativeElement;\n element.scrollTop = element.scrollHeight;\n });\n }\n }\n\n /**\n * Removes a message from the rendered list\n * Called externally when a message is deleted\n */\n public removeMessage(message: MJConversationDetailEntity): void {\n const key = this.getMessageKey(message);\n const componentRef = this._renderedMessages.get(key);\n if (componentRef) {\n componentRef.destroy();\n this._renderedMessages.delete(key);\n }\n }\n}","<div class=\"message-list-container\" #scrollContainer>\n <!-- Sticky Date Header (only show for long conversations spanning multiple days) -->\n @if (shouldShowDateFilter && messages.length > 0) {\n <div class=\"sticky-date-header\">\n <div class=\"sticky-date-wrapper\">\n <button class=\"sticky-date-button\" (click)=\"toggleDateNav()\">\n <span>{{ currentDateDisplay }}</span>\n <i class=\"fas fa-chevron-down\"></i>\n </button>\n <div class=\"date-nav-dropdown\" [class.show]=\"showDateNav\">\n <div class=\"date-nav-option jump-to\">Jump to...</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('today')\">Today</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('yesterday')\">Yesterday</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('last-week')\">Last week</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('last-month')\">Last month</div>\n </div>\n </div>\n </div>\n }\n\n <ng-container #messageContainer></ng-container>\n\n @if (messages.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-comments\"></i>\n <p>No messages yet. Start a conversation!</p>\n </div>\n }\n</div>"]}
|
|
1
|
+
{"version":3,"file":"message-list.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-list.component.ts","../../../../src/lib/components/message/message-list.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ViewContainerRef,\n OnInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n ChangeDetectorRef,\n ElementRef,\n AfterViewInit,\n AfterViewChecked,\n ComponentRef,\n EmbeddedViewRef,\n TemplateRef\n} from '@angular/core';\nimport { MJConversationDetailEntity, MJConversationEntity, RatingJSON } from '@memberjunction/core-entities';\nimport { UserInfo, CompositeKey } from '@memberjunction/core';\nimport { NormalizeUUID } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MessageItemComponent, MessageAttachment } from './message-item.component';\nimport {\n BeforeResponseFormSubmittedEventArgs,\n AfterResponseFormSubmittedEventArgs,\n} from '../../events/chat-events';\nimport { RealtimeSessionTimelineCardComponent } from '../realtime/realtime-session-timeline-card.component';\nimport { LazyArtifactInfo } from '../../models/lazy-artifact-info';\nimport { selectDistinctLatestArtifacts } from '../../utils/distinct-artifacts';\nimport {\n BuildConversationTimeline,\n ConversationTimelineItem,\n RealtimeSessionTimelineGroup,\n RealtimeSessionTimelineMeta\n} from '../../utils/realtime-session-timeline';\nimport { MJAIAgentRunEntityExtended } from '@memberjunction/ai-core-plus';\n\n/** Context handed to the `messageRenderer` slot template per message. */\ninterface MessageRendererContext {\n $implicit: MJConversationDetailEntity;\n message: MJConversationDetailEntity;\n}\n\n/**\n * One per rendered message in the list. Three paths can produce an entry:\n * - `component` — the default `MessageItemComponent` (single message).\n * - `embedded` — an `EmbeddedViewRef` from the consumer's\n * `messageRenderer` slot template (full per-message\n * replacement, PR 2c slot system).\n * - `realtime-session` — a `RealtimeSessionTimelineCardComponent` collapsing\n * an entire past realtime session into one timeline\n * card (PR #2787 co-agent timeline). The grouping pass\n * (`BuildConversationTimeline`) emits these alongside\n * normal messages — see the timeline utility for the\n * rules.\n *\n * Discriminated by the `kind` tag for ergonomic narrowing.\n */\ntype RenderedMessageEntry =\n | { kind: 'component'; ref: ComponentRef<MessageItemComponent> }\n | { kind: 'embedded'; ref: EmbeddedViewRef<MessageRendererContext> }\n | { kind: 'realtime-session'; ref: ComponentRef<RealtimeSessionTimelineCardComponent> };\n\n/**\n * Container component for displaying a list of messages\n * Uses dynamic component creation (like skip-chat) to avoid Angular binding overhead\n * This dramatically improves performance when messages are added/removed\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-message-list',\n templateUrl: './message-list.component.html',\n styleUrls: ['./message-list.component.css']\n})\nexport class MessageListComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit, AfterViewChecked {\n @Input() public messages: MJConversationDetailEntity[] = [];\n @Input() public conversation!: MJConversationEntity | null;\n @Input() public currentUser!: UserInfo;\n @Input() public isProcessing: boolean = false;\n @Input() public artifactMap: Map<string, LazyArtifactInfo[]> = new Map();\n @Input() public agentRunMap: Map<string, MJAIAgentRunEntityExtended> = new Map();\n @Input() public ratingsMap: Map<string, RatingJSON[]> = new Map();\n @Input() public userAvatarMap: Map<string, {imageUrl: string | null; iconClass: string | null}> = new Map();\n @Input() public attachmentsMap: Map<string, MessageAttachment[]> = new Map();\n /**\n * Optional session-row enrichment for realtime SESSION BLOCKS, keyed by\n * `NormalizeUUID(sessionId)` (agent name / status / close reason). Details stamped\n * with an `AgentSessionID` collapse into one timeline card per session — see\n * `BuildConversationTimeline` — and this map dresses those cards up when present.\n */\n @Input() public sessionMetaMap: Map<string, RealtimeSessionTimelineMeta> = new Map();\n\n /**\n * Optional per-iteration custom message renderer. When set, the list renders each\n * message via this template (full replacement) instead of the default\n * `MessageItemComponent`. Forwarded by chat-area when a consumer projects\n * `mjChatSlot=\"messageRenderer\"`. The template receives the message as\n * `$implicit` and as a named `message` context binding.\n *\n * Consumers opting into a custom renderer take full responsibility for displaying\n * the message — edit/delete/retry affordances, artifacts, ratings, attachments,\n * etc. The minimal `MJChatMessageBubbleDefaultComponent` ships as a ready-to-use\n * bubble renderer.\n */\n @Input() public messageRendererTemplate: TemplateRef<unknown> | null = null;\n\n /**\n * Optional per-message additive decoration template, projected INSIDE the default\n * `MessageItemComponent` (after the message text). Forwarded by chat-area when a\n * consumer projects `mjChatSlot=\"messageExtra\"`. Ignored when\n * `messageRendererTemplate` is set (custom renderers own all per-message content).\n */\n @Input() public messageExtraTemplate: TemplateRef<unknown> | null = null;\n\n @Output() public editMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public deleteMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public retryMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public testFeedbackMessage = new EventEmitter<MJConversationDetailEntity>();\n @Output() public artifactClicked = new EventEmitter<{artifactId: string; versionId?: string}>();\n @Output() public replyInThread = new EventEmitter<MJConversationDetailEntity>();\n @Output() public viewThread = new EventEmitter<MJConversationDetailEntity>();\n @Output() public messageEdited = new EventEmitter<MJConversationDetailEntity>();\n @Output() public openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() public suggestedResponseSelected = new EventEmitter<{text: string; customInput?: string}>();\n @Output() public attachmentClicked = new EventEmitter<MessageAttachment>();\n @Output() public diagnosticRequested = new EventEmitter<string>(); // emits messageId\n @Output() public messagePinToggled = new EventEmitter<MJConversationDetailEntity>();\n /** Emitted with the `MJ: AI Agent Sessions.ID` when a realtime session block's Open affordance is clicked. */\n @Output() public realtimeSessionOpenRequested = new EventEmitter<string>();\n\n /** Forwarded from MessageItemComponent — see its docs. */\n @Output() public beforeResponseFormSubmitted = new EventEmitter<BeforeResponseFormSubmittedEventArgs>();\n /** Forwarded from MessageItemComponent — see its docs. */\n @Output() public afterResponseFormSubmitted = new EventEmitter<AfterResponseFormSubmittedEventArgs>();\n\n @ViewChild('messageContainer', { read: ViewContainerRef }) messageContainerRef!: ViewContainerRef;\n @ViewChild('scrollContainer') scrollContainer!: ElementRef;\n\n /**\n * Per-message rendered entries — see `RenderedMessageEntry` for the 3-way\n * union (default MessageItemComponent / consumer messageRenderer slot\n * embedded view / collapsed realtime session timeline card).\n */\n private _renderedMessages = new Map<string, RenderedMessageEntry>();\n private _shouldScrollToBottom = false;\n private _previousMessageCount = 0; // Track previous count to detect new messages\n\n public currentDateDisplay: string = 'Today';\n public showDateNav: boolean = false;\n public shouldShowDateFilter: boolean = false;\n\n constructor(private cdRef: ChangeDetectorRef) {\n super();\n }\n\n public toggleDateNav(): void {\n this.showDateNav = !this.showDateNav;\n }\n\n public jumpToDate(period: string): void {\n // TODO: Implement date jumping logic\n console.log('Jump to date:', period);\n this.showDateNav = false;\n\n // Update display based on period\n switch(period) {\n case 'today':\n this.currentDateDisplay = 'Today';\n break;\n case 'yesterday':\n this.currentDateDisplay = 'Yesterday';\n break;\n case 'last-week':\n this.currentDateDisplay = 'Last week';\n break;\n case 'last-month':\n this.currentDateDisplay = 'Last month';\n break;\n }\n }\n\n // Track whether initial render has happened\n private _initialRenderComplete = false;\n\n ngOnInit() {\n // Initial render will happen in ngAfterViewInit when ViewContainerRef is available\n }\n\n ngAfterViewInit() {\n // ViewContainerRef is now available - perform initial render if we have messages\n if (this.messages && this.messages.length > 0 && this.messageContainerRef && !this._initialRenderComplete) {\n this._initialRenderComplete = true;\n this.updateMessages(this.messages);\n this.updateDateFilterVisibility();\n }\n }\n\n ngOnChanges(changes: SimpleChanges) {\n // React to messages array changes\n // Note: On initial load, messageContainerRef may not be available yet (ngOnChanges runs before ngAfterViewInit)\n // In that case, ngAfterViewInit will handle the initial render\n if (changes['messages'] && this.messages && this.messageContainerRef) {\n this._initialRenderComplete = true;\n this.updateMessages(this.messages);\n this.updateDateFilterVisibility();\n }\n\n // Watch for artifactMap changes to handle newly created artifacts\n // While artifacts are pre-loaded during initial peripheral data load,\n // new artifacts can be created mid-conversation (e.g., by agent runs)\n // This ensures artifact cards appear in messages immediately without requiring a refresh\n if (changes['artifactMap'] && this.messages && this.messageContainerRef) {\n this.updateMessages(this.messages);\n }\n\n // Watch for attachmentsMap changes to handle newly created attachments\n // This ensures media attachments (e.g., images generated by agents) appear\n // immediately without requiring a page refresh\n if (changes['attachmentsMap'] && this.messages && this.messageContainerRef) {\n this.updateMessages(this.messages);\n }\n\n // Watch for session-meta changes so realtime session blocks pick up their\n // agent name / status chip once the (async, batched) session lookup lands\n if (changes['sessionMetaMap'] && this.messages && this.messageContainerRef) {\n this.updateMessages(this.messages);\n }\n }\n\n ngAfterViewChecked() {\n if (this._shouldScrollToBottom) {\n this.scrollToBottom();\n this._shouldScrollToBottom = false;\n }\n }\n\n ngOnDestroy() {\n // Clean up all dynamically created components AND embedded views (both have destroy()).\n this._renderedMessages.forEach((entry) => {\n if (entry) {\n entry.ref.destroy();\n }\n });\n this._renderedMessages.clear();\n\n if (this.messageContainerRef) {\n this.messageContainerRef.clear();\n }\n }\n\n /**\n * Called when messages array changes\n * Efficiently updates the DOM without re-rendering everything\n */\n @Input()\n set messagesUpdate(messages: MJConversationDetailEntity[]) {\n if (messages && this.messageContainerRef) {\n this.updateMessages(messages);\n }\n }\n\n /**\n * Updates the message list using dynamic component creation\n * Only adds/removes changed messages for optimal performance\n *\n * REALTIME SESSIONS: details stamped with an `AgentSessionID` (turns persisted during\n * a live realtime session) do NOT render as normal chat bubbles. The timeline pass\n * (`BuildConversationTimeline`) collapses each session's stamped rows into ONE session\n * block, rendered as a `RealtimeSessionTimelineCardComponent` at the session's\n * chronological position. Everything else renders exactly as before.\n */\n private updateMessages(messages: MJConversationDetailEntity[]): void {\n // Temporarily detach change detection for performance\n this.cdRef.detach();\n\n try {\n // Build the timeline first — collapses contiguous realtime-session rows\n // into ONE session block per session, leaving normal messages in place.\n // See `BuildConversationTimeline` in `utils/realtime-session-timeline`.\n const timeline = BuildConversationTimeline(messages);\n\n // Remove rendered items (messages AND session blocks) that no longer exist\n const currentKeys = new Set(timeline.map(item => this.getTimelineKey(item)));\n this._renderedMessages.forEach((entry, key) => {\n if (!currentKeys.has(key)) {\n entry.ref.destroy();\n this._renderedMessages.delete(key);\n }\n });\n\n // Add or update timeline items in chronological order. `renderMessageItem`\n // internally branches on the slot template (messageRenderer) vs the\n // default MessageItemComponent; `renderSessionBlock` always creates a\n // RealtimeSessionTimelineCardComponent.\n const lastMessageKey = this.findLastMessageKey(timeline);\n for (const item of timeline) {\n if (item.Kind === 'session') {\n this.renderSessionBlock(item.Group);\n } else {\n this.renderMessageItem(item.Detail, messages, this.getMessageKey(item.Detail) === lastMessageKey);\n }\n }\n\n // Only scroll to bottom if new messages were added (not just updates)\n // This prevents scrolling when the message list is merely refreshed (e.g., during agent run timer)\n const previousCount = this._previousMessageCount;\n this._previousMessageCount = messages.length;\n\n if (messages.length > previousCount) {\n this._shouldScrollToBottom = true;\n }\n } finally {\n // Re-attach change detection\n this.cdRef.reattach();\n this.cdRef.detectChanges();\n }\n }\n\n /** Stable render key for a timeline item — message ID, or a prefixed session key for session blocks. */\n private getTimelineKey(item: ConversationTimelineItem<MJConversationDetailEntity>): string {\n return item.Kind === 'session' ? this.getSessionKey(item.Group.SessionID) : this.getMessageKey(item.Detail);\n }\n\n /** Render key for a session block (case-insensitive on the session id; prefixed so it can't collide with message IDs). */\n private getSessionKey(sessionId: string): string {\n return `session:${NormalizeUUID(sessionId)}`;\n }\n\n /** The render key of the LAST normal message item in the timeline (drives `isLastMessage`), or null when none. */\n private findLastMessageKey(timeline: ConversationTimelineItem<MJConversationDetailEntity>[]): string | null {\n for (let i = timeline.length - 1; i >= 0; i--) {\n const item = timeline[i];\n if (item.Kind === 'message') {\n return this.getMessageKey(item.Detail);\n }\n }\n return null;\n }\n\n /**\n * Creates or updates the ONE timeline card a realtime session collapses to.\n * Click/Open on the card bubbles up via {@link realtimeSessionOpenRequested} so the\n * chat area can host the SESSION REVIEW overlay for it.\n */\n private renderSessionBlock(group: RealtimeSessionTimelineGroup): void {\n const key = this.getSessionKey(group.SessionID);\n const meta = this.sessionMetaMap.get(NormalizeUUID(group.SessionID)) ?? null;\n const existing = this._renderedMessages.get(key);\n\n if (existing && existing.kind === 'realtime-session') {\n // Update existing card in place.\n const instance = existing.ref.instance;\n instance.Group = group;\n instance.Meta = meta;\n existing.ref.changeDetectorRef.markForCheck();\n return;\n }\n\n // Different kind at this key (e.g. mode changed) — drop the old entry, fall through to create.\n if (existing) {\n existing.ref.destroy();\n this._renderedMessages.delete(key);\n }\n\n const componentRef = this.messageContainerRef.createComponent(RealtimeSessionTimelineCardComponent);\n componentRef.instance.Group = group;\n componentRef.instance.Meta = meta;\n componentRef.instance.UserName = this.currentUser?.Name || 'You';\n componentRef.instance.OpenRequested.subscribe((sessionId: string) => this.realtimeSessionOpenRequested.emit(sessionId));\n this._renderedMessages.set(key, { kind: 'realtime-session', ref: componentRef });\n }\n\n /**\n * Creates or updates one normal chat message item. Routes to the\n * consumer-projected `messageRenderer` slot template (EmbeddedViewRef path)\n * when present, otherwise falls back to the default `MessageItemComponent`\n * dynamic-component path. Both paths flow through the shared\n * `createRenderedEntry` / `updateMessageItemInstance` helpers.\n */\n private renderMessageItem(message: MJConversationDetailEntity, messages: MJConversationDetailEntity[], isLastMessage: boolean): void {\n const key = this.getMessageKey(message);\n // `index` is only used for the `isLastMessage` heuristic inside\n // updateMessageItemInstance — synthesize a value that produces the right\n // boolean (last index when `isLastMessage` is true, else 0 — any non-last\n // index works since it just affects that one comparison).\n const index = isLastMessage ? messages.length - 1 : 0;\n const useCustomRenderer = this.messageRendererTemplate !== null;\n const existing = this._renderedMessages.get(key);\n\n if (existing && existing.kind === 'embedded' && useCustomRenderer) {\n // Update existing embedded view from messageRenderer slot\n existing.ref.context.$implicit = message;\n existing.ref.context.message = message;\n existing.ref.markForCheck();\n return;\n }\n if (existing && existing.kind === 'component' && !useCustomRenderer) {\n // Update existing MessageItemComponent in place\n this.updateMessageItemInstance(existing.ref, message, messages, index);\n return;\n }\n if (existing) {\n // Rendering kind changed (e.g. component↔embedded, or a session block was\n // overwritten with a message). Destroy + recreate.\n existing.ref.destroy();\n this._renderedMessages.delete(key);\n }\n\n this.createRenderedEntry(message, messages, index, key, useCustomRenderer);\n }\n\n /**\n * Updates an existing `MessageItemComponent` in place — used on the default\n * (non-custom-renderer) path when a message's status / artifacts / agent-run /\n * etc. changes mid-stream.\n */\n private updateMessageItemInstance(\n ref: ComponentRef<MessageItemComponent>,\n message: MJConversationDetailEntity,\n messages: MJConversationDetailEntity[],\n index: number\n ): void {\n const instance = ref.instance;\n const previousMessage = instance.message;\n\n instance.message = message;\n instance.allMessages = messages;\n instance.isProcessing = this.isProcessing;\n instance.userAvatarMap = this.userAvatarMap;\n instance.isLastMessage = (index === messages.length - 1);\n instance.messageExtraTemplate = this.messageExtraTemplate;\n\n this.applyArtifactsToInstance(instance, message.ID, ref.changeDetectorRef);\n\n instance.agentRun = this.agentRunMap.get(message.ID) || null;\n instance.ratings = this.ratingsMap.get(message.ID);\n instance.attachments = this.attachmentsMap.get(message.ID) || [];\n\n // Status change requires explicit markForCheck on the OnPush dynamic child.\n if (previousMessage && previousMessage.Status !== message.Status) {\n ref.changeDetectorRef.markForCheck();\n }\n }\n\n /**\n * Creates a new rendered entry — either a `MessageItemComponent` (default path)\n * or an `EmbeddedViewRef` from the consumer's `messageRenderer` slot template.\n * Stores the entry in `_renderedMessages` and stamps a back-reference on the\n * message entity.\n */\n private createRenderedEntry(\n message: MJConversationDetailEntity,\n messages: MJConversationDetailEntity[],\n index: number,\n key: string,\n useCustomRenderer: boolean\n ): void {\n if (useCustomRenderer && this.messageRendererTemplate) {\n // The slot directive carries TemplateRef<unknown>; assert the contract here\n // (consumers' `let-message` bindings consume the message context shape below).\n const template = this.messageRendererTemplate as TemplateRef<MessageRendererContext>;\n const viewRef = this.messageContainerRef.createEmbeddedView<MessageRendererContext>(\n template,\n { $implicit: message, message }\n );\n this._renderedMessages.set(key, { kind: 'embedded', ref: viewRef });\n // Stamp back-ref for parity with the component path.\n (message as unknown as { _viewRef?: EmbeddedViewRef<MessageRendererContext> })._viewRef = viewRef;\n return;\n }\n\n const componentRef = this.messageContainerRef.createComponent(MessageItemComponent);\n const instance = componentRef.instance;\n\n instance.message = message;\n instance.conversation = this.conversation;\n instance.currentUser = this.currentUser;\n instance.allMessages = messages;\n instance.isProcessing = this.isProcessing;\n instance.userAvatarMap = this.userAvatarMap;\n instance.isLastMessage = (index === messages.length - 1);\n instance.messageExtraTemplate = this.messageExtraTemplate;\n\n this.applyArtifactsToInstance(instance, message.ID, componentRef.changeDetectorRef);\n\n instance.agentRun = this.agentRunMap.get(message.ID) || null;\n instance.ratings = this.ratingsMap.get(message.ID);\n instance.attachments = this.attachmentsMap.get(message.ID) || [];\n\n instance.editClicked.subscribe((msg: MJConversationDetailEntity) => this.editMessage.emit(msg));\n instance.deleteClicked.subscribe((msg: MJConversationDetailEntity) => this.deleteMessage.emit(msg));\n instance.retryClicked.subscribe((msg: MJConversationDetailEntity) => this.retryMessage.emit(msg));\n instance.testFeedbackClicked.subscribe((msg: MJConversationDetailEntity) => this.testFeedbackMessage.emit(msg));\n instance.artifactClicked.subscribe((data: {artifactId: string; versionId?: string}) => this.artifactClicked.emit(data));\n instance.messageEdited.subscribe((msg: MJConversationDetailEntity) => this.messageEdited.emit(msg));\n instance.openEntityRecord.subscribe((data: {entityName: string; compositeKey: CompositeKey}) => this.openEntityRecord.emit(data));\n instance.suggestedResponseSelected.subscribe((data: {text: string; customInput?: string}) => this.suggestedResponseSelected.emit(data));\n instance.attachmentClicked.subscribe((attachment: MessageAttachment) => this.attachmentClicked.emit(attachment));\n instance.diagnosticRequested.subscribe((messageId: string) => this.diagnosticRequested.emit(messageId));\n instance.messagePinToggled.subscribe((msg: MJConversationDetailEntity) => this.messagePinToggled.emit(msg));\n instance.beforeResponseFormSubmitted.subscribe((e: BeforeResponseFormSubmittedEventArgs) => this.beforeResponseFormSubmitted.emit(e));\n instance.afterResponseFormSubmitted.subscribe((e: AfterResponseFormSubmittedEventArgs) => this.afterResponseFormSubmitted.emit(e));\n\n if (instance.artifactActionPerformed) {\n instance.artifactActionPerformed.subscribe((data: {action: string; artifactId: string}) => {\n // Parent can handle artifact actions (save, fork, history, share)\n console.log('Artifact action:', data);\n });\n }\n\n this._renderedMessages.set(key, { kind: 'component', ref: componentRef });\n // Preserve the existing back-ref pattern from the skip-chat performance design.\n (message as unknown as { _componentRef?: ComponentRef<MessageItemComponent> })._componentRef = componentRef;\n }\n\n /**\n * Resolves the DISTINCT artifacts for a message (one entry per artifactId at its\n * latest version), lazy-loads them all, and applies them to the rendered\n * message-item. Loads in the background so the UI never blocks.\n *\n * WHY WE SURFACE THEM ALL (design rationale — see PR discussion w/ Pranav & Ethan):\n * A single message can legitimately carry more than one DISTINCT artifact — e.g. a\n * research report PLUS a *standalone* generated infographic. This is deliberately\n * NOT in conflict with the server-side consolidation in AgentRunner\n * (Pranav, 5664b86: \"keep the report's embedded image in the report, not as a\n * duplicate artifact\"): that logic only suppresses media that is *embedded inline*\n * (base64) in another artifact's payload — a true duplicate. Genuinely standalone\n * sibling artifacts (the report uses SVG charts; the infographic is a separate JPEG)\n * are correctly kept as separate artifacts, and the UI must show every one of them.\n *\n * The earlier `artifactList[length - 1]` (\"show only the most recent\") approach\n * (EL-BC, 95492622) assumed consolidation always left exactly one artifact per\n * message; when it legitimately leaves two, that silently hid the report behind the\n * image. Grouping by artifactId (latest version each) shows all distinct artifacts\n * while still collapsing multiple *versions* of the same artifact to one card.\n */\n private applyArtifactsToInstance(\n instance: MessageItemComponent,\n messageId: string,\n childCdRef: ChangeDetectorRef\n ): void {\n const infos = this.resolveDistinctArtifacts(messageId);\n if (infos.length === 0) {\n instance.artifacts = [];\n instance.artifact = undefined;\n instance.artifactVersion = undefined;\n return;\n }\n\n Promise.all(\n infos.map(info =>\n Promise.all([info.getArtifact(), info.getVersion()]).then(([artifact, version]) => ({ artifact, version }))\n )\n )\n .then(refs => {\n instance.artifacts = refs;\n // Keep the legacy single inputs pointed at the first entry for back-compat.\n instance.artifact = refs[0]?.artifact;\n instance.artifactVersion = refs[0]?.version;\n // zone.js 0.15: parent detectChanges doesn't propagate to dynamically created children\n childCdRef.detectChanges();\n this.cdRef.detectChanges();\n })\n .catch(err => {\n console.error('Failed to lazy-load artifacts:', err);\n });\n }\n\n /**\n * Groups a message's artifact list by artifactId, keeping the highest version of\n * each. Multiple versions of the SAME artifact collapse to one card (latest wins),\n * while genuinely distinct artifacts are all retained.\n */\n private resolveDistinctArtifacts(messageId: string): LazyArtifactInfo[] {\n const list = this.artifactMap.get(messageId);\n if (!list || list.length === 0) {\n return [];\n }\n return selectDistinctLatestArtifacts(list);\n }\n\n /**\n * Generates a unique key for a message\n * Uses ID if available, otherwise uses a temporary key\n */\n private getMessageKey(message: MJConversationDetailEntity): string {\n return message.ID && message.ID.length > 0\n ? message.ID\n : `temp_${message.__mj_CreatedAt?.getTime() || Date.now()}`;\n }\n\n /**\n * Determines whether to show the date filter dropdown\n * Only show if conversation is long and spans multiple days\n */\n private updateDateFilterVisibility(): void {\n if (!this.messages || this.messages.length < 20) {\n this.shouldShowDateFilter = false;\n return;\n }\n\n // Check if messages span more than 2 days\n const dates = this.messages\n .map(m => m.__mj_CreatedAt)\n .filter(d => d != null)\n .map(d => new Date(d!).setHours(0, 0, 0, 0));\n\n if (dates.length === 0) {\n this.shouldShowDateFilter = false;\n return;\n }\n\n const uniqueDates = new Set(dates);\n const daySpan = uniqueDates.size;\n\n // Show filter if conversation has 20+ messages and spans 3+ days\n this.shouldShowDateFilter = daySpan >= 3;\n }\n\n /**\n * Scrolls the message list to the bottom\n */\n private scrollToBottom(): void {\n if (this.scrollContainer && this.scrollContainer.nativeElement) {\n Promise.resolve().then(() => {\n const element = this.scrollContainer.nativeElement;\n element.scrollTop = element.scrollHeight;\n });\n }\n }\n\n /**\n * Removes a message from the rendered list\n * Called externally when a message is deleted\n */\n public removeMessage(message: MJConversationDetailEntity): void {\n const key = this.getMessageKey(message);\n const entry = this._renderedMessages.get(key);\n if (entry) {\n entry.ref.destroy();\n this._renderedMessages.delete(key);\n }\n }\n}","<div class=\"message-list-container\" #scrollContainer>\n <!-- Sticky Date Header (only show for long conversations spanning multiple days) -->\n @if (shouldShowDateFilter && messages.length > 0) {\n <div class=\"sticky-date-header\">\n <div class=\"sticky-date-wrapper\">\n <button class=\"sticky-date-button\" (click)=\"toggleDateNav()\">\n <span>{{ currentDateDisplay }}</span>\n <i class=\"fas fa-chevron-down\"></i>\n </button>\n <div class=\"date-nav-dropdown\" [class.show]=\"showDateNav\">\n <div class=\"date-nav-option jump-to\">Jump to...</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('today')\">Today</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('yesterday')\">Yesterday</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('last-week')\">Last week</div>\n <div class=\"date-nav-option\" (click)=\"jumpToDate('last-month')\">Last month</div>\n </div>\n </div>\n </div>\n }\n\n <ng-container #messageContainer></ng-container>\n\n @if (messages.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-comments\"></i>\n <p>No messages yet. Start a conversation!</p>\n </div>\n }\n</div>"]}
|
|
@@ -16,12 +16,16 @@ export declare class ProjectFormModalComponent extends BaseAngularComponent impl
|
|
|
16
16
|
project: MJProjectEntity | null;
|
|
17
17
|
environmentId: string;
|
|
18
18
|
currentUser: UserInfo;
|
|
19
|
+
/** When creating a new folder, the parent folder ID for nesting (null = top level). */
|
|
20
|
+
parentId: string | null;
|
|
19
21
|
projectSaved: EventEmitter<MJProjectEntity>;
|
|
20
22
|
formData: ProjectFormData;
|
|
21
23
|
showNameError: boolean;
|
|
22
24
|
isEditMode: boolean;
|
|
23
25
|
availableColors: string[];
|
|
24
26
|
availableIcons: string[];
|
|
27
|
+
/** Translucent tint of the selected color, used behind the preview/icon glyph. */
|
|
28
|
+
get chipBackground(): string;
|
|
25
29
|
constructor(cdr: ChangeDetectorRef);
|
|
26
30
|
ngOnInit(): void;
|
|
27
31
|
private loadProjectData;
|
|
@@ -30,6 +34,6 @@ export declare class ProjectFormModalComponent extends BaseAngularComponent impl
|
|
|
30
34
|
onSave(): Promise<void>;
|
|
31
35
|
onCancel(): void;
|
|
32
36
|
static ɵfac: i0.ɵɵFactoryDeclaration<ProjectFormModalComponent, never>;
|
|
33
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ProjectFormModalComponent, "mj-project-form-modal", never, { "dialogRef": { "alias": "dialogRef"; "required": false; }; "project": { "alias": "project"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; }, { "projectSaved": "projectSaved"; }, never, never, false, never>;
|
|
37
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProjectFormModalComponent, "mj-project-form-modal", never, { "dialogRef": { "alias": "dialogRef"; "required": false; }; "project": { "alias": "project"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "parentId": { "alias": "parentId"; "required": false; }; }, { "projectSaved": "projectSaved"; }, never, never, false, never>;
|
|
34
38
|
}
|
|
35
39
|
//# sourceMappingURL=project-form-modal.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-form-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/project/project-form-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAa,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;;AAE1D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAgDD,
|
|
1
|
+
{"version":3,"file":"project-form-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/project/project-form-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAa,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;;AAE1D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAgDD,qBAkSa,yBAA0B,SAAQ,oBAAqB,YAAW,MAAM;IA6BvE,OAAO,CAAC,GAAG;IA5Bd,SAAS,EAAG,WAAW,CAAC;IACxB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAQ;IACvC,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IAChC,uFAAuF;IAC9E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE9B,YAAY,gCAAuC;IAEtD,QAAQ,EAAE,eAAe,CAK9B;IAEK,aAAa,UAAS;IACtB,UAAU,UAAS;IACnB,eAAe,WAA0B;IACzC,cAAc,WAAyB;IAE9C,kFAAkF;IAClF,IAAW,cAAc,IAAI,MAAM,CAIlC;gBAEmB,GAAG,EAAE,iBAAiB;IAG1C,QAAQ,IAAI,IAAI;IAQhB,OAAO,CAAC,eAAe;IAWvB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC7B,QAAQ,IAAI,IAAI;yCArGL,yBAAyB;2CAAzB,yBAAyB;CAwGrC"}
|
|
@@ -3,15 +3,15 @@ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
import * as i1 from "@angular/forms";
|
|
5
5
|
import * as i2 from "@memberjunction/ng-ui-components";
|
|
6
|
-
function
|
|
7
|
-
i0.ɵɵelementStart(0, "div",
|
|
8
|
-
i0.ɵɵtext(1, "
|
|
6
|
+
function ProjectFormModalComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
7
|
+
i0.ɵɵelementStart(0, "div", 8);
|
|
8
|
+
i0.ɵɵtext(1, "Folder name is required");
|
|
9
9
|
i0.ɵɵelementEnd();
|
|
10
10
|
} }
|
|
11
|
-
function
|
|
11
|
+
function ProjectFormModalComponent_For_22_Template(rf, ctx) { if (rf & 1) {
|
|
12
12
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
13
|
-
i0.ɵɵelementStart(0, "button",
|
|
14
|
-
i0.ɵɵlistener("click", function
|
|
13
|
+
i0.ɵɵelementStart(0, "button", 22);
|
|
14
|
+
i0.ɵɵlistener("click", function ProjectFormModalComponent_For_22_Template_button_click_0_listener() { const color_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.selectColor(color_r2)); });
|
|
15
15
|
i0.ɵɵelementEnd();
|
|
16
16
|
} if (rf & 2) {
|
|
17
17
|
const color_r2 = ctx.$implicit;
|
|
@@ -22,13 +22,14 @@ function ProjectFormModalComponent_For_17_Template(rf, ctx) { if (rf & 1) {
|
|
|
22
22
|
} }
|
|
23
23
|
function ProjectFormModalComponent_For_34_Template(rf, ctx) { if (rf & 1) {
|
|
24
24
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
25
|
-
i0.ɵɵelementStart(0, "button",
|
|
25
|
+
i0.ɵɵelementStart(0, "button", 23);
|
|
26
26
|
i0.ɵɵlistener("click", function ProjectFormModalComponent_For_34_Template_button_click_0_listener() { const icon_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.selectIcon(icon_r5)); });
|
|
27
27
|
i0.ɵɵelement(1, "i");
|
|
28
28
|
i0.ɵɵelementEnd();
|
|
29
29
|
} if (rf & 2) {
|
|
30
30
|
const icon_r5 = ctx.$implicit;
|
|
31
31
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
32
|
+
i0.ɵɵstyleProp("color", ctx_r2.formData.icon === icon_r5 ? ctx_r2.formData.color : null);
|
|
32
33
|
i0.ɵɵclassProp("selected", ctx_r2.formData.icon === icon_r5);
|
|
33
34
|
i0.ɵɵproperty("title", icon_r5);
|
|
34
35
|
i0.ɵɵadvance();
|
|
@@ -84,6 +85,8 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
84
85
|
project = null;
|
|
85
86
|
environmentId;
|
|
86
87
|
currentUser;
|
|
88
|
+
/** When creating a new folder, the parent folder ID for nesting (null = top level). */
|
|
89
|
+
parentId = null;
|
|
87
90
|
projectSaved = new EventEmitter();
|
|
88
91
|
formData = {
|
|
89
92
|
name: '',
|
|
@@ -95,6 +98,12 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
95
98
|
isEditMode = false;
|
|
96
99
|
availableColors = DEFAULT_PROJECT_COLORS;
|
|
97
100
|
availableIcons = DEFAULT_PROJECT_ICONS;
|
|
101
|
+
/** Translucent tint of the selected color, used behind the preview/icon glyph. */
|
|
102
|
+
get chipBackground() {
|
|
103
|
+
const hex = this.formData.color || '#0076B6';
|
|
104
|
+
// 8-digit hex (#RRGGBBAA) — ~14% alpha tint of the chosen color
|
|
105
|
+
return /^#[0-9a-fA-F]{6}$/.test(hex) ? `${hex}24` : hex;
|
|
106
|
+
}
|
|
98
107
|
constructor(cdr) {
|
|
99
108
|
super();
|
|
100
109
|
this.cdr = cdr;
|
|
@@ -141,6 +150,9 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
141
150
|
if (!this.isEditMode) {
|
|
142
151
|
project.EnvironmentID = this.environmentId;
|
|
143
152
|
project.IsArchived = false;
|
|
153
|
+
if (this.parentId) {
|
|
154
|
+
project.ParentID = this.parentId;
|
|
155
|
+
}
|
|
144
156
|
}
|
|
145
157
|
const saved = await project.Save();
|
|
146
158
|
if (saved) {
|
|
@@ -160,64 +172,71 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
160
172
|
this.dialogRef.Close();
|
|
161
173
|
}
|
|
162
174
|
static ɵfac = function ProjectFormModalComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ProjectFormModalComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
163
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProjectFormModalComponent, selectors: [["mj-project-form-modal"]], inputs: { dialogRef: "dialogRef", project: "project", environmentId: "environmentId", currentUser: "currentUser" }, outputs: { projectSaved: "projectSaved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 40, vars:
|
|
175
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProjectFormModalComponent, selectors: [["mj-project-form-modal"]], inputs: { dialogRef: "dialogRef", project: "project", environmentId: "environmentId", currentUser: "currentUser", parentId: "parentId" }, outputs: { projectSaved: "projectSaved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 40, vars: 18, consts: [[3, "Close", "Title", "Width", "MinWidth", "Visible"], [1, "project-form"], [1, "folder-preview"], [1, "folder-preview-chip"], [1, "folder-preview-name"], [1, "form-field"], ["for", "projectName", 1, "required"], ["id", "projectName", "type", "text", "placeholder", "e.g. Client work, Research, Ideas", "autofocus", "", 1, "mj-input", "full-width", 3, "ngModelChange", "keydown.enter", "ngModel"], [1, "error-message"], ["for", "projectDescription"], ["id", "projectDescription", "placeholder", "What goes in this folder? (optional)", "rows", "2", 1, "mj-textarea", "full-width", 3, "ngModelChange", "ngModel"], [1, "color-picker-section"], [1, "color-palette"], ["type", "button", 1, "color-swatch", 3, "selected", "backgroundColor", "title"], [1, "custom-color-input"], ["for", "customColor"], ["id", "customColor", "type", "color", 1, "custom-color-picker", 3, "ngModelChange", "ngModel"], [1, "color-value"], [1, "icon-grid"], ["type", "button", 1, "icon-option", 3, "selected", "color", "title"], ["mjButton", "", "variant", "primary", 3, "click"], ["mjButton", "", 3, "click"], ["type", "button", 1, "color-swatch", 3, "click", "title"], ["type", "button", 1, "icon-option", 3, "click", "title"]], template: function ProjectFormModalComponent_Template(rf, ctx) { if (rf & 1) {
|
|
164
176
|
i0.ɵɵelementStart(0, "mj-dialog", 0);
|
|
165
177
|
i0.ɵɵlistener("Close", function ProjectFormModalComponent_Template_mj_dialog_Close_0_listener() { return ctx.onCancel(); });
|
|
166
|
-
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "
|
|
167
|
-
i0.ɵɵ
|
|
178
|
+
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "span", 3);
|
|
179
|
+
i0.ɵɵelement(4, "i");
|
|
180
|
+
i0.ɵɵelementEnd();
|
|
181
|
+
i0.ɵɵelementStart(5, "span", 4);
|
|
182
|
+
i0.ɵɵtext(6);
|
|
183
|
+
i0.ɵɵelementEnd()();
|
|
184
|
+
i0.ɵɵelementStart(7, "div", 5)(8, "label", 6);
|
|
185
|
+
i0.ɵɵtext(9, " Folder Name ");
|
|
168
186
|
i0.ɵɵelementEnd();
|
|
169
|
-
i0.ɵɵelementStart(
|
|
170
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
171
|
-
i0.ɵɵlistener("keydown.enter", function
|
|
187
|
+
i0.ɵɵelementStart(10, "input", 7);
|
|
188
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ProjectFormModalComponent_Template_input_ngModelChange_10_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.formData.name, $event) || (ctx.formData.name = $event); return $event; });
|
|
189
|
+
i0.ɵɵlistener("keydown.enter", function ProjectFormModalComponent_Template_input_keydown_enter_10_listener() { return ctx.onSave(); });
|
|
172
190
|
i0.ɵɵelementEnd();
|
|
173
|
-
i0.ɵɵconditionalCreate(
|
|
191
|
+
i0.ɵɵconditionalCreate(11, ProjectFormModalComponent_Conditional_11_Template, 2, 0, "div", 8);
|
|
174
192
|
i0.ɵɵelementEnd();
|
|
175
|
-
i0.ɵɵelementStart(
|
|
176
|
-
i0.ɵɵtext(
|
|
193
|
+
i0.ɵɵelementStart(12, "div", 5)(13, "label", 9);
|
|
194
|
+
i0.ɵɵtext(14, " Description ");
|
|
177
195
|
i0.ɵɵelementEnd();
|
|
178
|
-
i0.ɵɵelementStart(
|
|
179
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
196
|
+
i0.ɵɵelementStart(15, "textarea", 10);
|
|
197
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ProjectFormModalComponent_Template_textarea_ngModelChange_15_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.formData.description, $event) || (ctx.formData.description = $event); return $event; });
|
|
180
198
|
i0.ɵɵelementEnd()();
|
|
181
|
-
i0.ɵɵelementStart(
|
|
182
|
-
i0.ɵɵtext(
|
|
199
|
+
i0.ɵɵelementStart(16, "div", 5)(17, "label");
|
|
200
|
+
i0.ɵɵtext(18, "Color");
|
|
183
201
|
i0.ɵɵelementEnd();
|
|
184
|
-
i0.ɵɵelementStart(
|
|
185
|
-
i0.ɵɵrepeaterCreate(
|
|
202
|
+
i0.ɵɵelementStart(19, "div", 11)(20, "div", 12);
|
|
203
|
+
i0.ɵɵrepeaterCreate(21, ProjectFormModalComponent_For_22_Template, 1, 5, "button", 13, i0.ɵɵrepeaterTrackByIdentity);
|
|
186
204
|
i0.ɵɵelementEnd();
|
|
187
|
-
i0.ɵɵelementStart(
|
|
188
|
-
i0.ɵɵtext(
|
|
205
|
+
i0.ɵɵelementStart(23, "div", 14)(24, "label", 15);
|
|
206
|
+
i0.ɵɵtext(25, "Custom:");
|
|
189
207
|
i0.ɵɵelementEnd();
|
|
190
|
-
i0.ɵɵelementStart(
|
|
191
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
208
|
+
i0.ɵɵelementStart(26, "input", 16);
|
|
209
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ProjectFormModalComponent_Template_input_ngModelChange_26_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.formData.color, $event) || (ctx.formData.color = $event); return $event; });
|
|
192
210
|
i0.ɵɵelementEnd();
|
|
193
|
-
i0.ɵɵelementStart(
|
|
194
|
-
i0.ɵɵtext(
|
|
211
|
+
i0.ɵɵelementStart(27, "span", 17);
|
|
212
|
+
i0.ɵɵtext(28);
|
|
195
213
|
i0.ɵɵelementEnd()()()();
|
|
196
|
-
i0.ɵɵelementStart(
|
|
197
|
-
i0.ɵɵtext(
|
|
214
|
+
i0.ɵɵelementStart(29, "div", 5)(30, "label");
|
|
215
|
+
i0.ɵɵtext(31, "Icon");
|
|
198
216
|
i0.ɵɵelementEnd();
|
|
199
|
-
i0.ɵɵelementStart(
|
|
200
|
-
i0.ɵɵ
|
|
201
|
-
i0.ɵɵ
|
|
202
|
-
i0.ɵɵ
|
|
203
|
-
i0.ɵɵ
|
|
204
|
-
i0.ɵɵ
|
|
205
|
-
i0.ɵɵrepeaterCreate(33, ProjectFormModalComponent_For_34_Template, 2, 6, "button", 18, i0.ɵɵrepeaterTrackByIdentity);
|
|
206
|
-
i0.ɵɵelementEnd()()()();
|
|
207
|
-
i0.ɵɵelementStart(35, "mj-dialog-actions")(36, "button", 19);
|
|
208
|
-
i0.ɵɵlistener("click", function ProjectFormModalComponent_Template_button_click_36_listener() { return ctx.onCancel(); });
|
|
209
|
-
i0.ɵɵtext(37, "Cancel");
|
|
217
|
+
i0.ɵɵelementStart(32, "div", 18);
|
|
218
|
+
i0.ɵɵrepeaterCreate(33, ProjectFormModalComponent_For_34_Template, 2, 8, "button", 19, i0.ɵɵrepeaterTrackByIdentity);
|
|
219
|
+
i0.ɵɵelementEnd()()();
|
|
220
|
+
i0.ɵɵelementStart(35, "mj-dialog-actions")(36, "button", 20);
|
|
221
|
+
i0.ɵɵlistener("click", function ProjectFormModalComponent_Template_button_click_36_listener() { return ctx.onSave(); });
|
|
222
|
+
i0.ɵɵtext(37);
|
|
210
223
|
i0.ɵɵelementEnd();
|
|
211
|
-
i0.ɵɵelementStart(38, "button",
|
|
212
|
-
i0.ɵɵlistener("click", function ProjectFormModalComponent_Template_button_click_38_listener() { return ctx.
|
|
213
|
-
i0.ɵɵtext(39);
|
|
224
|
+
i0.ɵɵelementStart(38, "button", 21);
|
|
225
|
+
i0.ɵɵlistener("click", function ProjectFormModalComponent_Template_button_click_38_listener() { return ctx.onCancel(); });
|
|
226
|
+
i0.ɵɵtext(39, "Cancel");
|
|
214
227
|
i0.ɵɵelementEnd()()();
|
|
215
228
|
} if (rf & 2) {
|
|
216
|
-
i0.ɵɵproperty("Title", ctx.isEditMode ? "Edit
|
|
217
|
-
i0.ɵɵadvance(
|
|
229
|
+
i0.ɵɵproperty("Title", ctx.isEditMode ? "Edit Folder" : "New Folder")("Width", 560)("MinWidth", 400)("Visible", true);
|
|
230
|
+
i0.ɵɵadvance(3);
|
|
231
|
+
i0.ɵɵstyleProp("background-color", ctx.chipBackground)("color", ctx.formData.color);
|
|
232
|
+
i0.ɵɵadvance();
|
|
233
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", ctx.formData.icon));
|
|
234
|
+
i0.ɵɵadvance(2);
|
|
235
|
+
i0.ɵɵtextInterpolate(ctx.formData.name.trim() || "Untitled folder");
|
|
236
|
+
i0.ɵɵadvance(4);
|
|
218
237
|
i0.ɵɵtwoWayProperty("ngModel", ctx.formData.name);
|
|
219
238
|
i0.ɵɵadvance();
|
|
220
|
-
i0.ɵɵconditional(ctx.showNameError ?
|
|
239
|
+
i0.ɵɵconditional(ctx.showNameError ? 11 : -1);
|
|
221
240
|
i0.ɵɵadvance(4);
|
|
222
241
|
i0.ɵɵtwoWayProperty("ngModel", ctx.formData.description);
|
|
223
242
|
i0.ɵɵadvance(6);
|
|
@@ -226,43 +245,46 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
226
245
|
i0.ɵɵtwoWayProperty("ngModel", ctx.formData.color);
|
|
227
246
|
i0.ɵɵadvance(2);
|
|
228
247
|
i0.ɵɵtextInterpolate(ctx.formData.color);
|
|
229
|
-
i0.ɵɵadvance(
|
|
230
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", ctx.formData.icon));
|
|
231
|
-
i0.ɵɵstyleProp("color", ctx.formData.color);
|
|
232
|
-
i0.ɵɵadvance(2);
|
|
233
|
-
i0.ɵɵtextInterpolate(ctx.formData.icon);
|
|
234
|
-
i0.ɵɵadvance(2);
|
|
248
|
+
i0.ɵɵadvance(5);
|
|
235
249
|
i0.ɵɵrepeater(ctx.availableIcons);
|
|
236
|
-
i0.ɵɵadvance(
|
|
237
|
-
i0.ɵɵtextInterpolate1(" ", ctx.isEditMode ? "Save" : "Create", " ");
|
|
238
|
-
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDialogComponent, i2.MJDialogActionsComponent], styles: [".project-form[_ngcontent-%COMP%] {\n padding:
|
|
250
|
+
i0.ɵɵadvance(4);
|
|
251
|
+
i0.ɵɵtextInterpolate1(" ", ctx.isEditMode ? "Save Changes" : "Create Folder", " ");
|
|
252
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDialogComponent, i2.MJDialogActionsComponent], styles: [".project-form[_ngcontent-%COMP%] {\n padding: 20px 24px 8px;\n display: flex;\n flex-direction: column;\n gap: 22px;\n }\n\n \n\n .folder-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n }\n .folder-preview-chip[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n transition: background-color 150ms ease, color 150ms ease;\n }\n .folder-preview-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .form-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n letter-spacing: 0.01em;\n color: var(--mj-text-secondary);\n }\n\n .form-field[_ngcontent-%COMP%] label.required[_ngcontent-%COMP%]::after {\n content: '*';\n color: var(--mj-status-error);\n margin-left: 4px;\n }\n\n .full-width[_ngcontent-%COMP%] { width: 100%; }\n\n .error-message[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-size: 12px;\n }\n\n \n\n .color-picker-section[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 14px;\n background: var(--mj-bg-surface);\n }\n\n .color-palette[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .color-swatch[_ngcontent-%COMP%] {\n width: 100%;\n aspect-ratio: 1;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n padding: 0;\n transition: transform 120ms ease, box-shadow 120ms ease;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n }\n\n .color-swatch[_ngcontent-%COMP%]:hover {\n transform: scale(1.12);\n }\n\n .color-swatch.selected[_ngcontent-%COMP%] {\n box-shadow: 0 0 0 2px var(--mj-bg-surface), 0 0 0 4px var(--mj-brand-primary);\n }\n\n .custom-color-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding-top: 14px;\n border-top: 1px solid var(--mj-border-subtle);\n }\n\n .custom-color-input[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n }\n\n .custom-color-picker[_ngcontent-%COMP%] {\n width: 44px;\n height: 30px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n }\n\n .color-value[_ngcontent-%COMP%] {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 13px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n }\n\n \n\n .icon-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 8px;\n max-height: 184px;\n overflow-y: auto;\n padding: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n }\n\n .icon-option[_ngcontent-%COMP%] {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;\n }\n\n .icon-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n }\n\n .icon-option.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 1px var(--mj-brand-primary);\n }\n\n .icon-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 17px; }\n\n \n\n .icon-grid[_ngcontent-%COMP%]::-webkit-scrollbar { width: 8px; }\n .icon-grid[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n }\n .icon-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n }\n .icon-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n }"] });
|
|
239
253
|
}
|
|
240
254
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ProjectFormModalComponent, [{
|
|
241
255
|
type: Component,
|
|
242
256
|
args: [{ standalone: false, selector: 'mj-project-form-modal', template: `
|
|
243
257
|
<mj-dialog
|
|
244
|
-
[Title]="isEditMode ? 'Edit
|
|
245
|
-
[Width]="
|
|
258
|
+
[Title]="isEditMode ? 'Edit Folder' : 'New Folder'"
|
|
259
|
+
[Width]="560"
|
|
246
260
|
[MinWidth]="400"
|
|
247
261
|
[Visible]="true"
|
|
248
262
|
(Close)="onCancel()">
|
|
249
263
|
|
|
250
264
|
<div class="project-form">
|
|
265
|
+
<!-- Live preview chip -->
|
|
266
|
+
<div class="folder-preview">
|
|
267
|
+
<span class="folder-preview-chip" [style.backgroundColor]="chipBackground" [style.color]="formData.color">
|
|
268
|
+
<i class="fa-solid {{ formData.icon }}"></i>
|
|
269
|
+
</span>
|
|
270
|
+
<span class="folder-preview-name">{{ formData.name.trim() || 'Untitled folder' }}</span>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
251
273
|
<!-- Name Input -->
|
|
252
274
|
<div class="form-field">
|
|
253
275
|
<label for="projectName" class="required">
|
|
254
|
-
|
|
276
|
+
Folder Name
|
|
255
277
|
</label>
|
|
256
278
|
<input
|
|
257
279
|
id="projectName"
|
|
258
280
|
type="text"
|
|
259
281
|
[(ngModel)]="formData.name"
|
|
260
|
-
placeholder="
|
|
261
|
-
class="mj-
|
|
282
|
+
placeholder="e.g. Client work, Research, Ideas"
|
|
283
|
+
class="mj-input full-width"
|
|
262
284
|
(keydown.enter)="onSave()"
|
|
263
285
|
autofocus />
|
|
264
286
|
@if (showNameError) {
|
|
265
|
-
<div class="error-message">
|
|
287
|
+
<div class="error-message">Folder name is required</div>
|
|
266
288
|
}
|
|
267
289
|
</div>
|
|
268
290
|
|
|
@@ -274,9 +296,9 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
274
296
|
<textarea
|
|
275
297
|
id="projectDescription"
|
|
276
298
|
[(ngModel)]="formData.description"
|
|
277
|
-
placeholder="
|
|
299
|
+
placeholder="What goes in this folder? (optional)"
|
|
278
300
|
class="mj-textarea full-width"
|
|
279
|
-
rows="
|
|
301
|
+
rows="2"></textarea>
|
|
280
302
|
</div>
|
|
281
303
|
|
|
282
304
|
<!-- Color Picker -->
|
|
@@ -310,35 +332,30 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
310
332
|
<!-- Icon Selector -->
|
|
311
333
|
<div class="form-field">
|
|
312
334
|
<label>Icon</label>
|
|
313
|
-
<div class="icon-
|
|
314
|
-
|
|
315
|
-
<
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
[title]="icon">
|
|
326
|
-
<i class="fa-solid {{ icon }}"></i>
|
|
327
|
-
</button>
|
|
328
|
-
}
|
|
329
|
-
</div>
|
|
335
|
+
<div class="icon-grid">
|
|
336
|
+
@for (icon of availableIcons; track icon) {
|
|
337
|
+
<button
|
|
338
|
+
type="button"
|
|
339
|
+
class="icon-option"
|
|
340
|
+
[class.selected]="formData.icon === icon"
|
|
341
|
+
[style.color]="formData.icon === icon ? formData.color : null"
|
|
342
|
+
(click)="selectIcon(icon)"
|
|
343
|
+
[title]="icon">
|
|
344
|
+
<i class="fa-solid {{ icon }}"></i>
|
|
345
|
+
</button>
|
|
346
|
+
}
|
|
330
347
|
</div>
|
|
331
348
|
</div>
|
|
332
349
|
</div>
|
|
333
350
|
|
|
334
351
|
<mj-dialog-actions>
|
|
335
|
-
<button mjButton (click)="onCancel()">Cancel</button>
|
|
336
352
|
<button mjButton variant="primary" (click)="onSave()">
|
|
337
|
-
{{ isEditMode ? 'Save' : 'Create' }}
|
|
353
|
+
{{ isEditMode ? 'Save Changes' : 'Create Folder' }}
|
|
338
354
|
</button>
|
|
355
|
+
<button mjButton (click)="onCancel()">Cancel</button>
|
|
339
356
|
</mj-dialog-actions>
|
|
340
357
|
</mj-dialog>
|
|
341
|
-
`, styles: ["\n .project-form {\n padding: 16px;\n }\n\n .
|
|
358
|
+
`, styles: ["\n .project-form {\n padding: 20px 24px 8px;\n display: flex;\n flex-direction: column;\n gap: 22px;\n }\n\n /* Live preview chip */\n .folder-preview {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n }\n .folder-preview-chip {\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n transition: background-color 150ms ease, color 150ms ease;\n }\n .folder-preview-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .form-field label {\n font-weight: 600;\n font-size: 13px;\n letter-spacing: 0.01em;\n color: var(--mj-text-secondary);\n }\n\n .form-field label.required::after {\n content: '*';\n color: var(--mj-status-error);\n margin-left: 4px;\n }\n\n .full-width { width: 100%; }\n\n .error-message {\n color: var(--mj-status-error);\n font-size: 12px;\n }\n\n /* Color Picker */\n .color-picker-section {\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 14px;\n background: var(--mj-bg-surface);\n }\n\n .color-palette {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .color-swatch {\n width: 100%;\n aspect-ratio: 1;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n padding: 0;\n transition: transform 120ms ease, box-shadow 120ms ease;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n }\n\n .color-swatch:hover {\n transform: scale(1.12);\n }\n\n .color-swatch.selected {\n box-shadow: 0 0 0 2px var(--mj-bg-surface), 0 0 0 4px var(--mj-brand-primary);\n }\n\n .custom-color-input {\n display: flex;\n align-items: center;\n gap: 10px;\n padding-top: 14px;\n border-top: 1px solid var(--mj-border-subtle);\n }\n\n .custom-color-input label {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n }\n\n .custom-color-picker {\n width: 44px;\n height: 30px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n }\n\n .color-value {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 13px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n }\n\n /* Icon Selector */\n .icon-grid {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 8px;\n max-height: 184px;\n overflow-y: auto;\n padding: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n }\n\n .icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;\n }\n\n .icon-option:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n }\n\n .icon-option.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 1px var(--mj-brand-primary);\n }\n\n .icon-option i { font-size: 17px; }\n\n /* Scrollbar */\n .icon-grid::-webkit-scrollbar { width: 8px; }\n .icon-grid::-webkit-scrollbar-track {\n background: transparent;\n }\n .icon-grid::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n }\n .icon-grid::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n }\n "] }]
|
|
342
359
|
}], () => [{ type: i0.ChangeDetectorRef }], { dialogRef: [{
|
|
343
360
|
type: Input
|
|
344
361
|
}], project: [{
|
|
@@ -347,8 +364,10 @@ export class ProjectFormModalComponent extends BaseAngularComponent {
|
|
|
347
364
|
type: Input
|
|
348
365
|
}], currentUser: [{
|
|
349
366
|
type: Input
|
|
367
|
+
}], parentId: [{
|
|
368
|
+
type: Input
|
|
350
369
|
}], projectSaved: [{
|
|
351
370
|
type: Output
|
|
352
371
|
}] }); })();
|
|
353
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProjectFormModalComponent, { className: "ProjectFormModalComponent", filePath: "src/lib/components/project/project-form-modal.component.ts", lineNumber:
|
|
372
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProjectFormModalComponent, { className: "ProjectFormModalComponent", filePath: "src/lib/components/project/project-form-modal.component.ts", lineNumber: 350 }); })();
|
|
354
373
|
//# sourceMappingURL=project-form-modal.component.js.map
|