@memberjunction/ng-conversations 6.2.0-edge.3 → 6.2.0-edge.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +4 -7
  2. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  3. package/dist/lib/components/collection/collection-view.component.js +1 -0
  4. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  5. package/dist/lib/components/composer/ai-composer.component.d.ts +14 -2
  6. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
  7. package/dist/lib/components/composer/ai-composer.component.js +35 -4
  8. package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +588 -51
  10. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-chat-area.component.js +2654 -665
  12. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  13. package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
  14. package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
  15. package/dist/lib/components/conversation/forks-popover.component.js +164 -0
  16. package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
  17. package/dist/lib/components/export/export-modal.component.d.ts +7 -2
  18. package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
  19. package/dist/lib/components/export/export-modal.component.js +16 -3
  20. package/dist/lib/components/export/export-modal.component.js.map +1 -1
  21. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  22. package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
  23. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  24. package/dist/lib/components/message/message-input.component.d.ts +96 -11
  25. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  26. package/dist/lib/components/message/message-input.component.js +244 -103
  27. package/dist/lib/components/message/message-input.component.js.map +1 -1
  28. package/dist/lib/components/message/message-item.component.d.ts +171 -4
  29. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  30. package/dist/lib/components/message/message-item.component.js +899 -298
  31. package/dist/lib/components/message/message-item.component.js.map +1 -1
  32. package/dist/lib/components/message/message-list.component.d.ts +82 -21
  33. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  34. package/dist/lib/components/message/message-list.component.js +299 -52
  35. package/dist/lib/components/message/message-list.component.js.map +1 -1
  36. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
  37. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
  38. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
  39. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
  40. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
  41. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
  42. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
  43. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
  44. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
  45. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
  46. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
  47. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
  48. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
  49. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
  50. package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
  51. package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
  52. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
  53. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
  54. package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
  55. package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
  56. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
  57. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
  58. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
  59. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
  60. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
  61. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  62. package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
  63. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  64. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
  65. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  66. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
  67. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  68. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
  69. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
  70. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
  71. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
  72. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
  73. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
  74. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
  75. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
  76. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
  77. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
  78. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
  79. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
  80. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
  81. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
  82. package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
  83. package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
  84. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
  85. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
  86. package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
  87. package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
  88. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
  89. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
  90. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
  91. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
  92. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
  93. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
  94. package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
  95. package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
  96. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
  97. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
  98. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
  99. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
  100. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
  101. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
  102. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
  103. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
  104. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
  105. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
  106. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
  107. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
  108. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
  109. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
  110. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
  111. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
  112. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
  113. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
  114. package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
  115. package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
  116. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
  117. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
  118. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
  119. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
  120. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
  121. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
  122. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
  123. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
  124. package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
  125. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  126. package/dist/lib/components/realtime/media/media-channel.js +28 -1
  127. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  128. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
  129. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  130. package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
  131. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  132. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
  133. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
  134. package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
  135. package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
  136. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
  137. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  138. package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
  139. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  140. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
  141. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  142. package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
  143. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  144. package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
  145. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  146. package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
  147. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  148. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
  149. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
  150. package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
  151. package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
  152. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
  153. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  154. package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
  155. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  156. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
  157. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
  158. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
  159. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
  160. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
  161. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
  162. package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
  163. package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
  164. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
  165. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  166. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
  167. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  168. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
  169. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  170. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
  171. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  172. package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
  173. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  174. package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
  175. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  176. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
  177. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  178. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
  179. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  180. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
  181. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
  182. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
  183. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
  184. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
  185. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  186. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
  187. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  188. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  189. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  190. package/dist/lib/components/search/search-panel.component.js +25 -12
  191. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  192. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +22 -31
  193. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  194. package/dist/lib/components/workspace/conversation-workspace.component.js +50 -63
  195. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  196. package/dist/lib/conversations.module.d.ts +30 -29
  197. package/dist/lib/conversations.module.d.ts.map +1 -1
  198. package/dist/lib/conversations.module.js +27 -5
  199. package/dist/lib/conversations.module.js.map +1 -1
  200. package/dist/lib/events/chat-events.d.ts +25 -0
  201. package/dist/lib/events/chat-events.d.ts.map +1 -1
  202. package/dist/lib/events/chat-events.js +36 -0
  203. package/dist/lib/events/chat-events.js.map +1 -1
  204. package/dist/lib/models/agent-turn.model.d.ts +5 -0
  205. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  206. package/dist/lib/models/agent-turn.model.js.map +1 -1
  207. package/dist/lib/services/agent-state.service.d.ts +34 -8
  208. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  209. package/dist/lib/services/agent-state.service.js +82 -29
  210. package/dist/lib/services/agent-state.service.js.map +1 -1
  211. package/dist/lib/services/artifact-state.service.d.ts +0 -9
  212. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  213. package/dist/lib/services/artifact-state.service.js +1 -32
  214. package/dist/lib/services/artifact-state.service.js.map +1 -1
  215. package/dist/lib/services/browser-realtime-media-host.d.ts +12 -0
  216. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
  217. package/dist/lib/services/browser-realtime-media-host.js +19 -0
  218. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  219. package/dist/lib/services/browser-recording-unload-guard.d.ts +30 -0
  220. package/dist/lib/services/browser-recording-unload-guard.d.ts.map +1 -0
  221. package/dist/lib/services/browser-recording-unload-guard.js +43 -0
  222. package/dist/lib/services/browser-recording-unload-guard.js.map +1 -0
  223. package/dist/lib/services/conversation-agent.service.d.ts +35 -11
  224. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  225. package/dist/lib/services/conversation-agent.service.js +65 -20
  226. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  227. package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
  228. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  229. package/dist/lib/services/conversation-detail-window.store.js +50 -9
  230. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  231. package/dist/lib/services/conversation-naming.d.ts +72 -22
  232. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  233. package/dist/lib/services/conversation-naming.js +84 -10
  234. package/dist/lib/services/conversation-naming.js.map +1 -1
  235. package/dist/lib/services/data-cache.service.d.ts +13 -5
  236. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  237. package/dist/lib/services/data-cache.service.js +39 -19
  238. package/dist/lib/services/data-cache.service.js.map +1 -1
  239. package/dist/lib/services/export.service.d.ts +26 -9
  240. package/dist/lib/services/export.service.d.ts.map +1 -1
  241. package/dist/lib/services/export.service.js +61 -18
  242. package/dist/lib/services/export.service.js.map +1 -1
  243. package/dist/lib/services/realtime-audio-recorder.d.ts +33 -5
  244. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  245. package/dist/lib/services/realtime-audio-recorder.js +71 -11
  246. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  247. package/dist/lib/services/realtime-pairing.d.ts +10 -5
  248. package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
  249. package/dist/lib/services/realtime-pairing.js +15 -6
  250. package/dist/lib/services/realtime-pairing.js.map +1 -1
  251. package/dist/lib/services/realtime-session.service.d.ts +3 -2
  252. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  253. package/dist/lib/services/realtime-session.service.js +7 -2
  254. package/dist/lib/services/realtime-session.service.js.map +1 -1
  255. package/dist/lib/services/search.service.d.ts +7 -2
  256. package/dist/lib/services/search.service.d.ts.map +1 -1
  257. package/dist/lib/services/search.service.js +13 -4
  258. package/dist/lib/services/search.service.js.map +1 -1
  259. package/dist/lib/utils/conversation-branching.d.ts +4 -0
  260. package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
  261. package/dist/lib/utils/conversation-branching.js +5 -0
  262. package/dist/lib/utils/conversation-branching.js.map +1 -0
  263. package/dist/lib/utils/conversation-forks.d.ts +315 -0
  264. package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
  265. package/dist/lib/utils/conversation-forks.js +456 -0
  266. package/dist/lib/utils/conversation-forks.js.map +1 -0
  267. package/dist/public-api.d.ts +23 -1
  268. package/dist/public-api.d.ts.map +1 -1
  269. package/dist/public-api.js +30 -1
  270. package/dist/public-api.js.map +1 -1
  271. package/package.json +37 -33
  272. package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
  273. package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
  274. package/dist/lib/components/thread/thread-panel.component.js +0 -440
  275. package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
@@ -1,30 +1,33 @@
1
- import { Component, EventEmitter, Input, Output, ChangeDetectorRef, ViewChild, inject } from '@angular/core';
1
+ import { Component, EventEmitter, Input, Output, ChangeDetectorRef, ViewChild, ViewChildren, inject } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
+ import { MediaMoveMenuComponent } from '@memberjunction/ng-realtime-media';
4
+ import { MEDIA_PLACEMENTS } from '@memberjunction/ai-realtime-client/media';
5
+ import { MJButtonDirective } from '@memberjunction/ng-ui-components';
3
6
  import { UserInfoEngine } from '@memberjunction/core-entities';
4
7
  import { ArtifactsModule } from '@memberjunction/ng-artifacts';
5
8
  import { RealtimeActivityRailComponent } from './realtime-activity-rail.component';
6
- import { RealtimeChannelPaneComponent } from './channels/realtime-channel-pane.component';
7
9
  import { ChannelOnboardingPanelComponent } from './channels/channel-onboarding-panel.component';
8
10
  import { RealtimeSurfaceTabsModel } from './realtime-surface-tabs.model';
9
11
  import * as i0 from "@angular/core";
10
12
  import * as i1 from "@angular/common";
13
+ const _c0 = ["channelSlot"];
11
14
  function RealtimeSurfaceTabsComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
12
15
  const _r1 = i0.ɵɵgetCurrentView();
