@memberjunction/ng-conversations 2.106.0 → 2.108.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.
Files changed (112) hide show
  1. package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts +67 -0
  2. package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -0
  3. package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +725 -0
  4. package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -0
  5. package/dist/lib/components/collection/artifact-create-modal.component.d.ts +39 -0
  6. package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -0
  7. package/dist/lib/components/collection/artifact-create-modal.component.js +351 -0
  8. package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -0
  9. package/dist/lib/components/collection/collection-form-modal.component.d.ts +3 -1
  10. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  11. package/dist/lib/components/collection/collection-form-modal.component.js +60 -10
  12. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  13. package/dist/lib/components/collection/collection-share-modal.component.d.ts +43 -0
  14. package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -0
  15. package/dist/lib/components/collection/collection-share-modal.component.js +728 -0
  16. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -0
  17. package/dist/lib/components/collection/collection-tree.component.d.ts +8 -1
  18. package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
  19. package/dist/lib/components/collection/collection-tree.component.js +217 -115
  20. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  21. package/dist/lib/components/collection/collection-view.component.d.ts +2 -1
  22. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  23. package/dist/lib/components/collection/collection-view.component.js +52 -34
  24. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  25. package/dist/lib/components/collection/collections-full-view.component.d.ts +45 -9
  26. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  27. package/dist/lib/components/collection/collections-full-view.component.js +586 -220
  28. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  29. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +53 -20
  30. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  31. package/dist/lib/components/conversation/conversation-chat-area.component.js +365 -250
  32. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  33. package/dist/lib/components/message/message-input.component.d.ts +71 -1
  34. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  35. package/dist/lib/components/message/message-input.component.js +303 -104
  36. package/dist/lib/components/message/message-input.component.js.map +1 -1
  37. package/dist/lib/components/message/message-item.component.d.ts +39 -5
  38. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  39. package/dist/lib/components/message/message-item.component.js +259 -137
  40. package/dist/lib/components/message/message-item.component.js.map +1 -1
  41. package/dist/lib/components/message/message-list.component.d.ts +8 -6
  42. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  43. package/dist/lib/components/message/message-list.component.js +52 -9
  44. package/dist/lib/components/message/message-list.component.js.map +1 -1
  45. package/dist/lib/components/message/suggested-responses.component.d.ts +55 -0
  46. package/dist/lib/components/message/suggested-responses.component.d.ts.map +1 -0
  47. package/dist/lib/components/message/suggested-responses.component.js +207 -0
  48. package/dist/lib/components/message/suggested-responses.component.js.map +1 -0
  49. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  50. package/dist/lib/components/search/search-panel.component.js +245 -113
  51. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  52. package/dist/lib/components/shared/user-picker.component.d.ts +29 -0
  53. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -0
  54. package/dist/lib/components/shared/user-picker.component.js +229 -0
  55. package/dist/lib/components/shared/user-picker.component.js.map +1 -0
  56. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +7 -1
  57. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  58. package/dist/lib/components/tasks/tasks-dropdown.component.js +36 -6
  59. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  60. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +19 -2
  61. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  62. package/dist/lib/components/workspace/conversation-workspace.component.js +167 -58
  63. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  64. package/dist/lib/conversations.module.d.ts +52 -47
  65. package/dist/lib/conversations.module.d.ts.map +1 -1
  66. package/dist/lib/conversations.module.js +27 -4
  67. package/dist/lib/conversations.module.js.map +1 -1
  68. package/dist/lib/models/conversation-complete-query.model.d.ts +75 -0
  69. package/dist/lib/models/conversation-complete-query.model.d.ts.map +1 -0
  70. package/dist/lib/models/conversation-complete-query.model.js +19 -0
  71. package/dist/lib/models/conversation-complete-query.model.js.map +1 -0
  72. package/dist/lib/models/conversation-state.model.d.ts +27 -0
  73. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  74. package/dist/lib/models/lazy-artifact-info.d.ts +68 -0
  75. package/dist/lib/models/lazy-artifact-info.d.ts.map +1 -0
  76. package/dist/lib/models/lazy-artifact-info.js +150 -0
  77. package/dist/lib/models/lazy-artifact-info.js.map +1 -0
  78. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  79. package/dist/lib/services/agent-state.service.js +5 -0
  80. package/dist/lib/services/agent-state.service.js.map +1 -1
  81. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  82. package/dist/lib/services/artifact-state.service.js +14 -9
  83. package/dist/lib/services/artifact-state.service.js.map +1 -1
  84. package/dist/lib/services/collection-permission.service.d.ts +96 -0
  85. package/dist/lib/services/collection-permission.service.d.ts.map +1 -0
  86. package/dist/lib/services/collection-permission.service.js +303 -0
  87. package/dist/lib/services/collection-permission.service.js.map +1 -0
  88. package/dist/lib/services/collection-state.service.d.ts +34 -0
  89. package/dist/lib/services/collection-state.service.d.ts.map +1 -0
  90. package/dist/lib/services/collection-state.service.js +50 -0
  91. package/dist/lib/services/collection-state.service.js.map +1 -0
  92. package/dist/lib/services/conversation-agent.service.d.ts +20 -4
  93. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  94. package/dist/lib/services/conversation-agent.service.js +179 -17
  95. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  96. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  97. package/dist/lib/services/data-cache.service.js +5 -0
  98. package/dist/lib/services/data-cache.service.js.map +1 -1
  99. package/dist/lib/services/mention-autocomplete.service.js +1 -1
  100. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  101. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  102. package/dist/lib/services/mention-parser.service.js +0 -5
  103. package/dist/lib/services/mention-parser.service.js.map +1 -1
  104. package/dist/lib/services/search.service.d.ts +26 -3
  105. package/dist/lib/services/search.service.d.ts.map +1 -1
  106. package/dist/lib/services/search.service.js +172 -12
  107. package/dist/lib/services/search.service.js.map +1 -1
  108. package/dist/public-api.d.ts +4 -0
  109. package/dist/public-api.d.ts.map +1 -1
  110. package/dist/public-api.js +4 -0
  111. package/dist/public-api.js.map +1 -1
  112. package/package.json +12 -12
@@ -1,30 +1,35 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
- import { RunView, Metadata } from '@memberjunction/core';
2
+ import { RunQuery, Metadata } from '@memberjunction/core';
3
+ import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
4
+ import { parseConversationDetailComplete } from '../../models/conversation-complete-query.model';
5
+ import { MessageInputComponent } from '../message/message-input.component';
6
+ import { ArtifactViewerPanelComponent } from '@memberjunction/ng-artifacts';
3
7
  import { Subject } from 'rxjs';
4
8
  import * as i0 from "@angular/core";
5
9
  import * as i1 from "../../services/conversation-state.service";
6
- import * as i2 from "../../services/data-cache.service";
7
- import * as i3 from "../../services/agent-state.service";
8
- import * as i4 from "../../services/conversation-agent.service";
9
- import * as i5 from "../../services/active-tasks.service";
10
+ import * as i2 from "../../services/agent-state.service";
11
+ import * as i3 from "../../services/conversation-agent.service";
12
+ import * as i4 from "../../services/active-tasks.service";
13
+ import * as i5 from "../../services/mention-autocomplete.service";
10
14
  import * as i6 from "@angular/common";
11
15
  import * as i7 from "@memberjunction/ng-artifacts";
12
- import * as i8 from "../message/message-list.component";
13
- import * as i9 from "../message/message-input.component";
14
- import * as i10 from "../thread/thread-panel.component";
15
- import * as i11 from "../project/project-selector.component";
16
- import * as i12 from "../tasks/tasks-dropdown.component";
17
- import * as i13 from "../agent/active-agent-indicator.component";
18
- import * as i14 from "../members/members-modal.component";
19
- import * as i15 from "../export/export-modal.component";
16
+ import * as i8 from "../collection/artifact-collection-picker-modal.component";
17
+ import * as i9 from "../message/message-list.component";
18
+ import * as i10 from "../message/message-input.component";
19
+ import * as i11 from "../thread/thread-panel.component";
20
+ import * as i12 from "../project/project-selector.component";
21
+ import * as i13 from "../tasks/tasks-dropdown.component";
22
+ import * as i14 from "../agent/active-agent-indicator.component";
23
+ import * as i15 from "../members/members-modal.component";
24
+ import * as i16 from "../export/export-modal.component";
20
25
  const _c0 = ["scrollContainer"];
21
26
  const _forTrack0 = ($index, $item) => $item.artifactId;
22
27
  const _forTrack1 = ($index, $item) => $item.versionId;
