@memberjunction/ng-conversations 5.40.2 → 5.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/README.md +57 -0
  2. package/dist/__tests__/channel-optional-surface.test.d.ts +2 -0
  3. package/dist/__tests__/channel-optional-surface.test.d.ts.map +1 -0
  4. package/dist/__tests__/channel-optional-surface.test.js +53 -0
  5. package/dist/__tests__/channel-optional-surface.test.js.map +1 -0
  6. package/dist/__tests__/chat-events.test.d.ts +14 -0
  7. package/dist/__tests__/chat-events.test.d.ts.map +1 -0
  8. package/dist/__tests__/chat-events.test.js +109 -0
  9. package/dist/__tests__/chat-events.test.js.map +1 -0
  10. package/dist/__tests__/conversation-naming.test.d.ts +2 -0
  11. package/dist/__tests__/conversation-naming.test.d.ts.map +1 -0
  12. package/dist/__tests__/conversation-naming.test.js +110 -0
  13. package/dist/__tests__/conversation-naming.test.js.map +1 -0
  14. package/dist/__tests__/delegation-result-parser.test.d.ts +2 -0
  15. package/dist/__tests__/delegation-result-parser.test.d.ts.map +1 -0
  16. package/dist/__tests__/delegation-result-parser.test.js +107 -0
  17. package/dist/__tests__/delegation-result-parser.test.js.map +1 -0
  18. package/dist/__tests__/event-wiring.test.d.ts +15 -0
  19. package/dist/__tests__/event-wiring.test.d.ts.map +1 -0
  20. package/dist/__tests__/event-wiring.test.js +100 -0
  21. package/dist/__tests__/event-wiring.test.js.map +1 -0
  22. package/dist/__tests__/narration-template.test.d.ts +2 -0
  23. package/dist/__tests__/narration-template.test.d.ts.map +1 -0
  24. package/dist/__tests__/narration-template.test.js +76 -0
  25. package/dist/__tests__/narration-template.test.js.map +1 -0
  26. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +2 -0
  27. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +1 -0
  28. package/dist/__tests__/realtime-agent-picker-models.test.js +49 -0
  29. package/dist/__tests__/realtime-agent-picker-models.test.js.map +1 -0
  30. package/dist/__tests__/realtime-audio-visuals.test.d.ts +2 -0
  31. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +1 -0
  32. package/dist/__tests__/realtime-audio-visuals.test.js +123 -0
  33. package/dist/__tests__/realtime-audio-visuals.test.js.map +1 -0
  34. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +2 -0
  35. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +1 -0
  36. package/dist/__tests__/realtime-delegation-card-cancel.test.js +48 -0
  37. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +1 -0
  38. package/dist/__tests__/realtime-disclosure.test.d.ts +2 -0
  39. package/dist/__tests__/realtime-disclosure.test.d.ts.map +1 -0
  40. package/dist/__tests__/realtime-disclosure.test.js +164 -0
  41. package/dist/__tests__/realtime-disclosure.test.js.map +1 -0
  42. package/dist/__tests__/realtime-pairing.test.d.ts +2 -0
  43. package/dist/__tests__/realtime-pairing.test.d.ts.map +1 -0
  44. package/dist/__tests__/realtime-pairing.test.js +207 -0
  45. package/dist/__tests__/realtime-pairing.test.js.map +1 -0
  46. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +2 -0
  47. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +1 -0
  48. package/dist/__tests__/realtime-review-lifecycle.test.js +154 -0
  49. package/dist/__tests__/realtime-review-lifecycle.test.js.map +1 -0
  50. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +2 -0
  51. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +1 -0
  52. package/dist/__tests__/realtime-session-cancel-usage.test.js +230 -0
  53. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +1 -0
  54. package/dist/__tests__/realtime-session-channels.test.d.ts +2 -0
  55. package/dist/__tests__/realtime-session-channels.test.d.ts.map +1 -0
  56. package/dist/__tests__/realtime-session-channels.test.js +252 -0
  57. package/dist/__tests__/realtime-session-channels.test.js.map +1 -0
  58. package/dist/__tests__/realtime-session-client-tools.test.d.ts +2 -0
  59. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +1 -0
  60. package/dist/__tests__/realtime-session-client-tools.test.js +103 -0
  61. package/dist/__tests__/realtime-session-client-tools.test.js.map +1 -0
  62. package/dist/__tests__/realtime-session-minimized.test.d.ts +2 -0
  63. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +1 -0
  64. package/dist/__tests__/realtime-session-minimized.test.js +32 -0
  65. package/dist/__tests__/realtime-session-minimized.test.js.map +1 -0
  66. package/dist/__tests__/realtime-session-mint.test.d.ts +2 -0
  67. package/dist/__tests__/realtime-session-mint.test.d.ts.map +1 -0
  68. package/dist/__tests__/realtime-session-mint.test.js +69 -0
  69. package/dist/__tests__/realtime-session-mint.test.js.map +1 -0
  70. package/dist/__tests__/realtime-session-policy.test.d.ts +2 -0
  71. package/dist/__tests__/realtime-session-policy.test.d.ts.map +1 -0
  72. package/dist/__tests__/realtime-session-policy.test.js +303 -0
  73. package/dist/__tests__/realtime-session-policy.test.js.map +1 -0
  74. package/dist/__tests__/realtime-session-review.service.test.d.ts +2 -0
  75. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +1 -0
  76. package/dist/__tests__/realtime-session-review.service.test.js +743 -0
  77. package/dist/__tests__/realtime-session-review.service.test.js.map +1 -0
  78. package/dist/__tests__/realtime-session-state.test.d.ts +2 -0
  79. package/dist/__tests__/realtime-session-state.test.d.ts.map +1 -0
  80. package/dist/__tests__/realtime-session-state.test.js +83 -0
  81. package/dist/__tests__/realtime-session-state.test.js.map +1 -0
  82. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +2 -0
  83. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +1 -0
  84. package/dist/__tests__/realtime-session-timeline-card.test.js +106 -0
  85. package/dist/__tests__/realtime-session-timeline-card.test.js.map +1 -0
  86. package/dist/__tests__/realtime-session-timeline.test.d.ts +2 -0
  87. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +1 -0
  88. package/dist/__tests__/realtime-session-timeline.test.js +142 -0
  89. package/dist/__tests__/realtime-session-timeline.test.js.map +1 -0
  90. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +19 -0
  91. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +1 -0
  92. package/dist/__tests__/realtime-sessions-adapter.test.js +188 -0
  93. package/dist/__tests__/realtime-sessions-adapter.test.js.map +1 -0
  94. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +2 -0
  95. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +1 -0
  96. package/dist/__tests__/realtime-surface-panel-prefs.test.js +100 -0
  97. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +1 -0
  98. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +2 -0
  99. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +1 -0
  100. package/dist/__tests__/realtime-surface-tabs-model.test.js +193 -0
  101. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +1 -0
  102. package/dist/__tests__/remote-browser-audio-player.test.d.ts +2 -0
  103. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +1 -0
  104. package/dist/__tests__/remote-browser-audio-player.test.js +137 -0
  105. package/dist/__tests__/remote-browser-audio-player.test.js.map +1 -0
  106. package/dist/__tests__/remote-browser-channel.test.d.ts +2 -0
  107. package/dist/__tests__/remote-browser-channel.test.d.ts.map +1 -0
  108. package/dist/__tests__/remote-browser-channel.test.js +585 -0
  109. package/dist/__tests__/remote-browser-channel.test.js.map +1 -0
  110. package/dist/__tests__/slot-defaults.test.d.ts +24 -0
  111. package/dist/__tests__/slot-defaults.test.d.ts.map +1 -0
  112. package/dist/__tests__/slot-defaults.test.js +63 -0
  113. package/dist/__tests__/slot-defaults.test.js.map +1 -0
  114. package/dist/__tests__/user-authorization.test.d.ts +2 -0
  115. package/dist/__tests__/user-authorization.test.d.ts.map +1 -0
  116. package/dist/__tests__/user-authorization.test.js +97 -0
  117. package/dist/__tests__/user-authorization.test.js.map +1 -0
  118. package/dist/__tests__/voice-session-narration.test.d.ts +2 -0
  119. package/dist/__tests__/voice-session-narration.test.d.ts.map +1 -0
  120. package/dist/__tests__/voice-session-narration.test.js +609 -0
  121. package/dist/__tests__/voice-session-narration.test.js.map +1 -0
  122. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +2 -0
  123. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +1 -0
  124. package/dist/__tests__/whiteboard-artifact-viewer.test.js +101 -0
  125. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +1 -0
  126. package/dist/__tests__/whiteboard-channel.test.d.ts +2 -0
  127. package/dist/__tests__/whiteboard-channel.test.d.ts.map +1 -0
  128. package/dist/__tests__/whiteboard-channel.test.js +260 -0
  129. package/dist/__tests__/whiteboard-channel.test.js.map +1 -0
  130. package/dist/__tests__/whiteboard-restore-state.test.d.ts +2 -0
  131. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +1 -0
  132. package/dist/__tests__/whiteboard-restore-state.test.js +108 -0
  133. package/dist/__tests__/whiteboard-restore-state.test.js.map +1 -0
  134. package/dist/lib/components/collection/collections-full-view.component.d.ts +105 -2
  135. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  136. package/dist/lib/components/collection/collections-full-view.component.js +1378 -489
  137. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  138. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +209 -3
  139. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  140. package/dist/lib/components/conversation/conversation-chat-area.component.js +924 -350
  141. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  142. package/dist/lib/components/conversation/conversation-list.component.d.ts +98 -5
  143. package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
  144. package/dist/lib/components/conversation/conversation-list.component.js +1102 -401
  145. package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
  146. package/dist/lib/components/mention/mention-dropdown.component.js +35 -17
  147. package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
  148. package/dist/lib/components/mention/mention-editor.component.d.ts +4 -0
  149. package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
  150. package/dist/lib/components/mention/mention-editor.component.js +43 -19
  151. package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
  152. package/dist/lib/components/message/message-input-box.component.d.ts +17 -1
  153. package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
  154. package/dist/lib/components/message/message-input-box.component.js +73 -15
  155. package/dist/lib/components/message/message-input-box.component.js.map +1 -1
  156. package/dist/lib/components/message/message-input.component.d.ts +142 -6
  157. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  158. package/dist/lib/components/message/message-input.component.js +328 -82
  159. package/dist/lib/components/message/message-input.component.js.map +1 -1
  160. package/dist/lib/components/message/message-item.component.d.ts +28 -3
  161. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  162. package/dist/lib/components/message/message-item.component.js +180 -108
  163. package/dist/lib/components/message/message-item.component.js.map +1 -1
  164. package/dist/lib/components/message/message-list.component.d.ts +81 -2
  165. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  166. package/dist/lib/components/message/message-list.component.js +252 -87
  167. package/dist/lib/components/message/message-list.component.js.map +1 -1
  168. package/dist/lib/components/project/project-form-modal.component.d.ts +5 -1
  169. package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
  170. package/dist/lib/components/project/project-form-modal.component.js +104 -85
  171. package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
  172. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +304 -0
  173. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -0
  174. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +198 -0
  175. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -0
  176. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +25 -0
  177. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -0
  178. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +140 -0
  179. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -0
  180. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +35 -0
  181. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -0
  182. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +58 -0
  183. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -0
  184. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +63 -0
  185. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -0
  186. package/dist/lib/components/realtime/realtime-activity-rail.component.js +260 -0
  187. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -0
  188. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +117 -0
  189. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -0
  190. package/dist/lib/components/realtime/realtime-agent-banner.component.js +504 -0
  191. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -0
  192. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +179 -0
  193. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -0
  194. package/dist/lib/components/realtime/realtime-agent-picker.component.js +634 -0
  195. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -0
  196. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +97 -0
  197. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -0
  198. package/dist/lib/components/realtime/realtime-audio-visuals.js +139 -0
  199. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -0
  200. package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts +29 -0
  201. package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts.map +1 -0
  202. package/dist/lib/components/realtime/realtime-channel-strip.component.js +69 -0
  203. package/dist/lib/components/realtime/realtime-channel-strip.component.js.map +1 -0
  204. package/dist/lib/components/realtime/realtime-composer.component.d.ts +65 -0
  205. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -0
  206. package/dist/lib/components/realtime/realtime-composer.component.js +256 -0
  207. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -0
  208. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +71 -0
  209. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -0
  210. package/dist/lib/components/realtime/realtime-delegation-card.component.js +324 -0
  211. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -0
  212. package/dist/lib/components/realtime/realtime-disclosure.d.ts +135 -0
  213. package/dist/lib/components/realtime/realtime-disclosure.d.ts.map +1 -0
  214. package/dist/lib/components/realtime/realtime-disclosure.js +188 -0
  215. package/dist/lib/components/realtime/realtime-disclosure.js.map +1 -0
  216. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +491 -0
  217. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -0
  218. package/dist/lib/components/realtime/realtime-session-overlay.component.js +1274 -0
  219. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -0
  220. package/dist/lib/components/realtime/realtime-session-state.d.ts +191 -0
  221. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -0
  222. package/dist/lib/components/realtime/realtime-session-state.js +244 -0
  223. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -0
  224. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +56 -0
  225. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -0
  226. package/dist/lib/components/realtime/realtime-session-thread.component.js +246 -0
  227. package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -0
  228. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +51 -0
  229. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -0
  230. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +193 -0
  231. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -0
  232. package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts +77 -0
  233. package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts.map +1 -0
  234. package/dist/lib/components/realtime/realtime-surface-panel-prefs.js +114 -0
  235. package/dist/lib/components/realtime/realtime-surface-panel-prefs.js.map +1 -0
  236. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +173 -0
  237. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -0
  238. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +496 -0
  239. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -0
  240. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +181 -0
  241. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -0
  242. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +223 -0
  243. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -0
  244. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts +163 -0
  245. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts.map +1 -0
  246. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js +309 -0
  247. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js.map +1 -0
  248. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +201 -0
  249. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -0
  250. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +681 -0
  251. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -0
  252. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +379 -0
  253. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -0
  254. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +914 -0
  255. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -0
  256. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +87 -0
  257. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -0
  258. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +223 -0
  259. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -0
  260. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts +48 -0
  261. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts.map +1 -0
  262. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js +180 -0
  263. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js.map +1 -0
  264. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +119 -0
  265. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -0
  266. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +274 -0
  267. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -0
  268. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts +11 -0
  269. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts.map +1 -0
  270. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js +98 -0
  271. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js.map +1 -0
  272. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts +9 -0
  273. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts.map +1 -0
  274. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js +35 -0
  275. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js.map +1 -0
  276. package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts +28 -0
  277. package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts.map +1 -0
  278. package/dist/lib/components/slots/mj-chat-empty-state-default.component.js +104 -0
  279. package/dist/lib/components/slots/mj-chat-empty-state-default.component.js.map +1 -0
  280. package/dist/lib/components/slots/mj-chat-header-default.component.d.ts +11 -0
  281. package/dist/lib/components/slots/mj-chat-header-default.component.d.ts.map +1 -0
  282. package/dist/lib/components/slots/mj-chat-header-default.component.js +103 -0
  283. package/dist/lib/components/slots/mj-chat-header-default.component.js.map +1 -0
  284. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts +15 -0
  285. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts.map +1 -0
  286. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js +73 -0
  287. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js.map +1 -0
  288. package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts +9 -0
  289. package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts.map +1 -0
  290. package/dist/lib/components/slots/mj-chat-message-extra-default.component.js +34 -0
  291. package/dist/lib/components/slots/mj-chat-message-extra-default.component.js.map +1 -0
  292. package/dist/lib/components/slots/slot-interfaces.d.ts +95 -0
  293. package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -0
  294. package/dist/lib/components/slots/slot-interfaces.js +18 -0
  295. package/dist/lib/components/slots/slot-interfaces.js.map +1 -0
  296. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +15 -0
  297. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  298. package/dist/lib/components/workspace/conversation-workspace.component.js +41 -12
  299. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  300. package/dist/lib/conversations.module.d.ts +12 -1
  301. package/dist/lib/conversations.module.d.ts.map +1 -1
  302. package/dist/lib/conversations.module.js +93 -5
  303. package/dist/lib/conversations.module.js.map +1 -1
  304. package/dist/lib/directives/chat-slot.directive.d.ts +44 -0
  305. package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -0
  306. package/dist/lib/directives/chat-slot.directive.js +54 -0
  307. package/dist/lib/directives/chat-slot.directive.js.map +1 -0
  308. package/dist/lib/events/chat-events.d.ts +137 -0
  309. package/dist/lib/events/chat-events.d.ts.map +1 -0
  310. package/dist/lib/events/chat-events.js +189 -0
  311. package/dist/lib/events/chat-events.js.map +1 -0
  312. package/dist/lib/models/conversation-state.model.d.ts +2 -1
  313. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  314. package/dist/lib/models/conversation-state.model.js.map +1 -1
  315. package/dist/lib/services/artifact-state.service.d.ts +1 -1
  316. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  317. package/dist/lib/services/artifact-state.service.js +29 -7
  318. package/dist/lib/services/artifact-state.service.js.map +1 -1
  319. package/dist/lib/services/conversation-agent.service.d.ts +60 -74
  320. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  321. package/dist/lib/services/conversation-agent.service.js +100 -313
  322. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  323. package/dist/lib/services/conversation-bridge.service.d.ts +11 -70
  324. package/dist/lib/services/conversation-bridge.service.d.ts.map +1 -1
  325. package/dist/lib/services/conversation-bridge.service.js +51 -85
  326. package/dist/lib/services/conversation-bridge.service.js.map +1 -1
  327. package/dist/lib/services/conversation-naming.d.ts +63 -0
  328. package/dist/lib/services/conversation-naming.d.ts.map +1 -0
  329. package/dist/lib/services/conversation-naming.js +58 -0
  330. package/dist/lib/services/conversation-naming.js.map +1 -0
  331. package/dist/lib/services/conversation-streaming.service.d.ts +24 -154
  332. package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
  333. package/dist/lib/services/conversation-streaming.service.js +39 -361
  334. package/dist/lib/services/conversation-streaming.service.js.map +1 -1
  335. package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts +10 -0
  336. package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts.map +1 -0
  337. package/dist/lib/services/conversations-runtime-bootstrap.service.js +104 -0
  338. package/dist/lib/services/conversations-runtime-bootstrap.service.js.map +1 -0
  339. package/dist/lib/services/delegation-result-parser.d.ts +45 -0
  340. package/dist/lib/services/delegation-result-parser.d.ts.map +1 -0
  341. package/dist/lib/services/delegation-result-parser.js +48 -0
  342. package/dist/lib/services/delegation-result-parser.js.map +1 -0
  343. package/dist/lib/services/mention-autocomplete.service.d.ts +19 -4
  344. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  345. package/dist/lib/services/mention-autocomplete.service.js +65 -4
  346. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  347. package/dist/lib/services/mention-parser.service.d.ts +8 -53
  348. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  349. package/dist/lib/services/mention-parser.service.js +32 -243
  350. package/dist/lib/services/mention-parser.service.js.map +1 -1
  351. package/dist/lib/services/narration-template.d.ts +42 -0
  352. package/dist/lib/services/narration-template.d.ts.map +1 -0
  353. package/dist/lib/services/narration-template.js +73 -0
  354. package/dist/lib/services/narration-template.js.map +1 -0
  355. package/dist/lib/services/realtime-pairing.d.ts +121 -0
  356. package/dist/lib/services/realtime-pairing.d.ts.map +1 -0
  357. package/dist/lib/services/realtime-pairing.js +160 -0
  358. package/dist/lib/services/realtime-pairing.js.map +1 -0
  359. package/dist/lib/services/realtime-session-review.service.d.ts +233 -0
  360. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -0
  361. package/dist/lib/services/realtime-session-review.service.js +417 -0
  362. package/dist/lib/services/realtime-session-review.service.js.map +1 -0
  363. package/dist/lib/services/realtime-session.service.d.ts +739 -0
  364. package/dist/lib/services/realtime-session.service.d.ts.map +1 -0
  365. package/dist/lib/services/realtime-session.service.js +1647 -0
  366. package/dist/lib/services/realtime-session.service.js.map +1 -0
  367. package/dist/lib/services/realtime-sessions-adapter.d.ts +54 -0
  368. package/dist/lib/services/realtime-sessions-adapter.d.ts.map +1 -0
  369. package/dist/lib/services/realtime-sessions-adapter.js +154 -0
  370. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -0
  371. package/dist/lib/services/user-authorization.d.ts +67 -0
  372. package/dist/lib/services/user-authorization.d.ts.map +1 -0
  373. package/dist/lib/services/user-authorization.js +66 -0
  374. package/dist/lib/services/user-authorization.js.map +1 -0
  375. package/dist/lib/utils/realtime-session-timeline.d.ts +84 -0
  376. package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -0
  377. package/dist/lib/utils/realtime-session-timeline.js +94 -0
  378. package/dist/lib/utils/realtime-session-timeline.js.map +1 -0
  379. package/dist/public-api.d.ts +41 -0
  380. package/dist/public-api.d.ts.map +1 -1
  381. package/dist/public-api.js +50 -0
  382. package/dist/public-api.js.map +1 -1
  383. package/package.json +27 -24
  384. package/dist/__tests__/conversation-bridge.service.test.d.ts +0 -2
  385. package/dist/__tests__/conversation-bridge.service.test.d.ts.map +0 -1
  386. package/dist/__tests__/conversation-bridge.service.test.js +0 -98
  387. package/dist/__tests__/conversation-bridge.service.test.js.map +0 -1
  388. package/dist/__tests__/mention-parser.test.d.ts +0 -2
  389. package/dist/__tests__/mention-parser.test.d.ts.map +0 -1
  390. package/dist/__tests__/mention-parser.test.js +0 -154
  391. package/dist/__tests__/mention-parser.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-list.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-list.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, HostListener, ChangeDetectorRef } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity } from '@memberjunction/core-entities';\nimport { ConversationEngine } from '@memberjunction/core-entities';\nimport { DialogService } from '../../services/dialog.service';\nimport { NotificationService } from '../../services/notification.service';\nimport { ActiveTasksService } from '../../services/active-tasks.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n@Component({\n standalone: false,\n selector: 'mj-conversation-list',\n template: `\n <div class=\"conversation-list\">\n <div class=\"list-header\">\n <div class=\"header-top\">\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search conversations...\"\n [(ngModel)]=\"searchQuery\">\n @if (!isSelectionMode) {\n <div class=\"header-menu-container\">\n <button class=\"btn-menu\" (click)=\"toggleHeaderMenu($event)\" title=\"Options\">\n <i class=\"fas fa-ellipsis-v\"></i>\n </button>\n @if (isHeaderMenuOpen) {\n <div class=\"header-dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"onRefreshConversationsClick($event)\" [disabled]=\"isRefreshing\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"isRefreshing\"></i>\n <span>{{ isRefreshing ? 'Refreshing...' : 'Refresh' }}</span>\n </button>\n <button class=\"dropdown-item\" (click)=\"onSelectConversationsClick($event)\">\n <i class=\"fas fa-check-square\"></i>\n <span>Select Conversations</span>\n </button>\n @if (!isMobileView) {\n <button class=\"dropdown-item\" (click)=\"onUnpinSidebarClick($event)\">\n <i class=\"fas fa-table-columns\"></i>\n <span>Hide Sidebar</span>\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n <button class=\"btn-new-conversation\" (click)=\"createNewConversation()\" title=\"New Conversation\">\n <i class=\"fas fa-plus\"></i>\n <span>New Conversation</span>\n </button>\n <div class=\"list-content\">\n <!-- Pinned Section (only show if there are pinned conversations) -->\n @if (pinnedConversations.length > 0) {\n <div class=\"sidebar-section pinned-section\">\n <div class=\"section-header\" [class.expanded]=\"pinnedExpanded\" (click)=\"togglePinned()\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <i class=\"fas fa-thumbtack section-icon\"></i>\n <span>Pinned</span>\n </div>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"pinnedExpanded\">\n @for (conversation of pinnedConversations; track conversation.ID) {\n <div class=\"conversation-item\"\n [class.active]=\"IsConversationActive(conversation)\"\n [class.renamed]=\"IsConversationRenamed(conversation)\"\n (click)=\"handleConversationClick(conversation)\">\n @if (isSelectionMode) {\n <div class=\"conversation-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"selectedConversationIds.has(conversation.ID)\"\n (click)=\"$event.stopPropagation(); toggleConversationSelection(conversation.ID)\">\n </div>\n }\n <div class=\"conversation-icon-wrapper\">\n @if (hasActiveTasks(conversation.ID)) {\n <div class=\"conversation-icon has-tasks\">\n <i class=\"fas fa-spinner fa-pulse\"></i>\n </div>\n }\n <div class=\"badge-overlay\">\n <mj-notification-badge [conversationId]=\"conversation.ID\"></mj-notification-badge>\n </div>\n </div>\n <div class=\"conversation-info\" [title]=\"conversation.Name + (conversation.Description ? '\\n' + conversation.Description : '')\">\n <div class=\"conversation-name\">\n {{ conversation.Name }}\n @if (isSharedWithMe(conversation)) {\n <i class=\"fas fa-share-nodes shared-indicator\"\n [title]=\"sharedWithMeTooltip(conversation)\"></i>\n }\n </div>\n <div class=\"conversation-preview\">{{ conversation.Description }}</div>\n </div>\n @if (!isSelectionMode) {\n <div class=\"conversation-actions\">\n <button class=\"menu-btn\" (click)=\"toggleMenu(conversation.ID, $event)\" title=\"More options\">\n <i class=\"fas fa-ellipsis\"></i>\n </button>\n @if (IsMenuOpen(conversation)) {\n <div class=\"context-menu\" (click)=\"$event.stopPropagation()\">\n <button class=\"menu-item\" (click)=\"togglePin(conversation, $event)\">\n <i class=\"fas fa-thumbtack\"></i>\n <span>Unpin</span>\n </button>\n <button class=\"menu-item\" (click)=\"renameConversation(conversation); closeMenu()\">\n <i class=\"fas fa-edit\"></i>\n <span>Rename</span>\n </button>\n <div class=\"menu-divider\"></div>\n <button class=\"menu-item danger\" (click)=\"deleteConversation(conversation); closeMenu()\">\n <i class=\"fas fa-trash\"></i>\n <span>Delete</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Messages Section -->\n <div class=\"sidebar-section\">\n <div class=\"section-header\" [class.expanded]=\"directMessagesExpanded\" (click)=\"toggleDirectMessages()\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <span>Messages</span>\n </div>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"directMessagesExpanded\">\n @for (conversation of unpinnedConversations; track conversation.ID) {\n <div class=\"conversation-item\"\n [class.active]=\"IsConversationActive(conversation)\"\n [class.renamed]=\"IsConversationRenamed(conversation)\"\n (click)=\"handleConversationClick(conversation)\">\n @if (isSelectionMode) {\n <div class=\"conversation-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"selectedConversationIds.has(conversation.ID)\"\n (click)=\"$event.stopPropagation(); toggleConversationSelection(conversation.ID)\">\n </div>\n }\n <div class=\"conversation-icon-wrapper\">\n @if (hasActiveTasks(conversation.ID)) {\n <div class=\"conversation-icon has-tasks\">\n <i class=\"fas fa-spinner fa-pulse\"></i>\n </div>\n }\n <div class=\"badge-overlay\">\n <mj-notification-badge [conversationId]=\"conversation.ID\"></mj-notification-badge>\n </div>\n </div>\n <div class=\"conversation-info\" [title]=\"conversation.Name + (conversation.Description ? '\\n' + conversation.Description : '')\">\n <div class=\"conversation-name\">\n {{ conversation.Name }}\n @if (isSharedWithMe(conversation)) {\n <i class=\"fas fa-share-nodes shared-indicator\"\n [title]=\"sharedWithMeTooltip(conversation)\"></i>\n }\n </div>\n <div class=\"conversation-preview\">{{ conversation.Description }}</div>\n </div>\n @if (!isSelectionMode) {\n <div class=\"conversation-actions\">\n <button class=\"menu-btn\" (click)=\"toggleMenu(conversation.ID, $event)\" title=\"More options\">\n <i class=\"fas fa-ellipsis\"></i>\n </button>\n @if (IsMenuOpen(conversation)) {\n <div class=\"context-menu\" (click)=\"$event.stopPropagation()\">\n <button class=\"menu-item\" (click)=\"togglePin(conversation, $event)\">\n <i class=\"fas fa-thumbtack\"></i>\n <span>Pin</span>\n </button>\n <button class=\"menu-item\" (click)=\"renameConversation(conversation); closeMenu()\">\n <i class=\"fas fa-edit\"></i>\n <span>Rename</span>\n </button>\n <div class=\"menu-divider\"></div>\n <button class=\"menu-item danger\" (click)=\"deleteConversation(conversation); closeMenu()\">\n <i class=\"fas fa-trash\"></i>\n <span>Delete</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Selection Action Bar -->\n @if (isSelectionMode) {\n <div class=\"selection-action-bar\">\n <div class=\"selection-info\">\n <span class=\"selection-count\">{{ selectedConversationIds.size }} selected</span>\n @if (selectedConversationIds.size < filteredConversations.length) {\n <button class=\"link-btn\" (click)=\"selectAll()\">Select All</button>\n } @else {\n <button class=\"link-btn\" (click)=\"deselectAll()\">Deselect All</button>\n }\n </div>\n <div class=\"selection-actions\">\n <button class=\"btn-delete-bulk\"\n (click)=\"bulkDeleteConversations()\"\n [disabled]=\"selectedConversationIds.size === 0\">\n <i class=\"fas fa-trash\"></i>\n Delete ({{ selectedConversationIds.size }})\n </button>\n <button class=\"btn-cancel\" (click)=\"toggleSelectionMode()\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n `,\n styles: [`\n :host { display: block; height: 100%; }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation:hover { background: var(--mj-brand-primary-hover); }\n .btn-new-conversation i { font-size: 14px; }\n .list-content { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n /* Collapsible Sections */\n .sidebar-section { margin-bottom: 20px; }\n .pinned-section .section-title .section-icon {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); }\n .section-title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title i {\n font-size: 10px;\n }\n .section-title i:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded .section-title i:not(.section-icon) { transform: rotate(90deg); }\n .chat-list {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded { display: block; }\n\n .conversation-item {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\n .conversation-icon-wrapper { position: relative; flex-shrink: 0; }\n .conversation-icon { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks { color: var(--mj-status-warning); }\n .badge-overlay { position: absolute; top: -4px; right: -4px; }\n .conversation-info { flex: 1; min-width: 0; }\n .conversation-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator { font-size: 10px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent); }\n .conversation-meta { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n /* Project Badge */\n .project-badge {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item:hover .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .conversation-actions {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item:hover .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-item.active .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-actions > * { pointer-events: auto; }\n .pinned-icon { color: var(--mj-brand-accent); font-size: 12px; }\n\n /* Task Indicator */\n .task-indicator {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: pulse-glow 2s ease-in-out infinite;\n }\n @keyframes pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active .task-indicator {\n color: var(--mj-status-warning);\n }\n\n .menu-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active .menu-btn {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\n }\n .menu-btn i { font-size: 14px; }\n\n .context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n pointer-events: auto;\n }\n\n .menu-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item.danger {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger i {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover i {\n color: var(--mj-status-error);\n }\n\n .menu-divider {\n height: 1px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n margin: 4px 0;\n }\n\n /* Rename Animation */\n .conversation-item.renamed {\n animation: renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n /* Selection Mode Styles */\n .header-top {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n /* Header menu button and dropdown */\n .header-menu-container {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 30%, transparent);\n }\n\n .header-dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu .dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu .dropdown-item:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 30%, transparent);\n }\n\n .conversation-checkbox {\n display: flex;\n align-items: center;\n margin-right: 8px;\n flex-shrink: 0;\n }\n\n .conversation-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n }\n\n .selection-action-bar {\n position: sticky;\n bottom: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n gap: 12px;\n flex-wrap: wrap;\n flex-shrink: 0;\n }\n\n .selection-info {\n display: flex;\n align-items: center;\n gap: 12px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 90%, transparent);\n font-size: 14px;\n font-weight: 500;\n flex: 1 1 auto;\n min-width: 150px;\n }\n\n .selection-count {\n color: var(--mj-brand-on-secondary);\n }\n\n .link-btn {\n background: none;\n border: none;\n color: var(--mj-brand-accent);\n cursor: pointer;\n font-size: 13px;\n text-decoration: underline;\n padding: 0;\n transition: color 0.2s;\n }\n\n .link-btn:hover {\n color: var(--mj-brand-on-secondary);\n }\n\n .selection-actions {\n display: flex;\n gap: 8px;\n flex: 0 0 auto;\n }\n\n .btn-cancel {\n padding: 8px 16px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n }\n\n .btn-cancel:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .btn-delete-bulk {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-error);\n border: none;\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: all 0.2s;\n }\n\n .btn-delete-bulk:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 80%, black);\n }\n\n .btn-delete-bulk:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .btn-delete-bulk i {\n font-size: 12px;\n }\n `]\n})\nexport class ConversationListComponent implements OnInit, OnDestroy {\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() selectedConversationId: string | null = null;\n @Input() renamedConversationId: string | null = null;\n @Input() isSidebarPinned: boolean = true; // Whether sidebar is pinned (stays open after selection)\n @Input() isMobileView: boolean = false; // Whether we're on mobile (no pin options)\n\n @Output() conversationSelected = new EventEmitter<string>();\n @Output() conversationDeleted = new EventEmitter<string>(); // Emits the deleted conversation ID\n @Output() newConversationRequested = new EventEmitter<void>();\n @Output() pinSidebarRequested = new EventEmitter<void>(); // Request to pin sidebar\n @Output() unpinSidebarRequested = new EventEmitter<void>(); // Request to unpin (collapse) sidebar\n @Output() refreshRequested = new EventEmitter<void>(); // Emitted after list refresh so chat area can also reload\n\n public directMessagesExpanded: boolean = true;\n public pinnedExpanded: boolean = true;\n public openMenuConversationId: string | null = null;\n public conversationIdsWithTasks = new Set<string>();\n public isSelectionMode: boolean = false;\n public selectedConversationIds = new Set<string>();\n public searchQuery: string = '';\n public isHeaderMenuOpen: boolean = false;\n public isRefreshing: boolean = false;\n\n private destroy$ = new Subject<void>();\n\n private engine = ConversationEngine.Instance;\n\n // Local UI state for loading/refreshing\n public IsLoading: boolean = false;\n\n constructor(\n private dialogService: DialogService,\n private notificationService: NotificationService,\n private activeTasksService: ActiveTasksService,\n private cdr: ChangeDetectorRef\n ) {}\n\n get filteredConversations(): MJConversationEntity[] {\n if (!this.searchQuery || this.searchQuery.trim() === '') {\n return this.engine.Conversations;\n }\n const lowerQuery = this.searchQuery.toLowerCase();\n return this.engine.Conversations.filter(c =>\n (c.Name?.toLowerCase().includes(lowerQuery)) ||\n (c.Description?.toLowerCase().includes(lowerQuery))\n );\n }\n\n get pinnedConversations() {\n return this.filteredConversations.filter(c => c.IsPinned);\n }\n\n get unpinnedConversations() {\n return this.filteredConversations.filter(c => !c.IsPinned);\n }\n\n ngOnInit() {\n // Load conversations on init\n this.engine.LoadConversations(this.environmentId, this.currentUser, false);\n\n // Re-run change detection whenever the conversations list changes (pin, archive, rename, etc.).\n // filteredConversations/pinnedConversations/unpinnedConversations are pure getters that read\n // engine.Conversations directly, so Angular doesn't know to re-evaluate them unless\n // we explicitly trigger a check here.\n this.engine.Conversations$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.cdr.detectChanges();\n });\n\n // Subscribe to conversation IDs with active tasks (hot set)\n this.activeTasksService.conversationIdsWithTasks$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(conversationIds => {\n this.conversationIdsWithTasks = conversationIds;\n this.cdr.detectChanges(); // Force change detection to ensure spinner icons update reliably\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n @HostListener('document:click')\n onDocumentClick(): void {\n // Close menus when clicking outside\n if (this.openMenuConversationId) {\n this.closeMenu();\n }\n if (this.isHeaderMenuOpen) {\n this.closeHeaderMenu();\n }\n }\n\n public toggleHeaderMenu(event: Event): void {\n event.stopPropagation();\n this.isHeaderMenuOpen = !this.isHeaderMenuOpen;\n }\n\n public closeHeaderMenu(): void {\n this.isHeaderMenuOpen = false;\n }\n\n public onSelectConversationsClick(event: Event): void {\n event.stopPropagation();\n this.toggleSelectionMode();\n this.closeHeaderMenu();\n }\n\n public async onRefreshConversationsClick(event: Event): Promise<void> {\n event.stopPropagation();\n if (this.isRefreshing) return;\n\n this.isRefreshing = true;\n try {\n await this.engine.LoadConversations(this.environmentId, this.currentUser, true);\n // Signal parent to also reload messages in the active conversation\n this.refreshRequested.emit();\n } catch (error) {\n console.error('Error refreshing conversations:', error);\n await this.dialogService.alert('Error', 'Failed to refresh conversations. Please try again.');\n } finally {\n this.isRefreshing = false;\n this.cdr.detectChanges();\n this.closeHeaderMenu();\n }\n }\n\n public onPinSidebarClick(event: Event): void {\n event.stopPropagation();\n this.closeHeaderMenu();\n this.pinSidebarRequested.emit();\n }\n\n public onUnpinSidebarClick(event: Event): void {\n event.stopPropagation();\n this.closeHeaderMenu();\n this.unpinSidebarRequested.emit();\n }\n\n public toggleDirectMessages(): void {\n this.directMessagesExpanded = !this.directMessagesExpanded;\n }\n\n public togglePinned(): void {\n this.pinnedExpanded = !this.pinnedExpanded;\n }\n\n IsConversationActive(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(conversation.ID, this.selectedConversationId);\n }\n\n IsConversationRenamed(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(conversation.ID, this.renamedConversationId);\n }\n\n IsMenuOpen(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(this.openMenuConversationId, conversation.ID);\n }\n\n selectConversation(conversation: MJConversationEntity): void {\n this.conversationSelected.emit(conversation.ID);\n // Clear unread notifications when conversation is opened\n this.notificationService.markConversationAsRead(conversation.ID);\n }\n\n async createNewConversation(): Promise<void> {\n // Don't create DB record yet - just show the welcome screen\n // Conversation will be created when user sends first message\n this.newConversationRequested.emit();\n }\n\n async renameConversation(conversation: MJConversationEntity): Promise<void> {\n try {\n const result = await this.dialogService.input({\n title: 'Edit Conversation',\n message: 'Update the name and description for this conversation',\n inputLabel: 'Conversation Name',\n inputValue: conversation.Name || '',\n placeholder: 'My Conversation',\n required: true,\n secondInputLabel: 'Description',\n secondInputValue: conversation.Description || '',\n secondInputPlaceholder: 'Optional description',\n secondInputRequired: false,\n okText: 'Save',\n cancelText: 'Cancel'\n });\n\n if (result) {\n const newName = typeof result === 'string' ? result : result.value;\n const newDescription = typeof result === 'string' ? conversation.Description : result.secondValue;\n\n if (newName !== conversation.Name || newDescription !== conversation.Description) {\n await this.engine.SaveConversation(\n conversation.ID,\n { Name: newName, Description: newDescription || '' },\n this.currentUser\n );\n }\n }\n } catch (error) {\n console.error('Error renaming conversation:', error);\n await this.dialogService.alert('Error', 'Failed to update conversation. Please try again.');\n }\n }\n\n async deleteConversation(conversation: MJConversationEntity): Promise<void> {\n try {\n const confirmed = await this.dialogService.confirm({\n title: 'Delete Conversation',\n message: `Are you sure you want to delete \"${conversation.Name}\"? This action cannot be undone.`,\n okText: 'Delete',\n cancelText: 'Cancel'\n });\n\n if (confirmed) {\n const deletedId = conversation.ID;\n await this.engine.DeleteConversation(deletedId, this.currentUser);\n this.cdr.detectChanges();\n this.conversationDeleted.emit(deletedId);\n }\n } catch (error) {\n console.error('Error deleting conversation:', error);\n await this.dialogService.alert('Error', 'Failed to delete conversation. Please try again.');\n }\n }\n\n toggleMenu(conversationId: string, event: Event): void {\n event.stopPropagation();\n this.openMenuConversationId = this.openMenuConversationId === conversationId ? null : conversationId;\n }\n\n closeMenu(): void {\n this.openMenuConversationId = null;\n }\n\n async togglePin(conversation: MJConversationEntity, event?: Event): Promise<void> {\n if (event) event.stopPropagation();\n this.closeMenu(); // Close immediately on user action — don't wait for the async op\n try {\n await this.engine.PinConversation(conversation.ID, !conversation.IsPinned, this.currentUser);\n } catch (error) {\n console.error('Error toggling pin:', error);\n await this.dialogService.alert('Error', 'Failed to pin/unpin conversation. Please try again.');\n }\n }\n\n hasActiveTasks(conversationId: string): boolean {\n return this.conversationIdsWithTasks.has(conversationId);\n }\n\n /** True when this conversation was shared with the current user by someone else. */\n isSharedWithMe(conversation: MJConversationEntity): boolean {\n return this.engine.GetSharedByInfo(conversation.ID) !== null;\n }\n\n /** Tooltip for the sidebar share icon: \"Shared by {email or name}\". */\n sharedWithMeTooltip(conversation: MJConversationEntity): string {\n const info = this.engine.GetSharedByInfo(conversation.ID);\n if (!info) return 'Shared with you';\n return `Shared by ${info.Email ?? info.Name ?? 'another user'}`;\n }\n\n toggleSelectionMode(): void {\n this.isSelectionMode = !this.isSelectionMode;\n if (!this.isSelectionMode) {\n this.selectedConversationIds.clear();\n }\n }\n\n toggleConversationSelection(conversationId: string): void {\n if (this.selectedConversationIds.has(conversationId)) {\n this.selectedConversationIds.delete(conversationId);\n } else {\n this.selectedConversationIds.add(conversationId);\n }\n }\n\n selectAll(): void {\n this.filteredConversations.forEach(c => {\n this.selectedConversationIds.add(c.ID);\n });\n }\n\n deselectAll(): void {\n this.selectedConversationIds.clear();\n }\n\n async bulkDeleteConversations(): Promise<void> {\n const count = this.selectedConversationIds.size;\n\n if (count === 0) return;\n\n const confirmed = await this.dialogService.confirm({\n title: 'Delete Conversations',\n message: `Are you sure you want to delete ${count} conversation${count > 1 ? 's' : ''}? This action cannot be undone.`,\n okText: 'Delete',\n cancelText: 'Cancel'\n });\n\n if (confirmed) {\n try {\n const result = await this.engine.DeleteMultipleConversations(\n Array.from(this.selectedConversationIds),\n this.currentUser\n );\n\n if (result.Failed.length > 0 && result.Successful.length > 0) {\n // Partial success\n const failedNames = result.Failed.map(f => `\"${f.Name}\"`).join(', ');\n await this.dialogService.alert(\n 'Partial Success',\n `Deleted ${result.Successful.length} of ${count} conversations.\\n\\n` +\n `${result.Failed.length} could not be deleted: ${failedNames}`\n );\n } else if (result.Failed.length > 0 && result.Successful.length === 0) {\n // All failed\n await this.dialogService.alert(\n 'Delete Failed',\n `None of the ${count} conversations could be deleted. They may have already been removed.`\n );\n }\n\n // Emit deleted events for successful deletions\n for (const id of result.Successful) {\n this.conversationDeleted.emit(id);\n }\n\n } catch (error) {\n console.error('Error deleting conversations:', error);\n await this.dialogService.alert('Error', 'Failed to delete conversations. Please try again.');\n } finally {\n // Always exit selection mode after an attempt, whether success or failure\n this.selectedConversationIds.clear();\n this.isSelectionMode = false;\n this.cdr.detectChanges();\n }\n }\n }\n\n handleConversationClick(conversation: MJConversationEntity): void {\n if (this.isSelectionMode) {\n this.toggleConversationSelection(conversation.ID);\n } else {\n this.selectConversation(conversation);\n }\n }\n}"]}
