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

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 (143) hide show
  1. package/README.md +28 -0
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +15 -7
  5. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +7 -1
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +209 -57
  9. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +12 -11
  11. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -1
  12. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +15 -15
  13. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -1
  14. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  15. package/dist/AI/components/execution-monitoring.component.js +28 -16
  16. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  17. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
  18. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
  19. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +30 -6
  20. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  21. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -1
  22. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  23. package/dist/AI/components/tags/tags-resource.component.js +15 -7
  24. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  25. package/dist/AI/components/vectors/sensitive-fields.d.ts +9 -4
  26. package/dist/AI/components/vectors/sensitive-fields.d.ts.map +1 -1
  27. package/dist/AI/components/vectors/sensitive-fields.js +39 -14
  28. package/dist/AI/components/vectors/sensitive-fields.js.map +1 -1
  29. package/dist/AI/components/vectors/vector-document-rules.d.ts +13 -0
  30. package/dist/AI/components/vectors/vector-document-rules.d.ts.map +1 -1
  31. package/dist/AI/components/vectors/vector-document-rules.js +14 -0
  32. package/dist/AI/components/vectors/vector-document-rules.js.map +1 -1
  33. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +34 -14
  34. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  35. package/dist/AI/components/vectors/vector-management-resource.component.js +127 -50
  36. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  37. package/dist/AI/components/vectors/vector-store-selection.d.ts +32 -0
  38. package/dist/AI/components/vectors/vector-store-selection.d.ts.map +1 -0
  39. package/dist/AI/components/vectors/vector-store-selection.js +57 -0
  40. package/dist/AI/components/vectors/vector-store-selection.js.map +1 -0
  41. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts +236 -0
  42. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts.map +1 -0
  43. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js +374 -0
  44. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js.map +1 -0
  45. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts +195 -0
  46. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts.map +1 -0
  47. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js +2910 -0
  48. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js.map +1 -0
  49. package/dist/ChiefOfStaff/index.d.ts +3 -0
  50. package/dist/ChiefOfStaff/index.d.ts.map +1 -0
  51. package/dist/ChiefOfStaff/index.js +3 -0
  52. package/dist/ChiefOfStaff/index.js.map +1 -0
  53. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  54. package/dist/Communication/communication-logs-resource.component.js +2 -1
  55. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  56. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  57. package/dist/Communication/communication-monitor-resource.component.js +23 -18
  58. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  59. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  60. package/dist/Communication/communication-runs-resource.component.js +11 -10
  61. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  62. package/dist/DashboardEditor/dashboard-editor.component.d.ts +17 -2
  63. package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -1
  64. package/dist/DashboardEditor/dashboard-editor.component.js +94 -43
  65. package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -1
  66. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +24 -0
  67. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  68. package/dist/DataExplorer/data-explorer-dashboard.component.js +146 -50
  69. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  70. package/dist/DataExplorer/models/explorer-state.interface.d.ts +2 -0
  71. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  72. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  73. package/dist/LoginStudio/login-studio-resource.component.d.ts +10 -2
  74. package/dist/LoginStudio/login-studio-resource.component.d.ts.map +1 -1
  75. package/dist/LoginStudio/login-studio-resource.component.js +110 -77
  76. package/dist/LoginStudio/login-studio-resource.component.js.map +1 -1
  77. package/dist/MCP/mcp-dashboard.component.d.ts +24 -4
  78. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  79. package/dist/MCP/mcp-dashboard.component.js +118 -65
  80. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  81. package/dist/PredictiveStudio/business-predictions.view-models.d.ts +1 -1
  82. package/dist/PredictiveStudio/business-predictions.view-models.d.ts.map +1 -1
  83. package/dist/PredictiveStudio/business-predictions.view-models.js +3 -3
  84. package/dist/PredictiveStudio/business-predictions.view-models.js.map +1 -1
  85. package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +6 -63
  86. package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
  87. package/dist/PredictiveStudio/components/ps-experiments.component.js +256 -521
  88. package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
  89. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +0 -18
  90. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -1
  91. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +122 -249
  92. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -1
  93. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +5 -9
  94. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
  95. package/dist/PredictiveStudio/components/ps-pipelines.component.js +98 -130
  96. package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
  97. package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +53 -4
  98. package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -1
  99. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +335 -326
  100. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -1
  101. package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts +19 -0
  102. package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts.map +1 -0
  103. package/dist/PredictiveStudio/components/ps-row-drivers.component.js +85 -0
  104. package/dist/PredictiveStudio/components/ps-row-drivers.component.js.map +1 -0
  105. package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts +19 -1
  106. package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts.map +1 -1
  107. package/dist/PredictiveStudio/engine/predictive-studio.engine.js +51 -2
  108. package/dist/PredictiveStudio/engine/predictive-studio.engine.js.map +1 -1
  109. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts +3 -1
  110. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts.map +1 -1
  111. package/dist/PredictiveStudio/predictive-studio-agent-context.js +3 -0
  112. package/dist/PredictiveStudio/predictive-studio-agent-context.js.map +1 -1
  113. package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +27 -4
  114. package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -1
  115. package/dist/PredictiveStudio/predictive-studio-score-history.service.js +94 -61
  116. package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -1
  117. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +29 -5
  118. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
  119. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +185 -103
  120. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
  121. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +1 -1
  122. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
  123. package/dist/ai-dashboards.module.d.ts +22 -21
  124. package/dist/ai-dashboards.module.d.ts.map +1 -1
  125. package/dist/ai-dashboards.module.js +8 -2
  126. package/dist/ai-dashboards.module.js.map +1 -1
  127. package/dist/public-api.d.ts +2 -0
  128. package/dist/public-api.d.ts.map +1 -1
  129. package/dist/public-api.js +3 -0
  130. package/dist/public-api.js.map +1 -1
  131. package/package.json +71 -71
  132. package/dist/PredictiveStudio/at-risk.view-models.d.ts +0 -120
  133. package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +0 -1
  134. package/dist/PredictiveStudio/at-risk.view-models.js +0 -261
  135. package/dist/PredictiveStudio/at-risk.view-models.js.map +0 -1
  136. package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts +0 -109
  137. package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts.map +0 -1
  138. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js +0 -323
  139. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js.map +0 -1
  140. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +0 -137
  141. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +0 -1
  142. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +0 -826
  143. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"communication-logs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-logs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\n@RegisterClass(BaseResourceComponent, 'CommunicationLogsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-logs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header Title=\"Logs\" Icon=\"fa-solid fa-list-ul\">\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"loadData()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search messages, providers, recipients...\"\n (ValueChange)=\"onSearchValue($event)\">\n </mj-page-search>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"resetFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterValuesChange($event)\"\n (Reset)=\"resetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n </mj-page-header>\n <mj-page-body [Flex]=\"true\">\n <div class=\"logs-card\">\n <div class=\"table-wrapper\">\n <table class=\"log-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Direction</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Date</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (log of filteredLogs; track log) {\n <tr>\n <td>\n <span class=\"log-status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"getStatusIcon(log.Status)\"></i>\n {{log.Status}}\n </span>\n </td>\n <td>\n <span class=\"log-direction\" [ngClass]=\"log.Direction.toLowerCase()\">\n <i [class]=\"log.Direction === 'Sending' ? 'fa-solid fa-arrow-up-right' : 'fa-solid fa-arrow-down-left'\"></i>\n {{log.Direction}}\n </span>\n </td>\n <td>\n <span class=\"log-provider-badge\">\n <i [class]=\"getProviderIcon(log.CommunicationProvider)\" [style.color]=\"getProviderColor(log.CommunicationProvider)\"></i>\n {{log.CommunicationProvider}}\n </span>\n </td>\n <td>{{log.CommunicationProviderMessageType}}</td>\n <td>{{log.MessageDate | date:'medium'}}</td>\n <td>\n @if (log.ErrorMessage) {\n <span class=\"log-error-text\" [title]=\"log.ErrorMessage\">\n {{log.ErrorMessage}}\n </span>\n }\n @if (!log.ErrorMessage) {\n <span class=\"no-error\">&mdash;</span>\n }\n </td>\n </tr>\n }\n @if (filteredLogs.length === 0 && !isLoading) {\n <tr>\n <td colspan=\"6\" class=\"no-data\">\n <mj-empty-state Variant=\"no-results\" Icon=\"fa-solid fa-inbox\"\n Title=\"No logs found matching your criteria\" />\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n /* Card wrapper inside <mj-page-body>: the table sits in a tinted card. */\n .logs-card {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n /* TABLE */\n .table-wrapper { flex: 1; overflow-y: auto; }\n\n .log-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n .log-table thead {\n background: var(--mj-bg-surface-sunken);\n position: sticky; top: 0; z-index: 1;\n }\n .log-table th {\n padding: 10px 16px;\n text-align: left;\n font-weight: 700; font-size: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n }\n .log-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: middle;\n }\n .log-table tbody tr { transition: background 0.15s; }\n .log-table tbody tr:hover { background: var(--mj-bg-surface-sunken); }\n\n .log-status-badge {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n }\n .log-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .log-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .log-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .log-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .log-direction {\n display: flex; align-items: center;\n gap: 4px; font-size: 11px;\n color: var(--mj-text-muted);\n }\n .log-direction i { font-size: 10px; }\n .log-direction.sending i { color: var(--mj-brand-primary); }\n .log-direction.receiving i { color: var(--mj-status-success); }\n\n .log-provider-badge {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 3px 10px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 500;\n }\n\n .log-error-text {\n color: var(--mj-status-error);\n max-width: 200px;\n overflow: hidden; text-overflow: ellipsis;\n white-space: nowrap; font-size: 11px;\n display: block;\n }\n .no-error { color: var(--mj-text-muted); }\n\n .no-data { padding: 0 !important; }\n `]\n})\nexport class CommunicationLogsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public Logs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link Logs}. */\n public get logs(): MJCommunicationLogEntity[] {\n return this.Logs;\n }\n /** @deprecated Use {@link Logs}. */\n public set logs(value: MJCommunicationLogEntity[]) {\n this.Logs = value;\n }\n public FilteredLogs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link FilteredLogs}. */\n public get filteredLogs(): MJCommunicationLogEntity[] {\n return this.FilteredLogs;\n }\n /** @deprecated Use {@link FilteredLogs}. */\n public set filteredLogs(value: MJCommunicationLogEntity[]) {\n this.FilteredLogs = value;\n }\n public isLoading = false;\n public StatusFilter = '';\n\n /** @deprecated Use {@link StatusFilter}. */\n public get statusFilter() {\n return this.StatusFilter;\n }\n /** @deprecated Use {@link StatusFilter}. */\n public set statusFilter(value) {\n this.StatusFilter = value;\n }\n private searchTerm = '';\n\n /** The current free-text search applied to the log list (read-only, for agent context). */\n public get SearchText(): string {\n return this.searchTerm;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 200,\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.Logs = result.Results;\n this.applyFilter();\n }\n } catch (error) {\n console.error('Error loading logs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public OnSearchValue(value: string): void {\n this.searchTerm = (value ?? '').toLowerCase();\n this.applyFilter();\n }\n\n /** @deprecated Use {@link OnSearchValue}. */\n public onSearchValue(value: string): void {\n return this.OnSearchValue(value);\n }\n\n public OnStatusFilter(status: string): void {\n this.StatusFilter = status;\n this.applyFilter();\n }\n\n /** @deprecated Use {@link OnStatusFilter}. */\n public onStatusFilter(status: string): void {\n return this.OnStatusFilter(status);\n }\n\n // -- Concise chrome: Status lives behind the one Filter popover -----------\n\n public get FilterFields(): FilterFieldConfig[] {\n return [{\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: '' },\n { text: 'Sent', value: 'Complete', icon: 'fa-solid fa-check-circle' },\n { text: 'Failed', value: 'Failed', icon: 'fa-solid fa-times-circle' },\n { text: 'Pending', value: 'Pending', icon: 'fa-solid fa-clock' },\n ],\n }];\n }\n\n /** @deprecated Use {@link FilterFields}. */\n public get filterFields(): FilterFieldConfig[] {\n return this.FilterFields;\n }\n\n public get FilterValues(): Record<string, unknown> {\n return { status: this.StatusFilter };\n }\n\n /** @deprecated Use {@link FilterValues}. */\n public get filterValues(): Record<string, unknown> {\n return this.FilterValues;\n }\n\n public get ActiveFilterCount(): number {\n return this.StatusFilter ? 1 : 0;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n this.OnStatusFilter((values['status'] as string) ?? '');\n }\n\n /** @deprecated Use {@link OnFilterValuesChange}. */\n public onFilterValuesChange(values: Record<string, unknown>): void {\n return this.OnFilterValuesChange(values);\n }\n\n public ResetFilters(): void {\n this.OnStatusFilter('');\n }\n\n /** @deprecated Use {@link ResetFilters}. */\n public resetFilters(): void {\n return this.ResetFilters();\n }\n\n public GetStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'pending') return 'pending';\n if (s === 'in-progress') return 'in-progress';\n return '';\n }\n\n /** @deprecated Use {@link GetStatusClass}. */\n public getStatusClass(status: string): string {\n return this.GetStatusClass(status);\n }\n\n public GetStatusIcon(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'fa-solid fa-check';\n if (s === 'failed') return 'fa-solid fa-xmark';\n if (s === 'pending') return 'fa-solid fa-clock';\n if (s === 'in-progress') return 'fa-solid fa-spinner';\n return 'fa-solid fa-circle';\n }\n\n /** @deprecated Use {@link GetStatusIcon}. */\n public getStatusIcon(status: string): string {\n return this.GetStatusIcon(status);\n }\n\n public GetProviderIcon(name: string): string {\n if (!name) return 'fa-solid fa-server';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n /** @deprecated Use {@link GetProviderIcon}. */\n public getProviderIcon(name: string): string {\n return this.GetProviderIcon(name);\n }\n\n public GetProviderColor(name: string): string {\n if (!name) return 'inherit';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return '#1A82E2';\n if (n.includes('twilio')) return '#F22F46';\n if (n.includes('gmail') || n.includes('google')) return '#EA4335';\n if (n.includes('microsoft') || n.includes('graph')) return '#0078D4';\n return 'inherit';\n }\n\n /** @deprecated Use {@link GetProviderColor}. */\n public getProviderColor(name: string): string {\n return this.GetProviderColor(name);\n }\n\n private applyFilter(): void {\n let filtered = this.Logs;\n\n if (this.StatusFilter) {\n filtered = filtered.filter(l => l.Status === this.StatusFilter);\n }\n\n if (this.searchTerm) {\n filtered = filtered.filter(l =>\n l.CommunicationProvider?.toLowerCase().includes(this.searchTerm) ||\n l.CommunicationProviderMessageType?.toLowerCase().includes(this.searchTerm) ||\n l.Status?.toLowerCase().includes(this.searchTerm) ||\n l.ErrorMessage?.toLowerCase().includes(this.searchTerm)\n );\n }\n\n this.FilteredLogs = filtered;\n this.cdr.detectChanges();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Message Logs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-list-ul';\n }\n}\n"]}