23
28
  function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf & 1) {
24
29
  const _r3 = i0.ɵɵgetCurrentView();
25
- i0.ɵɵelementStart(0, "button", 30);
30
+ i0.ɵɵelementStart(0, "button", 31);
26
31
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.openProjectSelector()); });
27
- i0.ɵɵelement(1, "i", 31);
32
+ i0.ɵɵelement(1, "i", 32);
28
33
  i0.ɵɵelementStart(2, "span");
29
34
  i0.ɵɵtext(3);
30
35
  i0.ɵɵelementEnd()();
@@ -35,9 +40,9 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
35
40
  } }
36
41
  function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf & 1) {
37
42
  const _r6 = i0.ɵɵgetCurrentView();
38
- i0.ɵɵelementStart(0, "button", 32);
43
+ i0.ɵɵelementStart(0, "button", 33);
39
44
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.viewArtifacts()); });
40
- i0.ɵɵelement(1, "i", 33);
45
+ i0.ɵɵelement(1, "i", 34);
41
46
  i0.ɵɵelementStart(2, "span");
42
47
  i0.ɵɵtext(3);
43
48
  i0.ɵɵelementEnd()();
@@ -48,31 +53,31 @@ function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf
48
53
  } }
49
54
  function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
50
55
  const _r2 = i0.ɵɵgetCurrentView();
51
- i0.ɵɵelementStart(0, "div", 16)(1, "div", 17)(2, "div", 18);
56
+ i0.ɵɵelementStart(0, "div", 17)(1, "div", 18)(2, "div", 19);
52
57
  i0.ɵɵtext(3);
53
58
  i0.ɵɵelementEnd();
54
- i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 19);
55
- i0.ɵɵelementStart(5, "button", 20);
59
+ i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 20);
60
+ i0.ɵɵelementStart(5, "button", 21);
56
61
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleMembersModal()); });
57
- i0.ɵɵelement(6, "i", 21);
62
+ i0.ɵɵelement(6, "i", 22);
58
63
  i0.ɵɵelementStart(7, "span");
59
64
  i0.ɵɵtext(8);
60
65
  i0.ɵɵelementEnd()();
61
- i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button", 22);
62
- i0.ɵɵelementStart(10, "mj-active-agent-indicator", 23);
66
+ i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button", 23);
67
+ i0.ɵɵelementStart(10, "mj-active-agent-indicator", 24);
63
68
  i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_10_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_10_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAgentSelected($event)); });
64
69
  i0.ɵɵelementEnd()();
65
- i0.ɵɵelementStart(11, "div", 24)(12, "mj-tasks-dropdown", 25);
70
+ i0.ɵɵelementStart(11, "div", 25)(12, "mj-tasks-dropdown", 26);
66
71
  i0.ɵɵlistener("taskClicked", function ConversationChatAreaComponent_div_1_Template_mj_tasks_dropdown_taskClicked_12_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onTaskClicked($event)); });
67
72
  i0.ɵɵelementEnd();
68
- i0.ɵɵelementStart(13, "button", 26);
73
+ i0.ɵɵelementStart(13, "button", 27);
69
74
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.exportConversation()); });
70
- i0.ɵɵelement(14, "i", 27);
75
+ i0.ɵɵelement(14, "i", 28);
71
76
  i0.ɵɵtext(15, " Export ");
72
77
  i0.ɵɵelementEnd();
73
- i0.ɵɵelementStart(16, "button", 28);
78
+ i0.ɵɵelementStart(16, "button", 29);
74
79
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.shareConversation()); });
75
- i0.ɵɵelement(17, "i", 29);
80
+ i0.ɵɵelement(17, "i", 30);
76
81
  i0.ɵɵtext(18, " Share ");
77
82
  i0.ɵɵelementEnd()()();
78
83
  } if (rf & 2) {
@@ -96,21 +101,21 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
96
101
  } }
97
102
  function ConversationChatAreaComponent_span_8_Template(rf, ctx) { if (rf & 1) {
98
103
  const _r7 = i0.ɵɵgetCurrentView();
99
- i0.ɵɵelementStart(0, "span", 34);
104
+ i0.ɵɵelementStart(0, "span", 35);
100
105
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_span_8_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.scrollToBottomAnimate()); });
101
- i0.ɵɵelement(1, "i", 35);
106
+ i0.ɵɵelement(1, "i", 36);
102
107
  i0.ɵɵelementEnd();
103
108
  } }
104
109
  function ConversationChatAreaComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
105
- i0.ɵɵelementStart(0, "div", 10)(1, "div", 36);
106
- i0.ɵɵelement(2, "i", 37);
110
+ i0.ɵɵelementStart(0, "div", 10)(1, "div", 37);
111
+ i0.ɵɵelement(2, "i", 38);
107
112
  i0.ɵɵelementStart(3, "span");
108
113
  i0.ɵɵtext(4, "Loading conversation data...");
109
114
  i0.ɵɵelementEnd()()();
110
115
  } }
111
116
  function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template(rf, ctx) { if (rf & 1) {
112
117
  const _r8 = i0.ɵɵgetCurrentView();
113
- i0.ɵɵelementStart(0, "mj-message-input", 39);
118
+ i0.ɵɵelementStart(0, "mj-message-input", 40);
114
119
  i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onAgentRunDetected($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onConversationRenamed($event)); });
115
120
  i0.ɵɵelementEnd();
116
121
  } if (rf & 2) {
@@ -118,18 +123,18 @@ function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Templat
118
123
  i0.ɵɵproperty("conversationId", ctx_r3.conversationState.activeConversation.ID)("currentUser", ctx_r3.currentUser)("conversationHistory", ctx_r3.messages)("disabled", ctx_r3.isProcessing);
119
124
  } }
120
125
  function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
121
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template, 1, 4, "mj-message-input", 38);
126
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template, 1, 4, "mj-message-input", 39);
122
127
  } if (rf & 2) {
123
128
  const ctx_r3 = i0.ɵɵnextContext();
124
129
  i0.ɵɵproperty("ngIf", ctx_r3.conversationState.activeConversation);
125
130
  } }
126
131
  function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
127
132
  const _r9 = i0.ɵɵgetCurrentView();
128
- i0.ɵɵelementStart(0, "div", 40);
133
+ i0.ɵɵelementStart(0, "div", 41);
129
134
  i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_12_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onResizeStart($event)); });
130
135
  i0.ɵɵelementEnd();
131
- i0.ɵɵelementStart(1, "div", 41)(2, "mj-artifact-viewer-panel", 42);
132
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseArtifactPanel()); });
136
+ i0.ɵɵelementStart(1, "div", 42)(2, "mj-artifact-viewer-panel", 43);
137
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSaveToCollectionRequested($event)); });
133
138
  i0.ɵɵelementEnd()();
134
139
  } if (rf & 2) {
135
140
  const ctx_r3 = i0.ɵɵnextContext();
@@ -140,7 +145,7 @@ function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf
140
145
  } }
141
146
  function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
142
147
  const _r10 = i0.ɵɵgetCurrentView();
143
- i0.ɵɵelementStart(0, "mj-thread-panel", 43);
148
+ i0.ɵɵelementStart(0, "mj-thread-panel", 44);
144
149
  i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_13_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onThreadClosed()); })("replyAdded", function ConversationChatAreaComponent_Conditional_13_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onThreadReplyAdded($event)); });
145
150
  i0.ɵɵelementEnd();
146
151
  } if (rf & 2) {
@@ -149,18 +154,18 @@ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf
149
154
  } }
150
155
  function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
151
156
  const _r11 = i0.ɵɵgetCurrentView();
152
- i0.ɵɵelementStart(0, "div", 44);
157
+ i0.ɵɵelementStart(0, "div", 45);
153
158
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
154
- i0.ɵɵelementStart(1, "div", 45);
159
+ i0.ɵɵelementStart(1, "div", 46);
155
160
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
156
- i0.ɵɵelementStart(2, "div", 46)(3, "h3");
161
+ i0.ɵɵelementStart(2, "div", 47)(3, "h3");
157
162
  i0.ɵɵtext(4, "Assign Project");
158
163
  i0.ɵɵelementEnd();
159
- i0.ɵɵelementStart(5, "button", 47);
164
+ i0.ɵɵelementStart(5, "button", 48);
160
165
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
161
- i0.ɵɵelement(6, "i", 48);
166
+ i0.ɵɵelement(6, "i", 49);
162
167
  i0.ɵɵelementEnd()();
163
- i0.ɵɵelementStart(7, "div", 49)(8, "mj-project-selector", 50);
168
+ i0.ɵɵelementStart(7, "div", 50)(8, "mj-project-selector", 51);
164
169
  i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_16_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onProjectSelected($event)); });
