@memberjunction/ng-dashboards 6.2.0-edge.6 → 6.2.0-edge.8

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 (233) hide show
  1. package/README.md +23 -16
  2. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js +2 -2
  3. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js.map +1 -1
  4. package/dist/AI/components/analytics/realtime/realtime-management.component.d.ts.map +1 -1
  5. package/dist/AI/components/analytics/realtime/realtime-management.component.js +3 -1
  6. package/dist/AI/components/analytics/realtime/realtime-management.component.js.map +1 -1
  7. package/dist/AI/components/analytics/realtime/realtime-overview.component.d.ts +1 -1
  8. package/dist/AI/components/analytics/realtime/realtime-overview.component.js +3 -3
  9. package/dist/AI/components/analytics/realtime/realtime-overview.component.js.map +1 -1
  10. package/dist/AI/components/analytics/realtime/realtime-session-data.d.ts +6 -4
  11. package/dist/AI/components/analytics/realtime/realtime-session-data.d.ts.map +1 -1
  12. package/dist/AI/components/analytics/realtime/realtime-session-data.js +8 -2
  13. package/dist/AI/components/analytics/realtime/realtime-session-data.js.map +1 -1
  14. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  15. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +31 -10
  16. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  17. package/dist/AI/components/autotagging/components/classify-item-grid.component.js +1 -1
  18. package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -1
  19. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -1
  20. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +1 -0
  21. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -1
  22. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -1
  23. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +1 -0
  24. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -1
  25. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -1
  26. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1 -0
  27. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -1
  28. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  29. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +1 -0
  30. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  31. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
  32. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  33. package/dist/AI/components/tags/tags-resource.component.js +14 -24
  34. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  35. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  36. package/dist/AI/components/vectors/vector-management-resource.component.js +14 -7
  37. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  38. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  39. package/dist/AI/services/ai-instrumentation.service.js +4 -2
  40. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  41. package/dist/Actions/action-result-code.d.ts +80 -0
  42. package/dist/Actions/action-result-code.d.ts.map +1 -0
  43. package/dist/Actions/action-result-code.js +163 -0
  44. package/dist/Actions/action-result-code.js.map +1 -0
  45. package/dist/Actions/components/actions-overview.component.d.ts +8 -0
  46. package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
  47. package/dist/Actions/components/actions-overview.component.js +12 -9
  48. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  49. package/dist/Actions/components/execution-monitoring.component.d.ts +29 -9
  50. package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
  51. package/dist/Actions/components/execution-monitoring.component.js +65 -42
  52. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  53. package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -1
  54. package/dist/Actions/components/explorer/action-card.component.js +5 -4
  55. package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
  56. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts +92 -130
  57. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts.map +1 -1
  58. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js +189 -274
  59. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js.map +1 -1
  60. package/dist/ChiefOfStaff/chief-of-staff-approvals.component.d.ts +29 -0
  61. package/dist/ChiefOfStaff/chief-of-staff-approvals.component.d.ts.map +1 -0
  62. package/dist/ChiefOfStaff/chief-of-staff-approvals.component.js +666 -0
  63. package/dist/ChiefOfStaff/chief-of-staff-approvals.component.js.map +1 -0
  64. package/dist/ChiefOfStaff/chief-of-staff-governance.component.d.ts +56 -0
  65. package/dist/ChiefOfStaff/chief-of-staff-governance.component.d.ts.map +1 -0
  66. package/dist/ChiefOfStaff/chief-of-staff-governance.component.js +515 -0
  67. package/dist/ChiefOfStaff/chief-of-staff-governance.component.js.map +1 -0
  68. package/dist/ChiefOfStaff/chief-of-staff-live-refresh.d.ts +14 -0
  69. package/dist/ChiefOfStaff/chief-of-staff-live-refresh.d.ts.map +1 -0
  70. package/dist/ChiefOfStaff/chief-of-staff-live-refresh.js +39 -0
  71. package/dist/ChiefOfStaff/chief-of-staff-live-refresh.js.map +1 -0
  72. package/dist/ChiefOfStaff/chief-of-staff-overview.component.d.ts +17 -0
  73. package/dist/ChiefOfStaff/chief-of-staff-overview.component.d.ts.map +1 -0
  74. package/dist/ChiefOfStaff/chief-of-staff-overview.component.js +485 -0
  75. package/dist/ChiefOfStaff/chief-of-staff-overview.component.js.map +1 -0
  76. package/dist/ChiefOfStaff/chief-of-staff-page-base.d.ts +139 -0
  77. package/dist/ChiefOfStaff/chief-of-staff-page-base.d.ts.map +1 -0
  78. package/dist/ChiefOfStaff/chief-of-staff-page-base.js +602 -0
  79. package/dist/ChiefOfStaff/chief-of-staff-page-base.js.map +1 -0
  80. package/dist/ChiefOfStaff/index.d.ts +4 -1
  81. package/dist/ChiefOfStaff/index.d.ts.map +1 -1
  82. package/dist/ChiefOfStaff/index.js +4 -1
  83. package/dist/ChiefOfStaff/index.js.map +1 -1
  84. package/dist/Communication/communication-monitor-resource.component.js +3 -3
  85. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  86. package/dist/Communication/communication-runs-resource.component.js +3 -3
  87. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  88. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  89. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
  90. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  91. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
  92. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -1
  93. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  94. package/dist/ComponentStudio/services/component-version.service.d.ts.map +1 -1
  95. package/dist/ComponentStudio/services/component-version.service.js +3 -0
  96. package/dist/ComponentStudio/services/component-version.service.js.map +1 -1
  97. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +21 -2
  98. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  99. package/dist/DataExplorer/data-explorer-dashboard.component.js +32 -5
  100. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  101. package/dist/DevTools/graphql-console.component.js +2 -2
  102. package/dist/DevTools/lazy-module-status.component.js +2 -2
  103. package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
  104. package/dist/FormBuilder/form-builder-resource.component.js +5 -0
  105. package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
  106. package/dist/Integration/components/connections/connections.component.js +2 -2
  107. package/dist/Integration/services/integration-data.service.d.ts +1 -1
  108. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  109. package/dist/Integration/services/integration-data.service.js +4 -3
  110. package/dist/Integration/services/integration-data.service.js.map +1 -1
  111. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  112. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +11 -3
  113. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  114. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +16 -16
  115. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  116. package/dist/KnowledgeHub/components/visualize/semantic-graph/semantic-graph-explorer.component.d.ts +113 -0
  117. package/dist/KnowledgeHub/components/visualize/semantic-graph/semantic-graph-explorer.component.d.ts.map +1 -0
  118. package/dist/KnowledgeHub/components/visualize/semantic-graph/semantic-graph-explorer.component.js +1184 -0
  119. package/dist/KnowledgeHub/components/visualize/semantic-graph/semantic-graph-explorer.component.js.map +1 -0
  120. package/dist/KnowledgeHub/components/visualize/visualize-agent-context.d.ts +1 -1
  121. package/dist/KnowledgeHub/components/visualize/visualize-agent-context.d.ts.map +1 -1
  122. package/dist/KnowledgeHub/components/visualize/visualize-agent-context.js +1 -1
  123. package/dist/KnowledgeHub/components/visualize/visualize-agent-context.js.map +1 -1
  124. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +1 -1
  125. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -1
  126. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +21 -10
  127. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -1
  128. package/dist/Lists/components/lists-browse-resource.component.js +1 -1
  129. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  130. package/dist/Lists/components/lists-my-lists-resource.component.js +1 -1
  131. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  132. package/dist/LoginStudio/login-studio-resource.component.d.ts.map +1 -1
  133. package/dist/LoginStudio/login-studio-resource.component.js +1 -0
  134. package/dist/LoginStudio/login-studio-resource.component.js.map +1 -1
  135. package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
  136. package/dist/PredictiveStudio/components/ps-experiments.component.js +1 -0
  137. package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
  138. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +2 -2
  139. package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -1
  140. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +3 -0
  141. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -1
  142. package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts.map +1 -1
  143. package/dist/PredictiveStudio/engine/predictive-studio.engine.js +1 -0
  144. package/dist/PredictiveStudio/engine/predictive-studio.engine.js.map +1 -1
  145. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
  146. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +1 -0
  147. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
  148. package/dist/QueryBrowser/query-browser-resource.component.d.ts +26 -0
  149. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  150. package/dist/QueryBrowser/query-browser-resource.component.js +375 -252
  151. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  152. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  153. package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -2
  154. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  155. package/dist/UserRoutines/user-routines-resource.component.d.ts +8 -1
  156. package/dist/UserRoutines/user-routines-resource.component.d.ts.map +1 -1
  157. package/dist/UserRoutines/user-routines-resource.component.js +22 -4
  158. package/dist/UserRoutines/user-routines-resource.component.js.map +1 -1
  159. package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
  160. package/dist/VersionHistory/components/diff-resource.component.js +1 -0
  161. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  162. package/dist/VideoStudio/components/vs-archetype-editor.component.d.ts +162 -0
  163. package/dist/VideoStudio/components/vs-archetype-editor.component.d.ts.map +1 -0
  164. package/dist/VideoStudio/components/vs-archetype-editor.component.js +1105 -0
  165. package/dist/VideoStudio/components/vs-archetype-editor.component.js.map +1 -0
  166. package/dist/VideoStudio/components/vs-audio-options.component.d.ts +27 -0
  167. package/dist/VideoStudio/components/vs-audio-options.component.d.ts.map +1 -0
  168. package/dist/VideoStudio/components/vs-audio-options.component.js +119 -0
  169. package/dist/VideoStudio/components/vs-audio-options.component.js.map +1 -0
  170. package/dist/VideoStudio/components/vs-copilot-panel.component.d.ts +105 -0
  171. package/dist/VideoStudio/components/vs-copilot-panel.component.d.ts.map +1 -0
  172. package/dist/VideoStudio/components/vs-copilot-panel.component.js +560 -0
  173. package/dist/VideoStudio/components/vs-copilot-panel.component.js.map +1 -0
  174. package/dist/VideoStudio/components/vs-production-brief.component.d.ts +163 -0
  175. package/dist/VideoStudio/components/vs-production-brief.component.d.ts.map +1 -0
  176. package/dist/VideoStudio/components/vs-production-brief.component.js +1054 -0
  177. package/dist/VideoStudio/components/vs-production-brief.component.js.map +1 -0
  178. package/dist/VideoStudio/components/vs-setup-health-card.component.d.ts +43 -0
  179. package/dist/VideoStudio/components/vs-setup-health-card.component.d.ts.map +1 -0
  180. package/dist/VideoStudio/components/vs-setup-health-card.component.js +412 -0
  181. package/dist/VideoStudio/components/vs-setup-health-card.component.js.map +1 -0
  182. package/dist/VideoStudio/components/vs-studio-slide-in.component.d.ts +73 -0
  183. package/dist/VideoStudio/components/vs-studio-slide-in.component.d.ts.map +1 -0
  184. package/dist/VideoStudio/components/vs-studio-slide-in.component.js +271 -0
  185. package/dist/VideoStudio/components/vs-studio-slide-in.component.js.map +1 -0
  186. package/dist/VideoStudio/index.d.ts +12 -0
  187. package/dist/VideoStudio/index.d.ts.map +1 -0
  188. package/dist/VideoStudio/index.js +12 -0
  189. package/dist/VideoStudio/index.js.map +1 -0
  190. package/dist/VideoStudio/resources/video-studio-archetypes-resource.component.d.ts +118 -0
  191. package/dist/VideoStudio/resources/video-studio-archetypes-resource.component.d.ts.map +1 -0
  192. package/dist/VideoStudio/resources/video-studio-archetypes-resource.component.js +964 -0
  193. package/dist/VideoStudio/resources/video-studio-archetypes-resource.component.js.map +1 -0
  194. package/dist/VideoStudio/resources/video-studio-brand-kits-resource.component.d.ts +70 -0
  195. package/dist/VideoStudio/resources/video-studio-brand-kits-resource.component.d.ts.map +1 -0
  196. package/dist/VideoStudio/resources/video-studio-brand-kits-resource.component.js +600 -0
  197. package/dist/VideoStudio/resources/video-studio-brand-kits-resource.component.js.map +1 -0
  198. package/dist/VideoStudio/resources/video-studio-productions-resource.component.d.ts +182 -0
  199. package/dist/VideoStudio/resources/video-studio-productions-resource.component.d.ts.map +1 -0
  200. package/dist/VideoStudio/resources/video-studio-productions-resource.component.js +1481 -0
  201. package/dist/VideoStudio/resources/video-studio-productions-resource.component.js.map +1 -0
  202. package/dist/VideoStudio/services/vs-studio-slide-in-state.service.d.ts +102 -0
  203. package/dist/VideoStudio/services/vs-studio-slide-in-state.service.d.ts.map +1 -0
  204. package/dist/VideoStudio/services/vs-studio-slide-in-state.service.js +240 -0
  205. package/dist/VideoStudio/services/vs-studio-slide-in-state.service.js.map +1 -0
  206. package/dist/VideoStudio/video-studio-agent-context.d.ts +495 -0
  207. package/dist/VideoStudio/video-studio-agent-context.d.ts.map +1 -0
  208. package/dist/VideoStudio/video-studio-agent-context.js +992 -0
  209. package/dist/VideoStudio/video-studio-agent-context.js.map +1 -0
  210. package/dist/ai-dashboards.module.d.ts +46 -41
  211. package/dist/ai-dashboards.module.d.ts.map +1 -1
  212. package/dist/ai-dashboards.module.js +33 -7
  213. package/dist/ai-dashboards.module.js.map +1 -1
  214. package/dist/module.d.ts +13 -12
  215. package/dist/module.d.ts.map +1 -1
  216. package/dist/module.js +7 -0
  217. package/dist/module.js.map +1 -1
  218. package/dist/public-api.d.ts +8 -1
  219. package/dist/public-api.d.ts.map +1 -1
  220. package/dist/public-api.js +10 -2
  221. package/dist/public-api.js.map +1 -1
  222. package/dist/shared/action-scheduled-job.d.ts.map +1 -1
  223. package/dist/shared/action-scheduled-job.js +2 -0
  224. package/dist/shared/action-scheduled-job.js.map +1 -1
  225. package/dist/video-studio-dashboards.module.d.ts +40 -0
  226. package/dist/video-studio-dashboards.module.d.ts.map +1 -0
  227. package/dist/video-studio-dashboards.module.js +159 -0
  228. package/dist/video-studio-dashboards.module.js.map +1 -0
  229. package/package.json +78 -71
  230. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts +0 -195
  231. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts.map +0 -1
  232. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js +0 -2910
  233. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-management.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/realtime/realtime-management.component.ts","../../../../../src/AI/components/analytics/realtime/realtime-management.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Realtime management section — the whole realtime + bridge\n * surface (§11b of the Realtime Bridges architecture) in one place.\n *\n * Hosts an internal sub-tab rail across seven surfaces:\n * 1. Live Sessions — active session bridges (Connecting/Connected) joined\n * with their session: agent, provider, turn mode,\n * participant count, started-at.\n * 2. Bridge Providers — the platform registry with a compact capability\n * summary derived from `SupportedFeaturesObject`.\n * 3. Agent Identities — which agents are reachable where (mailboxes, numbers).\n * 4. Channels — the `MJ: AI Agent Channels` registry + which providers\n * contribute them.\n * 5. Co-Agents — the `MJ: AI Agent Co Agents` pairing registry.\n * 6. Session History — closed/terminal session bridges with close reason.\n * 7. Metrics — client-side aggregates (by provider / status / agent;\n * bridges-over-time bucketed per day).\n *\n * Read-only for v1. Data loads once per `TimeRange` change via one batched\n * `RunViews` in {@link LoadRealtimeManagementDataset}; everything else is\n * in-memory aggregation. The selected sub-tab persists via `UserInfoEngine`\n * under `mj.realtimeDashboard.subTab`.\n */\n\nimport { Component, ChangeDetectionStrategy, Input, OnInit, ChangeDetectorRef, inject } from '@angular/core';\nimport { CompositeKey } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { TabConfig } from '@memberjunction/ng-ui-components';\nimport {\n RealtimeManagementDataset, LoadRealtimeManagementDataset,\n BridgeProviderRollup, SessionBridgeRollup, BridgeAgentIdentityRecord,\n AgentChannelRecord, BridgeProviderChannelRecord, AgentCoAgentRecord,\n SessionBridgeDayBucket, MetricSlice,\n BucketSessionBridgesByDay, SummarizeBridgesByProvider,\n SummarizeBridgesByStatus, SummarizeBridgesByAgent,\n BuildCapabilityChips, CapabilityChip, BridgeTypeIcon, IdentityTypeIcon,\n TransportTypeIcon, FormatBridgeDuration, FormatBridgeStart\n} from './realtime-management-data';\n\n/** The seven management sub-tabs. */\ntype RealtimeSubTab =\n | 'live-sessions' | 'providers' | 'identities'\n | 'channels' | 'co-agents' | 'history' | 'metrics';\n\ninterface SubTabDef {\n Key: RealtimeSubTab;\n Label: string;\n Icon: string;\n}\n\n/** Persisted preferences shape (UserInfoEngine: `mj.realtimeDashboard.*`). */\ninterface RealtimeManagementPrefs {\n subTab?: RealtimeSubTab;\n}\n\nconst SUB_TAB_PREF_KEY = 'mj.realtimeDashboard.subTab';\n\n@Component({\n standalone: false,\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'app-realtime-management',\n templateUrl: './realtime-management.component.html',\n styleUrls: ['./realtime-management.component.css']\n})\nexport class RealtimeManagementComponent extends BaseAngularComponent implements OnInit {\n // ── Inputs ──\n\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n // ── State ──\n\n private initialized = false;\n private cdr = inject(ChangeDetectorRef);\n private dataset: RealtimeManagementDataset | null = null;\n\n public IsLoading = false;\n public ActiveSubTab: RealtimeSubTab = 'live-sessions';\n\n public readonly SubTabs: SubTabDef[] = [\n { Key: 'live-sessions', Label: 'Live Sessions', Icon: 'fa-solid fa-tower-broadcast' },\n { Key: 'providers', Label: 'Bridge Providers', Icon: 'fa-solid fa-network-wired' },\n { Key: 'identities', Label: 'Agent Identities', Icon: 'fa-solid fa-id-badge' },\n { Key: 'channels', Label: 'Channels', Icon: 'fa-solid fa-satellite-dish' },\n { Key: 'co-agents', Label: 'Co-Agents', Icon: 'fa-solid fa-people-arrows' },\n { Key: 'history', Label: 'Session History', Icon: 'fa-solid fa-clock-rotate-left' },\n { Key: 'metrics', Label: 'Metrics', Icon: 'fa-solid fa-chart-column' }\n ];\n\n /** The same sub-tabs in the shape `<mj-tab-nav>` renders. */\n public readonly SubTabConfigs: TabConfig[] = this.SubTabs.map(t => ({ key: t.Key, label: t.Label, icon: t.Icon }));\n\n // ── View models (rebuilt on load) ──\n\n public LiveBridges: SessionBridgeRollup[] = [];\n public HistoryBridges: SessionBridgeRollup[] = [];\n public Providers: BridgeProviderRollup[] = [];\n public Identities: BridgeAgentIdentityRecord[] = [];\n public Channels: AgentChannelRecord[] = [];\n public ProviderChannels: BridgeProviderChannelRecord[] = [];\n public CoAgents: AgentCoAgentRecord[] = [];\n\n // Metrics\n public DayBuckets: SessionBridgeDayBucket[] = [];\n public ByProvider: MetricSlice[] = [];\n public ByStatus: MetricSlice[] = [];\n public ByAgent: MetricSlice[] = [];\n\n // ── Provider capability summary cache (chips + remainder) ──\n private capabilityChips = new Map<string, CapabilityChip[]>();\n\n // ── Lifecycle ──\n\n async ngOnInit(): Promise<void> {\n this.loadPrefs();\n this.initialized = true;\n await this.LoadData();\n }\n\n // ── Sub-tab navigation ──\n\n /** `(TabChange)` handler: `mj-tab-nav` emits a plain string, so accept only a known sub-tab key. */\n public OnSubTabChange(key: string): void {\n const match = this.SubTabs.find(t => t.Key === key);\n if (match) this.SelectSubTab(match.Key);\n }\n\n public SelectSubTab(key: RealtimeSubTab): void {\n if (key === this.ActiveSubTab) return;\n this.ActiveSubTab = key;\n this.savePrefs();\n this.cdr.detectChanges();\n }\n\n // ── Data loading ──\n\n /** Reloads the whole management surface for the current time range. */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n this.dataset = await LoadRealtimeManagementDataset(this.ProviderToUse, this.TimeRange);\n this.applyDataset(this.dataset);\n } catch (e) {\n console.error('Realtime management load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private applyDataset(ds: RealtimeManagementDataset): void {\n this.LiveBridges = ds.LiveBridges;\n this.HistoryBridges = ds.HistoryBridges;\n this.Providers = ds.Providers;\n this.Identities = ds.Identities;\n this.Channels = ds.Channels;\n this.ProviderChannels = ds.ProviderChannels;\n this.CoAgents = ds.CoAgents;\n\n this.capabilityChips.clear();\n for (const p of ds.Providers) {\n this.capabilityChips.set(p.Record.ID, BuildCapabilityChips(p.Features));\n }\n\n this.DayBuckets = BucketSessionBridgesByDay(ds.AllBridges, ds.WindowStart, new Date());\n this.ByProvider = SummarizeBridgesByProvider(ds.AllBridges);\n this.ByStatus = SummarizeBridgesByStatus(ds.AllBridges);\n this.ByAgent = SummarizeBridgesByAgent(ds.AllBridges);\n }\n\n // ── Drill-in ──\n\n /** Opens the AIAgentSession record behind a bridge via the shared record-open path. */\n public OpenSession(sessionId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', CompositeKey.FromID(sessionId));\n }\n\n /** Opens a bridge provider record. */\n public OpenProvider(providerId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Bridge Providers', CompositeKey.FromID(providerId));\n }\n\n // ── Capability summary accessors (template helpers) ──\n\n /** First N capability chips for a provider (kept compact in the grid). */\n public CapabilityChipsFor(providerId: string, limit = 4): CapabilityChip[] {\n return (this.capabilityChips.get(providerId) ?? []).slice(0, limit);\n }\n\n /** Count of capability chips beyond the displayed `limit` (for a \"+N\" pill). */\n public CapabilityOverflowFor(providerId: string, limit = 4): number {\n const total = this.capabilityChips.get(providerId)?.length ?? 0;\n return Math.max(0, total - limit);\n }\n\n // ── Channel surface helpers ──\n\n /** Providers contributing a given channel (for the Channels grid). */\n public ProvidersForChannel(channelId: string): BridgeProviderChannelRecord[] {\n const target = channelId.toLowerCase();\n return this.ProviderChannels.filter(pc => pc.ChannelID.toLowerCase() === target);\n }\n\n // ── Co-agent helpers ──\n\n /** Human-readable pairing target — a specific agent or a whole agent type. */\n public CoAgentTargetLabel(row: AgentCoAgentRecord): string {\n if (row.TargetAgent) return row.TargetAgent;\n if (row.TargetAgentType) return `Type: ${row.TargetAgentType}`;\n return '—';\n }\n\n // ── Metric rendering helpers ──\n\n /** Max count across day buckets (for bar height scaling); min 1 to avoid /0. */\n public get MaxDayCount(): number {\n return Math.max(1, ...this.DayBuckets.map(b => b.Count));\n }\n\n /** Bar height percentage for a day bucket. */\n public DayBarHeight(count: number): number {\n return Math.round((count / this.MaxDayCount) * 100);\n }\n\n /** Max slice count (for horizontal bar scaling); min 1. */\n public MaxSlice(slices: MetricSlice[]): number {\n return Math.max(1, ...slices.map(s => s.Count));\n }\n\n /** @deprecated Use {@link MaxSlice}. */\n public maxSlice(slices: MetricSlice[]): number {\n return this.MaxSlice(slices);\n }\n\n /** Bar width percentage for a metric slice. */\n public SliceBarWidth(slices: MetricSlice[], count: number): number {\n return Math.round((count / this.MaxSlice(slices)) * 100);\n }\n\n // ── Summary getters ──\n\n public get LiveCount(): number { return this.LiveBridges.length; }\n public get HistoryCount(): number { return this.HistoryBridges.length; }\n public get ActiveProviderCount(): number {\n return this.Providers.filter(p => p.Record.Status === 'Active').length;\n }\n public get ActiveIdentityCount(): number {\n return this.Identities.filter(i => i.IsActive).length;\n }\n public get ActiveCoAgentCount(): number {\n return this.CoAgents.filter(c => c.Status === 'Active').length;\n }\n\n // ── Pure presentation helpers (delegated to the data module) ──\n\n public BridgeTypeIcon = BridgeTypeIcon;\n public IdentityTypeIcon = IdentityTypeIcon;\n public TransportTypeIcon = TransportTypeIcon;\n public FormatBridgeDuration = FormatBridgeDuration;\n public FormatBridgeStart = FormatBridgeStart;\n\n /** CSS class for a bridge status pill. */\n public BridgeStatusClass(status: string): string {\n switch (status) {\n case 'Connected': return 'status-pill status-connected';\n case 'Connecting':\n case 'Pending':\n case 'Scheduled': return 'status-pill status-pending';\n case 'Disconnecting': return 'status-pill status-pending';\n case 'Failed': return 'status-pill status-failed';\n default: return 'status-pill status-closed';\n }\n }\n\n /** CSS class for a session-bridge close-reason pill. */\n public CloseReasonClass(reason: string | null): string {\n switch (reason) {\n case 'Error': return 'reason-pill reason-error';\n case 'Janitor': return 'reason-pill reason-janitor';\n case 'HostEnded': return 'reason-pill reason-hostended';\n case 'Shutdown': return 'reason-pill reason-shutdown';\n case 'Explicit': return 'reason-pill reason-explicit';\n default: return 'reason-pill reason-unknown';\n }\n }\n\n // ── Preferences ──\n\n private loadPrefs(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(SUB_TAB_PREF_KEY);\n if (raw) {\n const prefs = JSON.parse(raw) as RealtimeManagementPrefs;\n if (prefs.subTab && this.SubTabs.some(t => t.Key === prefs.subTab)) {\n this.ActiveSubTab = prefs.subTab;\n }\n }\n } catch {\n // Use defaults on parse failure.\n }\n }\n\n private savePrefs(): void {\n const prefs: RealtimeManagementPrefs = { subTab: this.ActiveSubTab };\n UserInfoEngine.Instance.SetSettingDebounced(SUB_TAB_PREF_KEY, JSON.stringify(prefs));\n }\n}\n\nexport function LoadRealtimeManagement() { /* tree-shaking prevention */ }\n","@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading realtime surface...\"></mj-loading>\n </div>\n} @else {\n <!-- Sub-tab rail + refresh -->\n <div class=\"subtab-bar\">\n <mj-tab-nav class=\"subtab-nav\" [Tabs]=\"SubTabConfigs\" [ActiveKey]=\"ActiveSubTab\"\n (TabChange)=\"OnSubTabChange($event)\"></mj-tab-nav>\n <mj-refresh-button [Loading]=\"IsLoading\" [ShowLabel]=\"false\" Title=\"Refresh realtime surface\"\n (Clicked)=\"LoadData()\"></mj-refresh-button>\n </div>\n\n @switch (ActiveSubTab) {\n\n <!-- ═══════════════════════════ LIVE SESSIONS ═══════════════════════════ -->\n @case ('live-sessions') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Direction</th>\n <th>Turn mode</th>\n <th class=\"th-numeric\">Participants</th>\n <th>Status</th>\n <th>Started</th>\n <th>Host instance</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @if (LiveBridges.length === 0) {\n <tr><td colspan=\"9\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No live bridged sessions right now\" />\n </td></tr>\n }\n @for (b of LiveBridges; track b.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenSession(b.Record.AgentSessionID)\">\n <td class=\"cell-strong\">{{ b.AgentName }}</td>\n <td>{{ b.Record.Provider }}</td>\n <td>\n <span class=\"dir-pill\">\n <i class=\"fa-solid\"\n [class.fa-arrow-right-from-bracket]=\"b.Record.Direction === 'Outbound'\"\n [class.fa-arrow-right-to-bracket]=\"b.Record.Direction === 'Inbound'\"></i>\n {{ b.Record.Direction }}\n </span>\n </td>\n <td>{{ b.Record.TurnMode }}</td>\n <td class=\"cell-numeric\">{{ b.ParticipantCount }}</td>\n <td>\n <span [class]=\"BridgeStatusClass(b.Record.Status)\">\n @if (b.Record.Status === 'Connected') { <span class=\"dot dot--live\"></span> }\n {{ b.Record.Status }}\n </span>\n </td>\n <td class=\"cell-time\">{{ FormatBridgeStart(b.StartedAt) }}</td>\n <td class=\"cell-host mono\" [title]=\"b.Record.HostInstanceID || ''\">{{ b.Record.HostInstanceID || '—' }}</td>\n <td class=\"cell-action\">\n <!-- TODO(v1+): replace with the observer-console deep link (§1 read-only monitor). -->\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(b.Record.AgentSessionID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ LiveCount }} live bridge{{ LiveCount === 1 ? '' : 's' }}</span>\n </div>\n }\n\n <!-- ═══════════════════════════ BRIDGE PROVIDERS ═══════════════════════════ -->\n @case ('providers') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Provider</th>\n <th>Type</th>\n <th>Status</th>\n <th>Driver class</th>\n <th>Capabilities</th>\n <th class=\"th-numeric\">Channels</th>\n </tr>\n </thead>\n <tbody>\n @if (Providers.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No bridge providers registered\" />\n </td></tr>\n }\n @for (p of Providers; track p.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenProvider(p.Record.ID)\">\n <td>\n <div class=\"cell-strong\">\n <i [class]=\"BridgeTypeIcon(p.Record.BridgeType)\" class=\"type-icon\"></i>\n {{ p.Record.Name }}\n </div>\n @if (p.Record.Description) {\n <div class=\"cell-sub\">{{ p.Record.Description }}</div>\n }\n </td>\n <td>{{ p.Record.BridgeType }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"p.Record.Status === 'Active'\"\n [class.status-closed]=\"p.Record.Status !== 'Active'\">\n {{ p.Record.Status }}\n </span>\n </td>\n <td class=\"mono cell-host\" [title]=\"p.Record.DriverClass\">{{ p.Record.DriverClass }}</td>\n <td>\n <span class=\"cap-chips\">\n @for (chip of CapabilityChipsFor(p.Record.ID); track chip.Label) {\n <span class=\"cap-chip\" [title]=\"chip.Label\"><i [class]=\"chip.Icon\"></i></span>\n }\n @if (CapabilityOverflowFor(p.Record.ID) > 0) {\n <span class=\"cap-more\">+{{ CapabilityOverflowFor(p.Record.ID) }}</span>\n }\n @if (p.FeatureCount === 0) {\n <span class=\"cell-muted\">none declared</span>\n }\n </span>\n </td>\n <td class=\"cell-numeric\">{{ p.Channels.length }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Providers.length }} providers · {{ ActiveProviderCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ AGENT IDENTITIES ═══════════════════════════ -->\n @case ('identities') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Identity</th>\n <th>Display name</th>\n <th>Active</th>\n </tr>\n </thead>\n <tbody>\n @if (Identities.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No agent identities provisioned\" />\n </td></tr>\n }\n @for (id of Identities; track id.ID) {\n <tr class=\"data-row\">\n <td class=\"cell-strong\">{{ id.Agent || 'Unknown agent' }}</td>\n <td>{{ id.Provider }}</td>\n <td>\n <span class=\"type-chip\"><i [class]=\"IdentityTypeIcon(id.IdentityType)\"></i> {{ id.IdentityType }}</span>\n </td>\n <td class=\"mono\">{{ id.IdentityValue }}</td>\n <td class=\"cell-muted\">{{ id.DisplayName || '—' }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"id.IsActive\"\n [class.status-closed]=\"!id.IsActive\">\n {{ id.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Identities.length }} identities · {{ ActiveIdentityCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ CHANNELS ═══════════════════════════ -->\n @case ('channels') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Channel</th>\n <th>Transport</th>\n <th>Active</th>\n <th>Contributed by</th>\n </tr>\n </thead>\n <tbody>\n @if (Channels.length === 0) {\n <tr><td colspan=\"4\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No channels registered\" />\n </td></tr>\n }\n @for (ch of Channels; track ch.ID) {\n <tr class=\"data-row\">\n <td>\n <div class=\"cell-strong\">{{ ch.Name }}</div>\n @if (ch.Description) { <div class=\"cell-sub\">{{ ch.Description }}</div> }\n </td>\n <td>\n <span class=\"type-chip\"><i [class]=\"TransportTypeIcon(ch.TransportType)\"></i> {{ ch.TransportType }}</span>\n </td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"ch.IsActive\"\n [class.status-closed]=\"!ch.IsActive\">\n {{ ch.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <span class=\"provider-tags\">\n @for (pc of ProvidersForChannel(ch.ID); track pc.ID) {\n <span class=\"provider-tag\" [class.provider-tag--default]=\"pc.IsDefault\"\n [title]=\"pc.IsDefault ? 'Auto-attached by default' : 'Available on demand'\">\n {{ pc.Provider }}\n @if (pc.IsDefault) { <i class=\"fa-solid fa-star\"></i> }\n </span>\n } @empty {\n <span class=\"cell-muted\">no provider contributions</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Channels.length }} channels · {{ ProviderChannels.length }} provider contributions</span>\n </div>\n }\n\n <!-- ═══════════════════════════ CO-AGENTS ═══════════════════════════ -->\n @case ('co-agents') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Co-Agent</th>\n <th>Pairs with</th>\n <th>Relationship</th>\n <th>Default</th>\n <th class=\"th-numeric\">Seq</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n @if (CoAgents.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No co-agent pairings configured\" />\n </td></tr>\n }\n @for (c of CoAgents; track c.ID) {\n <tr class=\"data-row\">\n <td class=\"cell-strong\">{{ c.CoAgent || 'Unknown' }}</td>\n <td>{{ CoAgentTargetLabel(c) }}</td>\n <td><span class=\"type-chip\">{{ c.Type }}</span></td>\n <td>\n @if (c.IsDefault) {\n <span class=\"default-pill\"><i class=\"fa-solid fa-star\"></i> default</span>\n } @else { <span class=\"cell-muted\">—</span> }\n </td>\n <td class=\"cell-numeric\">{{ c.Sequence }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"c.Status === 'Active'\"\n [class.status-closed]=\"c.Status !== 'Active'\">\n {{ c.Status }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ CoAgents.length }} pairings · {{ ActiveCoAgentCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ SESSION HISTORY ═══════════════════════════ -->\n @case ('history') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Join method</th>\n <th class=\"th-numeric\">Participants</th>\n <th class=\"th-numeric\">Duration</th>\n <th>Close reason</th>\n <th>Started</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @if (HistoryBridges.length === 0) {\n <tr><td colspan=\"8\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No closed bridges in this window\" />\n </td></tr>\n }\n @for (b of HistoryBridges; track b.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenSession(b.Record.AgentSessionID)\">\n <td class=\"cell-strong\">{{ b.AgentName }}</td>\n <td>{{ b.Record.Provider }}</td>\n <td>{{ b.Record.JoinMethod }}</td>\n <td class=\"cell-numeric\">{{ b.ParticipantCount }}</td>\n <td class=\"cell-numeric mono\">{{ FormatBridgeDuration(b.DurationMs) }}</td>\n <td>\n <span [class]=\"CloseReasonClass(b.Record.CloseReason)\">\n {{ b.Record.CloseReason || 'unknown' }}\n </span>\n </td>\n <td class=\"cell-time\">{{ FormatBridgeStart(b.StartedAt) }}</td>\n <td class=\"cell-action\">\n <!-- TODO(v1+): transcript / recording review launch (§7 review reuse). -->\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(b.Record.AgentSessionID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ HistoryCount }} closed bridge{{ HistoryCount === 1 ? '' : 's' }} ({{ TimeRange }})</span>\n </div>\n }\n\n <!-- ═══════════════════════════ METRICS ═══════════════════════════ -->\n @case ('metrics') {\n <div class=\"metrics-grid\">\n <!-- Bridges over time (per-day bars) -->\n <div class=\"metric-card metric-card--wide\">\n <div class=\"metric-title\">Bridges over time</div>\n @if (DayBuckets.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-column\"\n Title=\"No bridge activity in this window\" />\n } @else {\n <div class=\"bar-chart\">\n @for (bucket of DayBuckets; track bucket.Label) {\n <div class=\"bar-col\" [title]=\"bucket.Label + ': ' + bucket.Count\">\n <div class=\"bar-track\">\n <div class=\"bar-fill\" [style.height.%]=\"DayBarHeight(bucket.Count)\"></div>\n </div>\n <div class=\"bar-value\">{{ bucket.Count }}</div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- By provider -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By provider</div>\n @if (ByProvider.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByProvider; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByProvider, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n\n <!-- By status -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By status</div>\n @if (ByStatus.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByStatus; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByStatus, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n\n <!-- By agent -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By agent</div>\n @if (ByAgent.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByAgent; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByAgent, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n </div>\n }\n }\n}\n"]}
1
+ {"version":3,"file":"realtime-management.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/realtime/realtime-management.component.ts","../../../../../src/AI/components/analytics/realtime/realtime-management.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Realtime management section — the whole realtime + bridge\n * surface (§11b of the Realtime Bridges architecture) in one place.\n *\n * Hosts an internal sub-tab rail across seven surfaces:\n * 1. Live Sessions — active session bridges (Connecting/Connected) joined\n * with their session: agent, provider, turn mode,\n * participant count, started-at.\n * 2. Bridge Providers — the platform registry with a compact capability\n * summary derived from `SupportedFeaturesObject`.\n * 3. Agent Identities — which agents are reachable where (mailboxes, numbers).\n * 4. Channels — the `MJ: AI Agent Channels` registry + which providers\n * contribute them.\n * 5. Co-Agents — the `MJ: AI Agent Co Agents` pairing registry.\n * 6. Session History — closed/terminal session bridges with close reason.\n * 7. Metrics — client-side aggregates (by provider / status / agent;\n * bridges-over-time bucketed per day).\n *\n * Read-only for v1. Data loads once per `TimeRange` change via one batched\n * `RunViews` in {@link LoadRealtimeManagementDataset}; everything else is\n * in-memory aggregation. The selected sub-tab persists via `UserInfoEngine`\n * under `mj.realtimeDashboard.subTab`.\n */\n\nimport { Component, ChangeDetectionStrategy, Input, OnInit, ChangeDetectorRef, inject } from '@angular/core';\nimport { CompositeKey } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { TabConfig } from '@memberjunction/ng-ui-components';\nimport {\n RealtimeManagementDataset, LoadRealtimeManagementDataset,\n BridgeProviderRollup, SessionBridgeRollup, BridgeAgentIdentityRecord,\n AgentChannelRecord, BridgeProviderChannelRecord, AgentCoAgentRecord,\n SessionBridgeDayBucket, MetricSlice,\n BucketSessionBridgesByDay, SummarizeBridgesByProvider,\n SummarizeBridgesByStatus, SummarizeBridgesByAgent,\n BuildCapabilityChips, CapabilityChip, BridgeTypeIcon, IdentityTypeIcon,\n TransportTypeIcon, FormatBridgeDuration, FormatBridgeStart\n} from './realtime-management-data';\n\n/** The seven management sub-tabs. */\ntype RealtimeSubTab =\n | 'live-sessions' | 'providers' | 'identities'\n | 'channels' | 'co-agents' | 'history' | 'metrics';\n\ninterface SubTabDef {\n Key: RealtimeSubTab;\n Label: string;\n Icon: string;\n}\n\n/** Persisted preferences shape (UserInfoEngine: `mj.realtimeDashboard.*`). */\ninterface RealtimeManagementPrefs {\n subTab?: RealtimeSubTab;\n}\n\nconst SUB_TAB_PREF_KEY = 'mj.realtimeDashboard.subTab';\n\n@Component({\n standalone: false,\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'app-realtime-management',\n templateUrl: './realtime-management.component.html',\n styleUrls: ['./realtime-management.component.css']\n})\nexport class RealtimeManagementComponent extends BaseAngularComponent implements OnInit {\n // ── Inputs ──\n\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n // ── State ──\n\n private initialized = false;\n private cdr = inject(ChangeDetectorRef);\n private dataset: RealtimeManagementDataset | null = null;\n\n public IsLoading = false;\n public ActiveSubTab: RealtimeSubTab = 'live-sessions';\n\n public readonly SubTabs: SubTabDef[] = [\n { Key: 'live-sessions', Label: 'Live Sessions', Icon: 'fa-solid fa-tower-broadcast' },\n { Key: 'providers', Label: 'Bridge Providers', Icon: 'fa-solid fa-network-wired' },\n { Key: 'identities', Label: 'Agent Identities', Icon: 'fa-solid fa-id-badge' },\n { Key: 'channels', Label: 'Channels', Icon: 'fa-solid fa-satellite-dish' },\n { Key: 'co-agents', Label: 'Co-Agents', Icon: 'fa-solid fa-people-arrows' },\n { Key: 'history', Label: 'Session History', Icon: 'fa-solid fa-clock-rotate-left' },\n { Key: 'metrics', Label: 'Metrics', Icon: 'fa-solid fa-chart-column' }\n ];\n\n /** The same sub-tabs in the shape `<mj-tab-nav>` renders. */\n public readonly SubTabConfigs: TabConfig[] = this.SubTabs.map(t => ({ key: t.Key, label: t.Label, icon: t.Icon }));\n\n // ── View models (rebuilt on load) ──\n\n public LiveBridges: SessionBridgeRollup[] = [];\n public HistoryBridges: SessionBridgeRollup[] = [];\n public Providers: BridgeProviderRollup[] = [];\n public Identities: BridgeAgentIdentityRecord[] = [];\n public Channels: AgentChannelRecord[] = [];\n public ProviderChannels: BridgeProviderChannelRecord[] = [];\n public CoAgents: AgentCoAgentRecord[] = [];\n\n // Metrics\n public DayBuckets: SessionBridgeDayBucket[] = [];\n public ByProvider: MetricSlice[] = [];\n public ByStatus: MetricSlice[] = [];\n public ByAgent: MetricSlice[] = [];\n\n // ── Provider capability summary cache (chips + remainder) ──\n private capabilityChips = new Map<string, CapabilityChip[]>();\n\n // ── Lifecycle ──\n\n async ngOnInit(): Promise<void> {\n this.loadPrefs();\n this.initialized = true;\n await this.LoadData();\n }\n\n // ── Sub-tab navigation ──\n\n /** `(TabChange)` handler: `mj-tab-nav` emits a plain string, so accept only a known sub-tab key. */\n public OnSubTabChange(key: string): void {\n const match = this.SubTabs.find(t => t.Key === key);\n if (match) this.SelectSubTab(match.Key);\n }\n\n public SelectSubTab(key: RealtimeSubTab): void {\n if (key === this.ActiveSubTab) return;\n this.ActiveSubTab = key;\n this.savePrefs();\n this.cdr.detectChanges();\n }\n\n // ── Data loading ──\n\n /** Reloads the whole management surface for the current time range. */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n this.dataset = await LoadRealtimeManagementDataset(this.ProviderToUse, this.TimeRange);\n this.applyDataset(this.dataset);\n } catch (e) {\n console.error('Realtime management load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private applyDataset(ds: RealtimeManagementDataset): void {\n this.LiveBridges = ds.LiveBridges;\n this.HistoryBridges = ds.HistoryBridges;\n this.Providers = ds.Providers;\n this.Identities = ds.Identities;\n this.Channels = ds.Channels;\n this.ProviderChannels = ds.ProviderChannels;\n this.CoAgents = ds.CoAgents;\n\n this.capabilityChips.clear();\n for (const p of ds.Providers) {\n this.capabilityChips.set(p.Record.ID, BuildCapabilityChips(p.Features));\n }\n\n this.DayBuckets = BucketSessionBridgesByDay(ds.AllBridges, ds.WindowStart, new Date());\n this.ByProvider = SummarizeBridgesByProvider(ds.AllBridges);\n this.ByStatus = SummarizeBridgesByStatus(ds.AllBridges);\n this.ByAgent = SummarizeBridgesByAgent(ds.AllBridges);\n }\n\n // ── Drill-in ──\n\n /** Opens the AIAgentSession record behind a bridge via the shared record-open path. */\n public OpenSession(sessionId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', CompositeKey.FromID(sessionId));\n }\n\n /** Opens a bridge provider record. */\n public OpenProvider(providerId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Bridge Providers', CompositeKey.FromID(providerId));\n }\n\n // ── Capability summary accessors (template helpers) ──\n\n /** First N capability chips for a provider (kept compact in the grid). */\n public CapabilityChipsFor(providerId: string, limit = 4): CapabilityChip[] {\n return (this.capabilityChips.get(providerId) ?? []).slice(0, limit);\n }\n\n /** Count of capability chips beyond the displayed `limit` (for a \"+N\" pill). */\n public CapabilityOverflowFor(providerId: string, limit = 4): number {\n const total = this.capabilityChips.get(providerId)?.length ?? 0;\n return Math.max(0, total - limit);\n }\n\n // ── Channel surface helpers ──\n\n /** Providers contributing a given channel (for the Channels grid). */\n public ProvidersForChannel(channelId: string): BridgeProviderChannelRecord[] {\n const target = channelId.toLowerCase();\n return this.ProviderChannels.filter(pc => pc.ChannelID.toLowerCase() === target);\n }\n\n // ── Co-agent helpers ──\n\n /** Human-readable pairing target — a specific agent or a whole agent type. */\n public CoAgentTargetLabel(row: AgentCoAgentRecord): string {\n if (row.TargetAgent) return row.TargetAgent;\n if (row.TargetAgentType) return `Type: ${row.TargetAgentType}`;\n return '—';\n }\n\n // ── Metric rendering helpers ──\n\n /** Max count across day buckets (for bar height scaling); min 1 to avoid /0. */\n public get MaxDayCount(): number {\n return Math.max(1, ...this.DayBuckets.map(b => b.Count));\n }\n\n /** Bar height percentage for a day bucket. */\n public DayBarHeight(count: number): number {\n return Math.round((count / this.MaxDayCount) * 100);\n }\n\n /** Max slice count (for horizontal bar scaling); min 1. */\n public MaxSlice(slices: MetricSlice[]): number {\n return Math.max(1, ...slices.map(s => s.Count));\n }\n\n /** @deprecated Use {@link MaxSlice}. */\n public maxSlice(slices: MetricSlice[]): number {\n return this.MaxSlice(slices);\n }\n\n /** Bar width percentage for a metric slice. */\n public SliceBarWidth(slices: MetricSlice[], count: number): number {\n return Math.round((count / this.MaxSlice(slices)) * 100);\n }\n\n // ── Summary getters ──\n\n public get LiveCount(): number { return this.LiveBridges.length; }\n public get HistoryCount(): number { return this.HistoryBridges.length; }\n public get ActiveProviderCount(): number {\n return this.Providers.filter(p => p.Record.Status === 'Active').length;\n }\n public get ActiveIdentityCount(): number {\n return this.Identities.filter(i => i.IsActive).length;\n }\n public get ActiveCoAgentCount(): number {\n return this.CoAgents.filter(c => c.Status === 'Active').length;\n }\n\n // ── Pure presentation helpers (delegated to the data module) ──\n\n public BridgeTypeIcon = BridgeTypeIcon;\n public IdentityTypeIcon = IdentityTypeIcon;\n public TransportTypeIcon = TransportTypeIcon;\n public FormatBridgeDuration = FormatBridgeDuration;\n public FormatBridgeStart = FormatBridgeStart;\n\n /** CSS class for a bridge status pill. */\n public BridgeStatusClass(status: string): string {\n switch (status) {\n case 'Connected': return 'status-pill status-connected';\n case 'Connecting':\n case 'Pending':\n case 'Scheduled': return 'status-pill status-pending';\n case 'Disconnecting': return 'status-pill status-pending';\n case 'Failed': return 'status-pill status-failed';\n default: return 'status-pill status-closed';\n }\n }\n\n /** CSS class for a session-bridge close-reason pill. */\n public CloseReasonClass(reason: string | null): string {\n switch (reason) {\n case 'Error': return 'reason-pill reason-error';\n case 'Janitor':\n case 'TimeLimit':\n case 'Idle': return 'reason-pill reason-janitor';\n case 'HostEnded': return 'reason-pill reason-hostended';\n case 'Shutdown': return 'reason-pill reason-shutdown';\n case 'Explicit': return 'reason-pill reason-explicit';\n default: return 'reason-pill reason-unknown';\n }\n }\n\n // ── Preferences ──\n\n private loadPrefs(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(SUB_TAB_PREF_KEY);\n if (raw) {\n const prefs = JSON.parse(raw) as RealtimeManagementPrefs;\n if (prefs.subTab && this.SubTabs.some(t => t.Key === prefs.subTab)) {\n this.ActiveSubTab = prefs.subTab;\n }\n }\n } catch {\n // Use defaults on parse failure.\n }\n }\n\n private savePrefs(): void {\n const prefs: RealtimeManagementPrefs = { subTab: this.ActiveSubTab };\n UserInfoEngine.Instance.SetSettingDebounced(SUB_TAB_PREF_KEY, JSON.stringify(prefs));\n }\n}\n\nexport function LoadRealtimeManagement() { /* tree-shaking prevention */ }\n","@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading realtime surface...\"></mj-loading>\n </div>\n} @else {\n <!-- Sub-tab rail + refresh -->\n <div class=\"subtab-bar\">\n <mj-tab-nav class=\"subtab-nav\" [Tabs]=\"SubTabConfigs\" [ActiveKey]=\"ActiveSubTab\"\n (TabChange)=\"OnSubTabChange($event)\"></mj-tab-nav>\n <mj-refresh-button [Loading]=\"IsLoading\" [ShowLabel]=\"false\" Title=\"Refresh realtime surface\"\n (Clicked)=\"LoadData()\"></mj-refresh-button>\n </div>\n\n @switch (ActiveSubTab) {\n\n <!-- ═══════════════════════════ LIVE SESSIONS ═══════════════════════════ -->\n @case ('live-sessions') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Direction</th>\n <th>Turn mode</th>\n <th class=\"th-numeric\">Participants</th>\n <th>Status</th>\n <th>Started</th>\n <th>Host instance</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @if (LiveBridges.length === 0) {\n <tr><td colspan=\"9\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No live bridged sessions right now\" />\n </td></tr>\n }\n @for (b of LiveBridges; track b.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenSession(b.Record.AgentSessionID)\">\n <td class=\"cell-strong\">{{ b.AgentName }}</td>\n <td>{{ b.Record.Provider }}</td>\n <td>\n <span class=\"dir-pill\">\n <i class=\"fa-solid\"\n [class.fa-arrow-right-from-bracket]=\"b.Record.Direction === 'Outbound'\"\n [class.fa-arrow-right-to-bracket]=\"b.Record.Direction === 'Inbound'\"></i>\n {{ b.Record.Direction }}\n </span>\n </td>\n <td>{{ b.Record.TurnMode }}</td>\n <td class=\"cell-numeric\">{{ b.ParticipantCount }}</td>\n <td>\n <span [class]=\"BridgeStatusClass(b.Record.Status)\">\n @if (b.Record.Status === 'Connected') { <span class=\"dot dot--live\"></span> }\n {{ b.Record.Status }}\n </span>\n </td>\n <td class=\"cell-time\">{{ FormatBridgeStart(b.StartedAt) }}</td>\n <td class=\"cell-host mono\" [title]=\"b.Record.HostInstanceID || ''\">{{ b.Record.HostInstanceID || '—' }}</td>\n <td class=\"cell-action\">\n <!-- TODO(v1+): replace with the observer-console deep link (§1 read-only monitor). -->\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(b.Record.AgentSessionID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ LiveCount }} live bridge{{ LiveCount === 1 ? '' : 's' }}</span>\n </div>\n }\n\n <!-- ═══════════════════════════ BRIDGE PROVIDERS ═══════════════════════════ -->\n @case ('providers') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Provider</th>\n <th>Type</th>\n <th>Status</th>\n <th>Driver class</th>\n <th>Capabilities</th>\n <th class=\"th-numeric\">Channels</th>\n </tr>\n </thead>\n <tbody>\n @if (Providers.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No bridge providers registered\" />\n </td></tr>\n }\n @for (p of Providers; track p.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenProvider(p.Record.ID)\">\n <td>\n <div class=\"cell-strong\">\n <i [class]=\"BridgeTypeIcon(p.Record.BridgeType)\" class=\"type-icon\"></i>\n {{ p.Record.Name }}\n </div>\n @if (p.Record.Description) {\n <div class=\"cell-sub\">{{ p.Record.Description }}</div>\n }\n </td>\n <td>{{ p.Record.BridgeType }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"p.Record.Status === 'Active'\"\n [class.status-closed]=\"p.Record.Status !== 'Active'\">\n {{ p.Record.Status }}\n </span>\n </td>\n <td class=\"mono cell-host\" [title]=\"p.Record.DriverClass\">{{ p.Record.DriverClass }}</td>\n <td>\n <span class=\"cap-chips\">\n @for (chip of CapabilityChipsFor(p.Record.ID); track chip.Label) {\n <span class=\"cap-chip\" [title]=\"chip.Label\"><i [class]=\"chip.Icon\"></i></span>\n }\n @if (CapabilityOverflowFor(p.Record.ID) > 0) {\n <span class=\"cap-more\">+{{ CapabilityOverflowFor(p.Record.ID) }}</span>\n }\n @if (p.FeatureCount === 0) {\n <span class=\"cell-muted\">none declared</span>\n }\n </span>\n </td>\n <td class=\"cell-numeric\">{{ p.Channels.length }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Providers.length }} providers · {{ ActiveProviderCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ AGENT IDENTITIES ═══════════════════════════ -->\n @case ('identities') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Identity</th>\n <th>Display name</th>\n <th>Active</th>\n </tr>\n </thead>\n <tbody>\n @if (Identities.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No agent identities provisioned\" />\n </td></tr>\n }\n @for (id of Identities; track id.ID) {\n <tr class=\"data-row\">\n <td class=\"cell-strong\">{{ id.Agent || 'Unknown agent' }}</td>\n <td>{{ id.Provider }}</td>\n <td>\n <span class=\"type-chip\"><i [class]=\"IdentityTypeIcon(id.IdentityType)\"></i> {{ id.IdentityType }}</span>\n </td>\n <td class=\"mono\">{{ id.IdentityValue }}</td>\n <td class=\"cell-muted\">{{ id.DisplayName || '—' }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"id.IsActive\"\n [class.status-closed]=\"!id.IsActive\">\n {{ id.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Identities.length }} identities · {{ ActiveIdentityCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ CHANNELS ═══════════════════════════ -->\n @case ('channels') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Channel</th>\n <th>Transport</th>\n <th>Active</th>\n <th>Contributed by</th>\n </tr>\n </thead>\n <tbody>\n @if (Channels.length === 0) {\n <tr><td colspan=\"4\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No channels registered\" />\n </td></tr>\n }\n @for (ch of Channels; track ch.ID) {\n <tr class=\"data-row\">\n <td>\n <div class=\"cell-strong\">{{ ch.Name }}</div>\n @if (ch.Description) { <div class=\"cell-sub\">{{ ch.Description }}</div> }\n </td>\n <td>\n <span class=\"type-chip\"><i [class]=\"TransportTypeIcon(ch.TransportType)\"></i> {{ ch.TransportType }}</span>\n </td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"ch.IsActive\"\n [class.status-closed]=\"!ch.IsActive\">\n {{ ch.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <span class=\"provider-tags\">\n @for (pc of ProvidersForChannel(ch.ID); track pc.ID) {\n <span class=\"provider-tag\" [class.provider-tag--default]=\"pc.IsDefault\"\n [title]=\"pc.IsDefault ? 'Auto-attached by default' : 'Available on demand'\">\n {{ pc.Provider }}\n @if (pc.IsDefault) { <i class=\"fa-solid fa-star\"></i> }\n </span>\n } @empty {\n <span class=\"cell-muted\">no provider contributions</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ Channels.length }} channels · {{ ProviderChannels.length }} provider contributions</span>\n </div>\n }\n\n <!-- ═══════════════════════════ CO-AGENTS ═══════════════════════════ -->\n @case ('co-agents') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Co-Agent</th>\n <th>Pairs with</th>\n <th>Relationship</th>\n <th>Default</th>\n <th class=\"th-numeric\">Seq</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n @if (CoAgents.length === 0) {\n <tr><td colspan=\"6\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No co-agent pairings configured\" />\n </td></tr>\n }\n @for (c of CoAgents; track c.ID) {\n <tr class=\"data-row\">\n <td class=\"cell-strong\">{{ c.CoAgent || 'Unknown' }}</td>\n <td>{{ CoAgentTargetLabel(c) }}</td>\n <td><span class=\"type-chip\">{{ c.Type }}</span></td>\n <td>\n @if (c.IsDefault) {\n <span class=\"default-pill\"><i class=\"fa-solid fa-star\"></i> default</span>\n } @else { <span class=\"cell-muted\">—</span> }\n </td>\n <td class=\"cell-numeric\">{{ c.Sequence }}</td>\n <td>\n <span class=\"status-pill\" [class.status-connected]=\"c.Status === 'Active'\"\n [class.status-closed]=\"c.Status !== 'Active'\">\n {{ c.Status }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ CoAgents.length }} pairings · {{ ActiveCoAgentCount }} active</span>\n </div>\n }\n\n <!-- ═══════════════════════════ SESSION HISTORY ═══════════════════════════ -->\n @case ('history') {\n <div class=\"panel\">\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Agent</th>\n <th>Provider</th>\n <th>Join method</th>\n <th class=\"th-numeric\">Participants</th>\n <th class=\"th-numeric\">Duration</th>\n <th>Close reason</th>\n <th>Started</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @if (HistoryBridges.length === 0) {\n <tr><td colspan=\"8\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No closed bridges in this window\" />\n </td></tr>\n }\n @for (b of HistoryBridges; track b.Record.ID) {\n <tr class=\"data-row\" (click)=\"OpenSession(b.Record.AgentSessionID)\">\n <td class=\"cell-strong\">{{ b.AgentName }}</td>\n <td>{{ b.Record.Provider }}</td>\n <td>{{ b.Record.JoinMethod }}</td>\n <td class=\"cell-numeric\">{{ b.ParticipantCount }}</td>\n <td class=\"cell-numeric mono\">{{ FormatBridgeDuration(b.DurationMs) }}</td>\n <td>\n <span [class]=\"CloseReasonClass(b.Record.CloseReason)\">\n {{ b.Record.CloseReason || 'unknown' }}\n </span>\n </td>\n <td class=\"cell-time\">{{ FormatBridgeStart(b.StartedAt) }}</td>\n <td class=\"cell-action\">\n <!-- TODO(v1+): transcript / recording review launch (§7 review reuse). -->\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(b.Record.AgentSessionID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"grid-footer\">\n <span class=\"grid-summary\">{{ HistoryCount }} closed bridge{{ HistoryCount === 1 ? '' : 's' }} ({{ TimeRange }})</span>\n </div>\n }\n\n <!-- ═══════════════════════════ METRICS ═══════════════════════════ -->\n @case ('metrics') {\n <div class=\"metrics-grid\">\n <!-- Bridges over time (per-day bars) -->\n <div class=\"metric-card metric-card--wide\">\n <div class=\"metric-title\">Bridges over time</div>\n @if (DayBuckets.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-column\"\n Title=\"No bridge activity in this window\" />\n } @else {\n <div class=\"bar-chart\">\n @for (bucket of DayBuckets; track bucket.Label) {\n <div class=\"bar-col\" [title]=\"bucket.Label + ': ' + bucket.Count\">\n <div class=\"bar-track\">\n <div class=\"bar-fill\" [style.height.%]=\"DayBarHeight(bucket.Count)\"></div>\n </div>\n <div class=\"bar-value\">{{ bucket.Count }}</div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- By provider -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By provider</div>\n @if (ByProvider.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByProvider; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByProvider, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n\n <!-- By status -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By status</div>\n @if (ByStatus.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByStatus; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByStatus, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n\n <!-- By agent -->\n <div class=\"metric-card\">\n <div class=\"metric-title\">By agent</div>\n @if (ByAgent.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-simple\" Title=\"No data\" />\n } @else {\n @for (slice of ByAgent; track slice.Label) {\n <div class=\"hbar-row\">\n <span class=\"hbar-label\" [title]=\"slice.Label\">{{ slice.Label }}</span>\n <div class=\"hbar-track\">\n <div class=\"hbar-fill\" [style.width.%]=\"SliceBarWidth(ByAgent, slice.Count)\"></div>\n </div>\n <span class=\"hbar-count\">{{ slice.Count }}</span>\n </div>\n }\n }\n </div>\n </div>\n }\n }\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  * `MJ: AI Agent Sessions`, their `MJ: AI Agent Session Channels` rows, and the
6
6
  * delegated `MJ: AI Agent Runs` linked via `AgentSessionID`. Renders the KPI
7
7
  * row (active sessions, sessions in window, avg duration, delegated runs,
8
- * janitor closes, cost), a sessions-over-time bar chart, the channel-usage
8
+ * system closes, cost), a sessions-over-time bar chart, the channel-usage
9
9
  * donut, the top delegated target agents, and a recent-sessions list with a
10
10
  * "View all" jump to the full sessions grid.
11
11
  */
@@ -5,7 +5,7 @@
5
5
  * `MJ: AI Agent Sessions`, their `MJ: AI Agent Session Channels` rows, and the
6
6
  * delegated `MJ: AI Agent Runs` linked via `AgentSessionID`. Renders the KPI
7
7
  * row (active sessions, sessions in window, avg duration, delegated runs,
8
- * janitor closes, cost), a sessions-over-time bar chart, the channel-usage
8
+ * system closes, cost), a sessions-over-time bar chart, the channel-usage
9
9
  * donut, the top delegated target agents, and a recent-sessions list with a
