@memberjunction/ng-conversations 6.2.0-edge.2 → 6.2.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -7
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +1 -0
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +14 -2
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.js +35 -4
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +632 -55
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +2748 -624
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
- package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
- package/dist/lib/components/conversation/forks-popover.component.js +164 -0
- package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
- package/dist/lib/components/export/export-modal.component.d.ts +7 -2
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +16 -3
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +121 -11
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +307 -106
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +178 -5
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +919 -306
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +92 -21
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +337 -52
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
- package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
- package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
- package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
- package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
- package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
- package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
- package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
- package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
- package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
- package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
- package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
- package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
- package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
- package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
- package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
- package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
- package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
- package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
- package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
- package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
- package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
- package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
- package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
- package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.js +28 -1
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
- package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
- package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
- package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
- package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
- package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
- package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
- package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
- package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
- package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- 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 +25 -12
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +22 -31
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +50 -63
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +30 -29
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +27 -5
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/events/chat-events.d.ts +25 -0
- package/dist/lib/events/chat-events.d.ts.map +1 -1
- package/dist/lib/events/chat-events.js +36 -0
- package/dist/lib/events/chat-events.js.map +1 -1
- package/dist/lib/models/agent-turn.model.d.ts +5 -0
- package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
- package/dist/lib/models/agent-turn.model.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +34 -8
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +82 -29
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts +0 -9
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +1 -32
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +12 -0
- package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.js +19 -0
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
- package/dist/lib/services/browser-recording-unload-guard.d.ts +30 -0
- package/dist/lib/services/browser-recording-unload-guard.d.ts.map +1 -0
- package/dist/lib/services/browser-recording-unload-guard.js +43 -0
- package/dist/lib/services/browser-recording-unload-guard.js.map +1 -0
- package/dist/lib/services/conversation-agent.service.d.ts +35 -11
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +65 -20
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +50 -9
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts +72 -22
- package/dist/lib/services/conversation-naming.d.ts.map +1 -1
- package/dist/lib/services/conversation-naming.js +84 -10
- package/dist/lib/services/conversation-naming.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts +13 -5
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +39 -19
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/dist/lib/services/export.service.d.ts +26 -9
- package/dist/lib/services/export.service.d.ts.map +1 -1
- package/dist/lib/services/export.service.js +61 -18
- package/dist/lib/services/export.service.js.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.d.ts +33 -5
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.js +71 -11
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-pairing.d.ts +10 -5
- package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
- package/dist/lib/services/realtime-pairing.js +15 -6
- package/dist/lib/services/realtime-pairing.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +3 -2
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +7 -2
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/search.service.d.ts +7 -2
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +13 -4
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/util/frame-zone.d.ts +10 -0
- package/dist/lib/util/frame-zone.d.ts.map +1 -0
- package/dist/lib/util/frame-zone.js +10 -0
- package/dist/lib/util/frame-zone.js.map +1 -0
- package/dist/lib/utils/conversation-branching.d.ts +4 -0
- package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
- package/dist/lib/utils/conversation-branching.js +5 -0
- package/dist/lib/utils/conversation-branching.js.map +1 -0
- package/dist/lib/utils/conversation-forks.d.ts +315 -0
- package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
- package/dist/lib/utils/conversation-forks.js +456 -0
- package/dist/lib/utils/conversation-forks.js.map +1 -0
- package/dist/public-api.d.ts +23 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +30 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +37 -32
- package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
- package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
- package/dist/lib/components/thread/thread-panel.component.js +0 -440
- package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
|
@@ -1,440 +0,0 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
-
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
3
|
-
import { RunView } from '@memberjunction/core';
|
|
4
|
-
import { Subject } from 'rxjs';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "../../services/data-cache.service";
|
|
7
|
-
import * as i2 from "@angular/forms";
|
|
8
|
-
const _forTrack0 = ($index, $item) => $item.ID;
|
|
9
|
-
function ThreadPanelComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
10
|
-
i0.ɵɵelementStart(0, "div", 7);
|
|
11
|
-
i0.ɵɵelement(1, "i", 9);
|
|
12
|
-
i0.ɵɵelementStart(2, "span");
|
|
13
|
-
i0.ɵɵtext(3, "Loading thread...");
|
|
14
|
-
i0.ɵɵelementEnd()();
|
|
15
|
-
} }
|
|
16
|
-
function ThreadPanelComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
17
|
-
i0.ɵɵelementStart(0, "div", 8);
|
|
18
|
-
i0.ɵɵelement(1, "i", 10);
|
|
19
|
-
i0.ɵɵelementStart(2, "span");
|
|
20
|
-
i0.ɵɵtext(3);
|
|
21
|
-
i0.ɵɵelementEnd()();
|
|
22
|
-
} if (rf & 2) {
|
|
23
|
-
const ctx_r0 = i0.ɵɵnextContext();
|
|
24
|
-
i0.ɵɵadvance(3);
|
|
25
|
-
i0.ɵɵtextInterpolate(ctx_r0.errorMessage);
|
|
26
|
-
} }
|
|
27
|
-
function ThreadPanelComponent_Conditional_11_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
28
|
-
i0.ɵɵelementStart(0, "div", 20);
|
|
29
|
-
i0.ɵɵelement(1, "i", 27);
|
|
30
|
-
i0.ɵɵelementStart(2, "span");
|
|
31
|
-
i0.ɵɵtext(3, "No replies yet. Be the first to reply!");
|
|
32
|
-
i0.ɵɵelementEnd()();
|
|
33
|
-
} }
|
|
34
|
-
function ThreadPanelComponent_Conditional_11_For_16_Template(rf, ctx) { if (rf & 1) {
|
|
35
|
-
i0.ɵɵelementStart(0, "div", 28)(1, "div", 29)(2, "span", 30);
|
|
36
|
-
i0.ɵɵtext(3);
|
|
37
|
-
i0.ɵɵelementEnd();
|
|
38
|
-
i0.ɵɵelementStart(4, "span", 31);
|
|
39
|
-
i0.ɵɵtext(5);
|
|
40
|
-
i0.ɵɵelementEnd()();
|
|
41
|
-
i0.ɵɵelementStart(6, "div", 32);
|
|
42
|
-
i0.ɵɵtext(7);
|
|
43
|
-
i0.ɵɵelementEnd()();
|
|
44
|
-
} if (rf & 2) {
|
|
45
|
-
const reply_r3 = ctx.$implicit;
|
|
46
|
-
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
47
|
-
i0.ɵɵclassProp("ai-reply", reply_r3.Role === "AI");
|
|
48
|
-
i0.ɵɵadvance(3);
|
|
49
|
-
i0.ɵɵtextInterpolate(ctx_r0.getSenderName(reply_r3));
|
|
50
|
-
i0.ɵɵadvance(2);
|
|
51
|
-
i0.ɵɵtextInterpolate(ctx_r0.getMessageTime(reply_r3));
|
|
52
|
-
i0.ɵɵadvance(2);
|
|
53
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r0.getMessageText(reply_r3), " ");
|
|
54
|
-
} }
|
|
55
|
-
function ThreadPanelComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
56
|
-
const _r2 = i0.ɵɵgetCurrentView();
|
|
57
|
-
i0.ɵɵelementStart(0, "div", 11)(1, "div", 12)(2, "div", 13)(3, "span", 14);
|
|
58
|
-
i0.ɵɵtext(4);
|
|
59
|
-
i0.ɵɵelementEnd();
|
|
60
|
-
i0.ɵɵelementStart(5, "span", 15);
|
|
61
|
-
i0.ɵɵtext(6);
|
|
62
|
-
i0.ɵɵelementEnd()();
|
|
63
|
-
i0.ɵɵelementStart(7, "div", 16);
|
|
64
|
-
i0.ɵɵtext(8);
|
|
65
|
-
i0.ɵɵelementEnd();
|
|
66
|
-
i0.ɵɵelementStart(9, "div", 17);
|
|
67
|
-
i0.ɵɵelement(10, "i", 18);
|
|
68
|
-
i0.ɵɵelementStart(11, "span");
|
|
69
|
-
i0.ɵɵtext(12);
|
|
70
|
-
i0.ɵɵelementEnd()()();
|
|
71
|
-
i0.ɵɵelementStart(13, "div", 19);
|
|
72
|
-
i0.ɵɵconditionalCreate(14, ThreadPanelComponent_Conditional_11_Conditional_14_Template, 4, 0, "div", 20);
|
|
73
|
-
i0.ɵɵrepeaterCreate(15, ThreadPanelComponent_Conditional_11_For_16_Template, 8, 5, "div", 21, _forTrack0);
|
|
74
|
-
i0.ɵɵelementEnd()();
|
|
75
|
-
i0.ɵɵelementStart(17, "div", 22)(18, "textarea", 23);
|
|
76
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ThreadPanelComponent_Conditional_11_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.replyText, $event) || (ctx_r0.replyText = $event); return i0.ɵɵresetView($event); });
|
|
77
|
-
i0.ɵɵlistener("keydown.control.enter", function ThreadPanelComponent_Conditional_11_Template_textarea_keydown_control_enter_18_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); })("keydown.meta.enter", function ThreadPanelComponent_Conditional_11_Template_textarea_keydown_meta_enter_18_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); });
|
|
78
|
-
i0.ɵɵtext(19, " ");
|
|
79
|
-
i0.ɵɵelementEnd();
|
|
80
|
-
i0.ɵɵelementStart(20, "div", 24)(21, "button", 25);
|
|
81
|
-
i0.ɵɵlistener("click", function ThreadPanelComponent_Conditional_11_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); });
|
|
82
|
-
i0.ɵɵelement(22, "i", 26);
|
|
83
|
-
i0.ɵɵelementStart(23, "span");
|
|
84
|
-
i0.ɵɵtext(24);
|
|
85
|
-
i0.ɵɵelementEnd()()()();
|
|
86
|
-
} if (rf & 2) {
|
|
87
|
-
const ctx_r0 = i0.ɵɵnextContext();
|
|
88
|
-
i0.ɵɵadvance(4);
|
|
89
|
-
i0.ɵɵtextInterpolate(ctx_r0.getSenderName(ctx_r0.parentMessage));
|
|
90
|
-
i0.ɵɵadvance(2);
|
|
91
|
-
i0.ɵɵtextInterpolate(ctx_r0.getMessageTime(ctx_r0.parentMessage));
|
|
92
|
-
i0.ɵɵadvance(2);
|
|
93
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r0.getMessageText(ctx_r0.parentMessage), " ");
|
|
94
|
-
i0.ɵɵadvance(4);
|
|
95
|
-
i0.ɵɵtextInterpolate(ctx_r0.replyCountText);
|
|
96
|
-
i0.ɵɵadvance(2);
|
|
97
|
-
i0.ɵɵconditional(ctx_r0.replies.length === 0 ? 14 : -1);
|
|
98
|
-
i0.ɵɵadvance();
|
|
99
|
-
i0.ɵɵrepeater(ctx_r0.replies);
|
|
100
|
-
i0.ɵɵadvance(3);
|
|
101
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r0.replyText);
|
|
102
|
-
i0.ɵɵproperty("disabled", ctx_r0.isSending);
|
|
103
|
-
i0.ɵɵadvance(3);
|
|
104
|
-
i0.ɵɵproperty("disabled", !ctx_r0.canSendReply);
|
|
105
|
-
i0.ɵɵadvance(3);
|
|
106
|
-
i0.ɵɵtextInterpolate(ctx_r0.isSending ? "Sending..." : "Reply");
|
|
107
|
-
} }
|
|
108
|
-
/**
|
|
109
|
-
* Side panel component for displaying and managing threaded message replies
|
|
110
|
-
* Shows parent message at top with all replies in chronological order
|
|
111
|
-
*/
|
|
112
|
-
export class ThreadPanelComponent extends BaseAngularComponent {
|
|
113
|
-
dataCache;
|
|
114
|
-
cdRef;
|
|
115
|
-
ParentMessageId;
|
|
116
|
-
/** @deprecated Use {@link ParentMessageId}. */
|
|
117
|
-
set parentMessageId(value) {
|
|
118
|
-
this.ParentMessageId = value;
|
|
119
|
-
}
|
|
120
|
-
/** @deprecated Use {@link ParentMessageId}. */
|
|
121
|
-
get parentMessageId() {
|
|
122
|
-
return this.ParentMessageId;
|
|
123
|
-
}
|
|
124
|
-
ConversationId;
|
|
125
|
-
/** @deprecated Use {@link ConversationId}. */
|
|
126
|
-
set conversationId(value) {
|
|
127
|
-
this.ConversationId = value;
|
|
128
|
-
}
|
|
129
|
-
/** @deprecated Use {@link ConversationId}. */
|
|
130
|
-
get conversationId() {
|
|
131
|
-
return this.ConversationId;
|
|
132
|
-
}
|
|
133
|
-
CurrentUser;
|
|
134
|
-
/** @deprecated Use {@link CurrentUser}. */
|
|
135
|
-
set currentUser(value) {
|
|
136
|
-
this.CurrentUser = value;
|
|
137
|
-
}
|
|
138
|
-
/** @deprecated Use {@link CurrentUser}. */
|
|
139
|
-
get currentUser() {
|
|
140
|
-
return this.CurrentUser;
|
|
141
|
-
}
|
|
142
|
-
Closed = new EventEmitter();
|
|
143
|
-
/**
|
|
144
|
-
* @deprecated Use {@link Closed}.
|
|
145
|
-
*
|
|
146
|
-
* The same emitter under the old binding name, so a template still binding
|
|
147
|
-
* (closed) keeps working. Must stay AFTER Closed: class fields
|
|
148
|
-
* initialise in order, and the other way round this captures undefined.
|
|
149
|
-
*/
|
|
150
|
-
closed = this.Closed;
|
|
151
|
-
ReplyAdded = new EventEmitter();
|
|
152
|
-
/**
|
|
153
|
-
* @deprecated Use {@link ReplyAdded}.
|
|
154
|
-
*
|
|
155
|
-
* The same emitter under the old binding name, so a template still binding
|
|
156
|
-
* (replyAdded) keeps working. Must stay AFTER ReplyAdded: class fields
|
|
157
|
-
* initialise in order, and the other way round this captures undefined.
|
|
158
|
-
*/
|
|
159
|
-
replyAdded = this.ReplyAdded;
|
|
160
|
-
ParentMessage = null;
|
|
161
|
-
/** @deprecated Use {@link ParentMessage}. */
|
|
162
|
-
get parentMessage() {
|
|
163
|
-
return this.ParentMessage;
|
|
164
|
-
}
|
|
165
|
-
/** @deprecated Use {@link ParentMessage}. */
|
|
166
|
-
set parentMessage(value) {
|
|
167
|
-
this.ParentMessage = value;
|
|
168
|
-
}
|
|
169
|
-
Replies = [];
|
|
170
|
-
/** @deprecated Use {@link Replies}. */
|
|
171
|
-
get replies() {
|
|
172
|
-
return this.Replies;
|
|
173
|
-
}
|
|
174
|
-
/** @deprecated Use {@link Replies}. */
|
|
175
|
-
set replies(value) {
|
|
176
|
-
this.Replies = value;
|
|
177
|
-
}
|
|
178
|
-
ReplyText = '';
|
|
179
|
-
/** @deprecated Use {@link ReplyText}. */
|
|
180
|
-
get replyText() {
|
|
181
|
-
return this.ReplyText;
|
|
182
|
-
}
|
|
183
|
-
/** @deprecated Use {@link ReplyText}. */
|
|
184
|
-
set replyText(value) {
|
|
185
|
-
this.ReplyText = value;
|
|
186
|
-
}
|
|
187
|
-
isLoading = false;
|
|
188
|
-
IsSending = false;
|
|
189
|
-
/** @deprecated Use {@link IsSending}. */
|
|
190
|
-
get isSending() {
|
|
191
|
-
return this.IsSending;
|
|
192
|
-
}
|
|
193
|
-
/** @deprecated Use {@link IsSending}. */
|
|
194
|
-
set isSending(value) {
|
|
195
|
-
this.IsSending = value;
|
|
196
|
-
}
|
|
197
|
-
errorMessage = '';
|
|
198
|
-
destroy$ = new Subject();
|
|
199
|
-
constructor(dataCache, cdRef) {
|
|
200
|
-
super();
|
|
201
|
-
this.dataCache = dataCache;
|
|
202
|
-
this.cdRef = cdRef;
|
|
203
|
-
}
|
|
204
|
-
async ngOnInit() {
|
|
205
|
-
this.dataCache.Provider = this.ProviderToUse;
|
|
206
|
-
await this.loadThreadData();
|
|
207
|
-
}
|
|
208
|
-
ngOnDestroy() {
|
|
209
|
-
this.destroy$.next();
|
|
210
|
-
this.destroy$.complete();
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Loads the parent message and all replies
|
|
214
|
-
*/
|
|
215
|
-
async loadThreadData() {
|
|
216
|
-
this.isLoading = true;
|
|
217
|
-
this.errorMessage = '';
|
|
218
|
-
try {
|
|
219
|
-
// Load parent message from cache
|
|
220
|
-
const parent = await this.dataCache.getConversationDetail(this.ParentMessageId, this.CurrentUser);
|
|
221
|
-
if (!parent) {
|
|
222
|
-
this.errorMessage = 'Failed to load parent message';
|
|
223
|
-
this.isLoading = false;
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
this.ParentMessage = parent;
|
|
227
|
-
// Load all replies
|
|
228
|
-
await this.loadReplies();
|
|
229
|
-
}
|
|
230
|
-
catch (error) {
|
|
231
|
-
console.error('Error loading thread data:', error);
|
|
232
|
-
this.errorMessage = 'Error loading thread. Please try again.';
|
|
233
|
-
}
|
|
234
|
-
finally {
|
|
235
|
-
this.isLoading = false;
|
|
236
|
-
this.cdRef.detectChanges();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Loads all replies for the parent message
|
|
241
|
-
*/
|
|
242
|
-
async loadReplies() {
|
|
243
|
-
try {
|
|
244
|
-
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
245
|
-
const result = await rv.RunView({
|
|
246
|
-
EntityName: 'MJ: Conversation Details',
|
|
247
|
-
ExtraFilter: `ParentID='${this.ParentMessageId}'`,
|
|
248
|
-
OrderBy: '__mj_CreatedAt ASC',
|
|
249
|
-
ResultType: 'entity_object'
|
|
250
|
-
}, this.CurrentUser);
|
|
251
|
-
if (result.Success) {
|
|
252
|
-
this.Replies = result.Results || [];
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
console.error('Failed to load replies:', result.ErrorMessage);
|
|
256
|
-
this.errorMessage = 'Failed to load replies';
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
console.error('Error loading replies:', error);
|
|
261
|
-
this.errorMessage = 'Error loading replies';
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Handles sending a new reply
|
|
266
|
-
*/
|
|
267
|
-
async OnSendReply() {
|
|
268
|
-
if (!this.CanSendReply)
|
|
269
|
-
return;
|
|
270
|
-
this.IsSending = true;
|
|
271
|
-
this.errorMessage = '';
|
|
272
|
-
try {
|
|
273
|
-
const reply = await this.dataCache.createConversationDetail(this.CurrentUser);
|
|
274
|
-
reply.ConversationID = this.ConversationId;
|
|
275
|
-
reply.ParentID = this.ParentMessageId;
|
|
276
|
-
reply.Message = this.ReplyText.trim();
|
|
277
|
-
reply.Role = 'User';
|
|
278
|
-
const saved = await reply.Save();
|
|
279
|
-
if (saved) {
|
|
280
|
-
// Add to local list
|
|
281
|
-
this.Replies = [...this.Replies, reply];
|
|
282
|
-
this.ReplyText = '';
|
|
283
|
-
// Emit event to parent
|
|
284
|
-
this.ReplyAdded.emit(reply);
|
|
285
|
-
// Update parent message thread count
|
|
286
|
-
if (this.ParentMessage) {
|
|
287
|
-
this.ParentMessage.ThreadCount = (this.ParentMessage.ThreadCount || 0) + 1; // TODO: ThreadCount field doesn't exist on MJConversationDetailEntity yet
|
|
288
|
-
}
|
|
289
|
-
this.cdRef.detectChanges();
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
console.error('Failed to save reply:', reply.LatestResult?.Message);
|
|
293
|
-
this.errorMessage = 'Failed to send reply. Please try again.';
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
catch (error) {
|
|
297
|
-
console.error('Error sending reply:', error);
|
|
298
|
-
this.errorMessage = 'Error sending reply. Please try again.';
|
|
299
|
-
}
|
|
300
|
-
finally {
|
|
301
|
-
this.IsSending = false;
|
|
302
|
-
this.cdRef.detectChanges();
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
/** @deprecated Use {@link OnSendReply}. */
|
|
306
|
-
async onSendReply() {
|
|
307
|
-
return this.OnSendReply();
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Handles closing the thread panel
|
|
311
|
-
*/
|
|
312
|
-
OnClose() {
|
|
313
|
-
this.Closed.emit();
|
|
314
|
-
}
|
|
315
|
-
/** @deprecated Use {@link OnClose}. */
|
|
316
|
-
onClose() {
|
|
317
|
-
return this.OnClose();
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Gets the display text for a message
|
|
321
|
-
*/
|
|
322
|
-
GetMessageText(message) {
|
|
323
|
-
return message.Message || '';
|
|
324
|
-
}
|
|
325
|
-
/** @deprecated Use {@link GetMessageText}. */
|
|
326
|
-
getMessageText(message) {
|
|
327
|
-
return this.GetMessageText(message);
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Gets the timestamp display for a message
|
|
331
|
-
*/
|
|
332
|
-
GetMessageTime(message) {
|
|
333
|
-
if (!message.__mj_CreatedAt)
|
|
334
|
-
return '';
|
|
335
|
-
const date = new Date(message.__mj_CreatedAt);
|
|
336
|
-
const now = new Date();
|
|
337
|
-
const diffMs = now.getTime() - date.getTime();
|
|
338
|
-
const diffMins = Math.floor(diffMs / 60000);
|
|
339
|
-
const diffHours = Math.floor(diffMs / 3600000);
|
|
340
|
-
const diffDays = Math.floor(diffMs / 86400000);
|
|
341
|
-
if (diffMins < 1)
|
|
342
|
-
return 'Just now';
|
|
343
|
-
if (diffMins < 60)
|
|
344
|
-
return `${diffMins}m ago`;
|
|
345
|
-
if (diffHours < 24)
|
|
346
|
-
return `${diffHours}h ago`;
|
|
347
|
-
if (diffDays < 7)
|
|
348
|
-
return `${diffDays}d ago`;
|
|
349
|
-
return date.toLocaleDateString();
|
|
350
|
-
}
|
|
351
|
-
/** @deprecated Use {@link GetMessageTime}. */
|
|
352
|
-
getMessageTime(message) {
|
|
353
|
-
return this.GetMessageTime(message);
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Gets the sender name for a message
|
|
357
|
-
*/
|
|
358
|
-
GetSenderName(message) {
|
|
359
|
-
if (message.Role === 'AI')
|
|
360
|
-
return 'AI Assistant';
|
|
361
|
-
return message.User || 'User';
|
|
362
|
-
}
|
|
363
|
-
/** @deprecated Use {@link GetSenderName}. */
|
|
364
|
-
getSenderName(message) {
|
|
365
|
-
return this.GetSenderName(message);
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Checks if current user can send reply
|
|
369
|
-
*/
|
|
370
|
-
get CanSendReply() {
|
|
371
|
-
return !this.IsSending && !this.isLoading && this.ReplyText.trim().length > 0;
|
|
372
|
-
}
|
|
373
|
-
/** @deprecated Use {@link CanSendReply}. */
|
|
374
|
-
get canSendReply() {
|
|
375
|
-
return this.CanSendReply;
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Gets the reply count text
|
|
379
|
-
*/
|
|
380
|
-
get ReplyCountText() {
|
|
381
|
-
const count = this.Replies.length;
|
|
382
|
-
return count === 1 ? '1 reply' : `${count} replies`;
|
|
383
|
-
}
|
|
384
|
-
/** @deprecated Use {@link ReplyCountText}. */
|
|
385
|
-
get replyCountText() {
|
|
386
|
-
return this.ReplyCountText;
|
|
387
|
-
}
|
|
388
|
-
static ɵfac = function ThreadPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ThreadPanelComponent)(i0.ɵɵdirectiveInject(i1.DataCacheService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
389
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ThreadPanelComponent, selectors: [["mj-thread-panel"]], inputs: { ParentMessageId: "ParentMessageId", parentMessageId: "parentMessageId", ConversationId: "ConversationId", conversationId: "conversationId", CurrentUser: "CurrentUser", currentUser: "currentUser" }, outputs: { Closed: "Closed", closed: "closed", ReplyAdded: "ReplyAdded", replyAdded: "replyAdded" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 3, consts: [[1, "thread-panel-overlay", 3, "click"], [1, "thread-panel"], [1, "thread-header"], [1, "thread-title"], [1, "fa-solid", "fa-comments"], ["title", "Close thread", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "thread-loading"], [1, "thread-error"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-exclamation-circle"], [1, "thread-content"], [1, "parent-message"], [1, "message-header"], [1, "message-sender"], [1, "message-time"], [1, "message-body"], [1, "reply-count"], [1, "fa-solid", "fa-reply"], [1, "replies-container"], [1, "no-replies"], [1, "reply-item", 3, "ai-reply"], [1, "reply-input-container"], ["placeholder", "Reply to thread...", "rows", "3", 1, "reply-input", 3, "ngModelChange", "keydown.control.enter", "keydown.meta.enter", "ngModel", "disabled"], [1, "reply-actions"], [1, "btn-send-reply", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], [1, "fa-solid", "fa-message"], [1, "reply-item"], [1, "reply-header"], [1, "reply-sender"], [1, "reply-time"], [1, "reply-body"]], template: function ThreadPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
390
|
-
i0.ɵɵelementStart(0, "div", 0);
|
|
391
|
-
i0.ɵɵlistener("click", function ThreadPanelComponent_Template_div_click_0_listener() { return ctx.onClose(); });
|
|
392
|
-
i0.ɵɵelementEnd();
|
|
393
|
-
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
394
|
-
i0.ɵɵelement(4, "i", 4);
|
|
395
|
-
i0.ɵɵelementStart(5, "span");
|
|
396
|
-
i0.ɵɵtext(6, "Thread");
|
|
397
|
-
i0.ɵɵelementEnd()();
|
|
398
|
-
i0.ɵɵelementStart(7, "button", 5);
|
|
399
|
-
i0.ɵɵlistener("click", function ThreadPanelComponent_Template_button_click_7_listener() { return ctx.onClose(); });
|
|
400
|
-
i0.ɵɵelement(8, "i", 6);
|
|
401
|
-
i0.ɵɵelementEnd()();
|
|
402
|
-
i0.ɵɵconditionalCreate(9, ThreadPanelComponent_Conditional_9_Template, 4, 0, "div", 7);
|
|
403
|
-
i0.ɵɵconditionalCreate(10, ThreadPanelComponent_Conditional_10_Template, 4, 1, "div", 8);
|
|
404
|
-
i0.ɵɵconditionalCreate(11, ThreadPanelComponent_Conditional_11_Template, 25, 9);
|
|
405
|
-
i0.ɵɵelementEnd();
|
|
406
|
-
} if (rf & 2) {
|
|
407
|
-
i0.ɵɵadvance(9);
|
|
408
|
-
i0.ɵɵconditional(ctx.isLoading ? 9 : -1);
|
|
409
|
-
i0.ɵɵadvance();
|
|
410
|
-
i0.ɵɵconditional(ctx.errorMessage && !ctx.isLoading ? 10 : -1);
|
|
411
|
-
i0.ɵɵadvance();
|
|
412
|
-
i0.ɵɵconditional(!ctx.isLoading && !ctx.errorMessage && ctx.parentMessage ? 11 : -1);
|
|
413
|
-
} }, dependencies: [i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel], styles: ["\n.thread-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: _ngcontent-%COMP%_fadeIn 200ms ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n.thread-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 450px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 250ms ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n\n.thread-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.thread-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 150ms ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n\n.thread-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px;\n color: var(--mj-text-secondary);\n}\n\n.thread-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n\n.thread-error[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-error);\n color: var(--mj-status-error);\n margin: 16px 20px;\n border-radius: 4px;\n}\n\n\n.thread-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n.parent-message[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 20px;\n}\n\n.message-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.message-sender[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.message-time[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.message-body[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n margin-bottom: 12px;\n}\n\n.reply-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.reply-count[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.replies-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.no-replies[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-replies[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n opacity: 0.5;\n}\n\n.no-replies[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n.reply-item[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 150ms ease;\n}\n\n.reply-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n.reply-item.ai-reply[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.reply-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.reply-sender[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.reply-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.reply-body[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 13px;\n}\n\n\n.reply-input-container[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.reply-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n min-height: 60px;\n transition: all 150ms ease;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n.reply-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.reply-input[_ngcontent-%COMP%]:disabled {\n background: var(--mj-bg-surface-sunken);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.reply-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-top: 10px;\n}\n\n.btn-send-reply[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-weight: 600;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.btn-send-reply[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.btn-send-reply[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.btn-send-reply[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 3px;\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}"] });
|
|
414
|
-
}
|
|
415
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ThreadPanelComponent, [{
|
|
416
|
-
type: Component,
|
|
417
|
-
args: [{ standalone: false, selector: 'mj-thread-panel', template: "<div class=\"thread-panel-overlay\" (click)=\"onClose()\"></div>\n\n<div class=\"thread-panel\">\n <div class=\"thread-header\">\n <div class=\"thread-title\">\n <i class=\"fa-solid fa-comments\"></i>\n <span>Thread</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close thread\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (isLoading) {\n <div class=\"thread-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading thread...</span>\n </div>\n }\n\n @if (errorMessage && !isLoading) {\n <div class=\"thread-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (!isLoading && !errorMessage && parentMessage) {\n <div class=\"thread-content\">\n <!-- Parent Message -->\n <div class=\"parent-message\">\n <div class=\"message-header\">\n <span class=\"message-sender\">{{ getSenderName(parentMessage) }}</span>\n <span class=\"message-time\">{{ getMessageTime(parentMessage) }}</span>\n </div>\n <div class=\"message-body\">\n {{ getMessageText(parentMessage) }}\n </div>\n <div class=\"reply-count\">\n <i class=\"fa-solid fa-reply\"></i>\n <span>{{ replyCountText }}</span>\n </div>\n </div>\n\n <!-- Replies List -->\n <div class=\"replies-container\">\n @if (replies.length === 0) {\n <div class=\"no-replies\">\n <i class=\"fa-solid fa-message\"></i>\n <span>No replies yet. Be the first to reply!</span>\n </div>\n }\n\n @for (reply of replies; track reply.ID) {\n <div class=\"reply-item\" [class.ai-reply]=\"reply.Role === 'AI'\">\n <div class=\"reply-header\">\n <span class=\"reply-sender\">{{ getSenderName(reply) }}</span>\n <span class=\"reply-time\">{{ getMessageTime(reply) }}</span>\n </div>\n <div class=\"reply-body\">\n {{ getMessageText(reply) }}\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Reply Input -->\n <div class=\"reply-input-container\">\n <textarea\n class=\"reply-input\"\n [(ngModel)]=\"replyText\"\n [disabled]=\"isSending\"\n placeholder=\"Reply to thread...\"\n rows=\"3\"\n (keydown.control.enter)=\"onSendReply()\"\n (keydown.meta.enter)=\"onSendReply()\">\n </textarea>\n <div class=\"reply-actions\">\n <button\n class=\"btn-send-reply\"\n [disabled]=\"!canSendReply\"\n (click)=\"onSendReply()\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>{{ isSending ? 'Sending...' : 'Reply' }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n", styles: ["/* Thread Panel Overlay */\n.thread-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeIn 200ms ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Thread Panel Container */\n.thread-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 450px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n animation: slideIn 250ms ease;\n}\n\n@keyframes slideIn {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n/* Header */\n.thread-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.thread-title i {\n color: var(--mj-text-secondary);\n}\n\n.close-btn {\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 150ms ease;\n}\n\n.close-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n/* Loading State */\n.thread-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px;\n color: var(--mj-text-secondary);\n}\n\n.thread-loading i {\n font-size: 24px;\n}\n\n/* Error State */\n.thread-error {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-error);\n color: var(--mj-status-error);\n margin: 16px 20px;\n border-radius: 4px;\n}\n\n/* Content Container */\n.thread-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Parent Message */\n.parent-message {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 20px;\n}\n\n.message-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.message-sender {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.message-time {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.message-body {\n color: var(--mj-text-primary);\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n margin-bottom: 12px;\n}\n\n.reply-count {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.reply-count i {\n font-size: 12px;\n}\n\n/* Replies Container */\n.replies-container {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.no-replies {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-replies i {\n font-size: 32px;\n opacity: 0.5;\n}\n\n.no-replies span {\n font-size: 14px;\n}\n\n/* Reply Item */\n.reply-item {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 150ms ease;\n}\n\n.reply-item:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n.reply-item.ai-reply {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.reply-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.reply-sender {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.reply-time {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.reply-body {\n color: var(--mj-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 13px;\n}\n\n/* Reply Input */\n.reply-input-container {\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.reply-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n min-height: 60px;\n transition: all 150ms ease;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n.reply-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.reply-input:disabled {\n background: var(--mj-bg-surface-sunken);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.reply-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 10px;\n}\n\n.btn-send-reply {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-weight: 600;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.btn-send-reply:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.btn-send-reply:disabled {\n background: var(--mj-border-default);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.btn-send-reply i {\n font-size: 12px;\n}\n\n/* Scrollbar Styling */\n.thread-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.thread-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 3px;\n}\n\n.thread-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n"] }]
|
|
418
|
-
}], () => [{ type: i1.DataCacheService }, { type: i0.ChangeDetectorRef }], { ParentMessageId: [{
|
|
419
|
-
type: Input
|
|
420
|
-
}], parentMessageId: [{
|
|
421
|
-
type: Input
|
|
422
|
-
}], ConversationId: [{
|
|
423
|
-
type: Input
|
|
424
|
-
}], conversationId: [{
|
|
425
|
-
type: Input
|
|
426
|
-
}], CurrentUser: [{
|
|
427
|
-
type: Input
|
|
428
|
-
}], currentUser: [{
|
|
429
|
-
type: Input
|
|
430
|
-
}], Closed: [{
|
|
431
|
-
type: Output
|
|
432
|
-
}], closed: [{
|
|
433
|
-
type: Output
|
|
434
|
-
}], ReplyAdded: [{
|
|
435
|
-
type: Output
|
|
436
|
-
}], replyAdded: [{
|
|
437
|
-
type: Output
|
|
438
|
-
}] }); })();
|
|
439
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ThreadPanelComponent, { className: "ThreadPanelComponent", filePath: "src/lib/components/thread/thread-panel.component.ts", lineNumber: 19 }); })();
|
|
440
|
-
//# sourceMappingURL=thread-panel.component.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thread-panel.component.js","sourceRoot":"","sources":["../../../../src/lib/components/thread/thread-panel.component.ts","../../../../src/lib/components/thread/thread-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJConversationDetailEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { DataCacheService } from '../../services/data-cache.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n/**\n * Side panel component for displaying and managing threaded message replies\n * Shows parent message at top with all replies in chronological order\n */\n@Component({\n standalone: false,\n selector: 'mj-thread-panel',\n templateUrl: './thread-panel.component.html',\n styleUrls: ['./thread-panel.component.css']\n})\nexport class ThreadPanelComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() ParentMessageId!: string;\n\n /** @deprecated Use {@link ParentMessageId}. */\n @Input() set parentMessageId(value: string) {\n this.ParentMessageId = value;\n }\n /** @deprecated Use {@link ParentMessageId}. */\n get parentMessageId(): string {\n return this.ParentMessageId;\n }\n @Input() ConversationId!: string;\n\n /** @deprecated Use {@link ConversationId}. */\n @Input() set conversationId(value: string) {\n this.ConversationId = value;\n }\n /** @deprecated Use {@link ConversationId}. */\n get conversationId(): string {\n return this.ConversationId;\n }\n @Input() CurrentUser!: UserInfo;\n\n /** @deprecated Use {@link CurrentUser}. */\n @Input() set currentUser(value: UserInfo) {\n this.CurrentUser = value;\n }\n /** @deprecated Use {@link CurrentUser}. */\n get currentUser(): UserInfo {\n return this.CurrentUser;\n }\n\n @Output() Closed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Closed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (closed) keeps working. Must stay AFTER Closed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() closed = this.Closed;\n @Output() ReplyAdded = new EventEmitter<MJConversationDetailEntity>();\n\n /**\n * @deprecated Use {@link ReplyAdded}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (replyAdded) keeps working. Must stay AFTER ReplyAdded: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() replyAdded = this.ReplyAdded;\n\n public ParentMessage: MJConversationDetailEntity | null = null;\n\n /** @deprecated Use {@link ParentMessage}. */\n public get parentMessage(): MJConversationDetailEntity | null {\n return this.ParentMessage;\n }\n /** @deprecated Use {@link ParentMessage}. */\n public set parentMessage(value: MJConversationDetailEntity | null) {\n this.ParentMessage = value;\n }\n public Replies: MJConversationDetailEntity[] = [];\n\n /** @deprecated Use {@link Replies}. */\n public get replies(): MJConversationDetailEntity[] {\n return this.Replies;\n }\n /** @deprecated Use {@link Replies}. */\n public set replies(value: MJConversationDetailEntity[]) {\n this.Replies = value;\n }\n public ReplyText: string = '';\n\n /** @deprecated Use {@link ReplyText}. */\n public get replyText(): string {\n return this.ReplyText;\n }\n /** @deprecated Use {@link ReplyText}. */\n public set replyText(value: string) {\n this.ReplyText = value;\n }\n public isLoading: boolean = false;\n public IsSending: boolean = false;\n\n /** @deprecated Use {@link IsSending}. */\n public get isSending(): boolean {\n return this.IsSending;\n }\n /** @deprecated Use {@link IsSending}. */\n public set isSending(value: boolean) {\n this.IsSending = value;\n }\n public errorMessage: string = '';\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private dataCache: DataCacheService,\n private cdRef: ChangeDetectorRef\n ) {\n super();}\n\n async ngOnInit() {\n this.dataCache.Provider = this.ProviderToUse;\n await this.loadThreadData();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Loads the parent message and all replies\n */\n private async loadThreadData(): Promise<void> {\n this.isLoading = true;\n this.errorMessage = '';\n\n try {\n // Load parent message from cache\n const parent = await this.dataCache.getConversationDetail(this.ParentMessageId, this.CurrentUser);\n\n if (!parent) {\n this.errorMessage = 'Failed to load parent message';\n this.isLoading = false;\n return;\n }\n\n this.ParentMessage = parent;\n\n // Load all replies\n await this.loadReplies();\n } catch (error) {\n console.error('Error loading thread data:', error);\n this.errorMessage = 'Error loading thread. Please try again.';\n } finally {\n this.isLoading = false;\n this.cdRef.detectChanges();\n }\n }\n\n /**\n * Loads all replies for the parent message\n */\n private async loadReplies(): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJConversationDetailEntity>(\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `ParentID='${this.ParentMessageId}'`,\n OrderBy: '__mj_CreatedAt ASC',\n ResultType: 'entity_object'\n },\n this.CurrentUser\n );\n\n if (result.Success) {\n this.Replies = result.Results || [];\n } else {\n console.error('Failed to load replies:', result.ErrorMessage);\n this.errorMessage = 'Failed to load replies';\n }\n } catch (error) {\n console.error('Error loading replies:', error);\n this.errorMessage = 'Error loading replies';\n }\n }\n\n /**\n * Handles sending a new reply\n */\n async OnSendReply(): Promise<void> {\n if (!this.CanSendReply) return;\n\n this.IsSending = true;\n this.errorMessage = '';\n\n try {\n const reply = await this.dataCache.createConversationDetail(this.CurrentUser);\n\n reply.ConversationID = this.ConversationId;\n reply.ParentID = this.ParentMessageId;\n reply.Message = this.ReplyText.trim();\n reply.Role = 'User';\n\n const saved = await reply.Save();\n\n if (saved) {\n // Add to local list\n this.Replies = [...this.Replies, reply];\n this.ReplyText = '';\n\n // Emit event to parent\n this.ReplyAdded.emit(reply);\n\n // Update parent message thread count\n if (this.ParentMessage) {\n (this.ParentMessage as any).ThreadCount = ((this.ParentMessage as any).ThreadCount || 0) + 1; // TODO: ThreadCount field doesn't exist on MJConversationDetailEntity yet\n }\n\n this.cdRef.detectChanges();\n } else {\n console.error('Failed to save reply:', reply.LatestResult?.Message);\n this.errorMessage = 'Failed to send reply. Please try again.';\n }\n } catch (error) {\n console.error('Error sending reply:', error);\n this.errorMessage = 'Error sending reply. Please try again.';\n } finally {\n this.IsSending = false;\n this.cdRef.detectChanges();\n }\n }\n\n /** @deprecated Use {@link OnSendReply}. */\n async onSendReply(): Promise<void> {\n return this.OnSendReply();\n }\n\n /**\n * Handles closing the thread panel\n */\n OnClose(): void {\n this.Closed.emit();\n }\n\n /** @deprecated Use {@link OnClose}. */\n onClose(): void {\n return this.OnClose();\n }\n\n /**\n * Gets the display text for a message\n */\n GetMessageText(message: MJConversationDetailEntity): string {\n return message.Message || '';\n }\n\n /** @deprecated Use {@link GetMessageText}. */\n getMessageText(message: MJConversationDetailEntity): string {\n return this.GetMessageText(message);\n }\n\n /**\n * Gets the timestamp display for a message\n */\n GetMessageTime(message: MJConversationDetailEntity): string {\n if (!message.__mj_CreatedAt) return '';\n\n const date = new Date(message.__mj_CreatedAt);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString();\n }\n\n /** @deprecated Use {@link GetMessageTime}. */\n getMessageTime(message: MJConversationDetailEntity): string {\n return this.GetMessageTime(message);\n }\n\n /**\n * Gets the sender name for a message\n */\n GetSenderName(message: MJConversationDetailEntity): string {\n if (message.Role === 'AI') return 'AI Assistant';\n return message.User || 'User';\n }\n\n /** @deprecated Use {@link GetSenderName}. */\n getSenderName(message: MJConversationDetailEntity): string {\n return this.GetSenderName(message);\n }\n\n /**\n * Checks if current user can send reply\n */\n get CanSendReply(): boolean {\n return !this.IsSending && !this.isLoading && this.ReplyText.trim().length > 0;\n }\n\n /** @deprecated Use {@link CanSendReply}. */\n get canSendReply(): boolean {\n return this.CanSendReply;\n }\n\n /**\n * Gets the reply count text\n */\n get ReplyCountText(): string {\n const count = this.Replies.length;\n return count === 1 ? '1 reply' : `${count} replies`;\n }\n\n /** @deprecated Use {@link ReplyCountText}. */\n get replyCountText(): string {\n return this.ReplyCountText;\n }\n}\n","<div class=\"thread-panel-overlay\" (click)=\"onClose()\"></div>\n\n<div class=\"thread-panel\">\n <div class=\"thread-header\">\n <div class=\"thread-title\">\n <i class=\"fa-solid fa-comments\"></i>\n <span>Thread</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close thread\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (isLoading) {\n <div class=\"thread-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading thread...</span>\n </div>\n }\n\n @if (errorMessage && !isLoading) {\n <div class=\"thread-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (!isLoading && !errorMessage && parentMessage) {\n <div class=\"thread-content\">\n <!-- Parent Message -->\n <div class=\"parent-message\">\n <div class=\"message-header\">\n <span class=\"message-sender\">{{ getSenderName(parentMessage) }}</span>\n <span class=\"message-time\">{{ getMessageTime(parentMessage) }}</span>\n </div>\n <div class=\"message-body\">\n {{ getMessageText(parentMessage) }}\n </div>\n <div class=\"reply-count\">\n <i class=\"fa-solid fa-reply\"></i>\n <span>{{ replyCountText }}</span>\n </div>\n </div>\n\n <!-- Replies List -->\n <div class=\"replies-container\">\n @if (replies.length === 0) {\n <div class=\"no-replies\">\n <i class=\"fa-solid fa-message\"></i>\n <span>No replies yet. Be the first to reply!</span>\n </div>\n }\n\n @for (reply of replies; track reply.ID) {\n <div class=\"reply-item\" [class.ai-reply]=\"reply.Role === 'AI'\">\n <div class=\"reply-header\">\n <span class=\"reply-sender\">{{ getSenderName(reply) }}</span>\n <span class=\"reply-time\">{{ getMessageTime(reply) }}</span>\n </div>\n <div class=\"reply-body\">\n {{ getMessageText(reply) }}\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Reply Input -->\n <div class=\"reply-input-container\">\n <textarea\n class=\"reply-input\"\n [(ngModel)]=\"replyText\"\n [disabled]=\"isSending\"\n placeholder=\"Reply to thread...\"\n rows=\"3\"\n (keydown.control.enter)=\"onSendReply()\"\n (keydown.meta.enter)=\"onSendReply()\">\n </textarea>\n <div class=\"reply-actions\">\n <button\n class=\"btn-send-reply\"\n [disabled]=\"!canSendReply\"\n (click)=\"onSendReply()\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>{{ isSending ? 'Sending...' : 'Reply' }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n"]}
|