@memberjunction/ng-conversations 5.43.0 → 5.44.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/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +0 -1
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +56 -52
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +37 -41
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +41 -45
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +22 -36
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +134 -166
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +73 -8
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +487 -123
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
- package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/library/library-full-view.component.js +20 -24
- package/dist/lib/components/library/library-full-view.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +10 -11
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +49 -28
- package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.js +24 -10
- package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +11 -16
- package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +52 -46
- package/dist/lib/components/message/message-input-box.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +83 -18
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +238 -151
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +10 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +67 -15
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.js +6 -9
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +3 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
- package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
- package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
- package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
- package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel.js +253 -0
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
- package/dist/lib/components/search/search-panel.component.d.ts +2 -0
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +92 -101
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +10 -11
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
- package/dist/lib/components/shared/user-picker.component.js +12 -15
- package/dist/lib/components/shared/user-picker.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +5 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +18 -7
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +29 -26
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +37 -6
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/models/conversation-state.model.d.ts +6 -3
- 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/conversation-agent.service.d.ts +2 -2
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +6 -2
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +17 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +58 -2
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
- package/dist/lib/services/realtime-audio-recorder.js +379 -0
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
- package/dist/lib/services/realtime-pcm-wav.js +205 -0
- package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
- package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +12 -3
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +210 -20
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +452 -21
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/realtime-sessions-adapter.js +1 -1
- package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
- package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
- package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
- package/dist/lib/services/ui-command-handler.service.js +6 -2
- package/dist/lib/services/ui-command-handler.service.js.map +1 -1
- package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
- package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
- package/dist/lib/utils/plan-mode-preference.js +130 -0
- package/dist/lib/utils/plan-mode-preference.js.map +1 -0
- package/dist/public-api.d.ts +6 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +8 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +28 -26
- package/dist/__tests__/attachment-badge.test.d.ts +0 -2
- package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
- package/dist/__tests__/attachment-badge.test.js +0 -66
- package/dist/__tests__/attachment-badge.test.js.map +0 -1
- package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
- package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
- package/dist/__tests__/channel-optional-surface.test.js +0 -53
- package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
- package/dist/__tests__/chat-events.test.d.ts +0 -14
- package/dist/__tests__/chat-events.test.d.ts.map +0 -1
- package/dist/__tests__/chat-events.test.js +0 -109
- package/dist/__tests__/chat-events.test.js.map +0 -1
- package/dist/__tests__/collections-full-view.test.d.ts +0 -2
- package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
- package/dist/__tests__/collections-full-view.test.js +0 -225
- package/dist/__tests__/collections-full-view.test.js.map +0 -1
- package/dist/__tests__/conversation-cache.test.d.ts +0 -2
- package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-cache.test.js +0 -233
- package/dist/__tests__/conversation-cache.test.js.map +0 -1
- package/dist/__tests__/conversation-naming.test.d.ts +0 -2
- package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-naming.test.js +0 -110
- package/dist/__tests__/conversation-naming.test.js.map +0 -1
- package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
- package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
- package/dist/__tests__/delegation-result-parser.test.js +0 -107
- package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
- package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
- package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
- package/dist/__tests__/distinct-artifacts.test.js +0 -56
- package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
- package/dist/__tests__/event-wiring.test.d.ts +0 -15
- package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
- package/dist/__tests__/event-wiring.test.js +0 -100
- package/dist/__tests__/event-wiring.test.js.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -7
- package/dist/__tests__/index.test.js.map +0 -1
- package/dist/__tests__/narration-template.test.d.ts +0 -2
- package/dist/__tests__/narration-template.test.d.ts.map +0 -1
- package/dist/__tests__/narration-template.test.js +0 -76
- package/dist/__tests__/narration-template.test.js.map +0 -1
- package/dist/__tests__/notification-model.test.d.ts +0 -2
- package/dist/__tests__/notification-model.test.d.ts.map +0 -1
- package/dist/__tests__/notification-model.test.js +0 -68
- package/dist/__tests__/notification-model.test.js.map +0 -1
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
- package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
- package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
- package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
- package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
- package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
- package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
- package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-disclosure.test.js +0 -164
- package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
- package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
- package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-pairing.test.js +0 -207
- package/dist/__tests__/realtime-pairing.test.js.map +0 -1
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
- package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
- package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
- package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-channels.test.js +0 -252
- package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
- package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
- package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
- package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-minimized.test.js +0 -32
- package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
- package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-mint.test.js +0 -69
- package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
- package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-policy.test.js +0 -303
- package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
- package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-review.service.test.js +0 -743
- package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
- package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-state.test.js +0 -83
- package/dist/__tests__/realtime-session-state.test.js.map +0 -1
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
- package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
- package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-timeline.test.js +0 -142
- package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
- package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
- package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
- package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
- package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
- package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
- package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
- package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
- package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
- package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
- package/dist/__tests__/remote-browser-channel.test.js +0 -585
- package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
- package/dist/__tests__/search-service.test.d.ts +0 -2
- package/dist/__tests__/search-service.test.d.ts.map +0 -1
- package/dist/__tests__/search-service.test.js +0 -114
- package/dist/__tests__/search-service.test.js.map +0 -1
- package/dist/__tests__/slot-defaults.test.d.ts +0 -24
- package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
- package/dist/__tests__/slot-defaults.test.js +0 -63
- package/dist/__tests__/slot-defaults.test.js.map +0 -1
- package/dist/__tests__/toast-service.test.d.ts +0 -2
- package/dist/__tests__/toast-service.test.d.ts.map +0 -1
- package/dist/__tests__/toast-service.test.js +0 -143
- package/dist/__tests__/toast-service.test.js.map +0 -1
- package/dist/__tests__/user-authorization.test.d.ts +0 -2
- package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
- package/dist/__tests__/user-authorization.test.js +0 -97
- package/dist/__tests__/user-authorization.test.js.map +0 -1
- package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
- package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
- package/dist/__tests__/voice-session-narration.test.js +0 -609
- package/dist/__tests__/voice-session-narration.test.js.map +0 -1
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
- package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
- package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-channel.test.js +0 -260
- package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
- package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
- package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
|
@@ -5,48 +5,57 @@ import * as i2 from "../mention/mention-editor.component";
|
|
|
5
5
|
const _c0 = ["mentionEditor"];
|
|
6
6
|
function MessageInputBoxComponent_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
7
7
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
8
|
-
i0.ɵɵelementStart(0, "button",
|
|
9
|
-
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.
|
|
10
|
-
i0.ɵɵelement(1, "i",
|
|
11
|
-
i0.ɵɵelementEnd();
|
|
12
|
-
i0.ɵɵelementStart(2, "button", 9);
|
|
13
|
-
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_click_2_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openArtifactPicker(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
14
|
-
i0.ɵɵelement(3, "i", 10);
|
|
8
|
+
i0.ɵɵelementStart(0, "button", 9);
|
|
9
|
+
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.planModeToggle.emit(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
10
|
+
i0.ɵɵelement(1, "i", 10);
|
|
15
11
|
i0.ɵɵelementEnd();
|
|
16
12
|
} if (rf & 2) {
|
|
17
13
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
18
|
-
i0.ɵɵ
|
|
19
|
-
i0.ɵɵ
|
|
20
|
-
i0.ɵɵ
|
|
14
|
+
i0.ɵɵclassProp("plan-mode-button-icon--active", ctx_r2.planModeActive);
|
|
15
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled)("title", ctx_r2.planModeActive ? "Plan Mode ON \u2014 the agent presents a plan for your approval before it acts" : "Plan Mode: have the agent present a plan for your approval before it acts");
|
|
16
|
+
i0.ɵɵattribute("aria-pressed", ctx_r2.planModeActive);
|
|
21
17
|
} }
|
|
22
18
|
function MessageInputBoxComponent_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
23
19
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
24
20
|
i0.ɵɵelementStart(0, "button", 11);
|
|
25
|
-
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.
|
|
21
|
+
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openFilePicker(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
26
22
|
i0.ɵɵelement(1, "i", 12);
|
|
27
23
|
i0.ɵɵelementEnd();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
i0.ɵɵ
|
|
24
|
+
} if (rf & 2) {
|
|
25
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
26
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled);
|
|
27
|
+
} }
|
|
28
|
+
function MessageInputBoxComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
29
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
30
|
+
i0.ɵɵelementStart(0, "button", 13);
|
|
31
|
+
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_3_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.onRealtimeClick(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
32
|
+
i0.ɵɵelement(1, "i", 14);
|
|
33
|
+
i0.ɵɵelementEnd();
|
|
34
|
+
i0.ɵɵelementStart(2, "button", 15);
|
|
35
|
+
i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_3_Template_button_click_2_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.onRealtimeOptionsClick(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
36
|
+
i0.ɵɵelement(3, "i", 16);
|
|
31
37
|
i0.ɵɵelementEnd();
|
|
32
38
|
} if (rf & 2) {
|
|
33
39
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
34
40
|
i0.ɵɵclassProp("voice-button-icon--active", ctx_r2.voiceActive);
|
|
35
|
-
i0.ɵɵproperty("disabled", !ctx_r2.
|
|
41
|
+
i0.ɵɵproperty("disabled", !ctx_r2.canStartRealtime)("title", ctx_r2.voiceActive ? "Voice call active" : "Start a voice call");
|
|
36
42
|
i0.ɵɵadvance(2);
|
|
37
|
-
i0.ɵɵproperty("disabled", !ctx_r2.
|
|
43
|
+
i0.ɵɵproperty("disabled", !ctx_r2.canStartRealtime);
|
|
38
44
|
} }
|
|
39
45
|
function MessageInputBoxComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
40
46
|
i0.ɵɵelementStart(0, "div", 4);
|
|
41
|
-
i0.ɵɵconditionalCreate(1, MessageInputBoxComponent_Conditional_4_Conditional_1_Template,
|
|
42
|
-
i0.ɵɵconditionalCreate(2, MessageInputBoxComponent_Conditional_4_Conditional_2_Template,
|
|
47
|
+
i0.ɵɵconditionalCreate(1, MessageInputBoxComponent_Conditional_4_Conditional_1_Template, 2, 5, "button", 7);
|
|
48
|
+
i0.ɵɵconditionalCreate(2, MessageInputBoxComponent_Conditional_4_Conditional_2_Template, 2, 1, "button", 8);
|
|
49
|
+
i0.ɵɵconditionalCreate(3, MessageInputBoxComponent_Conditional_4_Conditional_3_Template, 4, 5);
|
|
43
50
|
i0.ɵɵelementEnd();
|
|
44
51
|
} if (rf & 2) {
|
|
45
52
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
46
53
|
i0.ɵɵadvance();
|
|
47
|
-
i0.ɵɵconditional(ctx_r2.
|
|
54
|
+
i0.ɵɵconditional(ctx_r2.enablePlanMode ? 1 : -1);
|
|
48
55
|
i0.ɵɵadvance();
|
|
49
|
-
i0.ɵɵconditional(ctx_r2.
|
|
56
|
+
i0.ɵɵconditional(ctx_r2.enableAttachments ? 2 : -1);
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵconditional(ctx_r2.enableRealtime ? 3 : -1);
|
|
50
59
|
} }
|
|
51
60
|
/**
|
|
52
61
|
* Reusable message input box component (presentational)
|
|
@@ -78,17 +87,20 @@ export class MessageInputBoxComponent {
|
|
|
78
87
|
maxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB
|
|
79
88
|
acceptedFileTypes = 'image/*';
|
|
80
89
|
/** Shows the in-composer mic button when true. */
|
|
81
|
-
|
|
90
|
+
enableRealtime = false;
|
|
82
91
|
/** Whether a realtime voice session is currently active (mic renders in its active state). */
|
|
83
92
|
voiceActive = false;
|
|
84
93
|
/** Whether a voice session can be started right now (mic disabled when false). */
|
|
85
|
-
|
|
94
|
+
canStartRealtime = true;
|
|
95
|
+
/** Shows the in-composer Plan Mode toggle button when true. */
|
|
96
|
+
enablePlanMode = false;
|
|
97
|
+
/** Current Plan Mode toggle state (renders the button in its active state). */
|
|
98
|
+
planModeActive = false;
|
|
86
99
|
textSubmitted = new EventEmitter();
|
|
87
100
|
valueChange = new EventEmitter();
|
|
88
101
|
attachmentsChanged = new EventEmitter();
|
|
89
102
|
attachmentError = new EventEmitter();
|
|
90
103
|
attachmentClicked = new EventEmitter();
|
|
91
|
-
artifactPickerRequested = new EventEmitter();
|
|
92
104
|
/** Emitted when the user clicks the mic button to start/stop a voice session. */
|
|
93
105
|
voiceRequested = new EventEmitter();
|
|
94
106
|
/**
|
|
@@ -97,10 +109,12 @@ export class MessageInputBoxComponent {
|
|
|
97
109
|
* without adding friction to the plain phone click's instant-start path.
|
|
98
110
|
*/
|
|
99
111
|
voiceOptionsRequested = new EventEmitter();
|
|
100
|
-
|
|
112
|
+
/** Emitted when the user clicks the in-composer Plan Mode toggle button. */
|
|
113
|
+
planModeToggle = new EventEmitter();
|
|
114
|
+
onRealtimeClick() {
|
|
101
115
|
this.voiceRequested.emit();
|
|
102
116
|
}
|
|
103
|
-
|
|
117
|
+
onRealtimeOptionsClick() {
|
|
104
118
|
this.voiceOptionsRequested.emit();
|
|
105
119
|
}
|
|
106
120
|
get canSend() {
|
|
@@ -219,18 +233,6 @@ export class MessageInputBoxComponent {
|
|
|
219
233
|
openFilePicker() {
|
|
220
234
|
this.mentionEditor?.openFilePicker();
|
|
221
235
|
}
|
|
222
|
-
/**
|
|
223
|
-
* Open artifact picker - emits event for parent to handle.
|
|
224
|
-
*
|
|
225
|
-
* TODO (2026-04-15): no consumer currently handles `artifactPickerRequested`.
|
|
226
|
-
* The prior handler was removed by commit 0a4612abf1 and the orphaned
|
|
227
|
-
* template was cleaned up in 7a063fc12a. The template button is disabled
|
|
228
|
-
* to signal the gap. See message-input-box.component.html for the TODO
|
|
229
|
-
* describing the suggested picker implementation.
|
|
230
|
-
*/
|
|
231
|
-
openArtifactPicker() {
|
|
232
|
-
this.artifactPickerRequested.emit();
|
|
233
|
-
}
|
|
234
236
|
/**
|
|
235
237
|
* Add an artifact as a pending attachment (called by parent after artifact selection)
|
|
236
238
|
*/
|
|
@@ -243,7 +245,7 @@ export class MessageInputBoxComponent {
|
|
|
243
245
|
} if (rf & 2) {
|
|
244
246
|
let _t;
|
|
245
247
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mentionEditor = _t.first);
|
|
246
|
-
} }, inputs: { placeholder: "placeholder", disabled: "disabled", value: "value", showCharacterCount: "showCharacterCount", enableMentions: "enableMentions", currentUser: "currentUser", rows: "rows", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes",
|
|
248
|
+
} }, inputs: { placeholder: "placeholder", disabled: "disabled", value: "value", showCharacterCount: "showCharacterCount", enableMentions: "enableMentions", currentUser: "currentUser", rows: "rows", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", enableRealtime: "enableRealtime", voiceActive: "voiceActive", canStartRealtime: "canStartRealtime", enablePlanMode: "enablePlanMode", planModeActive: "planModeActive" }, outputs: { textSubmitted: "textSubmitted", valueChange: "valueChange", attachmentsChanged: "attachmentsChanged", attachmentError: "attachmentError", attachmentClicked: "attachmentClicked", voiceRequested: "voiceRequested", voiceOptionsRequested: "voiceOptionsRequested", planModeToggle: "planModeToggle" }, standalone: false, decls: 7, vars: 11, consts: [["mentionEditor", ""], [1, "message-input-box-container", 3, "click"], [1, "input-wrapper"], [3, "ngModelChange", "valueChange", "enterPressed", "mentionSelected", "attachmentsChanged", "attachmentError", "attachmentClicked", "placeholder", "disabled", "currentUser", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "ngModel"], [1, "attach-buttons"], ["title", "Send message (Enter)", 1, "send-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "plan-mode-button-icon--active", "disabled", "title"], ["title", "Attach file", 1, "attach-button-icon", 3, "disabled"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-route"], ["title", "Attach file", 1, "attach-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paperclip"], ["aria-label", "Start a voice call", 1, "attach-button-icon", "voice-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone"], ["title", "Voice call options (choose agent and voice model)", "aria-label", "Voice call options", 1, "attach-button-icon", "voice-options-button-icon", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"]], template: function MessageInputBoxComponent_Template(rf, ctx) { if (rf & 1) {
|
|
247
249
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
248
250
|
i0.ɵɵelementStart(0, "div", 1);
|
|
249
251
|
i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onContainerClick($event)); });
|
|
@@ -251,7 +253,7 @@ export class MessageInputBoxComponent {
|
|
|
251
253
|
i0.ɵɵtwoWayListener("ngModelChange", function MessageInputBoxComponent_Template_mj_mention_editor_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.value, $event) || (ctx.value = $event); return i0.ɵɵresetView($event); });
|
|
252
254
|
i0.ɵɵlistener("valueChange", function MessageInputBoxComponent_Template_mj_mention_editor_valueChange_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onValueChange($event)); })("enterPressed", function MessageInputBoxComponent_Template_mj_mention_editor_enterPressed_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onEnterPressed($event)); })("mentionSelected", function MessageInputBoxComponent_Template_mj_mention_editor_mentionSelected_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMentionSelected($event)); })("attachmentsChanged", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentsChanged_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentsChanged($event)); })("attachmentError", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentError_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentError($event)); })("attachmentClicked", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentClicked_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentClicked($event)); });
|
|
253
255
|
i0.ɵɵelementEnd();
|
|
254
|
-
i0.ɵɵconditionalCreate(4, MessageInputBoxComponent_Conditional_4_Template,
|
|
256
|
+
i0.ɵɵconditionalCreate(4, MessageInputBoxComponent_Conditional_4_Template, 4, 3, "div", 4);
|
|
255
257
|
i0.ɵɵelementStart(5, "button", 5);
|
|
256
258
|
i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSendClick()); });
|
|
257
259
|
i0.ɵɵelement(6, "i", 6);
|
|
@@ -261,14 +263,14 @@ export class MessageInputBoxComponent {
|
|
|
261
263
|
i0.ɵɵproperty("placeholder", ctx.placeholder)("disabled", ctx.disabled)("currentUser", ctx.currentUser)("enableMentions", ctx.enableMentions)("enableAttachments", ctx.enableAttachments)("maxAttachments", ctx.maxAttachments)("maxAttachmentSizeBytes", ctx.maxAttachmentSizeBytes)("acceptedFileTypes", ctx.acceptedFileTypes);
|
|
262
264
|
i0.ɵɵtwoWayProperty("ngModel", ctx.value);
|
|
263
265
|
i0.ɵɵadvance(2);
|
|
264
|
-
i0.ɵɵconditional(ctx.enableAttachments || ctx.
|
|
266
|
+
i0.ɵɵconditional(ctx.enableAttachments || ctx.enableRealtime || ctx.enablePlanMode ? 4 : -1);
|
|
265
267
|
i0.ɵɵadvance();
|
|
266
268
|
i0.ɵɵproperty("disabled", !ctx.canSend);
|
|
267
|
-
} }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MentionEditorComponent], styles: [".message-input-box-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper[_ngcontent-%COMP%] mj-mention-editor[_ngcontent-%COMP%] {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:focus, .message-input-box-textarea[_ngcontent-%COMP%]:active, .message-input-box-textarea[_ngcontent-%COMP%]:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.send-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n.attach-buttons[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.attach-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n@media (max-width: 768px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n@media (max-width: 480px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n\n\n\n.voice-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n\n\n\n\n.voice-options-button-icon[_ngcontent-%COMP%] {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}"] });
|
|
269
|
+
} }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MentionEditorComponent], styles: [".message-input-box-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper[_ngcontent-%COMP%] mj-mention-editor[_ngcontent-%COMP%] {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:focus, .message-input-box-textarea[_ngcontent-%COMP%]:active, .message-input-box-textarea[_ngcontent-%COMP%]:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.send-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n.attach-buttons[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.attach-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n\n\n@media (max-width: 768px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n@media (max-width: 480px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n\n\n\n.voice-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n\n\n\n\n.voice-options-button-icon[_ngcontent-%COMP%] {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}"] });
|
|
268
270
|
}
|
|
269
271
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputBoxComponent, [{
|
|
270
272
|
type: Component,
|
|
271
|
-
args: [{ standalone: false, selector: 'mj-message-input-box', template: "<div class=\"message-input-box-container\" (click)=\"onContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [currentUser]=\"currentUser\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [(ngModel)]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (enterPressed)=\"onEnterPressed($event)\"\n (mentionSelected)=\"onMentionSelected($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-mention-editor>\n\n <!-- Attach + voice buttons - Positioned over editor -->\n @if (enableAttachments || enableVoice) {\n <div class=\"attach-buttons\">\n @if (enableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"disabled\"\n (click)=\"openFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n <!--\n TODO: \"Attach artifact from library\" button is not yet wired.\n\n Current state (2026-04-15): emits `artifactPickerRequested` but no\n consumer handles the event (handler was removed by commit 0a4612abf1,\n orphaned template cleaned up in 7a063fc12a). Button is intentionally\n visible but disabled so it's obvious what's missing.\n\n To finish: build a picker modal (suggested approach: wrap the\n `<mj-tree-dropdown>` used in dashboard-viewer's artifact-config-panel)\n and on selection, attach the artifact version as a Direction='Input'\n MJConversationDetailArtifact junction on the outgoing message.\n The infrastructure for agents reading input artifacts is already in\n place via AgentRunner.gatherConversationArtifacts().\n\n See also: packages/Angular/Generic/artifacts/src/lib/services/analyze-artifact.service.ts\n which does the similar end-to-end flow for standalone Analyze \u2014 the\n attach-to-draft path is a strict subset (no artifact creation, no\n conversation creation, just the junction).\n -->\n <button\n class=\"attach-button-icon attach-artifact-button\"\n [disabled]=\"true\"\n (click)=\"openArtifactPicker(); $event.stopPropagation()\"\n title=\"Attach artifact from library \u2014 not yet wired (see message-input-box.component.html TODO)\"\n >\n <i class=\"fa-solid fa-cube\"></i>\n </button>\n }\n @if (enableVoice) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"voiceActive\"\n [disabled]=\"!canStartVoice\"\n (click)=\"onVoiceClick(); $event.stopPropagation()\"\n [title]=\"voiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!canStartVoice\"\n (click)=\"onVoiceOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!canSend\"\n (click)=\"onSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n", styles: [".message-input-box-container {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper mj-mention-editor {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea:focus, .message-input-box-textarea:active, .message-input-box-textarea:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon i {\n font-size: 1rem;\n}\n.send-button-icon:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Attach buttons container */\n.attach-buttons {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon i {\n font-size: 1rem;\n}\n.attach-button-icon:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .message-input-box-container {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .message-input-box-container {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n\n/* Voice call button \u2014 a phone icon in the attach-buttons cluster, left of send.\n Inherits .attach-button-icon base. Subtle brand glow on hover; active state (call\n live) renders a brand-color tint. The orb visual now lives ONLY inside the call\n overlay's banner. */\n.voice-button-icon i {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon:hover:not(:disabled) i {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n/* Voice OPTIONS caret \u2014 a slim chevron hugging the phone button. Opens the agent/model\n picker; intentionally quieter (smaller icon, narrower hit area) than the phone so the\n common instant-start click stays the visual primary. */\n.voice-options-button-icon {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon i {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon:hover:not(:disabled) i {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n"] }]
|
|
273
|
+
args: [{ standalone: false, selector: 'mj-message-input-box', template: "<div class=\"message-input-box-container\" (click)=\"onContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [currentUser]=\"currentUser\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [(ngModel)]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (enterPressed)=\"onEnterPressed($event)\"\n (mentionSelected)=\"onMentionSelected($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (enableAttachments || enableRealtime || enablePlanMode) {\n <div class=\"attach-buttons\">\n @if (enablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"planModeActive\"\n [disabled]=\"disabled\"\n [attr.aria-pressed]=\"planModeActive\"\n (click)=\"planModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"planModeActive ? 'Plan Mode ON \u2014 the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (enableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"disabled\"\n (click)=\"openFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (enableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"voiceActive\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeClick(); $event.stopPropagation()\"\n [title]=\"voiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!canSend\"\n (click)=\"onSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n", styles: [".message-input-box-container {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper mj-mention-editor {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea:focus, .message-input-box-textarea:active, .message-input-box-textarea:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon i {\n font-size: 1rem;\n}\n.send-button-icon:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Attach buttons container */\n.attach-buttons {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon i {\n font-size: 1rem;\n}\n.attach-button-icon:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Plan Mode toggle \u2014 inherits .attach-button-icon; when active it fills with the brand color\n so the on/off state reads clearly at a glance (parallels the voice button's active state). */\n.plan-mode-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .message-input-box-container {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .message-input-box-container {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n\n/* Voice call button \u2014 a phone icon in the attach-buttons cluster, left of send.\n Inherits .attach-button-icon base. Subtle brand glow on hover; active state (call\n live) renders a brand-color tint. The orb visual now lives ONLY inside the call\n overlay's banner. */\n.voice-button-icon i {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon:hover:not(:disabled) i {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n/* Voice OPTIONS caret \u2014 a slim chevron hugging the phone button. Opens the agent/model\n picker; intentionally quieter (smaller icon, narrower hit area) than the phone so the\n common instant-start click stays the visual primary. */\n.voice-options-button-icon {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon i {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon:hover:not(:disabled) i {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n"] }]
|
|
272
274
|
}], null, { mentionEditor: [{
|
|
273
275
|
type: ViewChild,
|
|
274
276
|
args: ['mentionEditor']
|
|
@@ -294,11 +296,15 @@ export class MessageInputBoxComponent {
|
|
|
294
296
|
type: Input
|
|
295
297
|
}], acceptedFileTypes: [{
|
|
296
298
|
type: Input
|
|
297
|
-
}],
|
|
299
|
+
}], enableRealtime: [{
|
|
298
300
|
type: Input
|
|
299
301
|
}], voiceActive: [{
|
|
300
302
|
type: Input
|
|
301
|
-
}],
|
|
303
|
+
}], canStartRealtime: [{
|
|
304
|
+
type: Input
|
|
305
|
+
}], enablePlanMode: [{
|
|
306
|
+
type: Input
|
|
307
|
+
}], planModeActive: [{
|
|
302
308
|
type: Input
|
|
303
309
|
}], textSubmitted: [{
|
|
304
310
|
type: Output
|
|
@@ -310,12 +316,12 @@ export class MessageInputBoxComponent {
|
|
|
310
316
|
type: Output
|
|
311
317
|
}], attachmentClicked: [{
|
|
312
318
|
type: Output
|
|
313
|
-
}], artifactPickerRequested: [{
|
|
314
|
-
type: Output
|
|
315
319
|
}], voiceRequested: [{
|
|
316
320
|
type: Output
|
|
317
321
|
}], voiceOptionsRequested: [{
|
|
318
322
|
type: Output
|
|
323
|
+
}], planModeToggle: [{
|
|
324
|
+
type: Output
|
|
319
325
|
}] }); })();
|
|
320
326
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputBoxComponent, { className: "MessageInputBoxComponent", filePath: "src/lib/components/message/message-input-box.component.ts", lineNumber: 27 }); })();
|
|
321
327
|
//# sourceMappingURL=message-input-box.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-input-box.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts","../../../../src/lib/components/message/message-input-box.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { MentionSuggestion } from '../../services/mention-autocomplete.service';\nimport { MentionEditorComponent, PendingAttachment } from '../mention/mention-editor.component';\n\n/**\n * Reusable message input box component (presentational)\n * Now uses MentionEditorComponent for rich @mention functionality with chips\n *\n * Handles:\n * - Text input with keyboard shortcuts via MentionEditorComponent\n * - @mention autocomplete with visual chips (contentEditable)\n * - Send button\n *\n * Does NOT handle:\n * - Saving messages to database\n * - Agent invocation\n * - Artifact creation\n * - Conversation management\n */\n@Component({\n standalone: false,\n selector: 'mj-message-input-box',\n templateUrl: './message-input-box.component.html',\n styleUrls: ['./message-input-box.component.css']\n})\nexport class MessageInputBoxComponent {\n @ViewChild('mentionEditor') mentionEditor?: MentionEditorComponent;\n\n @Input() placeholder: string = 'Type your message to start a new conversation...';\n @Input() disabled: boolean = false;\n @Input() value: string = '';\n @Input() showCharacterCount: boolean = false;\n @Input() enableMentions: boolean = true;\n @Input() currentUser?: UserInfo;\n @Input() rows: number = 3;\n\n // Attachment settings\n @Input() enableAttachments: boolean = true;\n @Input() maxAttachments: number = 10;\n @Input() maxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() acceptedFileTypes: string = 'image/*';\n\n /** Shows the in-composer mic button when true. */\n @Input() enableVoice: boolean = false;\n /** Whether a realtime voice session is currently active (mic renders in its active state). */\n @Input() voiceActive: boolean = false;\n /** Whether a voice session can be started right now (mic disabled when false). */\n @Input() canStartVoice: boolean = true;\n\n @Output() textSubmitted = new EventEmitter<string>();\n @Output() valueChange = new EventEmitter<string>();\n @Output() attachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() attachmentError = new EventEmitter<string>();\n @Output() attachmentClicked = new EventEmitter<PendingAttachment>();\n @Output() artifactPickerRequested = new EventEmitter<void>();\n /** Emitted when the user clicks the mic button to start/stop a voice session. */\n @Output() voiceRequested = new EventEmitter<void>();\n /**\n * Emitted when the user clicks the small caret next to the phone button — the host opens the\n * voice agent/model picker so call options (which agent, which voice model) stay reachable\n * without adding friction to the plain phone click's instant-start path.\n */\n @Output() voiceOptionsRequested = new EventEmitter<void>();\n\n onVoiceClick(): void {\n this.voiceRequested.emit();\n }\n\n onVoiceOptionsClick(): void {\n this.voiceOptionsRequested.emit();\n }\n\n get canSend(): boolean {\n const hasText = this.value.trim().length > 0;\n const hasAttachments = this.mentionEditor?.hasAttachments() || false;\n return !this.disabled && (hasText || hasAttachments);\n }\n\n /**\n * Handle value changes from MentionEditorComponent\n */\n onValueChange(newValue: string): void {\n this.value = newValue;\n this.valueChange.emit(this.value);\n }\n\n /**\n * Handle attachment changes from MentionEditorComponent\n */\n onAttachmentsChanged(attachments: PendingAttachment[]): void {\n this.attachmentsChanged.emit(attachments);\n }\n\n /**\n * Handle attachment errors from MentionEditorComponent\n */\n onAttachmentError(error: string): void {\n this.attachmentError.emit(error);\n }\n\n /**\n * Handle attachment click from MentionEditorComponent\n */\n onAttachmentClicked(attachment: PendingAttachment): void {\n this.attachmentClicked.emit(attachment);\n }\n\n /**\n * Handle Enter key from MentionEditorComponent\n * Extracts plain text with JSON-encoded mentions for message submission\n */\n onEnterPressed(_text: string): void {\n this.onSendClick();\n }\n\n /**\n * Handle mention selection from MentionEditorComponent\n */\n onMentionSelected(suggestion: MentionSuggestion): void {\n // MentionEditorComponent already inserts the mention chip\n // This is just for additional tracking/analytics if needed\n }\n\n /**\n * Send the message\n * Extracts plain text with JSON-encoded mentions for proper persistence\n */\n onSendClick(): void {\n if (this.canSend) {\n // Get plain text with JSON-encoded mentions (preserves configuration info)\n const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.value.trim();\n this.textSubmitted.emit(textToSend);\n this.value = ''; // Clear input after sending\n\n // Clear the editor content\n if (this.mentionEditor) {\n this.mentionEditor.clear();\n }\n\n this.valueChange.emit(this.value);\n }\n }\n\n /**\n * Handle clicks on the container - focus the mention editor\n * Only moves cursor to end if clicking outside the contentEditable area\n */\n onContainerClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n\n // Don't handle clicks on the send button\n if (target.closest('.send-button-icon')) {\n return;\n }\n\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (!editor) return;\n\n // If clicking directly on the editor or its children, let the browser handle cursor placement\n if (target === editor || editor.contains(target)) {\n return;\n }\n\n // Only if clicking on the container (empty space), focus and move cursor to end\n editor.focus();\n const selection = window.getSelection();\n const range = document.createRange();\n\n if (selection) {\n range.selectNodeContents(editor);\n range.collapse(false); // Collapse to end\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n\n /**\n * Public method to focus the input programmatically\n */\n focus(): void {\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (editor) {\n editor.focus();\n }\n }\n\n /**\n * Get mention chip data including configuration presets\n */\n getMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.mentionEditor?.getMentionChipsData() || [];\n }\n\n /**\n * Get pending attachments from the editor\n */\n getPendingAttachments(): PendingAttachment[] {\n return this.mentionEditor?.getPendingAttachments() || [];\n }\n\n /**\n * Open file picker programmatically\n */\n openFilePicker(): void {\n this.mentionEditor?.openFilePicker();\n }\n\n /**\n * Open artifact picker - emits event for parent to handle.\n *\n * TODO (2026-04-15): no consumer currently handles `artifactPickerRequested`.\n * The prior handler was removed by commit 0a4612abf1 and the orphaned\n * template was cleaned up in 7a063fc12a. The template button is disabled\n * to signal the gap. See message-input-box.component.html for the TODO\n * describing the suggested picker implementation.\n */\n openArtifactPicker(): void {\n this.artifactPickerRequested.emit();\n }\n\n /**\n * Add an artifact as a pending attachment (called by parent after artifact selection)\n */\n AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.mentionEditor?.AddArtifactAttachment(artifact);\n }\n}\n","<div class=\"message-input-box-container\" (click)=\"onContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [currentUser]=\"currentUser\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [(ngModel)]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (enterPressed)=\"onEnterPressed($event)\"\n (mentionSelected)=\"onMentionSelected($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-mention-editor>\n\n <!-- Attach + voice buttons - Positioned over editor -->\n @if (enableAttachments || enableVoice) {\n <div class=\"attach-buttons\">\n @if (enableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"disabled\"\n (click)=\"openFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n <!--\n TODO: \"Attach artifact from library\" button is not yet wired.\n\n Current state (2026-04-15): emits `artifactPickerRequested` but no\n consumer handles the event (handler was removed by commit 0a4612abf1,\n orphaned template cleaned up in 7a063fc12a). Button is intentionally\n visible but disabled so it's obvious what's missing.\n\n To finish: build a picker modal (suggested approach: wrap the\n `<mj-tree-dropdown>` used in dashboard-viewer's artifact-config-panel)\n and on selection, attach the artifact version as a Direction='Input'\n MJConversationDetailArtifact junction on the outgoing message.\n The infrastructure for agents reading input artifacts is already in\n place via AgentRunner.gatherConversationArtifacts().\n\n See also: packages/Angular/Generic/artifacts/src/lib/services/analyze-artifact.service.ts\n which does the similar end-to-end flow for standalone Analyze — the\n attach-to-draft path is a strict subset (no artifact creation, no\n conversation creation, just the junction).\n -->\n <button\n class=\"attach-button-icon attach-artifact-button\"\n [disabled]=\"true\"\n (click)=\"openArtifactPicker(); $event.stopPropagation()\"\n title=\"Attach artifact from library — not yet wired (see message-input-box.component.html TODO)\"\n >\n <i class=\"fa-solid fa-cube\"></i>\n </button>\n }\n @if (enableVoice) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"voiceActive\"\n [disabled]=\"!canStartVoice\"\n (click)=\"onVoiceClick(); $event.stopPropagation()\"\n [title]=\"voiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!canStartVoice\"\n (click)=\"onVoiceOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!canSend\"\n (click)=\"onSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"message-input-box.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts","../../../../src/lib/components/message/message-input-box.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { MentionSuggestion } from '../../services/mention-autocomplete.service';\nimport { MentionEditorComponent, PendingAttachment } from '../mention/mention-editor.component';\n\n/**\n * Reusable message input box component (presentational)\n * Now uses MentionEditorComponent for rich @mention functionality with chips\n *\n * Handles:\n * - Text input with keyboard shortcuts via MentionEditorComponent\n * - @mention autocomplete with visual chips (contentEditable)\n * - Send button\n *\n * Does NOT handle:\n * - Saving messages to database\n * - Agent invocation\n * - Artifact creation\n * - Conversation management\n */\n@Component({\n standalone: false,\n selector: 'mj-message-input-box',\n templateUrl: './message-input-box.component.html',\n styleUrls: ['./message-input-box.component.css']\n})\nexport class MessageInputBoxComponent {\n @ViewChild('mentionEditor') mentionEditor?: MentionEditorComponent;\n\n @Input() placeholder: string = 'Type your message to start a new conversation...';\n @Input() disabled: boolean = false;\n @Input() value: string = '';\n @Input() showCharacterCount: boolean = false;\n @Input() enableMentions: boolean = true;\n @Input() currentUser?: UserInfo;\n @Input() rows: number = 3;\n\n // Attachment settings\n @Input() enableAttachments: boolean = true;\n @Input() maxAttachments: number = 10;\n @Input() maxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() acceptedFileTypes: string = 'image/*';\n\n /** Shows the in-composer mic button when true. */\n @Input() enableRealtime: boolean = false;\n /** Whether a realtime voice session is currently active (mic renders in its active state). */\n @Input() voiceActive: boolean = false;\n /** Whether a voice session can be started right now (mic disabled when false). */\n @Input() canStartRealtime: boolean = true;\n /** Shows the in-composer Plan Mode toggle button when true. */\n @Input() enablePlanMode: boolean = false;\n /** Current Plan Mode toggle state (renders the button in its active state). */\n @Input() planModeActive: boolean = false;\n\n @Output() textSubmitted = new EventEmitter<string>();\n @Output() valueChange = new EventEmitter<string>();\n @Output() attachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() attachmentError = new EventEmitter<string>();\n @Output() attachmentClicked = new EventEmitter<PendingAttachment>();\n /** Emitted when the user clicks the mic button to start/stop a voice session. */\n @Output() voiceRequested = new EventEmitter<void>();\n /**\n * Emitted when the user clicks the small caret next to the phone button — the host opens the\n * voice agent/model picker so call options (which agent, which voice model) stay reachable\n * without adding friction to the plain phone click's instant-start path.\n */\n @Output() voiceOptionsRequested = new EventEmitter<void>();\n /** Emitted when the user clicks the in-composer Plan Mode toggle button. */\n @Output() planModeToggle = new EventEmitter<void>();\n\n onRealtimeClick(): void {\n this.voiceRequested.emit();\n }\n\n onRealtimeOptionsClick(): void {\n this.voiceOptionsRequested.emit();\n }\n\n get canSend(): boolean {\n const hasText = this.value.trim().length > 0;\n const hasAttachments = this.mentionEditor?.hasAttachments() || false;\n return !this.disabled && (hasText || hasAttachments);\n }\n\n /**\n * Handle value changes from MentionEditorComponent\n */\n onValueChange(newValue: string): void {\n this.value = newValue;\n this.valueChange.emit(this.value);\n }\n\n /**\n * Handle attachment changes from MentionEditorComponent\n */\n onAttachmentsChanged(attachments: PendingAttachment[]): void {\n this.attachmentsChanged.emit(attachments);\n }\n\n /**\n * Handle attachment errors from MentionEditorComponent\n */\n onAttachmentError(error: string): void {\n this.attachmentError.emit(error);\n }\n\n /**\n * Handle attachment click from MentionEditorComponent\n */\n onAttachmentClicked(attachment: PendingAttachment): void {\n this.attachmentClicked.emit(attachment);\n }\n\n /**\n * Handle Enter key from MentionEditorComponent\n * Extracts plain text with JSON-encoded mentions for message submission\n */\n onEnterPressed(_text: string): void {\n this.onSendClick();\n }\n\n /**\n * Handle mention selection from MentionEditorComponent\n */\n onMentionSelected(suggestion: MentionSuggestion): void {\n // MentionEditorComponent already inserts the mention chip\n // This is just for additional tracking/analytics if needed\n }\n\n /**\n * Send the message\n * Extracts plain text with JSON-encoded mentions for proper persistence\n */\n onSendClick(): void {\n if (this.canSend) {\n // Get plain text with JSON-encoded mentions (preserves configuration info)\n const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.value.trim();\n this.textSubmitted.emit(textToSend);\n this.value = ''; // Clear input after sending\n\n // Clear the editor content\n if (this.mentionEditor) {\n this.mentionEditor.clear();\n }\n\n this.valueChange.emit(this.value);\n }\n }\n\n /**\n * Handle clicks on the container - focus the mention editor\n * Only moves cursor to end if clicking outside the contentEditable area\n */\n onContainerClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n\n // Don't handle clicks on the send button\n if (target.closest('.send-button-icon')) {\n return;\n }\n\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (!editor) return;\n\n // If clicking directly on the editor or its children, let the browser handle cursor placement\n if (target === editor || editor.contains(target)) {\n return;\n }\n\n // Only if clicking on the container (empty space), focus and move cursor to end\n editor.focus();\n const selection = window.getSelection();\n const range = document.createRange();\n\n if (selection) {\n range.selectNodeContents(editor);\n range.collapse(false); // Collapse to end\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n\n /**\n * Public method to focus the input programmatically\n */\n focus(): void {\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (editor) {\n editor.focus();\n }\n }\n\n /**\n * Get mention chip data including configuration presets\n */\n getMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.mentionEditor?.getMentionChipsData() || [];\n }\n\n /**\n * Get pending attachments from the editor\n */\n getPendingAttachments(): PendingAttachment[] {\n return this.mentionEditor?.getPendingAttachments() || [];\n }\n\n /**\n * Open file picker programmatically\n */\n openFilePicker(): void {\n this.mentionEditor?.openFilePicker();\n }\n\n /**\n * Add an artifact as a pending attachment (called by parent after artifact selection)\n */\n AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.mentionEditor?.AddArtifactAttachment(artifact);\n }\n}\n","<div class=\"message-input-box-container\" (click)=\"onContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [currentUser]=\"currentUser\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [(ngModel)]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (enterPressed)=\"onEnterPressed($event)\"\n (mentionSelected)=\"onMentionSelected($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (enableAttachments || enableRealtime || enablePlanMode) {\n <div class=\"attach-buttons\">\n @if (enablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"planModeActive\"\n [disabled]=\"disabled\"\n [attr.aria-pressed]=\"planModeActive\"\n (click)=\"planModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"planModeActive ? 'Plan Mode ON — the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (enableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"disabled\"\n (click)=\"openFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (enableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"voiceActive\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeClick(); $event.stopPropagation()\"\n [title]=\"voiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!canSend\"\n (click)=\"onSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n"]}
|