10
10
  * "View all" jump to the full sessions grid.
11
11
  */
@@ -403,9 +403,9 @@ export class AnalyticsRealtimeOverviewComponent extends BaseAngularComponent {
403
403
  color: 'info'
404
404
  },
405
405
  {
406
- title: 'Janitor closes',
406
+ title: 'System closes',
407
407
  value: janitorCloses,
408
- subtitle: `orphans reconciled (${this.TimeRange})`,
408
+ subtitle: `orphan, idle & time-limit closes (${this.TimeRange})`,
409
409
  icon: 'fa-broom',
410
410
  color: 'warning'
411
411
  },
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-overview.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/realtime/realtime-overview.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Realtime Voice — analytics overview section.\n *\n * Operational analytics for voice-agent sessions, built from\n * `MJ: AI Agent Sessions`, their `MJ: AI Agent Session Channels` rows, and the\n * delegated `MJ: AI Agent Runs` linked via `AgentSessionID`. Renders the KPI\n * row (active sessions, sessions in window, avg duration, delegated runs,\n * janitor closes, cost), a sessions-over-time bar chart, the channel-usage\n * donut, the top delegated target agents, and a recent-sessions list with a\n * \"View all\" jump to the full sessions grid.\n */\n\nimport {\n Component, ChangeDetectionStrategy, Input, Output, EventEmitter,\n OnInit, ChangeDetectorRef, inject\n} from '@angular/core';\nimport { CompositeKey } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { KPICardData } from '../../widgets/kpi-card.component';\nimport {\n RealtimeSessionRollup, RealtimeSessionsDataset,\n LoadRealtimeSessionsDataset, FormatSessionDuration, FormatTokenCount,\n FormatSessionCost, ChannelIconClass, TimeRangeToMs,\n BuildSessionStatusDisplay\n} from './realtime-session-data';\n\n// ── View models ──\n\ninterface TimeBucket {\n Label: string;\n Count: number;\n /** 0–100, relative to the busiest bucket. */\n HeightPercent: number;\n /** Flagged when the bucket is delegated-heavy (≥2 delegated runs/session avg). */\n DelegatedHeavy: boolean;\n}\n\ninterface ChannelShare {\n Name: string;\n Count: number;\n Percent: number;\n Color: string;\n}\n\ninterface TargetAgentBar {\n Name: string;\n Count: number;\n WidthPercent: number;\n}\n\ninterface RecentSessionRow {\n ID: string;\n Target: string;\n ViaAgent: string;\n User: string;\n Status: string;\n StatusClass: string;\n StatusLabel: string;\n StatusTitle: string;\n /** Pill icon (close cause for Closed rows); empty for Active, which renders the live dot. */\n StatusIcon: string;\n ChannelIcons: string[];\n Runs: number;\n Cost: string;\n Duration: string;\n}\n\n/** Channels are categorical series, so they take the categorical data-viz ramp (not status colours). */\nconst DONUT_COLORS = [\n 'var(--mj-viz-1)',\n 'var(--mj-viz-2)',\n 'var(--mj-viz-3)',\n 'var(--mj-viz-4)',\n 'var(--mj-viz-5)',\n 'var(--mj-viz-6)'\n];\n\n@Component({\n standalone: false,\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'app-analytics-realtime-overview',\n template: `\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading realtime voice analytics...\"></mj-loading>\n </div>\n } @else {\n <!-- KPI Row -->\n <div class=\"kpi-grid\">\n @for (kpi of KPICards; track kpi.title) {\n <app-kpi-card [data]=\"kpi\"></app-kpi-card>\n }\n </div>\n\n <!-- Charts row 1: sessions over time + channel usage -->\n <div class=\"charts-2\">\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-chart-column panel-header__icon\"></i>\n Sessions over time\n </div>\n <span class=\"panel-header__subtitle\">Accented bars = delegated-heavy</span>\n </div>\n <div class=\"panel-body\">\n @if (TimeBuckets.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-column\"\n Title=\"No sessions in the selected period\" />\n } @else {\n <div class=\"bars\">\n @for (bucket of TimeBuckets; track bucket.Label; let i = $index, count = $count) {\n <div class=\"bcol\" [title]=\"bucket.Label + ': ' + bucket.Count + ' session(s)'\">\n <div class=\"bar\"\n [class.bar--accent]=\"bucket.DelegatedHeavy\"\n [style.height.%]=\"bucket.HeightPercent\"></div>\n <div class=\"blabel\" [class.blabel--skipped]=\"(count - 1 - i) % LabelStep(count) !== 0\">{{ bucket.Label }}</div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-chart-pie panel-header__icon\"></i>\n Channel usage\n </div>\n <span class=\"panel-header__subtitle\">Share of attached session channels</span>\n </div>\n <div class=\"panel-body\">\n @if (ChannelShares.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-pie\"\n Title=\"No channels attached in the selected period\" />\n } @else {\n <div class=\"donut-row\">\n <div class=\"donut\" [style.background]=\"DonutGradient\"></div>\n <div class=\"legend\">\n @for (share of ChannelShares; track share.Name) {\n <div class=\"legend-item\">\n <span class=\"legend-dot\" [style.background]=\"share.Color\"></span>\n {{ share.Name }}\n <span class=\"legend-pct\">{{ share.Percent | number:'1.0-0' }}%</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Charts row 2: top delegated target agents -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-diagram-project panel-header__icon\"></i>\n Top delegated target agents\n </div>\n <span class=\"panel-header__subtitle\">Delegated agent runs by target · selected period</span>\n </div>\n <div class=\"panel-body\">\n @if (TopTargetAgents.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"No delegated runs in the selected period\" />\n }\n @for (bar of TopTargetAgents; track bar.Name) {\n <div class=\"hbar-row\">\n <span class=\"hbar-name\" [title]=\"bar.Name\">{{ bar.Name }}</span>\n <span class=\"hbar-track\">\n <span class=\"hbar-fill\" [style.width.%]=\"bar.WidthPercent\"></span>\n </span>\n <span class=\"hbar-val\">{{ bar.Count }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Recent sessions -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-tower-broadcast panel-header__icon\"></i>\n Recent sessions\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"SectionNavigate.emit('realtime-sessions')\">\n View all <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Target</th><th>User</th><th>Status</th><th>Channels</th>\n <th class=\"th-numeric\">Runs</th><th class=\"th-numeric\">Cost</th>\n <th class=\"th-numeric\">Duration</th><th></th>\n </tr>\n </thead>\n <tbody>\n @if (RecentSessions.length === 0) {\n <tr><td colspan=\"8\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No sessions in the selected period\" />\n </td></tr>\n }\n @for (row of RecentSessions; track row.ID) {\n <tr class=\"session-row\" (click)=\"OpenSession(row.ID)\">\n <td>\n <div class=\"cell-strong\">{{ row.Target }}</div>\n <div class=\"cell-sub\">via {{ row.ViaAgent }}</div>\n </td>\n <td>{{ row.User }}</td>\n <td>\n <span class=\"status-pill\" [class]=\"row.StatusClass\"\n [title]=\"row.StatusTitle\">\n @if (row.Status === 'Active') { <span class=\"dot dot--live\"></span> }\n @else if (row.StatusIcon) { <i [class]=\"row.StatusIcon\"></i> }\n {{ row.StatusLabel }}\n </span>\n </td>\n <td>\n <span class=\"chan-icons\">\n @for (icon of row.ChannelIcons; track $index) {\n <i [class]=\"icon\"></i>\n }\n </span>\n </td>\n <td class=\"cell-numeric\">{{ row.Runs }}</td>\n <td class=\"cell-numeric mono\">{{ row.Cost }}</td>\n <td class=\"cell-numeric mono\">{{ row.Duration }}</td>\n <td class=\"cell-action\">\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(row.ID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n `,\n styles: [`\n :host { display: block; }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n }\n\n /* ── KPI Grid ── */\n .kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n }\n\n /* ── Layout ── */\n .charts-2 {\n display: grid;\n grid-template-columns: 1.4fr 1fr;\n gap: 16px;\n margin-bottom: 16px;\n }\n\n @media (max-width: 1000px) {\n .charts-2 { grid-template-columns: 1fr; }\n }\n\n /* ── Panel (matches sibling analytics sections) ── */\n .panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n margin-bottom: 16px;\n overflow: hidden;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .panel-header__title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .panel-header__icon {\n font-size: 13px;\n color: var(--mj-brand-primary);\n }\n\n .panel-header__subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .panel-body { padding: 16px 18px; }\n\n /* ── Vertical bars ── */\n .bars {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n height: 160px;\n }\n\n .bcol {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n height: 100%;\n min-width: 0;\n }\n\n .bar {\n width: 100%;\n max-width: 42px;\n min-height: 2px;\n border-radius: 6px 6px 2px 2px;\n background: linear-gradient(180deg,\n color-mix(in srgb, var(--mj-brand-primary) 85%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .bar--accent {\n background: linear-gradient(180deg,\n color-mix(in srgb, var(--mj-status-success) 85%, transparent),\n color-mix(in srgb, var(--mj-status-success) 55%, transparent));\n }\n\n /* Centred on its bar and allowed to spill into the neighbours, whose labels LabelStep hides. */\n .blabel {\n margin-top: 6px;\n font-size: 10px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n width: max-content;\n }\n\n .blabel--skipped {\n visibility: hidden;\n }\n\n /* ── Donut ── */\n .donut-row {\n display: flex;\n align-items: center;\n gap: 22px;\n flex-wrap: wrap;\n }\n\n .donut {\n width: 140px;\n height: 140px;\n border-radius: 50%;\n flex-shrink: 0;\n -webkit-mask: radial-gradient(circle at center, transparent 42px, #000 43px); /* token-exempt: alpha mask, colour irrelevant */\n mask: radial-gradient(circle at center, transparent 42px, #000 43px); /* token-exempt: alpha mask, colour irrelevant */\n }\n\n .legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 160px;\n flex: 1;\n }\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12.5px;\n color: var(--mj-text-secondary);\n }\n\n .legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .legend-pct {\n margin-left: auto;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n /* ── Horizontal bars ── */\n .hbar-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 10px;\n }\n\n .hbar-row:last-child { margin-bottom: 0; }\n\n .hbar-name {\n width: 140px;\n min-width: 140px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .hbar-track {\n flex: 1;\n height: 18px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .hbar-fill {\n display: block;\n height: 100%;\n border-radius: 6px;\n background: linear-gradient(90deg,\n var(--mj-brand-primary),\n color-mix(in srgb, var(--mj-brand-primary) 65%, var(--mj-bg-surface)));\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .hbar-val {\n width: 48px;\n min-width: 48px;\n text-align: right;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n /* ── Table ── */\n .table-wrapper { overflow-x: auto; }\n\n .data-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n .data-table th,\n .data-table td {\n padding: 10px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .data-table th {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--mj-bg-surface-card);\n }\n\n .th-numeric { text-align: right; }\n\n .session-row { cursor: pointer; transition: background 0.15s; }\n .session-row:hover { background: var(--mj-bg-surface-hover); }\n\n .cell-strong {\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cell-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cell-numeric {\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .cell-action { text-align: right; white-space: nowrap; }\n\n .mono {\n font-family: var(--mj-font-family-mono);\n font-size: 12px;\n }\n\n .data-table td.empty-cell {\n padding: 0;\n }\n\n /* ── Status pills ── */\n .status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.3px;\n white-space: nowrap;\n }\n\n .status-active {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .status-idle {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n .status-closed {\n background: color-mix(in srgb, var(--mj-text-disabled) 12%, var(--mj-bg-surface));\n color: var(--mj-text-muted);\n }\n\n .dot--live {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-status-success);\n animation: pulse-live 1.6s ease-in-out infinite;\n }\n\n @keyframes pulse-live {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.35; }\n }\n\n .chan-icons {\n display: inline-flex;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n }\n `]\n})\nexport class AnalyticsRealtimeOverviewComponent extends BaseAngularComponent implements OnInit {\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n /** Lets the shell jump to the full sessions grid (mirrors Executive Summary's pattern). */\n @Output() SectionNavigate = new EventEmitter<string>();\n\n private initialized = false;\n private cdr = inject(ChangeDetectorRef);\n private dataset: RealtimeSessionsDataset | null = null;\n\n public IsLoading = false;\n public KPICards: KPICardData[] = [];\n public TimeBuckets: TimeBucket[] = [];\n public ChannelShares: ChannelShare[] = [];\n public DonutGradient = '';\n public TopTargetAgents: TargetAgentBar[] = [];\n public RecentSessions: RecentSessionRow[] = [];\n\n ngOnInit(): void {\n this.initialized = true;\n this.LoadData();\n }\n\n /** Reloads everything for the current time range. */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n this.dataset = await LoadRealtimeSessionsDataset(this.ProviderToUse, this.TimeRange);\n this.buildKPICards();\n this.buildTimeBuckets();\n this.buildChannelShares();\n this.buildTopTargetAgents();\n this.buildRecentSessions();\n } catch (e) {\n console.error('Realtime Voice overview load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Opens the AIAgentSession record using the shared Explorer record-open path. */\n public OpenSession(sessionId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', CompositeKey.FromID(sessionId));\n }\n\n // ── Builders ──\n\n private get windowSessions(): RealtimeSessionRollup[] {\n return this.dataset?.Sessions ?? [];\n }\n\n private buildKPICards(): void {\n const ds = this.dataset;\n const sessions = this.windowSessions;\n const activeCount = sessions.filter(s => s.Record.Status === 'Active').length;\n const startedInWindow = sessions.filter(s => ds != null && s.StartedAt >= ds.WindowStart);\n const priorCount = ds?.PriorWindowSessionCount ?? 0;\n\n const durations = sessions.map(s => s.DurationMs).filter(d => d > 0);\n const avgDuration = durations.length > 0\n ? durations.reduce((a, b) => a + b, 0) / durations.length\n : 0;\n\n const delegatedTotal = sessions.reduce((a, s) => a + s.DelegatedRunCount, 0);\n const delegatedPerSession = sessions.length > 0 ? delegatedTotal / sessions.length : 0;\n const janitorCloses = sessions.filter(s => s.IsJanitorClosed).length;\n const totalCost = sessions.reduce((a, s) => a + s.TotalCost, 0);\n\n const trendPct = priorCount > 0\n ? Math.round(((startedInWindow.length - priorCount) / priorCount) * 100)\n : 0;\n\n this.KPICards = [\n {\n title: 'Active sessions',\n value: activeCount,\n subtitle: 'live right now',\n icon: 'fa-tower-broadcast',\n color: 'success'\n },\n {\n title: `Sessions (${this.TimeRange})`,\n value: startedInWindow.length,\n icon: 'fa-calendar-day',\n color: 'primary',\n trend: priorCount > 0 ? {\n direction: trendPct > 0 ? 'up' : trendPct < 0 ? 'down' : 'stable',\n percentage: Math.abs(trendPct),\n period: `vs prior ${this.TimeRange}`\n } : undefined,\n subtitle: priorCount > 0 ? undefined : 'no prior-period data'\n },\n {\n title: 'Avg duration',\n value: FormatSessionDuration(avgDuration),\n subtitle: 'min:sec per session',\n icon: 'fa-stopwatch',\n color: 'info'\n },\n {\n title: 'Delegated runs',\n value: delegatedTotal,\n subtitle: `${delegatedPerSession.toFixed(1)} per session avg`,\n icon: 'fa-diagram-project',\n color: 'info'\n },\n {\n title: 'Janitor closes',\n value: janitorCloses,\n subtitle: `orphans reconciled (${this.TimeRange})`,\n icon: 'fa-broom',\n color: 'warning'\n },\n {\n title: `Cost (${this.TimeRange})`,\n value: FormatSessionCost(totalCost),\n subtitle: 'co-agent + delegated',\n icon: 'fa-coins',\n color: 'danger'\n }\n ];\n }\n\n /**\n * Show every Nth bar label so 24 hourly / 30 daily labels never run into each other. The\n * template counts from the newest bar, so the current bucket always keeps its label.\n */\n public LabelStep(count: number): number {\n return Math.max(1, Math.ceil(count / 12));\n }\n\n private buildTimeBuckets(): void {\n const ds = this.dataset;\n // No sessions in the window: an empty bucket list renders the empty state, not a row of blank bars.\n if (!ds || this.windowSessions.length === 0) { this.TimeBuckets = []; return; }\n\n const hourly = this.TimeRange === '24h';\n const bucketMs = hourly ? 3_600_000 : 86_400_000;\n const bucketCount = Math.max(1, Math.round(ds.WindowMs / bucketMs));\n const now = Date.now();\n const buckets: { start: number; count: number; delegated: number }[] = [];\n for (let i = bucketCount - 1; i >= 0; i--) {\n buckets.push({ start: now - (i + 1) * bucketMs, count: 0, delegated: 0 });\n }\n\n for (const session of this.windowSessions) {\n const t = session.StartedAt.getTime();\n const idx = buckets.findIndex(b => t >= b.start && t < b.start + bucketMs);\n if (idx >= 0) {\n buckets[idx].count++;\n buckets[idx].delegated += session.DelegatedRunCount;\n }\n }\n\n const max = Math.max(1, ...buckets.map(b => b.count));\n this.TimeBuckets = buckets.map((b, i) => {\n const date = new Date(b.start + bucketMs);\n const isLast = i === buckets.length - 1;\n const label = hourly\n ? date.toLocaleTimeString([], { hour: 'numeric' }).toLowerCase()\n : isLast ? 'Today' : date.toLocaleDateString([], { weekday: this.TimeRange === '7d' ? 'short' : undefined, month: this.TimeRange === '7d' ? undefined : 'numeric', day: this.TimeRange === '7d' ? undefined : 'numeric' });\n return {\n Label: label,\n Count: b.count,\n HeightPercent: Math.round((b.count / max) * 100),\n DelegatedHeavy: b.count > 0 && b.delegated / b.count >= 2\n };\n });\n }\n\n private buildChannelShares(): void {\n const counts = new Map<string, number>();\n for (const session of this.windowSessions) {\n for (const name of session.ChannelNames) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n }\n const total = Array.from(counts.values()).reduce((a, b) => a + b, 0);\n if (total === 0) {\n this.ChannelShares = [];\n this.DonutGradient = '';\n return;\n }\n const sorted = Array.from(counts.entries()).sort((a, b) => b[1] - a[1]);\n this.ChannelShares = sorted.map(([name, count], i) => ({\n Name: name,\n Count: count,\n Percent: (count / total) * 100,\n Color: DONUT_COLORS[i % DONUT_COLORS.length]\n }));\n\n let cursor = 0;\n const stops: string[] = [];\n for (const share of this.ChannelShares) {\n const end = cursor + share.Percent;\n stops.push(`${share.Color} ${cursor.toFixed(2)}% ${end.toFixed(2)}%`);\n cursor = end;\n }\n this.DonutGradient = `conic-gradient(${stops.join(', ')})`;\n }\n\n private buildTopTargetAgents(): void {\n const counts = new Map<string, number>();\n for (const session of this.windowSessions) {\n if (session.DelegatedRunCount === 0) continue;\n const name = session.TargetAgentName ?? session.TargetAgentID ?? 'Unknown';\n counts.set(name, (counts.get(name) ?? 0) + session.DelegatedRunCount);\n }\n const sorted = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n const max = Math.max(1, ...sorted.map(([, c]) => c));\n this.TopTargetAgents = sorted.map(([name, count]) => ({\n Name: name,\n Count: count,\n WidthPercent: Math.round((count / max) * 100)\n }));\n }\n\n private buildRecentSessions(): void {\n this.RecentSessions = [...this.windowSessions]\n .sort((a, b) => b.StartedAt.getTime() - a.StartedAt.getTime())\n .slice(0, 8)\n .map(s => {\n const statusDisplay = BuildSessionStatusDisplay(s.Record.Status, s.CloseReason);\n return {\n ID: s.Record.ID,\n Target: s.TargetAgentName ?? s.Record.Agent ?? 'Unknown',\n ViaAgent: s.Record.Agent ?? 'Unknown',\n User: s.Record.User,\n Status: s.Record.Status,\n StatusClass: 'status-pill status-' + s.Record.Status.toLowerCase(),\n StatusLabel: statusDisplay.Label,\n StatusTitle: statusDisplay.Title,\n StatusIcon: statusDisplay.Icon,\n ChannelIcons: s.ChannelNames.map(ChannelIconClass),\n Runs: s.DelegatedRunCount,\n Cost: FormatSessionCost(s.TotalCost),\n Duration: FormatSessionDuration(s.DurationMs)\n };\n });\n }\n\n /** Exposed for testability / template type narrowing. */\n public FormatTokens(value: number): string {\n return FormatTokenCount(value);\n }\n\n /** Window length in ms for the active range (exposed for tests). */\n public get WindowMs(): number {\n return TimeRangeToMs(this.TimeRange);\n }\n}\n\nexport function LoadAnalyticsRealtimeOverview() { /* tree-shaking prevention */ }\n"]}
1
+ {"version":3,"file":"realtime-overview.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/realtime/realtime-overview.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACH,SAAS,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EACvD,iBAAiB,EAAE,MAAM,EACpC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAEH,2BAA2B,EAAE,qBAAqB,EAAE,gBAAgB,EACpE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAClD,yBAAyB,EAC5B,MAAM,yBAAyB,CAAC;;;;;;;;;;;IA2DrB,8BAA+B;IAC3B,gCAAoE;IACxE,iBAAM;;;IAKE,kCAA0C;;;IAA5B,6BAAY;;;IAgBlB,qCACiD;;;IAIzC,+BAA+E;IAC3E,0BAEmD;IACnD,+BAAuF;IAAA,YAAkB;IAC7G,AAD6G,iBAAM,EAC7G;;;;;;IALY,gFAA4D;IAGrE,cAAuC;IAAvC,sDAAuC;IADvC,uDAA2C;IAE5B,cAAkE;IAAlE,8GAAkE;IAAC,cAAkB;IAAlB,qCAAkB;;;IANrH,+BAAkB;IACd,mIAOC;IACL,iBAAM;;;IARF,cAOC;IAPD,iCAOC;;;IAeL,qCAC0D;;;IAM9C,+BAAyB;IACrB,2BAAiE;IACjE,YACA;IAAA,gCAAyB;IAAA,YAAqC;;IAClE,AADkE,iBAAO,EACnE;;;IAHuB,cAAgC;IAAhC,4CAAgC;IACzD,cACA;IADA,8CACA;IAAyB,eAAqC;IAArC,+EAAqC;;;IAP9E,+BAAuB;IACnB,0BAA4D;IAC5D,+BAAoB;IAChB,mIAMC;IAET,AADI,iBAAM,EACJ;;;IAViB,cAAkC;IAAlC,kDAAkC;IAEjD,eAMC;IAND,mCAMC;;;IAmBb,qCACuD;;;IAInD,AADJ,+BAAsB,eACyB;IAAA,YAAc;IAAA,iBAAO;IAChE,gCAAyB;IACrB,2BAAkE;IACtE,iBAAO;IACP,gCAAuB;IAAA,YAAe;IAC1C,AAD0C,iBAAO,EAC3C;;;IALsB,cAAkB;IAAlB,mCAAkB;IAAC,cAAc;IAAd,iCAAc;IAE7B,eAAkC;IAAlC,iDAAkC;IAEvC,eAAe;IAAf,kCAAe;;;IA4B9B,AAAJ,0BAAI,aAAmC;IACnC,qCAA4F;IAC3F,AAAL,iBAAK,EAAK;;;IAYkC,2BAAmC;;;IACvC,oBAAgC;;;IAA7B,iCAAwB;;;IAOnD,oBAAsB;;;IAAnB,uBAAc;;;;IAjBjC,8BAAsD;IAA9B,oOAAS,8BAAmB,KAAC;IAE7C,AADJ,0BAAI,cACyB;IAAA,YAAgB;IAAA,iBAAM;IAC/C,+BAAsB;IAAA,YAAsB;IAChD,AADgD,iBAAM,EACjD;IACL,0BAAI;IAAA,YAAc;IAAA,iBAAK;IAEnB,AADJ,0BAAI,eAEgC;IAE5B,AADA,6HAA+B,oGACJ;IAC3B,aACJ;IACJ,AADI,iBAAO,EACN;IAED,AADJ,2BAAI,gBACyB;IACrB,0IAEC;IAET,AADI,iBAAO,EACN;IACL,+BAAyB;IAAA,aAAc;IAAA,iBAAK;IAC5C,+BAA8B;IAAA,aAAc;IAAA,iBAAK;IACjD,+BAA8B;IAAA,aAAkB;IAAA,iBAAK;IAEjD,AADJ,+BAAwB,kBAE4C;IAAxD,yNAAS,8BAAmB,wBAAE,wBAAwB,KAAC;IAC3D,yBAAsD;IAGlE,AADI,AADI,iBAAS,EACR,EACJ;;;IA5B4B,eAAgB;IAAhB,oCAAgB;IACnB,eAAsB;IAAtB,+CAAsB;IAE5C,eAAc;IAAd,kCAAc;IAEY,eAAyB;IAAzB,kCAAyB;IAC7C,2CAAyB;IAC3B,cAC8D;IAD9D,iFAC8D;IAC9D,eACJ;IADI,oDACJ;IAII,eAEC;IAFD,mCAEC;IAGgB,eAAc;IAAd,kCAAc;IACT,eAAc;IAAd,kCAAc;IACd,eAAkB;IAAlB,sCAAkB;;;;IA5IxE,8BAAsB;IAClB,4HAEC;IACL,iBAAM;IAMM,AADJ,AADJ,AADJ,8BAAsB,aACC,aACW,aACW;IAC7B,uBAA2D;IAC3D,oCACJ;IAAA,iBAAM;IACN,+BAAqC;IAAA,gDAA+B;IACxE,AADwE,iBAAO,EACzE;IACN,gCAAwB;IAIlB,AAHF,gIAAgC,+FAGvB;IAajB,AADI,iBAAM,EACJ;IAGE,AADJ,AADJ,+BAAmB,cACW,cACW;IAC7B,yBAAwD;IACxD,gCACJ;IAAA,iBAAM;IACN,gCAAqC;IAAA,mDAAkC;IAC3E,AAD2E,iBAAO,EAC5E;IACN,gCAAwB;IAIlB,AAHF,gIAAkC,+FAGzB;IAgBrB,AADI,AADI,iBAAM,EACJ,EACJ;IAKE,AADJ,AADJ,+BAAmB,cACW,cACW;IAC7B,yBAA8D;IAC9D,8CACJ;IAAA,iBAAM;IACN,gCAAqC;IAAA,sEAAgD;IACzF,AADyF,iBAAO,EAC1F;IACN,gCAAwB;IACpB,gIAAoC;IAIpC,sHAQC;IAET,AADI,iBAAM,EACJ;IAKE,AADJ,AADJ,+BAAmB,cACW,cACW;IAC7B,yBAA8D;IAC9D,kCACJ;IAAA,iBAAM;IACN,mCAAmG;IAApD,uMAAS,4BAAqB,mBAAmB,CAAC,KAAC;IAC9F,2BAAS;IAAA,yBAAuC;IAExD,AADI,iBAAS,EACP;IAKU,AADJ,AADJ,AADJ,AADJ,gCAA2B,iBACG,aACf,UACC,UACI;IAAA,uBAAM;IAAA,iBAAK;IAAA,2BAAI;IAAA,qBAAI;IAAA,iBAAK;IAAA,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IAAA,2BAAI;IAAA,yBAAQ;IAAA,iBAAK;IAC5D,+BAAuB;IAAA,qBAAI;IAAA,iBAAK;IAAA,+BAAuB;IAAA,qBAAI;IAAA,iBAAK;IAChE,+BAAuB;IAAA,yBAAQ;IAAA,iBAAK;IAAA,sBAAS;IAErD,AADI,iBAAK,EACD;IACR,8BAAO;IACH,gHAAmC;IAKnC,uHAgCC;IAIjB,AADI,AADI,AADI,iBAAQ,EACJ,EACN,EACJ;;;IAvJF,cAEC;IAFD,8BAEC;IAcO,gBAcC;IAdD,2DAcC;IAYD,gBAgBC;IAhBD,6DAgBC;IAeL,gBAGC;IAHD,+DAGC;IACD,cAQC;IARD,qCAQC;IAyBO,gBAIC;IAJD,8DAIC;IACD,cAgCC;IAhCD,oCAgCC;;AAzK7B,wGAAwG;AACxG,MAAM,YAAY,GAAG;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;CACpB,CAAC;AAqeF,MAAM,OAAO,kCAAmC,SAAQ,oBAAoB;IAChE,UAAU,GAAG,IAAI,CAAC;IAC1B,IACI,SAAS,CAAC,KAAa;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAEnD,2FAA2F;IACjF,eAAe,GAAG,IAAI,YAAY,EAAU,CAAC;IAE/C,WAAW,GAAG,KAAK,CAAC;IACpB,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,OAAO,GAAmC,IAAI,CAAC;IAEhD,SAAS,GAAG,KAAK,CAAC;IAClB,QAAQ,GAAkB,EAAE,CAAC;IAC7B,WAAW,GAAiB,EAAE,CAAC;IAC/B,aAAa,GAAmB,EAAE,CAAC;IACnC,aAAa,GAAG,EAAE,CAAC;IACnB,eAAe,GAAqB,EAAE,CAAC;IACvC,cAAc,GAAuB,EAAE,CAAC;IAE/C,QAAQ;QACJ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,qDAAqD;IAC9C,KAAK,CAAC,QAAQ;QACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,MAAM,2BAA2B,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACrF,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,kFAAkF;IAC3E,WAAW,CAAC,SAAiB;QAChC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,iBAAiB;IAEjB,IAAY,cAAc;QACtB,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;IACxC,CAAC;IAEO,aAAa;QACjB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;QACrC,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC9E,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC;QAC1F,MAAM,UAAU,GAAG,EAAE,EAAE,uBAAuB,IAAI,CAAC,CAAC;QAEpD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;YACpC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YACzD,CAAC,CAAC,CAAC,CAAC;QAER,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;QACrE,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC;YAC3B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC;YACxE,CAAC,CAAC,CAAC,CAAC;QAER,IAAI,CAAC,QAAQ,GAAG;YACZ;gBACI,KAAK,EAAE,iBAAiB;gBACxB,KAAK,EAAE,WAAW;gBAClB,QAAQ,EAAE,gBAAgB;gBAC1B,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,SAAS;aACnB;YACD;gBACI,KAAK,EAAE,aAAa,IAAI,CAAC,SAAS,GAAG;gBACrC,KAAK,EAAE,eAAe,CAAC,MAAM;gBAC7B,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;oBACpB,SAAS,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;oBACjE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAC9B,MAAM,EAAE,YAAY,IAAI,CAAC,SAAS,EAAE;iBACvC,CAAC,CAAC,CAAC,SAAS;gBACb,QAAQ,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB;aAChE;YACD;gBACI,KAAK,EAAE,cAAc;gBACrB,KAAK,EAAE,qBAAqB,CAAC,WAAW,CAAC;gBACzC,QAAQ,EAAE,qBAAqB;gBAC/B,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,MAAM;aAChB;YACD;gBACI,KAAK,EAAE,gBAAgB;gBACvB,KAAK,EAAE,cAAc;gBACrB,QAAQ,EAAE,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB;gBAC7D,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,MAAM;aAChB;YACD;gBACI,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,aAAa;gBACpB,QAAQ,EAAE,qCAAqC,IAAI,CAAC,SAAS,GAAG;gBAChE,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,SAAS;aACnB;YACD;gBACI,KAAK,EAAE,SAAS,IAAI,CAAC,SAAS,GAAG;gBACjC,KAAK,EAAE,iBAAiB,CAAC,SAAS,CAAC;gBACnC,QAAQ,EAAE,sBAAsB;gBAChC,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,QAAQ;aAClB;SACJ,CAAC;IACN,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAEO,gBAAgB;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxB,oGAAoG;QACpG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAE/E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAA0D,EAAE,CAAC;QAC1E,KAAK,IAAI,CAAC,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;YAC3E,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC;YACxD,CAAC;QACL,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,MAAM;gBAChB,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,WAAW,EAAE;gBAChE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YAC/N,OAAO;gBACH,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;gBAChD,cAAc,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC;aAC5D,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClD,CAAC;QACL,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;YACxB,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG;YAC9B,KAAK,EAAE,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;SAC/C,CAAC,CAAC,CAAC;QAEJ,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACtE,MAAM,GAAG,GAAG,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,kBAAkB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC/D,CAAC;IAEO,oBAAoB;QACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,IAAI,OAAO,CAAC,iBAAiB,KAAK,CAAC;gBAAE,SAAS;YAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,aAAa,IAAI,SAAS,CAAC;YAC3E,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;aACtC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;SAChD,CAAC,CAAC,CAAC;IACR,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;aACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;aAC7D,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,MAAM,aAAa,GAAG,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YAChF,OAAO;gBACH,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;gBACf,MAAM,EAAE,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;gBACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;gBACrC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI;gBACnB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM;gBACvB,WAAW,EAAE,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE;gBAClE,WAAW,EAAE,aAAa,CAAC,KAAK;gBAChC,WAAW,EAAE,aAAa,CAAC,KAAK;gBAChC,UAAU,EAAE,aAAa,CAAC,IAAI;gBAC9B,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBAClD,IAAI,EAAE,CAAC,CAAC,iBAAiB;gBACzB,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;gBACpC,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,UAAU,CAAC;aAChD,CAAC;QACN,CAAC,CAAC,CAAC;IACX,CAAC;IAED,yDAAyD;IAClD,YAAY,CAAC,KAAa;QAC7B,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,oEAAoE;IACpE,IAAW,QAAQ;QACf,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;qTApQQ,kCAAkC,yBAAlC,kCAAkC;6DAAlC,kCAAkC;YA1drC,AAJF,oGAAiB,qEAIR;;YAJT,uCA+JC;;;iFA+TI,kCAAkC;cAne9C,SAAS;6BACM,KAAK,mBACA,uBAAuB,CAAC,MAAM,YACrC,iCAAiC,YACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiKT;;kBAgUA,KAAK;;kBASL,MAAM;;kFAXE,kCAAkC;AAuQ/C,MAAM,UAAU,6BAA6B,KAAmC,CAAC","sourcesContent":["/**\n * @fileoverview Realtime Voice — analytics overview section.\n *\n * Operational analytics for voice-agent sessions, built from\n * `MJ: AI Agent Sessions`, their `MJ: AI Agent Session Channels` rows, and the\n * delegated `MJ: AI Agent Runs` linked via `AgentSessionID`. Renders the KPI\n * row (active sessions, sessions in window, avg duration, delegated runs,\n * system closes, cost), a sessions-over-time bar chart, the channel-usage\n * donut, the top delegated target agents, and a recent-sessions list with a\n * \"View all\" jump to the full sessions grid.\n */\n\nimport {\n Component, ChangeDetectionStrategy, Input, Output, EventEmitter,\n OnInit, ChangeDetectorRef, inject\n} from '@angular/core';\nimport { CompositeKey } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { KPICardData } from '../../widgets/kpi-card.component';\nimport {\n RealtimeSessionRollup, RealtimeSessionsDataset,\n LoadRealtimeSessionsDataset, FormatSessionDuration, FormatTokenCount,\n FormatSessionCost, ChannelIconClass, TimeRangeToMs,\n BuildSessionStatusDisplay\n} from './realtime-session-data';\n\n// ── View models ──\n\ninterface TimeBucket {\n Label: string;\n Count: number;\n /** 0–100, relative to the busiest bucket. */\n HeightPercent: number;\n /** Flagged when the bucket is delegated-heavy (≥2 delegated runs/session avg). */\n DelegatedHeavy: boolean;\n}\n\ninterface ChannelShare {\n Name: string;\n Count: number;\n Percent: number;\n Color: string;\n}\n\ninterface TargetAgentBar {\n Name: string;\n Count: number;\n WidthPercent: number;\n}\n\ninterface RecentSessionRow {\n ID: string;\n Target: string;\n ViaAgent: string;\n User: string;\n Status: string;\n StatusClass: string;\n StatusLabel: string;\n StatusTitle: string;\n /** Pill icon (close cause for Closed rows); empty for Active, which renders the live dot. */\n StatusIcon: string;\n ChannelIcons: string[];\n Runs: number;\n Cost: string;\n Duration: string;\n}\n\n/** Channels are categorical series, so they take the categorical data-viz ramp (not status colours). */\nconst DONUT_COLORS = [\n 'var(--mj-viz-1)',\n 'var(--mj-viz-2)',\n 'var(--mj-viz-3)',\n 'var(--mj-viz-4)',\n 'var(--mj-viz-5)',\n 'var(--mj-viz-6)'\n];\n\n@Component({\n standalone: false,\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'app-analytics-realtime-overview',\n template: `\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading realtime voice analytics...\"></mj-loading>\n </div>\n } @else {\n <!-- KPI Row -->\n <div class=\"kpi-grid\">\n @for (kpi of KPICards; track kpi.title) {\n <app-kpi-card [data]=\"kpi\"></app-kpi-card>\n }\n </div>\n\n <!-- Charts row 1: sessions over time + channel usage -->\n <div class=\"charts-2\">\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-chart-column panel-header__icon\"></i>\n Sessions over time\n </div>\n <span class=\"panel-header__subtitle\">Accented bars = delegated-heavy</span>\n </div>\n <div class=\"panel-body\">\n @if (TimeBuckets.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-column\"\n Title=\"No sessions in the selected period\" />\n } @else {\n <div class=\"bars\">\n @for (bucket of TimeBuckets; track bucket.Label; let i = $index, count = $count) {\n <div class=\"bcol\" [title]=\"bucket.Label + ': ' + bucket.Count + ' session(s)'\">\n <div class=\"bar\"\n [class.bar--accent]=\"bucket.DelegatedHeavy\"\n [style.height.%]=\"bucket.HeightPercent\"></div>\n <div class=\"blabel\" [class.blabel--skipped]=\"(count - 1 - i) % LabelStep(count) !== 0\">{{ bucket.Label }}</div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-chart-pie panel-header__icon\"></i>\n Channel usage\n </div>\n <span class=\"panel-header__subtitle\">Share of attached session channels</span>\n </div>\n <div class=\"panel-body\">\n @if (ChannelShares.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-chart-pie\"\n Title=\"No channels attached in the selected period\" />\n } @else {\n <div class=\"donut-row\">\n <div class=\"donut\" [style.background]=\"DonutGradient\"></div>\n <div class=\"legend\">\n @for (share of ChannelShares; track share.Name) {\n <div class=\"legend-item\">\n <span class=\"legend-dot\" [style.background]=\"share.Color\"></span>\n {{ share.Name }}\n <span class=\"legend-pct\">{{ share.Percent | number:'1.0-0' }}%</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Charts row 2: top delegated target agents -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-diagram-project panel-header__icon\"></i>\n Top delegated target agents\n </div>\n <span class=\"panel-header__subtitle\">Delegated agent runs by target · selected period</span>\n </div>\n <div class=\"panel-body\">\n @if (TopTargetAgents.length === 0) {\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"No delegated runs in the selected period\" />\n }\n @for (bar of TopTargetAgents; track bar.Name) {\n <div class=\"hbar-row\">\n <span class=\"hbar-name\" [title]=\"bar.Name\">{{ bar.Name }}</span>\n <span class=\"hbar-track\">\n <span class=\"hbar-fill\" [style.width.%]=\"bar.WidthPercent\"></span>\n </span>\n <span class=\"hbar-val\">{{ bar.Count }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Recent sessions -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header__title\">\n <i class=\"fa-solid fa-tower-broadcast panel-header__icon\"></i>\n Recent sessions\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"SectionNavigate.emit('realtime-sessions')\">\n View all <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"table-wrapper\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Target</th><th>User</th><th>Status</th><th>Channels</th>\n <th class=\"th-numeric\">Runs</th><th class=\"th-numeric\">Cost</th>\n <th class=\"th-numeric\">Duration</th><th></th>\n </tr>\n </thead>\n <tbody>\n @if (RecentSessions.length === 0) {\n <tr><td colspan=\"8\" class=\"empty-cell\">\n <mj-empty-state Size=\"compact\" Variant=\"empty\" Title=\"No sessions in the selected period\" />\n </td></tr>\n }\n @for (row of RecentSessions; track row.ID) {\n <tr class=\"session-row\" (click)=\"OpenSession(row.ID)\">\n <td>\n <div class=\"cell-strong\">{{ row.Target }}</div>\n <div class=\"cell-sub\">via {{ row.ViaAgent }}</div>\n </td>\n <td>{{ row.User }}</td>\n <td>\n <span class=\"status-pill\" [class]=\"row.StatusClass\"\n [title]=\"row.StatusTitle\">\n @if (row.Status === 'Active') { <span class=\"dot dot--live\"></span> }\n @else if (row.StatusIcon) { <i [class]=\"row.StatusIcon\"></i> }\n {{ row.StatusLabel }}\n </span>\n </td>\n <td>\n <span class=\"chan-icons\">\n @for (icon of row.ChannelIcons; track $index) {\n <i [class]=\"icon\"></i>\n }\n </span>\n </td>\n <td class=\"cell-numeric\">{{ row.Runs }}</td>\n <td class=\"cell-numeric mono\">{{ row.Cost }}</td>\n <td class=\"cell-numeric mono\">{{ row.Duration }}</td>\n <td class=\"cell-action\">\n <button mjButton variant=\"icon\" size=\"sm\" AriaLabel=\"Open session record\" title=\"Open session record\"\n (click)=\"OpenSession(row.ID); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n `,\n styles: [`\n :host { display: block; }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n }\n\n /* ── KPI Grid ── */\n .kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n }\n\n /* ── Layout ── */\n .charts-2 {\n display: grid;\n grid-template-columns: 1.4fr 1fr;\n gap: 16px;\n margin-bottom: 16px;\n }\n\n @media (max-width: 1000px) {\n .charts-2 { grid-template-columns: 1fr; }\n }\n\n /* ── Panel (matches sibling analytics sections) ── */\n .panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n margin-bottom: 16px;\n overflow: hidden;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .panel-header__title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .panel-header__icon {\n font-size: 13px;\n color: var(--mj-brand-primary);\n }\n\n .panel-header__subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .panel-body { padding: 16px 18px; }\n\n /* ── Vertical bars ── */\n .bars {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n height: 160px;\n }\n\n .bcol {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n height: 100%;\n min-width: 0;\n }\n\n .bar {\n width: 100%;\n max-width: 42px;\n min-height: 2px;\n border-radius: 6px 6px 2px 2px;\n background: linear-gradient(180deg,\n color-mix(in srgb, var(--mj-brand-primary) 85%, transparent),\n color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .bar--accent {\n background: linear-gradient(180deg,\n color-mix(in srgb, var(--mj-status-success) 85%, transparent),\n color-mix(in srgb, var(--mj-status-success) 55%, transparent));\n }\n\n /* Centred on its bar and allowed to spill into the neighbours, whose labels LabelStep hides. */\n .blabel {\n margin-top: 6px;\n font-size: 10px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n width: max-content;\n }\n\n .blabel--skipped {\n visibility: hidden;\n }\n\n /* ── Donut ── */\n .donut-row {\n display: flex;\n align-items: center;\n gap: 22px;\n flex-wrap: wrap;\n }\n\n .donut {\n width: 140px;\n height: 140px;\n border-radius: 50%;\n flex-shrink: 0;\n -webkit-mask: radial-gradient(circle at center, transparent 42px, #000 43px); /* token-exempt: alpha mask, colour irrelevant */\n mask: radial-gradient(circle at center, transparent 42px, #000 43px); /* token-exempt: alpha mask, colour irrelevant */\n }\n\n .legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 160px;\n flex: 1;\n }\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12.5px;\n color: var(--mj-text-secondary);\n }\n\n .legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .legend-pct {\n margin-left: auto;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n /* ── Horizontal bars ── */\n .hbar-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 10px;\n }\n\n .hbar-row:last-child { margin-bottom: 0; }\n\n .hbar-name {\n width: 140px;\n min-width: 140px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .hbar-track {\n flex: 1;\n height: 18px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .hbar-fill {\n display: block;\n height: 100%;\n border-radius: 6px;\n background: linear-gradient(90deg,\n var(--mj-brand-primary),\n color-mix(in srgb, var(--mj-brand-primary) 65%, var(--mj-bg-surface)));\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .hbar-val {\n width: 48px;\n min-width: 48px;\n text-align: right;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n /* ── Table ── */\n .table-wrapper { overflow-x: auto; }\n\n .data-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n .data-table th,\n .data-table td {\n padding: 10px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .data-table th {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--mj-bg-surface-card);\n }\n\n .th-numeric { text-align: right; }\n\n .session-row { cursor: pointer; transition: background 0.15s; }\n .session-row:hover { background: var(--mj-bg-surface-hover); }\n\n .cell-strong {\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cell-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cell-numeric {\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .cell-action { text-align: right; white-space: nowrap; }\n\n .mono {\n font-family: var(--mj-font-family-mono);\n font-size: 12px;\n }\n\n .data-table td.empty-cell {\n padding: 0;\n }\n\n /* ── Status pills ── */\n .status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.3px;\n white-space: nowrap;\n }\n\n .status-active {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .status-idle {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n .status-closed {\n background: color-mix(in srgb, var(--mj-text-disabled) 12%, var(--mj-bg-surface));\n color: var(--mj-text-muted);\n }\n\n .dot--live {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-status-success);\n animation: pulse-live 1.6s ease-in-out infinite;\n }\n\n @keyframes pulse-live {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.35; }\n }\n\n .chan-icons {\n display: inline-flex;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n }\n `]\n})\nexport class AnalyticsRealtimeOverviewComponent extends BaseAngularComponent implements OnInit {\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n /** Lets the shell jump to the full sessions grid (mirrors Executive Summary's pattern). */\n @Output() SectionNavigate = new EventEmitter<string>();\n\n private initialized = false;\n private cdr = inject(ChangeDetectorRef);\n private dataset: RealtimeSessionsDataset | null = null;\n\n public IsLoading = false;\n public KPICards: KPICardData[] = [];\n public TimeBuckets: TimeBucket[] = [];\n public ChannelShares: ChannelShare[] = [];\n public DonutGradient = '';\n public TopTargetAgents: TargetAgentBar[] = [];\n public RecentSessions: RecentSessionRow[] = [];\n\n ngOnInit(): void {\n this.initialized = true;\n this.LoadData();\n }\n\n /** Reloads everything for the current time range. */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n this.dataset = await LoadRealtimeSessionsDataset(this.ProviderToUse, this.TimeRange);\n this.buildKPICards();\n this.buildTimeBuckets();\n this.buildChannelShares();\n this.buildTopTargetAgents();\n this.buildRecentSessions();\n } catch (e) {\n console.error('Realtime Voice overview load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Opens the AIAgentSession record using the shared Explorer record-open path. */\n public OpenSession(sessionId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', CompositeKey.FromID(sessionId));\n }\n\n // ── Builders ──\n\n private get windowSessions(): RealtimeSessionRollup[] {\n return this.dataset?.Sessions ?? [];\n }\n\n private buildKPICards(): void {\n const ds = this.dataset;\n const sessions = this.windowSessions;\n const activeCount = sessions.filter(s => s.Record.Status === 'Active').length;\n const startedInWindow = sessions.filter(s => ds != null && s.StartedAt >= ds.WindowStart);\n const priorCount = ds?.PriorWindowSessionCount ?? 0;\n\n const durations = sessions.map(s => s.DurationMs).filter(d => d > 0);\n const avgDuration = durations.length > 0\n ? durations.reduce((a, b) => a + b, 0) / durations.length\n : 0;\n\n const delegatedTotal = sessions.reduce((a, s) => a + s.DelegatedRunCount, 0);\n const delegatedPerSession = sessions.length > 0 ? delegatedTotal / sessions.length : 0;\n const janitorCloses = sessions.filter(s => s.IsJanitorClosed).length;\n const totalCost = sessions.reduce((a, s) => a + s.TotalCost, 0);\n\n const trendPct = priorCount > 0\n ? Math.round(((startedInWindow.length - priorCount) / priorCount) * 100)\n : 0;\n\n this.KPICards = [\n {\n title: 'Active sessions',\n value: activeCount,\n subtitle: 'live right now',\n icon: 'fa-tower-broadcast',\n color: 'success'\n },\n {\n title: `Sessions (${this.TimeRange})`,\n value: startedInWindow.length,\n icon: 'fa-calendar-day',\n color: 'primary',\n trend: priorCount > 0 ? {\n direction: trendPct > 0 ? 'up' : trendPct < 0 ? 'down' : 'stable',\n percentage: Math.abs(trendPct),\n period: `vs prior ${this.TimeRange}`\n } : undefined,\n subtitle: priorCount > 0 ? undefined : 'no prior-period data'\n },\n {\n title: 'Avg duration',\n value: FormatSessionDuration(avgDuration),\n subtitle: 'min:sec per session',\n icon: 'fa-stopwatch',\n color: 'info'\n },\n {\n title: 'Delegated runs',\n value: delegatedTotal,\n subtitle: `${delegatedPerSession.toFixed(1)} per session avg`,\n icon: 'fa-diagram-project',\n color: 'info'\n },\n {\n title: 'System closes',\n value: janitorCloses,\n subtitle: `orphan, idle & time-limit closes (${this.TimeRange})`,\n icon: 'fa-broom',\n color: 'warning'\n },\n {\n title: `Cost (${this.TimeRange})`,\n value: FormatSessionCost(totalCost),\n subtitle: 'co-agent + delegated',\n icon: 'fa-coins',\n color: 'danger'\n }\n ];\n }\n\n /**\n * Show every Nth bar label so 24 hourly / 30 daily labels never run into each other. The\n * template counts from the newest bar, so the current bucket always keeps its label.\n */\n public LabelStep(count: number): number {\n return Math.max(1, Math.ceil(count / 12));\n }\n\n private buildTimeBuckets(): void {\n const ds = this.dataset;\n // No sessions in the window: an empty bucket list renders the empty state, not a row of blank bars.\n if (!ds || this.windowSessions.length === 0) { this.TimeBuckets = []; return; }\n\n const hourly = this.TimeRange === '24h';\n const bucketMs = hourly ? 3_600_000 : 86_400_000;\n const bucketCount = Math.max(1, Math.round(ds.WindowMs / bucketMs));\n const now = Date.now();\n const buckets: { start: number; count: number; delegated: number }[] = [];\n for (let i = bucketCount - 1; i >= 0; i--) {\n buckets.push({ start: now - (i + 1) * bucketMs, count: 0, delegated: 0 });\n }\n\n for (const session of this.windowSessions) {\n const t = session.StartedAt.getTime();\n const idx = buckets.findIndex(b => t >= b.start && t < b.start + bucketMs);\n if (idx >= 0) {\n buckets[idx].count++;\n buckets[idx].delegated += session.DelegatedRunCount;\n }\n }\n\n const max = Math.max(1, ...buckets.map(b => b.count));\n this.TimeBuckets = buckets.map((b, i) => {\n const date = new Date(b.start + bucketMs);\n const isLast = i === buckets.length - 1;\n const label = hourly\n ? date.toLocaleTimeString([], { hour: 'numeric' }).toLowerCase()\n : isLast ? 'Today' : date.toLocaleDateString([], { weekday: this.TimeRange === '7d' ? 'short' : undefined, month: this.TimeRange === '7d' ? undefined : 'numeric', day: this.TimeRange === '7d' ? undefined : 'numeric' });\n return {\n Label: label,\n Count: b.count,\n HeightPercent: Math.round((b.count / max) * 100),\n DelegatedHeavy: b.count > 0 && b.delegated / b.count >= 2\n };\n });\n }\n\n private buildChannelShares(): void {\n const counts = new Map<string, number>();\n for (const session of this.windowSessions) {\n for (const name of session.ChannelNames) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n }\n const total = Array.from(counts.values()).reduce((a, b) => a + b, 0);\n if (total === 0) {\n this.ChannelShares = [];\n this.DonutGradient = '';\n return;\n }\n const sorted = Array.from(counts.entries()).sort((a, b) => b[1] - a[1]);\n this.ChannelShares = sorted.map(([name, count], i) => ({\n Name: name,\n Count: count,\n Percent: (count / total) * 100,\n Color: DONUT_COLORS[i % DONUT_COLORS.length]\n }));\n\n let cursor = 0;\n const stops: string[] = [];\n for (const share of this.ChannelShares) {\n const end = cursor + share.Percent;\n stops.push(`${share.Color} ${cursor.toFixed(2)}% ${end.toFixed(2)}%`);\n cursor = end;\n }\n this.DonutGradient = `conic-gradient(${stops.join(', ')})`;\n }\n\n private buildTopTargetAgents(): void {\n const counts = new Map<string, number>();\n for (const session of this.windowSessions) {\n if (session.DelegatedRunCount === 0) continue;\n const name = session.TargetAgentName ?? session.TargetAgentID ?? 'Unknown';\n counts.set(name, (counts.get(name) ?? 0) + session.DelegatedRunCount);\n }\n const sorted = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n const max = Math.max(1, ...sorted.map(([, c]) => c));\n this.TopTargetAgents = sorted.map(([name, count]) => ({\n Name: name,\n Count: count,\n WidthPercent: Math.round((count / max) * 100)\n }));\n }\n\n private buildRecentSessions(): void {\n this.RecentSessions = [...this.windowSessions]\n .sort((a, b) => b.StartedAt.getTime() - a.StartedAt.getTime())\n .slice(0, 8)\n .map(s => {\n const statusDisplay = BuildSessionStatusDisplay(s.Record.Status, s.CloseReason);\n return {\n ID: s.Record.ID,\n Target: s.TargetAgentName ?? s.Record.Agent ?? 'Unknown',\n ViaAgent: s.Record.Agent ?? 'Unknown',\n User: s.Record.User,\n Status: s.Record.Status,\n StatusClass: 'status-pill status-' + s.Record.Status.toLowerCase(),\n StatusLabel: statusDisplay.Label,\n StatusTitle: statusDisplay.Title,\n StatusIcon: statusDisplay.Icon,\n ChannelIcons: s.ChannelNames.map(ChannelIconClass),\n Runs: s.DelegatedRunCount,\n Cost: FormatSessionCost(s.TotalCost),\n Duration: FormatSessionDuration(s.DurationMs)\n };\n });\n }\n\n /** Exposed for testability / template type narrowing. */\n public FormatTokens(value: number): string {\n return FormatTokenCount(value);\n }\n\n /** Window length in ms for the active range (exposed for tests). */\n public get WindowMs(): number {\n return TimeRangeToMs(this.TimeRange);\n }\n}\n\nexport function LoadAnalyticsRealtimeOverview() { /* tree-shaking prevention */ }\n"]}
@@ -12,12 +12,13 @@
12
12
  * share one query shape and one aggregation pass.
