@memberjunction/ng-conversations 5.43.0 → 5.45.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 (405) hide show
  1. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +0 -1
  2. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
  3. package/dist/lib/components/active-tasks/active-tasks-panel.component.js +56 -52
  4. package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
  5. package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +3 -1
  6. package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
  7. package/dist/lib/components/artifact/artifact-share-modal.component.js +52 -52
  8. package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
  9. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  10. package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
  11. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  12. package/dist/lib/components/collection/collection-share-modal.component.d.ts +3 -1
  13. package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
  14. package/dist/lib/components/collection/collection-share-modal.component.js +56 -56
  15. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
  16. package/dist/lib/components/collection/collection-tree.component.d.ts +3 -1
  17. package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
  18. package/dist/lib/components/collection/collection-tree.component.js +10 -7
  19. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  20. package/dist/lib/components/collection/collection-view.component.d.ts +3 -1
  21. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  22. package/dist/lib/components/collection/collection-view.component.js +29 -41
  23. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  24. package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
  25. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  26. package/dist/lib/components/collection/collections-full-view.component.js +134 -166
  27. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  28. package/dist/lib/components/composer/ai-composer.component.d.ts +103 -0
  29. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -0
  30. package/dist/lib/components/composer/ai-composer.component.js +263 -0
  31. package/dist/lib/components/composer/ai-composer.component.js.map +1 -0
  32. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +76 -12
  33. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  34. package/dist/lib/components/conversation/conversation-chat-area.component.js +522 -158
  35. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  36. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -1
  37. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
  38. package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
  39. package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
  40. package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
  41. package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
  42. package/dist/lib/components/library/library-full-view.component.js +20 -24
  43. package/dist/lib/components/library/library-full-view.component.js.map +1 -1
  44. package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
  45. package/dist/lib/components/members/members-modal.component.js +10 -11
  46. package/dist/lib/components/members/members-modal.component.js.map +1 -1
  47. package/dist/lib/components/message/message-input.component.d.ts +87 -23
  48. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  49. package/dist/lib/components/message/message-input.component.js +245 -158
  50. package/dist/lib/components/message/message-input.component.js.map +1 -1
  51. package/dist/lib/components/message/message-item.component.d.ts +11 -3
  52. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  53. package/dist/lib/components/message/message-item.component.js +73 -21
  54. package/dist/lib/components/message/message-item.component.js.map +1 -1
  55. package/dist/lib/components/message/message-list.component.js +6 -9
  56. package/dist/lib/components/message/message-list.component.js.map +1 -1
  57. package/dist/lib/components/overlay/chat-overlay.component.d.ts +4 -1
  58. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  59. package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
  60. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  61. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
  62. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
  63. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
  64. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
  65. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
  66. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
  67. package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
  68. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
  69. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
  70. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
  71. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
  72. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
  73. package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
  74. package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
  75. package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
  76. package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
  77. package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
  78. package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
  79. package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
  80. package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
  81. package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
  82. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
  83. package/dist/lib/components/realtime/media/media-channel.js +253 -0
  84. package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
  85. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
  86. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
  87. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
  88. package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
  89. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
  90. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
  91. package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
  92. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
  93. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
  94. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  95. package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
  96. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  97. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
  98. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  99. package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
  100. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  101. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
  102. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  103. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  104. package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
  105. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  106. package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
  107. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  108. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
  109. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
  110. package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
  111. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
  112. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
  113. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  114. package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
  115. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  116. package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
  117. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
  118. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
  119. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
  120. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
  121. package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
  122. package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
  123. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
  124. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  125. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
  126. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  127. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
  128. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  129. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
  130. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  131. package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
  132. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
  133. package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
  134. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
  135. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  136. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  137. package/dist/lib/components/search/search-panel.component.js +92 -101
  138. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  139. package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
  140. package/dist/lib/components/share/share-modal.component.js +10 -11
  141. package/dist/lib/components/share/share-modal.component.js.map +1 -1
  142. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
  143. package/dist/lib/components/shared/user-picker.component.js +12 -15
  144. package/dist/lib/components/shared/user-picker.component.js.map +1 -1
  145. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +11 -3
  146. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
  147. package/dist/lib/components/sidebar/conversation-sidebar.component.js +34 -10
  148. package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
  149. package/dist/lib/components/sidebar/routines-section.component.d.ts +73 -0
  150. package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -0
  151. package/dist/lib/components/sidebar/routines-section.component.js +211 -0
  152. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -0
  153. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +12 -0
  154. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  155. package/dist/lib/components/tasks/tasks-dropdown.component.js +37 -1
  156. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  157. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +16 -5
  158. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  159. package/dist/lib/components/workspace/conversation-workspace.component.js +51 -31
  160. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  161. package/dist/lib/composer-plugins/agent-mention.provider.d.ts +16 -0
  162. package/dist/lib/composer-plugins/agent-mention.provider.d.ts.map +1 -0
  163. package/dist/lib/composer-plugins/agent-mention.provider.js +28 -0
  164. package/dist/lib/composer-plugins/agent-mention.provider.js.map +1 -0
  165. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +20 -0
  166. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -0
  167. package/dist/lib/composer-plugins/base-conversation-mention.provider.js +32 -0
  168. package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -0
  169. package/dist/lib/composer-plugins/load-composer-plugins.d.ts +9 -0
  170. package/dist/lib/composer-plugins/load-composer-plugins.d.ts.map +1 -0
  171. package/dist/lib/composer-plugins/load-composer-plugins.js +17 -0
  172. package/dist/lib/composer-plugins/load-composer-plugins.js.map +1 -0
  173. package/dist/lib/composer-plugins/record-mention.provider.d.ts +14 -0
  174. package/dist/lib/composer-plugins/record-mention.provider.d.ts.map +1 -0
  175. package/dist/lib/composer-plugins/record-mention.provider.js +26 -0
  176. package/dist/lib/composer-plugins/record-mention.provider.js.map +1 -0
  177. package/dist/lib/composer-plugins/skill-command.provider.d.ts +15 -0
  178. package/dist/lib/composer-plugins/skill-command.provider.d.ts.map +1 -0
  179. package/dist/lib/composer-plugins/skill-command.provider.js +27 -0
  180. package/dist/lib/composer-plugins/skill-command.provider.js.map +1 -0
  181. package/dist/lib/conversations.module.d.ts +68 -64
  182. package/dist/lib/conversations.module.d.ts.map +1 -1
  183. package/dist/lib/conversations.module.js +69 -18
  184. package/dist/lib/conversations.module.js.map +1 -1
  185. package/dist/lib/models/conversation-state.model.d.ts +6 -3
  186. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  187. package/dist/lib/models/conversation-state.model.js.map +1 -1
  188. package/dist/lib/services/conversation-agent.service.d.ts +9 -2
  189. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  190. package/dist/lib/services/conversation-agent.service.js +26 -2
  191. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  192. package/dist/lib/services/conversation-attachment.service.d.ts +1 -1
  193. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
  194. package/dist/lib/services/conversation-attachment.service.js.map +1 -1
  195. package/dist/lib/services/mention-autocomplete.service.d.ts +42 -19
  196. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  197. package/dist/lib/services/mention-autocomplete.service.js +113 -18
  198. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  199. package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
  200. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
  201. package/dist/lib/services/realtime-audio-recorder.js +379 -0
  202. package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
  203. package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
  204. package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
  205. package/dist/lib/services/realtime-pcm-wav.js +205 -0
  206. package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
  207. package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
  208. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  209. package/dist/lib/services/realtime-session-review.service.js +12 -3
  210. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  211. package/dist/lib/services/realtime-session.service.d.ts +210 -20
  212. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  213. package/dist/lib/services/realtime-session.service.js +452 -21
  214. package/dist/lib/services/realtime-session.service.js.map +1 -1
  215. package/dist/lib/services/realtime-sessions-adapter.js +1 -1
  216. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
  217. package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
  218. package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
  219. package/dist/lib/services/ui-command-handler.service.js +6 -2
  220. package/dist/lib/services/ui-command-handler.service.js.map +1 -1
  221. package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
  222. package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
  223. package/dist/lib/utils/plan-mode-preference.js +130 -0
  224. package/dist/lib/utils/plan-mode-preference.js.map +1 -0
  225. package/dist/public-api.d.ts +29 -3
  226. package/dist/public-api.d.ts.map +1 -1
  227. package/dist/public-api.js +46 -3
  228. package/dist/public-api.js.map +1 -1
  229. package/package.json +30 -26
  230. package/dist/__tests__/attachment-badge.test.d.ts +0 -2
  231. package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
  232. package/dist/__tests__/attachment-badge.test.js +0 -66
  233. package/dist/__tests__/attachment-badge.test.js.map +0 -1
  234. package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
  235. package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
  236. package/dist/__tests__/channel-optional-surface.test.js +0 -53
  237. package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
  238. package/dist/__tests__/chat-events.test.d.ts +0 -14
  239. package/dist/__tests__/chat-events.test.d.ts.map +0 -1
  240. package/dist/__tests__/chat-events.test.js +0 -109
  241. package/dist/__tests__/chat-events.test.js.map +0 -1
  242. package/dist/__tests__/collections-full-view.test.d.ts +0 -2
  243. package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
  244. package/dist/__tests__/collections-full-view.test.js +0 -225
  245. package/dist/__tests__/collections-full-view.test.js.map +0 -1
  246. package/dist/__tests__/conversation-cache.test.d.ts +0 -2
  247. package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
  248. package/dist/__tests__/conversation-cache.test.js +0 -233
  249. package/dist/__tests__/conversation-cache.test.js.map +0 -1
  250. package/dist/__tests__/conversation-naming.test.d.ts +0 -2
  251. package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
  252. package/dist/__tests__/conversation-naming.test.js +0 -110
  253. package/dist/__tests__/conversation-naming.test.js.map +0 -1
  254. package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
  255. package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
  256. package/dist/__tests__/delegation-result-parser.test.js +0 -107
  257. package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
  258. package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
  259. package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
  260. package/dist/__tests__/distinct-artifacts.test.js +0 -56
  261. package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
  262. package/dist/__tests__/event-wiring.test.d.ts +0 -15
  263. package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
  264. package/dist/__tests__/event-wiring.test.js +0 -100
  265. package/dist/__tests__/event-wiring.test.js.map +0 -1
  266. package/dist/__tests__/index.test.d.ts +0 -2
  267. package/dist/__tests__/index.test.d.ts.map +0 -1
  268. package/dist/__tests__/index.test.js +0 -7
  269. package/dist/__tests__/index.test.js.map +0 -1
  270. package/dist/__tests__/narration-template.test.d.ts +0 -2
  271. package/dist/__tests__/narration-template.test.d.ts.map +0 -1
  272. package/dist/__tests__/narration-template.test.js +0 -76
  273. package/dist/__tests__/narration-template.test.js.map +0 -1
  274. package/dist/__tests__/notification-model.test.d.ts +0 -2
  275. package/dist/__tests__/notification-model.test.d.ts.map +0 -1
  276. package/dist/__tests__/notification-model.test.js +0 -68
  277. package/dist/__tests__/notification-model.test.js.map +0 -1
  278. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
  279. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
  280. package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
  281. package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
  282. package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
  283. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
  284. package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
  285. package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
  286. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
  287. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
  288. package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
  289. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
  290. package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
  291. package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
  292. package/dist/__tests__/realtime-disclosure.test.js +0 -164
  293. package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
  294. package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
  295. package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
  296. package/dist/__tests__/realtime-pairing.test.js +0 -207
  297. package/dist/__tests__/realtime-pairing.test.js.map +0 -1
  298. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
  299. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
  300. package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
  301. package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
  302. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
  303. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
  304. package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
  305. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
  306. package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
  307. package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
  308. package/dist/__tests__/realtime-session-channels.test.js +0 -252
  309. package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
  310. package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
  311. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
  312. package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
  313. package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
  314. package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
  315. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
  316. package/dist/__tests__/realtime-session-minimized.test.js +0 -32
  317. package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
  318. package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
  319. package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
  320. package/dist/__tests__/realtime-session-mint.test.js +0 -69
  321. package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
  322. package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
  323. package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
  324. package/dist/__tests__/realtime-session-policy.test.js +0 -303
  325. package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
  326. package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
  327. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
  328. package/dist/__tests__/realtime-session-review.service.test.js +0 -743
  329. package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
  330. package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
  331. package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
  332. package/dist/__tests__/realtime-session-state.test.js +0 -83
  333. package/dist/__tests__/realtime-session-state.test.js.map +0 -1
  334. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
  335. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
  336. package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
  337. package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
  338. package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
  339. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
  340. package/dist/__tests__/realtime-session-timeline.test.js +0 -142
  341. package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
  342. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
  343. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
  344. package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
  345. package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
  346. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
  347. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
  348. package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
  349. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
  350. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
  351. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
  352. package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
  353. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
  354. package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
  355. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
  356. package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
  357. package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
  358. package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
  359. package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
  360. package/dist/__tests__/remote-browser-channel.test.js +0 -585
  361. package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
  362. package/dist/__tests__/search-service.test.d.ts +0 -2
  363. package/dist/__tests__/search-service.test.d.ts.map +0 -1
  364. package/dist/__tests__/search-service.test.js +0 -114
  365. package/dist/__tests__/search-service.test.js.map +0 -1
  366. package/dist/__tests__/slot-defaults.test.d.ts +0 -24
  367. package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
  368. package/dist/__tests__/slot-defaults.test.js +0 -63
  369. package/dist/__tests__/slot-defaults.test.js.map +0 -1
  370. package/dist/__tests__/toast-service.test.d.ts +0 -2
  371. package/dist/__tests__/toast-service.test.d.ts.map +0 -1
  372. package/dist/__tests__/toast-service.test.js +0 -143
  373. package/dist/__tests__/toast-service.test.js.map +0 -1
  374. package/dist/__tests__/user-authorization.test.d.ts +0 -2
  375. package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
  376. package/dist/__tests__/user-authorization.test.js +0 -97
  377. package/dist/__tests__/user-authorization.test.js.map +0 -1
  378. package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
  379. package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
  380. package/dist/__tests__/voice-session-narration.test.js +0 -609
  381. package/dist/__tests__/voice-session-narration.test.js.map +0 -1
  382. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
  383. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
  384. package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
  385. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
  386. package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
  387. package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
  388. package/dist/__tests__/whiteboard-channel.test.js +0 -260
  389. package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
  390. package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
  391. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
  392. package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
  393. package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
  394. package/dist/lib/components/mention/mention-dropdown.component.d.ts +0 -53
  395. package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +0 -1
  396. package/dist/lib/components/mention/mention-dropdown.component.js +0 -276
  397. package/dist/lib/components/mention/mention-dropdown.component.js.map +0 -1
  398. package/dist/lib/components/mention/mention-editor.component.d.ts +0 -256
  399. package/dist/lib/components/mention/mention-editor.component.d.ts.map +0 -1
  400. package/dist/lib/components/mention/mention-editor.component.js +0 -1233
  401. package/dist/lib/components/mention/mention-editor.component.js.map +0 -1
  402. package/dist/lib/components/message/message-input-box.component.d.ts +0 -137
  403. package/dist/lib/components/message/message-input-box.component.d.ts.map +0 -1
  404. package/dist/lib/components/message/message-input-box.component.js +0 -321
  405. package/dist/lib/components/message/message-input-box.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"user-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/shared/user-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\nimport { FormsModule } from '@angular/forms';\nimport { UserInfo, RunView } from '@memberjunction/core';\nimport { MJUserEntity } from '@memberjunction/core-entities';\n\nexport interface UserSearchResult {\n id: string;\n name: string;\n email: string;\n firstName: string;\n lastName: string;\n}\n\n@Component({\n selector: 'mj-user-picker',\n standalone: true,\n imports: [FormsModule],\n template: `\n <div class=\"user-picker\">\n <div class=\"search-input-wrapper\">\n <input\n type=\"text\"\n class=\"user-search-input\"\n [(ngModel)]=\"searchQuery\"\n [placeholder]=\"placeholder\"\n (keydown.enter)=\"onSearch()\"\n [disabled]=\"isSearching\"\n />\n <button class=\"search-button\" (click)=\"onSearch()\" [disabled]=\"isSearching\">\n @if (isSearching) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n }\n </button>\n </div>\n\n @if (showResults && searchResults.length > 0) {\n <div class=\"search-results-dropdown\">\n @for (user of searchResults; track user.id) {\n <div class=\"user-search-item\" (click)=\"onSelectUser(user)\">\n <div class=\"user-avatar\">\n <i class=\"fa-solid fa-user\"></i>\n </div>\n <div class=\"user-info\">\n <div class=\"user-name\">{{ user.name }}</div>\n <div class=\"user-email\">{{ user.email }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n @if (showResults && searchResults.length === 0 && searchQuery.length >= 2 && !isSearching) {\n <div class=\"search-results-dropdown\">\n <div class=\"no-results\">\n <i class=\"fa-solid fa-user-slash\"></i>\n <span>No users found</span>\n </div>\n </div>\n }\n </div>\n `,\n styles: [`\n .user-picker {\n width: 100%;\n position: relative;\n }\n\n .search-input-wrapper {\n display: flex;\n gap: 8px;\n width: 100%;\n }\n\n .user-search-input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n outline: none;\n transition: border-color 0.2s;\n }\n\n .user-search-input:focus {\n border-color: #6366F1;\n }\n\n .user-search-input:disabled {\n background: #F3F4F6;\n cursor: not-allowed;\n }\n\n .search-button {\n padding: 8px 16px;\n background: #6366F1;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n }\n\n .search-button:hover:not(:disabled) {\n background: #5558E3;\n }\n\n .search-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .search-button i {\n font-size: 14px;\n }\n\n .search-results-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-height: 300px;\n overflow-y: auto;\n z-index: 1000;\n }\n\n .user-search-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .user-search-item:hover {\n background-color: #F3F4F6;\n }\n\n .user-avatar {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667EEA 0%, #764BA2 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 16px;\n flex-shrink: 0;\n }\n\n .user-info {\n flex: 1;\n min-width: 0;\n }\n\n .user-name {\n font-size: 14px;\n font-weight: 500;\n color: #1F2937;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .user-email {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .no-results {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 24px;\n color: #9CA3AF;\n }\n\n .no-results i {\n font-size: 32px;\n }\n\n .no-results span {\n font-size: 14px;\n }\n `]\n})\nexport class UserPickerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() currentUser!: UserInfo;\n @Input() excludeUserIds: string[] = [];\n @Input() placeholder: string = 'Search for a user (press Enter)...';\n\n constructor(private cdr: ChangeDetectorRef) {\n super();}\n\n @Output() userSelected = new EventEmitter<UserSearchResult>();\n\n searchQuery: string = '';\n searchResults: UserSearchResult[] = [];\n isSearching: boolean = false;\n showResults: boolean = false;\n\n ngOnInit(): void {\n // Add click outside listener to close dropdown\n document.addEventListener('click', this.handleClickOutside.bind(this));\n }\n\n ngOnDestroy(): void {\n document.removeEventListener('click', this.handleClickOutside.bind(this));\n }\n\n private handleClickOutside(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (!target.closest('.user-picker')) {\n this.showResults = false;\n }\n }\n\n onSearch(): void {\n if (!this.searchQuery || this.searchQuery.trim().length < 2) {\n this.showResults = false;\n return;\n }\n\n this.performSearch(this.searchQuery.trim());\n }\n\n onSelectUser(user: UserSearchResult): void {\n this.userSelected.emit(user);\n this.searchQuery = '';\n this.searchResults = [];\n this.showResults = false;\n }\n\n private async performSearch(query: string): Promise<void> {\n if (!query || query.length < 2) {\n this.searchResults = [];\n this.showResults = false;\n return;\n }\n\n this.isSearching = true;\n this.showResults = true;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Escape single quotes in query to prevent SQL errors\n const escapedQuery = query.replace(/'/g, \"''\");\n\n // Build exclude filter\n let excludeFilter = '';\n if (this.excludeUserIds.length > 0) {\n const ids = this.excludeUserIds.map(id => `'${id}'`).join(',');\n excludeFilter = ` AND ID NOT IN (${ids})`;\n }\n\n // Search in Name, Email, FirstName, and LastName (case-insensitive)\n const searchFilter = `(\n Name LIKE '%${escapedQuery}%' OR\n Email LIKE '%${escapedQuery}%' OR\n FirstName LIKE '%${escapedQuery}%' OR\n LastName LIKE '%${escapedQuery}%'\n )${excludeFilter}`;\n\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: searchFilter,\n OrderBy: 'Name ASC',\n MaxRows: 20,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n console.log('User search result:', {\n query,\n success: result.Success,\n count: result.Results?.length,\n error: result.ErrorMessage\n });\n\n if (result.Success && result.Results) {\n this.searchResults = result.Results.map(user => ({\n id: user.ID,\n name: user.Name,\n email: user.Email,\n firstName: user.FirstName || '',\n lastName: user.LastName || ''\n }));\n } else {\n console.warn('User search returned no results or failed:', result.ErrorMessage);\n this.searchResults = [];\n }\n } catch (error) {\n console.error('Error searching users:', error);\n this.searchResults = [];\n } finally {\n this.isSearching = false;\n this.cdr.detectChanges();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"user-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/shared/user-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\nimport { FormsModule } from '@angular/forms';\nimport { MJEmptyStateComponent } from '@memberjunction/ng-ui-components';\nimport { UserInfo, RunView } from '@memberjunction/core';\nimport { MJUserEntity } from '@memberjunction/core-entities';\n\nexport interface UserSearchResult {\n id: string;\n name: string;\n email: string;\n firstName: string;\n lastName: string;\n}\n\n@Component({\n selector: 'mj-user-picker',\n standalone: true,\n imports: [FormsModule, MJEmptyStateComponent],\n template: `\n <div class=\"user-picker\">\n <div class=\"search-input-wrapper\">\n <input\n type=\"text\"\n class=\"user-search-input\"\n [(ngModel)]=\"searchQuery\"\n [placeholder]=\"placeholder\"\n (keydown.enter)=\"onSearch()\"\n [disabled]=\"isSearching\"\n />\n <button class=\"search-button\" (click)=\"onSearch()\" [disabled]=\"isSearching\">\n @if (isSearching) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n }\n </button>\n </div>\n\n @if (showResults && searchResults.length > 0) {\n <div class=\"search-results-dropdown\">\n @for (user of searchResults; track user.id) {\n <div class=\"user-search-item\" (click)=\"onSelectUser(user)\">\n <div class=\"user-avatar\">\n <i class=\"fa-solid fa-user\"></i>\n </div>\n <div class=\"user-info\">\n <div class=\"user-name\">{{ user.name }}</div>\n <div class=\"user-email\">{{ user.email }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n @if (showResults && searchResults.length === 0 && searchQuery.length >= 2 && !isSearching) {\n <div class=\"search-results-dropdown\">\n <mj-empty-state Variant=\"no-results\" Size=\"compact\"\n Icon=\"fa-solid fa-user-slash\" Title=\"No users found\" />\n </div>\n }\n </div>\n `,\n styles: [`\n .user-picker {\n width: 100%;\n position: relative;\n }\n\n .search-input-wrapper {\n display: flex;\n gap: 8px;\n width: 100%;\n }\n\n .user-search-input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n outline: none;\n transition: border-color 0.2s;\n }\n\n .user-search-input:focus {\n border-color: #6366F1;\n }\n\n .user-search-input:disabled {\n background: #F3F4F6;\n cursor: not-allowed;\n }\n\n .search-button {\n padding: 8px 16px;\n background: #6366F1;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n }\n\n .search-button:hover:not(:disabled) {\n background: #5558E3;\n }\n\n .search-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .search-button i {\n font-size: 14px;\n }\n\n .search-results-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-height: 300px;\n overflow-y: auto;\n z-index: 1000;\n }\n\n .user-search-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .user-search-item:hover {\n background-color: #F3F4F6;\n }\n\n .user-avatar {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667EEA 0%, #764BA2 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 16px;\n flex-shrink: 0;\n }\n\n .user-info {\n flex: 1;\n min-width: 0;\n }\n\n .user-name {\n font-size: 14px;\n font-weight: 500;\n color: #1F2937;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .user-email {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n `]\n})\nexport class UserPickerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() currentUser!: UserInfo;\n @Input() excludeUserIds: string[] = [];\n @Input() placeholder: string = 'Search for a user (press Enter)...';\n\n constructor(private cdr: ChangeDetectorRef) {\n super();}\n\n @Output() userSelected = new EventEmitter<UserSearchResult>();\n\n searchQuery: string = '';\n searchResults: UserSearchResult[] = [];\n isSearching: boolean = false;\n showResults: boolean = false;\n\n ngOnInit(): void {\n // Add click outside listener to close dropdown\n document.addEventListener('click', this.handleClickOutside.bind(this));\n }\n\n ngOnDestroy(): void {\n document.removeEventListener('click', this.handleClickOutside.bind(this));\n }\n\n private handleClickOutside(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (!target.closest('.user-picker')) {\n this.showResults = false;\n }\n }\n\n onSearch(): void {\n if (!this.searchQuery || this.searchQuery.trim().length < 2) {\n this.showResults = false;\n return;\n }\n\n this.performSearch(this.searchQuery.trim());\n }\n\n onSelectUser(user: UserSearchResult): void {\n this.userSelected.emit(user);\n this.searchQuery = '';\n this.searchResults = [];\n this.showResults = false;\n }\n\n private async performSearch(query: string): Promise<void> {\n if (!query || query.length < 2) {\n this.searchResults = [];\n this.showResults = false;\n return;\n }\n\n this.isSearching = true;\n this.showResults = true;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Escape single quotes in query to prevent SQL errors\n const escapedQuery = query.replace(/'/g, \"''\");\n\n // Build exclude filter\n let excludeFilter = '';\n if (this.excludeUserIds.length > 0) {\n const ids = this.excludeUserIds.map(id => `'${id}'`).join(',');\n excludeFilter = ` AND ID NOT IN (${ids})`;\n }\n\n // Search in Name, Email, FirstName, and LastName (case-insensitive)\n const searchFilter = `(\n Name LIKE '%${escapedQuery}%' OR\n Email LIKE '%${escapedQuery}%' OR\n FirstName LIKE '%${escapedQuery}%' OR\n LastName LIKE '%${escapedQuery}%'\n )${excludeFilter}`;\n\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: searchFilter,\n OrderBy: 'Name ASC',\n MaxRows: 20,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n console.log('User search result:', {\n query,\n success: result.Success,\n count: result.Results?.length,\n error: result.ErrorMessage\n });\n\n if (result.Success && result.Results) {\n this.searchResults = result.Results.map(user => ({\n id: user.ID,\n name: user.Name,\n email: user.Email,\n firstName: user.FirstName || '',\n lastName: user.LastName || ''\n }));\n } else {\n console.warn('User search returned no results or failed:', result.ErrorMessage);\n this.searchResults = [];\n }\n } catch (error) {\n console.error('Error searching users:', error);\n this.searchResults = [];\n } finally {\n this.isSearching = false;\n this.cdr.detectChanges();\n }\n }\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  import { EventEmitter } from '@angular/core';
2
- import { UserInfo } from '@memberjunction/core';
2
+ import { CompositeKey, UserInfo } from '@memberjunction/core';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
4
  import { NavigationTab } from '../../models/conversation-state.model';
4
5
  import * as i0 from "@angular/core";
5
- export declare class ConversationSidebarComponent {
6
+ export declare class ConversationSidebarComponent extends BaseAngularComponent {
6
7
  activeTab: NavigationTab;
7
8
  environmentId: string;
8
9
  currentUser: UserInfo;
@@ -10,13 +11,20 @@ export declare class ConversationSidebarComponent {
10
11
  renamedConversationId: string | null;
11
12
  isSidebarPinned: boolean;
12
13
  isMobileView: boolean;
14
+ /** Show the Routines section at the bottom of the sidebar (bubbled from the workspace; default true). */
15
+ ShowRoutines: boolean;
13
16
  conversationSelected: EventEmitter<string>;
17
+ /** Forwarded from the routines section — a run's linked execution record was clicked. */
18
+ openEntityRecord: EventEmitter<{
19
+ entityName: string;
20
+ compositeKey: CompositeKey;
21
+ }>;
14
22
  newConversationRequested: EventEmitter<void>;
15
23
  pinSidebarRequested: EventEmitter<void>;
16
24
  unpinSidebarRequested: EventEmitter<void>;
17
25
  onPinSidebarRequested(): void;
18
26
  onUnpinSidebarRequested(): void;
19
27
  static ɵfac: i0.ɵɵFactoryDeclaration<ConversationSidebarComponent, never>;
20
- static ɵcmp: i0.ɵɵComponentDeclaration<ConversationSidebarComponent, "mj-conversation-sidebar", never, { "activeTab": { "alias": "activeTab"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "selectedConversationId": { "alias": "selectedConversationId"; "required": false; }; "renamedConversationId": { "alias": "renamedConversationId"; "required": false; }; "isSidebarPinned": { "alias": "isSidebarPinned"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; }, { "conversationSelected": "conversationSelected"; "newConversationRequested": "newConversationRequested"; "pinSidebarRequested": "pinSidebarRequested"; "unpinSidebarRequested": "unpinSidebarRequested"; }, never, never, false, never>;
28
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConversationSidebarComponent, "mj-conversation-sidebar", never, { "activeTab": { "alias": "activeTab"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "selectedConversationId": { "alias": "selectedConversationId"; "required": false; }; "renamedConversationId": { "alias": "renamedConversationId"; "required": false; }; "isSidebarPinned": { "alias": "isSidebarPinned"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; "ShowRoutines": { "alias": "ShowRoutines"; "required": false; }; }, { "conversationSelected": "conversationSelected"; "openEntityRecord": "openEntityRecord"; "newConversationRequested": "newConversationRequested"; "pinSidebarRequested": "pinSidebarRequested"; "unpinSidebarRequested": "unpinSidebarRequested"; }, never, never, false, never>;
21
29
  }
22
30
  //# sourceMappingURL=conversation-sidebar.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-sidebar.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/conversation-sidebar.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;;AAEtE,qBAyDa,4BAA4B;IAC9B,SAAS,EAAE,aAAa,CAAmB;IAC3C,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IACvB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5C,eAAe,EAAE,OAAO,CAAQ;IAChC,YAAY,EAAE,OAAO,CAAS;IAE7B,oBAAoB,uBAA8B;IAClD,wBAAwB,qBAA4B;IACpD,mBAAmB,qBAA4B;IAC/C,qBAAqB,qBAA4B;IAE3D,qBAAqB,IAAI,IAAI;IAI7B,uBAAuB,IAAI,IAAI;yCAlBpB,4BAA4B;2CAA5B,4BAA4B;CAqBxC"}
1
+ {"version":3,"file":"conversation-sidebar.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/conversation-sidebar.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;;AAEtE,qBAmEa,4BAA6B,SAAQ,oBAAoB;IAC3D,SAAS,EAAE,aAAa,CAAmB;IAC3C,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IACvB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5C,eAAe,EAAE,OAAO,CAAQ;IAChC,YAAY,EAAE,OAAO,CAAS;IACvC,yGAAyG;IAChG,YAAY,EAAE,OAAO,CAAQ;IAE5B,oBAAoB,uBAA8B;IAC5D,yFAAyF;IAC/E,gBAAgB;oBAAkC,MAAM;sBAAgB,YAAY;OAAM;IAC1F,wBAAwB,qBAA4B;IACpD,mBAAmB,qBAA4B;IAC/C,qBAAqB,qBAA4B;IAE3D,qBAAqB,IAAI,IAAI;IAI7B,uBAAuB,IAAI,IAAI;yCAtBpB,4BAA4B;2CAA5B,4BAA4B;CAyBxC"}
@@ -1,10 +1,12 @@
1
1
  import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
2
3
  import * as i0 from "@angular/core";
3
- import * as i1 from "../conversation/conversation-list.component";
4
- import * as i2 from "../collection/collection-tree.component";
4
+ import * as i1 from "./routines-section.component";
5
+ import * as i2 from "../conversation/conversation-list.component";
6
+ import * as i3 from "../collection/collection-tree.component";
5
7
  function ConversationSidebarComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
6
8
  const _r1 = i0.ɵɵgetCurrentView();
7
- i0.ɵɵelementStart(0, "div", 1)(1, "mj-conversation-list", 2);
9
+ i0.ɵɵelementStart(0, "div", 1)(1, "mj-conversation-list", 3);
8
10
  i0.ɵɵlistener("conversationSelected", function ConversationSidebarComponent_Conditional_1_Template_mj_conversation_list_conversationSelected_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.conversationSelected.emit($event)); })("newConversationRequested", function ConversationSidebarComponent_Conditional_1_Template_mj_conversation_list_newConversationRequested_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.newConversationRequested.emit()); })("pinSidebarRequested", function ConversationSidebarComponent_Conditional_1_Template_mj_conversation_list_pinSidebarRequested_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onPinSidebarRequested()); })("unpinSidebarRequested", function ConversationSidebarComponent_Conditional_1_Template_mj_conversation_list_unpinSidebarRequested_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onUnpinSidebarRequested()); });