13
- i0.ɵɵelementStart(0, "div", 1)(1, "button", 2);
16
+ i0.ɵɵelementStart(0, "div", 2)(1, "button", 3);
14
17
  i0.ɵɵlistener("click", function RealtimeSurfaceTabsComponent_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCollapsed()); });
15
- i0.ɵɵelement(2, "i", 3);
18
+ i0.ɵɵelement(2, "i", 4);
16
19
  i0.ɵɵelementEnd();
17
- i0.ɵɵelement(3, "i", 4);
20
+ i0.ɵɵelement(3, "i", 5);
18
21
  i0.ɵɵelementEnd();
19
22
  } }
20
23
  function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
21
- i0.ɵɵelement(0, "span", 11);
24
+ i0.ɵɵelement(0, "span", 12);
22
25
  } }
23
26
  function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
24
- i0.ɵɵelement(0, "span", 13);
27
+ i0.ɵɵelement(0, "span", 14);
25
28
  } }
26
29
  function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
27
- i0.ɵɵelementStart(0, "span", 16);
30
+ i0.ɵɵelementStart(0, "span", 17);
28
31
  i0.ɵɵtext(1);
29
32
  i0.ɵɵelementEnd();
30
33
  } if (rf & 2) {
@@ -32,18 +35,29 @@ function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_6_Template
32
35
  i0.ɵɵadvance();
33
36
  i0.ɵɵtextInterpolate(ctx_r1.State.Cards.length);
34
37
  } }
38
+ function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
39
+ const _r6 = i0.ɵɵgetCurrentView();
40
+ i0.ɵɵelementStart(0, "mj-media-move-menu", 19);
41
+ i0.ɵɵlistener("MoveRequested", function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_7_Template_mj_media_move_menu_MoveRequested_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.MoveRequested.emit($event)); })("ResetLayoutRequested", function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_7_Template_mj_media_move_menu_ResetLayoutRequested_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ResetLayoutRequested.emit()); });
42
+ i0.ɵɵelementEnd();
43
+ } if (rf & 2) {
44
+ const tab_r5 = i0.ɵɵnextContext().$implicit;
45
+ const ctx_r1 = i0.ɵɵnextContext(2);
46
+ i0.ɵɵproperty("Key", tab_r5.Key)("Title", tab_r5.Title)("Placement", ctx_r1.PlacementOf(tab_r5.Key))("Allowed", ctx_r1.AllowedOf(tab_r5.Key));
47
+ } }
35
48
  function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
36
49
  const _r4 = i0.ɵɵgetCurrentView();
37
- i0.ɵɵconditionalCreate(0, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_0_Template, 1, 0, "span", 11);
38
- i0.ɵɵelementStart(1, "button", 12);
50
+ i0.ɵɵconditionalCreate(0, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_0_Template, 1, 0, "span", 12);
51
+ i0.ɵɵelementStart(1, "button", 13);
39
52
  i0.ɵɵlistener("click", function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Template_button_click_1_listener() { const tab_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Model.Focus(tab_r5.Key)); });
40
- i0.ɵɵconditionalCreate(2, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_2_Template, 1, 0, "span", 13);
41
- i0.ɵɵelement(3, "i", 14);
42
- i0.ɵɵelementStart(4, "span", 15);
53
+ i0.ɵɵconditionalCreate(2, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_2_Template, 1, 0, "span", 14);
54
+ i0.ɵɵelement(3, "i", 15);
55
+ i0.ɵɵelementStart(4, "span", 16);
43
56
  i0.ɵɵtext(5);
44
57
  i0.ɵɵelementEnd();
45
- i0.ɵɵconditionalCreate(6, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_6_Template, 2, 1, "span", 16);
58
+ i0.ɵɵconditionalCreate(6, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_6_Template, 2, 1, "span", 17);
46
59
  i0.ɵɵelementEnd();
60
+ i0.ɵɵconditionalCreate(7, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Conditional_7_Template, 1, 4, "mj-media-move-menu", 18);
47
61
  } if (rf & 2) {
48
62
  const tab_r5 = ctx.$implicit;
49
63
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -61,87 +75,115 @@ function RealtimeSurfaceTabsComponent_Conditional_2_For_2_Template(rf, ctx) { if
61
75
  i0.ɵɵtextInterpolate(tab_r5.Title);
62
76
  i0.ɵɵadvance();
63
77
  i0.ɵɵconditional(tab_r5.Kind === "activity" && ctx_r1.State.Cards.length > 0 ? 6 : -1);
78
+ i0.ɵɵadvance();
79
+ i0.ɵɵconditional(tab_r5.Kind === "channel" && (tab_r5.Data == null ? null : tab_r5.Data.Plugin) && tab_r5.Key === ctx_r1.Model.ActiveKey ? 7 : -1);
64
80
  } }
65
81
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_1_Template(rf, ctx) { if (rf & 1) {
66
- const _r6 = i0.ɵɵgetCurrentView();
67
- i0.ɵɵelementStart(0, "mj-realtime-activity-rail", 19);
68
- i0.ɵɵlistener("OpenRunRequested", function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_1_Template_mj_realtime_activity_rail_OpenRunRequested_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OpenRunRequested.emit($event)); });
82
+ const _r7 = i0.ɵɵgetCurrentView();
83
+ i0.ɵɵelementStart(0, "mj-realtime-activity-rail", 22);
84
+ i0.ɵɵlistener("OpenRunRequested", function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_1_Template_mj_realtime_activity_rail_OpenRunRequested_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OpenRunRequested.emit($event)); });
69
85
  i0.ɵɵelementEnd();
70
86
  } if (rf & 2) {
71
87
  const ctx_r1 = i0.ɵɵnextContext(3);
72
88
  i0.ɵɵproperty("State", ctx_r1.State)("DevMode", ctx_r1.DevMode)("Embedded", true)("CurrentUser", ctx_r1.CurrentUser)("EnvironmentID", ctx_r1.EnvironmentID)("ExtraArtifacts", ctx_r1.ExtraArtifacts);
73
89
  } }
74
- function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
75
- const _r7 = i0.ɵɵgetCurrentView();
76
- i0.ɵɵelementStart(0, "mj-channel-onboarding-panel", 24);
77
- i0.ɵɵlistener("Dismissed", function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_1_Template_mj_channel_onboarding_panel_Dismissed_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.DismissOnboarding()); });
90
+ function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
91
+ const _r8 = i0.ɵɵgetCurrentView();
92
+ i0.ɵɵelementStart(0, "button", 27);
93
+ i0.ɵɵlistener("click", function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const tab_r9 = i0.ɵɵnextContext(3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MoveRequested.emit({ Key: tab_r9.Key, Placement: "tab" })); });
94
+ i0.ɵɵtext(1, " Bring it here ");
78
95
  i0.ɵɵelementEnd();
79
- } if (rf & 2) {
80
- const ctx_r1 = i0.ɵɵnextContext(5);
81
- i0.ɵɵproperty("Content", ctx_r1.OnboardingContent);
82
96
  } }
83
97
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
84
- i0.ɵɵelement(0, "mj-realtime-channel-pane", 22);
85
- i0.ɵɵconditionalCreate(1, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_1_Template, 1, 1, "mj-channel-onboarding-panel", 23);
98
+ i0.ɵɵelementStart(0, "div", 23);
99
+ i0.ɵɵelement(1, "i", 15);
100
+ i0.ɵɵelementStart(2, "span");
101
+ i0.ɵɵtext(3);
102
+ i0.ɵɵelementEnd();
103
+ i0.ɵɵconditionalCreate(4, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Conditional_4_Template, 2, 0, "button", 26);
104
+ i0.ɵɵelementEnd();
86
105
  } if (rf & 2) {
87
- const tab_r8 = i0.ɵɵnextContext(2).$implicit;
106
+ const tab_r9 = i0.ɵɵnextContext(2).$implicit;
88
107
  const ctx_r1 = i0.ɵɵnextContext(2);
89
- i0.ɵɵproperty("Plugin", ctx);
90
108
  i0.ɵɵadvance();
91
- i0.ɵɵconditional(tab_r8.Key === ctx_r1.Model.ActiveKey && ctx_r1.OnboardingContent ? 1 : -1);
109
+ i0.ɵɵclassMap(ctx_r1.AwayIcon(tab_r9.Key));
110
+ i0.ɵɵadvance(2);
111
+ i0.ɵɵtextInterpolate2("", tab_r9.Title, " is ", ctx_r1.AwayText(tab_r9.Key), ".");
112
+ i0.ɵɵadvance();
113
+ i0.ɵɵconditional(ctx_r1.AllowedOf(tab_r9.Key).includes("tab") ? 4 : -1);
114
+ } }
115
+ function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
116
+ const _r10 = i0.ɵɵgetCurrentView();
117
+ i0.ɵɵelementStart(0, "mj-channel-onboarding-panel", 30);
118
+ i0.ɵɵlistener("Dismissed", function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Conditional_2_Template_mj_channel_onboarding_panel_Dismissed_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.DismissOnboarding()); });
119
+ i0.ɵɵelementEnd();
120
+ } if (rf & 2) {
121
+ const ctx_r1 = i0.ɵɵnextContext(5);
122
+ i0.ɵɵproperty("Content", ctx_r1.OnboardingContent);
92
123
  } }