13
13
  */
14
14
  import { IMetadataProvider } from '@memberjunction/core';
15
+ import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
15
16
  /**
16
17
  * Why a session was closed, as stamped server-side by `SessionManager.CloseSession`
17
18
  * (mirrors `AIAgentSessionEntity.CloseReason`). `null` means a legacy row closed
18
19
  * before the column existed — rendered as "unknown".
19
20
  */
20
- export type RealtimeSessionCloseReason = 'Error' | 'Explicit' | 'Janitor' | 'Shutdown';
21
+ export type RealtimeSessionCloseReason = NonNullable<MJAIAgentSessionEntity['CloseReason']>;
21
22
  export interface RealtimeSessionRecord {
22
23
  ID: string;
23
24
  AgentID: string;
@@ -77,9 +78,10 @@ export interface RealtimeSessionRollup {
77
78
  */
78
79
  CloseReason: RealtimeSessionCloseReason | null;
79
80
  /**
80
- * `CloseReason === 'Janitor'` — the session was force-closed by the
81
- * lifecycle janitor (startup orphan recovery or staleness sweep) rather
82
- * than ended explicitly. Derived from the real column; the old
81
+ * The session was closed by the system rather than ended by a person: `Idle` (the janitor's staleness sweep),
82
+ * `TimeLimit` (the janitor's deadline sweep, or the browser's deadline alarm once the server verified the claim) or
83
+ * `Janitor` (crash orphan reconciled at startup, and every expiry close recorded before `Idle` and `TimeLimit`
84
+ * existed). All three count toward the "System closes" KPI. Derived from the real column; the old
83
85
  * ClosedAt−LastActiveAt timing heuristic has been retired, so legacy
84
86
  * NULL-reason rows report `false` here and "unknown" in the UI.
85
87
  */