9
11
  i0.ɵɵelementEnd()();
10
12
  } if (rf & 2) {
@@ -14,14 +16,14 @@ function ConversationSidebarComponent_Conditional_1_Template(rf, ctx) { if (rf &
14
16
  } }
15
17
  function ConversationSidebarComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
16
18
  i0.ɵɵelementStart(0, "div", 1);
17
- i0.ɵɵelement(1, "mj-collection-tree", 3);
19
+ i0.ɵɵelement(1, "mj-collection-tree", 4);
18
20
  i0.ɵɵelementEnd();
19
21
  } if (rf & 2) {
20
22
  const ctx_r1 = i0.ɵɵnextContext();
21
23
  i0.ɵɵadvance();
22
24
  i0.ɵɵproperty("environmentId", ctx_r1.environmentId)("currentUser", ctx_r1.currentUser);
23
25
  } }
24
- export class ConversationSidebarComponent {
26
+ export class ConversationSidebarComponent extends BaseAngularComponent {
25
27
  activeTab = 'conversations';
26
28
  environmentId;
27
29
  currentUser;
@@ -29,7 +31,11 @@ export class ConversationSidebarComponent {
29
31
  renamedConversationId = null;
30
32
  isSidebarPinned = true;
31
33
  isMobileView = false;
34
+ /** Show the Routines section at the bottom of the sidebar (bubbled from the workspace; default true). */
35
+ ShowRoutines = true;
32
36
  conversationSelected = new EventEmitter();
37
+ /** Forwarded from the routines section — a run's linked execution record was clicked. */
38
+ openEntityRecord = new EventEmitter();
33
39
  newConversationRequested = new EventEmitter();
34
40
  pinSidebarRequested = new EventEmitter();
35
41
  unpinSidebarRequested = new EventEmitter();
@@ -39,18 +45,22 @@ export class ConversationSidebarComponent {
39
45
  onUnpinSidebarRequested() {
40
46
  this.unpinSidebarRequested.emit();
41
47
  }
42
- static ɵfac = function ConversationSidebarComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ConversationSidebarComponent)(); };
43
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationSidebarComponent, selectors: [["mj-conversation-sidebar"]], inputs: { activeTab: "activeTab", environmentId: "environmentId", currentUser: "currentUser", selectedConversationId: "selectedConversationId", renamedConversationId: "renamedConversationId", isSidebarPinned: "isSidebarPinned", isMobileView: "isMobileView" }, outputs: { conversationSelected: "conversationSelected", newConversationRequested: "newConversationRequested", pinSidebarRequested: "pinSidebarRequested", unpinSidebarRequested: "unpinSidebarRequested" }, standalone: false, decls: 3, vars: 2, consts: [[1, "conversation-sidebar"], [1, "sidebar-content"], [3, "conversationSelected", "newConversationRequested", "pinSidebarRequested", "unpinSidebarRequested", "environmentId", "currentUser", "selectedConversationId", "renamedConversationId", "isSidebarPinned", "isMobileView"], [3, "environmentId", "currentUser"]], template: function ConversationSidebarComponent_Template(rf, ctx) { if (rf & 1) {
48
+ static ɵfac = /*@__PURE__*/ (() => { let ɵConversationSidebarComponent_BaseFactory; return function ConversationSidebarComponent_Factory(__ngFactoryType__) { return (ɵConversationSidebarComponent_BaseFactory || (ɵConversationSidebarComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ConversationSidebarComponent)))(__ngFactoryType__ || ConversationSidebarComponent); }; })();
49
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationSidebarComponent, selectors: [["mj-conversation-sidebar"]], inputs: { activeTab: "activeTab", environmentId: "environmentId", currentUser: "currentUser", selectedConversationId: "selectedConversationId", renamedConversationId: "renamedConversationId", isSidebarPinned: "isSidebarPinned", isMobileView: "isMobileView", ShowRoutines: "ShowRoutines" }, outputs: { conversationSelected: "conversationSelected", openEntityRecord: "openEntityRecord", newConversationRequested: "newConversationRequested", pinSidebarRequested: "pinSidebarRequested", unpinSidebarRequested: "unpinSidebarRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 4, consts: [[1, "conversation-sidebar"], [1, "sidebar-content"], [3, "openEntityRecord", "openConversation", "Provider", "ShowRoutines"], [3, "conversationSelected", "newConversationRequested", "pinSidebarRequested", "unpinSidebarRequested", "environmentId", "currentUser", "selectedConversationId", "renamedConversationId", "isSidebarPinned", "isMobileView"], [3, "environmentId", "currentUser"]], template: function ConversationSidebarComponent_Template(rf, ctx) { if (rf & 1) {
44
50
  i0.ɵɵelementStart(0, "div", 0);
45
51
  i0.ɵɵconditionalCreate(1, ConversationSidebarComponent_Conditional_1_Template, 2, 6, "div", 1);
46
52
  i0.ɵɵconditionalCreate(2, ConversationSidebarComponent_Conditional_2_Template, 2, 2, "div", 1);
47
- i0.ɵɵelementEnd();
53
+ i0.ɵɵelementStart(3, "mj-conversation-routines-section", 2);
54
+ i0.ɵɵlistener("openEntityRecord", function ConversationSidebarComponent_Template_mj_conversation_routines_section_openEntityRecord_3_listener($event) { return ctx.openEntityRecord.emit($event); })("openConversation", function ConversationSidebarComponent_Template_mj_conversation_routines_section_openConversation_3_listener($event) { return ctx.conversationSelected.emit($event); });
55
+ i0.ɵɵelementEnd()();
48
56
  } if (rf & 2) {
49
57
  i0.ɵɵadvance();
50
58
  i0.ɵɵconditional(ctx.activeTab === "conversations" ? 1 : -1);
51
59
  i0.ɵɵadvance();
52
60
  i0.ɵɵconditional(ctx.activeTab === "collections" ? 2 : -1);
53
- } }, dependencies: [i1.ConversationListComponent, i2.CollectionTreeComponent], styles: [".conversation-sidebar[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n }\n .placeholder[_ngcontent-%COMP%] {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n .placeholder[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n }"] });
61
+ i0.ɵɵadvance();
62
+ i0.ɵɵproperty("Provider", ctx.Provider)("ShowRoutines", ctx.ShowRoutines);
63
+ } }, dependencies: [i1.RoutinesSectionComponent, i2.ConversationListComponent, i3.CollectionTreeComponent], styles: [".conversation-sidebar[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n }\n .placeholder[_ngcontent-%COMP%] {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n .placeholder[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n }"] });
54
64
  }