93
124
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
94
- i0.ɵɵelementContainer(0, 20);
125
+ i0.ɵɵelement(0, "div", 28, 0);
126
+ i0.ɵɵconditionalCreate(2, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Conditional_2_Template, 1, 1, "mj-channel-onboarding-panel", 29);
95
127
  } if (rf & 2) {
96
- i0.ɵɵproperty("ngTemplateOutlet", ctx);
128
+ const tab_r9 = i0.ɵɵnextContext(2).$implicit;
129
+ const ctx_r1 = i0.ɵɵnextContext(2);
130
+ i0.ɵɵattribute("data-channel-key", tab_r9.Key);
131
+ i0.ɵɵadvance(2);
132
+ i0.ɵɵconditional(tab_r9.Key === ctx_r1.Model.ActiveKey && ctx_r1.OnboardingContent ? 2 : -1);
97
133
  } }
98
134
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
99
- i0.ɵɵelementStart(0, "div", 21);
100
- i0.ɵɵelement(1, "i", 25);
135
+ i0.ɵɵelementContainer(0, 24);
136
+ } if (rf & 2) {
137
+ i0.ɵɵproperty("ngTemplateOutlet", ctx);
138
+ } }
139
+ function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
140
+ i0.ɵɵelementStart(0, "div", 25);
141
+ i0.ɵɵelement(1, "i", 31);
101
142
  i0.ɵɵelementStart(2, "span");
102
143
  i0.ɵɵtext(3);
103
144
  i0.ɵɵelementEnd()();
104
145
  } if (rf & 2) {
105
- const tab_r8 = i0.ɵɵnextContext(2).$implicit;
146
+ const tab_r9 = i0.ɵɵnextContext(2).$implicit;
106
147
  i0.ɵɵadvance(3);
107
- i0.ɵɵtextInterpolate1("", tab_r8.Title, " coming online\u2026");
148
+ i0.ɵɵtextInterpolate1("", tab_r9.Title, " coming online\u2026");
108
149
  } }
109
150
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Template(rf, ctx) { if (rf & 1) {
110
- i0.ɵɵconditionalCreate(0, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Template, 2, 2)(1, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Template, 1, 1, "ng-container", 20)(2, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_2_Template, 4, 1, "div", 21);
151
+ i0.ɵɵconditionalCreate(0, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_0_Template, 5, 5, "div", 23)(1, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_1_Template, 3, 2)(2, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_2_Template, 1, 1, "ng-container", 24)(3, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Conditional_3_Template, 4, 1, "div", 25);
111
152
  } if (rf & 2) {
112
153
  let tmp_12_0;
113
- const tab_r8 = i0.ɵɵnextContext().$implicit;
114
- i0.ɵɵconditional((tmp_12_0 = tab_r8.Data == null ? null : tab_r8.Data.Plugin) ? 0 : (tmp_12_0 = tab_r8.Data == null ? null : tab_r8.Data.Content) ? 1 : 2, tmp_12_0);
154
+ const tab_r9 = i0.ɵɵnextContext().$implicit;
155
+ const ctx_r1 = i0.ɵɵnextContext(2);
156
+ i0.ɵɵconditional((tab_r9.Data == null ? null : tab_r9.Data.Plugin) && ctx_r1.PlacementOf(tab_r9.Key) !== "tab" ? 0 : (tab_r9.Data == null ? null : tab_r9.Data.Plugin) ? 1 : (tmp_12_0 = tab_r9.Data == null ? null : tab_r9.Data.Content) ? 2 : 3, tmp_12_0);
115
157
  } }
116
158
  function RealtimeSurfaceTabsComponent_Conditional_2_For_7_Template(rf, ctx) { if (rf & 1) {
117
- i0.ɵɵelementStart(0, "div", 17);
118
- i0.ɵɵconditionalCreate(1, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_1_Template, 1, 6, "mj-realtime-activity-rail", 18)(2, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Template, 3, 1);
159
+ i0.ɵɵelementStart(0, "div", 20);
160
+ i0.ɵɵconditionalCreate(1, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_1_Template, 1, 6, "mj-realtime-activity-rail", 21)(2, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Case_2_Template, 4, 1);
119
161
  i0.ɵɵelementEnd();
120
162
  } if (rf & 2) {
121
163
  let tmp_12_0;
122
- const tab_r8 = ctx.$implicit;
164
+ const tab_r9 = ctx.$implicit;
123
165
  const ctx_r1 = i0.ɵɵnextContext(2);
124
- i0.ɵɵclassProp("s-pane--active", tab_r8.Key === ctx_r1.Model.ActiveKey);
166
+ i0.ɵɵclassProp("s-pane--active", tab_r9.Key === ctx_r1.Model.ActiveKey);
125
167
  i0.ɵɵadvance();
126
- i0.ɵɵconditional((tmp_12_0 = tab_r8.Kind) === "activity" ? 1 : tmp_12_0 === "channel" ? 2 : -1);
168
+ i0.ɵɵconditional((tmp_12_0 = tab_r9.Kind) === "activity" ? 1 : tmp_12_0 === "channel" ? 2 : -1);
127
169
  } }
128
170
  function RealtimeSurfaceTabsComponent_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
129
- i0.ɵɵelementStart(0, "div", 10);
130
- i0.ɵɵelement(1, "i", 26);
171
+ i0.ɵɵelementStart(0, "div", 11);
172
+ i0.ɵɵelement(1, "i", 32);
131
173
  i0.ɵɵelementStart(2, "span");
132
174
  i0.ɵɵtext(3, "Surfaces appear here as the call gets going.");
133
175
  i0.ɵɵelementEnd()();
134
176
  } }
135
177
  function RealtimeSurfaceTabsComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
136
178
  const _r3 = i0.ɵɵgetCurrentView();
137
- i0.ɵɵelementStart(0, "div", 5);
138
- i0.ɵɵrepeaterCreate(1, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Template, 7, 18, null, null, i0.ɵɵcomponentInstance().TrackTab, true);
139
- i0.ɵɵelementStart(3, "div", 6)(4, "button", 7);
179
+ i0.ɵɵelementStart(0, "div", 6);
180
+ i0.ɵɵrepeaterCreate(1, RealtimeSurfaceTabsComponent_Conditional_2_For_2_Template, 8, 19, null, null, i0.ɵɵcomponentInstance().TrackTab, true);
181
+ i0.ɵɵelementStart(3, "div", 7)(4, "button", 8);
140
182
  i0.ɵɵlistener("click", function RealtimeSurfaceTabsComponent_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCollapsed()); });
141
- i0.ɵɵelement(5, "i", 8);
183
+ i0.ɵɵelement(5, "i", 9);
142
184
  i0.ɵɵelementEnd()()();