165
170
  i0.ɵɵelementEnd()()()();
166
171
  } if (rf & 2) {
@@ -169,9 +174,9 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
169
174
  i0.ɵɵproperty("environmentId", ctx_r3.environmentId)("currentUser", ctx_r3.currentUser)("selectedProjectId", ctx_r3.conversationState.activeConversation.ProjectID);
170
175
  } }
171
176
  function ConversationChatAreaComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
172
- i0.ɵɵelementStart(0, "div", 53);
173
- i0.ɵɵelement(1, "i", 55);
174
- i0.ɵɵelementStart(2, "p", 56);
177
+ i0.ɵɵelementStart(0, "div", 54);
178
+ i0.ɵɵelement(1, "i", 56);
179
+ i0.ɵɵelementStart(2, "p", 57);
175
180
  i0.ɵɵtext(3, "No artifacts in this conversation yet");
176
181
  i0.ɵɵelementEnd()();
177
182
  } }
@@ -186,9 +191,9 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Templ
186
191
  } }
187
192
  function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template(rf, ctx) { if (rf & 1) {
188
193
  const _r15 = i0.ɵɵgetCurrentView();
189
- i0.ɵɵelementStart(0, "button", 68);
194
+ i0.ɵɵelementStart(0, "button", 69);
190
195
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r15); const artifact_r14 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.toggleArtifactExpansion(artifact_r14.artifactId, $event)); });
191
- i0.ɵɵelement(1, "i", 69);
196
+ i0.ɵɵelement(1, "i", 70);
192
197
  i0.ɵɵelementEnd();
193
198
  } if (rf & 2) {
194
199
  const artifact_r14 = i0.ɵɵnextContext().$implicit;
@@ -198,15 +203,15 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Temp
198
203
  } }
199
204
  function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
200
205
  const _r16 = i0.ɵɵgetCurrentView();
201
- i0.ɵɵelementStart(0, "div", 71);
206
+ i0.ɵɵelementStart(0, "div", 72);
202
207
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r17 = i0.ɵɵrestoreView(_r16).$implicit; const artifact_r14 = i0.ɵɵnextContext(2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.openArtifactFromModal(artifact_r14.artifactId, version_r17.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
203
- i0.ɵɵelementStart(1, "span", 72);
208
+ i0.ɵɵelementStart(1, "span", 73);
204
209
  i0.ɵɵtext(2);
205
210
  i0.ɵɵelementEnd();
206
- i0.ɵɵelementStart(3, "span", 73);
211
+ i0.ɵɵelementStart(3, "span", 74);
207
212
  i0.ɵɵtext(4, "Open this version");
208
213
  i0.ɵɵelementEnd();
209
- i0.ɵɵelement(5, "i", 74);
214
+ i0.ɵɵelement(5, "i", 75);
210
215
  i0.ɵɵelementEnd();
211
216
  } if (rf & 2) {
212
217
  const version_r17 = ctx.$implicit;
@@ -214,8 +219,8 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_
214
219
  i0.ɵɵtextInterpolate1("v", version_r17.versionNumber, "");
215
220
  } }
216
221
  function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
217
- i0.ɵɵelementStart(0, "div", 67);
218
- i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template, 6, 1, "div", 70, _forTrack1);
222
+ i0.ɵɵelementStart(0, "div", 68);
223
+ i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template, 6, 1, "div", 71, _forTrack1);
219
224
  i0.ɵɵelementEnd();
220
225
  } if (rf & 2) {
221
226
  const artifact_r14 = i0.ɵɵnextContext().$implicit;
@@ -224,22 +229,22 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Temp
224
229
  } }
225
230
  function ConversationChatAreaComponent_Conditional_17_For_10_Template(rf, ctx) { if (rf & 1) {
226
231
  const _r13 = i0.ɵɵgetCurrentView();
227
- i0.ɵɵelementStart(0, "div", 57)(1, "div", 58);
232
+ i0.ɵɵelementStart(0, "div", 58)(1, "div", 59);
228
233
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Template_div_click_1_listener() { const artifact_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.openArtifactFromModal(artifact_r14.artifactId)); });
229
- i0.ɵɵelementStart(2, "div", 59);
230
- i0.ɵɵelement(3, "i", 60);
234
+ i0.ɵɵelementStart(2, "div", 60);
235
+ i0.ɵɵelement(3, "i", 61);
231
236
  i0.ɵɵelementEnd();
232
- i0.ɵɵelementStart(4, "div", 61)(5, "div", 62);
237
+ i0.ɵɵelementStart(4, "div", 62)(5, "div", 63);
233
238
  i0.ɵɵtext(6);
234
239
  i0.ɵɵelementEnd();
235
- i0.ɵɵelementStart(7, "div", 63);
240
+ i0.ɵɵelementStart(7, "div", 64);
236
241
  i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Template, 1, 0);
237
242
  i0.ɵɵelementEnd()();
238
- i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template, 2, 4, "button", 64);
239
- i0.ɵɵelementStart(11, "div", 65);
240
- i0.ɵɵelement(12, "i", 66);
243
+ i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template, 2, 4, "button", 65);
244
+ i0.ɵɵelementStart(11, "div", 66);
245
+ i0.ɵɵelement(12, "i", 67);
241
246
  i0.ɵɵelementEnd()();
242
- i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template, 3, 0, "div", 67);
247
+ i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template, 3, 0, "div", 68);
243
248
  i0.ɵɵelementEnd();
244
249
  } if (rf & 2) {
245
250
  const artifact_r14 = ctx.$implicit;
@@ -256,20 +261,20 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Template(rf, ctx) {
256
261
  } }
257
262
  function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
258
263
  const _r12 = i0.ɵɵgetCurrentView();
259
- i0.ɵɵelementStart(0, "div", 44);
264
+ i0.ɵɵelementStart(0, "div", 45);
260
265
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showArtifactsModal = false); });
261
- i0.ɵɵelementStart(1, "div", 51);
266
+ i0.ɵɵelementStart(1, "div", 52);
262
267
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
263
- i0.ɵɵelementStart(2, "div", 46)(3, "h3");
268
+ i0.ɵɵelementStart(2, "div", 47)(3, "h3");
264
269
  i0.ɵɵtext(4, "Conversation Artifacts");
265
270
  i0.ɵɵelementEnd();
266
- i0.ɵɵelementStart(5, "button", 47);
271
+ i0.ɵɵelementStart(5, "button", 48);
267
272
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showArtifactsModal = false); });
268
- i0.ɵɵelement(6, "i", 48);
273
+ i0.ɵɵelement(6, "i", 49);
269
274
  i0.ɵɵelementEnd()();
270
- i0.ɵɵelementStart(7, "div", 52);
271
- i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div", 53);
272
- i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 14, 6, "div", 54, _forTrack0);
275
+ i0.ɵɵelementStart(7, "div", 53);
276
+ i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div", 54);
277
+ i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 14, 6, "div", 55, _forTrack0);
273
278
  i0.ɵɵelementEnd()()();
274
279
  } if (rf & 2) {
275
280
  const ctx_r3 = i0.ɵɵnextContext();
@@ -278,23 +283,35 @@ function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf
278
283
  i0.ɵɵadvance();
279
284
  i0.ɵɵrepeater(ctx_r3.getArtifactsArray());
280
285
  } }