55
65
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationSidebarComponent, [{
56
66
  type: Component,
@@ -80,6 +90,16 @@ export class ConversationSidebarComponent {
80
90
  </mj-collection-tree>
81
91
  </div>
82
92
  }
93
+
94
+ <!-- Routines — pinned at the very bottom of the sidebar. Gated by the
95
+ ShowRoutines opt-out AND the user's Read permission on
96
+ 'MJ: User Routines' (checked inside the section component). -->
97
+ <mj-conversation-routines-section
98
+ [Provider]="Provider"
99
+ [ShowRoutines]="ShowRoutines"
100
+ (openEntityRecord)="openEntityRecord.emit($event)"
101
+ (openConversation)="conversationSelected.emit($event)">
102
+ </mj-conversation-routines-section>
83
103
  </div>
84
104
  `, styles: ["\n .conversation-sidebar {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .sidebar-content {\n flex: 1;\n overflow-y: auto;\n }\n .placeholder {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n .placeholder p {\n margin: 0;\n font-size: 14px;\n }\n "] }]
85
105
  }], null, { activeTab: [{
@@ -96,8 +116,12 @@ export class ConversationSidebarComponent {
96
116
  type: Input
97
117
  }], isMobileView: [{
98
118
  type: Input
119
+ }], ShowRoutines: [{
120
+ type: Input
99
121
  }], conversationSelected: [{
100
122
  type: Output
123
+ }], openEntityRecord: [{
124
+ type: Output
101
125
  }], newConversationRequested: [{
102
126
  type: Output
103
127
  }], pinSidebarRequested: [{
@@ -105,5 +129,5 @@ export class ConversationSidebarComponent {
105
129
  }], unpinSidebarRequested: [{
106
130
  type: Output
107
131
  }] }); })();
108
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationSidebarComponent, { className: "ConversationSidebarComponent", filePath: "src/lib/components/sidebar/conversation-sidebar.component.ts", lineNumber: 62 }); })();
132
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationSidebarComponent, { className: "ConversationSidebarComponent", filePath: "src/lib/components/sidebar/conversation-sidebar.component.ts", lineNumber: 73 }); })();
109
133
  //# sourceMappingURL=conversation-sidebar.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-sidebar.component.js","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/conversation-sidebar.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;;;;;IAW7D,AADF,8BAA6B,8BAW2B;IAApD,AADA,AADA,AADA,kPAAwB,wCAAiC,KAAC,uOAC9B,sCAA+B,KAAC,6NACrC,8BAAuB,KAAC,iOACtB,gCAAyB,KAAC;IAEvD,AADE,iBAAuB,EACnB;;;IAXF,cAA+B;IAK/B,AADA,AADA,AADA,AADA,AADA,oDAA+B,mCACJ,yDACsB,uDACF,2CACZ,qCACN;;;IASjC,8BAA6B;IAC3B,wCAGqB;IACvB,iBAAM;;;IAHF,cAA+B;IAC/B,AADA,oDAA+B,mCACJ;;AAgCvC,MAAM,OAAO,4BAA4B;IAC9B,SAAS,GAAkB,eAAe,CAAC;IAC3C,aAAa,CAAU;IACvB,WAAW,CAAY;IACvB,sBAAsB,GAAkB,IAAI,CAAC;IAC7C,qBAAqB,GAAkB,IAAI,CAAC;IAC5C,eAAe,GAAY,IAAI,CAAC;IAChC,YAAY,GAAY,KAAK,CAAC;IAE7B,oBAAoB,GAAG,IAAI,YAAY,EAAU,CAAC;IAClD,wBAAwB,GAAG,IAAI,YAAY,EAAQ,CAAC;IACpD,mBAAmB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC/C,qBAAqB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE3D,qBAAqB;QACnB,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,uBAAuB;QACrB,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;sHApBU,4BAA4B;6DAA5B,4BAA4B;YArDrC,8BAAkC;YAChC,8FAAqC;YAgBrC,8FAAmC;YAQrC,iBAAM;;YAxBJ,cAeC;YAfD,4DAeC;YACD,cAOC;YAPD,0DAOC;;;iFA6BM,4BAA4B;cAzDxC,SAAS;6BACI,KAAK,YACP,yBAAyB,YACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BP;;kBA4BF,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAEL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kFAZI,4BAA4B","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { NavigationTab } from '../../models/conversation-state.model';\n\n@Component({\n standalone: false,\n selector: 'mj-conversation-sidebar',\n template: `\n <div class=\"conversation-sidebar\">\n @if (activeTab === 'conversations') {\n <div class=\"sidebar-content\">\n <mj-conversation-list\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedConversationId]=\"selectedConversationId\"\n [renamedConversationId]=\"renamedConversationId\"\n [isSidebarPinned]=\"isSidebarPinned\"\n [isMobileView]=\"isMobileView\"\n (conversationSelected)=\"conversationSelected.emit($event)\"\n (newConversationRequested)=\"newConversationRequested.emit()\"\n (pinSidebarRequested)=\"onPinSidebarRequested()\"\n (unpinSidebarRequested)=\"onUnpinSidebarRequested()\">\n </mj-conversation-list>\n </div>\n }\n @if (activeTab === 'collections') {\n <div class=\"sidebar-content\">\n <mj-collection-tree\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\">\n </mj-collection-tree>\n </div>\n }\n </div>\n `,\n styles: [`\n .conversation-sidebar {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .sidebar-content {\n flex: 1;\n overflow-y: auto;\n }\n .placeholder {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n .placeholder p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class ConversationSidebarComponent {\n @Input() activeTab: NavigationTab = 'conversations';\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;\n @Input() isMobileView: boolean = false;\n\n @Output() conversationSelected = new EventEmitter<string>();\n @Output() newConversationRequested = new EventEmitter<void>();\n @Output() pinSidebarRequested = new EventEmitter<void>();\n @Output() unpinSidebarRequested = new EventEmitter<void>();\n\n onPinSidebarRequested(): void {\n this.pinSidebarRequested.emit();\n }\n\n onUnpinSidebarRequested(): void {\n this.unpinSidebarRequested.emit();\n }\n}"]}
