@memberjunction/ng-dashboards 6.2.0-edge.2 → 6.2.0-edge.3

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 (69) hide show
  1. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +12 -1
  2. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -1
  3. package/dist/ComponentStudio/components/form-override-dialog.component.js +128 -81
  4. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -1
  5. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
  6. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  7. package/dist/DataExplorer/data-explorer-dashboard.component.js +47 -13
  8. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  9. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts +107 -0
  10. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts.map +1 -0
  11. package/dist/TelephonyOperations/telephony-operations-agent-context.js +216 -0
  12. package/dist/TelephonyOperations/telephony-operations-agent-context.js.map +1 -0
  13. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +57 -0
  14. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -0
  15. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +805 -0
  16. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -0
  17. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts +37 -0
  18. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts.map +1 -0
  19. package/dist/WorkQueue/components/work-queue-bindings.component.js +210 -0
  20. package/dist/WorkQueue/components/work-queue-bindings.component.js.map +1 -0
  21. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts +70 -0
  22. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts.map +1 -0
  23. package/dist/WorkQueue/components/work-queue-dead-letters.component.js +496 -0
  24. package/dist/WorkQueue/components/work-queue-dead-letters.component.js.map +1 -0
  25. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts +22 -0
  26. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts.map +1 -0
  27. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js +99 -0
  28. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js.map +1 -0
  29. package/dist/WorkQueue/components/work-queue-overview.component.d.ts +29 -0
  30. package/dist/WorkQueue/components/work-queue-overview.component.d.ts.map +1 -0
  31. package/dist/WorkQueue/components/work-queue-overview.component.js +278 -0
  32. package/dist/WorkQueue/components/work-queue-overview.component.js.map +1 -0
  33. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts +59 -0
  34. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts.map +1 -0
  35. package/dist/WorkQueue/components/work-queue-partitions.component.js +359 -0
  36. package/dist/WorkQueue/components/work-queue-partitions.component.js.map +1 -0
  37. package/dist/WorkQueue/services/work-queue-operator.service.d.ts +22 -0
  38. package/dist/WorkQueue/services/work-queue-operator.service.d.ts.map +1 -0
  39. package/dist/WorkQueue/services/work-queue-operator.service.js +44 -0
  40. package/dist/WorkQueue/services/work-queue-operator.service.js.map +1 -0
  41. package/dist/WorkQueue/work-queue-agent-context.d.ts +67 -0
  42. package/dist/WorkQueue/work-queue-agent-context.d.ts.map +1 -0
  43. package/dist/WorkQueue/work-queue-agent-context.js +119 -0
  44. package/dist/WorkQueue/work-queue-agent-context.js.map +1 -0
  45. package/dist/WorkQueue/work-queue-dashboard.component.d.ts +94 -0
  46. package/dist/WorkQueue/work-queue-dashboard.component.d.ts.map +1 -0
  47. package/dist/WorkQueue/work-queue-dashboard.component.js +545 -0
  48. package/dist/WorkQueue/work-queue-dashboard.component.js.map +1 -0
  49. package/dist/WorkQueue/work-queue-types.d.ts +40 -0
  50. package/dist/WorkQueue/work-queue-types.d.ts.map +1 -0
  51. package/dist/WorkQueue/work-queue-types.js +2 -0
  52. package/dist/WorkQueue/work-queue-types.js.map +1 -0
  53. package/dist/core-dashboards.module.d.ts +29 -28
  54. package/dist/core-dashboards.module.d.ts.map +1 -1
  55. package/dist/core-dashboards.module.js +7 -0
  56. package/dist/core-dashboards.module.js.map +1 -1
  57. package/dist/module.d.ts +14 -13
  58. package/dist/module.d.ts.map +1 -1
  59. package/dist/module.js +7 -0
  60. package/dist/module.js.map +1 -1
  61. package/dist/public-api.d.ts +4 -0
  62. package/dist/public-api.d.ts.map +1 -1
  63. package/dist/public-api.js +6 -0
  64. package/dist/public-api.js.map +1 -1
  65. package/dist/work-queue-dashboards.module.d.ts +23 -0
  66. package/dist/work-queue-dashboards.module.d.ts.map +1 -0
  67. package/dist/work-queue-dashboards.module.js +92 -0
  68. package/dist/work-queue-dashboards.module.js.map +1 -0
  69. package/package.json +72 -66
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telephony-operations-dashboard.component.js","sourceRoot":"","sources":["../../src/TelephonyOperations/telephony-operations-dashboard.component.ts","../../src/TelephonyOperations/telephony-operations-dashboard.component.html"],"names":[],"mappings":"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","sourcesContent":["import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport {\n BuildTelephonyOperationsAgentContext,\n CalculateOperationsMetrics,\n FormatCurrency,\n FormatDuration,\n ValidateChannelParam,\n ValidateTimeRangeParam,\n type ChannelFilter,\n type InteractionEventRecordLike,\n type InteractionRecordLike,\n type OperationsMetrics,\n type PhoneNumberRecordLike,\n type TimeRangeFilter,\n} from './telephony-operations-agent-context';\n\n/**\n * TELEPHONY & INTERACTION OPERATIONS DASHBOARD\n *\n * An Explorer L3 dashboard providing operational analytics across phone calls, web realtime\n * sessions, and multi-party meetings.\n *\n * Metrics computed from `MJ: Interactions`, `MJ: Interaction Events`, and `MJ: Phone Numbers`:\n * - Volume by channel (Phone, Web, Meeting) and direction (Inbound, Outbound, Internal)\n * - Answer rate and abandonment rate\n * - Average handle time (AHT) and speed to answer (ASA)\n * - Transfer and escalation volumes\n * - Cost estimates by day and by phone number\n * - Active live calls / sessions in real time\n *\n * Data is loaded in a single batched `RunViews` call and aggregated in memory.\n */\n@RegisterClass(BaseResourceComponent, 'TelephonyOperationsDashboard')\n@RegisterClass(BaseResourceComponent, 'InteractionOperationsDashboard')\n@Component({\n standalone: false,\n selector: 'mj-telephony-operations-dashboard',\n templateUrl: './telephony-operations-dashboard.component.html',\n styleUrls: ['./telephony-operations-dashboard.component.css'],\n})\nexport class TelephonyOperationsDashboardComponent\n extends BaseResourceComponent\n implements OnInit, OnDestroy, AfterViewInit\n{\n public IsLoading = true;\n public ErrorMessage: string | null = null;\n\n public SelectedTimeRange: TimeRangeFilter = '7d';\n public SelectedChannelFilter: ChannelFilter = 'all';\n public SearchQuery = '';\n\n public RawInteractions: InteractionRecordLike[] = [];\n public RawEvents: InteractionEventRecordLike[] = [];\n public RawPhoneNumbers: PhoneNumberRecordLike[] = [];\n\n public Metrics: OperationsMetrics = CalculateOperationsMetrics([], [], []);\n\n private refreshTimer: ReturnType<typeof setInterval> | null = null;\n private readonly cdr = inject(ChangeDetectorRef);\n\n override async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Telephony & Interaction Operations';\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-line';\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.LoadData();\n this.NotifyLoadComplete();\n\n // Auto-refresh live status every 15 seconds\n this.refreshTimer = setInterval(() => {\n this.recalculateMetrics();\n this.cdr.markForCheck();\n }, 15000);\n }\n\n ngAfterViewInit(): void {\n this.publishAgentContext();\n this.registerAgentClientTools();\n }\n\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.ErrorMessage = null;\n this.cdr.markForCheck();\n\n try {\n const dateFilterInteractions = this.getDateFilter('StartedAt');\n const dateFilterEvents = this.getDateFilter('OccurredAt');\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const [interactionsResult, eventsResult, phoneNumbersResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Interactions',\n ResultType: 'simple',\n ExtraFilter: dateFilterInteractions,\n OrderBy: 'StartedAt DESC',\n MaxRows: 1000,\n },\n {\n EntityName: 'MJ: Interaction Events',\n ResultType: 'simple',\n ExtraFilter: dateFilterEvents,\n OrderBy: 'OccurredAt DESC',\n MaxRows: 2500,\n },\n {\n EntityName: 'MJ: Phone Numbers',\n ResultType: 'simple',\n ExtraFilter: \"Status = 'Active'\",\n MaxRows: 200,\n },\n ]);\n\n if (interactionsResult.Success && Array.isArray(interactionsResult.Results)) {\n this.RawInteractions = interactionsResult.Results as unknown as InteractionRecordLike[];\n } else {\n this.RawInteractions = [];\n }\n\n if (eventsResult.Success && Array.isArray(eventsResult.Results)) {\n this.RawEvents = eventsResult.Results as unknown as InteractionEventRecordLike[];\n } else {\n this.RawEvents = [];\n }\n\n if (phoneNumbersResult.Success && Array.isArray(phoneNumbersResult.Results)) {\n this.RawPhoneNumbers = phoneNumbersResult.Results as unknown as PhoneNumberRecordLike[];\n } else {\n this.RawPhoneNumbers = [];\n }\n\n this.recalculateMetrics();\n } catch (err) {\n this.ErrorMessage = err instanceof Error ? err.message : String(err);\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n this.publishAgentContext();\n }\n }\n\n public SetTimeRange(range: TimeRangeFilter): void {\n if (this.SelectedTimeRange !== range) {\n this.SelectedTimeRange = range;\n void this.LoadData();\n }\n }\n\n public SetChannelFilter(channel: ChannelFilter): void {\n if (this.SelectedChannelFilter !== channel) {\n this.SelectedChannelFilter = channel;\n this.recalculateMetrics();\n this.cdr.markForCheck();\n this.publishAgentContext();\n }\n }\n\n public OnSearchQueryChange(query: string): void {\n this.SearchQuery = query;\n this.cdr.markForCheck();\n }\n\n public get FilteredLiveInteractions(): OperationsMetrics['LiveInteractions'] {\n if (!this.SearchQuery.trim()) {\n return this.Metrics.LiveInteractions;\n }\n const q = this.SearchQuery.toLowerCase();\n return this.Metrics.LiveInteractions.filter(\n (i) =>\n (i.RemoteAddress && i.RemoteAddress.toLowerCase().includes(q)) ||\n i.Channel.toLowerCase().includes(q) ||\n i.Direction.toLowerCase().includes(q) ||\n i.ID.toLowerCase().includes(q),\n );\n }\n\n public get FilteredRecentInteractions(): InteractionRecordLike[] {\n let rows = this.filteredRawInteractions;\n if (this.SearchQuery.trim()) {\n const q = this.SearchQuery.toLowerCase();\n rows = rows.filter(\n (r) =>\n (r.RemoteAddress && r.RemoteAddress.toLowerCase().includes(q)) ||\n (r.EndReason && r.EndReason.toLowerCase().includes(q)) ||\n r.Channel.toLowerCase().includes(q) ||\n r.Direction.toLowerCase().includes(q) ||\n r.ID.toLowerCase().includes(q),\n );\n }\n return rows.slice(0, 15);\n }\n\n public FormatCost(amount: number | null): string {\n return FormatCurrency(amount ?? 0);\n }\n\n public FormatTime(date: Date | string | null): string {\n if (!date) return '-';\n const d = date instanceof Date ? date : new Date(date);\n return isNaN(d.getTime()) ? '-' : d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n\n public FormatDate(date: Date | string | null): string {\n if (!date) return '-';\n const d = date instanceof Date ? date : new Date(date);\n return isNaN(d.getTime()) ? '-' : d.toLocaleDateString([], { month: 'short', day: 'numeric' });\n }\n\n public ComputeDuration(started: Date | string, ended: Date | string | null): string {\n const s = started instanceof Date ? started : new Date(started);\n if (isNaN(s.getTime())) return '-';\n const e = ended ? (ended instanceof Date ? ended : new Date(ended)) : new Date();\n if (isNaN(e.getTime())) return '-';\n const sec = Math.max(0, Math.floor((e.getTime() - s.getTime()) / 1000));\n return FormatDuration(sec);\n }\n\n private get filteredRawInteractions(): InteractionRecordLike[] {\n if (this.SelectedChannelFilter === 'all') {\n return this.RawInteractions;\n }\n return this.RawInteractions.filter((i) => i.Channel === this.SelectedChannelFilter);\n }\n\n private recalculateMetrics(): void {\n const filtered = this.filteredRawInteractions;\n const activeIds = new Set(filtered.map((i) => i.ID.toLowerCase()));\n const relevantEvents = this.RawEvents.filter((e) => activeIds.has(e.InteractionID.toLowerCase()));\n\n this.Metrics = CalculateOperationsMetrics(filtered, relevantEvents, this.RawPhoneNumbers);\n }\n\n private getDateFilter(field: string): string {\n switch (this.SelectedTimeRange) {\n case '24h':\n return `${field} >= DATEADD(hour, -24, GETUTCDATE())`;\n case '7d':\n return `${field} >= DATEADD(day, -7, GETUTCDATE())`;\n case '30d':\n return `${field} >= DATEADD(day, -30, GETUTCDATE())`;\n case 'all':\n default:\n return '1=1';\n }\n }\n\n private publishAgentContext(): void {\n if (!this.navigationService) return;\n const snapshot = BuildTelephonyOperationsAgentContext(\n this.Metrics,\n this.SelectedTimeRange,\n this.SelectedChannelFilter,\n );\n this.navigationService.SetAgentContext(this, snapshot);\n }\n\n private registerAgentClientTools(): void {\n if (!this.navigationService) return;\n\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RefreshOperationsData',\n Description: 'Refresh telephony and interaction operations data from the database.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.LoadData();\n return { Success: true };\n },\n },\n {\n Name: 'SetTimeRange',\n Description: 'Set the active time range window (24h, 7d, 30d, all).',\n ParameterSchema: {\n type: 'object',\n properties: {\n timeRange: {\n type: 'string',\n description: 'Time range to display: 24h, 7d, 30d, or all',\n enum: ['24h', '7d', '30d', 'all'],\n },\n },\n required: ['timeRange'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const validated = ValidateTimeRangeParam(params['timeRange']);\n if (!validated.ok) {\n return validated.result;\n }\n this.SetTimeRange(validated.value);\n return { Success: true };\n },\n },\n {\n Name: 'FilterByChannel',\n Description: 'Filter operations metrics by interaction channel (all, Phone, Web, Meeting).',\n ParameterSchema: {\n type: 'object',\n properties: {\n channel: {\n type: 'string',\n description: 'Channel to filter: all, Phone, Web, or Meeting',\n enum: ['all', 'Phone', 'Web', 'Meeting'],\n },\n },\n required: ['channel'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const validated = ValidateChannelParam(params['channel']);\n if (!validated.ok) {\n return validated.result;\n }\n this.SetChannelFilter(validated.value);\n return { Success: true };\n },\n },\n ]);\n }\n}\n","<mj-page-layout>\n <mj-page-header\n Title=\"Telephony & Interaction Operations\"\n Subtitle=\"Real-time metrics, volume breakdown, answer rates, and cost analysis across channels\"\n Icon=\"fa-solid fa-chart-line\"\n >\n <div meta>\n <mj-stat-badge\n [Count]=\"Metrics.LiveCallsCount\"\n [Total]=\"Metrics.TotalVolume\"\n Label=\"live now\"\n [Variant]=\"Metrics.LiveCallsCount > 0 ? 'success' : 'default'\"\n />\n </div>\n\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"LoadData()\" />\n </div>\n\n <div toolbar>\n <div class=\"toolbar-controls\">\n <mj-page-search [Value]=\"SearchQuery\" (ValueChange)=\"OnSearchQueryChange($event)\" />\n\n <div class=\"time-range-pills\" role=\"radiogroup\" aria-label=\"Time Range\">\n <button\n type=\"button\"\n class=\"range-pill\"\n [class.active]=\"SelectedTimeRange === '24h'\"\n (click)=\"SetTimeRange('24h')\"\n >\n 24h\n </button>\n <button\n type=\"button\"\n class=\"range-pill\"\n [class.active]=\"SelectedTimeRange === '7d'\"\n (click)=\"SetTimeRange('7d')\"\n >\n 7d\n </button>\n <button\n type=\"button\"\n class=\"range-pill\"\n [class.active]=\"SelectedTimeRange === '30d'\"\n (click)=\"SetTimeRange('30d')\"\n >\n 30d\n </button>\n <button\n type=\"button\"\n class=\"range-pill\"\n [class.active]=\"SelectedTimeRange === 'all'\"\n (click)=\"SetTimeRange('all')\"\n >\n All Time\n </button>\n </div>\n\n <div class=\"channel-filter-pills\" role=\"radiogroup\" aria-label=\"Channel Filter\">\n <button\n type=\"button\"\n class=\"channel-pill\"\n [class.active]=\"SelectedChannelFilter === 'all'\"\n (click)=\"SetChannelFilter('all')\"\n >\n All Channels\n </button>\n <button\n type=\"button\"\n class=\"channel-pill\"\n [class.active]=\"SelectedChannelFilter === 'Phone'\"\n (click)=\"SetChannelFilter('Phone')\"\n >\n <i class=\"fa-solid fa-phone\"></i> Phone\n </button>\n <button\n type=\"button\"\n class=\"channel-pill\"\n [class.active]=\"SelectedChannelFilter === 'Web'\"\n (click)=\"SetChannelFilter('Web')\"\n >\n <i class=\"fa-solid fa-globe\"></i> Web\n </button>\n <button\n type=\"button\"\n class=\"channel-pill\"\n [class.active]=\"SelectedChannelFilter === 'Meeting'\"\n (click)=\"SetChannelFilter('Meeting')\"\n >\n <i class=\"fa-solid fa-users\"></i> Meeting\n </button>\n </div>\n </div>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (ErrorMessage) {\n <div class=\"error-banner\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n\n <!-- KPI Metric Cards Grid -->\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap primary\">\n <i class=\"fa-solid fa-headset\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Total Volume</span>\n <span class=\"kpi-value\">{{ Metrics.TotalVolume }}</span>\n <span class=\"kpi-subtext\">in selected window</span>\n </div>\n </div>\n\n <div class=\"kpi-card\" [class.live-active]=\"Metrics.LiveCallsCount > 0\">\n <div class=\"kpi-icon-wrap success\">\n <span class=\"live-dot-ping\"></span>\n <i class=\"fa-solid fa-phone-volume\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Live Now</span>\n <span class=\"kpi-value\">{{ Metrics.LiveCallsCount }}</span>\n <span class=\"kpi-subtext\">active sessions</span>\n </div>\n </div>\n\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap success\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Answer Rate</span>\n <span class=\"kpi-value\">{{ Metrics.AnswerRate | number:'1.0-1' }}%</span>\n <span class=\"kpi-subtext\">{{ Metrics.AnsweredCount }} answered</span>\n </div>\n </div>\n\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap warning\">\n <i class=\"fa-solid fa-phone-slash\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Abandonment Rate</span>\n <span class=\"kpi-value\">{{ Metrics.AbandonmentRate | number:'1.0-1' }}%</span>\n <span class=\"kpi-subtext\">{{ Metrics.AbandonedCount }} caller abandons</span>\n </div>\n </div>\n\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap info\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Avg Handle Time</span>\n <span class=\"kpi-value\">{{ Metrics.AverageHandleTimeFormatted }}</span>\n <span class=\"kpi-subtext\">ASA: {{ Metrics.AverageSpeedToAnswerFormatted }}</span>\n </div>\n </div>\n\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap accent\">\n <i class=\"fa-solid fa-arrows-split-up-and-left\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Transfers & Esc.</span>\n <span class=\"kpi-value\">{{ Metrics.TransferCount }} / {{ Metrics.EscalationCount }}</span>\n <span class=\"kpi-subtext\">transfers / escalations</span>\n </div>\n </div>\n\n <div class=\"kpi-card\">\n <div class=\"kpi-icon-wrap cost\">\n <i class=\"fa-solid fa-dollar-sign\"></i>\n </div>\n <div class=\"kpi-content\">\n <span class=\"kpi-label\">Total Cost Est.</span>\n <span class=\"kpi-value\">{{ Metrics.TotalCostFormatted }}</span>\n <span class=\"kpi-subtext\">usage & carrier minutes</span>\n </div>\n </div>\n </div>\n\n <!-- Active Live Calls Section -->\n <div class=\"dashboard-section live-section\">\n <div class=\"section-header\">\n <div class=\"section-title\">\n <span class=\"live-pulse-badge\"></span>\n <h2>Active Live Sessions</h2>\n <span class=\"count-pill\">{{ FilteredLiveInteractions.length }}</span>\n </div>\n </div>\n\n @if (FilteredLiveInteractions.length === 0) {\n <div class=\"empty-feed\">\n <i class=\"fa-solid fa-phone-slash empty-icon\"></i>\n <p>No active live interactions at this moment.</p>\n </div>\n } @else {\n <div class=\"live-table-container\">\n <table class=\"ops-table\">\n <thead>\n <tr>\n <th>Remote Address</th>\n <th>Channel</th>\n <th>Direction</th>\n <th>Status</th>\n <th>Started</th>\n <th>Elapsed</th>\n </tr>\n </thead>\n <tbody>\n @for (live of FilteredLiveInteractions; track live.ID) {\n <tr class=\"live-row\">\n <td class=\"address-col\">\n <i class=\"fa-solid fa-user-circle address-icon\"></i>\n <span class=\"address-text\">{{ live.RemoteAddress || 'Unknown' }}</span>\n </td>\n <td>\n <span class=\"badge channel-badge {{ live.Channel.toLowerCase() }}\">\n {{ live.Channel }}\n </span>\n </td>\n <td>\n <span class=\"badge direction-badge {{ live.Direction.toLowerCase() }}\">\n {{ live.Direction }}\n </span>\n </td>\n <td>\n <span class=\"status-indicator active\">\n <span class=\"dot\"></span>\n {{ live.Status }}\n </span>\n </td>\n <td>{{ FormatTime(live.StartedAt) }}</td>\n <td class=\"elapsed-col\">\n <span class=\"elapsed-badge\">{{ live.ElapsedLabel }}</span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n\n <!-- Middle Row: Volume Breakdown Cards -->\n <div class=\"two-col-grid\">\n <!-- Volume by Channel & Direction -->\n <div class=\"dashboard-card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-layer-group\"></i> Volume Distribution</h3>\n </div>\n <div class=\"card-body\">\n <div class=\"distribution-group\">\n <h4>By Channel</h4>\n <div class=\"bars-container\">\n @for (item of Metrics.VolumeByChannel; track item.Channel) {\n <div class=\"bar-row\">\n <div class=\"bar-info\">\n <span class=\"bar-label\">{{ item.Channel }}</span>\n <span class=\"bar-stats\">{{ item.Count }} ({{ item.Percentage }}%)</span>\n </div>\n <div class=\"bar-track\">\n <div class=\"bar-fill channel-{{ item.Channel.toLowerCase() }}\" [style.width.%]=\"item.Percentage\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"distribution-group\">\n <h4>By Direction</h4>\n <div class=\"bars-container\">\n @for (item of Metrics.VolumeByDirection; track item.Direction) {\n <div class=\"bar-row\">\n <div class=\"bar-info\">\n <span class=\"bar-label\">{{ item.Direction }}</span>\n <span class=\"bar-stats\">{{ item.Count }} ({{ item.Percentage }}%)</span>\n </div>\n <div class=\"bar-track\">\n <div class=\"bar-fill direction-{{ item.Direction.toLowerCase() }}\" [style.width.%]=\"item.Percentage\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- Cost by Number -->\n <div class=\"dashboard-card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-money-bill-wave\"></i> Cost by Phone Number</h3>\n </div>\n <div class=\"card-body\">\n @if (Metrics.CostByNumber.length === 0) {\n <div class=\"empty-feed\">\n <p>No phone number cost records in this window.</p>\n </div>\n } @else {\n <div class=\"cost-table-container\">\n <table class=\"ops-table compact\">\n <thead>\n <tr>\n <th>Phone Number / Target</th>\n <th>Calls</th>\n <th class=\"text-right\">Est. Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (num of Metrics.CostByNumber; track num.PhoneNumber) {\n <tr>\n <td class=\"font-medium\">{{ num.PhoneNumber }}</td>\n <td>{{ num.Count }}</td>\n <td class=\"text-right font-semibold\">{{ FormatCost(num.Cost) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Bottom Row: Recent Interactions Audit Table -->\n <div class=\"dashboard-section\">\n <div class=\"section-header\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-list-check\"></i>\n <h2>Recent Interactions</h2>\n <span class=\"count-pill\">{{ FilteredRecentInteractions.length }}</span>\n </div>\n </div>\n\n @if (FilteredRecentInteractions.length === 0) {\n <div class=\"empty-feed\">\n <p>No interactions found matching criteria.</p>\n </div>\n } @else {\n <div class=\"table-container\">\n <table class=\"ops-table\">\n <thead>\n <tr>\n <th>Date / Time</th>\n <th>Remote Party</th>\n <th>Channel</th>\n <th>Direction</th>\n <th>Status</th>\n <th>Duration</th>\n <th>End Reason</th>\n <th class=\"text-right\">Est. Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRecentInteractions; track row.ID) {\n <tr>\n <td>\n <div class=\"datetime-cell\">\n <span class=\"date\">{{ FormatDate(row.StartedAt) }}</span>\n <span class=\"time\">{{ FormatTime(row.StartedAt) }}</span>\n </div>\n </td>\n <td class=\"address-col\">\n <span>{{ row.RemoteAddress || 'Unknown' }}</span>\n </td>\n <td>\n <span class=\"badge channel-badge {{ row.Channel.toLowerCase() }}\">\n {{ row.Channel }}\n </span>\n </td>\n <td>\n <span class=\"badge direction-badge {{ row.Direction.toLowerCase() }}\">\n {{ row.Direction }}\n </span>\n </td>\n <td>\n <span class=\"status-indicator {{ row.Status.toLowerCase() }}\">\n <span class=\"dot\"></span>\n {{ row.Status }}\n </span>\n </td>\n <td>{{ ComputeDuration(row.StartedAt, row.EndedAt) }}</td>\n <td class=\"end-reason-cell\">{{ row.EndReason || '-' }}</td>\n <td class=\"text-right\">{{ FormatCost(row.CostEstimate) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n </mj-page-body>\n</mj-page-layout>\n"]}
@@ -0,0 +1,37 @@
1
+ import { ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import type { IMetadataProvider } from '@memberjunction/core';
3
+ import type { WorkQueueValidateBindingsOutput } from '@memberjunction/core-entities';
4
+ import { WorkQueueOperatorService } from '../services/work-queue-operator.service';
5
+ import type { WorkQueueTransportOption } from '../work-queue-types';
6
+ import * as i0 from "@angular/core";
7
+ type BindingIssue = WorkQueueValidateBindingsOutput['issues'][number];
8
+ /**
9
+ * Runs WorkQueue.ValidateBindings for every transport (or one) and lists the issues by severity. Read-only: the
10
+ * fix is always a metadata or infrastructure change, so each issue links back to its subject in words.
11
+ */
12
+ export declare class WorkQueueBindingsComponent implements OnChanges {
13
+ private readonly operator;
14
+ private readonly cdr;
15
+ Provider: IMetadataProvider;
16
+ Transports: WorkQueueTransportOption[];
17
+ Loaded: EventEmitter<{
18
+ Errors: number;
19
+ Warnings: number;
20
+ }>;
21
+ SelectedTransport: string | null;
22
+ Issues: BindingIssue[];
23
+ IsLoading: boolean;
24
+ HasRun: boolean;
25
+ LoadError: string | null;
26
+ LastRunAt: Date | null;
27
+ constructor(operator: WorkQueueOperatorService, cdr: ChangeDetectorRef);
28
+ ngOnChanges(changes: SimpleChanges): void;
29
+ get Errors(): BindingIssue[];
30
+ get Warnings(): BindingIssue[];
31
+ OnTransportChange(name: string): void;
32
+ Refresh(): Promise<void>;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<WorkQueueBindingsComponent, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<WorkQueueBindingsComponent, "mj-work-queue-bindings", never, { "Provider": { "alias": "Provider"; "required": false; }; "Transports": { "alias": "Transports"; "required": false; }; }, { "Loaded": "Loaded"; }, never, never, false, never>;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=work-queue-bindings.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-queue-bindings.component.d.ts","sourceRoot":"","sources":["../../../src/WorkQueue/components/work-queue-bindings.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,iBAAiB,EAAa,YAAY,EAAS,SAAS,EAAU,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7I,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;;AAEpE,KAAK,YAAY,GAAG,+BAA+B,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;;GAGG;AACH,qBAOa,0BAA2B,YAAW,SAAS;IAY5C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAA4B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAX5E,QAAQ,EAAG,iBAAiB,CAAC;IAC7B,UAAU,EAAE,wBAAwB,EAAE,CAAM;IAC3C,MAAM;gBAA8B,MAAM;kBAAY,MAAM;OAAM;IAErE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,MAAM,EAAE,YAAY,EAAE,CAAM;IAC5B,SAAS,UAAS;IAClB,MAAM,UAAS;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAER,QAAQ,EAAE,wBAAwB,EAAmB,GAAG,EAAE,iBAAiB;IAEjG,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMhD,IAAW,MAAM,IAAI,YAAY,EAAE,CAElC;IAED,IAAW,QAAQ,IAAI,YAAY,EAAE,CAEpC;IAEM,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;yCAjC5B,0BAA0B;2CAA1B,0BAA0B;CAoDtC"}
@@ -0,0 +1,210 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "../services/work-queue-operator.service";
4
+ import * as i2 from "@angular/forms";
5
+ import * as i3 from "@memberjunction/ng-ui-components";
6
+ import * as i4 from "@memberjunction/ng-shared-generic";
7
+ import * as i5 from "@angular/common";
8
+ const _forTrack0 = ($index, $item) => $item.ID;
9
+ const _forTrack1 = ($index, $item) => $item.Subject + $item.Message;
10
+ function WorkQueueBindingsComponent_For_8_Template(rf, ctx) { if (rf & 1) {
11
+ i0.ɵɵelementStart(0, "option", 5);
12
+ i0.ɵɵtext(1);
13
+ i0.ɵɵelementEnd();
14
+ } if (rf & 2) {
15
+ const t_r1 = ctx.$implicit;
16
+ i0.ɵɵproperty("value", t_r1.Name);
17
+ i0.ɵɵadvance();
18
+ i0.ɵɵtextInterpolate2("", t_r1.Name, " (", t_r1.DriverClass, ")");
19
+ } }
20
+ function WorkQueueBindingsComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵelementStart(0, "span", 6);
22
+ i0.ɵɵtext(1);
23
+ i0.ɵɵpipe(2, "date");
24
+ i0.ɵɵelementEnd();
25
+ } if (rf & 2) {
26
+ const ctx_r1 = i0.ɵɵnextContext();
27
+ i0.ɵɵadvance();
28
+ i0.ɵɵtextInterpolate1("Checked ", i0.ɵɵpipeBind2(2, 1, ctx_r1.LastRunAt, "mediumTime"));
29
+ } }
30
+ function WorkQueueBindingsComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelementStart(0, "div", 7);
32
+ i0.ɵɵelement(1, "mj-loading", 10);
33
+ i0.ɵɵelementEnd();
34
+ } }
35
+ function WorkQueueBindingsComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
36
+ i0.ɵɵelement(0, "mj-alert", 8);
37
+ } if (rf & 2) {
38
+ const ctx_r1 = i0.ɵɵnextContext();
39
+ i0.ɵɵproperty("Message", ctx_r1.LoadError);
40
+ } }
41
+ function WorkQueueBindingsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
42
+ i0.ɵɵelement(0, "mj-empty-state", 9);
43
+ } if (rf & 2) {
44
+ const ctx_r1 = i0.ɵɵnextContext();
45
+ i0.ɵɵproperty("Message", "Every topic and subscription" + (ctx_r1.SelectedTransport ? " on " + ctx_r1.SelectedTransport : "") + " resolves to a live transport resource with a compatible driver.");
46
+ } }
47
+ function WorkQueueBindingsComponent_Conditional_13_Conditional_0_For_5_Template(rf, ctx) { if (rf & 1) {
48
+ i0.ɵɵelementStart(0, "div", 15)(1, "span", 16);
49
+ i0.ɵɵtext(2);
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(3, "span", 17);
52
+ i0.ɵɵtext(4);
53
+ i0.ɵɵelementEnd()();
54
+ } if (rf & 2) {
55
+ const issue_r3 = ctx.$implicit;
56
+ i0.ɵɵadvance(2);
57
+ i0.ɵɵtextInterpolate(issue_r3.Subject);
58
+ i0.ɵɵadvance(2);
59
+ i0.ɵɵtextInterpolate(issue_r3.Message);
60
+ } }
61
+ function WorkQueueBindingsComponent_Conditional_13_Conditional_0_Template(rf, ctx) { if (rf & 1) {
62
+ i0.ɵɵelementStart(0, "section", 11)(1, "h3", 13);
63
+ i0.ɵɵelement(2, "i", 14);
64
+ i0.ɵɵtext(3);
65
+ i0.ɵɵelementEnd();
66
+ i0.ɵɵrepeaterCreate(4, WorkQueueBindingsComponent_Conditional_13_Conditional_0_For_5_Template, 5, 2, "div", 15, _forTrack1);
67
+ i0.ɵɵelementEnd();
68
+ } if (rf & 2) {
69
+ const ctx_r1 = i0.ɵɵnextContext(2);
70
+ i0.ɵɵadvance(3);
71
+ i0.ɵɵtextInterpolate2(" ", ctx_r1.Errors.length, " error", ctx_r1.Errors.length === 1 ? "" : "s");
72
+ i0.ɵɵadvance();
73
+ i0.ɵɵrepeater(ctx_r1.Errors);
74
+ } }
75
+ function WorkQueueBindingsComponent_Conditional_13_Conditional_1_For_5_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelementStart(0, "div", 20)(1, "span", 16);
77
+ i0.ɵɵtext(2);
78
+ i0.ɵɵelementEnd();
79
+ i0.ɵɵelementStart(3, "span", 17);
80
+ i0.ɵɵtext(4);
81
+ i0.ɵɵelementEnd()();
82
+ } if (rf & 2) {
83
+ const issue_r4 = ctx.$implicit;
84
+ i0.ɵɵadvance(2);
85
+ i0.ɵɵtextInterpolate(issue_r4.Subject);
86
+ i0.ɵɵadvance(2);
87
+ i0.ɵɵtextInterpolate(issue_r4.Message);
88
+ } }
89
+ function WorkQueueBindingsComponent_Conditional_13_Conditional_1_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵelementStart(0, "section", 11)(1, "h3", 18);
91
+ i0.ɵɵelement(2, "i", 19);
92
+ i0.ɵɵtext(3);
93
+ i0.ɵɵelementEnd();
94
+ i0.ɵɵrepeaterCreate(4, WorkQueueBindingsComponent_Conditional_13_Conditional_1_For_5_Template, 5, 2, "div", 20, _forTrack1);
95
+ i0.ɵɵelementEnd();
96
+ } if (rf & 2) {
97
+ const ctx_r1 = i0.ɵɵnextContext(2);
98
+ i0.ɵɵadvance(3);
99
+ i0.ɵɵtextInterpolate2(" ", ctx_r1.Warnings.length, " warning", ctx_r1.Warnings.length === 1 ? "" : "s");
100
+ i0.ɵɵadvance();
101
+ i0.ɵɵrepeater(ctx_r1.Warnings);
102
+ } }
103
+ function WorkQueueBindingsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
104
+ i0.ɵɵconditionalCreate(0, WorkQueueBindingsComponent_Conditional_13_Conditional_0_Template, 6, 2, "section", 11);
105
+ i0.ɵɵconditionalCreate(1, WorkQueueBindingsComponent_Conditional_13_Conditional_1_Template, 6, 2, "section", 11);
106
+ i0.ɵɵelementStart(2, "p", 12);
107
+ i0.ɵɵtext(3, "Errors stop a host from starting the affected subscription. Warnings are advisory. Fix them in the topology records or the transport's infrastructure, then re-check.");
108
+ i0.ɵɵelementEnd();
109
+ } if (rf & 2) {
110
+ const ctx_r1 = i0.ɵɵnextContext();
111
+ i0.ɵɵconditional(ctx_r1.Errors.length > 0 ? 0 : -1);
112
+ i0.ɵɵadvance();
113
+ i0.ɵɵconditional(ctx_r1.Warnings.length > 0 ? 1 : -1);
114
+ } }
115
+ /**
116
+ * Runs WorkQueue.ValidateBindings for every transport (or one) and lists the issues by severity. Read-only: the
117
+ * fix is always a metadata or infrastructure change, so each issue links back to its subject in words.
118
+ */
119
+ export class WorkQueueBindingsComponent {
120
+ operator;
121
+ cdr;
122
+ Provider;
123
+ Transports = [];
124
+ Loaded = new EventEmitter();
125
+ SelectedTransport = null;
126
+ Issues = [];
127
+ IsLoading = false;
128
+ HasRun = false;
129
+ LoadError = null;
130
+ LastRunAt = null;
131
+ constructor(operator, cdr) {
132
+ this.operator = operator;
133
+ this.cdr = cdr;
134
+ }
135
+ ngOnChanges(changes) {
136
+ if (changes['Provider'] && this.Provider && !this.HasRun) {
137
+ void this.Refresh();
138
+ }
139
+ }
140
+ get Errors() {
141
+ return this.Issues.filter((i) => i.Severity === 'Error');
142
+ }
143
+ get Warnings() {
144
+ return this.Issues.filter((i) => i.Severity === 'Warning');
145
+ }
146
+ OnTransportChange(name) {
147
+ this.SelectedTransport = name === '' ? null : name;
148
+ void this.Refresh();
149
+ }
150
+ async Refresh() {
151
+ if (!this.Provider)
152
+ return;
153
+ this.IsLoading = true;
154
+ this.LoadError = null;
155
+ this.cdr.markForCheck();
156
+ try {
157
+ const output = await this.operator.ValidateBindings(this.Provider, this.SelectedTransport ?? undefined);
158
+ this.Issues = [...output.issues].sort((a, b) => (a.Severity === b.Severity ? a.Subject.localeCompare(b.Subject) : a.Severity === 'Error' ? -1 : 1));
159
+ this.HasRun = true;
160
+ this.LastRunAt = new Date();
161
+ }
162
+ catch (error) {
163
+ this.Issues = [];
164
+ this.LoadError = error instanceof Error ? error.message : String(error);
165
+ }
166
+ finally {
167
+ this.IsLoading = false;
168
+ this.Loaded.emit({ Errors: this.Errors.length, Warnings: this.Warnings.length });
169
+ this.cdr.markForCheck();
170
+ }
171
+ }
172
+ static ɵfac = function WorkQueueBindingsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || WorkQueueBindingsComponent)(i0.ɵɵdirectiveInject(i1.WorkQueueOperatorService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
173
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WorkQueueBindingsComponent, selectors: [["mj-work-queue-bindings"]], inputs: { Provider: "Provider", Transports: "Transports" }, outputs: { Loaded: "Loaded" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 14, vars: 3, consts: [[1, "wq-panel"], [1, "wq-picker-row"], ["for", "wq-bd-transport", 1, "wq-label"], ["id", "wq-bd-transport", 1, "wq-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "wq-hint"], [1, "wq-loading"], ["Variant", "error", "Title", "Validation could not run", 3, "Message"], ["Variant", "success", "Icon", "fa-solid fa-circle-check", "Title", "Bindings are consistent", 3, "Message"], ["text", "Validating bindings...", "size", "medium"], [1, "wq-issues"], [1, "wq-footnote"], [1, "wq-issues-title", "wq-issues-error"], [1, "fa-solid", "fa-circle-xmark"], [1, "wq-issue", "wq-issue-error"], [1, "wq-issue-subject"], [1, "wq-issue-message"], [1, "wq-issues-title", "wq-issues-warning"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "wq-issue", "wq-issue-warning"]], template: function WorkQueueBindingsComponent_Template(rf, ctx) { if (rf & 1) {
174
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "label", 2);
175
+ i0.ɵɵtext(3, "Transport");
176
+ i0.ɵɵelementEnd();
177
+ i0.ɵɵelementStart(4, "select", 3);
178
+ i0.ɵɵlistener("ngModelChange", function WorkQueueBindingsComponent_Template_select_ngModelChange_4_listener($event) { return ctx.OnTransportChange($event); });
179
+ i0.ɵɵelementStart(5, "option", 4);
180
+ i0.ɵɵtext(6, "All transports");
181
+ i0.ɵɵelementEnd();
182
+ i0.ɵɵrepeaterCreate(7, WorkQueueBindingsComponent_For_8_Template, 2, 3, "option", 5, _forTrack0);
183
+ i0.ɵɵelementEnd();
184
+ i0.ɵɵconditionalCreate(9, WorkQueueBindingsComponent_Conditional_9_Template, 3, 4, "span", 6);
185
+ i0.ɵɵelementEnd();
186
+ i0.ɵɵconditionalCreate(10, WorkQueueBindingsComponent_Conditional_10_Template, 2, 0, "div", 7)(11, WorkQueueBindingsComponent_Conditional_11_Template, 1, 1, "mj-alert", 8)(12, WorkQueueBindingsComponent_Conditional_12_Template, 1, 1, "mj-empty-state", 9)(13, WorkQueueBindingsComponent_Conditional_13_Template, 4, 2);
187
+ i0.ɵɵelementEnd();
188
+ } if (rf & 2) {
189
+ i0.ɵɵadvance(4);
190
+ i0.ɵɵproperty("ngModel", ctx.SelectedTransport ?? "");
191
+ i0.ɵɵadvance(3);
192
+ i0.ɵɵrepeater(ctx.Transports);
193
+ i0.ɵɵadvance(2);
194
+ i0.ɵɵconditional(ctx.LastRunAt ? 9 : -1);
195
+ i0.ɵɵadvance();
196
+ i0.ɵɵconditional(ctx.IsLoading ? 10 : ctx.LoadError ? 11 : ctx.HasRun && ctx.Issues.length === 0 ? 12 : ctx.HasRun ? 13 : -1);
197
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJAlertComponent, i3.MJEmptyStateComponent, i4.LoadingComponent, i5.DatePipe], styles: [".wq-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.wq-picker-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.wq-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-select[_ngcontent-%COMP%] {\n min-width: 280px;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.wq-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}\n\n.wq-hint[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n.wq-loading[_ngcontent-%COMP%] {\n padding: 40px 0;\n}\n\n.wq-issues[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.wq-issues-title[_ngcontent-%COMP%] {\n margin: 0 0 4px;\n font-size: 0.85rem;\n font-weight: 600;\n}\n\n.wq-issues-error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n}\n\n.wq-issues-warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text);\n}\n\n.wq-issue[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) 3fr;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n font-size: 0.85rem;\n}\n\n.wq-issue-error[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-status-error);\n}\n\n.wq-issue-warning[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n.wq-issue-subject[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.wq-issue-message[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.wq-footnote[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 800px) {\n .wq-issue[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .wq-select[_ngcontent-%COMP%] {\n min-width: 0;\n width: 100%;\n }\n}"], changeDetection: 0 });
198
+ }
199
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WorkQueueBindingsComponent, [{
200
+ type: Component,
201
+ args: [{ standalone: false, selector: 'mj-work-queue-bindings', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"wq-panel\">\n <div class=\"wq-picker-row\">\n <label class=\"wq-label\" for=\"wq-bd-transport\">Transport</label>\n <select id=\"wq-bd-transport\" class=\"wq-select\" [ngModel]=\"SelectedTransport ?? ''\" (ngModelChange)=\"OnTransportChange($event)\">\n <option value=\"\">All transports</option>\n @for (t of Transports; track t.ID) {\n <option [value]=\"t.Name\">{{ t.Name }} ({{ t.DriverClass }})</option>\n }\n </select>\n @if (LastRunAt) {\n <span class=\"wq-hint\">Checked {{ LastRunAt | date:'mediumTime' }}</span>\n }\n </div>\n\n @if (IsLoading) {\n <div class=\"wq-loading\"><mj-loading text=\"Validating bindings...\" size=\"medium\"></mj-loading></div>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" Title=\"Validation could not run\" [Message]=\"LoadError\"></mj-alert>\n } @else if (HasRun && Issues.length === 0) {\n <mj-empty-state Variant=\"success\" Icon=\"fa-solid fa-circle-check\" Title=\"Bindings are consistent\"\n [Message]=\"'Every topic and subscription' + (SelectedTransport ? ' on ' + SelectedTransport : '') + ' resolves to a live transport resource with a compatible driver.'\" />\n } @else if (HasRun) {\n @if (Errors.length > 0) {\n <section class=\"wq-issues\">\n <h3 class=\"wq-issues-title wq-issues-error\"><i class=\"fa-solid fa-circle-xmark\"></i> {{ Errors.length }} error{{ Errors.length === 1 ? '' : 's' }}</h3>\n @for (issue of Errors; track issue.Subject + issue.Message) {\n <div class=\"wq-issue wq-issue-error\">\n <span class=\"wq-issue-subject\">{{ issue.Subject }}</span>\n <span class=\"wq-issue-message\">{{ issue.Message }}</span>\n </div>\n }\n </section>\n }\n @if (Warnings.length > 0) {\n <section class=\"wq-issues\">\n <h3 class=\"wq-issues-title wq-issues-warning\"><i class=\"fa-solid fa-triangle-exclamation\"></i> {{ Warnings.length }} warning{{ Warnings.length === 1 ? '' : 's' }}</h3>\n @for (issue of Warnings; track issue.Subject + issue.Message) {\n <div class=\"wq-issue wq-issue-warning\">\n <span class=\"wq-issue-subject\">{{ issue.Subject }}</span>\n <span class=\"wq-issue-message\">{{ issue.Message }}</span>\n </div>\n }\n </section>\n }\n <p class=\"wq-footnote\">Errors stop a host from starting the affected subscription. Warnings are advisory. Fix them in the topology records or the transport's infrastructure, then re-check.</p>\n }\n</div>\n", styles: [".wq-panel {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.wq-picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.wq-label {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-select {\n min-width: 280px;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.wq-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}\n\n.wq-hint {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n.wq-loading {\n padding: 40px 0;\n}\n\n.wq-issues {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.wq-issues-title {\n margin: 0 0 4px;\n font-size: 0.85rem;\n font-weight: 600;\n}\n\n.wq-issues-error {\n color: var(--mj-status-error-text);\n}\n\n.wq-issues-warning {\n color: var(--mj-status-warning-text);\n}\n\n.wq-issue {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) 3fr;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n font-size: 0.85rem;\n}\n\n.wq-issue-error {\n border-left: 3px solid var(--mj-status-error);\n}\n\n.wq-issue-warning {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n.wq-issue-subject {\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.wq-issue-message {\n color: var(--mj-text-secondary);\n}\n\n.wq-footnote {\n margin: 0;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 800px) {\n .wq-issue {\n grid-template-columns: 1fr;\n }\n .wq-select {\n min-width: 0;\n width: 100%;\n }\n}\n"] }]
202
+ }], () => [{ type: i1.WorkQueueOperatorService }, { type: i0.ChangeDetectorRef }], { Provider: [{
203
+ type: Input
204
+ }], Transports: [{
205
+ type: Input
206
+ }], Loaded: [{
207
+ type: Output
208
+ }] }); })();
209
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WorkQueueBindingsComponent, { className: "WorkQueueBindingsComponent", filePath: "src/WorkQueue/components/work-queue-bindings.component.ts", lineNumber: 20 }); })();
210
+ //# sourceMappingURL=work-queue-bindings.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-queue-bindings.component.js","sourceRoot":"","sources":["../../../src/WorkQueue/components/work-queue-bindings.component.ts","../../../src/WorkQueue/components/work-queue-bindings.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';\nimport type { IMetadataProvider } from '@memberjunction/core';\nimport type { WorkQueueValidateBindingsOutput } from '@memberjunction/core-entities';\nimport { WorkQueueOperatorService } from '../services/work-queue-operator.service';\nimport type { WorkQueueTransportOption } from '../work-queue-types';\n\ntype BindingIssue = WorkQueueValidateBindingsOutput['issues'][number];\n\n/**\n * Runs WorkQueue.ValidateBindings for every transport (or one) and lists the issues by severity. Read-only: the\n * fix is always a metadata or infrastructure change, so each issue links back to its subject in words.\n */\n@Component({\n standalone: false,\n selector: 'mj-work-queue-bindings',\n templateUrl: './work-queue-bindings.component.html',\n styleUrls: ['./work-queue-bindings.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class WorkQueueBindingsComponent implements OnChanges {\n @Input() Provider!: IMetadataProvider;\n @Input() Transports: WorkQueueTransportOption[] = [];\n @Output() Loaded = new EventEmitter<{ Errors: number; Warnings: number }>();\n\n public SelectedTransport: string | null = null;\n public Issues: BindingIssue[] = [];\n public IsLoading = false;\n public HasRun = false;\n public LoadError: string | null = null;\n public LastRunAt: Date | null = null;\n\n constructor(private readonly operator: WorkQueueOperatorService, private readonly cdr: ChangeDetectorRef) {}\n\n public ngOnChanges(changes: SimpleChanges): void {\n if (changes['Provider'] && this.Provider && !this.HasRun) {\n void this.Refresh();\n }\n }\n\n public get Errors(): BindingIssue[] {\n return this.Issues.filter((i) => i.Severity === 'Error');\n }\n\n public get Warnings(): BindingIssue[] {\n return this.Issues.filter((i) => i.Severity === 'Warning');\n }\n\n public OnTransportChange(name: string): void {\n this.SelectedTransport = name === '' ? null : name;\n void this.Refresh();\n }\n\n public async Refresh(): Promise<void> {\n if (!this.Provider) return;\n this.IsLoading = true;\n this.LoadError = null;\n this.cdr.markForCheck();\n try {\n const output = await this.operator.ValidateBindings(this.Provider, this.SelectedTransport ?? undefined);\n this.Issues = [...output.issues].sort((a, b) => (a.Severity === b.Severity ? a.Subject.localeCompare(b.Subject) : a.Severity === 'Error' ? -1 : 1));\n this.HasRun = true;\n this.LastRunAt = new Date();\n } catch (error) {\n this.Issues = [];\n this.LoadError = error instanceof Error ? error.message : String(error);\n } finally {\n this.IsLoading = false;\n this.Loaded.emit({ Errors: this.Errors.length, Warnings: this.Warnings.length });\n this.cdr.markForCheck();\n }\n }\n}\n","<div class=\"wq-panel\">\n <div class=\"wq-picker-row\">\n <label class=\"wq-label\" for=\"wq-bd-transport\">Transport</label>\n <select id=\"wq-bd-transport\" class=\"wq-select\" [ngModel]=\"SelectedTransport ?? ''\" (ngModelChange)=\"OnTransportChange($event)\">\n <option value=\"\">All transports</option>\n @for (t of Transports; track t.ID) {\n <option [value]=\"t.Name\">{{ t.Name }} ({{ t.DriverClass }})</option>\n }\n </select>\n @if (LastRunAt) {\n <span class=\"wq-hint\">Checked {{ LastRunAt | date:'mediumTime' }}</span>\n }\n </div>\n\n @if (IsLoading) {\n <div class=\"wq-loading\"><mj-loading text=\"Validating bindings...\" size=\"medium\"></mj-loading></div>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" Title=\"Validation could not run\" [Message]=\"LoadError\"></mj-alert>\n } @else if (HasRun && Issues.length === 0) {\n <mj-empty-state Variant=\"success\" Icon=\"fa-solid fa-circle-check\" Title=\"Bindings are consistent\"\n [Message]=\"'Every topic and subscription' + (SelectedTransport ? ' on ' + SelectedTransport : '') + ' resolves to a live transport resource with a compatible driver.'\" />\n } @else if (HasRun) {\n @if (Errors.length > 0) {\n <section class=\"wq-issues\">\n <h3 class=\"wq-issues-title wq-issues-error\"><i class=\"fa-solid fa-circle-xmark\"></i> {{ Errors.length }} error{{ Errors.length === 1 ? '' : 's' }}</h3>\n @for (issue of Errors; track issue.Subject + issue.Message) {\n <div class=\"wq-issue wq-issue-error\">\n <span class=\"wq-issue-subject\">{{ issue.Subject }}</span>\n <span class=\"wq-issue-message\">{{ issue.Message }}</span>\n </div>\n }\n </section>\n }\n @if (Warnings.length > 0) {\n <section class=\"wq-issues\">\n <h3 class=\"wq-issues-title wq-issues-warning\"><i class=\"fa-solid fa-triangle-exclamation\"></i> {{ Warnings.length }} warning{{ Warnings.length === 1 ? '' : 's' }}</h3>\n @for (issue of Warnings; track issue.Subject + issue.Message) {\n <div class=\"wq-issue wq-issue-warning\">\n <span class=\"wq-issue-subject\">{{ issue.Subject }}</span>\n <span class=\"wq-issue-message\">{{ issue.Message }}</span>\n </div>\n }\n </section>\n }\n <p class=\"wq-footnote\">Errors stop a host from starting the affected subscription. Warnings are advisory. Fix them in the topology records or the transport's infrastructure, then re-check.</p>\n }\n</div>\n"]}
@@ -0,0 +1,70 @@
1
+ import { ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import type { IMetadataProvider } from '@memberjunction/core';
3
+ import type { WorkQueueDeadLetterRow } from '@memberjunction/core-entities';
4
+ import { WorkQueueOperatorService } from '../services/work-queue-operator.service';
5
+ import type { WorkQueueSubscriptionOption } from '../work-queue-types';
6
+ import * as i0 from "@angular/core";
7
+ /** One per-item outcome of a bulk replay or discard, shown until the next action. */
8
+ export interface WorkQueueActionOutcome {
9
+ DeliveryID: string;
10
+ Ok: boolean;
11
+ Message: string;
12
+ }
13
+ /**
14
+ * Dead-letter browser for one subscription: list (best-effort scan on cloud transports), envelope viewer, and the
15
+ * replay / discard actions, which loop the single-item operations client-side and report per-item results.
16
+ */
17
+ export declare class WorkQueueDeadLettersComponent implements OnChanges {
18
+ private readonly operator;
19
+ private readonly cdr;
20
+ Provider: IMetadataProvider;
21
+ Subscriptions: WorkQueueSubscriptionOption[];
22
+ SelectedSubscription: string | null;
23
+ /** Update on MJ: Work Queue Subscriptions — replay and discard are disabled without it. */
24
+ CanOperate: boolean;
25
+ SelectedSubscriptionChange: EventEmitter<string | null>;
26
+ /** Emitted after a replay or discard changed something, so the dashboard refreshes stats. */
27
+ Changed: EventEmitter<void>;
28
+ Loaded: EventEmitter<{
29
+ Count: number;
30
+ Selected: number;
31
+ }>;
32
+ Items: WorkQueueDeadLetterRow[];
33
+ Supported: boolean;
34
+ IsLoading: boolean;
35
+ LoadError: string | null;
36
+ ExpandedID: string | null;
37
+ Selected: Set<string>;
38
+ ConfirmReplayVisible: boolean;
39
+ DiscardVisible: boolean;
40
+ ActionInProgress: boolean;
41
+ Outcomes: WorkQueueActionOutcome[];
42
+ constructor(operator: WorkQueueOperatorService, cdr: ChangeDetectorRef);
43
+ ngOnChanges(changes: SimpleChanges): void;
44
+ get Current(): WorkQueueSubscriptionOption | undefined;
45
+ get IsBestEffort(): boolean;
46
+ get SelectedCount(): number;
47
+ get AllSelected(): boolean;
48
+ OnSubscriptionChange(name: string): void;
49
+ Refresh(): Promise<void>;
50
+ ToggleExpanded(id: string): void;
51
+ ToggleSelected(id: string, event: Event): void;
52
+ ToggleAll(): void;
53
+ Age(seconds: number | null | undefined): string;
54
+ PrettyPayload(item: WorkQueueDeadLetterRow): string;
55
+ AttributeEntries(item: WorkQueueDeadLetterRow): {
56
+ Key: string;
57
+ Value: string;
58
+ }[];
59
+ /** How many waiting items a discard of the selected blocking heads would release, for the confirmation text. */
60
+ get DiscardMessage(): string;
61
+ RequestReplay(): void;
62
+ RequestDiscard(): void;
63
+ ReplaySelected(): Promise<void>;
64
+ DiscardSelected(reason: string): Promise<void>;
65
+ private runForSelected;
66
+ private emitLoaded;
67
+ static ɵfac: i0.ɵɵFactoryDeclaration<WorkQueueDeadLettersComponent, never>;
68
+ static ɵcmp: i0.ɵɵComponentDeclaration<WorkQueueDeadLettersComponent, "mj-work-queue-dead-letters", never, { "Provider": { "alias": "Provider"; "required": false; }; "Subscriptions": { "alias": "Subscriptions"; "required": false; }; "SelectedSubscription": { "alias": "SelectedSubscription"; "required": false; }; "CanOperate": { "alias": "CanOperate"; "required": false; }; }, { "SelectedSubscriptionChange": "SelectedSubscriptionChange"; "Changed": "Changed"; "Loaded": "Loaded"; }, never, never, false, never>;
69
+ }
70
+ //# sourceMappingURL=work-queue-dead-letters.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-queue-dead-letters.component.d.ts","sourceRoot":"","sources":["../../../src/WorkQueue/components/work-queue-dead-letters.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,iBAAiB,EAAa,YAAY,EAAS,SAAS,EAAU,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7I,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAEnF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;;AAEvE,qFAAqF;AACrF,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,qBAOa,6BAA8B,YAAW,SAAS;IAsB/C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAA4B,OAAO,CAAC,QAAQ,CAAC,GAAG;IArB5E,QAAQ,EAAG,iBAAiB,CAAC;IAC7B,aAAa,EAAE,2BAA2B,EAAE,CAAM;IAClD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpD,2FAA2F;IAClF,UAAU,UAAS;IAClB,0BAA0B,8BAAqC;IACzE,6FAA6F;IACnF,OAAO,qBAA4B;IACnC,MAAM;eAA6B,MAAM;kBAAY,MAAM;OAAM;IAEpE,KAAK,EAAE,sBAAsB,EAAE,CAAM;IACrC,SAAS,UAAQ;IACjB,SAAS,UAAS;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IACjC,QAAQ,cAAqB;IAC7B,oBAAoB,UAAS;IAC7B,cAAc,UAAS;IACvB,gBAAgB,UAAS;IACzB,QAAQ,EAAE,sBAAsB,EAAE,CAAM;gBAElB,QAAQ,EAAE,wBAAwB,EAAmB,GAAG,EAAE,iBAAiB;IAEjG,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMhD,IAAW,OAAO,IAAI,2BAA2B,GAAG,SAAS,CAE5D;IAED,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,WAAW,IAAI,OAAO,CAEhC;IAEM,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B9B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAM9C,SAAS,IAAI,IAAI;IAKjB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAI/C,aAAa,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM;IAYnD,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE;IAIvF,gHAAgH;IAChH,IAAW,cAAc,IAAI,MAAM,CAIlC;IAEM,aAAa,IAAI,IAAI;IAIrB,cAAc,IAAI,IAAI;IAIhB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAO7C,cAAc;IAoB5B,OAAO,CAAC,UAAU;yCA/JT,6BAA6B;2CAA7B,6BAA6B;CAkKzC"}