286
+ function ConversationChatAreaComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
287
+ const _r18 = i0.ɵɵgetCurrentView();
288
+ i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 76);
289
+ i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_18_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCollectionPickerSaved($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_18_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCollectionPickerCancelled()); });
290
+ i0.ɵɵelementEnd();
291
+ } if (rf & 2) {
292
+ const ctx_r3 = i0.ɵɵnextContext();
293
+ i0.ɵɵproperty("isOpen", ctx_r3.showCollectionPicker)("environmentId", ctx_r3.environmentId)("currentUser", ctx_r3.currentUser)("excludeCollectionIds", ctx_r3.collectionPickerExcludedIds);
294
+ } }
281
295
  export class ConversationChatAreaComponent {
282
296
  conversationState;
283
- dataCache;
284
297
  agentStateService;
285
298
  conversationAgentService;
286
299
  activeTasks;
287
300
  cdr;
301
+ mentionAutocompleteService;
288
302
  environmentId;
289
303
  currentUser;
290
304
  conversationRenamed = new EventEmitter();
291
305
  openEntityRecord = new EventEmitter();
292
306
  taskClicked = new EventEmitter();
293
307
  scrollContainer;
308
+ messageInputComponent;
309
+ artifactViewerComponent;
294
310
  messages = [];
295
311
  showScrollToBottomIcon = false;
296
312
  scrollToBottom = false;
297
313
  previousConversationId = null;
314
+ lastLoadedConversationId = null; // Track which conversation's peripheral data was loaded
298
315
  isProcessing = false;
299
316
  memberCount = 1;
300
317
  artifactCount = 0;
@@ -309,8 +326,14 @@ export class ConversationChatAreaComponent {
309
326
  selectedVersionNumber = undefined; // Version to show in artifact viewer
310
327
  artifactPaneWidth = 40; // Default 40% width
311
328
  expandedArtifactId = null; // Track which artifact card is expanded in modal
312
- // Artifact mapping: ConversationDetailID -> Array of {artifact, version}
313
- // Full entities loaded once and reused across all message components
329
+ showCollectionPicker = false;
330
+ collectionPickerArtifactId = null;
331
+ collectionPickerExcludedIds = [];
332
+ // Conversation data cache: ConversationID -> Array of ConversationDetailComplete
333
+ // Stores raw query results so we don't need to re-query when switching conversations
334
+ conversationDataCache = new Map();
335
+ // Artifact mapping: ConversationDetailID -> Array of LazyArtifactInfo
336
+ // Uses lazy-loading pattern: display data loaded immediately, full entities on-demand
314
337
  // Supports multiple artifacts per conversation detail (0-N relationship)
315
338
  artifactsByDetailId = new Map();
316
339
  // Agent run mapping: ConversationDetailID -> AIAgentRunEntityExtended
@@ -326,15 +349,18 @@ export class ConversationChatAreaComponent {
326
349
  startWidth = 0;
327
350
  // LocalStorage key
328
351
  ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
329
- constructor(conversationState, dataCache, agentStateService, conversationAgentService, activeTasks, cdr) {
352
+ constructor(conversationState, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService) {
330
353
  this.conversationState = conversationState;
331
- this.dataCache = dataCache;
332
354
  this.agentStateService = agentStateService;
333
355
  this.conversationAgentService = conversationAgentService;
334
356
  this.activeTasks = activeTasks;
335
357
  this.cdr = cdr;
358
+ this.mentionAutocompleteService = mentionAutocompleteService;
336
359
  }
337
- ngOnInit() {
360
+ async ngOnInit() {
361
+ // Initialize mention service BEFORE loading messages
362
+ // This ensures agents are loaded and available for @mention parsing in existing messages
363
+ await this.mentionAutocompleteService.initialize(this.currentUser);
338
364
  // Load saved artifact pane width
339
365
  this.loadArtifactPaneWidth();
340
366
  // Initial load if there's already an active conversation
@@ -390,18 +416,41 @@ export class ConversationChatAreaComponent {
390
416
  }
391
417
  async loadMessages(conversationId) {
392
418
  try {
393
- // PHASE 1: Load messages from cache (fast, shows content immediately)
394
- // The cache will load from DB if not already cached
395
- const loadedMessages = await this.dataCache.loadConversationDetails(conversationId, this.currentUser);
396
- this.messages = loadedMessages;
397
- this.scrollToBottom = true;
398
- this.cdr.detectChanges(); // Show messages immediately
399
- // PHASE 2: Load peripheral data in background (agent runs & artifacts)
400
- this.isLoadingPeripheralData = true;
401
- this.loadPeripheralData(conversationId).finally(() => {
402
- this.isLoadingPeripheralData = false;
403
- this.cdr.detectChanges();
404
- });
419
+ // Check if we have cached data for this conversation
420
+ const cachedData = this.conversationDataCache.get(conversationId);
421
+ if (cachedData) {
422
+ // Use cached data - instant load!
423
+ console.log(`📦 Loading conversation ${conversationId} from cache - instant!`);
424
+ this.buildMessagesFromCache(cachedData);
425
+ this.loadPeripheralData(conversationId); // Process cached data for maps
426
+ }
427
+ else {
428
+ // Load from database with single optimized query
429
+ console.log(`🔍 Loading conversation ${conversationId} from database - single query`);
430
+ const rq = new RunQuery();
431
+ const result = await rq.RunQuery({
432
+ QueryName: 'GetConversationComplete',
433
+ CategoryPath: 'MJ/Conversations',
434
+ Parameters: { ConversationID: conversationId }
435
+ }, this.currentUser);
436
+ if (!result.Success || !result.Results) {
437
+ console.error('Failed to load conversation data:', result.ErrorMessage);
438
+ this.messages = [];
439
+ return;
440
+ }
441
+ // Cache the raw results for future use
442
+ const conversationData = result.Results;
443
+ this.conversationDataCache.set(conversationId, conversationData);
444
+ console.log(`💾 Cached ${conversationData.length} conversation details for conversation ${conversationId}`);
445
+ // Build messages and show immediately
446
+ this.buildMessagesFromCache(conversationData);
447
+ // Process peripheral data (agent runs & artifacts) in background
448
+ this.isLoadingPeripheralData = true;
449
+ this.loadPeripheralData(conversationId).finally(() => {
450
+ this.isLoadingPeripheralData = false;
451
+ this.cdr.detectChanges();
452
+ });
453
+ }
405
454
  }
406
455
  catch (error) {
407
456
  console.error('Error loading messages:', error);
@@ -409,105 +458,112 @@ export class ConversationChatAreaComponent {
409
458
  }
410
459
  }
411
460
  /**
412
- * Load peripheral data (agent runs and artifacts) in background
413
- * This allows messages to display immediately while slower queries complete
461
+ * Build message entities from cached conversation data
462
+ * Creates ConversationDetailEntity objects from the raw query results
463
+ */
464
+ async buildMessagesFromCache(conversationData) {
465
+ const md = new Metadata();
466
+ const messages = [];
467
+ for (const row of conversationData) {
468
+ if (!row.ID)
469
+ continue;
470
+ // Create entity object and load from raw data
471
+ const message = await md.GetEntityObject('Conversation Details', this.currentUser);
472
+ // LoadFromData expects the same structure as the query result
473
+ // Since we're using SELECT *, all fields should be present
474
+ message.LoadFromData(row);
475
+ messages.push(message);
476
+ }
477
+ this.messages = messages;
478
+ this.scrollToBottom = true;
479
+ this.cdr.detectChanges(); // Show messages immediately
480
+ }
481
+ /**
482
+ * Process peripheral data (agent runs and artifacts) from cached conversation data
483
+ * Parses JSON columns and builds maps for display
484
+ *
485
+ * PERFORMANCE OPTIMIZATION: Uses cached data instead of querying
486
+ * - Data already loaded by loadMessages() - no additional queries needed
487
+ * - Processes cached JSON data to build display maps
488
+ * - Instant when switching between conversations
414
489
  */
415
490
  async loadPeripheralData(conversationId) {
491
+ const timestamp = new Date().toISOString();
492
+ // Skip if we've already processed peripheral data for this conversation
493
+ if (this.lastLoadedConversationId === conversationId) {
494
+ console.log(`[${timestamp}] ⏭️ Skipping peripheral data processing - already processed for conversation ${conversationId}`);
495
+ return;
496
+ }
497
+ // Mark this conversation as processed to prevent duplicate processing
498
+ this.lastLoadedConversationId = conversationId;
499
+ console.log(`[${timestamp}] 📊 Processing peripheral data for conversation ${conversationId} from cache`);
416
500
  try {
417
- const rv = new RunView();
501
+ // Get cached data - should always be present by the time we get here
502
+ const conversationData = this.conversationDataCache.get(conversationId);
503
+ if (!conversationData) {
504
+ console.warn(`No cached data found for conversation ${conversationId}`);
505
+ return;
506
+ }
418
507
  const md = new Metadata();
419
- const convoDetailEntity = md.EntityByName("Conversation Details");
420
- // Load agent runs and artifacts in parallel
421
- const [agentRunsResult, conversationDetailArtifacts] = await Promise.all([
422
- rv.RunView({
423
- EntityName: 'MJ: AI Agent Runs',
424
- ExtraFilter: `ConversationDetailID IN (SELECT ID FROM [${convoDetailEntity.SchemaName}].[${convoDetailEntity.BaseView}] WHERE ConversationID='${conversationId}')`,
425
- ResultType: 'entity_object',
426
- // Only fetch fields we actually display to reduce payload size
427
- Fields: ['ID', 'AgentID', 'Agent', 'Status', '__mj_CreatedAt', '__mj_UpdatedAt', 'TotalPromptTokensUsed', 'TotalCompletionTokensUsed', 'TotalCost', 'ConversationDetailID']
428
- }, this.currentUser),
429
- rv.RunView({
430
- EntityName: 'MJ: Conversation Detail Artifacts',
431
- ExtraFilter: `ConversationDetailID IN (SELECT ID FROM [${convoDetailEntity.SchemaName}].[${convoDetailEntity.BaseView}] WHERE ConversationID='${conversationId}') AND Direction='Output'`,
432
- ResultType: 'entity_object'
433
- }, this.currentUser)
434
- ]);
435
- // Build agent runs map - single query loads all runs for this conversation
508
+ // Clear and rebuild maps from cached data
436
509
  this.agentRunsByDetailId.clear();
437
- if (agentRunsResult.Success && agentRunsResult.Results) {
438
- for (const run of agentRunsResult.Results) {
439
- if (run.ConversationDetailID) {
440
- this.agentRunsByDetailId.set(run.ConversationDetailID, run);
441
- }
442
- }
443
- }
444
- // Build artifact map from preloaded artifacts
445
510
  this.artifactsByDetailId.clear();
446
- if (conversationDetailArtifacts.Success && conversationDetailArtifacts.Results && conversationDetailArtifacts.Results.length > 0) {
447
- // Load artifact versions to get ArtifactID
448
- const versionIds = conversationDetailArtifacts.Results.map(a => `'${a.ArtifactVersionID}'`).join(',');
449
- const versionsResult = await rv.RunView({
450
- EntityName: 'MJ: Artifact Versions',
451
- ExtraFilter: `ID IN (${versionIds})`,
452
- ResultType: 'entity_object'
453
- }, this.currentUser);
454
- if (versionsResult.Success && versionsResult.Results) {
455
- // Get all unique artifact IDs
456
- const artifactIds = [...new Set(versionsResult.Results.map(v => v.ArtifactID))];
457
- // Load full artifact entities
458
- const artifactsResult = await rv.RunView({
459
- EntityName: 'MJ: Artifacts',
460
- ExtraFilter: `ID IN (${artifactIds.map(id => `'${id}'`).join(',')})`,
461
- ResultType: 'entity_object'
462
- }, this.currentUser);
463
- // Create maps of entities by ID for fast lookup
464
- const artifactEntities = new Map();
465
- const versionEntities = new Map();
466
- if (artifactsResult.Success && artifactsResult.Results) {
467
- for (const artifact of artifactsResult.Results) {
468
- artifactEntities.set(artifact.ID, artifact);
469
- }
470
- }
471
- for (const version of versionsResult.Results) {
472
- versionEntities.set(version.ID, version);
473
- }
474
- // Build final artifact map with FULL entities
475
- // Group artifacts by ConversationDetailID (supports multiple artifacts per detail)
476
- for (const junctionRecord of conversationDetailArtifacts.Results) {
477
- const version = versionEntities.get(junctionRecord.ArtifactVersionID);
478
- const artifact = version ? artifactEntities.get(version.ArtifactID) : undefined;
479
- if (junctionRecord.ConversationDetailID && version && artifact) {
480
- const existing = this.artifactsByDetailId.get(junctionRecord.ConversationDetailID) || [];
481
- existing.push({
482
- artifact: artifact, // Full ArtifactEntity
483
- version: version // Full ArtifactVersionEntity
484
- });
485
- this.artifactsByDetailId.set(junctionRecord.ConversationDetailID, existing);
486
- }
511
+ for (const row of conversationData) {
512
+ // Skip rows without ID (should never happen, but type safety check)
513
+ if (!row.ID) {
514
+ console.warn('Skipping conversation detail row without ID');
515
+ continue;
516
+ }
517
+ const parsed = parseConversationDetailComplete(row);
518
+ // Build agent runs map
519
+ if (parsed.agentRuns.length > 0) {
520
+ // Convert AgentRunJSON to AIAgentRunEntityExtended
521
+ const agentRunData = parsed.agentRuns[0]; // Should only be one per detail
522
+ const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
523
+ // Convert ISO date strings to Date objects
524
+ agentRun.LoadFromData({
525
+ ID: agentRunData.ID,
526
+ AgentID: agentRunData.AgentID,
527
+ Agent: agentRunData.Agent,
528
+ Status: agentRunData.Status,
529
+ __mj_CreatedAt: new Date(agentRunData.__mj_CreatedAt),
530
+ __mj_UpdatedAt: new Date(agentRunData.__mj_UpdatedAt),
531
+ TotalPromptTokensUsed: agentRunData.TotalPromptTokensUsed,
532
+ TotalCompletionTokensUsed: agentRunData.TotalCompletionTokensUsed,
533
+ TotalCost: agentRunData.TotalCost,
534
+ ConversationDetailID: agentRunData.ConversationDetailID
535
+ });
536
+ this.agentRunsByDetailId.set(row.ID, agentRun);
537
+ }
538
+ // Build artifacts map - no need to load full entities, just create LazyArtifactInfo
539
+ if (parsed.artifacts.length > 0) {
540
+ const artifactList = [];
541
+ for (const artifactData of parsed.artifacts) {
542
+ // Create LazyArtifactInfo with display data from query
543
+ // Full entities will be loaded on-demand when artifact is clicked
544
+ const lazyInfo = new LazyArtifactInfo(artifactData, this.currentUser);
545
+ artifactList.push(lazyInfo);
487
546
  }
488
- // Create new Map reference to trigger Angular change detection
489
- this.artifactsByDetailId = new Map(this.artifactsByDetailId);
490
- console.log(`📦 Preloaded ${this.artifactsByDetailId.size} artifacts for conversation ${conversationId}`);
547
+ this.artifactsByDetailId.set(row.ID, artifactList);
491
548
  }
492
549
  }
550
+ // Create new Map references to trigger Angular change detection
551
+ this.agentRunsByDetailId = new Map(this.agentRunsByDetailId);
552
+ this.artifactsByDetailId = new Map(this.artifactsByDetailId);
493
553
  // Update artifact count for header display (unique artifacts, not versions)
494
554
  this.artifactCount = this.calculateUniqueArtifactCount();
495
- // Debug: Log all artifacts to console
496
- console.log(`📊 Artifact Count: ${this.artifactCount}`);
497
- console.log(`📦 Artifacts by Detail ID:`, Array.from(this.artifactsByDetailId.entries()).flatMap(([detailId, artifactList]) => artifactList.map(info => ({
498
- conversationDetailId: detailId,
499
- artifactId: info.artifact.ID,
500
- artifactName: info.artifact.Name,
501
- versionId: info.version.ID,
502
- versionNumber: info.version.VersionNumber
503
- }))));
555
+ // Debug: Log summary
556
+ console.log(`📊 Processed ${this.agentRunsByDetailId.size} agent runs, ${this.artifactsByDetailId.size} artifact mappings (${this.artifactCount} unique artifacts)`);
504
557
  // CRITICAL: Trigger message re-render now that agent runs and artifacts are loaded
505
558
  // This updates all message components with the newly loaded agent run data
506
559
  this.messages = [...this.messages]; // Create new array reference to trigger change detection
507
560
  this.cdr.detectChanges();
561
+ console.log(`✅ Peripheral data processed successfully for conversation ${conversationId} from cache`);
508
562
  }
509
563
  catch (error) {
510
- console.error('Failed to load peripheral data:', error);
564
+ console.error('Failed to process peripheral data:', error);
565
+ // Don't set lastLoadedConversationId on error so we can retry
566
+ this.lastLoadedConversationId = null;
511
567
  }
512
568
  }
513
569
  /**
@@ -548,6 +604,11 @@ export class ConversationChatAreaComponent {
548
604
  async onAgentResponse(event) {
549
605
  // Add the agent's response message to the conversation
550
606
  this.messages = [...this.messages, event.message];
607
+ // Invalidate cache for this conversation since we have new messages
608
+ const conversationId = this.conversationState.activeConversationId;
609
+ if (conversationId) {
610
+ this.invalidateConversationCache(conversationId);
611
+ }
551
612
  // Scroll to bottom when agent responds
552
613
  this.scrollToBottom = true;
553
614
  // Add agent run to the map if present (fallback if not already loaded from progress)
@@ -564,24 +625,38 @@ export class ConversationChatAreaComponent {
564
625
  if (this.artifactsByDetailId.has(event.message.ID) && !this.showArtifactPanel) {
565
626
  const artifactList = this.artifactsByDetailId.get(event.message.ID);
566
627
  if (artifactList && artifactList.length > 0) {
567
- // Show the first (or most recent) artifact
568
- this.selectedArtifactId = artifactList[0].artifact.ID;
628
+ // Show the LAST (most recent) artifact - uses display data, no lazy load needed
629
+ this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
569
630
  this.showArtifactPanel = true;
570
631
  }
571
632
  }
572
633
  // Force change detection to update the UI
573
634
  this.cdr.detectChanges();
574
635
  }
636
+ /**
637
+ * Invalidate cached conversation data
638
+ * Called when new messages are added or conversation data changes
639
+ */
640
+ invalidateConversationCache(conversationId) {
641
+ this.conversationDataCache.delete(conversationId);
642
+ console.log(`🗑️ Invalidated cache for conversation ${conversationId}`);
643
+ }
575
644
  /**
576
645
  * Add or update an agent run in the map
577
646
  * Called when a new agent run completes to keep the map in sync
578
647
  */
579
648
  async addAgentRunToMap(conversationDetailId, agentRunId) {
580
649
  try {
581
- const md = new Metadata();
582
- const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
583
- if (await agentRun.Load(agentRunId)) {
584
- this.agentRunsByDetailId.set(conversationDetailId, agentRun);
650
+ if (!this.agentRunsByDetailId.has(conversationDetailId)) {
651
+ const md = new Metadata();
652
+ const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
653
+ if (await agentRun.Load(agentRunId)) {
654
+ this.agentRunsByDetailId.set(conversationDetailId, agentRun);
655
+ }
656
+ }
657
+ else {
658
+ // nothing to do, temp console log to catch how many of these where we were wasting time
659
+ console.log(`⏭️ Agent run for detail ${conversationDetailId} already in map, skipping load`);
585
660
  }
586
661
  }
587
662
  catch (error) {
@@ -591,68 +666,55 @@ export class ConversationChatAreaComponent {
591
666
  /**
592
667
  * Reload artifacts for a specific message ID
593
668
  * Called after an artifact is created to update the UI immediately
669
+ * Invalidates and refreshes the conversation cache
594
670
  */
595
671
  async reloadArtifactsForMessage(conversationDetailId) {
596
672
  console.log(`🔄 Reloading artifacts for message ${conversationDetailId}`);
597
673
  try {
598
- const rv = new RunView();
599
- const artifactsResult = await rv.RunView({
600
- EntityName: 'MJ: Conversation Detail Artifacts',
601
- ExtraFilter: `ConversationDetailID='${conversationDetailId}' AND Direction='Output'`,
602
- ResultType: 'entity_object'
674
+ const rq = new RunQuery();
675
+ const md = new Metadata();
676
+ // Get the ConversationID for this detail
677
+ const detail = await md.GetEntityObject('Conversation Details', this.currentUser);
678
+ if (!(await detail.Load(conversationDetailId))) {
679
+ console.error('Failed to load conversation detail');
680
+ return;
681
+ }
682
+ // Invalidate cache since artifacts changed
683
+ this.invalidateConversationCache(detail.ConversationID);
684
+ // Use optimized single query to reload all conversation data
685
+ const result = await rq.RunQuery({
686
+ QueryName: 'GetConversationComplete',
687
+ CategoryPath: '/MJ/Conversations',
688
+ Parameters: { ConversationID: detail.ConversationID }
603
689
  }, this.currentUser);
604
- console.log(`📊 Junction query result:`, {
605
- success: artifactsResult.Success,
606
- count: artifactsResult.Results?.length || 0,
607
- error: artifactsResult.ErrorMessage
608
- });
609
- if (artifactsResult.Success && artifactsResult.Results && artifactsResult.Results.length > 0) {
610
- // Load full artifact versions and artifacts
611
- const versionIds = artifactsResult.Results.map(a => `'${a.ArtifactVersionID}'`).join(',');
612
- const versionsResult = await rv.RunView({
613
- EntityName: 'MJ: Artifact Versions',
614
- ExtraFilter: `ID IN (${versionIds})`,
615
- ResultType: 'entity_object'
616
- }, this.currentUser);
617
- if (versionsResult.Success && versionsResult.Results) {
618
- // Load full artifact entities
619
- const artifactIds = versionsResult.Results.map(v => `'${v.ArtifactID}'`).join(',');
620
- const fullArtifactsResult = await rv.RunView({
621
- EntityName: 'MJ: Artifacts',
622
- ExtraFilter: `ID IN (${artifactIds})`,
623
- ResultType: 'entity_object'
624
- }, this.currentUser);
625
- if (fullArtifactsResult.Success && fullArtifactsResult.Results) {
626
- // Create maps for fast lookup
627
- const artifactEntities = new Map();
628
- const versionEntities = new Map();
629
- for (const artifact of fullArtifactsResult.Results) {
630
- artifactEntities.set(artifact.ID, artifact);
631
- }
632
- for (const version of versionsResult.Results) {
633
- versionEntities.set(version.ID, version);
634
- }
635
- // Update artifact map with full entities (supports multiple artifacts per detail)
690
+ if (!result.Success || !result.Results) {
691
+ console.error('Failed to reload artifacts:', result.ErrorMessage);
692
+ return;
693
+ }
694
+ console.log(`📊 Query result: ${result.Results.length} conversation details loaded`);
695
+ // Update cache with fresh data
696
+ const conversationData = result.Results;
697
+ this.conversationDataCache.set(detail.ConversationID, conversationData);
698
+ // Find the specific conversation detail we're reloading and update its artifacts
699
+ for (const row of conversationData) {
700
+ if (row.ID === conversationDetailId) {
701
+ const parsed = parseConversationDetailComplete(row);
702
+ // Clear existing artifacts for this detail and rebuild
703
+ this.artifactsByDetailId.delete(conversationDetailId);
704
+ if (parsed.artifacts.length > 0) {
636
705
  const artifactList = [];
637
- for (const junctionRecord of artifactsResult.Results) {
638
- const version = versionEntities.get(junctionRecord.ArtifactVersionID);
639
- const artifact = version ? artifactEntities.get(version.ArtifactID) : undefined;
640
- if (version && artifact) {
641
- artifactList.push({
642
- artifact: artifact,
643
- version: version
644
- });
645
- console.log(`✅ Loaded artifact ${artifact.ID} v${version.VersionNumber} for message ${conversationDetailId}`);
646
- }
706
+ for (const artifactData of parsed.artifacts) {
707
+ const lazyInfo = new LazyArtifactInfo(artifactData, this.currentUser);
708
+ artifactList.push(lazyInfo);
709
+ console.log(`✅ Loaded artifact ${artifactData.ArtifactID} v${artifactData.VersionNumber} for message ${conversationDetailId}`);
647
710
  }
648
- if (artifactList.length > 0) {
649
- this.artifactsByDetailId.set(conversationDetailId, artifactList);
650
- }
651
- // Create new Map reference to trigger Angular change detection
652
- this.artifactsByDetailId = new Map(this.artifactsByDetailId);
653
- // Update artifact count
654
- this.artifactCount = this.calculateUniqueArtifactCount();
711
+ this.artifactsByDetailId.set(conversationDetailId, artifactList);
655
712
  }
713
+ // Create new Map reference to trigger Angular change detection
714
+ this.artifactsByDetailId = new Map(this.artifactsByDetailId);
715
+ // Update artifact count
716
+ this.artifactCount = this.calculateUniqueArtifactCount();
717
+ break; // Found and updated the target message
656
718
  }
657
719
  }
658
720
  }
@@ -671,12 +733,13 @@ export class ConversationChatAreaComponent {
671
733
  }
672
734
  /**
673
735
  * Calculate count of unique artifacts (not versions)
736
+ * Works with LazyArtifactInfo - uses artifactId from display data
674
737
  */
675
738
  calculateUniqueArtifactCount() {
676
739
  const uniqueArtifactIds = new Set();
677
740
  for (const artifactList of this.artifactsByDetailId.values()) {
678
741
  for (const info of artifactList) {
679
- uniqueArtifactIds.add(info.artifact.ID);
742
+ uniqueArtifactIds.add(info.artifactId);
680
743
  }
681
744
  }
682
745
  return uniqueArtifactIds.size;
@@ -684,16 +747,17 @@ export class ConversationChatAreaComponent {
684
747
  /**
685
748
  * Get unique artifacts grouped by artifact ID (not by conversation detail)
686
749
  * Returns the latest version info for each unique artifact with all versions
750
+ * Works with LazyArtifactInfo - uses display data without loading full entities
687
751
  */
688
752
  getArtifactsArray() {
689
753
  const artifactMap = new Map();
690
754
  // Group by artifactId, collecting all version details
691
755
  for (const artifactList of this.artifactsByDetailId.values()) {
692
756
  for (const info of artifactList) {
693
- const artifactId = info.artifact.ID;
694
- const versionId = info.version.ID;
695
- const versionNumber = info.version.VersionNumber || 1;
696
- const name = info.version.Name || info.artifact.Name || 'Untitled';
757
+ const artifactId = info.artifactId;
758
+ const versionId = info.artifactVersionId;
759
+ const versionNumber = info.versionNumber || 1;
760
+ const name = info.artifactName || 'Untitled';
697
761
  if (!artifactMap.has(artifactId)) {
698
762
  artifactMap.set(artifactId, {
699
763
  artifactId: artifactId,
@@ -807,6 +871,19 @@ export class ConversationChatAreaComponent {
807
871
  // The message entity is already updated in place, so no need to reload
808
872
  // Just ensure the UI reflects the changes
809
873
  }
874
+ /**
875
+ * Handle suggested response selection from user
876
+ * Sends the selected response as a new user message WITHOUT modifying the visible input
877
+ */
878
+ async onSuggestedResponseSelected(event) {
879
+ const messageText = event.customInput || event.text;
880
+ if (this.messageInputComponent) {
881
+ await this.messageInputComponent.sendMessageWithText(messageText);
882
+ }
883
+ else {
884
+ console.error('MessageInputComponent not available');
885
+ }
886
+ }
810
887
  onRetryMessage(message) {
811
888
  // TODO: Implement retry logic
812
889
  // This should find the parent user message and re-trigger the agent invocation
@@ -815,12 +892,12 @@ export class ConversationChatAreaComponent {
815
892
  }
816
893
  onArtifactClicked(data) {
817
894
  this.selectedArtifactId = data.artifactId;
818
- // If versionId is provided, find the version number
895
+ // If versionId is provided, find the version number from display data (no lazy load needed)
819
896
  if (data.versionId) {
820
897
  for (const [detailId, artifactList] of this.artifactsByDetailId.entries()) {
821
898
  for (const artifactInfo of artifactList) {
822
- if (artifactInfo.version.ID === data.versionId) {
823
- this.selectedVersionNumber = artifactInfo.version.VersionNumber;
899
+ if (artifactInfo.artifactVersionId === data.versionId) {
900
+ this.selectedVersionNumber = artifactInfo.versionNumber;
824
901
  console.log(`📦 Opening artifact viewer for v${this.selectedVersionNumber}`);
825
902
  break;
826
903
  }
@@ -853,6 +930,28 @@ export class ConversationChatAreaComponent {
853
930
  this.showArtifactPanel = false;
854
931
  this.selectedArtifactId = null;
855
932
  }
933
+ onSaveToCollectionRequested(event) {
934
+ this.collectionPickerArtifactId = event.artifactId;
935
+ this.collectionPickerExcludedIds = event.excludedCollectionIds;
936
+ this.showCollectionPicker = true;
937
+ }
938
+ async onCollectionPickerSaved(collectionIds) {
939
+ if (!this.collectionPickerArtifactId || !this.artifactViewerComponent) {
940
+ return;
941
+ }
942
+ // Call the artifact viewer's save method
943
+ const success = await this.artifactViewerComponent.saveToCollections(collectionIds);
944
+ if (success) {
945
+ this.showCollectionPicker = false;
946
+ this.collectionPickerArtifactId = null;
947
+ this.collectionPickerExcludedIds = [];
948
+ }
949
+ }
950
+ onCollectionPickerCancelled() {
951
+ this.showCollectionPicker = false;
952
+ this.collectionPickerArtifactId = null;
953
+ this.collectionPickerExcludedIds = [];
954
+ }
856
955
  /**
857
956
  * Helper method to check if a conversation detail has an artifact
858
957
  * Used by message components to determine whether to show artifact card
@@ -862,15 +961,19 @@ export class ConversationChatAreaComponent {
862
961
  }
863
962
  /**
864
963
  * Get artifact info for a conversation detail
865
- * Returns the first artifact if multiple exist (for backward compatibility with message display)
964
+ * Returns the LAST (most recent) artifact if multiple exist
965
+ * Returns LazyArtifactInfo - caller can trigger lazy load if full entities needed
866
966
  */
867
967
  getArtifactInfo(conversationDetailId) {
868
968
  const artifactList = this.artifactsByDetailId.get(conversationDetailId);
869
- return artifactList && artifactList.length > 0 ? artifactList[0] : undefined;
969
+ return artifactList && artifactList.length > 0
970
+ ? artifactList[artifactList.length - 1]
971
+ : undefined;
870
972
  }
871
973
  /**
872
974
  * Get ALL artifacts for a conversation detail
873
975
  * Use this when you need to display all artifacts (e.g., in a list)
976
+ * Returns LazyArtifactInfo array - caller can trigger lazy load if full entities needed
874
977
  */
875
978
  getAllArtifactsForDetail(conversationDetailId) {
876
979
  return this.artifactsByDetailId.get(conversationDetailId) || [];
@@ -981,20 +1084,24 @@ export class ConversationChatAreaComponent {
981
1084
  element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
982
1085
  }
983
1086
  }
984
- static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationStateService), i0.ɵɵdirectiveInject(i2.DataCacheService), i0.ɵɵdirectiveInject(i3.AgentStateService), i0.ɵɵdirectiveInject(i4.ConversationAgentService), i0.ɵɵdirectiveInject(i5.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
1087
+ static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationStateService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService)); };
985
1088
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
986
1089
  i0.ɵɵviewQuery(_c0, 5);
1090
+ i0.ɵɵviewQuery(MessageInputComponent, 5);
1091
+ i0.ɵɵviewQuery(ArtifactViewerPanelComponent, 5);
987
1092
  } if (rf & 2) {
988
1093
  let _t;
989
1094
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
990
- } }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked" }, decls: 18, vars: 21, consts: [["scrollContainer", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "artifactClicked", "messageEdited", "openEntityRecord", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [3, "conversationId", "currentUser", "conversationHistory", "disabled"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [1, "chat-header"], [1, "chat-info"], [1, "chat-title"], ["class", "project-tag", "title", "Assign to project", 3, "click", 4, "ngIf"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions"], [3, "taskClicked", "currentUser"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["title", "Assign to project", 1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "loading-peripheral-content"], [1, "fas", "fa-spinner", "fa-spin"], [3, "conversationId", "currentUser", "conversationHistory", "disabled", "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", 4, "ngIf"], [3, "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", "conversationId", "currentUser", "conversationHistory", "disabled"], [1, "resize-handle", 3, "mousedown"], [1, "chat-artifact-pane"], [3, "closed", "artifactId", "currentUser", "environmentId", "versionNumber", "refreshTrigger"], [3, "closed", "replyAdded", "parentMessageId", "conversationId", "currentUser"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-body", "artifacts-grid"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
1095
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponent = _t.first);
1096
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
1097
+ } }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked" }, decls: 19, vars: 22, consts: [["scrollContainer", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [3, "conversationId", "currentUser", "conversationHistory", "disabled"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [1, "chat-header"], [1, "chat-info"], [1, "chat-title"], ["class", "project-tag", "title", "Assign to project", 3, "click", 4, "ngIf"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions"], [3, "taskClicked", "currentUser"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["title", "Assign to project", 1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "loading-peripheral-content"], [1, "fas", "fa-spinner", "fa-spin"], [3, "conversationId", "currentUser", "conversationHistory", "disabled", "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", 4, "ngIf"], [3, "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", "conversationId", "currentUser", "conversationHistory", "disabled"], [1, "resize-handle", 3, "mousedown"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "artifactId", "currentUser", "environmentId", "versionNumber", "refreshTrigger"], [3, "closed", "replyAdded", "parentMessageId", "conversationId", "currentUser"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-body", "artifacts-grid"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"], [3, "saved", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
991
1098
  const _r1 = i0.ɵɵgetCurrentView();
992
1099
  i0.ɵɵelementStart(0, "div", 1);
993
1100
  i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 19, 11, "div", 2);
994
1101
  i0.ɵɵelementStart(2, "div", 3)(3, "div", 4)(4, "div", 5)(5, "div", 6, 0);
995
1102
  i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Template_div_scroll_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.checkScroll()); });
996
1103
  i0.ɵɵelementStart(7, "mj-conversation-message-list", 7);
997
- i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_replyInThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_viewThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Template_mj_conversation_message_list_retryMessage_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRetryMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Template_mj_conversation_message_list_artifactClicked_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Template_mj_conversation_message_list_messageEdited_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Template_mj_conversation_message_list_openEntityRecord_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onOpenEntityRecord($event)); });
1104
+ i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_replyInThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_viewThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Template_mj_conversation_message_list_retryMessage_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRetryMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Template_mj_conversation_message_list_artifactClicked_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Template_mj_conversation_message_list_messageEdited_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Template_mj_conversation_message_list_openEntityRecord_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Template_mj_conversation_message_list_suggestedResponseSelected_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSuggestedResponseSelected($event)); });
998
1105
  i0.ɵɵelementEnd();
999
1106
  i0.ɵɵtemplate(8, ConversationChatAreaComponent_span_8_Template, 2, 0, "span", 8);
1000
1107
  i0.ɵɵelementEnd();
@@ -1010,7 +1117,7 @@ export class ConversationChatAreaComponent {
1010
1117
  i0.ɵɵelementStart(15, "mj-members-modal", 14);
1011
1118
  i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_15_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_15_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); });
1012
1119
  i0.ɵɵelementEnd();
1013
- i0.ɵɵtemplate(16, ConversationChatAreaComponent_Conditional_16_Template, 9, 3, "div", 15)(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 15);
1120
+ i0.ɵɵtemplate(16, ConversationChatAreaComponent_Conditional_16_Template, 9, 3, "div", 15)(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 15)(18, ConversationChatAreaComponent_Conditional_18_Template, 1, 4, "mj-artifact-collection-picker-modal", 16);
1014
1121
  } if (rf & 2) {
1015
1122
  i0.ɵɵadvance();
1016
1123
  i0.ɵɵproperty("ngIf", ctx.conversationState.activeConversation);
@@ -1034,12 +1141,14 @@ export class ConversationChatAreaComponent {
1034
1141
  i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversationState.activeConversation ? 16 : -1);
1035
1142
  i0.ɵɵadvance();
1036
1143
  i0.ɵɵconditional(ctx.showArtifactsModal ? 17 : -1);
1037
- } }, dependencies: [i6.NgIf, i7.ArtifactViewerPanelComponent, i8.MessageListComponent, i9.MessageInputComponent, i10.ThreadPanelComponent, i11.ProjectSelectorComponent, i12.TasksDropdownComponent, i13.ActiveAgentIndicatorComponent, i14.MembersModalComponent, i15.ExportModalComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.chat-members[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.chat-members[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: 300px;\n overflow: hidden;\n transition: width 0.3s ease;\n}\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n.resize-handle[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] placeholder[_ngcontent-%COMP%] -[_ngcontent-%COMP%] replaces[_ngcontent-%COMP%] input[_ngcontent-%COMP%] while[_ngcontent-%COMP%] loading\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n }\n\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] content[_ngcontent-%COMP%] styling\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] });
1144
+ i0.ɵɵadvance();
1145
+ i0.ɵɵconditional(ctx.showCollectionPicker ? 18 : -1);
1146
+ } }, dependencies: [i6.NgIf, i7.ArtifactViewerPanelComponent, i8.ArtifactCollectionPickerModalComponent, i9.MessageListComponent, i10.MessageInputComponent, i11.ThreadPanelComponent, i12.ProjectSelectorComponent, i13.TasksDropdownComponent, i14.ActiveAgentIndicatorComponent, i15.MembersModalComponent, i16.ExportModalComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.chat-members[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.chat-members[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: 300px;\n overflow: hidden;\n transition: width 0.3s ease;\n}\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n.resize-handle[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] placeholder[_ngcontent-%COMP%] -[_ngcontent-%COMP%] replaces[_ngcontent-%COMP%] input[_ngcontent-%COMP%] while[_ngcontent-%COMP%] loading\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n }\n\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] content[_ngcontent-%COMP%] styling\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] });
1038
1147
  }
1039
1148
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
1040
1149
  type: Component,
1041
- args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversationState.activeConversation as conversation\">\n <div class=\"chat-info\">\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span>{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }}</span>\n </button>\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCount > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCount }} artifact{{ artifactCount !== 1 ? 's' : '' }}</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <mj-tasks-dropdown\n [currentUser]=\"currentUser\"\n (taskClicked)=\"onTaskClicked($event)\">\n </mj-tasks-dropdown>\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n Share\n </button>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\" [class.full-width]=\"!showArtifactPanel\">\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversationState.activeConversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"artifactsByDetailId\"\n [agentRunMap]=\"agentRunsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <div class=\"loading-peripheral-content\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading conversation data...</span>\n </div>\n </div>\n } @else {\n <!-- Input Component -->\n <mj-message-input\n *ngIf=\"conversationState.activeConversation\"\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"messages\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\">\n </mj-message-input>\n }\n </div>\n </div>\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\"></div>\n <div class=\"chat-artifact-pane\" [style.width.%]=\"artifactPaneWidth\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\">\n </mj-artifact-viewer-panel>\n </div>\n }\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (conversationState.activeThreadId) {\n <mj-thread-panel\n [parentMessageId]=\"conversationState.activeThreadId\"\n [conversationId]=\"conversationState.activeConversation?.ID || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversationState.activeConversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversationState.activeConversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversationState.activeConversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversationState.activeConversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\" [class.expanded]=\"expandedArtifactId === artifact.artifactId\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag i {\n font-size: 10px;\n}\n.chat-members {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members i {\n font-size: 12px;\n}\n.chat-members span {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: 300px;\n overflow: hidden;\n transition: width 0.3s ease;\n}\n.chat-messages-pane.full-width {\n width: 100%;\n}\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle:hover {\n background: #3B82F6;\n}\n.resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n// Loading placeholder - replaces input while loading\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon i {\n font-size: 18px;\n}\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n }\n\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n// Loading content styling\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] }]
1042
- }], () => [{ type: i1.ConversationStateService }, { type: i2.DataCacheService }, { type: i3.AgentStateService }, { type: i4.ConversationAgentService }, { type: i5.ActiveTasksService }, { type: i0.ChangeDetectorRef }], { environmentId: [{
1150
+ args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversationState.activeConversation as conversation\">\n <div class=\"chat-info\">\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span>{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }}</span>\n </button>\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCount > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCount }} artifact{{ artifactCount !== 1 ? 's' : '' }}</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <mj-tasks-dropdown\n [currentUser]=\"currentUser\"\n (taskClicked)=\"onTaskClicked($event)\">\n </mj-tasks-dropdown>\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n Share\n </button>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\" [class.full-width]=\"!showArtifactPanel\">\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversationState.activeConversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"artifactsByDetailId\"\n [agentRunMap]=\"agentRunsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <div class=\"loading-peripheral-content\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading conversation data...</span>\n </div>\n </div>\n } @else {\n <!-- Input Component -->\n <mj-message-input\n *ngIf=\"conversationState.activeConversation\"\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"messages\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\">\n </mj-message-input>\n }\n </div>\n </div>\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\"></div>\n <div class=\"chat-artifact-pane\" [style.width.%]=\"artifactPaneWidth\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (conversationState.activeThreadId) {\n <mj-thread-panel\n [parentMessageId]=\"conversationState.activeThreadId\"\n [conversationId]=\"conversationState.activeConversation?.ID || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversationState.activeConversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversationState.activeConversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversationState.activeConversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversationState.activeConversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\" [class.expanded]=\"expandedArtifactId === artifact.artifactId\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n (saved)=\"onCollectionPickerSaved($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag i {\n font-size: 10px;\n}\n.chat-members {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members i {\n font-size: 12px;\n}\n.chat-members span {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: 300px;\n overflow: hidden;\n transition: width 0.3s ease;\n}\n.chat-messages-pane.full-width {\n width: 100%;\n}\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle:hover {\n background: #3B82F6;\n}\n.resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n// Loading placeholder - replaces input while loading\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon i {\n font-size: 18px;\n}\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n }\n\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n// Loading content styling\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] }]
1151
+ }], () => [{ type: i1.ConversationStateService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }], { environmentId: [{
1043
1152
  type: Input
1044
1153
  }], currentUser: [{
1045
1154
  type: Input
@@ -1052,6 +1161,12 @@ export class ConversationChatAreaComponent {
1052
1161
  }], scrollContainer: [{
1053
1162
  type: ViewChild,
1054
1163
  args: ['scrollContainer']
1164
+ }], messageInputComponent: [{
1165
+ type: ViewChild,
1166
+ args: [MessageInputComponent]
1167
+ }], artifactViewerComponent: [{
1168
+ type: ViewChild,
1169
+ args: [ArtifactViewerPanelComponent]
1055
1170
  }] }); })();
1056
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 16 }); })();
1171
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 20 }); })();
1057
1172
  //# sourceMappingURL=conversation-chat-area.component.js.map