1
+ {"version":3,"file":"conversation-list.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-list.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, HostListener, ChangeDetectorRef } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity, MJProjectEntity, ConversationEngine, UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJDialogService } from '@memberjunction/ng-ui-components';\nimport { DialogService } from '../../services/dialog.service';\nimport { NotificationService } from '../../services/notification.service';\nimport { ActiveTasksService } from '../../services/active-tasks.service';\nimport { ProjectFormModalComponent } from '../project/project-form-modal.component';\nimport { ConversationGroupBy } from '../../models/conversation-state.model';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';\n\n/**\n * A node in the conversation folder tree. Each node holds its project (folder),\n * the conversations directly assigned to it, and its nested child folders.\n */\ninterface FolderNode {\n project: MJProjectEntity;\n depth: number;\n /** Conversations directly in this folder (unpinned only — pinned live in the Pinned section). */\n conversations: MJConversationEntity[];\n children: FolderNode[];\n /** Total conversations in this folder and all descendants. */\n totalCount: number;\n /** True when this folder or any descendant has at least one (filtered) conversation. */\n hasContent: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-conversation-list',\n template: `\n <div class=\"conversation-list\">\n <div class=\"list-header\">\n <div class=\"header-top\">\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search conversations...\"\n [(ngModel)]=\"searchQuery\">\n @if (!isSelectionMode) {\n <div class=\"header-menu-container\">\n <button class=\"btn-menu\" (click)=\"toggleHeaderMenu($event)\" title=\"Options\">\n <i class=\"fas fa-ellipsis-v\"></i>\n </button>\n @if (isHeaderMenuOpen) {\n <div class=\"header-dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"onRefreshConversationsClick($event)\" [disabled]=\"isRefreshing\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"isRefreshing\"></i>\n <span>{{ isRefreshing ? 'Refreshing...' : 'Refresh' }}</span>\n </button>\n <button class=\"dropdown-item\" (click)=\"onSelectConversationsClick($event)\">\n <i class=\"fas fa-check-square\"></i>\n <span>Select Conversations</span>\n </button>\n <button class=\"dropdown-item\" (click)=\"onToggleGroupByClick($event)\">\n <i class=\"fas\" [class.fa-folder-tree]=\"groupBy !== 'project'\" [class.fa-list]=\"groupBy === 'project'\"></i>\n <span>{{ groupBy === 'project' ? 'Show as flat list' : 'Group by folder' }}</span>\n </button>\n @if (!isMobileView) {\n <button class=\"dropdown-item\" (click)=\"onUnpinSidebarClick($event)\">\n <i class=\"fas fa-table-columns\"></i>\n <span>Hide Sidebar</span>\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n <button class=\"btn-new-conversation\" (click)=\"createNewConversation()\" title=\"New Conversation\">\n <i class=\"fas fa-plus\"></i>\n <span>New Conversation</span>\n </button>\n <div class=\"list-content\">\n <!-- Pinned Section (only show if there are pinned conversations) -->\n @if (pinnedConversations.length > 0) {\n <div class=\"sidebar-section pinned-section\">\n <div class=\"section-header\" [class.expanded]=\"pinnedExpanded\" (click)=\"togglePinned()\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <i class=\"fas fa-thumbtack section-icon\"></i>\n <span>Pinned</span>\n </div>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"pinnedExpanded\">\n @for (conversation of pinnedConversations; track conversation.ID) {\n <ng-container [ngTemplateOutlet]=\"conversationItem\" [ngTemplateOutletContext]=\"{ $implicit: conversation }\"></ng-container>\n }\n </div>\n </div>\n }\n\n @if (groupBy === 'project') {\n <!-- Folders Section -->\n <div class=\"sidebar-section folders-section\">\n <div class=\"section-header\" [class.expanded]=\"foldersExpanded\"\n [class.drag-over]=\"dragOverTargetId === 'folders-root'\"\n (click)=\"toggleFolders()\"\n (dragover)=\"onFoldersRootDragOver($event)\"\n (dragleave)=\"onDragLeave('folders-root')\"\n (drop)=\"onFoldersRootDrop($event)\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <span>Folders</span>\n </div>\n <button class=\"section-action-btn\" (click)=\"createFolder(null, $event)\" title=\"New Folder\">\n <i class=\"fas fa-folder-plus\"></i>\n </button>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"foldersExpanded\">\n @for (node of folderTree; track node.project.ID) {\n @if (!isSearching || node.hasContent) {\n <ng-container [ngTemplateOutlet]=\"folderNode\" [ngTemplateOutletContext]=\"{ $implicit: node }\"></ng-container>\n }\n }\n @if (folderTree.length === 0) {\n <div class=\"folder-empty-hint\">No folders yet — create one to organize conversations.</div>\n }\n </div>\n </div>\n\n <!-- Ungrouped Section (drop target to remove from folder) -->\n <div class=\"sidebar-section ungrouped-section\"\n [class.drag-over]=\"dragOverTargetId === 'ungrouped'\"\n (dragover)=\"onUngroupedDragOver($event)\"\n (dragleave)=\"onDragLeave('ungrouped')\"\n (drop)=\"onUngroupedDrop($event)\">\n <div class=\"section-header\" [class.expanded]=\"ungroupedExpanded\" (click)=\"toggleUngrouped()\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <span>{{ folderTree.length > 0 ? 'Ungrouped' : 'Messages' }}</span>\n </div>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"ungroupedExpanded\">\n @for (conversation of ungroupedConversations; track conversation.ID) {\n <ng-container [ngTemplateOutlet]=\"conversationItem\" [ngTemplateOutletContext]=\"{ $implicit: conversation }\"></ng-container>\n }\n </div>\n </div>\n } @else {\n <!-- Flat Messages Section -->\n <div class=\"sidebar-section\">\n <div class=\"section-header\" [class.expanded]=\"directMessagesExpanded\" (click)=\"toggleDirectMessages()\">\n <div class=\"section-title\">\n <i class=\"fas fa-chevron-right\"></i>\n <span>Messages</span>\n </div>\n </div>\n <div class=\"chat-list\" [class.expanded]=\"directMessagesExpanded\">\n @for (conversation of unpinnedConversations; track conversation.ID) {\n <ng-container [ngTemplateOutlet]=\"conversationItem\" [ngTemplateOutletContext]=\"{ $implicit: conversation }\"></ng-container>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Selection Action Bar -->\n @if (isSelectionMode) {\n <div class=\"selection-action-bar\">\n <div class=\"selection-info\">\n <span class=\"selection-count\">{{ selectedConversationIds.size }} selected</span>\n @if (selectedConversationIds.size < filteredConversations.length) {\n <button class=\"link-btn\" (click)=\"selectAll()\">Select All</button>\n } @else {\n <button class=\"link-btn\" (click)=\"deselectAll()\">Deselect All</button>\n }\n </div>\n <div class=\"selection-actions\">\n <button class=\"btn-delete-bulk\"\n (click)=\"bulkDeleteConversations()\"\n [disabled]=\"selectedConversationIds.size === 0\">\n <i class=\"fas fa-trash\"></i>\n Delete ({{ selectedConversationIds.size }})\n </button>\n <button class=\"btn-cancel\" (click)=\"toggleSelectionMode()\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Recursive folder node: header + nested children + direct conversations -->\n <ng-template #folderNode let-node>\n <div class=\"folder-row\"\n [class.drag-over]=\"dragOverTargetId === node.project.ID\"\n [class.dragging]=\"draggedFolderId === node.project.ID\"\n [style.paddingLeft.px]=\"12 + node.depth * 14\"\n [draggable]=\"true\"\n (dragstart)=\"onFolderDragStart(node, $event)\"\n (dragend)=\"onFolderDragEnd()\"\n (click)=\"toggleFolder(node.project.ID)\"\n (dragover)=\"onFolderDragOver(node.project.ID, $event)\"\n (dragleave)=\"onDragLeave(node.project.ID)\"\n (drop)=\"onFolderDrop(node.project, $event)\"\n [title]=\"node.project.Name\">\n <i class=\"fas fa-chevron-right folder-chevron\" [class.expanded]=\"isFolderExpanded(node.project.ID)\"></i>\n <i class=\"fas {{ node.project.Icon || 'fa-folder' }} folder-icon\" [style.color]=\"node.project.Color || null\"></i>\n <span class=\"folder-name\">{{ node.project.Name }}</span>\n <span class=\"folder-count\">{{ node.totalCount }}</span>\n <div class=\"folder-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"folder-action-btn\" (click)=\"createFolder(node.project.ID, $event)\" title=\"New Subfolder\">\n <i class=\"fas fa-folder-plus\"></i>\n </button>\n <button class=\"folder-action-btn\" (click)=\"editFolder(node.project, $event)\" title=\"Edit Folder\">\n <i class=\"fas fa-pen\"></i>\n </button>\n <button class=\"folder-action-btn danger\" (click)=\"deleteFolder(node.project, $event)\" title=\"Delete Folder\">\n <i class=\"fas fa-trash\"></i>\n </button>\n </div>\n </div>\n @if (isFolderExpanded(node.project.ID)) {\n <div class=\"folder-children\">\n @for (child of node.children; track child.project.ID) {\n @if (!isSearching || child.hasContent) {\n <ng-container [ngTemplateOutlet]=\"folderNode\" [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n }\n }\n @for (conversation of node.conversations; track conversation.ID) {\n <ng-container [ngTemplateOutlet]=\"conversationItem\" [ngTemplateOutletContext]=\"{ $implicit: conversation, depth: node.depth + 1 }\"></ng-container>\n }\n @if (node.totalCount === 0 && !isSearching) {\n <div class=\"folder-empty-hint\" [style.paddingLeft.px]=\"26 + node.depth * 14\">Empty — drop a conversation here</div>\n }\n </div>\n }\n </ng-template>\n\n <!-- Shared conversation row used by Pinned, folders, and Ungrouped/Messages -->\n <ng-template #conversationItem let-conversation let-depth=\"depth\">\n <div class=\"conversation-item\"\n [class.active]=\"IsConversationActive(conversation)\"\n [class.renamed]=\"IsConversationRenamed(conversation)\"\n [class.dragging]=\"IsConversationDragging(conversation)\"\n [style.paddingLeft.px]=\"depth ? 16 + depth * 14 : 16\"\n [draggable]=\"!isSelectionMode\"\n (dragstart)=\"onConversationDragStart(conversation, $event)\"\n (dragend)=\"onConversationDragEnd()\"\n (click)=\"handleConversationClick(conversation)\">\n @if (isSelectionMode) {\n <div class=\"conversation-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"selectedConversationIds.has(conversation.ID)\"\n (click)=\"$event.stopPropagation(); toggleConversationSelection(conversation.ID)\">\n </div>\n }\n <div class=\"conversation-icon-wrapper\">\n @if (hasActiveTasks(conversation.ID)) {\n <div class=\"conversation-icon has-tasks\">\n <i class=\"fas fa-spinner fa-pulse\"></i>\n </div>\n }\n <div class=\"badge-overlay\">\n <mj-notification-badge [conversationId]=\"conversation.ID\"></mj-notification-badge>\n </div>\n </div>\n <div class=\"conversation-info\" [title]=\"conversation.Name + (conversation.Description ? '\\n' + conversation.Description : '')\">\n <div class=\"conversation-name\">\n {{ conversation.Name }}\n @if (isSharedWithMe(conversation)) {\n <i class=\"fas fa-share-nodes shared-indicator\"\n [title]=\"sharedWithMeTooltip(conversation)\"></i>\n }\n </div>\n <div class=\"conversation-preview\">{{ conversation.Description }}</div>\n </div>\n @if (!isSelectionMode) {\n <div class=\"conversation-actions\">\n <button class=\"menu-btn\" (click)=\"toggleMenu(conversation.ID, $event)\" title=\"More options\">\n <i class=\"fas fa-ellipsis\"></i>\n </button>\n @if (IsMenuOpen(conversation)) {\n <div class=\"context-menu\" (click)=\"$event.stopPropagation()\">\n @if (IsMoveSubmenuOpen(conversation)) {\n <button class=\"menu-item back\" (click)=\"closeMoveSubmenu($event)\">\n <i class=\"fas fa-chevron-left\"></i>\n <span>Move to folder</span>\n </button>\n <div class=\"menu-divider\"></div>\n <div class=\"move-folder-list\">\n <button class=\"menu-item\" [class.current]=\"!conversation.ProjectID\" (click)=\"selectMoveTarget(conversation, null)\">\n <i class=\"fas fa-inbox\"></i>\n <span>No folder</span>\n </button>\n @for (f of flatFolders; track f.project.ID) {\n <button class=\"menu-item\" [class.current]=\"IsInFolder(conversation, f.project.ID)\"\n [style.paddingLeft.px]=\"14 + f.depth * 12\"\n (click)=\"selectMoveTarget(conversation, f.project.ID)\">\n <i class=\"fas {{ f.project.Icon || 'fa-folder' }}\" [style.color]=\"f.project.Color || null\"></i>\n <span>{{ f.project.Name }}</span>\n </button>\n }\n </div>\n <div class=\"menu-divider\"></div>\n <button class=\"menu-item\" (click)=\"createFolderForConversation(conversation, $event)\">\n <i class=\"fas fa-folder-plus\"></i>\n <span>New folder…</span>\n </button>\n } @else {\n <button class=\"menu-item\" (click)=\"togglePin(conversation, $event)\">\n <i class=\"fas fa-thumbtack\"></i>\n <span>{{ conversation.IsPinned ? 'Unpin' : 'Pin' }}</span>\n </button>\n <button class=\"menu-item\" (click)=\"openMoveSubmenu(conversation.ID, $event)\">\n <i class=\"fas fa-folder-tree\"></i>\n <span>Move to folder</span>\n <i class=\"fas fa-chevron-right submenu-arrow\"></i>\n </button>\n <button class=\"menu-item\" (click)=\"renameConversation(conversation); closeMenu()\">\n <i class=\"fas fa-edit\"></i>\n <span>Rename</span>\n </button>\n <div class=\"menu-divider\"></div>\n <button class=\"menu-item danger\" (click)=\"deleteConversation(conversation); closeMenu()\">\n <i class=\"fas fa-trash\"></i>\n <span>Delete</span>\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n `,\n styles: [`\n :host { display: block; height: 100%; }\n .conversation-list { display: flex; flex-direction: column; height: 100%; background: var(--mj-brand-secondary); }\n .list-header { padding: 8px; border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent); }\n .search-input {\n width: 100%;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n transition: all 0.2s;\n }\n .search-input::placeholder { color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); }\n .search-input:focus { outline: none; background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent); border-color: var(--mj-brand-primary); }\n .btn-new-conversation {\n width: calc(100% - 16px);\n margin: 8px;\n padding: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background 0.2s;\n flex-shrink: 0;\n }\n .btn-new-conversation:hover { background: var(--mj-brand-primary-hover); }\n .btn-new-conversation i { font-size: 14px; }\n .list-content { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 0; }\n\n /* Collapsible Sections */\n .sidebar-section { margin-bottom: 20px; }\n .pinned-section .section-title .section-icon {\n color: var(--mj-status-warning);\n font-size: 11px;\n margin-left: 2px;\n }\n .section-header {\n padding: 4px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-brand-on-secondary);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s;\n user-select: none;\n }\n .section-header:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); }\n .section-title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .section-title i {\n font-size: 10px;\n }\n .section-title i:not(.section-icon) {\n transition: transform 0.2s;\n }\n .section-header.expanded .section-title i:not(.section-icon) { transform: rotate(90deg); }\n .chat-list {\n padding: 4px 0;\n display: none;\n }\n .chat-list.expanded { display: block; }\n\n .conversation-item {\n padding: 6px 5px 6px 16px;\n cursor: pointer;\n display: flex;\n gap: 8px;\n align-items: center;\n transition: all 0.2s;\n position: relative;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n font-size: 14px;\n min-height: 45px;\n }\n .conversation-item:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); color: var(--mj-brand-on-secondary); }\n .conversation-item:hover .conversation-actions { opacity: 1; }\n .conversation-item.active { background: var(--mj-brand-primary); color: var(--mj-brand-on-secondary); }\n .conversation-icon-wrapper { position: relative; flex-shrink: 0; }\n .conversation-icon { font-size: 12px; width: 16px; text-align: center; }\n .conversation-icon.has-tasks { color: var(--mj-status-warning); }\n .badge-overlay { position: absolute; top: -4px; right: -4px; }\n .conversation-info { flex: 1; min-width: 0; }\n .conversation-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }\n .shared-indicator { font-size: 10px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 55%, transparent); flex-shrink: 0; }\n .conversation-item.active .shared-indicator { color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent); }\n .conversation-preview { font-size: 12px; color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .conversation-item.active .conversation-preview { color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent); }\n .conversation-meta { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n\n /* Project Badge */\n .project-badge {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n margin-left: auto;\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .conversation-item:hover .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n }\n .conversation-item.active .project-badge {\n background-color: color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .conversation-actions {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n }\n .conversation-item:hover .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-item.active .conversation-actions { opacity: 1; pointer-events: auto; }\n .conversation-actions > * { pointer-events: auto; }\n .pinned-icon { color: var(--mj-brand-accent); font-size: 12px; }\n\n /* Task Indicator */\n .task-indicator {\n color: var(--mj-status-warning);\n font-size: 12px;\n margin-right: 8px;\n flex-shrink: 0;\n animation: pulse-glow 2s ease-in-out infinite;\n }\n @keyframes pulse-glow {\n 0%, 100% {\n opacity: 1;\n filter: drop-shadow(0 0 2px var(--mj-status-warning));\n }\n 50% {\n opacity: 0.6;\n filter: drop-shadow(0 0 4px var(--mj-status-warning));\n }\n }\n .conversation-item.active .task-indicator {\n color: var(--mj-status-warning);\n }\n\n .menu-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n background: var(--mj-brand-secondary) !important;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n .menu-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent) !important;\n color: var(--mj-brand-on-secondary);\n }\n .conversation-item.active .menu-btn {\n background: var(--mj-brand-primary-hover) !important;\n color: var(--mj-brand-on-secondary);\n }\n .menu-btn i { font-size: 14px; }\n\n .context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n pointer-events: auto;\n }\n\n .menu-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .menu-item:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .menu-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .menu-item.danger {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n color: var(--mj-status-error);\n }\n\n .menu-item.danger i {\n color: var(--mj-status-error);\n }\n\n .menu-item.danger:hover i {\n color: var(--mj-status-error);\n }\n\n .menu-divider {\n height: 1px;\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n margin: 4px 0;\n }\n\n /* Rename Animation */\n .conversation-item.renamed {\n animation: renameHighlight 1500ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes renameHighlight {\n 0% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.4));\n transform: scale(1.03);\n box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);\n }\n 25% {\n background: linear-gradient(90deg, rgba(59, 130, 246, 0.35), rgba(147, 51, 234, 0.35));\n box-shadow: 0 0 15px rgba(59, 130, 246, 0.4);\n }\n 50% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.3), rgba(59, 130, 246, 0.3));\n transform: scale(1.02);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);\n }\n 75% {\n background: linear-gradient(90deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));\n box-shadow: 0 0 5px rgba(16, 185, 129, 0.2);\n }\n 100% {\n background: transparent;\n transform: scale(1);\n box-shadow: none;\n }\n }\n\n /* Selection Mode Styles */\n .header-top {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n /* Header menu button and dropdown */\n .header-menu-container {\n position: relative;\n flex-shrink: 0;\n }\n\n .btn-menu {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-menu:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 30%, transparent);\n }\n\n .header-dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-brand-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n overflow: hidden;\n padding: 4px 0;\n }\n\n .header-dropdown-menu .dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: transparent;\n border: none;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 85%, transparent);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .header-dropdown-menu .dropdown-item:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item i {\n width: 16px;\n font-size: 13px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n }\n\n .header-dropdown-menu .dropdown-item:hover i {\n color: var(--mj-brand-on-secondary);\n }\n\n .header-dropdown-menu .dropdown-item .shortcut {\n margin-left: auto;\n font-size: 11px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 40%, transparent);\n font-family: system-ui, -apple-system, sans-serif;\n }\n\n .btn-select {\n padding: 8px 12px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n font-size: 13px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .btn-select:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n border-color: color-mix(in srgb, var(--mj-brand-on-secondary) 30%, transparent);\n }\n\n .conversation-checkbox {\n display: flex;\n align-items: center;\n margin-right: 8px;\n flex-shrink: 0;\n }\n\n .conversation-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n }\n\n .selection-action-bar {\n position: sticky;\n bottom: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-brand-secondary);\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n gap: 12px;\n flex-wrap: wrap;\n flex-shrink: 0;\n }\n\n .selection-info {\n display: flex;\n align-items: center;\n gap: 12px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 90%, transparent);\n font-size: 14px;\n font-weight: 500;\n flex: 1 1 auto;\n min-width: 150px;\n }\n\n .selection-count {\n color: var(--mj-brand-on-secondary);\n }\n\n .link-btn {\n background: none;\n border: none;\n color: var(--mj-brand-accent);\n cursor: pointer;\n font-size: 13px;\n text-decoration: underline;\n padding: 0;\n transition: color 0.2s;\n }\n\n .link-btn:hover {\n color: var(--mj-brand-on-secondary);\n }\n\n .selection-actions {\n display: flex;\n gap: 8px;\n flex: 0 0 auto;\n }\n\n .btn-cancel {\n padding: 8px 16px;\n background: transparent;\n border: 1px solid color-mix(in srgb, var(--mj-brand-on-secondary) 20%, transparent);\n border-radius: 6px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 70%, transparent);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n }\n\n .btn-cancel:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 10%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n\n .btn-delete-bulk {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-error);\n border: none;\n border-radius: 6px;\n color: var(--mj-brand-on-secondary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: all 0.2s;\n }\n\n .btn-delete-bulk:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 80%, black);\n }\n\n .btn-delete-bulk:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .btn-delete-bulk i {\n font-size: 12px;\n }\n\n /* Folders */\n .section-action-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n cursor: pointer;\n transition: all 0.2s;\n }\n .section-action-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 15%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n .section-action-btn i { font-size: 12px; }\n\n .folder-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n cursor: pointer;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 80%, transparent);\n font-size: 13px;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n }\n .folder-row:hover { background: color-mix(in srgb, var(--mj-brand-on-secondary) 8%, transparent); }\n .folder-row.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n }\n .folder-row.dragging { opacity: 0.4; }\n .section-header.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n border-radius: 6px;\n }\n .folder-chevron {\n font-size: 9px;\n width: 10px;\n flex-shrink: 0;\n transition: transform 0.2s;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 55%, transparent);\n }\n .folder-chevron.expanded { transform: rotate(90deg); }\n .folder-icon { font-size: 12px; width: 16px; text-align: center; flex-shrink: 0; }\n .folder-name {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 600;\n }\n .folder-count {\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 50%, transparent);\n flex-shrink: 0;\n margin-left: auto;\n padding-left: 6px;\n text-align: right;\n }\n .folder-actions {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n gap: 2px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 5;\n }\n .folder-row:hover .folder-actions { opacity: 1; pointer-events: auto; }\n .folder-row:hover .folder-count { opacity: 0; }\n .folder-action-btn {\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 60%, transparent);\n cursor: pointer;\n transition: all 0.15s;\n }\n .folder-action-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-on-secondary) 18%, transparent);\n color: var(--mj-brand-on-secondary);\n }\n .folder-action-btn.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 18%, transparent);\n color: var(--mj-status-error);\n }\n .folder-action-btn i { font-size: 11px; }\n .folder-children { display: block; }\n .folder-empty-hint {\n padding: 6px 16px;\n font-size: 11px;\n font-style: italic;\n color: color-mix(in srgb, var(--mj-brand-on-secondary) 45%, transparent);\n }\n .ungrouped-section.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n border-radius: 6px;\n }\n\n /* Dragging state */\n .conversation-item { user-select: none; }\n .conversation-item.dragging { opacity: 0.4; }\n\n /* Move-to-folder submenu */\n .menu-item.back { font-weight: 600; }\n .menu-item .submenu-arrow { margin-left: auto; font-size: 10px; }\n .menu-item.current { background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent); }\n .move-folder-list { max-height: 240px; overflow-y: auto; }\n `]\n})\nexport class ConversationListComponent implements OnInit, OnDestroy {\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() selectedConversationId: string | null = null;\n @Input() renamedConversationId: string | null = null;\n @Input() isSidebarPinned: boolean = true; // Whether sidebar is pinned (stays open after selection)\n @Input() isMobileView: boolean = false; // Whether we're on mobile (no pin options)\n\n @Output() conversationSelected = new EventEmitter<string>();\n @Output() conversationDeleted = new EventEmitter<string>(); // Emits the deleted conversation ID\n @Output() newConversationRequested = new EventEmitter<void>();\n @Output() pinSidebarRequested = new EventEmitter<void>(); // Request to pin sidebar\n @Output() unpinSidebarRequested = new EventEmitter<void>(); // Request to unpin (collapse) sidebar\n @Output() refreshRequested = new EventEmitter<void>(); // Emitted after list refresh so chat area can also reload\n\n public directMessagesExpanded: boolean = true;\n public pinnedExpanded: boolean = true;\n public foldersExpanded: boolean = true;\n public ungroupedExpanded: boolean = true;\n public openMenuConversationId: string | null = null;\n public conversationIdsWithTasks = new Set<string>();\n public isSelectionMode: boolean = false;\n public selectedConversationIds = new Set<string>();\n public isHeaderMenuOpen: boolean = false;\n public isRefreshing: boolean = false;\n\n /** UserInfoEngine key for persisting folder collapse state + group-by mode. */\n private static readonly FolderPrefsKey = 'mj.conversations.folderPrefs.v1';\n\n /** How the conversation list is grouped. 'project' = folders, 'none' = flat list. */\n public groupBy: ConversationGroupBy = 'project';\n\n /** Precomputed groupings, rebuilt whenever conversations/projects/search change. */\n public pinnedConversations: MJConversationEntity[] = [];\n public unpinnedConversations: MJConversationEntity[] = [];\n public ungroupedConversations: MJConversationEntity[] = [];\n public folderTree: FolderNode[] = [];\n /** Flattened folder list (depth-ordered) for the \"Move to folder\" menu. */\n public flatFolders: FolderNode[] = [];\n\n /** Folder IDs (normalized) whose children are collapsed. Absent = expanded. */\n private collapsedFolderIds = new Set<string>();\n\n /** Drag-and-drop state. */\n public draggedConversationId: string | null = null;\n public draggedFolderId: string | null = null;\n public dragOverTargetId: string | null = null;\n\n /** When set, the open conversation menu is showing its \"Move to folder\" picker. */\n public moveSubmenuConversationId: string | null = null;\n\n private _searchQuery: string = '';\n\n private destroy$ = new Subject<void>();\n\n private engine = ConversationEngine.Instance;\n\n // Local UI state for loading/refreshing\n public IsLoading: boolean = false;\n\n constructor(\n private dialogService: DialogService,\n private notificationService: NotificationService,\n private activeTasksService: ActiveTasksService,\n private mjDialogService: MJDialogService,\n private cdr: ChangeDetectorRef\n ) {}\n\n get searchQuery(): string {\n return this._searchQuery;\n }\n set searchQuery(value: string) {\n this._searchQuery = value ?? '';\n this.rebuildGroups();\n }\n\n /** True when a search filter is active. */\n get isSearching(): boolean {\n return this._searchQuery.trim().length > 0;\n }\n\n /** Conversations matching the current search (used by selection-mode helpers). */\n get filteredConversations(): MJConversationEntity[] {\n return this.filterConversations(this.engine.Conversations);\n }\n\n private filterConversations(conversations: MJConversationEntity[]): MJConversationEntity[] {\n if (!this.isSearching) {\n return conversations;\n }\n const lowerQuery = this._searchQuery.toLowerCase();\n return conversations.filter(c =>\n (c.Name?.toLowerCase().includes(lowerQuery)) ||\n (c.Description?.toLowerCase().includes(lowerQuery))\n );\n }\n\n ngOnInit() {\n // Restore persisted folder collapse state + group-by preference\n this.loadFolderPrefs();\n\n // Load conversations (and folders) on init\n this.engine.LoadConversations(this.environmentId, this.currentUser, false);\n\n // Rebuild the precomputed groupings whenever conversations OR projects change\n // (pin, archive, rename, move-to-folder, folder create/rename/delete, etc.).\n this.engine.Conversations$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.rebuildGroups();\n this.cdr.detectChanges();\n });\n\n this.engine.Projects$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.rebuildGroups();\n this.cdr.detectChanges();\n });\n\n // Subscribe to conversation IDs with active tasks (hot set)\n this.activeTasksService.conversationIdsWithTasks$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(conversationIds => {\n this.conversationIdsWithTasks = conversationIds;\n this.cdr.detectChanges(); // Force change detection to ensure spinner icons update reliably\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n @HostListener('document:click')\n onDocumentClick(): void {\n // Close menus when clicking outside\n if (this.openMenuConversationId) {\n this.closeMenu();\n }\n if (this.isHeaderMenuOpen) {\n this.closeHeaderMenu();\n }\n }\n\n public toggleHeaderMenu(event: Event): void {\n event.stopPropagation();\n this.isHeaderMenuOpen = !this.isHeaderMenuOpen;\n }\n\n public closeHeaderMenu(): void {\n this.isHeaderMenuOpen = false;\n }\n\n public onSelectConversationsClick(event: Event): void {\n event.stopPropagation();\n this.toggleSelectionMode();\n this.closeHeaderMenu();\n }\n\n public onToggleGroupByClick(event: Event): void {\n event.stopPropagation();\n this.toggleGroupBy();\n this.closeHeaderMenu();\n }\n\n public async onRefreshConversationsClick(event: Event): Promise<void> {\n event.stopPropagation();\n if (this.isRefreshing) return;\n\n this.isRefreshing = true;\n try {\n await this.engine.LoadConversations(this.environmentId, this.currentUser, true);\n // Signal parent to also reload messages in the active conversation\n this.refreshRequested.emit();\n } catch (error) {\n console.error('Error refreshing conversations:', error);\n await this.dialogService.alert('Error', 'Failed to refresh conversations. Please try again.');\n } finally {\n this.isRefreshing = false;\n this.cdr.detectChanges();\n this.closeHeaderMenu();\n }\n }\n\n public onPinSidebarClick(event: Event): void {\n event.stopPropagation();\n this.closeHeaderMenu();\n this.pinSidebarRequested.emit();\n }\n\n public onUnpinSidebarClick(event: Event): void {\n event.stopPropagation();\n this.closeHeaderMenu();\n this.unpinSidebarRequested.emit();\n }\n\n public toggleDirectMessages(): void {\n this.directMessagesExpanded = !this.directMessagesExpanded;\n }\n\n public togglePinned(): void {\n this.pinnedExpanded = !this.pinnedExpanded;\n }\n\n public toggleFolders(): void {\n this.foldersExpanded = !this.foldersExpanded;\n }\n\n public toggleUngrouped(): void {\n this.ungroupedExpanded = !this.ungroupedExpanded;\n }\n\n // ========================================================================\n // FOLDER GROUPING\n // ========================================================================\n\n /**\n * Recomputes pinned/unpinned/ungrouped lists and the folder tree from the\n * engine's conversation + project caches and the current search filter.\n */\n private rebuildGroups(): void {\n const matching = this.filterConversations(this.engine.Conversations);\n this.pinnedConversations = matching.filter(c => c.IsPinned);\n this.unpinnedConversations = matching.filter(c => !c.IsPinned);\n\n const projects = this.engine.Projects;\n const projectIds = new Set(projects.map(p => NormalizeUUID(p.ID)));\n\n // Bucket unpinned conversations by their folder (pinned ones live in the\n // Pinned section). Conversations with no/unknown folder are \"ungrouped\".\n const conversationsByProject = new Map<string, MJConversationEntity[]>();\n const ungrouped: MJConversationEntity[] = [];\n for (const c of this.unpinnedConversations) {\n const pid = c.ProjectID ? NormalizeUUID(c.ProjectID) : null;\n if (pid && projectIds.has(pid)) {\n const arr = conversationsByProject.get(pid) ?? [];\n arr.push(c);\n conversationsByProject.set(pid, arr);\n } else {\n ungrouped.push(c);\n }\n }\n this.ungroupedConversations = ungrouped;\n\n // Index projects by parent. A project whose parent isn't loaded is treated\n // as a root so it never disappears from the tree.\n const childrenByParent = new Map<string | null, MJProjectEntity[]>();\n for (const p of projects) {\n const parentId = p.ParentID ? NormalizeUUID(p.ParentID) : null;\n const key = parentId && projectIds.has(parentId) ? parentId : null;\n const arr = childrenByParent.get(key) ?? [];\n arr.push(p);\n childrenByParent.set(key, arr);\n }\n\n const build = (parentKey: string | null, depth: number): FolderNode[] => {\n const projectsAtLevel = childrenByParent.get(parentKey) ?? [];\n return projectsAtLevel.map(p => {\n const children = build(NormalizeUUID(p.ID), depth + 1);\n const conversations = conversationsByProject.get(NormalizeUUID(p.ID)) ?? [];\n const totalCount = conversations.length + children.reduce((sum, ch) => sum + ch.totalCount, 0);\n const hasContent = conversations.length > 0 || children.some(ch => ch.hasContent);\n return { project: p, depth, conversations, children, totalCount, hasContent };\n });\n };\n this.folderTree = build(null, 0);\n this.flatFolders = this.flattenFolders(this.folderTree);\n }\n\n private flattenFolders(nodes: FolderNode[]): FolderNode[] {\n const out: FolderNode[] = [];\n for (const node of nodes) {\n out.push(node);\n out.push(...this.flattenFolders(node.children));\n }\n return out;\n }\n\n private findFolderNode(nodes: FolderNode[], projectId: string): FolderNode | null {\n for (const node of nodes) {\n if (UUIDsEqual(node.project.ID, projectId)) return node;\n const found = this.findFolderNode(node.children, projectId);\n if (found) return found;\n }\n return null;\n }\n\n public isFolderExpanded(projectId: string): boolean {\n return !this.collapsedFolderIds.has(NormalizeUUID(projectId));\n }\n\n public toggleFolder(projectId: string): void {\n const key = NormalizeUUID(projectId);\n if (this.collapsedFolderIds.has(key)) {\n this.collapsedFolderIds.delete(key);\n } else {\n this.collapsedFolderIds.add(key);\n }\n this.saveFolderPrefs();\n }\n\n public toggleGroupBy(): void {\n this.groupBy = this.groupBy === 'project' ? 'none' : 'project';\n this.saveFolderPrefs();\n this.rebuildGroups();\n }\n\n private loadFolderPrefs(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(ConversationListComponent.FolderPrefsKey);\n if (!raw) return;\n const parsed = JSON.parse(raw) as { collapsed?: string[]; groupBy?: ConversationGroupBy };\n this.collapsedFolderIds = new Set((parsed.collapsed ?? []).map(id => NormalizeUUID(id)));\n if (parsed.groupBy === 'none' || parsed.groupBy === 'project') {\n this.groupBy = parsed.groupBy;\n }\n } catch {\n // Corrupt/legacy value — ignore and use defaults\n }\n }\n\n private saveFolderPrefs(): void {\n const payload = JSON.stringify({\n collapsed: Array.from(this.collapsedFolderIds),\n groupBy: this.groupBy\n });\n UserInfoEngine.Instance.SetSettingDebounced(ConversationListComponent.FolderPrefsKey, payload);\n }\n\n // ========================================================================\n // DRAG & DROP (move conversation into/out of a folder)\n // ========================================================================\n\n public onConversationDragStart(conversation: MJConversationEntity, event: DragEvent): void {\n if (this.isSelectionMode) return;\n this.draggedFolderId = null;\n this.draggedConversationId = conversation.ID;\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', conversation.ID);\n }\n }\n\n public onConversationDragEnd(): void {\n this.draggedConversationId = null;\n this.dragOverTargetId = null;\n }\n\n public onFolderDragStart(node: FolderNode, event: DragEvent): void {\n event.stopPropagation();\n this.draggedConversationId = null;\n this.draggedFolderId = node.project.ID;\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', node.project.ID);\n }\n }\n\n public onFolderDragEnd(): void {\n this.draggedFolderId = null;\n this.dragOverTargetId = null;\n }\n\n public onFolderDragOver(projectId: string, event: DragEvent): void {\n // A conversation can drop onto any folder; a folder can drop onto any folder\n // that isn't itself or one of its own descendants (which would create a cycle).\n const accepts = this.draggedConversationId\n ? true\n : this.draggedFolderId\n ? this.isValidFolderDropTarget(projectId)\n : false;\n if (!accepts) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n this.dragOverTargetId = projectId;\n }\n\n public onUngroupedDragOver(event: DragEvent): void {\n if (!this.draggedConversationId) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n this.dragOverTargetId = 'ungrouped';\n }\n\n /** The Folders section header accepts a dragged folder to move it back to the top level. */\n public onFoldersRootDragOver(event: DragEvent): void {\n if (!this.draggedFolderId) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n this.dragOverTargetId = 'folders-root';\n }\n\n public onDragLeave(targetId: string): void {\n if (this.dragOverTargetId === targetId) {\n this.dragOverTargetId = null;\n }\n }\n\n public onFolderDrop(project: MJProjectEntity, event: DragEvent): void {\n event.preventDefault();\n const conversationId = this.draggedConversationId;\n const folderId = this.draggedFolderId;\n this.dragOverTargetId = null;\n this.draggedConversationId = null;\n this.draggedFolderId = null;\n if (conversationId) {\n this.moveConversation(conversationId, project.ID);\n } else if (folderId && this.isValidFolderDropTarget(project.ID, folderId)) {\n this.moveFolder(folderId, project.ID);\n }\n }\n\n public onUngroupedDrop(event: DragEvent): void {\n event.preventDefault();\n const conversationId = this.draggedConversationId;\n this.dragOverTargetId = null;\n this.draggedConversationId = null;\n if (conversationId) {\n this.moveConversation(conversationId, null);\n }\n }\n\n public onFoldersRootDrop(event: DragEvent): void {\n event.preventDefault();\n const folderId = this.draggedFolderId;\n this.dragOverTargetId = null;\n this.draggedFolderId = null;\n if (folderId) {\n this.moveFolder(folderId, null);\n }\n }\n\n /**\n * A folder can be dropped onto a target folder only if the target isn't the dragged\n * folder itself and isn't one of its descendants (otherwise we'd create a cycle).\n */\n private isValidFolderDropTarget(targetId: string, draggedId: string | null = this.draggedFolderId): boolean {\n if (!draggedId) return false;\n if (UUIDsEqual(targetId, draggedId)) return false;\n return !this.isDescendantOf(targetId, draggedId);\n }\n\n /** True when `nodeId` is a descendant of `ancestorId` in the folder tree. */\n private isDescendantOf(nodeId: string, ancestorId: string): boolean {\n const byId = new Map(this.engine.Projects.map(p => [NormalizeUUID(p.ID), p]));\n const visited = new Set<string>();\n let current = byId.get(NormalizeUUID(nodeId));\n while (current?.ParentID) {\n const parentKey = NormalizeUUID(current.ParentID);\n if (visited.has(parentKey)) break; // guard against malformed cycles\n visited.add(parentKey);\n if (UUIDsEqual(parentKey, ancestorId)) return true;\n current = byId.get(parentKey);\n }\n return false;\n }\n\n /** Assigns a conversation to a folder (or null to ungroup) and refreshes the view. */\n private async moveConversation(conversationId: string, projectId: string | null): Promise<void> {\n try {\n await this.engine.MoveConversationToProject(conversationId, projectId, this.currentUser);\n // Reveal the destination folder so the user sees where it landed\n if (projectId) {\n this.collapsedFolderIds.delete(NormalizeUUID(projectId));\n }\n this.rebuildGroups();\n this.cdr.detectChanges();\n } catch (error) {\n console.error('Error moving conversation:', error);\n await this.dialogService.alert('Error', 'Failed to move conversation. Please try again.');\n }\n }\n\n /** Reparents a folder under another folder (or to the top level when projectId is null). */\n private async moveFolder(folderId: string, parentId: string | null): Promise<void> {\n // No-op if it's already under that parent\n const folder = this.engine.Projects.find(p => UUIDsEqual(p.ID, folderId));\n const currentParent = folder?.ParentID ?? null;\n const sameParent = (currentParent === null && parentId === null) ||\n (!!currentParent && !!parentId && UUIDsEqual(currentParent, parentId));\n if (sameParent) return;\n\n try {\n await this.engine.MoveProjectToParent(folderId, parentId, this.currentUser);\n // Reveal the new parent so the moved folder is visible\n if (parentId) {\n this.collapsedFolderIds.delete(NormalizeUUID(parentId));\n }\n this.rebuildGroups();\n this.cdr.detectChanges();\n } catch (error) {\n console.error('Error moving folder:', error);\n await this.dialogService.alert('Error', 'Failed to move folder. Please try again.');\n }\n }\n\n // ========================================================================\n // MOVE-TO-FOLDER MENU\n // ========================================================================\n\n public openMoveSubmenu(conversationId: string, event: Event): void {\n event.stopPropagation();\n this.moveSubmenuConversationId = conversationId;\n }\n\n public closeMoveSubmenu(event: Event): void {\n event.stopPropagation();\n this.moveSubmenuConversationId = null;\n }\n\n public IsInFolder(conversation: MJConversationEntity, projectId: string): boolean {\n return !!conversation.ProjectID && UUIDsEqual(conversation.ProjectID, projectId);\n }\n\n public selectMoveTarget(conversation: MJConversationEntity, projectId: string | null): void {\n this.moveConversation(conversation.ID, projectId);\n this.closeMenu();\n }\n\n // ========================================================================\n // FOLDER CRUD (reuses the existing project form modal)\n // ========================================================================\n\n public createFolder(parentId: string | null, event?: Event): void {\n if (event) event.stopPropagation();\n this.openFolderModal(null, parentId);\n }\n\n public editFolder(project: MJProjectEntity, event?: Event): void {\n if (event) event.stopPropagation();\n this.openFolderModal(project, null);\n }\n\n public createFolderForConversation(conversation: MJConversationEntity, event: Event): void {\n event.stopPropagation();\n const conversationId = conversation.ID;\n this.closeMenu();\n this.openFolderModal(null, null, (created) => this.moveConversation(conversationId, created.ID));\n }\n\n private openFolderModal(\n project: MJProjectEntity | null,\n parentId: string | null,\n onCreated?: (project: MJProjectEntity) => void\n ): void {\n const dialogRef = this.mjDialogService.open({\n content: ProjectFormModalComponent,\n width: 600,\n minWidth: 400\n });\n\n const instance = dialogRef.Content!.instance as unknown as ProjectFormModalComponent;\n instance.dialogRef = dialogRef;\n instance.environmentId = this.environmentId;\n instance.currentUser = this.currentUser;\n if (project) instance.project = project;\n if (parentId) instance.parentId = parentId;\n\n instance.projectSaved.subscribe((saved: MJProjectEntity) => {\n // The engine's entity-event handler keeps the projects cache in sync; we\n // just reveal the parent and refresh, then run any post-create action.\n if (parentId) {\n this.collapsedFolderIds.delete(NormalizeUUID(parentId));\n }\n this.rebuildGroups();\n this.cdr.detectChanges();\n if (onCreated) onCreated(saved);\n });\n }\n\n public async deleteFolder(project: MJProjectEntity, event?: Event): Promise<void> {\n if (event) event.stopPropagation();\n\n const node = this.findFolderNode(this.folderTree, project.ID);\n const total = node?.totalCount ?? 0;\n const childCount = node?.children.length ?? 0;\n\n let message = `Are you sure you want to delete the folder \"${project.Name}\"?`;\n if (total > 0 || childCount > 0) {\n message += `\\n\\nConversations inside will be moved out of the folder`;\n message += childCount > 0 ? ` and subfolders will move up one level.` : `.`;\n message += ` Nothing is deleted.`;\n }\n\n const confirmed = await this.dialogService.confirm({\n title: 'Delete Folder',\n message,\n okText: 'Delete',\n cancelText: 'Cancel',\n dangerous: true\n });\n if (!confirmed) return;\n\n try {\n await this.engine.DeleteProject(project.ID, this.currentUser);\n this.collapsedFolderIds.delete(NormalizeUUID(project.ID));\n this.rebuildGroups();\n this.cdr.detectChanges();\n } catch (error) {\n console.error('Error deleting folder:', error);\n await this.dialogService.alert(\n 'Error',\n error instanceof Error ? error.message : 'Failed to delete folder. Please try again.'\n );\n }\n }\n\n IsConversationActive(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(conversation.ID, this.selectedConversationId);\n }\n\n IsConversationRenamed(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(conversation.ID, this.renamedConversationId);\n }\n\n IsMenuOpen(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(this.openMenuConversationId, conversation.ID);\n }\n\n IsConversationDragging(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(this.draggedConversationId, conversation.ID);\n }\n\n IsMoveSubmenuOpen(conversation: MJConversationEntity): boolean {\n return UUIDsEqual(this.moveSubmenuConversationId, conversation.ID);\n }\n\n selectConversation(conversation: MJConversationEntity): void {\n this.conversationSelected.emit(conversation.ID);\n // Clear unread notifications when conversation is opened\n this.notificationService.markConversationAsRead(conversation.ID);\n }\n\n async createNewConversation(): Promise<void> {\n // Don't create DB record yet - just show the welcome screen\n // Conversation will be created when user sends first message\n this.newConversationRequested.emit();\n }\n\n async renameConversation(conversation: MJConversationEntity): Promise<void> {\n try {\n const result = await this.dialogService.input({\n title: 'Edit Conversation',\n message: 'Update the name and description for this conversation',\n inputLabel: 'Conversation Name',\n inputValue: conversation.Name || '',\n placeholder: 'My Conversation',\n required: true,\n secondInputLabel: 'Description',\n secondInputValue: conversation.Description || '',\n secondInputPlaceholder: 'Optional description',\n secondInputRequired: false,\n okText: 'Save',\n cancelText: 'Cancel'\n });\n\n if (result) {\n const newName = typeof result === 'string' ? result : result.value;\n const newDescription = typeof result === 'string' ? conversation.Description : result.secondValue;\n\n if (newName !== conversation.Name || newDescription !== conversation.Description) {\n await this.engine.SaveConversation(\n conversation.ID,\n { Name: newName, Description: newDescription || '' },\n this.currentUser\n );\n }\n }\n } catch (error) {\n console.error('Error renaming conversation:', error);\n await this.dialogService.alert('Error', 'Failed to update conversation. Please try again.');\n }\n }\n\n async deleteConversation(conversation: MJConversationEntity): Promise<void> {\n try {\n const confirmed = await this.dialogService.confirm({\n title: 'Delete Conversation',\n message: `Are you sure you want to delete \"${conversation.Name}\"? This action cannot be undone.`,\n okText: 'Delete',\n cancelText: 'Cancel'\n });\n\n if (confirmed) {\n const deletedId = conversation.ID;\n await this.engine.DeleteConversation(deletedId, this.currentUser);\n this.cdr.detectChanges();\n this.conversationDeleted.emit(deletedId);\n }\n } catch (error) {\n console.error('Error deleting conversation:', error);\n await this.dialogService.alert('Error', 'Failed to delete conversation. Please try again.');\n }\n }\n\n toggleMenu(conversationId: string, event: Event): void {\n event.stopPropagation();\n this.openMenuConversationId = this.openMenuConversationId === conversationId ? null : conversationId;\n }\n\n closeMenu(): void {\n this.openMenuConversationId = null;\n this.moveSubmenuConversationId = null;\n }\n\n async togglePin(conversation: MJConversationEntity, event?: Event): Promise<void> {\n if (event) event.stopPropagation();\n this.closeMenu(); // Close immediately on user action — don't wait for the async op\n try {\n await this.engine.PinConversation(conversation.ID, !conversation.IsPinned, this.currentUser);\n } catch (error) {\n console.error('Error toggling pin:', error);\n await this.dialogService.alert('Error', 'Failed to pin/unpin conversation. Please try again.');\n }\n }\n\n hasActiveTasks(conversationId: string): boolean {\n return this.conversationIdsWithTasks.has(conversationId);\n }\n\n /** True when this conversation was shared with the current user by someone else. */\n isSharedWithMe(conversation: MJConversationEntity): boolean {\n return this.engine.GetSharedByInfo(conversation.ID) !== null;\n }\n\n /** Tooltip for the sidebar share icon: \"Shared by {email or name}\". */\n sharedWithMeTooltip(conversation: MJConversationEntity): string {\n const info = this.engine.GetSharedByInfo(conversation.ID);\n if (!info) return 'Shared with you';\n return `Shared by ${info.Email ?? info.Name ?? 'another user'}`;\n }\n\n toggleSelectionMode(): void {\n this.isSelectionMode = !this.isSelectionMode;\n if (!this.isSelectionMode) {\n this.selectedConversationIds.clear();\n }\n }\n\n toggleConversationSelection(conversationId: string): void {\n if (this.selectedConversationIds.has(conversationId)) {\n this.selectedConversationIds.delete(conversationId);\n } else {\n this.selectedConversationIds.add(conversationId);\n }\n }\n\n selectAll(): void {\n this.filteredConversations.forEach(c => {\n this.selectedConversationIds.add(c.ID);\n });\n }\n\n deselectAll(): void {\n this.selectedConversationIds.clear();\n }\n\n async bulkDeleteConversations(): Promise<void> {\n const count = this.selectedConversationIds.size;\n\n if (count === 0) return;\n\n const confirmed = await this.dialogService.confirm({\n title: 'Delete Conversations',\n message: `Are you sure you want to delete ${count} conversation${count > 1 ? 's' : ''}? This action cannot be undone.`,\n okText: 'Delete',\n cancelText: 'Cancel'\n });\n\n if (confirmed) {\n try {\n const result = await this.engine.DeleteMultipleConversations(\n Array.from(this.selectedConversationIds),\n this.currentUser\n );\n\n if (result.Failed.length > 0 && result.Successful.length > 0) {\n // Partial success\n const failedNames = result.Failed.map(f => `\"${f.Name}\"`).join(', ');\n await this.dialogService.alert(\n 'Partial Success',\n `Deleted ${result.Successful.length} of ${count} conversations.\\n\\n` +\n `${result.Failed.length} could not be deleted: ${failedNames}`\n );\n } else if (result.Failed.length > 0 && result.Successful.length === 0) {\n // All failed\n await this.dialogService.alert(\n 'Delete Failed',\n `None of the ${count} conversations could be deleted. They may have already been removed.`\n );\n }\n\n // Emit deleted events for successful deletions\n for (const id of result.Successful) {\n this.conversationDeleted.emit(id);\n }\n\n } catch (error) {\n console.error('Error deleting conversations:', error);\n await this.dialogService.alert('Error', 'Failed to delete conversations. Please try again.');\n } finally {\n // Always exit selection mode after an attempt, whether success or failure\n this.selectedConversationIds.clear();\n this.isSelectionMode = false;\n this.cdr.detectChanges();\n }\n }\n }\n\n handleConversationClick(conversation: MJConversationEntity): void {\n if (this.isSelectionMode) {\n this.toggleConversationSelection(conversation.ID);\n } else {\n this.selectConversation(conversation);\n }\n }\n}"]}