1
+ {"version":3,"file":"communication-logs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-logs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\n@RegisterClass(BaseResourceComponent, 'CommunicationLogsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-logs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header Title=\"Logs\" Icon=\"fa-solid fa-list-ul\">\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"loadData()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search messages, providers, recipients...\"\n (ValueChange)=\"onSearchValue($event)\">\n </mj-page-search>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"resetFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterValuesChange($event)\"\n (Reset)=\"resetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n </mj-page-header>\n <mj-page-body [Flex]=\"true\">\n <div class=\"logs-card\">\n <div class=\"table-wrapper\">\n <table class=\"log-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Direction</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Date</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (log of filteredLogs; track log) {\n <tr>\n <td>\n <span class=\"log-status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"getStatusIcon(log.Status)\"></i>\n {{log.Status}}\n </span>\n </td>\n <td>\n <span class=\"log-direction\" [ngClass]=\"log.Direction.toLowerCase()\">\n <i [class]=\"log.Direction === 'Sending' ? 'fa-solid fa-arrow-up-right' : 'fa-solid fa-arrow-down-left'\"></i>\n {{log.Direction}}\n </span>\n </td>\n <td>\n <span class=\"log-provider-badge\">\n <i [class]=\"getProviderIcon(log.CommunicationProvider)\" [style.color]=\"getProviderColor(log.CommunicationProvider)\"></i>\n {{log.CommunicationProvider}}\n </span>\n </td>\n <td>{{log.CommunicationProviderMessageType}}</td>\n <td>{{log.MessageDate | date:'medium'}}</td>\n <td>\n @if (log.ErrorMessage) {\n <span class=\"log-error-text\" [title]=\"log.ErrorMessage\">\n {{log.ErrorMessage}}\n </span>\n }\n @if (!log.ErrorMessage) {\n <span class=\"no-error\">&mdash;</span>\n }\n </td>\n </tr>\n }\n @if (filteredLogs.length === 0 && !isLoading) {\n <tr>\n <td colspan=\"6\" class=\"no-data\">\n <mj-empty-state Variant=\"no-results\" Icon=\"fa-solid fa-inbox\"\n Title=\"No logs found matching your criteria\" />\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n /* Card wrapper inside <mj-page-body>: the table sits in a tinted card. */\n .logs-card {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n /* TABLE */\n .table-wrapper { flex: 1; overflow-y: auto; }\n\n .log-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n .log-table thead {\n background: var(--mj-bg-surface-sunken);\n position: sticky; top: 0; z-index: 1;\n }\n .log-table th {\n padding: 10px 16px;\n text-align: left;\n font-weight: 700; font-size: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n }\n .log-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: middle;\n }\n .log-table tbody tr { transition: background 0.15s; }\n .log-table tbody tr:hover { background: var(--mj-bg-surface-sunken); }\n\n .log-status-badge {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n }\n .log-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .log-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .log-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .log-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .log-direction {\n display: flex; align-items: center;\n gap: 4px; font-size: 11px;\n color: var(--mj-text-muted);\n }\n .log-direction i { font-size: 10px; }\n .log-direction.sending i { color: var(--mj-brand-primary); }\n .log-direction.receiving i { color: var(--mj-status-success); }\n\n .log-provider-badge {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 3px 10px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 500;\n }\n\n .log-error-text {\n color: var(--mj-status-error);\n max-width: 200px;\n overflow: hidden; text-overflow: ellipsis;\n white-space: nowrap; font-size: 11px;\n display: block;\n }\n .no-error { color: var(--mj-text-muted); }\n\n .no-data { padding: 0 !important; }\n `]\n})\nexport class CommunicationLogsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public Logs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link Logs}. */\n public get logs(): MJCommunicationLogEntity[] {\n return this.Logs;\n }\n /** @deprecated Use {@link Logs}. */\n public set logs(value: MJCommunicationLogEntity[]) {\n this.Logs = value;\n }\n public FilteredLogs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link FilteredLogs}. */\n public get filteredLogs(): MJCommunicationLogEntity[] {\n return this.FilteredLogs;\n }\n /** @deprecated Use {@link FilteredLogs}. */\n public set filteredLogs(value: MJCommunicationLogEntity[]) {\n this.FilteredLogs = value;\n }\n public isLoading = false;\n public StatusFilter = '';\n\n /** @deprecated Use {@link StatusFilter}. */\n public get statusFilter() {\n return this.StatusFilter;\n }\n /** @deprecated Use {@link StatusFilter}. */\n public set statusFilter(value) {\n this.StatusFilter = value;\n }\n private searchTerm = '';\n\n /** The current free-text search applied to the log list (read-only, for agent context). */\n public get SearchText(): string {\n return this.searchTerm;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 200,\n Fields: ['ID', 'Status', 'Direction', 'CommunicationProvider', 'CommunicationProviderMessageType', 'MessageDate', 'ErrorMessage'],\n ResultType: 'simple'\n });\n\n if (result.Success) {\n this.Logs = result.Results;\n this.applyFilter();\n }\n } catch (error) {\n console.error('Error loading logs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public OnSearchValue(value: string): void {\n this.searchTerm = (value ?? '').toLowerCase();\n this.applyFilter();\n }\n\n /** @deprecated Use {@link OnSearchValue}. */\n public onSearchValue(value: string): void {\n return this.OnSearchValue(value);\n }\n\n public OnStatusFilter(status: string): void {\n this.StatusFilter = status;\n this.applyFilter();\n }\n\n /** @deprecated Use {@link OnStatusFilter}. */\n public onStatusFilter(status: string): void {\n return this.OnStatusFilter(status);\n }\n\n // -- Concise chrome: Status lives behind the one Filter popover -----------\n\n public get FilterFields(): FilterFieldConfig[] {\n return [{\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: '' },\n { text: 'Sent', value: 'Complete', icon: 'fa-solid fa-check-circle' },\n { text: 'Failed', value: 'Failed', icon: 'fa-solid fa-times-circle' },\n { text: 'Pending', value: 'Pending', icon: 'fa-solid fa-clock' },\n ],\n }];\n }\n\n /** @deprecated Use {@link FilterFields}. */\n public get filterFields(): FilterFieldConfig[] {\n return this.FilterFields;\n }\n\n public get FilterValues(): Record<string, unknown> {\n return { status: this.StatusFilter };\n }\n\n /** @deprecated Use {@link FilterValues}. */\n public get filterValues(): Record<string, unknown> {\n return this.FilterValues;\n }\n\n public get ActiveFilterCount(): number {\n return this.StatusFilter ? 1 : 0;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n this.OnStatusFilter((values['status'] as string) ?? '');\n }\n\n /** @deprecated Use {@link OnFilterValuesChange}. */\n public onFilterValuesChange(values: Record<string, unknown>): void {\n return this.OnFilterValuesChange(values);\n }\n\n public ResetFilters(): void {\n this.OnStatusFilter('');\n }\n\n /** @deprecated Use {@link ResetFilters}. */\n public resetFilters(): void {\n return this.ResetFilters();\n }\n\n public GetStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'pending') return 'pending';\n if (s === 'in-progress') return 'in-progress';\n return '';\n }\n\n /** @deprecated Use {@link GetStatusClass}. */\n public getStatusClass(status: string): string {\n return this.GetStatusClass(status);\n }\n\n public GetStatusIcon(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'fa-solid fa-check';\n if (s === 'failed') return 'fa-solid fa-xmark';\n if (s === 'pending') return 'fa-solid fa-clock';\n if (s === 'in-progress') return 'fa-solid fa-spinner';\n return 'fa-solid fa-circle';\n }\n\n /** @deprecated Use {@link GetStatusIcon}. */\n public getStatusIcon(status: string): string {\n return this.GetStatusIcon(status);\n }\n\n public GetProviderIcon(name: string): string {\n if (!name) return 'fa-solid fa-server';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n /** @deprecated Use {@link GetProviderIcon}. */\n public getProviderIcon(name: string): string {\n return this.GetProviderIcon(name);\n }\n\n public GetProviderColor(name: string): string {\n if (!name) return 'inherit';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return '#1A82E2';\n if (n.includes('twilio')) return '#F22F46';\n if (n.includes('gmail') || n.includes('google')) return '#EA4335';\n if (n.includes('microsoft') || n.includes('graph')) return '#0078D4';\n return 'inherit';\n }\n\n /** @deprecated Use {@link GetProviderColor}. */\n public getProviderColor(name: string): string {\n return this.GetProviderColor(name);\n }\n\n private applyFilter(): void {\n let filtered = this.Logs;\n\n if (this.StatusFilter) {\n filtered = filtered.filter(l => l.Status === this.StatusFilter);\n }\n\n if (this.searchTerm) {\n filtered = filtered.filter(l =>\n l.CommunicationProvider?.toLowerCase().includes(this.searchTerm) ||\n l.CommunicationProviderMessageType?.toLowerCase().includes(this.searchTerm) ||\n l.Status?.toLowerCase().includes(this.searchTerm) ||\n l.ErrorMessage?.toLowerCase().includes(this.searchTerm)\n );\n }\n\n this.FilteredLogs = filtered;\n this.cdr.detectChanges();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Message Logs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-list-ul';\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"communication-monitor-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-monitor-resource.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"communication-monitor-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-monitor-resource.component.ts"],"names":[],"mappings":"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"}
@@ -209,39 +209,43 @@ let CommunicationMonitorResourceComponent = class CommunicationMonitorResourceCo
209
209
  const yesterday = new Date();