1
+ {"version":3,"file":"conversation-sidebar.component.js","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/conversation-sidebar.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;IAU3D,AADF,8BAA6B,8BAW2B;IAApD,AADA,AADA,AADA,kPAAwB,wCAAiC,KAAC,uOAC9B,sCAA+B,KAAC,6NACrC,8BAAuB,KAAC,iOACtB,gCAAyB,KAAC;IAEvD,AADE,iBAAuB,EACnB;;;IAXF,cAA+B;IAK/B,AADA,AADA,AADA,AADA,AADA,oDAA+B,mCACJ,yDACsB,uDACF,2CACZ,qCACN;;;IASjC,8BAA6B;IAC3B,wCAGqB;IACvB,iBAAM;;;IAHF,cAA+B;IAC/B,AADA,oDAA+B,mCACJ;;AA0CvC,MAAM,OAAO,4BAA6B,SAAQ,oBAAoB;IAC3D,SAAS,GAAkB,eAAe,CAAC;IAC3C,aAAa,CAAU;IACvB,WAAW,CAAY;IACvB,sBAAsB,GAAkB,IAAI,CAAC;IAC7C,qBAAqB,GAAkB,IAAI,CAAC;IAC5C,eAAe,GAAY,IAAI,CAAC;IAChC,YAAY,GAAY,KAAK,CAAC;IACvC,yGAAyG;IAChG,YAAY,GAAY,IAAI,CAAC;IAE5B,oBAAoB,GAAG,IAAI,YAAY,EAAU,CAAC;IAC5D,yFAAyF;IAC/E,gBAAgB,GAAG,IAAI,YAAY,EAAsD,CAAC;IAC1F,wBAAwB,GAAG,IAAI,YAAY,EAAQ,CAAC;IACpD,mBAAmB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC/C,qBAAqB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE3D,qBAAqB;QACnB,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,uBAAuB;QACrB,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;6RAxBU,4BAA4B,yBAA5B,4BAA4B;6DAA5B,4BAA4B;YA/DrC,8BAAkC;YAChC,8FAAqC;YAgBrC,8FAAmC;YAYnC,2DAIyD;YAAvD,AADA,+JAAoB,iCAA6B,IAAC,kJAC9B,qCAAiC,IAAC;YAE1D,AADE,iBAAmC,EAC/B;;YAlCJ,cAeC;YAfD,4DAeC;YACD,cAOC;YAPD,0DAOC;YAMC,cAAqB;YACrB,AADA,uCAAqB,kCACQ;;;iFAgCxB,4BAA4B;cAnExC,SAAS;6BACI,KAAK,YACP,yBAAyB,YACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqCP;;kBA4BF,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAEL,KAAK;;kBAEL,MAAM;;kBAEN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kFAhBI,4BAA4B","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { CompositeKey, UserInfo } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { NavigationTab } from '../../models/conversation-state.model';\n\n@Component({\n standalone: false,\n selector: 'mj-conversation-sidebar',\n template: `\n <div class=\"conversation-sidebar\">\n @if (activeTab === 'conversations') {\n <div class=\"sidebar-content\">\n <mj-conversation-list\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedConversationId]=\"selectedConversationId\"\n [renamedConversationId]=\"renamedConversationId\"\n [isSidebarPinned]=\"isSidebarPinned\"\n [isMobileView]=\"isMobileView\"\n (conversationSelected)=\"conversationSelected.emit($event)\"\n (newConversationRequested)=\"newConversationRequested.emit()\"\n (pinSidebarRequested)=\"onPinSidebarRequested()\"\n (unpinSidebarRequested)=\"onUnpinSidebarRequested()\">\n </mj-conversation-list>\n </div>\n }\n @if (activeTab === 'collections') {\n <div class=\"sidebar-content\">\n <mj-collection-tree\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\">\n </mj-collection-tree>\n </div>\n }\n\n <!-- Routines — pinned at the very bottom of the sidebar. Gated by the\n ShowRoutines opt-out AND the user's Read permission on\n 'MJ: User Routines' (checked inside the section component). -->\n <mj-conversation-routines-section\n [Provider]=\"Provider\"\n [ShowRoutines]=\"ShowRoutines\"\n (openEntityRecord)=\"openEntityRecord.emit($event)\"\n (openConversation)=\"conversationSelected.emit($event)\">\n </mj-conversation-routines-section>\n </div>\n `,\n styles: [`\n .conversation-sidebar {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .sidebar-content {\n flex: 1;\n overflow-y: auto;\n }\n .placeholder {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n .placeholder p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class ConversationSidebarComponent extends BaseAngularComponent {\n @Input() activeTab: NavigationTab = 'conversations';\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;\n @Input() isMobileView: boolean = false;\n /** Show the Routines section at the bottom of the sidebar (bubbled from the workspace; default true). */\n @Input() ShowRoutines: boolean = true;\n\n @Output() conversationSelected = new EventEmitter<string>();\n /** Forwarded from the routines section — a run's linked execution record was clicked. */\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; compositeKey: CompositeKey }>();\n @Output() newConversationRequested = new EventEmitter<void>();\n @Output() pinSidebarRequested = new EventEmitter<void>();\n @Output() unpinSidebarRequested = new EventEmitter<void>();\n\n onPinSidebarRequested(): void {\n this.pinSidebarRequested.emit();\n }\n\n onUnpinSidebarRequested(): void {\n this.unpinSidebarRequested.emit();\n }\n}"]}
@@ -0,0 +1,73 @@
1
+ import { CompositeKey } from '@memberjunction/core';
2
+ import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
+ import { ConversationOpenedEventArgs, HistoryRecordOpenedEventArgs } from '@memberjunction/ng-user-routines';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * Compact "Routines" entry pinned at the very bottom of the conversations left
8
+ * sidebar: a single header row — mark, "Routines", the ACTIVE routine count, a "+"
9
+ * (straight into the New Routine editor) and a details chevron. No routine rows —
10
+ * the full command-center slide-in is one click away and owns all detail.
11
+ *
12
+ * Visibility gates (both must pass):
13
+ * 1. `ShowRoutines` — host opt-out input bubbled from the top-level conversations
14
+ * workspace (default true).
15
+ * 2. The current user must have Read permission on 'MJ: User Routines'
16
+ * (EntityInfo user-permission check) — hidden entirely otherwise.
17
+ */
18
+ export declare class RoutinesSectionComponent extends BaseAngularComponent implements OnInit, OnDestroy {
19
+ private cdr;
20
+ private destroy$;
21
+ private _showRoutines;
22
+ /** Host opt-out (bubbled from the top-level conversations component). Default true. */
23
+ set ShowRoutines(value: boolean);
24
+ get ShowRoutines(): boolean;
25
+ /** True when the current user may read routines (permission gate). */
26
+ CanRead: boolean;
27
+ /** Number of Active routines — the header badge. */
28
+ ActiveCount: number;
29
+ /** Total routines of any status (for the header tooltip). */
30
+ TotalCount: number;
31
+ /**
32
+ * A run history row's linked execution record (Agent Run / Prompt Run / Action Log)
33
+ * was clicked. Same shape as the chat area's openEntityRecord — the host (Explorer
34
+ * wrapper or workspace) routes it to navigation; this package never navigates itself.
35
+ */
36
+ openEntityRecord: EventEmitter<{
37
+ entityName: string;
38
+ compositeKey: CompositeKey;
39
+ }>;
40
+ /**
41
+ * The user asked to open a routine's dedicated conversation (the hidden,
42
+ * Application-scoped thread its runs append to). Emits the conversation ID;
43
+ * the host selects it in chat — this component closes the slide-in first.
44
+ */
45
+ openConversation: EventEmitter<string>;
46
+ /** Slide-in open state. */
47
+ SlideInVisible: boolean;
48
+ /** Routine to open the slide-in on (history view). */
49
+ SlideInRoutineID: string | null;
50
+ /** Whether the slide-in opens straight on the New Routine editor. */
51
+ SlideInNewRoutine: boolean;
52
+ private initialized;
53
+ /** Section renders only when the opt-out AND permission gates both pass. */
54
+ get IsVisible(): boolean;
55
+ /** Header tooltip: active/total breakdown. */
56
+ get HeaderTitle(): string;
57
+ ngOnInit(): Promise<void>;
58
+ ngOnDestroy(): void;
59
+ /** Opens the slide-in on the routines list (header / details click). */
60
+ OpenRoutines(): void;
61
+ /** Opens the slide-in straight on the New Routine editor ("+" affordance). */
62
+ NewRoutine(event: Event): void;
63
+ /** Opens the routine's conversation in the host chat surface (closing the slide-in). */
64
+ OnConversationOpened(args: ConversationOpenedEventArgs): void;
65
+ /** Bridges the slide-in's HistoryRecordOpened to the standard openEntityRecord chain. */
66
+ OnHistoryRecordOpened(args: HistoryRecordOpenedEventArgs): void;
67
+ OnSlideInClosed(): void;
68
+ private initialize;
69
+ private rebuildCounts;
70
+ static ɵfac: i0.ɵɵFactoryDeclaration<RoutinesSectionComponent, never>;
71
+ static ɵcmp: i0.ɵɵComponentDeclaration<RoutinesSectionComponent, "mj-conversation-routines-section", never, { "ShowRoutines": { "alias": "ShowRoutines"; "required": false; }; }, { "openEntityRecord": "openEntityRecord"; "openConversation": "openConversation"; }, never, never, false, never>;
72
+ }
73
+ //# sourceMappingURL=routines-section.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routines-section.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/routines-section.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAgC,YAAY,EAAS,SAAS,EAAE,MAAM,EAAkB,MAAM,eAAe,CAAC;AAGrH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;;AAE7G;;;;;;;;;;;GAWG;AACH,qBAMa,wBAAyB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC3F,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAuB;IAEvC,OAAO,CAAC,aAAa,CAAQ;IAC7B,uFAAuF;IACvF,IACW,YAAY,CAAC,KAAK,EAAE,OAAO,EAQrC;IACD,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED,sEAAsE;IAC/D,OAAO,UAAS;IACvB,oDAAoD;IAC7C,WAAW,SAAK;IACvB,6DAA6D;IACtD,UAAU,SAAK;IAEtB;;;;OAIG;IACO,gBAAgB;oBAAkC,MAAM;sBAAgB,YAAY;OAAM;IAEpG;;;;OAIG;IACO,gBAAgB,uBAA8B;IAExD,2BAA2B;IACpB,cAAc,UAAS;IAC9B,sDAAsD;IAC/C,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC9C,qEAAqE;IAC9D,iBAAiB,UAAS;IAEjC,OAAO,CAAC,WAAW,CAAS;IAE5B,4EAA4E;IAC5E,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED,8CAA8C;IAC9C,IAAW,WAAW,IAAI,MAAM,CAK/B;IAEK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,WAAW,IAAI,IAAI;IAKnB,wEAAwE;IACjE,YAAY,IAAI,IAAI;IAO3B,8EAA8E;IACvE,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAQrC,wFAAwF;IACjF,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI;IAKpE,yFAAyF;IAClF,qBAAqB,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI;IAI/D,eAAe,IAAI,IAAI;YAUhB,UAAU;IAgCxB,OAAO,CAAC,aAAa;yCAhJZ,wBAAwB;2CAAxB,wBAAwB;CAsJpC"}
@@ -0,0 +1,211 @@
1
+ import { CompositeKey } from '@memberjunction/core';
2
+ import { ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
3
+ import { Subject } from 'rxjs';
4
+ import { takeUntil } from 'rxjs/operators';
5
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
6
+ import { UserRoutineEngine } from '@memberjunction/core-entities';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@memberjunction/ng-user-routines";
9
+ function RoutinesSectionComponent_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵelementStart(0, "span", 4);
11
+ i0.ɵɵtext(1);
12
+ i0.ɵɵelementEnd();
13
+ } if (rf & 2) {
14
+ const ctx_r1 = i0.ɵɵnextContext(2);
15
+ i0.ɵɵadvance();
16
+ i0.ɵɵtextInterpolate(ctx_r1.ActiveCount);
17
+ } }
18
+ function RoutinesSectionComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
19
+ const _r1 = i0.ɵɵgetCurrentView();
20
+ i0.ɵɵelementStart(0, "div", 0)(1, "button", 1);
21
+ i0.ɵɵlistener("click", function RoutinesSectionComponent_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenRoutines()); });
22
+ i0.ɵɵelement(2, "i", 2);
23
+ i0.ɵɵelementStart(3, "span", 3);
24
+ i0.ɵɵtext(4, "Routines");
25
+ i0.ɵɵelementEnd();
26
+ i0.ɵɵconditionalCreate(5, RoutinesSectionComponent_Conditional_0_Conditional_5_Template, 2, 1, "span", 4);
27
+ i0.ɵɵelement(6, "span", 5);
28
+ i0.ɵɵelementStart(7, "span", 6);
29
+ i0.ɵɵlistener("click", function RoutinesSectionComponent_Conditional_0_Template_span_click_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.NewRoutine($event)); });
30
+ i0.ɵɵelement(8, "i", 7);
31
+ i0.ɵɵelementEnd();
32
+ i0.ɵɵelementStart(9, "span", 8);
33
+ i0.ɵɵelement(10, "i", 9);
34
+ i0.ɵɵelementEnd()();
35
+ i0.ɵɵelementStart(11, "mj-user-routines-slide-in", 10);
36
+ i0.ɵɵtwoWayListener("VisibleChange", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_VisibleChange_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SlideInVisible, $event) || (ctx_r1.SlideInVisible = $event); return i0.ɵɵresetView($event); });
37
+ i0.ɵɵlistener("Closed", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_Closed_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSlideInClosed()); })("HistoryRecordOpened", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_HistoryRecordOpened_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnHistoryRecordOpened($event)); })("ConversationOpened", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_ConversationOpened_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationOpened($event)); });
38
+ i0.ɵɵelementEnd()();
39
+ } if (rf & 2) {
40
+ const ctx_r1 = i0.ɵɵnextContext();
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵproperty("title", ctx_r1.HeaderTitle);
43
+ i0.ɵɵadvance(4);
44
+ i0.ɵɵconditional(ctx_r1.ActiveCount > 0 ? 5 : -1);
45
+ i0.ɵɵadvance(6);
46
+ i0.ɵɵproperty("Provider", ctx_r1.Provider);
47
+ i0.ɵɵtwoWayProperty("Visible", ctx_r1.SlideInVisible);
48
+ i0.ɵɵproperty("InitialRoutineID", ctx_r1.SlideInRoutineID)("StartInNewRoutine", ctx_r1.SlideInNewRoutine);
49
+ } }
50
+ /**
51
+ * Compact "Routines" entry pinned at the very bottom of the conversations left
52
+ * sidebar: a single header row — mark, "Routines", the ACTIVE routine count, a "+"
53
+ * (straight into the New Routine editor) and a details chevron. No routine rows —
54
+ * the full command-center slide-in is one click away and owns all detail.
55
+ *
56
+ * Visibility gates (both must pass):
57
+ * 1. `ShowRoutines` — host opt-out input bubbled from the top-level conversations
58
+ * workspace (default true).
59
+ * 2. The current user must have Read permission on 'MJ: User Routines'
60
+ * (EntityInfo user-permission check) — hidden entirely otherwise.
61
+ */
62
+ export class RoutinesSectionComponent extends BaseAngularComponent {
63
+ cdr = inject(ChangeDetectorRef);
64
+ destroy$ = new Subject();
65
+ _showRoutines = true;
66
+ /** Host opt-out (bubbled from the top-level conversations component). Default true. */
67
+ set ShowRoutines(value) {
68
+ if (value !== this._showRoutines) {
69
+ this._showRoutines = value;
70
+ if (value && !this.initialized) {
71
+ void this.initialize();
72
+ }
73
+ this.cdr.markForCheck();
74
+ }
75
+ }
76
+ get ShowRoutines() {
77
+ return this._showRoutines;
78
+ }
79
+ /** True when the current user may read routines (permission gate). */
80
+ CanRead = false;
81
+ /** Number of Active routines — the header badge. */
82
+ ActiveCount = 0;
83
+ /** Total routines of any status (for the header tooltip). */
84
+ TotalCount = 0;
85
+ /**
86
+ * A run history row's linked execution record (Agent Run / Prompt Run / Action Log)
87
+ * was clicked. Same shape as the chat area's openEntityRecord — the host (Explorer
88
+ * wrapper or workspace) routes it to navigation; this package never navigates itself.
89
+ */
90
+ openEntityRecord = new EventEmitter();
91
+ /**
92
+ * The user asked to open a routine's dedicated conversation (the hidden,
93
+ * Application-scoped thread its runs append to). Emits the conversation ID;
94
+ * the host selects it in chat — this component closes the slide-in first.
95
+ */
96
+ openConversation = new EventEmitter();
97
+ /** Slide-in open state. */
98
+ SlideInVisible = false;
99
+ /** Routine to open the slide-in on (history view). */
100
+ SlideInRoutineID = null;
101
+ /** Whether the slide-in opens straight on the New Routine editor. */
102
+ SlideInNewRoutine = false;
103
+ initialized = false;
104
+ /** Section renders only when the opt-out AND permission gates both pass. */
105
+ get IsVisible() {
106
+ return this._showRoutines && this.CanRead;
107
+ }
108
+ /** Header tooltip: active/total breakdown. */
109
+ get HeaderTitle() {
110
+ if (this.TotalCount === 0) {
111
+ return 'Routines — none yet, click + to create one';
112
+ }
113
+ return `Routines — ${this.ActiveCount} active of ${this.TotalCount}. Click to open.`;
114
+ }
115
+ async ngOnInit() {
116
+ if (this._showRoutines) {
117
+ await this.initialize();
118
+ }
119
+ }
120
+ ngOnDestroy() {
121
+ this.destroy$.next();
122
+ this.destroy$.complete();
123
+ }
124
+ /** Opens the slide-in on the routines list (header / details click). */
125
+ OpenRoutines() {
126
+ this.SlideInRoutineID = null;
127
+ this.SlideInNewRoutine = false;
128
+ this.SlideInVisible = true;
129
+ this.cdr.markForCheck();
130
+ }
131
+ /** Opens the slide-in straight on the New Routine editor ("+" affordance). */
132
+ NewRoutine(event) {
133
+ event.stopPropagation();
134
+ this.SlideInRoutineID = null;
135
+ this.SlideInNewRoutine = true;
136
+ this.SlideInVisible = true;
137
+ this.cdr.markForCheck();
138
+ }
139
+ /** Opens the routine's conversation in the host chat surface (closing the slide-in). */
140
+ OnConversationOpened(args) {
141
+ this.OnSlideInClosed();
142
+ this.openConversation.emit(args.ConversationID);
143
+ }
144
+ /** Bridges the slide-in's HistoryRecordOpened to the standard openEntityRecord chain. */
145
+ OnHistoryRecordOpened(args) {
146
+ this.openEntityRecord.emit({ entityName: args.EntityName, compositeKey: CompositeKey.FromID(args.RecordID) });
147
+ }
148
+ OnSlideInClosed() {
149
+ this.SlideInVisible = false;
150
+ this.SlideInRoutineID = null;
151
+ this.SlideInNewRoutine = false;
152
+ this.cdr.markForCheck();
153
+ }
154
+ // ---------------------------------------------------------------
155
+ // Internals
156
+ // ---------------------------------------------------------------
157
+ async initialize() {
158
+ if (this.initialized) {
159
+ return;
160
+ }
161
+ this.initialized = true;
162
+ const p = this.ProviderToUse;
163
+ // Permission gate: hide entirely when the user lacks Read on the entity
164
+ // (or the entity isn't present in this instance's metadata).
165
+ const entityInfo = p.EntityByName('MJ: User Routines');
166
+ const permissions = entityInfo && p.CurrentUser ? entityInfo.GetUserPermisions(p.CurrentUser) : null;
167
+ this.CanRead = permissions?.CanRead === true;
168
+ if (!this.CanRead) {
169
+ this.cdr.markForCheck();
170
+ return;
171
+ }
172
+ try {
173
+ const engine = UserRoutineEngine.GetProviderInstance(p, UserRoutineEngine);
174
+ await engine.Config(false, p.CurrentUser, p);
175
+ engine.Routines$.pipe(takeUntil(this.destroy$)).subscribe(() => {
176
+ this.rebuildCounts(engine);
177
+ });
178
+ this.rebuildCounts(engine);
179
+ }
180
+ catch (e) {
181
+ console.error('[RoutinesSection] Failed to load routines:', e);
182
+ this.ActiveCount = 0;
183
+ this.TotalCount = 0;
184
+ }
185
+ this.cdr.markForCheck();
186
+ }
187
+ rebuildCounts(engine) {
188
+ const routines = engine.Routines;
189
+ this.TotalCount = routines.length;
190
+ this.ActiveCount = routines.filter((r) => r.Status === 'Active').length;
191
+ this.cdr.markForCheck();
192
+ }
193
+ static ɵfac = /*@__PURE__*/ (() => { let ɵRoutinesSectionComponent_BaseFactory; return function RoutinesSectionComponent_Factory(__ngFactoryType__) { return (ɵRoutinesSectionComponent_BaseFactory || (ɵRoutinesSectionComponent_BaseFactory = i0.ɵɵgetInheritedFactory(RoutinesSectionComponent)))(__ngFactoryType__ || RoutinesSectionComponent); }; })();
194
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RoutinesSectionComponent, selectors: [["mj-conversation-routines-section"]], inputs: { ShowRoutines: "ShowRoutines" }, outputs: { openEntityRecord: "openEntityRecord", openConversation: "openConversation" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [[1, "crs-section"], ["type", "button", 1, "crs-header", 3, "click", "title"], [1, "fa-solid", "fa-business-time", "crs-mark"], [1, "crs-title"], [1, "crs-count"], [1, "crs-spacer"], ["role", "button", "title", "New routine", 1, "crs-add", 3, "click"], [1, "fa-solid", "fa-plus"], ["role", "button", "title", "Open routines", 1, "crs-details"], [1, "fa-solid", "fa-chevron-right"], [3, "VisibleChange", "Closed", "HistoryRecordOpened", "ConversationOpened", "Provider", "Visible", "InitialRoutineID", "StartInNewRoutine"]], template: function RoutinesSectionComponent_Template(rf, ctx) { if (rf & 1) {
195
+ i0.ɵɵconditionalCreate(0, RoutinesSectionComponent_Conditional_0_Template, 12, 6, "div", 0);
196
+ } if (rf & 2) {
197
+ i0.ɵɵconditional(ctx.IsVisible ? 0 : -1);
198
+ } }, dependencies: [i1.UserRoutinesSlideInComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.crs-section[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n padding: 6px 8px;\n}\n\n.crs-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n border-radius: var(--mj-radius-md, 8px);\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.crs-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.crs-mark[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n.crs-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n}\n\n.crs-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.crs-spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n}\n\n.crs-add[_ngcontent-%COMP%], \n.crs-details[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 6px);\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.crs-add[_ngcontent-%COMP%]:hover, \n.crs-details[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.crs-details[_ngcontent-%COMP%] {\n font-size: 10px;\n}"] });
199
+ }
200
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RoutinesSectionComponent, [{
201
+ type: Component,
202
+ args: [{ standalone: false, selector: 'mj-conversation-routines-section', template: "@if (IsVisible) {\n <div class=\"crs-section\">\n <button type=\"button\" class=\"crs-header\" [title]=\"HeaderTitle\" (click)=\"OpenRoutines()\">\n <i class=\"fa-solid fa-business-time crs-mark\"></i>\n <span class=\"crs-title\">Routines</span>\n @if (ActiveCount > 0) {\n <span class=\"crs-count\">{{ ActiveCount }}</span>\n }\n <span class=\"crs-spacer\"></span>\n <span class=\"crs-add\" role=\"button\" title=\"New routine\" (click)=\"NewRoutine($event)\">\n <i class=\"fa-solid fa-plus\"></i>\n </span>\n <span class=\"crs-details\" role=\"button\" title=\"Open routines\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </span>\n </button>\n\n <mj-user-routines-slide-in\n [Provider]=\"Provider\"\n [(Visible)]=\"SlideInVisible\"\n [InitialRoutineID]=\"SlideInRoutineID\"\n [StartInNewRoutine]=\"SlideInNewRoutine\"\n (Closed)=\"OnSlideInClosed()\"\n (HistoryRecordOpened)=\"OnHistoryRecordOpened($event)\"\n (ConversationOpened)=\"OnConversationOpened($event)\">\n </mj-user-routines-slide-in>\n </div>\n}\n", styles: [":host {\n display: block;\n}\n\n.crs-section {\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n padding: 6px 8px;\n}\n\n.crs-header {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n border-radius: var(--mj-radius-md, 8px);\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.crs-header:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.crs-mark {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n.crs-title {\n font-size: 13px;\n font-weight: 600;\n}\n\n.crs-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.crs-spacer {\n flex: 1 1 auto;\n}\n\n.crs-add,\n.crs-details {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 6px);\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.crs-add:hover,\n.crs-details:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.crs-details {\n font-size: 10px;\n}\n"] }]
203
+ }], null, { ShowRoutines: [{
204
+ type: Input
205
+ }], openEntityRecord: [{
206
+ type: Output
207
+ }], openConversation: [{
208
+ type: Output
209
+ }] }); })();
210
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoutinesSectionComponent, { className: "RoutinesSectionComponent", filePath: "src/lib/components/sidebar/routines-section.component.ts", lineNumber: 27 }); })();
211
+ //# sourceMappingURL=routines-section.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routines-section.component.js","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/routines-section.component.ts","../../../../src/lib/components/sidebar/routines-section.component.html"],"names":[],"mappings":"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","sourcesContent":["import { CompositeKey } from '@memberjunction/core';\nimport { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJUserRoutineEntity, UserRoutineEngine } from '@memberjunction/core-entities';\nimport { ConversationOpenedEventArgs, HistoryRecordOpenedEventArgs } from '@memberjunction/ng-user-routines';\n\n/**\n * Compact \"Routines\" entry pinned at the very bottom of the conversations left\n * sidebar: a single header row — mark, \"Routines\", the ACTIVE routine count, a \"+\"\n * (straight into the New Routine editor) and a details chevron. No routine rows —\n * the full command-center slide-in is one click away and owns all detail.\n *\n * Visibility gates (both must pass):\n * 1. `ShowRoutines` — host opt-out input bubbled from the top-level conversations\n * workspace (default true).\n * 2. The current user must have Read permission on 'MJ: User Routines'\n * (EntityInfo user-permission check) — hidden entirely otherwise.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-routines-section',\n templateUrl: './routines-section.component.html',\n styleUrls: ['./routines-section.component.css'],\n})\nexport class RoutinesSectionComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n\n private _showRoutines = true;\n /** Host opt-out (bubbled from the top-level conversations component). Default true. */\n @Input()\n public set ShowRoutines(value: boolean) {\n if (value !== this._showRoutines) {\n this._showRoutines = value;\n if (value && !this.initialized) {\n void this.initialize();\n }\n this.cdr.markForCheck();\n }\n }\n public get ShowRoutines(): boolean {\n return this._showRoutines;\n }\n\n /** True when the current user may read routines (permission gate). */\n public CanRead = false;\n /** Number of Active routines — the header badge. */\n public ActiveCount = 0;\n /** Total routines of any status (for the header tooltip). */\n public TotalCount = 0;\n\n /**\n * A run history row's linked execution record (Agent Run / Prompt Run / Action Log)\n * was clicked. Same shape as the chat area's openEntityRecord — the host (Explorer\n * wrapper or workspace) routes it to navigation; this package never navigates itself.\n */\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; compositeKey: CompositeKey }>();\n\n /**\n * The user asked to open a routine's dedicated conversation (the hidden,\n * Application-scoped thread its runs append to). Emits the conversation ID;\n * the host selects it in chat — this component closes the slide-in first.\n */\n @Output() openConversation = new EventEmitter<string>();\n\n /** Slide-in open state. */\n public SlideInVisible = false;\n /** Routine to open the slide-in on (history view). */\n public SlideInRoutineID: string | null = null;\n /** Whether the slide-in opens straight on the New Routine editor. */\n public SlideInNewRoutine = false;\n\n private initialized = false;\n\n /** Section renders only when the opt-out AND permission gates both pass. */\n public get IsVisible(): boolean {\n return this._showRoutines && this.CanRead;\n }\n\n /** Header tooltip: active/total breakdown. */\n public get HeaderTitle(): string {\n if (this.TotalCount === 0) {\n return 'Routines — none yet, click + to create one';\n }\n return `Routines — ${this.ActiveCount} active of ${this.TotalCount}. Click to open.`;\n }\n\n async ngOnInit(): Promise<void> {\n if (this._showRoutines) {\n await this.initialize();\n }\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /** Opens the slide-in on the routines list (header / details click). */\n public OpenRoutines(): void {\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = false;\n this.SlideInVisible = true;\n this.cdr.markForCheck();\n }\n\n /** Opens the slide-in straight on the New Routine editor (\"+\" affordance). */\n public NewRoutine(event: Event): void {\n event.stopPropagation();\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = true;\n this.SlideInVisible = true;\n this.cdr.markForCheck();\n }\n\n /** Opens the routine's conversation in the host chat surface (closing the slide-in). */\n public OnConversationOpened(args: ConversationOpenedEventArgs): void {\n this.OnSlideInClosed();\n this.openConversation.emit(args.ConversationID);\n }\n\n /** Bridges the slide-in's HistoryRecordOpened to the standard openEntityRecord chain. */\n public OnHistoryRecordOpened(args: HistoryRecordOpenedEventArgs): void {\n this.openEntityRecord.emit({ entityName: args.EntityName, compositeKey: CompositeKey.FromID(args.RecordID) });\n }\n\n public OnSlideInClosed(): void {\n this.SlideInVisible = false;\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = false;\n this.cdr.markForCheck();\n }\n\n // ---------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------\n private async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n this.initialized = true;\n const p = this.ProviderToUse;\n\n // Permission gate: hide entirely when the user lacks Read on the entity\n // (or the entity isn't present in this instance's metadata).\n const entityInfo = p.EntityByName('MJ: User Routines');\n const permissions = entityInfo && p.CurrentUser ? entityInfo.GetUserPermisions(p.CurrentUser) : null;\n this.CanRead = permissions?.CanRead === true;\n if (!this.CanRead) {\n this.cdr.markForCheck();\n return;\n }\n\n try {\n const engine = UserRoutineEngine.GetProviderInstance<UserRoutineEngine>(p, UserRoutineEngine) as UserRoutineEngine;\n await engine.Config(false, p.CurrentUser, p);\n engine.Routines$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.rebuildCounts(engine);\n });\n this.rebuildCounts(engine);\n } catch (e) {\n console.error('[RoutinesSection] Failed to load routines:', e);\n this.ActiveCount = 0;\n this.TotalCount = 0;\n }\n this.cdr.markForCheck();\n }\n\n private rebuildCounts(engine: UserRoutineEngine): void {\n const routines = engine.Routines;\n this.TotalCount = routines.length;\n this.ActiveCount = routines.filter((r: MJUserRoutineEntity) => r.Status === 'Active').length;\n this.cdr.markForCheck();\n }\n}\n","@if (IsVisible) {\n <div class=\"crs-section\">\n <button type=\"button\" class=\"crs-header\" [title]=\"HeaderTitle\" (click)=\"OpenRoutines()\">\n <i class=\"fa-solid fa-business-time crs-mark\"></i>\n <span class=\"crs-title\">Routines</span>\n @if (ActiveCount > 0) {\n <span class=\"crs-count\">{{ ActiveCount }}</span>\n }\n <span class=\"crs-spacer\"></span>\n <span class=\"crs-add\" role=\"button\" title=\"New routine\" (click)=\"NewRoutine($event)\">\n <i class=\"fa-solid fa-plus\"></i>\n </span>\n <span class=\"crs-details\" role=\"button\" title=\"Open routines\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </span>\n </button>\n\n <mj-user-routines-slide-in\n [Provider]=\"Provider\"\n [(Visible)]=\"SlideInVisible\"\n [InitialRoutineID]=\"SlideInRoutineID\"\n [StartInNewRoutine]=\"SlideInNewRoutine\"\n (Closed)=\"OnSlideInClosed()\"\n (HistoryRecordOpened)=\"OnHistoryRecordOpened($event)\"\n (ConversationOpened)=\"OnConversationOpened($event)\">\n </mj-user-routines-slide-in>\n </div>\n}\n"]}