143
- i0.ɵɵrepeaterCreate(6, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Template, 3, 3, "div", 9, i0.ɵɵcomponentInstance().TrackTab, true);
144
- i0.ɵɵconditionalCreate(8, RealtimeSurfaceTabsComponent_Conditional_2_Conditional_8_Template, 4, 0, "div", 10);
185
+ i0.ɵɵrepeaterCreate(6, RealtimeSurfaceTabsComponent_Conditional_2_For_7_Template, 3, 3, "div", 10, i0.ɵɵcomponentInstance().TrackTab, true);
186
+ i0.ɵɵconditionalCreate(8, RealtimeSurfaceTabsComponent_Conditional_2_Conditional_8_Template, 4, 0, "div", 11);
145
187
  } if (rf & 2) {
146
188
  const ctx_r1 = i0.ɵɵnextContext();
147
189
  i0.ɵɵadvance();
@@ -158,14 +200,28 @@ function RealtimeSurfaceTabsComponent_Conditional_2_Template(rf, ctx) { if (rf &
158
200
  * follows them across devices.
159
201
  */
160
202
  const CHANNEL_ONBOARDING_SEEN_SETTING_KEY = 'mj.realtimeChannels.onboardingSeen.v1';
203
+ /** How a channel's tab says where its surface went. */
204
+ const AWAY_TEXT = {
205
+ stage: 'on the stage',
206
+ pip: 'in picture-in-picture',
207
+ tab: 'here',
208
+ hidden: 'hidden',
209
+ };
210
+ const AWAY_ICON = {
211
+ stage: 'fa-solid fa-expand',
212
+ pip: 'fa-regular fa-window-restore',
213
+ tab: 'fa-solid fa-table-columns',
214
+ hidden: 'fa-solid fa-eye-slash',
215
+ };
161
216
  /**
162
217
  * The call overlay's TABBED SURFACE PANEL (the right panel) — decluttered redesign:
163
218
  *
164
219
  * - **Channel tabs** (LEFT cluster) — one per channel that has come into play. The whiteboard
165
220
  * tabs immediately at session start; every other channel tabs only once the agent first
166
- * USES it. Each carries a distinct accent color + its plugin icon. The pane creates the
167
- * plugin's surface component dynamically (via `mj-realtime-channel-pane`); a placeholder
168
- * shows the "coming online…" state until a plugin/template is supplied.
221
+ * USES it. Each carries a distinct accent color + its plugin icon. A plugin's surface lives
222
+ * on the overlay's stage, which lays it over the pane's slot while the tab is active
223
+ * ({@link ChannelSlotChange}); a placeholder shows the "coming online…" state until a
224
+ * plugin/template is supplied.
169
225
  * - **Activity** (RIGHT-aligned, pinned LAST) — gated: appears only once ≥1 agent run has
170
226
  * occurred (or in review mode). Hosts {@link RealtimeActivityRailComponent}, which now also
171
227
  * renders inline artifact previews and a split-pane artifact viewer. Styled distinctly from
@@ -175,8 +231,9 @@ const CHANNEL_ONBOARDING_SEEN_SETTING_KEY = 'mj.realtimeChannels.onboardingSeen.
175
231
  * Artifacts NO LONGER get their own tab — they live inside the Activity tab (cleaner than a
176
232
  * row of per-artifact tabs).
177
233
  *
178
- * Panes are kept ALIVE while hidden (CSS `display:none`) so switching tabs never reloads a
179
- * channel surface or resets the rail. The whole panel collapses to a slim strip via the chevron.
234
+ * Panes are kept ALIVE while hidden (CSS `display:none`) so switching tabs never resets the rail;
235
+ * channel surfaces are on the overlay's stage, so switching tabs or collapsing the panel never
236
+ * reloads them either. The whole panel collapses to a slim strip via the chevron.
180
237
  *
181
238
  * SIZING IS EXTERNAL: the overlay shell hosts this panel in a fixed-width flex item and owns
182
239
  * the width. This panel just fills it and REPORTS the layout signals the shell sizes from:
@@ -191,9 +248,9 @@ export class RealtimeSurfaceTabsComponent {
191
248
  /** Whether developer affordances ("Open run" links) are revealed (gear-gated). */
192
249
  DevMode = false;
193
250
  /**
194
- * FILL presentation: the panel stretches to the overlay's full width (the board-focus
195
- * layout, where the main call column is hidden and a channel surface owns the screen).
196
- * Bound by the overlay shell; overrides the normal / wide width tiers.
251
+ * FILL presentation: the panel stretches to its host's full width with no left border,
252
+ * overriding the normal / wide width tiers. The overlay no longer binds it: in focus mode
253
+ * the focused channel's surface fills the overlay's stage instead.
197
254
  */
198
255
  Fill = false;
199
256
  /** The signed-in user, threaded to the artifact viewer panel. */
@@ -234,12 +291,50 @@ export class RealtimeSurfaceTabsComponent {
234
291
  * the user has never dragged an explicit width).
235
292
  */
236
293
  WideChanged = new EventEmitter();
294
+ /**
295
+ * The channel whose tab the user is looking at changed (`null` when a non-channel tab, such as Activity, is active).
296
+ * Lets the session show the model the surface the user is on when it can only watch one.
297
+ */
298
+ ActiveChannelChange = new EventEmitter();
299
+ /**
300
+ * The active channel tab's slot changed: the element its pane keeps for the channel's surface, or `null` while no
301
+ * channel tab is showing (another tab is active, or the panel is collapsed). The overlay's stage lays the surface
302
+ * over this element.
303
+ */
304
+ ChannelSlotChange = new EventEmitter();
305
+ /**
306
+ * Where each channel's surface is placed, by channel key (a channel not listed is on its tab). A channel whose
307
+ * surface is elsewhere shows where in its pane, with "Bring it here" when its channel allows the tab.
308
+ */
309
+ SurfacePlacements = new Map();
310
+ /** Where each channel lets the user move its surface, by channel key (a channel not listed allows anywhere). */
311
+ AllowedPlacements = new Map();
312
+ /** The user asked to move a channel's surface (from "Move to…" or "Bring it here"). */
313
+ MoveRequested = new EventEmitter();
314
+ /** The user asked to put every surface back where its channel places it. */
315
+ ResetLayoutRequested = new EventEmitter();
237
316
  /** The panel's tab state (add / focus / dedupe / flash) — see the model for the rules. */
238
317
  Model = new RealtimeSurfaceTabsModel();
239
- /** Whether the panel is collapsed to its slim strip. */
240
- Collapsed = false;
318
+ /**
319
+ * Whether the panel is collapsed to its slim strip. The chevron toggles it, a reveal expands it, and the panel reports
320
+ * each such change through {@link CollapsedChange}. A host may bind it, so that a panel it creates again starts as the
321
+ * user left the one before (the call overlay does when only the call's width hid the panel, #5433). A value the host
322
+ * sets is not reported back.
323
+ */
324
+ set Collapsed(value) {
325
+ this.collapsed = value;
326
+ this.syncWide();
327
+ }
328
+ get Collapsed() {
329
+ return this.collapsed;
330
+ }
331
+ collapsed = false;
241
332
  /** The embedded Activity rail (owns the inline artifact previews + the split-pane viewer). */
242
333
  activityRail;
334
+ /** The slots of the plugin channel panes, one per tab. */
335
+ channelSlots;
336
+ /** The slot last reported through {@link ChannelSlotChange}. */
337
+ reportedSlot = null;
243
338
  flashTimer = null;
244
339
  subs = [];
245
340
  lastWide = false;
@@ -263,6 +358,9 @@ export class RealtimeSurfaceTabsComponent {
263
358
  ngOnInit() {
264
359
  this.subs.push(this.Model.Changed$.subscribe(() => this.onModelChanged()));
265
360
  }
361
+ ngAfterViewChecked() {
362
+ this.reportChannelSlot();
363
+ }
266
364
  ngOnDestroy() {
267
365
  for (const s of this.subs) {
268
366
  s.unsubscribe();
@@ -273,14 +371,46 @@ export class RealtimeSurfaceTabsComponent {
273
371
  this.flashTimer = null;
274
372
  }
275
373
  }
374
+ /** Reports the active channel tab's slot when it differs from the one last reported. */
375
+ reportChannelSlot() {
376
+ const slot = this.activeChannelSlot();
377
+ if (slot?.Key === this.reportedSlot?.Key && slot?.Element === this.reportedSlot?.Element) {
378
+ return;
379
+ }
380
+ this.reportedSlot = slot;
381
+ // The view was just checked and the overlay binds the slot, so it hears about it in a fresh turn.
382
+ queueMicrotask(() => this.ChannelSlotChange.emit(slot));
383
+ }
384
+ /** The active tab's slot: present while that tab is a plugin channel and the panel is expanded. */
385
+ activeChannelSlot() {
386
+ const key = this.Model.ActiveKey;
387
+ const slot = this.channelSlots?.find(s => s.nativeElement.dataset['channelKey'] === key);
388
+ return slot ? { Key: key, Element: slot.nativeElement } : null;
389
+ }
390
+ /** Where a channel's surface is placed. */
391
+ PlacementOf(key) {
392
+ return this.SurfacePlacements.get(key) ?? 'tab';
393
+ }
394
+ /** Where a channel lets the user move its surface. */
395
+ AllowedOf(key) {
396
+ return this.AllowedPlacements.get(key) ?? MEDIA_PLACEMENTS;
397
+ }
398
+ /** Where a moved channel's surface is, as its tab says it: "on the stage", "in picture-in-picture", "hidden". */
399
+ AwayText(key) {
400
+ return AWAY_TEXT[this.PlacementOf(key)];
401
+ }
402
+ /** The icon for where a moved channel's surface is. */
403
+ AwayIcon(key) {
404
+ return AWAY_ICON[this.PlacementOf(key)];
405
+ }
276
406
  /** Toggle the panel between expanded and slim-collapsed. */
277
407
  ToggleCollapsed() {
278
408
  this.setCollapsed(!this.Collapsed);
279
409
  }
280
410
  /** Collapse-state transitions funnel through here so the shell always hears about them. */
281
411
  setCollapsed(value) {
282
- if (this.Collapsed !== value) {
283
- this.Collapsed = value;
412
+ if (this.collapsed !== value) {
413
+ this.collapsed = value;
284
414
  this.CollapsedChange.emit(value);
285
415
  this.syncWide();
286
416
  }
@@ -377,11 +507,22 @@ export class RealtimeSurfaceTabsComponent {
377
507
  }
378
508
  /** On model changes: schedule the flash clear, report a wide-tier flip, re-render. */
379
509
  onModelChanged() {
510
+ this.emitActiveChannelIfChanged();
380
511
  this.scheduleFlashClear();
381
512
  this.syncWide();
382
513
  this.evaluateOnboarding();
383
514
  this.cdr.markForCheck();
384
515
  }
516
+ /** The channel key last reported through {@link ActiveChannelChange}. */
517
+ lastReportedChannel = null;
518
+ /** Reports the focused channel when it differs from the last one reported. */
519
+ emitActiveChannelIfChanged() {
520
+ const key = this.Model.ActiveChannelKey;
521
+ if (key !== this.lastReportedChannel) {
522
+ this.lastReportedChannel = key;
523
+ this.ActiveChannelChange.emit(key);
524
+ }
525
+ }
385
526
  /**
386
527
  * Decides whether the first-run channel intro should be visible for the ACTIVE tab: shows it
387
528
  * the first time the user opens (focuses) a channel tab whose plugin supplies onboarding and
@@ -468,27 +609,28 @@ export class RealtimeSurfaceTabsComponent {
468
609
  }
469
610
  static ɵfac = function RealtimeSurfaceTabsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RealtimeSurfaceTabsComponent)(); };
470
611
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RealtimeSurfaceTabsComponent, selectors: [["mj-realtime-surface-tabs"]], viewQuery: function RealtimeSurfaceTabsComponent_Query(rf, ctx) { if (rf & 1) {
471
- i0.ɵɵviewQuery(RealtimeActivityRailComponent, 5);
612
+ i0.ɵɵviewQuery(RealtimeActivityRailComponent, 5)(_c0, 5);
472
613
  } if (rf & 2) {
473
614
  let _t;
474
615
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.activityRail = _t.first);
475
- } }, inputs: { State: "State", DevMode: "DevMode", Fill: "Fill", CurrentUser: "CurrentUser", EnvironmentID: "EnvironmentID", ExtraArtifacts: "ExtraArtifacts", ShowActivityTab: "ShowActivityTab" }, outputs: { OpenRunRequested: "OpenRunRequested", CollapsedChange: "CollapsedChange", WideChanged: "WideChanged" }, decls: 3, vars: 5, consts: [["aria-label", "Session surfaces", 1, "surface"], [1, "surface__strip"], ["type", "button", "title", "Show session panel", "aria-expanded", "false", 1, "surface__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-left"], ["aria-hidden", "true", "title", "Session activity", 1, "fa-solid", "fa-wave-square", "surface__strip-icon"], ["role", "tablist", 1, "surface-tabs"], [1, "tabs-end"], ["type", "button", "title", "Hide session panel", "aria-expanded", "true", 1, "surface__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right"], ["role", "tabpanel", 1, "s-pane", 3, "s-pane--active"], ["role", "status", 1, "surface__empty"], ["aria-hidden", "true", 1, "tabs-spacer"], ["type", "button", "role", "tab", 1, "s-tab", 3, "click", "title"], ["aria-hidden", "true", 1, "s-tab__dot"], ["aria-hidden", "true"], [1, "s-tab__title"], ["aria-hidden", "true", 1, "s-tab__badge"], ["role", "tabpanel", 1, "s-pane"], [3, "State", "DevMode", "Embedded", "CurrentUser", "EnvironmentID", "ExtraArtifacts"], [3, "OpenRunRequested", "State", "DevMode", "Embedded", "CurrentUser", "EnvironmentID", "ExtraArtifacts"], [3, "ngTemplateOutlet"], ["role", "status", 1, "channel-placeholder"], [3, "Plugin"], [3, "Content"], [3, "Dismissed", "Content"], ["aria-hidden", "true", 1, "fa-solid", "fa-chalkboard"], ["aria-hidden", "true", 1, "fa-solid", "fa-wave-square"]], template: function RealtimeSurfaceTabsComponent_Template(rf, ctx) { if (rf & 1) {
476
- i0.ɵɵelementStart(0, "aside", 0);
477
- i0.ɵɵconditionalCreate(1, RealtimeSurfaceTabsComponent_Conditional_1_Template, 4, 0, "div", 1)(2, RealtimeSurfaceTabsComponent_Conditional_2_Template, 9, 1);
616
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.channelSlots = _t);
617
+ } }, inputs: { State: "State", DevMode: "DevMode", Fill: "Fill", CurrentUser: "CurrentUser", EnvironmentID: "EnvironmentID", ExtraArtifacts: "ExtraArtifacts", ShowActivityTab: "ShowActivityTab", SurfacePlacements: "SurfacePlacements", AllowedPlacements: "AllowedPlacements", Collapsed: "Collapsed" }, outputs: { OpenRunRequested: "OpenRunRequested", CollapsedChange: "CollapsedChange", WideChanged: "WideChanged", ActiveChannelChange: "ActiveChannelChange", ChannelSlotChange: "ChannelSlotChange", MoveRequested: "MoveRequested", ResetLayoutRequested: "ResetLayoutRequested" }, decls: 3, vars: 5, consts: [["channelSlot", ""], ["aria-label", "Session surfaces", 1, "surface"], [1, "surface__strip"], ["type", "button", "title", "Show session panel", "aria-expanded", "false", 1, "surface__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-left"], ["aria-hidden", "true", "title", "Session activity", 1, "fa-solid", "fa-wave-square", "surface__strip-icon"], ["role", "tablist", 1, "surface-tabs"], [1, "tabs-end"], ["type", "button", "title", "Hide session panel", "aria-expanded", "true", 1, "surface__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right"], ["role", "tabpanel", 1, "s-pane", 3, "s-pane--active"], ["role", "status", 1, "surface__empty"], ["aria-hidden", "true", 1, "tabs-spacer"], ["type", "button", "role", "tab", 1, "s-tab", 3, "click", "title"], ["aria-hidden", "true", 1, "s-tab__dot"], ["aria-hidden", "true"], [1, "s-tab__title"], ["aria-hidden", "true", 1, "s-tab__badge"], [1, "s-tab-move", 3, "Key", "Title", "Placement", "Allowed"], [1, "s-tab-move", 3, "MoveRequested", "ResetLayoutRequested", "Key", "Title", "Placement", "Allowed"], ["role", "tabpanel", 1, "s-pane"], [3, "State", "DevMode", "Embedded", "CurrentUser", "EnvironmentID", "ExtraArtifacts"], [3, "OpenRunRequested", "State", "DevMode", "Embedded", "CurrentUser", "EnvironmentID", "ExtraArtifacts"], ["role", "status", 1, "s-pane__away"], [3, "ngTemplateOutlet"], ["role", "status", 1, "channel-placeholder"], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm"], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm", 3, "click"], [1, "s-pane__slot"], [3, "Content"], [3, "Dismissed", "Content"], ["aria-hidden", "true", 1, "fa-solid", "fa-chalkboard"], ["aria-hidden", "true", 1, "fa-solid", "fa-wave-square"]], template: function RealtimeSurfaceTabsComponent_Template(rf, ctx) { if (rf & 1) {
618
+ i0.ɵɵelementStart(0, "aside", 1);
619
+ i0.ɵɵconditionalCreate(1, RealtimeSurfaceTabsComponent_Conditional_1_Template, 4, 0, "div", 2)(2, RealtimeSurfaceTabsComponent_Conditional_2_Template, 9, 1);
478
620
  i0.ɵɵelementEnd();
479
621
  } if (rf & 2) {
480
622
  i0.ɵɵclassProp("surface--collapsed", ctx.Collapsed)("surface--fill", ctx.Fill && !ctx.Collapsed);
481
623
  i0.ɵɵadvance();
482
624
  i0.ɵɵconditional(ctx.Collapsed ? 1 : 2);
483
- } }, dependencies: [CommonModule, i1.NgTemplateOutlet, ArtifactsModule, RealtimeActivityRailComponent, RealtimeChannelPaneComponent,
484
- ChannelOnboardingPanelComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n \n --activity-accent: var(--mj-color-violet-400, #a78bfa);\n --activity-accent-bg: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 12%, transparent);\n --activity-accent-border: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 38%, transparent);\n \n --tab-accent: var(--mj-brand-primary);\n}\n\n\n\n.surface[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.surface--fill[_ngcontent-%COMP%] {\n width: 100%;\n border-left: none;\n}\n.surface--collapsed[_ngcontent-%COMP%] {\n width: 40px;\n background: var(--mj-bg-surface-card);\n}\n\n\n.surface__strip[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n.surface__strip-icon[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.surface__toggle[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: grid;\n place-items: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n font-size: 10px;\n transition: color 140ms ease, border-color 140ms ease;\n}\n.surface__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.surface-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.surface-tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n\n.tabs-spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 12px;\n}\n\n\n\n.s-tab[_ngcontent-%COMP%] {\n position: relative;\n padding: 10px 14px;\n border: 0;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n display: inline-flex;\n align-items: center;\n gap: 7px;\n border-bottom: 3px solid transparent;\n transition: color 150ms ease, border-color 150ms ease, background 150ms ease;\n white-space: nowrap;\n flex: 0 1 auto;\n min-width: calc(11px + 7px + 8ch + 28px); \n}\n.s-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n flex-shrink: 0;\n}\n.s-tab__title[_ngcontent-%COMP%] {\n max-width: 22ch;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.s-tab[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n\n.s-tab__dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--tab-accent);\n}\n\n\n.s-tab--active[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] {\n border-bottom-color: var(--tab-accent);\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] .s-tab__dot[_ngcontent-%COMP%] {\n box-shadow: 0 0 6px var(--tab-accent);\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--tab-accent);\n}\n\n\n.s-tab--activity[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n.s-tab--activity[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--activity-accent);\n}\n.s-tab--activity.s-tab--active[_ngcontent-%COMP%] {\n border-bottom-color: var(--activity-accent);\n background: var(--activity-accent-bg);\n color: var(--mj-text-primary);\n}\n.s-tab__badge[_ngcontent-%COMP%] {\n display: inline-grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--activity-accent);\n color: var(--mj-text-inverse);\n font-size: 9.5px;\n font-weight: 800;\n line-height: 1;\n flex-shrink: 0;\n}\n\n\n.s-tab--flash[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_tab-flash 1.4s ease;\n}\n@keyframes _ngcontent-%COMP%_tab-flash {\n 0% {\n background: color-mix(in srgb, var(--tab-accent) 30%, transparent);\n border-bottom-color: var(--tab-accent);\n color: var(--mj-text-primary);\n }\n 60% {\n background: color-mix(in srgb, var(--tab-accent) 16%, transparent);\n border-bottom-color: var(--tab-accent);\n }\n 100% {\n background: var(--mj-bg-surface);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .s-tab--flash[_ngcontent-%COMP%] {\n animation: none;\n background: color-mix(in srgb, var(--tab-accent) 18%, transparent);\n }\n}\n\n.tabs-end[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 8px;\n flex-shrink: 0;\n}\n\n\n.s-pane[_ngcontent-%COMP%] {\n display: none;\n flex: 1;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n \n position: relative;\n}\n.s-pane--active[_ngcontent-%COMP%] {\n display: flex;\n}\n\n\n.surface__empty[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 500;\n padding: 24px;\n text-align: center;\n}\n.surface__empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--activity-accent);\n opacity: 0.6;\n}\n\n\n.channel-placeholder[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12.5px;\n font-weight: 600;\n padding: 24px;\n text-align: center;\n}\n.channel-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n\n@media (max-width: 860px) {\n .surface[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
625
+ } }, dependencies: [CommonModule, i1.NgTemplateOutlet, ArtifactsModule, RealtimeActivityRailComponent, ChannelOnboardingPanelComponent,
626
+ MediaMoveMenuComponent, MJButtonDirective], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n \n --activity-accent: var(--mj-color-violet-400, #a78bfa);\n --activity-accent-bg: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 12%, transparent);\n --activity-accent-border: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 38%, transparent);\n \n --tab-accent: var(--mj-brand-primary);\n}\n\n\n\n.surface[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.surface--fill[_ngcontent-%COMP%] {\n width: 100%;\n border-left: none;\n}\n.surface--collapsed[_ngcontent-%COMP%] {\n width: 40px;\n background: var(--mj-bg-surface-card);\n}\n\n\n.surface__strip[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n.surface__strip-icon[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.surface__toggle[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: grid;\n place-items: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n font-size: 10px;\n transition: color 140ms ease, border-color 140ms ease;\n}\n.surface__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.surface-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.surface-tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n\n.tabs-spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 12px;\n}\n\n\n\n.s-tab[_ngcontent-%COMP%] {\n position: relative;\n padding: 10px 14px;\n border: 0;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n display: inline-flex;\n align-items: center;\n gap: 7px;\n border-bottom: 3px solid transparent;\n transition: color 150ms ease, border-color 150ms ease, background 150ms ease;\n white-space: nowrap;\n flex: 0 1 auto;\n min-width: calc(11px + 7px + 8ch + 28px); \n}\n.s-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n flex-shrink: 0;\n}\n.s-tab__title[_ngcontent-%COMP%] {\n max-width: 22ch;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.s-tab[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n\n.s-tab__dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--tab-accent);\n}\n\n\n.s-tab--active[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] {\n border-bottom-color: var(--tab-accent);\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] .s-tab__dot[_ngcontent-%COMP%] {\n box-shadow: 0 0 6px var(--tab-accent);\n}\n.s-tab--channel.s-tab--active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--tab-accent);\n}\n\n\n.s-tab--activity[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n.s-tab--activity[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--activity-accent);\n}\n.s-tab--activity.s-tab--active[_ngcontent-%COMP%] {\n border-bottom-color: var(--activity-accent);\n background: var(--activity-accent-bg);\n color: var(--mj-text-primary);\n}\n.s-tab__badge[_ngcontent-%COMP%] {\n display: inline-grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--activity-accent);\n color: var(--mj-text-inverse);\n font-size: 9.5px;\n font-weight: 800;\n line-height: 1;\n flex-shrink: 0;\n}\n\n\n.s-tab--flash[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_tab-flash 1.4s ease;\n}\n@keyframes _ngcontent-%COMP%_tab-flash {\n 0% {\n background: color-mix(in srgb, var(--tab-accent) 30%, transparent);\n border-bottom-color: var(--tab-accent);\n color: var(--mj-text-primary);\n }\n 60% {\n background: color-mix(in srgb, var(--tab-accent) 16%, transparent);\n border-bottom-color: var(--tab-accent);\n }\n 100% {\n background: var(--mj-bg-surface);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .s-tab--flash[_ngcontent-%COMP%] {\n animation: none;\n background: color-mix(in srgb, var(--tab-accent) 18%, transparent);\n }\n}\n\n.tabs-end[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 8px;\n flex-shrink: 0;\n}\n\n\n.s-pane[_ngcontent-%COMP%] {\n display: none;\n flex: 1;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n \n position: relative;\n}\n.s-pane--active[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.s-pane__slot[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}\n\n\n.s-pane__away[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 24px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n.s-pane__away[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n\n.s-tab-move[_ngcontent-%COMP%] {\n align-self: center;\n margin: 0 4px 0 -4px;\n}\n\n\n.surface__empty[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 500;\n padding: 24px;\n text-align: center;\n}\n.surface__empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--activity-accent);\n opacity: 0.6;\n}\n\n\n.channel-placeholder[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12.5px;\n font-weight: 600;\n padding: 24px;\n text-align: center;\n}\n.channel-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n\n@media (max-width: 860px) {\n .surface[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
485
627
  }
486
628
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RealtimeSurfaceTabsComponent, [{
487
629
  type: Component,
488
630
  args: [{ standalone: true, selector: 'mj-realtime-surface-tabs', imports: [
489
- CommonModule, ArtifactsModule, RealtimeActivityRailComponent, RealtimeChannelPaneComponent,
490
- ChannelOnboardingPanelComponent
491
- ], template: "<!-- SIZING IS EXTERNAL: the overlay hosts this panel inside a fixed-width flex item and\n owns its width (drag, persistence, default tiers) \u2014 the panel just fills it. -->\n<aside class=\"surface\"\n [class.surface--collapsed]=\"Collapsed\"\n [class.surface--fill]=\"Fill && !Collapsed\"\n aria-label=\"Session surfaces\">\n\n @if (Collapsed) {\n <!-- Slim strip: the panel's collapse target -->\n <div class=\"surface__strip\">\n <button type=\"button\"\n class=\"surface__toggle\"\n (click)=\"ToggleCollapsed()\"\n title=\"Show session panel\"\n aria-expanded=\"false\">\n <i class=\"fa-solid fa-chevron-left\" aria-hidden=\"true\"></i>\n </button>\n <i class=\"fa-solid fa-wave-square surface__strip-icon\" aria-hidden=\"true\" title=\"Session activity\"></i>\n </div>\n } @else {\n <!-- Tab strip: channel tabs (left cluster) \u2026 | spacer | Activity (right-aligned) -->\n <div class=\"surface-tabs\" role=\"tablist\">\n @for (tab of Model.Tabs; track TrackTab($index, tab)) {\n @if (tab.Kind === 'activity') {\n <!-- Flex spacer pushes the Activity tab to the far right -->\n <span class=\"tabs-spacer\" aria-hidden=\"true\"></span>\n }\n <button type=\"button\"\n class=\"s-tab\"\n role=\"tab\"\n [class.s-tab--activity]=\"tab.Kind === 'activity'\"\n [class.s-tab--channel]=\"tab.Kind === 'channel'\"\n [class.s-tab--active]=\"tab.Key === Model.ActiveKey\"\n [class.s-tab--flash]=\"tab.Key === Model.FlashKey\"\n [style.--tab-accent]=\"tab.Color || null\"\n [attr.aria-selected]=\"tab.Key === Model.ActiveKey\"\n [title]=\"tab.Title\"\n (click)=\"Model.Focus(tab.Key)\">\n @if (tab.Kind === 'channel') {\n <span class=\"s-tab__dot\" aria-hidden=\"true\"></span>\n }\n <i [class]=\"tab.Icon\" aria-hidden=\"true\"></i>\n <span class=\"s-tab__title\">{{ tab.Title }}</span>\n @if (tab.Kind === 'activity' && State.Cards.length > 0) {\n <span class=\"s-tab__badge\" aria-hidden=\"true\">{{ State.Cards.length }}</span>\n }\n </button>\n }\n <div class=\"tabs-end\">\n <button type=\"button\"\n class=\"surface__toggle\"\n (click)=\"ToggleCollapsed()\"\n title=\"Hide session panel\"\n aria-expanded=\"true\">\n <i class=\"fa-solid fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- Panes: ALL kept alive; only the active one is displayed -->\n @for (tab of Model.Tabs; track TrackTab($index, tab)) {\n <div class=\"s-pane\" [class.s-pane--active]=\"tab.Key === Model.ActiveKey\" role=\"tabpanel\">\n @switch (tab.Kind) {\n @case ('activity') {\n <mj-realtime-activity-rail\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [Embedded]=\"true\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ExtraArtifacts]=\"ExtraArtifacts\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\">\n </mj-realtime-activity-rail>\n }\n @case ('channel') {\n @if (tab.Data?.Plugin; as plugin) {\n <!-- Registry-resolved channel: the pane host creates the plugin's surface\n component dynamically and hands the instance back for binding -->\n <mj-realtime-channel-pane [Plugin]=\"plugin\"></mj-realtime-channel-pane>\n <!-- First-run intro: overlaid over the active channel pane the first time this user\n opens it; the pane host renders display:none + a sibling surface, so the overlay\n sits here (inside the positioned .s-pane) rather than inside the pane host. -->\n @if (tab.Key === Model.ActiveKey && OnboardingContent) {\n <mj-channel-onboarding-panel\n [Content]=\"OnboardingContent\"\n (Dismissed)=\"DismissOnboarding()\">\n </mj-channel-onboarding-panel>\n }\n } @else if (tab.Data?.Content; as content) {\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n } @else {\n <!-- Placeholder until the channel registration supplies a plugin / template -->\n <div class=\"channel-placeholder\" role=\"status\">\n <i class=\"fa-solid fa-chalkboard\" aria-hidden=\"true\"></i>\n <span>{{ tab.Title }} coming online\u2026</span>\n </div>\n }\n }\n }\n </div>\n }\n\n @if (Model.Tabs.length === 0) {\n <!-- Nothing in play yet (idle voice-first session): a gentle hint, not an empty grid -->\n <div class=\"surface__empty\" role=\"status\">\n <i class=\"fa-solid fa-wave-square\" aria-hidden=\"true\"></i>\n <span>Surfaces appear here as the call gets going.</span>\n </div>\n }\n }\n</aside>\n", styles: [":host {\n display: block;\n height: 100%;\n /* activity accent \u2014 same violet palette the rail + delegation cards use */\n --activity-accent: var(--mj-color-violet-400, #a78bfa);\n --activity-accent-bg: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 12%, transparent);\n --activity-accent-border: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 38%, transparent);\n /* per-tab accent, set inline per channel ([style.--tab-accent]); falls back to the brand. */\n --tab-accent: var(--mj-brand-primary);\n}\n\n/* The surface panel fills the overlay's `.call-panel` flex item \u2014 the overlay owns\n the width (user drag via the resize handle, persisted per-user, default tiers). */\n.surface {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n/* Board-focus fill: the panel owns the whole overlay (the main call column is hidden). */\n.surface--fill {\n width: 100%;\n border-left: none;\n}\n.surface--collapsed {\n width: 40px;\n background: var(--mj-bg-surface-card);\n}\n\n/* ---------- collapsed slim strip ---------- */\n.surface__strip {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n.surface__strip-icon {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.surface__toggle {\n width: 24px;\n height: 24px;\n display: grid;\n place-items: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n font-size: 10px;\n transition: color 140ms ease, border-color 140ms ease;\n}\n.surface__toggle:hover {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* ---------- tab strip: channel cluster (left) | spacer | Activity (right) ---------- */\n.surface-tabs {\n display: flex;\n align-items: stretch;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.surface-tabs::-webkit-scrollbar {\n display: none;\n}\n\n/* The flex spacer separates the channel cluster (left) from the Activity tab (right). */\n.tabs-spacer {\n flex: 1 1 auto;\n min-width: 12px;\n}\n\n/* Tabs keep their natural width while there's room; when space gets tight they shrink\n (ellipsizing their titles) down to a readable floor. The ACTIVE tab never shrinks. */\n.s-tab {\n position: relative;\n padding: 10px 14px;\n border: 0;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n display: inline-flex;\n align-items: center;\n gap: 7px;\n border-bottom: 3px solid transparent;\n transition: color 150ms ease, border-color 150ms ease, background 150ms ease;\n white-space: nowrap;\n flex: 0 1 auto;\n min-width: calc(11px + 7px + 8ch + 28px); /* icon + gap + ~8ch + padding */\n}\n.s-tab i {\n font-size: 11px;\n flex-shrink: 0;\n}\n.s-tab__title {\n max-width: 22ch;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.s-tab:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n/* Per-channel color dot \u2014 the distinct accent each channel tab carries. */\n.s-tab__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--tab-accent);\n}\n\n/* Active tab: filled background + a colored underline in the tab's own accent. */\n.s-tab--active {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.s-tab--channel.s-tab--active {\n border-bottom-color: var(--tab-accent);\n}\n.s-tab--channel.s-tab--active .s-tab__dot {\n box-shadow: 0 0 6px var(--tab-accent);\n}\n.s-tab--channel.s-tab--active i {\n color: var(--tab-accent);\n}\n\n/* ---------- the Activity tab (right-aligned, distinct accent + pulse icon) ---------- */\n.s-tab--activity {\n color: var(--mj-text-secondary);\n}\n.s-tab--activity i {\n color: var(--activity-accent);\n}\n.s-tab--activity.s-tab--active {\n border-bottom-color: var(--activity-accent);\n background: var(--activity-accent-bg);\n color: var(--mj-text-primary);\n}\n.s-tab__badge {\n display: inline-grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--activity-accent);\n color: var(--mj-text-inverse);\n font-size: 9.5px;\n font-weight: 800;\n line-height: 1;\n flex-shrink: 0;\n}\n\n/* Brief flash for a just-revealed channel tab (the agent first acted on it). */\n.s-tab--flash {\n animation: tab-flash 1.4s ease;\n}\n@keyframes tab-flash {\n 0% {\n background: color-mix(in srgb, var(--tab-accent) 30%, transparent);\n border-bottom-color: var(--tab-accent);\n color: var(--mj-text-primary);\n }\n 60% {\n background: color-mix(in srgb, var(--tab-accent) 16%, transparent);\n border-bottom-color: var(--tab-accent);\n }\n 100% {\n background: var(--mj-bg-surface);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .s-tab--flash {\n animation: none;\n background: color-mix(in srgb, var(--tab-accent) 18%, transparent);\n }\n}\n\n.tabs-end {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 8px;\n flex-shrink: 0;\n}\n\n/* ---------- panes: all alive, only the active one displayed ---------- */\n.s-pane {\n display: none;\n flex: 1;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n /* Positioning context for the first-run channel-onboarding overlay (absolute, inset:0). */\n position: relative;\n}\n.s-pane--active {\n display: flex;\n}\n\n/* Empty strip (idle voice-first session): a gentle hint rather than a bare grid. */\n.surface__empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 500;\n padding: 24px;\n text-align: center;\n}\n.surface__empty i {\n font-size: 20px;\n color: var(--activity-accent);\n opacity: 0.6;\n}\n\n/* Channel slot placeholder (\"Whiteboard coming online\u2026\") */\n.channel-placeholder {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12.5px;\n font-weight: 600;\n padding: 24px;\n text-align: center;\n}\n.channel-placeholder i {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n/* On narrow widths the panel stacks out of the way (overlay falls back to single column) */\n@media (max-width: 860px) {\n .surface {\n display: none;\n }\n}\n"] }]
631
+ CommonModule, ArtifactsModule, RealtimeActivityRailComponent, ChannelOnboardingPanelComponent,
632
+ MediaMoveMenuComponent, MJButtonDirective
633
+ ], template: "<!-- SIZING IS EXTERNAL: the overlay hosts this panel inside a fixed-width flex item and\n owns its width (drag, persistence, default tiers) \u2014 the panel just fills it. -->\n<aside class=\"surface\"\n [class.surface--collapsed]=\"Collapsed\"\n [class.surface--fill]=\"Fill && !Collapsed\"\n aria-label=\"Session surfaces\">\n\n @if (Collapsed) {\n <!-- Slim strip: the panel's collapse target -->\n <div class=\"surface__strip\">\n <button type=\"button\"\n class=\"surface__toggle\"\n (click)=\"ToggleCollapsed()\"\n title=\"Show session panel\"\n aria-expanded=\"false\">\n <i class=\"fa-solid fa-chevron-left\" aria-hidden=\"true\"></i>\n </button>\n <i class=\"fa-solid fa-wave-square surface__strip-icon\" aria-hidden=\"true\" title=\"Session activity\"></i>\n </div>\n } @else {\n <!-- Tab strip: channel tabs (left cluster) \u2026 | spacer | Activity (right-aligned) -->\n <div class=\"surface-tabs\" role=\"tablist\">\n @for (tab of Model.Tabs; track TrackTab($index, tab)) {\n @if (tab.Kind === 'activity') {\n <!-- Flex spacer pushes the Activity tab to the far right -->\n <span class=\"tabs-spacer\" aria-hidden=\"true\"></span>\n }\n <button type=\"button\"\n class=\"s-tab\"\n role=\"tab\"\n [class.s-tab--activity]=\"tab.Kind === 'activity'\"\n [class.s-tab--channel]=\"tab.Kind === 'channel'\"\n [class.s-tab--active]=\"tab.Key === Model.ActiveKey\"\n [class.s-tab--flash]=\"tab.Key === Model.FlashKey\"\n [style.--tab-accent]=\"tab.Color || null\"\n [attr.aria-selected]=\"tab.Key === Model.ActiveKey\"\n [title]=\"tab.Title\"\n (click)=\"Model.Focus(tab.Key)\">\n @if (tab.Kind === 'channel') {\n <span class=\"s-tab__dot\" aria-hidden=\"true\"></span>\n }\n <i [class]=\"tab.Icon\" aria-hidden=\"true\"></i>\n <span class=\"s-tab__title\">{{ tab.Title }}</span>\n @if (tab.Kind === 'activity' && State.Cards.length > 0) {\n <span class=\"s-tab__badge\" aria-hidden=\"true\">{{ State.Cards.length }}</span>\n }\n </button>\n @if (tab.Kind === 'channel' && tab.Data?.Plugin && tab.Key === Model.ActiveKey) {\n <!-- \"Move to\u2026\" for the active channel's surface: beside its tab, since a tab is itself a button. -->\n <mj-media-move-menu\n class=\"s-tab-move\"\n [Key]=\"tab.Key\"\n [Title]=\"tab.Title\"\n [Placement]=\"PlacementOf(tab.Key)\"\n [Allowed]=\"AllowedOf(tab.Key)\"\n (MoveRequested)=\"MoveRequested.emit($event)\"\n (ResetLayoutRequested)=\"ResetLayoutRequested.emit()\">\n </mj-media-move-menu>\n }\n }\n <div class=\"tabs-end\">\n <button type=\"button\"\n class=\"surface__toggle\"\n (click)=\"ToggleCollapsed()\"\n title=\"Hide session panel\"\n aria-expanded=\"true\">\n <i class=\"fa-solid fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- Panes: ALL kept alive; only the active one is displayed -->\n @for (tab of Model.Tabs; track TrackTab($index, tab)) {\n <div class=\"s-pane\" [class.s-pane--active]=\"tab.Key === Model.ActiveKey\" role=\"tabpanel\">\n @switch (tab.Kind) {\n @case ('activity') {\n <mj-realtime-activity-rail\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [Embedded]=\"true\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ExtraArtifacts]=\"ExtraArtifacts\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\">\n </mj-realtime-activity-rail>\n }\n @case ('channel') {\n @if (tab.Data?.Plugin && PlacementOf(tab.Key) !== 'tab') {\n <!-- The user moved this channel's surface elsewhere: the tab says where, and brings it back. -->\n <div class=\"s-pane__away\" role=\"status\">\n <i [class]=\"AwayIcon(tab.Key)\" aria-hidden=\"true\"></i>\n <span>{{ tab.Title }} is {{ AwayText(tab.Key) }}.</span>\n @if (AllowedOf(tab.Key).includes('tab')) {\n <button type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\"\n (click)=\"MoveRequested.emit({ Key: tab.Key, Placement: 'tab' })\">\n Bring it here\n </button>\n }\n </div>\n } @else if (tab.Data?.Plugin) {\n <!-- Registry-resolved channel: its surface lives on the overlay's stage, which lays it\n over this slot while the tab is active (ChannelSlotChange reports the slot). -->\n <div #channelSlot class=\"s-pane__slot\" [attr.data-channel-key]=\"tab.Key\"></div>\n <!-- First-run intro: overlaid over the active channel's surface the first time this user\n opens it. It sits here, inside the positioned .s-pane, above the stage's surface. -->\n @if (tab.Key === Model.ActiveKey && OnboardingContent) {\n <mj-channel-onboarding-panel\n [Content]=\"OnboardingContent\"\n (Dismissed)=\"DismissOnboarding()\">\n </mj-channel-onboarding-panel>\n }\n } @else if (tab.Data?.Content; as content) {\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n } @else {\n <!-- Placeholder until the channel registration supplies a plugin / template -->\n <div class=\"channel-placeholder\" role=\"status\">\n <i class=\"fa-solid fa-chalkboard\" aria-hidden=\"true\"></i>\n <span>{{ tab.Title }} coming online\u2026</span>\n </div>\n }\n }\n }\n </div>\n }\n\n @if (Model.Tabs.length === 0) {\n <!-- Nothing in play yet (idle voice-first session): a gentle hint, not an empty grid -->\n <div class=\"surface__empty\" role=\"status\">\n <i class=\"fa-solid fa-wave-square\" aria-hidden=\"true\"></i>\n <span>Surfaces appear here as the call gets going.</span>\n </div>\n }\n }\n</aside>\n", styles: [":host {\n display: block;\n height: 100%;\n /* activity accent \u2014 same violet palette the rail + delegation cards use */\n --activity-accent: var(--mj-color-violet-400, #a78bfa);\n --activity-accent-bg: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 12%, transparent);\n --activity-accent-border: color-mix(in srgb, var(--mj-color-violet-400, #a78bfa) 38%, transparent);\n /* per-tab accent, set inline per channel ([style.--tab-accent]); falls back to the brand. */\n --tab-accent: var(--mj-brand-primary);\n}\n\n/* The surface panel fills the overlay's `.call-panel` flex item \u2014 the overlay owns\n the width (user drag via the resize handle, persisted per-user, default tiers). */\n.surface {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n/* Board-focus fill: the panel owns the whole overlay (the main call column is hidden). */\n.surface--fill {\n width: 100%;\n border-left: none;\n}\n.surface--collapsed {\n width: 40px;\n background: var(--mj-bg-surface-card);\n}\n\n/* ---------- collapsed slim strip ---------- */\n.surface__strip {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n.surface__strip-icon {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.surface__toggle {\n width: 24px;\n height: 24px;\n display: grid;\n place-items: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n font-size: 10px;\n transition: color 140ms ease, border-color 140ms ease;\n}\n.surface__toggle:hover {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* ---------- tab strip: channel cluster (left) | spacer | Activity (right) ---------- */\n.surface-tabs {\n display: flex;\n align-items: stretch;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n.surface-tabs::-webkit-scrollbar {\n display: none;\n}\n\n/* The flex spacer separates the channel cluster (left) from the Activity tab (right). */\n.tabs-spacer {\n flex: 1 1 auto;\n min-width: 12px;\n}\n\n/* Tabs keep their natural width while there's room; when space gets tight they shrink\n (ellipsizing their titles) down to a readable floor. The ACTIVE tab never shrinks. */\n.s-tab {\n position: relative;\n padding: 10px 14px;\n border: 0;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n display: inline-flex;\n align-items: center;\n gap: 7px;\n border-bottom: 3px solid transparent;\n transition: color 150ms ease, border-color 150ms ease, background 150ms ease;\n white-space: nowrap;\n flex: 0 1 auto;\n min-width: calc(11px + 7px + 8ch + 28px); /* icon + gap + ~8ch + padding */\n}\n.s-tab i {\n font-size: 11px;\n flex-shrink: 0;\n}\n.s-tab__title {\n max-width: 22ch;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.s-tab:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n/* Per-channel color dot \u2014 the distinct accent each channel tab carries. */\n.s-tab__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--tab-accent);\n}\n\n/* Active tab: filled background + a colored underline in the tab's own accent. */\n.s-tab--active {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.s-tab--channel.s-tab--active {\n border-bottom-color: var(--tab-accent);\n}\n.s-tab--channel.s-tab--active .s-tab__dot {\n box-shadow: 0 0 6px var(--tab-accent);\n}\n.s-tab--channel.s-tab--active i {\n color: var(--tab-accent);\n}\n\n/* ---------- the Activity tab (right-aligned, distinct accent + pulse icon) ---------- */\n.s-tab--activity {\n color: var(--mj-text-secondary);\n}\n.s-tab--activity i {\n color: var(--activity-accent);\n}\n.s-tab--activity.s-tab--active {\n border-bottom-color: var(--activity-accent);\n background: var(--activity-accent-bg);\n color: var(--mj-text-primary);\n}\n.s-tab__badge {\n display: inline-grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--activity-accent);\n color: var(--mj-text-inverse);\n font-size: 9.5px;\n font-weight: 800;\n line-height: 1;\n flex-shrink: 0;\n}\n\n/* Brief flash for a just-revealed channel tab (the agent first acted on it). */\n.s-tab--flash {\n animation: tab-flash 1.4s ease;\n}\n@keyframes tab-flash {\n 0% {\n background: color-mix(in srgb, var(--tab-accent) 30%, transparent);\n border-bottom-color: var(--tab-accent);\n color: var(--mj-text-primary);\n }\n 60% {\n background: color-mix(in srgb, var(--tab-accent) 16%, transparent);\n border-bottom-color: var(--tab-accent);\n }\n 100% {\n background: var(--mj-bg-surface);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .s-tab--flash {\n animation: none;\n background: color-mix(in srgb, var(--tab-accent) 18%, transparent);\n }\n}\n\n.tabs-end {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 8px;\n flex-shrink: 0;\n}\n\n/* ---------- panes: all alive, only the active one displayed ---------- */\n.s-pane {\n display: none;\n flex: 1;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n /* Positioning context for the first-run channel-onboarding overlay (absolute, inset:0). */\n position: relative;\n}\n.s-pane--active {\n display: flex;\n}\n/* Where a channel's surface shows: the overlay's stage lays the surface over this box. */\n.s-pane__slot {\n flex: 1;\n min-height: 0;\n}\n\n/* A channel whose surface the user moved elsewhere: where it is, and a way back. */\n.s-pane__away {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 24px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n.s-pane__away > i {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n/* \"Move to\u2026\" beside the active channel tab. */\n.s-tab-move {\n align-self: center;\n margin: 0 4px 0 -4px;\n}\n\n/* Empty strip (idle voice-first session): a gentle hint rather than a bare grid. */\n.surface__empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 500;\n padding: 24px;\n text-align: center;\n}\n.surface__empty i {\n font-size: 20px;\n color: var(--activity-accent);\n opacity: 0.6;\n}\n\n/* Channel slot placeholder (\"Whiteboard coming online\u2026\") */\n.channel-placeholder {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 12.5px;\n font-weight: 600;\n padding: 24px;\n text-align: center;\n}\n.channel-placeholder i {\n font-size: 22px;\n color: var(--tab-accent);\n opacity: 0.7;\n}\n\n/* On narrow widths the panel stacks out of the way (overlay falls back to single column) */\n@media (max-width: 860px) {\n .surface {\n display: none;\n }\n}\n"] }]
492
634
  }], null, { State: [{
493
635
  type: Input,
494
636
  args: [{ required: true }]
@@ -510,9 +652,26 @@ export class RealtimeSurfaceTabsComponent {
510
652
  type: Output
511
653
  }], WideChanged: [{
512
654
  type: Output
655
+ }], ActiveChannelChange: [{
656
+ type: Output
657
+ }], ChannelSlotChange: [{
658
+ type: Output
659
+ }], SurfacePlacements: [{
660
+ type: Input
661
+ }], AllowedPlacements: [{
662
+ type: Input
663
+ }], MoveRequested: [{
664
+ type: Output
665
+ }], ResetLayoutRequested: [{
666
+ type: Output
667
+ }], Collapsed: [{
668
+ type: Input
513
669
  }], activityRail: [{
514
670
  type: ViewChild,
515
671
  args: [RealtimeActivityRailComponent]
672
+ }], channelSlots: [{
673
+ type: ViewChildren,
674
+ args: ['channelSlot']
516
675
  }] }); })();
517
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSurfaceTabsComponent, { className: "RealtimeSurfaceTabsComponent", filePath: "src/lib/components/realtime/realtime-surface-tabs.component.ts", lineNumber: 62 }); })();
676
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSurfaceTabsComponent, { className: "RealtimeSurfaceTabsComponent", filePath: "src/lib/components/realtime/realtime-surface-tabs.component.ts", lineNumber: 87 }); })();
518
677
  //# sourceMappingURL=realtime-surface-tabs.component.js.map