210
210
  yesterday.setDate(yesterday.getDate() - 1);
211
211
  const yesterdayIso = yesterday.toISOString();
212
- const [totalResult, failedResult, pendingResult, recentResult, allLogsResult, providersResult] = await Promise.all([
213
- rv.RunView({
212
+ const logFields = ['ID', 'MessageDate', 'Status', 'Direction', 'CommunicationProvider', 'CommunicationProviderMessageType'];
213
+ const [totalResult, failedResult, pendingResult, recentResult, allLogsResult, providersResult] = await rv.RunViews([
214
+ {
214
215
  EntityName: 'MJ: Communication Logs',
215
216
  ExtraFilter: `MessageDate >= '${yesterdayIso}'`,
216
217
  ResultType: 'count_only'
217
- }),
218
- rv.RunView({
218
+ },
219
+ {
219
220
  EntityName: 'MJ: Communication Logs',
220
221
  ExtraFilter: `MessageDate >= '${yesterdayIso}' AND Status = 'Failed'`,
221
222
  ResultType: 'count_only'
222
- }),
223
- rv.RunView({
223
+ },
224
+ {
224
225
  EntityName: 'MJ: Communication Logs',
225
226
  ExtraFilter: `Status = 'Pending'`,
226
227
  ResultType: 'count_only'
227
- }),
228
- rv.RunView({
228
+ },
229
+ {
229
230
  EntityName: 'MJ: Communication Logs',
230
231
  OrderBy: 'MessageDate DESC',
231
232
  MaxRows: 8,
232
- ResultType: 'entity_object'
233
- }),
234
- rv.RunView({
233
+ Fields: logFields,
234
+ ResultType: 'simple'
235
+ },
236
+ {
235
237
  EntityName: 'MJ: Communication Logs',
236
238
  ExtraFilter: `MessageDate >= '${yesterdayIso}'`,
237
239
  OrderBy: 'MessageDate ASC',
238
- ResultType: 'entity_object'
239
- }),
240
- rv.RunView({
240
+ Fields: logFields,
241
+ ResultType: 'simple'
242
+ },
243
+ {
241
244
  EntityName: 'MJ: Communication Providers',
242
245
  OrderBy: 'Name ASC',
243
- ResultType: 'entity_object'
244
- })
246
+ Fields: ['ID', 'Name', 'Status'],
247
+ ResultType: 'simple'
248
+ }
245
249
  ]);
246
250
  if (totalResult.Success)
247
251
  this.Stats.totalSent = totalResult.TotalRowCount;
@@ -256,8 +260,9 @@ let CommunicationMonitorResourceComponent = class CommunicationMonitorResourceCo
256
260
  this.RecentLogs = recentResult.Results;
257
261
  }
258
262
  if (allLogsResult.Success) {
259
- this.ChartData = this.processTrendData(allLogsResult.Results, yesterday);
260
- this.ChannelBreakdown = this.buildChannelBreakdown(allLogsResult.Results);
263
+ const allLogs = allLogsResult.Results;
264
+ this.ChartData = this.processTrendData(allLogs, yesterday);
265
+ this.ChannelBreakdown = this.buildChannelBreakdown(allLogs);
261
266
  }
262
267
  if (providersResult.Success && allLogsResult.Success) {
263
268
  this.ProviderHealth = this.buildProviderHealth(providersResult.Results, allLogsResult.Results);
@@ -1 +1 @@
1
- {"version":3,"file":"communication-monitor-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-monitor-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity, MJCommunicationProviderEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n\ninterface ProviderHealth {\n Name: string;\n Type: string;\n SentCount: number;\n SuccessRate: number;\n IsActive: boolean;\n IconClass: string;\n ColorClass: string;\n}\n\ninterface ChannelBreakdown {\n Name: string;\n IconClass: string;\n Count: number;\n Percentage: number;\n ColorClass: string;\n}\n\ninterface HourlyBucket {\n timestamp: Date;\n executions: number;\n errors: number;\n cost: number;\n tokens: number;\n avgTime: number;\n}\n@RegisterClass(BaseResourceComponent, 'CommunicationMonitorResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-monitor-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Monitor\"\n Icon=\"fa-solid fa-chart-line\"\n Subtitle=\"Live delivery health, provider status, and channel breakdown\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> <span class=\"action-btn-label\">Refresh</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <!-- KPI STRIP -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card sent\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-paper-plane\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Total Sent</span>\n <span class=\"kpi-value\">{{stats.totalSent | number}}</span>\n <span class=\"kpi-delta\" [class]=\"stats.totalSent > 0 ? 'up' : 'neutral'\">\n <i class=\"fa-solid\" [class.fa-arrow-up]=\"stats.totalSent > 0\" [class.fa-minus]=\"stats.totalSent === 0\"></i>\n Last 24 hours\n </span>\n </div>\n </div>\n <div class=\"kpi-card delivered\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-check-double\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Delivery Rate</span>\n <span class=\"kpi-value\">{{stats.deliveryRate}}%</span>\n <div class=\"delivery-bar\">\n <div class=\"delivery-fill\" [style.width.%]=\"stats.deliveryRate\"></div>\n </div>\n </div>\n </div>\n <div class=\"kpi-card pending\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-clock\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Pending</span>\n <span class=\"kpi-value\">{{stats.pending | number}}</span>\n <span class=\"kpi-delta neutral\">\n <i class=\"fa-solid fa-minus\"></i> Awaiting provider\n </span>\n </div>\n </div>\n <div class=\"kpi-card failed\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Failed</span>\n <span class=\"kpi-value\">{{stats.failed | number}}</span>\n <span class=\"kpi-delta\" [class]=\"stats.failed > 0 ? 'down' : 'neutral'\">\n <i class=\"fa-solid\" [class.fa-arrow-up]=\"stats.failed > 0\" [class.fa-minus]=\"stats.failed === 0\"></i>\n {{stats.failed > 0 ? 'Requires attention' : 'No failures'}}\n </span>\n </div>\n </div>\n </div>\n \n <!-- CHARTS + ACTIVITY ROW -->\n <div class=\"content-grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-chart-bar\"></i> Delivery Volume</h3>\n </div>\n <div class=\"chart-container-inner\">\n <app-time-series-chart\n [data]=\"chartData\"\n [showLegend]=\"true\"\n [showControls]=\"false\"\n [config]=\"chartConfig\">\n </app-time-series-chart>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-bolt\"></i> Recent Activity</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"activity-feed\">\n @for (log of recentLogs; track log) {\n <div class=\"activity-item\">\n <div class=\"activity-icon\" [ngClass]=\"getActivityIconClass(log)\">\n <i [class]=\"getActivityIcon(log)\"></i>\n </div>\n <div class=\"activity-body\">\n <span class=\"activity-title\">{{log.CommunicationProviderMessageType || 'Message'}}</span>\n <span class=\"activity-meta\">{{log.CommunicationProvider}} &bull; {{log.MessageDate | date:'shortTime'}}</span>\n </div>\n <span class=\"activity-status\" [ngClass]=\"log.Status.toLowerCase()\">\n {{log.Status}}\n </span>\n </div>\n }\n @if (recentLogs.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-inbox\"\n Title=\"No recent activity\" />\n }\n </div>\n </div>\n </div>\n </div>\n \n <!-- PROVIDER HEALTH + CHANNEL BREAKDOWN -->\n <div class=\"content-grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-heart-pulse\"></i> Provider Health</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"provider-health-list\">\n @for (provider of providerHealth; track provider) {\n <div class=\"provider-row\">\n <div class=\"provider-status-dot\" [class.active]=\"provider.IsActive\"></div>\n <div class=\"provider-logo\" [ngClass]=\"provider.ColorClass\">\n <i [class]=\"provider.IconClass\"></i>\n </div>\n <div class=\"provider-info\">\n <div class=\"provider-name\">{{provider.Name}}</div>\n <div class=\"provider-type\">{{provider.Type}} &bull; {{provider.SentCount}} sent today</div>\n </div>\n <div class=\"provider-health-bar\">\n <div class=\"provider-health-fill\" [ngClass]=\"getHealthClass(provider.SuccessRate)\" [style.width.%]=\"provider.SuccessRate\"></div>\n </div>\n <span class=\"provider-rate\" [ngClass]=\"getHealthClass(provider.SuccessRate)\">{{provider.SuccessRate}}%</span>\n </div>\n }\n @if (providerHealth.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-server\"\n Title=\"No providers configured\" />\n }\n </div>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-layer-group\"></i> Channel Breakdown</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"channel-breakdown\">\n @for (channel of channelBreakdown; track channel) {\n <div class=\"channel-row\">\n <div class=\"channel-icon\" [ngClass]=\"channel.ColorClass\">\n <i [class]=\"channel.IconClass\"></i>\n </div>\n <div class=\"channel-info\">\n <div class=\"channel-name\">{{channel.Name}}</div>\n <div class=\"channel-count\">{{channel.Count | number}} messages</div>\n </div>\n <div class=\"channel-bar-wrapper\">\n <div class=\"channel-bar-fill\" [style.width.%]=\"channel.Percentage\" [style.background]=\"channel.ColorClass === 'email' ? 'var(--mj-brand-primary)' : 'var(--mj-status-success)'\"></div>\n </div>\n <span class=\"channel-pct\">{{channel.Percentage}}%</span>\n </div>\n }\n @if (channelBreakdown.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-layer-group\"\n Title=\"No channel data available\" />\n }\n </div>\n </div>\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n /* KPI STRIP */\n .kpi-strip {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n }\n .kpi-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 20px;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n transition: all 0.15s ease;\n position: relative;\n overflow: hidden;\n }\n .kpi-card:hover {\n box-shadow: 0 2px 8px var(--mj-shadow-md);\n border-color: var(--mj-border-strong);\n }\n .kpi-card::before {\n content: '';\n position: absolute;\n top: 0; left: 0; right: 0;\n height: 3px;\n }\n .kpi-card.sent::before { background: var(--mj-brand-primary); }\n .kpi-card.delivered::before { background: var(--mj-status-success); }\n .kpi-card.pending::before { background: var(--mj-status-warning); }\n .kpi-card.failed::before { background: var(--mj-status-error); }\n\n .kpi-icon {\n width: 44px; height: 44px;\n border-radius: 12px;\n display: flex; align-items: center; justify-content: center;\n font-size: 16px; flex-shrink: 0;\n }\n .kpi-card.sent .kpi-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .kpi-card.delivered .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .kpi-card.pending .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .kpi-card.failed .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .kpi-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }\n .kpi-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n }\n .kpi-value {\n font-size: 28px; font-weight: 800;\n color: var(--mj-text-primary);\n letter-spacing: -0.02em; line-height: 1.1;\n }\n .kpi-delta {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n margin-top: 4px; padding: 2px 8px;\n border-radius: 10px; width: fit-content;\n }\n .kpi-delta.up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .kpi-delta.down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .kpi-delta.neutral {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .delivery-bar {\n height: 6px; margin-top: 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .delivery-fill {\n height: 100%; border-radius: 3px;\n background: var(--mj-status-success); transition: width 0.6s ease;\n }\n\n /* CONTENT GRID */\n .content-grid {\n display: grid;\n grid-template-columns: 1.6fr 1fr;\n gap: 16px;\n margin-bottom: 16px;\n }\n\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n .card-header h3 {\n font-size: 13px; font-weight: 700;\n color: var(--mj-text-primary);\n display: flex; align-items: center; gap: 8px;\n margin: 0;\n }\n .card-header h3 i {\n color: var(--mj-text-muted);\n font-size: 12px;\n }\n .card-body { padding: 16px 20px; }\n .card-body.no-padding { padding: 0; }\n\n .chart-container-inner {\n padding: 16px 20px;\n min-height: 300px;\n }\n\n /* ACTIVITY FEED */\n .activity-feed { max-height: 370px; overflow-y: auto; }\n .activity-item {\n display: flex; align-items: center; gap: 12px;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.15s ease; cursor: pointer;\n }\n .activity-item:last-child { border-bottom: none; }\n .activity-item:hover { background: var(--mj-bg-surface-sunken); }\n\n .activity-icon {\n width: 34px; height: 34px;\n border-radius: 8px;\n display: flex; align-items: center; justify-content: center;\n font-size: 12px; flex-shrink: 0;\n }\n .activity-icon.email {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .activity-icon.sms {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .activity-icon.error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .activity-body { flex: 1; min-width: 0; }\n .activity-title {\n font-size: 12px; font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n display: block;\n }\n .activity-meta {\n font-size: 11px; color: var(--mj-text-muted); margin-top: 1px;\n display: block;\n }\n .activity-status {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n flex-shrink: 0;\n }\n .activity-status.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .activity-status.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .activity-status.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n /* PROVIDER HEALTH */\n .provider-health-list { display: flex; flex-direction: column; }\n .provider-row {\n display: flex; align-items: center; gap: 12px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.15s ease;\n }\n .provider-row:last-child { border-bottom: none; }\n .provider-row:hover { background: var(--mj-bg-surface-sunken); }\n\n .provider-status-dot {\n width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;\n background: var(--mj-border-strong);\n }\n .provider-status-dot.active { background: var(--mj-status-success); }\n\n .provider-logo {\n width: 36px; height: 36px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n display: flex; align-items: center; justify-content: center;\n font-size: 16px; flex-shrink: 0;\n }\n .provider-logo.sendgrid { color: var(--mj-brand-primary); }\n .provider-logo.twilio { color: var(--mj-status-error); }\n .provider-logo.gmail { color: var(--mj-status-error); }\n .provider-logo.msgraph { color: var(--mj-brand-primary); }\n\n .provider-info { flex: 1; }\n .provider-name { font-size: 13px; font-weight: 600; color: var(--mj-text-primary); }\n .provider-type { font-size: 11px; color: var(--mj-text-muted); }\n\n .provider-health-bar {\n width: 80px; height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .provider-health-fill {\n height: 100%; border-radius: 3px;\n transition: width 0.4s ease;\n }\n .provider-health-fill.excellent { background: var(--mj-status-success); }\n .provider-health-fill.good { background: var(--mj-status-success); }\n .provider-health-fill.warning { background: var(--mj-status-warning); }\n .provider-health-fill.critical { background: var(--mj-status-error); }\n\n .provider-rate {\n font-size: 12px; font-weight: 700;\n min-width: 44px; text-align: right;\n }\n .provider-rate.excellent { color: var(--mj-status-success); }\n .provider-rate.good { color: var(--mj-status-success); }\n .provider-rate.warning { color: var(--mj-status-warning); }\n .provider-rate.critical { color: var(--mj-status-error); }\n\n /* CHANNEL BREAKDOWN */\n .channel-breakdown { display: flex; flex-direction: column; }\n .channel-row {\n display: flex; align-items: center; gap: 12px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n .channel-row:last-child { border-bottom: none; }\n .channel-icon {\n width: 32px; height: 32px;\n border-radius: 8px;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px; flex-shrink: 0;\n }\n .channel-icon.email {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .channel-icon.sms {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .channel-info { flex: 1; }\n .channel-name { font-size: 12px; font-weight: 600; color: var(--mj-text-primary); }\n .channel-count { font-size: 11px; color: var(--mj-text-muted); }\n\n .channel-bar-wrapper {\n width: 100px; height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .channel-bar-fill { height: 100%; border-radius: 3px; }\n .channel-pct {\n font-size: 12px; font-weight: 700;\n color: var(--mj-text-primary);\n min-width: 36px; text-align: right;\n }\n\n /* EMPTY STATE */\n\n @media (max-width: 1200px) {\n .kpi-strip { grid-template-columns: repeat(2, 1fr); }\n .content-grid { grid-template-columns: 1fr; }\n }\n `]\n})\nexport class CommunicationMonitorResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = false;\n public Stats = {\n totalSent: 0,\n deliveryRate: 0,\n pending: 0,\n failed: 0\n };\n\n /** @deprecated Use {@link Stats}. */\n public get stats() {\n return this.Stats;\n }\n /** @deprecated Use {@link Stats}. */\n public set stats(value) {\n this.Stats = value;\n }\n public RecentLogs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link RecentLogs}. */\n public get recentLogs(): MJCommunicationLogEntity[] {\n return this.RecentLogs;\n }\n /** @deprecated Use {@link RecentLogs}. */\n public set recentLogs(value: MJCommunicationLogEntity[]) {\n this.RecentLogs = value;\n }\n public ChartData: HourlyBucket[] = [];\n\n /** @deprecated Use {@link ChartData}. */\n public get chartData(): HourlyBucket[] {\n return this.ChartData;\n }\n /** @deprecated Use {@link ChartData}. */\n public set chartData(value: HourlyBucket[]) {\n this.ChartData = value;\n }\n public ChartConfig = {\n useDualAxis: false,\n showGrid: true,\n showTooltip: true,\n colors: ['#4f6bed', '#cf222e']\n };\n\n /** @deprecated Use {@link ChartConfig}. */\n public get chartConfig() {\n return this.ChartConfig;\n }\n /** @deprecated Use {@link ChartConfig}. */\n public set chartConfig(value) {\n this.ChartConfig = value;\n }\n public ProviderHealth: ProviderHealth[] = [];\n\n /** @deprecated Use {@link ProviderHealth}. */\n public get providerHealth(): ProviderHealth[] {\n return this.ProviderHealth;\n }\n /** @deprecated Use {@link ProviderHealth}. */\n public set providerHealth(value: ProviderHealth[]) {\n this.ProviderHealth = value;\n }\n public ChannelBreakdown: ChannelBreakdown[] = [];\n\n /** @deprecated Use {@link ChannelBreakdown}. */\n public get channelBreakdown(): ChannelBreakdown[] {\n return this.ChannelBreakdown;\n }\n /** @deprecated Use {@link ChannelBreakdown}. */\n public set channelBreakdown(value: ChannelBreakdown[]) {\n this.ChannelBreakdown = value;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [totalResult, failedResult, pendingResult, recentResult, allLogsResult, providersResult] = await Promise.all([\n rv.RunView({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `Status = 'Pending'`,\n ResultType: 'count_only'\n }),\n rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 8,\n ResultType: 'entity_object'\n }),\n rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n OrderBy: 'MessageDate ASC',\n ResultType: 'entity_object'\n }),\n rv.RunView<MJCommunicationProviderEntity>({\n EntityName: 'MJ: Communication Providers',\n OrderBy: 'Name ASC',\n ResultType: 'entity_object'\n })\n ]);\n\n if (totalResult.Success) this.Stats.totalSent = totalResult.TotalRowCount;\n if (failedResult.Success) this.Stats.failed = failedResult.TotalRowCount;\n if (pendingResult.Success) this.Stats.pending = pendingResult.TotalRowCount;\n\n this.Stats.deliveryRate = this.Stats.totalSent > 0\n ? parseFloat(((this.Stats.totalSent - this.Stats.failed) / this.Stats.totalSent * 100).toFixed(1))\n : 100;\n\n if (recentResult.Success) {\n this.RecentLogs = recentResult.Results;\n }\n\n if (allLogsResult.Success) {\n this.ChartData = this.processTrendData(allLogsResult.Results, yesterday);\n this.ChannelBreakdown = this.buildChannelBreakdown(allLogsResult.Results);\n }\n\n if (providersResult.Success && allLogsResult.Success) {\n this.ProviderHealth = this.buildProviderHealth(providersResult.Results, allLogsResult.Results);\n }\n\n } catch (error) {\n console.error('Error loading monitor data:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public GetActivityIconClass(log: MJCommunicationLogEntity): string {\n if (log.Status === 'Failed') return 'error';\n const type = (log.CommunicationProviderMessageType || '').toLowerCase();\n if (type.includes('sms')) return 'sms';\n return 'email';\n }\n\n /** @deprecated Use {@link GetActivityIconClass}. */\n public getActivityIconClass(log: MJCommunicationLogEntity): string {\n return this.GetActivityIconClass(log);\n }\n\n public GetActivityIcon(log: MJCommunicationLogEntity): string {\n if (log.Direction === 'Receiving') return 'fa-solid fa-arrow-down';\n const type = (log.CommunicationProviderMessageType || '').toLowerCase();\n if (type.includes('sms')) return 'fa-solid fa-comment-sms';\n return 'fa-solid fa-envelope';\n }\n\n /** @deprecated Use {@link GetActivityIcon}. */\n public getActivityIcon(log: MJCommunicationLogEntity): string {\n return this.GetActivityIcon(log);\n }\n\n public GetHealthClass(rate: number): string {\n if (rate >= 98) return 'excellent';\n if (rate >= 95) return 'good';\n if (rate >= 85) return 'warning';\n return 'critical';\n }\n\n /** @deprecated Use {@link GetHealthClass}. */\n public getHealthClass(rate: number): string {\n return this.GetHealthClass(rate);\n }\n\n private processTrendData(logs: MJCommunicationLogEntity[], startTime: Date): HourlyBucket[] {\n const buckets: HourlyBucket[] = [];\n const now = new Date();\n const current = new Date(startTime);\n current.setMinutes(0, 0, 0);\n\n while (current <= now) {\n const bucketStart = new Date(current);\n const bucketEnd = new Date(current.getTime() + 60 * 60 * 1000);\n const bucketLogs = logs.filter(l => {\n const d = new Date(l.MessageDate);\n return d >= bucketStart && d < bucketEnd;\n });\n\n buckets.push({\n timestamp: bucketStart,\n executions: bucketLogs.length,\n errors: bucketLogs.filter(l => l.Status === 'Failed').length,\n cost: 0,\n tokens: 0,\n avgTime: 0\n });\n current.setHours(current.getHours() + 1);\n }\n return buckets;\n }\n\n private buildProviderHealth(providers: MJCommunicationProviderEntity[], logs: MJCommunicationLogEntity[]): ProviderHealth[] {\n return providers.map(p => {\n const providerLogs = logs.filter(l => l.CommunicationProvider === p.Name);\n const sent = providerLogs.length;\n const failed = providerLogs.filter(l => l.Status === 'Failed').length;\n const rate = sent > 0 ? parseFloat(((sent - failed) / sent * 100).toFixed(1)) : 100;\n\n return {\n Name: p.Name,\n Type: this.getProviderType(p.Name),\n SentCount: sent,\n SuccessRate: rate,\n IsActive: p.Status === 'Active',\n IconClass: this.getProviderIconClass(p.Name),\n ColorClass: this.getProviderColorClass(p.Name)\n };\n });\n }\n\n private buildChannelBreakdown(logs: MJCommunicationLogEntity[]): ChannelBreakdown[] {\n const total = logs.length;\n if (total === 0) return [];\n\n const emailLogs = logs.filter(l => {\n const type = (l.CommunicationProviderMessageType || '').toLowerCase();\n return type.includes('email') || (!type.includes('sms'));\n });\n const smsLogs = logs.filter(l => {\n const type = (l.CommunicationProviderMessageType || '').toLowerCase();\n return type.includes('sms');\n });\n\n const channels: ChannelBreakdown[] = [];\n if (emailLogs.length > 0) {\n channels.push({\n Name: 'Email',\n IconClass: 'fa-solid fa-envelope',\n Count: emailLogs.length,\n Percentage: Math.round((emailLogs.length / total) * 100),\n ColorClass: 'email'\n });\n }\n if (smsLogs.length > 0) {\n channels.push({\n Name: 'SMS',\n IconClass: 'fa-solid fa-comment-sms',\n Count: smsLogs.length,\n Percentage: Math.round((smsLogs.length / total) * 100),\n ColorClass: 'sms'\n });\n }\n return channels;\n }\n\n private getProviderType(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('twilio')) return 'SMS';\n return 'Email';\n }\n\n private getProviderIconClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n private getProviderColorClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'sendgrid';\n if (n.includes('twilio')) return 'twilio';\n if (n.includes('gmail') || n.includes('google')) return 'gmail';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'msgraph';\n return '';\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Monitor';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-line';\n }\n}\n"]}
1
+ {"version":3,"file":"communication-monitor-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-monitor-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity, MJCommunicationProviderEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n\ninterface ProviderHealth {\n Name: string;\n Type: string;\n SentCount: number;\n SuccessRate: number;\n IsActive: boolean;\n IconClass: string;\n ColorClass: string;\n}\n\ninterface ChannelBreakdown {\n Name: string;\n IconClass: string;\n Count: number;\n Percentage: number;\n ColorClass: string;\n}\n\ninterface HourlyBucket {\n timestamp: Date;\n executions: number;\n errors: number;\n cost: number;\n tokens: number;\n avgTime: number;\n}\n@RegisterClass(BaseResourceComponent, 'CommunicationMonitorResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-monitor-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Monitor\"\n Icon=\"fa-solid fa-chart-line\"\n Subtitle=\"Live delivery health, provider status, and channel breakdown\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> <span class=\"action-btn-label\">Refresh</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <!-- KPI STRIP -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card sent\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-paper-plane\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Total Sent</span>\n <span class=\"kpi-value\">{{stats.totalSent | number}}</span>\n <span class=\"kpi-delta\" [class]=\"stats.totalSent > 0 ? 'up' : 'neutral'\">\n <i class=\"fa-solid\" [class.fa-arrow-up]=\"stats.totalSent > 0\" [class.fa-minus]=\"stats.totalSent === 0\"></i>\n Last 24 hours\n </span>\n </div>\n </div>\n <div class=\"kpi-card delivered\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-check-double\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Delivery Rate</span>\n <span class=\"kpi-value\">{{stats.deliveryRate}}%</span>\n <div class=\"delivery-bar\">\n <div class=\"delivery-fill\" [style.width.%]=\"stats.deliveryRate\"></div>\n </div>\n </div>\n </div>\n <div class=\"kpi-card pending\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-clock\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Pending</span>\n <span class=\"kpi-value\">{{stats.pending | number}}</span>\n <span class=\"kpi-delta neutral\">\n <i class=\"fa-solid fa-minus\"></i> Awaiting provider\n </span>\n </div>\n </div>\n <div class=\"kpi-card failed\">\n <div class=\"kpi-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <div class=\"kpi-body\">\n <span class=\"kpi-label\">Failed</span>\n <span class=\"kpi-value\">{{stats.failed | number}}</span>\n <span class=\"kpi-delta\" [class]=\"stats.failed > 0 ? 'down' : 'neutral'\">\n <i class=\"fa-solid\" [class.fa-arrow-up]=\"stats.failed > 0\" [class.fa-minus]=\"stats.failed === 0\"></i>\n {{stats.failed > 0 ? 'Requires attention' : 'No failures'}}\n </span>\n </div>\n </div>\n </div>\n \n <!-- CHARTS + ACTIVITY ROW -->\n <div class=\"content-grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-chart-bar\"></i> Delivery Volume</h3>\n </div>\n <div class=\"chart-container-inner\">\n <app-time-series-chart\n [data]=\"chartData\"\n [showLegend]=\"true\"\n [showControls]=\"false\"\n [config]=\"chartConfig\">\n </app-time-series-chart>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-bolt\"></i> Recent Activity</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"activity-feed\">\n @for (log of recentLogs; track log) {\n <div class=\"activity-item\">\n <div class=\"activity-icon\" [ngClass]=\"getActivityIconClass(log)\">\n <i [class]=\"getActivityIcon(log)\"></i>\n </div>\n <div class=\"activity-body\">\n <span class=\"activity-title\">{{log.CommunicationProviderMessageType || 'Message'}}</span>\n <span class=\"activity-meta\">{{log.CommunicationProvider}} &bull; {{log.MessageDate | date:'shortTime'}}</span>\n </div>\n <span class=\"activity-status\" [ngClass]=\"log.Status.toLowerCase()\">\n {{log.Status}}\n </span>\n </div>\n }\n @if (recentLogs.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-inbox\"\n Title=\"No recent activity\" />\n }\n </div>\n </div>\n </div>\n </div>\n \n <!-- PROVIDER HEALTH + CHANNEL BREAKDOWN -->\n <div class=\"content-grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-heart-pulse\"></i> Provider Health</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"provider-health-list\">\n @for (provider of providerHealth; track provider) {\n <div class=\"provider-row\">\n <div class=\"provider-status-dot\" [class.active]=\"provider.IsActive\"></div>\n <div class=\"provider-logo\" [ngClass]=\"provider.ColorClass\">\n <i [class]=\"provider.IconClass\"></i>\n </div>\n <div class=\"provider-info\">\n <div class=\"provider-name\">{{provider.Name}}</div>\n <div class=\"provider-type\">{{provider.Type}} &bull; {{provider.SentCount}} sent today</div>\n </div>\n <div class=\"provider-health-bar\">\n <div class=\"provider-health-fill\" [ngClass]=\"getHealthClass(provider.SuccessRate)\" [style.width.%]=\"provider.SuccessRate\"></div>\n </div>\n <span class=\"provider-rate\" [ngClass]=\"getHealthClass(provider.SuccessRate)\">{{provider.SuccessRate}}%</span>\n </div>\n }\n @if (providerHealth.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-server\"\n Title=\"No providers configured\" />\n }\n </div>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <h3><i class=\"fa-solid fa-layer-group\"></i> Channel Breakdown</h3>\n </div>\n <div class=\"card-body no-padding\">\n <div class=\"channel-breakdown\">\n @for (channel of channelBreakdown; track channel) {\n <div class=\"channel-row\">\n <div class=\"channel-icon\" [ngClass]=\"channel.ColorClass\">\n <i [class]=\"channel.IconClass\"></i>\n </div>\n <div class=\"channel-info\">\n <div class=\"channel-name\">{{channel.Name}}</div>\n <div class=\"channel-count\">{{channel.Count | number}} messages</div>\n </div>\n <div class=\"channel-bar-wrapper\">\n <div class=\"channel-bar-fill\" [style.width.%]=\"channel.Percentage\" [style.background]=\"channel.ColorClass === 'email' ? 'var(--mj-brand-primary)' : 'var(--mj-status-success)'\"></div>\n </div>\n <span class=\"channel-pct\">{{channel.Percentage}}%</span>\n </div>\n }\n @if (channelBreakdown.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-layer-group\"\n Title=\"No channel data available\" />\n }\n </div>\n </div>\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n /* KPI STRIP */\n .kpi-strip {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n }\n .kpi-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 20px;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n transition: all 0.15s ease;\n position: relative;\n overflow: hidden;\n }\n .kpi-card:hover {\n box-shadow: 0 2px 8px var(--mj-shadow-md);\n border-color: var(--mj-border-strong);\n }\n .kpi-card::before {\n content: '';\n position: absolute;\n top: 0; left: 0; right: 0;\n height: 3px;\n }\n .kpi-card.sent::before { background: var(--mj-brand-primary); }\n .kpi-card.delivered::before { background: var(--mj-status-success); }\n .kpi-card.pending::before { background: var(--mj-status-warning); }\n .kpi-card.failed::before { background: var(--mj-status-error); }\n\n .kpi-icon {\n width: 44px; height: 44px;\n border-radius: 12px;\n display: flex; align-items: center; justify-content: center;\n font-size: 16px; flex-shrink: 0;\n }\n .kpi-card.sent .kpi-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .kpi-card.delivered .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .kpi-card.pending .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .kpi-card.failed .kpi-icon {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .kpi-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }\n .kpi-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n }\n .kpi-value {\n font-size: 28px; font-weight: 800;\n color: var(--mj-text-primary);\n letter-spacing: -0.02em; line-height: 1.1;\n }\n .kpi-delta {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n margin-top: 4px; padding: 2px 8px;\n border-radius: 10px; width: fit-content;\n }\n .kpi-delta.up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .kpi-delta.down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .kpi-delta.neutral {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .delivery-bar {\n height: 6px; margin-top: 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .delivery-fill {\n height: 100%; border-radius: 3px;\n background: var(--mj-status-success); transition: width 0.6s ease;\n }\n\n /* CONTENT GRID */\n .content-grid {\n display: grid;\n grid-template-columns: 1.6fr 1fr;\n gap: 16px;\n margin-bottom: 16px;\n }\n\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n .card-header h3 {\n font-size: 13px; font-weight: 700;\n color: var(--mj-text-primary);\n display: flex; align-items: center; gap: 8px;\n margin: 0;\n }\n .card-header h3 i {\n color: var(--mj-text-muted);\n font-size: 12px;\n }\n .card-body { padding: 16px 20px; }\n .card-body.no-padding { padding: 0; }\n\n .chart-container-inner {\n padding: 16px 20px;\n min-height: 300px;\n }\n\n /* ACTIVITY FEED */\n .activity-feed { max-height: 370px; overflow-y: auto; }\n .activity-item {\n display: flex; align-items: center; gap: 12px;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.15s ease; cursor: pointer;\n }\n .activity-item:last-child { border-bottom: none; }\n .activity-item:hover { background: var(--mj-bg-surface-sunken); }\n\n .activity-icon {\n width: 34px; height: 34px;\n border-radius: 8px;\n display: flex; align-items: center; justify-content: center;\n font-size: 12px; flex-shrink: 0;\n }\n .activity-icon.email {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .activity-icon.sms {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .activity-icon.error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .activity-body { flex: 1; min-width: 0; }\n .activity-title {\n font-size: 12px; font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n display: block;\n }\n .activity-meta {\n font-size: 11px; color: var(--mj-text-muted); margin-top: 1px;\n display: block;\n }\n .activity-status {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n flex-shrink: 0;\n }\n .activity-status.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .activity-status.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .activity-status.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n /* PROVIDER HEALTH */\n .provider-health-list { display: flex; flex-direction: column; }\n .provider-row {\n display: flex; align-items: center; gap: 12px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.15s ease;\n }\n .provider-row:last-child { border-bottom: none; }\n .provider-row:hover { background: var(--mj-bg-surface-sunken); }\n\n .provider-status-dot {\n width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;\n background: var(--mj-border-strong);\n }\n .provider-status-dot.active { background: var(--mj-status-success); }\n\n .provider-logo {\n width: 36px; height: 36px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n display: flex; align-items: center; justify-content: center;\n font-size: 16px; flex-shrink: 0;\n }\n .provider-logo.sendgrid { color: var(--mj-brand-primary); }\n .provider-logo.twilio { color: var(--mj-status-error); }\n .provider-logo.gmail { color: var(--mj-status-error); }\n .provider-logo.msgraph { color: var(--mj-brand-primary); }\n\n .provider-info { flex: 1; }\n .provider-name { font-size: 13px; font-weight: 600; color: var(--mj-text-primary); }\n .provider-type { font-size: 11px; color: var(--mj-text-muted); }\n\n .provider-health-bar {\n width: 80px; height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .provider-health-fill {\n height: 100%; border-radius: 3px;\n transition: width 0.4s ease;\n }\n .provider-health-fill.excellent { background: var(--mj-status-success); }\n .provider-health-fill.good { background: var(--mj-status-success); }\n .provider-health-fill.warning { background: var(--mj-status-warning); }\n .provider-health-fill.critical { background: var(--mj-status-error); }\n\n .provider-rate {\n font-size: 12px; font-weight: 700;\n min-width: 44px; text-align: right;\n }\n .provider-rate.excellent { color: var(--mj-status-success); }\n .provider-rate.good { color: var(--mj-status-success); }\n .provider-rate.warning { color: var(--mj-status-warning); }\n .provider-rate.critical { color: var(--mj-status-error); }\n\n /* CHANNEL BREAKDOWN */\n .channel-breakdown { display: flex; flex-direction: column; }\n .channel-row {\n display: flex; align-items: center; gap: 12px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n .channel-row:last-child { border-bottom: none; }\n .channel-icon {\n width: 32px; height: 32px;\n border-radius: 8px;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px; flex-shrink: 0;\n }\n .channel-icon.email {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .channel-icon.sms {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .channel-info { flex: 1; }\n .channel-name { font-size: 12px; font-weight: 600; color: var(--mj-text-primary); }\n .channel-count { font-size: 11px; color: var(--mj-text-muted); }\n\n .channel-bar-wrapper {\n width: 100px; height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px; overflow: hidden;\n }\n .channel-bar-fill { height: 100%; border-radius: 3px; }\n .channel-pct {\n font-size: 12px; font-weight: 700;\n color: var(--mj-text-primary);\n min-width: 36px; text-align: right;\n }\n\n /* EMPTY STATE */\n\n @media (max-width: 1200px) {\n .kpi-strip { grid-template-columns: repeat(2, 1fr); }\n .content-grid { grid-template-columns: 1fr; }\n }\n `]\n})\nexport class CommunicationMonitorResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = false;\n public Stats = {\n totalSent: 0,\n deliveryRate: 0,\n pending: 0,\n failed: 0\n };\n\n /** @deprecated Use {@link Stats}. */\n public get stats() {\n return this.Stats;\n }\n /** @deprecated Use {@link Stats}. */\n public set stats(value) {\n this.Stats = value;\n }\n public RecentLogs: MJCommunicationLogEntity[] = [];\n\n /** @deprecated Use {@link RecentLogs}. */\n public get recentLogs(): MJCommunicationLogEntity[] {\n return this.RecentLogs;\n }\n /** @deprecated Use {@link RecentLogs}. */\n public set recentLogs(value: MJCommunicationLogEntity[]) {\n this.RecentLogs = value;\n }\n public ChartData: HourlyBucket[] = [];\n\n /** @deprecated Use {@link ChartData}. */\n public get chartData(): HourlyBucket[] {\n return this.ChartData;\n }\n /** @deprecated Use {@link ChartData}. */\n public set chartData(value: HourlyBucket[]) {\n this.ChartData = value;\n }\n public ChartConfig = {\n useDualAxis: false,\n showGrid: true,\n showTooltip: true,\n colors: ['#4f6bed', '#cf222e']\n };\n\n /** @deprecated Use {@link ChartConfig}. */\n public get chartConfig() {\n return this.ChartConfig;\n }\n /** @deprecated Use {@link ChartConfig}. */\n public set chartConfig(value) {\n this.ChartConfig = value;\n }\n public ProviderHealth: ProviderHealth[] = [];\n\n /** @deprecated Use {@link ProviderHealth}. */\n public get providerHealth(): ProviderHealth[] {\n return this.ProviderHealth;\n }\n /** @deprecated Use {@link ProviderHealth}. */\n public set providerHealth(value: ProviderHealth[]) {\n this.ProviderHealth = value;\n }\n public ChannelBreakdown: ChannelBreakdown[] = [];\n\n /** @deprecated Use {@link ChannelBreakdown}. */\n public get channelBreakdown(): ChannelBreakdown[] {\n return this.ChannelBreakdown;\n }\n /** @deprecated Use {@link ChannelBreakdown}. */\n public set channelBreakdown(value: ChannelBreakdown[]) {\n this.ChannelBreakdown = value;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const logFields = ['ID', 'MessageDate', 'Status', 'Direction', 'CommunicationProvider', 'CommunicationProviderMessageType'];\n const [totalResult, failedResult, pendingResult, recentResult, allLogsResult, providersResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n ResultType: 'count_only'\n },\n {\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n },\n {\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `Status = 'Pending'`,\n ResultType: 'count_only'\n },\n {\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 8,\n Fields: logFields,\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n OrderBy: 'MessageDate ASC',\n Fields: logFields,\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Communication Providers',\n OrderBy: 'Name ASC',\n Fields: ['ID', 'Name', 'Status'],\n ResultType: 'simple'\n }\n ]);\n\n if (totalResult.Success) this.Stats.totalSent = totalResult.TotalRowCount;\n if (failedResult.Success) this.Stats.failed = failedResult.TotalRowCount;\n if (pendingResult.Success) this.Stats.pending = pendingResult.TotalRowCount;\n\n this.Stats.deliveryRate = this.Stats.totalSent > 0\n ? parseFloat(((this.Stats.totalSent - this.Stats.failed) / this.Stats.totalSent * 100).toFixed(1))\n : 100;\n\n if (recentResult.Success) {\n this.RecentLogs = recentResult.Results as MJCommunicationLogEntity[];\n }\n\n if (allLogsResult.Success) {\n const allLogs = allLogsResult.Results as MJCommunicationLogEntity[];\n this.ChartData = this.processTrendData(allLogs, yesterday);\n this.ChannelBreakdown = this.buildChannelBreakdown(allLogs);\n }\n\n if (providersResult.Success && allLogsResult.Success) {\n this.ProviderHealth = this.buildProviderHealth(\n providersResult.Results as MJCommunicationProviderEntity[],\n allLogsResult.Results as MJCommunicationLogEntity[]\n );\n }\n\n } catch (error) {\n console.error('Error loading monitor data:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public GetActivityIconClass(log: MJCommunicationLogEntity): string {\n if (log.Status === 'Failed') return 'error';\n const type = (log.CommunicationProviderMessageType || '').toLowerCase();\n if (type.includes('sms')) return 'sms';\n return 'email';\n }\n\n /** @deprecated Use {@link GetActivityIconClass}. */\n public getActivityIconClass(log: MJCommunicationLogEntity): string {\n return this.GetActivityIconClass(log);\n }\n\n public GetActivityIcon(log: MJCommunicationLogEntity): string {\n if (log.Direction === 'Receiving') return 'fa-solid fa-arrow-down';\n const type = (log.CommunicationProviderMessageType || '').toLowerCase();\n if (type.includes('sms')) return 'fa-solid fa-comment-sms';\n return 'fa-solid fa-envelope';\n }\n\n /** @deprecated Use {@link GetActivityIcon}. */\n public getActivityIcon(log: MJCommunicationLogEntity): string {\n return this.GetActivityIcon(log);\n }\n\n public GetHealthClass(rate: number): string {\n if (rate >= 98) return 'excellent';\n if (rate >= 95) return 'good';\n if (rate >= 85) return 'warning';\n return 'critical';\n }\n\n /** @deprecated Use {@link GetHealthClass}. */\n public getHealthClass(rate: number): string {\n return this.GetHealthClass(rate);\n }\n\n private processTrendData(logs: MJCommunicationLogEntity[], startTime: Date): HourlyBucket[] {\n const buckets: HourlyBucket[] = [];\n const now = new Date();\n const current = new Date(startTime);\n current.setMinutes(0, 0, 0);\n\n while (current <= now) {\n const bucketStart = new Date(current);\n const bucketEnd = new Date(current.getTime() + 60 * 60 * 1000);\n const bucketLogs = logs.filter(l => {\n const d = new Date(l.MessageDate);\n return d >= bucketStart && d < bucketEnd;\n });\n\n buckets.push({\n timestamp: bucketStart,\n executions: bucketLogs.length,\n errors: bucketLogs.filter(l => l.Status === 'Failed').length,\n cost: 0,\n tokens: 0,\n avgTime: 0\n });\n current.setHours(current.getHours() + 1);\n }\n return buckets;\n }\n\n private buildProviderHealth(providers: MJCommunicationProviderEntity[], logs: MJCommunicationLogEntity[]): ProviderHealth[] {\n return providers.map(p => {\n const providerLogs = logs.filter(l => l.CommunicationProvider === p.Name);\n const sent = providerLogs.length;\n const failed = providerLogs.filter(l => l.Status === 'Failed').length;\n const rate = sent > 0 ? parseFloat(((sent - failed) / sent * 100).toFixed(1)) : 100;\n\n return {\n Name: p.Name,\n Type: this.getProviderType(p.Name),\n SentCount: sent,\n SuccessRate: rate,\n IsActive: p.Status === 'Active',\n IconClass: this.getProviderIconClass(p.Name),\n ColorClass: this.getProviderColorClass(p.Name)\n };\n });\n }\n\n private buildChannelBreakdown(logs: MJCommunicationLogEntity[]): ChannelBreakdown[] {\n const total = logs.length;\n if (total === 0) return [];\n\n const emailLogs = logs.filter(l => {\n const type = (l.CommunicationProviderMessageType || '').toLowerCase();\n return type.includes('email') || (!type.includes('sms'));\n });\n const smsLogs = logs.filter(l => {\n const type = (l.CommunicationProviderMessageType || '').toLowerCase();\n return type.includes('sms');\n });\n\n const channels: ChannelBreakdown[] = [];\n if (emailLogs.length > 0) {\n channels.push({\n Name: 'Email',\n IconClass: 'fa-solid fa-envelope',\n Count: emailLogs.length,\n Percentage: Math.round((emailLogs.length / total) * 100),\n ColorClass: 'email'\n });\n }\n if (smsLogs.length > 0) {\n channels.push({\n Name: 'SMS',\n IconClass: 'fa-solid fa-comment-sms',\n Count: smsLogs.length,\n Percentage: Math.round((smsLogs.length / total) * 100),\n ColorClass: 'sms'\n });\n }\n return channels;\n }\n\n private getProviderType(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('twilio')) return 'SMS';\n return 'Email';\n }\n\n private getProviderIconClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n private getProviderColorClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'sendgrid';\n if (n.includes('twilio')) return 'twilio';\n if (n.includes('gmail') || n.includes('google')) return 'gmail';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'msgraph';\n return '';\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Monitor';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-line';\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"communication-runs-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE,qBAgNa,kCAAmC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IA2B1F,OAAO,CAAC,GAAG;IA1BhB,IAAI,EAAE,wBAAwB,EAAE,CAAM;IAE7C,oCAAoC;IACpC,IAAW,IAAI,IAAI,wBAAwB,EAAE,CAE5C;IACD,oCAAoC;IACpC,IAAW,IAAI,CAAC,KAAK,EAAE,wBAAwB,EAAE,EAEhD;IACM,SAAS,UAAS;IAClB,OAAO;;;;MAIZ;IAEF,uCAAuC;IACvC,IAAW,OAAO;;;;MAEjB;IACD,uCAAuC;IACvC,IAAW,OAAO,CAAC,KAAK;;;;KAAA,EAEvB;gBAEmB,GAAG,EAAE,iBAAiB;IAIpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,WAAW,IAAI,IAAI;IAIN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAsD/B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ7C,8CAA8C;IACvC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAItC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ7C,8CAA8C;IACvC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIvC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCA7HtD,kCAAkC;2CAAlC,kCAAkC;CAgI9C"}
1
+ {"version":3,"file":"communication-runs-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE,qBAgNa,kCAAmC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IA2B1F,OAAO,CAAC,GAAG;IA1BhB,IAAI,EAAE,wBAAwB,EAAE,CAAM;IAE7C,oCAAoC;IACpC,IAAW,IAAI,IAAI,wBAAwB,EAAE,CAE5C;IACD,oCAAoC;IACpC,IAAW,IAAI,CAAC,KAAK,EAAE,wBAAwB,EAAE,EAEhD;IACM,SAAS,UAAS;IAClB,OAAO;;;;MAIZ;IAEF,uCAAuC;IACvC,IAAW,OAAO;;;;MAEjB;IACD,uCAAuC;IACvC,IAAW,OAAO,CAAC,KAAK;;;;KAAA,EAEvB;gBAEmB,GAAG,EAAE,iBAAiB;IAIpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,WAAW,IAAI,IAAI;IAIN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuD/B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ7C,8CAA8C;IACvC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAItC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ7C,8CAA8C;IACvC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIvC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCA9HtD,kCAAkC;2CAAlC,kCAAkC;CAiI9C"}
@@ -121,28 +121,29 @@ let CommunicationRunsResourceComponent = class CommunicationRunsResourceComponen
121
121
  const yesterday = new Date();
122
122
  yesterday.setDate(yesterday.getDate() - 1);
123
123
  const yesterdayIso = yesterday.toISOString();
124
- const [runsResult, activeResult, completedResult, failedResult] = await Promise.all([
125
- rv.RunView({
124
+ const [runsResult, activeResult, completedResult, failedResult] = await rv.RunViews([
125
+ {
126
126
  EntityName: 'MJ: Communication Runs',
127
127
  OrderBy: 'StartedAt DESC',
128
128
  MaxRows: 50,
129
- ResultType: 'entity_object'
130
- }),
131
- rv.RunView({
129
+ Fields: ['ID', 'Status', 'Direction', 'StartedAt', 'EndedAt', 'NumMessagesProcessed', 'Comments', 'User'],
130
+ ResultType: 'simple'
131
+ },
132
+ {
132
133
  EntityName: 'MJ: Communication Runs',
133
134
  ExtraFilter: `Status = 'In-Progress'`,
134
135
  ResultType: 'count_only'
135
- }),
136
- rv.RunView({
136
+ },
137
+ {
137
138
  EntityName: 'MJ: Communication Runs',
138
139
  ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Complete'`,
139
140
  ResultType: 'count_only'
140
- }),
141
- rv.RunView({
141
+ },
142
+ {
142
143
  EntityName: 'MJ: Communication Runs',
143
144
  ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Failed'`,
144
145
  ResultType: 'count_only'
145
- })
146
+ }
146
147
  ]);
147
148
  if (runsResult.Success) {
148
149
  this.Runs = runsResult.Results;
@@ -1 +1 @@
1
- {"version":3,"file":"communication-runs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationRunsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-runs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-play-circle\"\n Subtitle=\"Bulk communication run history\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> <span class=\"action-btn-label\">Refresh</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <div class=\"card\">\n <!-- SUMMARY STATS -->\n <div class=\"runs-summary\">\n <div class=\"run-stat-card info\">\n <div class=\"run-stat-value\">{{summary.active}}</div>\n <div class=\"run-stat-label\">Active Runs</div>\n </div>\n <div class=\"run-stat-card success\">\n <div class=\"run-stat-value\">{{summary.completed}}</div>\n <div class=\"run-stat-label\">Completed (24h)</div>\n </div>\n <div class=\"run-stat-card neutral\">\n <div class=\"run-stat-value\">{{summary.successRate}}%</div>\n <div class=\"run-stat-label\">Success Rate</div>\n </div>\n </div>\n \n <!-- TIMELINE -->\n <div class=\"run-timeline\">\n @for (run of runs; track run) {\n <div class=\"run-entry\">\n <div class=\"run-timeline-dot\" [ngClass]=\"getRunDotClass(run.Status)\"></div>\n <div class=\"run-entry-content\">\n <div class=\"run-entry-header\">\n <span class=\"run-entry-title\">Run #{{run.ID.substring(0, 8)}}</span>\n <span class=\"run-status-badge\" [ngClass]=\"getStatusClass(run.Status)\">\n {{run.Status}}\n </span>\n </div>\n <div class=\"run-entry-meta\">\n <span><i class=\"fa-solid fa-user\"></i> {{run.User || 'System'}}</span>\n <span><i class=\"fa-solid fa-clock\"></i> {{run.StartedAt | date:'medium'}}</span>\n @if (run.EndedAt) {\n <span><i class=\"fa-solid fa-flag-checkered\"></i> {{run.EndedAt | date:'shortTime'}}</span>\n }\n </div>\n @if (run.Comments) {\n <div class=\"run-entry-comments\">\n {{run.Comments}}\n </div>\n }\n </div>\n </div>\n }\n \n @if (runs.length === 0 && !isLoading) {\n <mj-empty-state Icon=\"fa-solid fa-play-circle\"\n Title=\"No communication runs found\" />\n }\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n padding: 16px 0 0;\n }\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* SUMMARY */\n .runs-summary {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 16px;\n padding: 20px;\n }\n .run-stat-card {\n border-radius: 12px;\n padding: 16px 20px;\n text-align: center;\n }\n .run-stat-card.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .run-stat-card.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-stat-card.neutral {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .run-stat-value {\n font-size: 24px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .run-stat-card.info .run-stat-value { color: var(--mj-brand-primary); }\n .run-stat-card.success .run-stat-value { color: var(--mj-status-success); }\n\n .run-stat-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n /* TIMELINE */\n .run-timeline { padding: 8px 20px 20px; }\n .run-entry {\n display: flex; gap: 16px;\n padding: 16px 0;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: flex-start;\n }\n .run-entry:last-child { border-bottom: none; }\n\n .run-timeline-dot {\n width: 12px; height: 12px;\n border-radius: 50%;\n margin-top: 4px; flex-shrink: 0;\n }\n .run-timeline-dot.complete { background: var(--mj-status-success); }\n .run-timeline-dot.failed { background: var(--mj-status-error); }\n .run-timeline-dot.in-progress {\n background: var(--mj-brand-primary);\n animation: pulse-dot 1.5s ease-in-out infinite;\n }\n .run-timeline-dot.pending { background: var(--mj-status-warning); }\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 40%, transparent); }\n 50% { box-shadow: 0 0 0 6px transparent; }\n }\n\n .run-entry-content { flex: 1; }\n .run-entry-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .run-entry-title {\n font-size: 13px; font-weight: 600;\n color: var(--mj-text-primary);\n }\n .run-status-badge {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .run-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n }\n .run-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n .run-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .run-entry-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n display: flex; align-items: center; gap: 12px;\n }\n .run-entry-meta span {\n display: flex; align-items: center; gap: 4px;\n }\n .run-entry-meta i { font-size: 10px; }\n\n .run-entry-comments {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 6px;\n font-style: italic;\n }\n\n /* EMPTY STATE */\n `]\n})\nexport class CommunicationRunsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public Runs: MJCommunicationRunEntity[] = [];\n\n /** @deprecated Use {@link Runs}. */\n public get runs(): MJCommunicationRunEntity[] {\n return this.Runs;\n }\n /** @deprecated Use {@link Runs}. */\n public set runs(value: MJCommunicationRunEntity[]) {\n this.Runs = value;\n }\n public isLoading = false;\n public Summary = {\n active: 0,\n completed: 0,\n successRate: 0\n };\n\n /** @deprecated Use {@link Summary}. */\n public get summary() {\n return this.Summary;\n }\n /** @deprecated Use {@link Summary}. */\n public set summary(value) {\n this.Summary = value;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [runsResult, activeResult, completedResult, failedResult] = await Promise.all([\n rv.RunView<MJCommunicationRunEntity>({\n EntityName: 'MJ: Communication Runs',\n OrderBy: 'StartedAt DESC',\n MaxRows: 50,\n ResultType: 'entity_object'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `Status = 'In-Progress'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Complete'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n })\n ]);\n\n if (runsResult.Success) {\n this.Runs = runsResult.Results;\n }\n\n if (activeResult.Success) this.Summary.active = activeResult.TotalRowCount;\n if (completedResult.Success) this.Summary.completed = completedResult.TotalRowCount;\n\n const totalCompleted = this.Summary.completed + (failedResult.Success ? failedResult.TotalRowCount : 0);\n this.Summary.successRate = totalCompleted > 0\n ? Math.round((this.Summary.completed / totalCompleted) * 100)\n : 100;\n\n } catch (error) {\n console.error('Error loading runs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public GetRunDotClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n /** @deprecated Use {@link GetRunDotClass}. */\n public getRunDotClass(status: string): string {\n return this.GetRunDotClass(status);\n }\n\n public GetStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n /** @deprecated Use {@link GetStatusClass}. */\n public getStatusClass(status: string): string {\n return this.GetStatusClass(status);\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Bulk Runs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-play-circle';\n }\n}\n"]}
1
+ {"version":3,"file":"communication-runs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationRunsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-runs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-play-circle\"\n Subtitle=\"Bulk communication run history\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> <span class=\"action-btn-label\">Refresh</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <div class=\"card\">\n <!-- SUMMARY STATS -->\n <div class=\"runs-summary\">\n <div class=\"run-stat-card info\">\n <div class=\"run-stat-value\">{{summary.active}}</div>\n <div class=\"run-stat-label\">Active Runs</div>\n </div>\n <div class=\"run-stat-card success\">\n <div class=\"run-stat-value\">{{summary.completed}}</div>\n <div class=\"run-stat-label\">Completed (24h)</div>\n </div>\n <div class=\"run-stat-card neutral\">\n <div class=\"run-stat-value\">{{summary.successRate}}%</div>\n <div class=\"run-stat-label\">Success Rate</div>\n </div>\n </div>\n \n <!-- TIMELINE -->\n <div class=\"run-timeline\">\n @for (run of runs; track run) {\n <div class=\"run-entry\">\n <div class=\"run-timeline-dot\" [ngClass]=\"getRunDotClass(run.Status)\"></div>\n <div class=\"run-entry-content\">\n <div class=\"run-entry-header\">\n <span class=\"run-entry-title\">Run #{{run.ID.substring(0, 8)}}</span>\n <span class=\"run-status-badge\" [ngClass]=\"getStatusClass(run.Status)\">\n {{run.Status}}\n </span>\n </div>\n <div class=\"run-entry-meta\">\n <span><i class=\"fa-solid fa-user\"></i> {{run.User || 'System'}}</span>\n <span><i class=\"fa-solid fa-clock\"></i> {{run.StartedAt | date:'medium'}}</span>\n @if (run.EndedAt) {\n <span><i class=\"fa-solid fa-flag-checkered\"></i> {{run.EndedAt | date:'shortTime'}}</span>\n }\n </div>\n @if (run.Comments) {\n <div class=\"run-entry-comments\">\n {{run.Comments}}\n </div>\n }\n </div>\n </div>\n }\n \n @if (runs.length === 0 && !isLoading) {\n <mj-empty-state Icon=\"fa-solid fa-play-circle\"\n Title=\"No communication runs found\" />\n }\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n padding: 16px 0 0;\n }\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* SUMMARY */\n .runs-summary {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 16px;\n padding: 20px;\n }\n .run-stat-card {\n border-radius: 12px;\n padding: 16px 20px;\n text-align: center;\n }\n .run-stat-card.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .run-stat-card.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-stat-card.neutral {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .run-stat-value {\n font-size: 24px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .run-stat-card.info .run-stat-value { color: var(--mj-brand-primary); }\n .run-stat-card.success .run-stat-value { color: var(--mj-status-success); }\n\n .run-stat-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n /* TIMELINE */\n .run-timeline { padding: 8px 20px 20px; }\n .run-entry {\n display: flex; gap: 16px;\n padding: 16px 0;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: flex-start;\n }\n .run-entry:last-child { border-bottom: none; }\n\n .run-timeline-dot {\n width: 12px; height: 12px;\n border-radius: 50%;\n margin-top: 4px; flex-shrink: 0;\n }\n .run-timeline-dot.complete { background: var(--mj-status-success); }\n .run-timeline-dot.failed { background: var(--mj-status-error); }\n .run-timeline-dot.in-progress {\n background: var(--mj-brand-primary);\n animation: pulse-dot 1.5s ease-in-out infinite;\n }\n .run-timeline-dot.pending { background: var(--mj-status-warning); }\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 40%, transparent); }\n 50% { box-shadow: 0 0 0 6px transparent; }\n }\n\n .run-entry-content { flex: 1; }\n .run-entry-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .run-entry-title {\n font-size: 13px; font-weight: 600;\n color: var(--mj-text-primary);\n }\n .run-status-badge {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .run-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n }\n .run-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n .run-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .run-entry-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n display: flex; align-items: center; gap: 12px;\n }\n .run-entry-meta span {\n display: flex; align-items: center; gap: 4px;\n }\n .run-entry-meta i { font-size: 10px; }\n\n .run-entry-comments {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 6px;\n font-style: italic;\n }\n\n /* EMPTY STATE */\n `]\n})\nexport class CommunicationRunsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public Runs: MJCommunicationRunEntity[] = [];\n\n /** @deprecated Use {@link Runs}. */\n public get runs(): MJCommunicationRunEntity[] {\n return this.Runs;\n }\n /** @deprecated Use {@link Runs}. */\n public set runs(value: MJCommunicationRunEntity[]) {\n this.Runs = value;\n }\n public isLoading = false;\n public Summary = {\n active: 0,\n completed: 0,\n successRate: 0\n };\n\n /** @deprecated Use {@link Summary}. */\n public get summary() {\n return this.Summary;\n }\n /** @deprecated Use {@link Summary}. */\n public set summary(value) {\n this.Summary = value;\n }\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [runsResult, activeResult, completedResult, failedResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Communication Runs',\n OrderBy: 'StartedAt DESC',\n MaxRows: 50,\n Fields: ['ID', 'Status', 'Direction', 'StartedAt', 'EndedAt', 'NumMessagesProcessed', 'Comments', 'User'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `Status = 'In-Progress'`,\n ResultType: 'count_only'\n },\n {\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Complete'`,\n ResultType: 'count_only'\n },\n {\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n }\n ]);\n\n if (runsResult.Success) {\n this.Runs = runsResult.Results as MJCommunicationRunEntity[];\n }\n\n if (activeResult.Success) this.Summary.active = activeResult.TotalRowCount;\n if (completedResult.Success) this.Summary.completed = completedResult.TotalRowCount;\n\n const totalCompleted = this.Summary.completed + (failedResult.Success ? failedResult.TotalRowCount : 0);\n this.Summary.successRate = totalCompleted > 0\n ? Math.round((this.Summary.completed / totalCompleted) * 100)\n : 100;\n\n } catch (error) {\n console.error('Error loading runs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public GetRunDotClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n /** @deprecated Use {@link GetRunDotClass}. */\n public getRunDotClass(status: string): string {\n return this.GetRunDotClass(status);\n }\n\n public GetStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n /** @deprecated Use {@link GetStatusClass}. */\n public getStatusClass(status: string): string {\n return this.GetStatusClass(status);\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Bulk Runs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-play-circle';\n }\n}\n"]}