@marinoscar/platform-web 0.0.0-stage → 0.1.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/LICENSE +21 -0
- package/README.md +96 -2
- package/dist/core/api-client.d.ts +112 -0
- package/dist/core/api-client.d.ts.map +1 -0
- package/dist/core/api-client.js +24 -0
- package/dist/core/api-client.js.map +1 -0
- package/dist/core/host.d.ts +74 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/core/host.js +84 -0
- package/dist/core/host.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/settings-page.d.ts +47 -0
- package/dist/core/settings-page.d.ts.map +1 -0
- package/dist/core/settings-page.js +5 -0
- package/dist/core/settings-page.js.map +1 -0
- package/dist/core/viewer.d.ts +14 -0
- package/dist/core/viewer.d.ts.map +1 -0
- package/dist/core/viewer.js +4 -0
- package/dist/core/viewer.js.map +1 -0
- package/dist/doctor/headless/categories.d.ts +31 -0
- package/dist/doctor/headless/categories.d.ts.map +1 -0
- package/dist/doctor/headless/categories.js +41 -0
- package/dist/doctor/headless/categories.js.map +1 -0
- package/dist/doctor/headless/client.d.ts +33 -0
- package/dist/doctor/headless/client.d.ts.map +1 -0
- package/dist/doctor/headless/client.js +31 -0
- package/dist/doctor/headless/client.js.map +1 -0
- package/dist/doctor/headless/contract.d.ts +18 -0
- package/dist/doctor/headless/contract.d.ts.map +1 -0
- package/dist/doctor/headless/contract.js +15 -0
- package/dist/doctor/headless/contract.js.map +1 -0
- package/dist/doctor/headless/index.d.ts +12 -0
- package/dist/doctor/headless/index.d.ts.map +1 -0
- package/dist/doctor/headless/index.js +8 -0
- package/dist/doctor/headless/index.js.map +1 -0
- package/dist/doctor/headless/use-doctor.d.ts +36 -0
- package/dist/doctor/headless/use-doctor.d.ts.map +1 -0
- package/dist/doctor/headless/use-doctor.js +80 -0
- package/dist/doctor/headless/use-doctor.js.map +1 -0
- package/dist/doctor/headless/use-support-bundle-download.d.ts +68 -0
- package/dist/doctor/headless/use-support-bundle-download.d.ts.map +1 -0
- package/dist/doctor/headless/use-support-bundle-download.js +135 -0
- package/dist/doctor/headless/use-support-bundle-download.js.map +1 -0
- package/dist/doctor/internal/relative-time.d.ts +2 -0
- package/dist/doctor/internal/relative-time.d.ts.map +1 -0
- package/dist/doctor/internal/relative-time.js +29 -0
- package/dist/doctor/internal/relative-time.js.map +1 -0
- package/dist/doctor/internal/status-colors.d.ts +5 -0
- package/dist/doctor/internal/status-colors.d.ts.map +1 -0
- package/dist/doctor/internal/status-colors.js +29 -0
- package/dist/doctor/internal/status-colors.js.map +1 -0
- package/dist/doctor/internal/use-is-mounted.d.ts +2 -0
- package/dist/doctor/internal/use-is-mounted.d.ts.map +1 -0
- package/dist/doctor/internal/use-is-mounted.js +15 -0
- package/dist/doctor/internal/use-is-mounted.js.map +1 -0
- package/dist/doctor/ui/check-row.d.ts +54 -0
- package/dist/doctor/ui/check-row.d.ts.map +1 -0
- package/dist/doctor/ui/check-row.js +100 -0
- package/dist/doctor/ui/check-row.js.map +1 -0
- package/dist/doctor/ui/copy.d.ts +3 -0
- package/dist/doctor/ui/copy.d.ts.map +1 -0
- package/dist/doctor/ui/copy.js +6 -0
- package/dist/doctor/ui/copy.js.map +1 -0
- package/dist/doctor/ui/doctor-page.d.ts +50 -0
- package/dist/doctor/ui/doctor-page.d.ts.map +1 -0
- package/dist/doctor/ui/doctor-page.js +152 -0
- package/dist/doctor/ui/doctor-page.js.map +1 -0
- package/dist/doctor/ui/index.d.ts +8 -0
- package/dist/doctor/ui/index.d.ts.map +1 -0
- package/dist/doctor/ui/index.js +7 -0
- package/dist/doctor/ui/index.js.map +1 -0
- package/dist/doctor/ui/settings-page.d.ts +20 -0
- package/dist/doctor/ui/settings-page.d.ts.map +1 -0
- package/dist/doctor/ui/settings-page.js +32 -0
- package/dist/doctor/ui/settings-page.js.map +1 -0
- package/dist/doctor/ui/support-bundle-button.d.ts +37 -0
- package/dist/doctor/ui/support-bundle-button.d.ts.map +1 -0
- package/dist/doctor/ui/support-bundle-button.js +39 -0
- package/dist/doctor/ui/support-bundle-button.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/telemetry/headless/adapters/TelemetryWebAdapters.d.ts +106 -0
- package/dist/telemetry/headless/adapters/TelemetryWebAdapters.d.ts.map +1 -0
- package/dist/telemetry/headless/adapters/TelemetryWebAdapters.js +58 -0
- package/dist/telemetry/headless/adapters/TelemetryWebAdapters.js.map +1 -0
- package/dist/telemetry/headless/context/TelemetryConfigProvider.d.ts +43 -0
- package/dist/telemetry/headless/context/TelemetryConfigProvider.d.ts.map +1 -0
- package/dist/telemetry/headless/context/TelemetryConfigProvider.js +24 -0
- package/dist/telemetry/headless/context/TelemetryConfigProvider.js.map +1 -0
- package/dist/telemetry/headless/context/telemetryConfig.d.ts +68 -0
- package/dist/telemetry/headless/context/telemetryConfig.d.ts.map +1 -0
- package/dist/telemetry/headless/context/telemetryConfig.js +119 -0
- package/dist/telemetry/headless/context/telemetryConfig.js.map +1 -0
- package/dist/telemetry/headless/guards/RequireTelemetryEnabled.d.ts +35 -0
- package/dist/telemetry/headless/guards/RequireTelemetryEnabled.d.ts.map +1 -0
- package/dist/telemetry/headless/guards/RequireTelemetryEnabled.js +44 -0
- package/dist/telemetry/headless/guards/RequireTelemetryEnabled.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAdmin.d.ts +40 -0
- package/dist/telemetry/headless/hooks/useTelemetryAdmin.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAdmin.js +111 -0
- package/dist/telemetry/headless/hooks/useTelemetryAdmin.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistant.d.ts +120 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistant.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistant.js +185 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistant.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistantAvailable.d.ts +12 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistantAvailable.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistantAvailable.js +36 -0
- package/dist/telemetry/headless/hooks/useTelemetryAssistantAvailable.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryConnection.d.ts +46 -0
- package/dist/telemetry/headless/hooks/useTelemetryConnection.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryConnection.js +133 -0
- package/dist/telemetry/headless/hooks/useTelemetryConnection.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.d.ts +147 -0
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.js +231 -0
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryExplorer.d.ts +95 -0
- package/dist/telemetry/headless/hooks/useTelemetryExplorer.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryExplorer.js +197 -0
- package/dist/telemetry/headless/hooks/useTelemetryExplorer.js.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryStack.d.ts +69 -0
- package/dist/telemetry/headless/hooks/useTelemetryStack.d.ts.map +1 -0
- package/dist/telemetry/headless/hooks/useTelemetryStack.js +129 -0
- package/dist/telemetry/headless/hooks/useTelemetryStack.js.map +1 -0
- package/dist/telemetry/headless/index.d.ts +34 -0
- package/dist/telemetry/headless/index.d.ts.map +1 -0
- package/dist/telemetry/headless/index.js +34 -0
- package/dist/telemetry/headless/index.js.map +1 -0
- package/dist/telemetry/headless/lib/assistantExport.d.ts +12 -0
- package/dist/telemetry/headless/lib/assistantExport.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/assistantExport.js +116 -0
- package/dist/telemetry/headless/lib/assistantExport.js.map +1 -0
- package/dist/telemetry/headless/lib/dashboard/assistantPrompt.d.ts +91 -0
- package/dist/telemetry/headless/lib/dashboard/assistantPrompt.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/dashboard/assistantPrompt.js +246 -0
- package/dist/telemetry/headless/lib/dashboard/assistantPrompt.js.map +1 -0
- package/dist/telemetry/headless/lib/dashboardState.d.ts +58 -0
- package/dist/telemetry/headless/lib/dashboardState.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/dashboardState.js +153 -0
- package/dist/telemetry/headless/lib/dashboardState.js.map +1 -0
- package/dist/telemetry/headless/lib/explorerHandoff.d.ts +62 -0
- package/dist/telemetry/headless/lib/explorerHandoff.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/explorerHandoff.js +77 -0
- package/dist/telemetry/headless/lib/explorerHandoff.js.map +1 -0
- package/dist/telemetry/headless/lib/format.d.ts +113 -0
- package/dist/telemetry/headless/lib/format.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/format.js +280 -0
- package/dist/telemetry/headless/lib/format.js.map +1 -0
- package/dist/telemetry/headless/lib/metrics/metricSections.d.ts +44 -0
- package/dist/telemetry/headless/lib/metrics/metricSections.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/metrics/metricSections.js +61 -0
- package/dist/telemetry/headless/lib/metrics/metricSections.js.map +1 -0
- package/dist/telemetry/headless/lib/metrics/topNPreference.d.ts +15 -0
- package/dist/telemetry/headless/lib/metrics/topNPreference.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/metrics/topNPreference.js +33 -0
- package/dist/telemetry/headless/lib/metrics/topNPreference.js.map +1 -0
- package/dist/telemetry/headless/lib/queryHistory.d.ts +20 -0
- package/dist/telemetry/headless/lib/queryHistory.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/queryHistory.js +53 -0
- package/dist/telemetry/headless/lib/queryHistory.js.map +1 -0
- package/dist/telemetry/headless/lib/starterQueries.d.ts +48 -0
- package/dist/telemetry/headless/lib/starterQueries.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/starterQueries.js +84 -0
- package/dist/telemetry/headless/lib/starterQueries.js.map +1 -0
- package/dist/telemetry/headless/lib/traceLink.d.ts +26 -0
- package/dist/telemetry/headless/lib/traceLink.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/traceLink.js +32 -0
- package/dist/telemetry/headless/lib/traceLink.js.map +1 -0
- package/dist/telemetry/headless/lib/unknownRoutes.d.ts +23 -0
- package/dist/telemetry/headless/lib/unknownRoutes.d.ts.map +1 -0
- package/dist/telemetry/headless/lib/unknownRoutes.js +35 -0
- package/dist/telemetry/headless/lib/unknownRoutes.js.map +1 -0
- package/dist/telemetry/headless/services/client.d.ts +144 -0
- package/dist/telemetry/headless/services/client.d.ts.map +1 -0
- package/dist/telemetry/headless/services/client.js +144 -0
- package/dist/telemetry/headless/services/client.js.map +1 -0
- package/dist/telemetry/headless/services/telemetry.d.ts +483 -0
- package/dist/telemetry/headless/services/telemetry.d.ts.map +1 -0
- package/dist/telemetry/headless/services/telemetry.js +190 -0
- package/dist/telemetry/headless/services/telemetry.js.map +1 -0
- package/dist/telemetry/headless/services/telemetryDashboard.d.ts +321 -0
- package/dist/telemetry/headless/services/telemetryDashboard.d.ts.map +1 -0
- package/dist/telemetry/headless/services/telemetryDashboard.js +103 -0
- package/dist/telemetry/headless/services/telemetryDashboard.js.map +1 -0
- package/dist/telemetry/internal/useIsMounted.d.ts +9 -0
- package/dist/telemetry/internal/useIsMounted.d.ts.map +1 -0
- package/dist/telemetry/internal/useIsMounted.js +19 -0
- package/dist/telemetry/internal/useIsMounted.js.map +1 -0
- package/dist/telemetry/internal/useVisiblePolling.d.ts +55 -0
- package/dist/telemetry/internal/useVisiblePolling.d.ts.map +1 -0
- package/dist/telemetry/internal/useVisiblePolling.js +96 -0
- package/dist/telemetry/internal/useVisiblePolling.js.map +1 -0
- package/dist/telemetry/internal/visuallyHidden.d.ts +12 -0
- package/dist/telemetry/internal/visuallyHidden.d.ts.map +1 -0
- package/dist/telemetry/internal/visuallyHidden.js +15 -0
- package/dist/telemetry/internal/visuallyHidden.js.map +1 -0
- package/dist/telemetry/theme/augment.d.ts +65 -0
- package/dist/telemetry/theme/augment.d.ts.map +1 -0
- package/dist/telemetry/theme/augment.js +37 -0
- package/dist/telemetry/theme/augment.js.map +1 -0
- package/dist/telemetry/theme/telemetryTokens.d.ts +121 -0
- package/dist/telemetry/theme/telemetryTokens.d.ts.map +1 -0
- package/dist/telemetry/theme/telemetryTokens.js +129 -0
- package/dist/telemetry/theme/telemetryTokens.js.map +1 -0
- package/dist/telemetry/ui/admin.d.ts +35 -0
- package/dist/telemetry/ui/admin.d.ts.map +1 -0
- package/dist/telemetry/ui/admin.js +58 -0
- package/dist/telemetry/ui/admin.js.map +1 -0
- package/dist/telemetry/ui/components/AssistantContainer.d.ts +35 -0
- package/dist/telemetry/ui/components/AssistantContainer.d.ts.map +1 -0
- package/dist/telemetry/ui/components/AssistantContainer.js +83 -0
- package/dist/telemetry/ui/components/AssistantContainer.js.map +1 -0
- package/dist/telemetry/ui/components/AssistantPanel.d.ts +22 -0
- package/dist/telemetry/ui/components/AssistantPanel.d.ts.map +1 -0
- package/dist/telemetry/ui/components/AssistantPanel.js +150 -0
- package/dist/telemetry/ui/components/AssistantPanel.js.map +1 -0
- package/dist/telemetry/ui/components/AssistantReport.d.ts +13 -0
- package/dist/telemetry/ui/components/AssistantReport.d.ts.map +1 -0
- package/dist/telemetry/ui/components/AssistantReport.js +89 -0
- package/dist/telemetry/ui/components/AssistantReport.js.map +1 -0
- package/dist/telemetry/ui/components/AssistantTimeline.d.ts +10 -0
- package/dist/telemetry/ui/components/AssistantTimeline.d.ts.map +1 -0
- package/dist/telemetry/ui/components/AssistantTimeline.js +84 -0
- package/dist/telemetry/ui/components/AssistantTimeline.js.map +1 -0
- package/dist/telemetry/ui/components/ResultsGrid.d.ts +10 -0
- package/dist/telemetry/ui/components/ResultsGrid.d.ts.map +1 -0
- package/dist/telemetry/ui/components/ResultsGrid.js +71 -0
- package/dist/telemetry/ui/components/ResultsGrid.js.map +1 -0
- package/dist/telemetry/ui/components/SchemaPanel.d.ts +9 -0
- package/dist/telemetry/ui/components/SchemaPanel.d.ts.map +1 -0
- package/dist/telemetry/ui/components/SchemaPanel.js +42 -0
- package/dist/telemetry/ui/components/SchemaPanel.js.map +1 -0
- package/dist/telemetry/ui/components/SqlEditor.d.ts +21 -0
- package/dist/telemetry/ui/components/SqlEditor.d.ts.map +1 -0
- package/dist/telemetry/ui/components/SqlEditor.js +60 -0
- package/dist/telemetry/ui/components/SqlEditor.js.map +1 -0
- package/dist/telemetry/ui/components/TelemetryConnectionSection.d.ts +14 -0
- package/dist/telemetry/ui/components/TelemetryConnectionSection.d.ts.map +1 -0
- package/dist/telemetry/ui/components/TelemetryConnectionSection.js +243 -0
- package/dist/telemetry/ui/components/TelemetryConnectionSection.js.map +1 -0
- package/dist/telemetry/ui/components/TelemetryCrossLink.d.ts +12 -0
- package/dist/telemetry/ui/components/TelemetryCrossLink.d.ts.map +1 -0
- package/dist/telemetry/ui/components/TelemetryCrossLink.js +21 -0
- package/dist/telemetry/ui/components/TelemetryCrossLink.js.map +1 -0
- package/dist/telemetry/ui/components/TelemetryServicesSection.d.ts +23 -0
- package/dist/telemetry/ui/components/TelemetryServicesSection.d.ts.map +1 -0
- package/dist/telemetry/ui/components/TelemetryServicesSection.js +138 -0
- package/dist/telemetry/ui/components/TelemetryServicesSection.js.map +1 -0
- package/dist/telemetry/ui/components/TelemetrySpinner.d.ts +3 -0
- package/dist/telemetry/ui/components/TelemetrySpinner.d.ts.map +1 -0
- package/dist/telemetry/ui/components/TelemetrySpinner.js +14 -0
- package/dist/telemetry/ui/components/TelemetrySpinner.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.d.ts +17 -0
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js +70 -0
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.d.ts +39 -0
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js +143 -0
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/DashboardPanel.d.ts +58 -0
- package/dist/telemetry/ui/components/dashboard/DashboardPanel.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/DashboardPanel.js +62 -0
- package/dist/telemetry/ui/components/dashboard/DashboardPanel.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/EventsFeed.d.ts +21 -0
- package/dist/telemetry/ui/components/dashboard/EventsFeed.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/EventsFeed.js +96 -0
- package/dist/telemetry/ui/components/dashboard/EventsFeed.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/KpiTiles.d.ts +13 -0
- package/dist/telemetry/ui/components/dashboard/KpiTiles.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/KpiTiles.js +82 -0
- package/dist/telemetry/ui/components/dashboard/KpiTiles.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.d.ts +8 -0
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js +34 -0
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/TopProblems.d.ts +19 -0
- package/dist/telemetry/ui/components/dashboard/TopProblems.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/TopProblems.js +61 -0
- package/dist/telemetry/ui/components/dashboard/TopProblems.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/UnknownRoutesPanel.d.ts +12 -0
- package/dist/telemetry/ui/components/dashboard/UnknownRoutesPanel.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/UnknownRoutesPanel.js +36 -0
- package/dist/telemetry/ui/components/dashboard/UnknownRoutesPanel.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/VerdictBanner.d.ts +35 -0
- package/dist/telemetry/ui/components/dashboard/VerdictBanner.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/VerdictBanner.js +68 -0
- package/dist/telemetry/ui/components/dashboard/VerdictBanner.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/ZoomBrush.d.ts +9 -0
- package/dist/telemetry/ui/components/dashboard/ZoomBrush.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/ZoomBrush.js +96 -0
- package/dist/telemetry/ui/components/dashboard/ZoomBrush.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.d.ts +75 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.js +247 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.d.ts +19 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js +64 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.d.ts +74 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js +126 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/severity.d.ts +43 -0
- package/dist/telemetry/ui/components/dashboard/severity.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/severity.js +66 -0
- package/dist/telemetry/ui/components/dashboard/severity.js.map +1 -0
- package/dist/telemetry/ui/components/dashboard/timelineAxis.d.ts +11 -0
- package/dist/telemetry/ui/components/dashboard/timelineAxis.d.ts.map +1 -0
- package/dist/telemetry/ui/components/dashboard/timelineAxis.js +20 -0
- package/dist/telemetry/ui/components/dashboard/timelineAxis.js.map +1 -0
- package/dist/telemetry/ui/dashboard-page.d.ts +2 -0
- package/dist/telemetry/ui/dashboard-page.d.ts.map +1 -0
- package/dist/telemetry/ui/dashboard-page.js +6 -0
- package/dist/telemetry/ui/dashboard-page.js.map +1 -0
- package/dist/telemetry/ui/explorer-page.d.ts +2 -0
- package/dist/telemetry/ui/explorer-page.d.ts.map +1 -0
- package/dist/telemetry/ui/explorer-page.js +6 -0
- package/dist/telemetry/ui/explorer-page.js.map +1 -0
- package/dist/telemetry/ui/index.d.ts +6 -0
- package/dist/telemetry/ui/index.d.ts.map +1 -0
- package/dist/telemetry/ui/index.js +10 -0
- package/dist/telemetry/ui/index.js.map +1 -0
- package/dist/telemetry/ui/pages/TelemetryDashboardPage.d.ts +14 -0
- package/dist/telemetry/ui/pages/TelemetryDashboardPage.d.ts.map +1 -0
- package/dist/telemetry/ui/pages/TelemetryDashboardPage.js +286 -0
- package/dist/telemetry/ui/pages/TelemetryDashboardPage.js.map +1 -0
- package/dist/telemetry/ui/pages/TelemetryExplorerPage.d.ts +15 -0
- package/dist/telemetry/ui/pages/TelemetryExplorerPage.d.ts.map +1 -0
- package/dist/telemetry/ui/pages/TelemetryExplorerPage.js +197 -0
- package/dist/telemetry/ui/pages/TelemetryExplorerPage.js.map +1 -0
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.d.ts +28 -0
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.d.ts.map +1 -0
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.js +278 -0
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.js.map +1 -0
- package/dist/telemetry/ui/settings-page.d.ts +2 -0
- package/dist/telemetry/ui/settings-page.d.ts.map +1 -0
- package/dist/telemetry/ui/settings-page.js +6 -0
- package/dist/telemetry/ui/settings-page.js.map +1 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/test-platform-host.d.ts +108 -0
- package/dist/testing/test-platform-host.d.ts.map +1 -0
- package/dist/testing/test-platform-host.js +101 -0
- package/dist/testing/test-platform-host.js.map +1 -0
- package/package.json +132 -4
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DashboardTile, DashboardUnknownRoutes } from '../../../headless/services/telemetryDashboard.js';
|
|
2
|
+
export interface KpiTilesProps {
|
|
3
|
+
tiles: DashboardTile[];
|
|
4
|
+
runtime?: DashboardTile[];
|
|
5
|
+
/** The summary's unknown-routes block (#650): caption and highlight of the `unknownRoutes` tile. */
|
|
6
|
+
unknownRoutes?: DashboardUnknownRoutes;
|
|
7
|
+
/** For relative timestamps; the page passes its clock. */
|
|
8
|
+
now?: number;
|
|
9
|
+
/** `data-testid` of the grid (the infrastructure sections, #602, reuse this component). */
|
|
10
|
+
testId?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function KpiTiles({ tiles, runtime, unknownRoutes, now, testId, }: KpiTilesProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=KpiTiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KpiTiles.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/KpiTiles.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AA6I9G,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,oGAAoG;IACpG,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAY,EACZ,aAAa,EACb,GAAgB,EAChB,MAAoB,GACrB,EAAE,aAAa,+BAiBf"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The Telemetry Dashboard's headline tiles — issue #578, epic #576.
|
|
4
|
+
*
|
|
5
|
+
* One tile per `summary.tiles` entry (requests/min, 5xx rate, p95, error and
|
|
6
|
+
* warning logs, last data), then the `runtime` tiles when the API sends them.
|
|
7
|
+
* Each shows the value and unit, the change against the previous window of
|
|
8
|
+
* equal length (▲/▼ and a percentage, coloured by whether that direction is
|
|
9
|
+
* good or bad for the measure — never by colour alone), and a sparkline in
|
|
10
|
+
* which a `null` bucket is a GAP, not a zero.
|
|
11
|
+
*
|
|
12
|
+
* Unknown API routes (#650): the `unknownRoutes` tile is drawn like the
|
|
13
|
+
* others (a null value is "—", unknown — never 0). When the summary carries
|
|
14
|
+
* its `unknownRoutes` block, a caption splits the count into requests from the
|
|
15
|
+
* application (with a bearer) and anonymous ones, and the tile is highlighted
|
|
16
|
+
* in the warning colour while any came from the application — the caption's
|
|
17
|
+
* words, not the colour, carry that meaning.
|
|
18
|
+
*
|
|
19
|
+
* Grid: 6 per row from `lg`, 3 from `sm`, 2 on phones.
|
|
20
|
+
*/
|
|
21
|
+
import { Box, Grid, Paper, Stack, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
22
|
+
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
|
23
|
+
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
|
24
|
+
import { SparkLineChart } from '@mui/x-charts/SparkLineChart';
|
|
25
|
+
import { formatTimestamp, formatTileValue, tileChange, tileDirection } from '../../../headless/lib/format.js';
|
|
26
|
+
import { useTelemetryTokens } from '../../../theme/telemetryTokens.js';
|
|
27
|
+
/** The change line's colour per tone: status tokens for good/bad, neutral chrome otherwise. */
|
|
28
|
+
function toneColor(tone, tokens) {
|
|
29
|
+
if (tone === 'good')
|
|
30
|
+
return tokens.status.ok;
|
|
31
|
+
if (tone === 'bad')
|
|
32
|
+
return tokens.status.crit;
|
|
33
|
+
return 'text.secondary';
|
|
34
|
+
}
|
|
35
|
+
function ChangeLine({ change, compact }) {
|
|
36
|
+
const tokens = useTelemetryTokens();
|
|
37
|
+
if (change.pct === null && change.trend === 'flat') {
|
|
38
|
+
return (_jsx(Typography, { variant: "caption", color: "text.secondary", children: compact ? '—' : 'No previous data' }));
|
|
39
|
+
}
|
|
40
|
+
const pctText = change.pct === null ? 'new' : `${Math.abs(change.pct).toLocaleString()}%`;
|
|
41
|
+
const words = change.trend === 'up' ? 'Up' : change.trend === 'down' ? 'Down' : 'Unchanged';
|
|
42
|
+
const glyph = change.trend === 'up' ? '▲' : change.trend === 'down' ? '▼' : '=';
|
|
43
|
+
const Icon = change.trend === 'up' ? ArrowUpwardIcon : change.trend === 'down' ? ArrowDownwardIcon : null;
|
|
44
|
+
return (_jsxs(Typography, { variant: "caption", "aria-label": `${words} ${pctText} vs previous window`, sx: { color: toneColor(change.tone, tokens), display: 'inline-flex', alignItems: 'center', gap: 0.25, fontWeight: 500 }, children: [compact && Icon ? _jsx(Icon, { "aria-hidden": true, sx: { fontSize: 14 } }) : _jsx("span", { "aria-hidden": true, children: glyph }), _jsx("span", { "aria-hidden": true, children: pctText }), !compact && (_jsx(Box, { component: "span", "aria-hidden": true, sx: { color: 'text.secondary', fontWeight: 400, ml: 0.5 }, children: "vs prev" }))] }));
|
|
45
|
+
}
|
|
46
|
+
function Sparkline({ data, height }) {
|
|
47
|
+
const tokens = useTelemetryTokens();
|
|
48
|
+
if (data.length < 2 || data.every((value) => value === null))
|
|
49
|
+
return _jsx(Box, { sx: { height } });
|
|
50
|
+
return (_jsx(Box, { "aria-hidden": true, sx: { height, mt: 0.5 }, children: _jsx(SparkLineChart, { data: data, height: height, color: tokens.chart.series[0], curve: "linear" }) }));
|
|
51
|
+
}
|
|
52
|
+
/** The `unknownRoutes` tile's caption and highlight (#650), from the summary's block. */
|
|
53
|
+
function unknownRoutesTileExtra(block, compact) {
|
|
54
|
+
if (!block || block.requests <= 0)
|
|
55
|
+
return {};
|
|
56
|
+
const app = block.bearer.toLocaleString();
|
|
57
|
+
const anonymous = block.anonymous.toLocaleString();
|
|
58
|
+
return {
|
|
59
|
+
caption: compact ? `${app} app · ${anonymous} anon.` : `${app} from the app · ${anonymous} anonymous`,
|
|
60
|
+
highlight: block.bearer > 0,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function Tile({ tile, compact, now, caption, highlight = false, }) {
|
|
64
|
+
const formatted = formatTileValue(tile.value, tile.unit, now);
|
|
65
|
+
const isTimestamp = tile.unit === 'timestamp';
|
|
66
|
+
const change = tileChange(tile.value, tile.previous, tileDirection(tile.key));
|
|
67
|
+
const tokens = useTelemetryTokens();
|
|
68
|
+
return (_jsxs(Paper, { variant: "outlined", "data-testid": `tile-${tile.key}`, "data-highlight": highlight ? 'warning' : undefined, sx: {
|
|
69
|
+
p: { xs: 1.25, sm: 1.5 },
|
|
70
|
+
height: '100%',
|
|
71
|
+
minWidth: 0,
|
|
72
|
+
display: 'flex',
|
|
73
|
+
flexDirection: 'column',
|
|
74
|
+
...(highlight ? { borderColor: tokens.status.warn } : {}),
|
|
75
|
+
}, children: [_jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, title: tile.label, component: "h3", children: tile.label }), _jsxs(Stack, { direction: "row", spacing: 0.5, sx: { alignItems: 'baseline', minWidth: 0 }, children: [_jsx(Typography, { variant: compact ? 'h6' : 'h5', component: "p", noWrap: true, title: isTimestamp && typeof tile.value === 'string' ? formatTimestamp(tile.value) : undefined, sx: { fontWeight: 600, minWidth: 0, ...(highlight ? { color: tokens.status.warn } : {}) }, children: formatted.value }), formatted.unit && (_jsx(Typography, { variant: "body2", color: "text.secondary", noWrap: true, children: formatted.unit }))] }), !isTimestamp && _jsx(ChangeLine, { change: change, compact: compact }), caption && (_jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, title: caption, "data-testid": `tile-${tile.key}-caption`, sx: { minWidth: 0 }, children: caption })), _jsx(Box, { sx: { mt: 'auto' }, children: !isTimestamp && _jsx(Sparkline, { data: tile.sparkline, height: compact ? 24 : 40 }) })] }));
|
|
76
|
+
}
|
|
77
|
+
export function KpiTiles({ tiles, runtime = [], unknownRoutes, now = Date.now(), testId = 'kpi-tiles', }) {
|
|
78
|
+
const theme = useTheme();
|
|
79
|
+
const compact = useMediaQuery(theme.breakpoints.down('sm'));
|
|
80
|
+
return (_jsx(Grid, { container: true, spacing: { xs: 1, sm: 1.5 }, "data-testid": testId, children: [...tiles, ...runtime].map((tile) => (_jsx(Grid, { size: { xs: 6, sm: 4, lg: 2 }, sx: { minWidth: 0 }, children: _jsx(Tile, { tile: tile, compact: compact, now: now, ...(tile.key === 'unknownRoutes' ? unknownRoutesTileExtra(unknownRoutes, compact) : {}) }) }, tile.key))) }));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=KpiTiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KpiTiles.js","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/KpiTiles.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DashboardLogsBucket, DashboardSeverity } from '../../../headless/services/telemetryDashboard.js';
|
|
2
|
+
import type { TimelineChartProps } from './ApiTimelineChart.js';
|
|
3
|
+
export interface LogSeverityChartProps extends TimelineChartProps {
|
|
4
|
+
buckets: DashboardLogsBucket[];
|
|
5
|
+
severities: DashboardSeverity[];
|
|
6
|
+
}
|
|
7
|
+
export declare function LogSeverityChart({ buckets, severities, height, spanMs, compact, zoom, onZoomBuckets, }: LogSeverityChartProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=LogSeverityChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogSeverityChart.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/LogSeverityChart.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAG/G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,UAAU,EACV,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,aAAa,GACd,EAAE,qBAAqB,+BAqCvB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Log severity timeline — issue #578, epic #576.
|
|
4
|
+
*
|
|
5
|
+
* Log records per bucket, stacked by the API's severity bands (error ≥ 17,
|
|
6
|
+
* warn 13–16, info 9–12, other). Only the bands the reader selected with the
|
|
7
|
+
* severity chips (`sev`) are drawn; `other` (debug, trace, unnumbered) rides
|
|
8
|
+
* with `info`, the band nearest it, so the default error+warn view stays about
|
|
9
|
+
* problems.
|
|
10
|
+
*/
|
|
11
|
+
import { Box } from '@mui/material';
|
|
12
|
+
import { BarChart } from '@mui/x-charts/BarChart';
|
|
13
|
+
import { timelineXAxis } from './timelineAxis.js';
|
|
14
|
+
import { ZoomBrush } from './ZoomBrush.js';
|
|
15
|
+
import { useTelemetryTokens } from '../../../theme/telemetryTokens.js';
|
|
16
|
+
export function LogSeverityChart({ buckets, severities, height, spanMs, compact, zoom, onZoomBuckets, }) {
|
|
17
|
+
const { status } = useTelemetryTokens();
|
|
18
|
+
const starts = buckets.map((bucket) => bucket.t);
|
|
19
|
+
const bands = [
|
|
20
|
+
{ id: 'error', label: 'Error', color: status.crit, shown: severities.includes('error') },
|
|
21
|
+
{ id: 'warn', label: 'Warn', color: status.warn, shown: severities.includes('warn') },
|
|
22
|
+
{ id: 'info', label: 'Info', color: status.info, shown: severities.includes('info') },
|
|
23
|
+
{ id: 'other', label: 'Other', color: status.neutral, shown: severities.includes('info') },
|
|
24
|
+
];
|
|
25
|
+
const shown = bands.filter((band) => band.shown);
|
|
26
|
+
return (_jsx(Box, { role: "img", "aria-label": `Log records per bucket by severity (${shown.map((band) => band.label).join(', ')}), ${buckets.length} buckets`, sx: { minWidth: 0, width: '100%' }, children: _jsx(BarChart, { height: height, skipAnimation: true, series: shown.map((band) => ({
|
|
27
|
+
id: band.id,
|
|
28
|
+
label: band.label,
|
|
29
|
+
data: buckets.map((bucket) => bucket[band.id]),
|
|
30
|
+
stack: 'severity',
|
|
31
|
+
color: band.color,
|
|
32
|
+
})), xAxis: [timelineXAxis(starts, spanMs, compact ? 4 : undefined)], yAxis: [{ width: compact ? 44 : 48, min: 0 }], grid: { horizontal: true }, margin: { top: 8, right: 8, bottom: 4, left: 4 }, slotProps: { legend: { position: { vertical: compact ? 'bottom' : 'top', horizontal: 'center' } } }, children: _jsx(ZoomBrush, { values: starts, drag: zoom.drag, tap: zoom.tap, onSelect: onZoomBuckets }) }) }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=LogSeverityChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogSeverityChart.js","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/LogSeverityChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DashboardResource } from '../../../headless/hooks/useTelemetryDashboard.js';
|
|
2
|
+
import type { DashboardTopErrors, DashboardTopRoutes } from '../../../headless/services/telemetryDashboard.js';
|
|
3
|
+
import { type PanelAction } from './DashboardPanel.js';
|
|
4
|
+
import type { DashboardLayout } from './DashboardFilterBar.js';
|
|
5
|
+
export type TopProblemsKind = 'routes' | 'errors';
|
|
6
|
+
export interface TopProblemsProps {
|
|
7
|
+
routes: DashboardResource<DashboardTopRoutes>;
|
|
8
|
+
errors: DashboardResource<DashboardTopErrors>;
|
|
9
|
+
layout: DashboardLayout;
|
|
10
|
+
/**
|
|
11
|
+
* Header actions: one list for both panels, or one per panel (#579 — "Ask
|
|
12
|
+
* assistant" describes the panel it was invoked from). On phones the single
|
|
13
|
+
* panel offers the actions of the view the toggle shows.
|
|
14
|
+
*/
|
|
15
|
+
actions?: PanelAction[] | ((kind: TopProblemsKind) => PanelAction[]);
|
|
16
|
+
now?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function TopProblems({ routes, errors, layout, actions, now }: TopProblemsProps): import("react").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=TopProblems.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TopProblems.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/TopProblems.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAC1F,OAAO,KAAK,EAEV,kBAAkB,EAElB,kBAAkB,EACnB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAgK/D,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,eAAe,KAAK,WAAW,EAAE,CAAC,CAAC;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAY,EAAE,GAAgB,EAAE,EAAE,gBAAgB,+BAqFvG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Top problems — issue #578, epic #576.
|
|
4
|
+
*
|
|
5
|
+
* The ten request paths with the most 5xx responses (then 4xx except 401,
|
|
6
|
+
* then highest p95), and
|
|
7
|
+
* the ten most frequent error log messages — ranked by the API. Two panels,
|
|
8
|
+
* each fetched on its own so one failing leaves the other working.
|
|
9
|
+
*
|
|
10
|
+
* A route no route of the running API matches (#650, `unknown`: a 404 from
|
|
11
|
+
* the not-found handler — e.g. a web build calling a route its API lacks)
|
|
12
|
+
* carries an "unknown route" chip beside its path.
|
|
13
|
+
*
|
|
14
|
+
* Desktop: two tables side by side. Tablet: stacked. Phone: ONE panel with a
|
|
15
|
+
* Routes / Errors toggle and a card list instead of a table.
|
|
16
|
+
*/
|
|
17
|
+
import { useState } from 'react';
|
|
18
|
+
import { Box, Chip, Grid, List, ListItem, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, ToggleButton, ToggleButtonGroup, Typography, } from '@mui/material';
|
|
19
|
+
import { DashboardPanel } from './DashboardPanel.js';
|
|
20
|
+
import { formatDuration, formatRelative, formatTimestamp } from '../../../headless/lib/format.js';
|
|
21
|
+
import { useTelemetryTokens } from '../../../theme/telemetryTokens.js';
|
|
22
|
+
const pct = (value) => `${value.toLocaleString(undefined, { maximumFractionDigits: 2 })}%`;
|
|
23
|
+
const ms = (value) => (value === null ? '—' : formatDuration(value));
|
|
24
|
+
/** `clientErrors` is always sent by a current API; `—` if an older one omits it. */
|
|
25
|
+
const clientErrorsText = (item) => item.clientErrors === undefined ? '—' : item.clientErrors.toLocaleString();
|
|
26
|
+
function UnknownRouteChip() {
|
|
27
|
+
return (_jsx(Chip, { label: "unknown route", size: "small", color: "warning", variant: "outlined", "data-testid": "unknown-route-chip", title: "No route of the running API matches this method and path (404 from the not-found handler)", sx: { ml: 0.75, height: 20, fontSize: '0.7rem', fontFamily: (theme) => theme.typography.fontFamily, verticalAlign: 'middle' } }));
|
|
28
|
+
}
|
|
29
|
+
const clamp = (lines) => ({
|
|
30
|
+
display: '-webkit-box',
|
|
31
|
+
WebkitLineClamp: lines,
|
|
32
|
+
WebkitBoxOrient: 'vertical',
|
|
33
|
+
overflow: 'hidden',
|
|
34
|
+
wordBreak: 'break-word',
|
|
35
|
+
});
|
|
36
|
+
function RoutesTable({ items }) {
|
|
37
|
+
const tokens = useTelemetryTokens();
|
|
38
|
+
return (_jsx(TableContainer, { sx: { overflowX: 'auto' }, children: _jsxs(Table, { size: "small", "aria-label": "Top routes", children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { children: "Method" }), _jsx(TableCell, { children: "Route" }), _jsx(TableCell, { align: "right", children: "Requests" }), _jsx(TableCell, { align: "right", children: "5xx" }), _jsx(TableCell, { align: "right", title: "4xx responses except 401", children: "4xx" }), _jsx(TableCell, { align: "right", children: "p95" })] }) }), _jsx(TableBody, { children: items.map((item, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { sx: { fontFamily: 'monospace' }, children: item.method ?? '—' }), _jsxs(TableCell, { sx: { fontFamily: 'monospace', overflowWrap: 'anywhere', minWidth: 200 }, children: [item.route ?? '—', item.unknown && _jsx(UnknownRouteChip, {})] }), _jsx(TableCell, { align: "right", children: item.count.toLocaleString() }), _jsx(TableCell, { align: "right", sx: { color: item.errors > 0 ? tokens.status.crit : undefined, whiteSpace: 'nowrap' }, children: pct(item.errorRatePct) }), _jsx(TableCell, { align: "right", sx: { color: (item.clientErrors ?? 0) > 0 ? tokens.status.warn : undefined, whiteSpace: 'nowrap' }, children: clientErrorsText(item) }), _jsx(TableCell, { align: "right", sx: { whiteSpace: 'nowrap' }, children: ms(item.p95Ms) })] }, `${item.method}-${item.route}-${index}`))) })] }) }));
|
|
39
|
+
}
|
|
40
|
+
function ErrorsTable({ items, now }) {
|
|
41
|
+
return (_jsx(TableContainer, { sx: { overflowX: 'auto' }, children: _jsxs(Table, { size: "small", "aria-label": "Top errors", children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { children: "Message" }), _jsx(TableCell, { align: "right", children: "Count" }), _jsx(TableCell, { children: "First seen" }), _jsx(TableCell, { children: "Last seen" }), _jsx(TableCell, { children: "Service" })] }) }), _jsx(TableBody, { children: items.map((item, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { sx: { minWidth: 160 }, children: _jsx(Box, { sx: clamp(2), title: item.message ?? undefined, children: item.message ?? '—' }) }), _jsx(TableCell, { align: "right", children: item.count.toLocaleString() }), _jsx(TableCell, { sx: { whiteSpace: 'nowrap' }, title: formatTimestamp(item.firstSeen), children: item.firstSeen ? formatRelative(item.firstSeen, now) : '—' }), _jsx(TableCell, { sx: { whiteSpace: 'nowrap' }, title: formatTimestamp(item.lastSeen), children: item.lastSeen ? formatRelative(item.lastSeen, now) : '—' }), _jsx(TableCell, { sx: { wordBreak: 'break-word' }, children: item.service ?? '—' })] }, `${item.message}-${index}`))) })] }) }));
|
|
42
|
+
}
|
|
43
|
+
function RoutesCards({ items }) {
|
|
44
|
+
const tokens = useTelemetryTokens();
|
|
45
|
+
return (_jsx(List, { disablePadding: true, "aria-label": "Top routes", children: items.map((item, index) => (_jsxs(ListItem, { divider: true, sx: { px: 0, display: 'block' }, children: [_jsxs(Typography, { variant: "body2", sx: { fontFamily: 'monospace', wordBreak: 'break-all' }, children: [_jsx("strong", { children: item.method ?? '—' }), " ", item.route ?? '—', item.unknown && _jsx(UnknownRouteChip, {})] }), _jsxs(Typography, { variant: "caption", color: "text.secondary", children: [item.count.toLocaleString(), " req \u00B7", ' ', _jsxs(Box, { component: "span", sx: { color: item.errors > 0 ? tokens.status.crit : undefined }, children: [pct(item.errorRatePct), " 5xx"] }), ' ', "\u00B7", ' ', _jsxs(Box, { component: "span", sx: { color: (item.clientErrors ?? 0) > 0 ? tokens.status.warn : undefined }, children: [clientErrorsText(item), " 4xx"] }), ' ', "\u00B7 p95 ", ms(item.p95Ms)] })] }, `${item.method}-${item.route}-${index}`))) }));
|
|
46
|
+
}
|
|
47
|
+
function ErrorsCards({ items, now }) {
|
|
48
|
+
return (_jsx(List, { disablePadding: true, "aria-label": "Top errors", children: items.map((item, index) => (_jsxs(ListItem, { divider: true, sx: { px: 0, display: 'block' }, children: [_jsx(Typography, { variant: "body2", sx: clamp(2), children: item.message ?? '—' }), _jsxs(Typography, { variant: "caption", color: "text.secondary", children: [item.count.toLocaleString(), "\u00D7 \u00B7 last ", item.lastSeen ? formatRelative(item.lastSeen, now) : '—', item.service ? ` · ${item.service}` : ''] })] }, `${item.message}-${index}`))) }));
|
|
49
|
+
}
|
|
50
|
+
export function TopProblems({ routes, errors, layout, actions = [], now = Date.now() }) {
|
|
51
|
+
const [kind, setKind] = useState('routes');
|
|
52
|
+
const actionsOf = (which) => (typeof actions === 'function' ? actions(which) : actions);
|
|
53
|
+
const routesPanel = (_jsx(DashboardPanel, { id: "panel-top-routes", title: "Top failing routes", actions: actionsOf('routes'), sql: routes.data?.sql, isLoading: routes.isLoading, isRefreshing: routes.isRefreshing, error: routes.error, onRetry: routes.reload, isEmpty: !!routes.data && routes.data.items.length === 0, emptyMessage: "No requests in this window.", children: routes.data && _jsx(RoutesTable, { items: routes.data.items }) }));
|
|
54
|
+
const errorsPanel = (_jsx(DashboardPanel, { id: "panel-top-errors", title: "Top errors", actions: actionsOf('errors'), sql: errors.data?.sql, isLoading: errors.isLoading, isRefreshing: errors.isRefreshing, error: errors.error, onRetry: errors.reload, isEmpty: !!errors.data && errors.data.items.length === 0, emptyMessage: "No error logs in this window.", children: errors.data && _jsx(ErrorsTable, { items: errors.data.items, now: now }) }));
|
|
55
|
+
if (layout === 'phone') {
|
|
56
|
+
const active = kind === 'routes' ? routes : errors;
|
|
57
|
+
return (_jsxs(DashboardPanel, { id: "panel-top", title: "Top problems", headerExtra: _jsxs(ToggleButtonGroup, { exclusive: true, size: "small", "aria-label": "Top problems view", value: kind, onChange: (_event, next) => next && setKind(next), children: [_jsx(ToggleButton, { value: "routes", sx: { minHeight: 44, textTransform: 'none' }, children: "Routes" }), _jsx(ToggleButton, { value: "errors", sx: { minHeight: 44, textTransform: 'none' }, children: "Errors" })] }), actions: actionsOf(kind), sql: active.data?.sql, isLoading: active.isLoading, isRefreshing: active.isRefreshing, error: active.error, onRetry: active.reload, isEmpty: !!active.data && active.data.items.length === 0, emptyMessage: kind === 'routes' ? 'No requests in this window.' : 'No error logs in this window.', children: [kind === 'routes' && routes.data && _jsx(RoutesCards, { items: routes.data.items }), kind === 'errors' && errors.data && _jsx(ErrorsCards, { items: errors.data.items, now: now })] }));
|
|
58
|
+
}
|
|
59
|
+
return (_jsxs(Grid, { container: true, spacing: 2, children: [_jsx(Grid, { size: { xs: 12, lg: 6 }, sx: { minWidth: 0 }, children: routesPanel }), _jsx(Grid, { size: { xs: 12, lg: 6 }, sx: { minWidth: 0 }, children: errorsPanel })] }));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=TopProblems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TopProblems.js","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/TopProblems.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DashboardUnknownRoutes } from '../../../headless/services/telemetryDashboard.js';
|
|
2
|
+
import { type PanelAction } from './DashboardPanel.js';
|
|
3
|
+
export declare const UNKNOWN_ROUTES_TITLE = "Unknown API routes";
|
|
4
|
+
export interface UnknownRoutesPanelProps {
|
|
5
|
+
unknownRoutes: DashboardUnknownRoutes;
|
|
6
|
+
/** The statements that computed the block (`unknownRoutesSql`), handed to the actions. */
|
|
7
|
+
sql: string[];
|
|
8
|
+
actions?: PanelAction[];
|
|
9
|
+
isRefreshing?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function UnknownRoutesPanel({ unknownRoutes, sql, actions, isRefreshing }: UnknownRoutesPanelProps): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=UnknownRoutesPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnknownRoutesPanel.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/UnknownRoutesPanel.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAyB,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AACtH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvE,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAoBzD,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,sBAAsB,CAAC;IACtC,0FAA0F;IAC1F,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,OAAY,EAAE,YAAoB,EAAE,EAAE,uBAAuB,+BAsDrH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Unknown API routes — issue #650.
|
|
4
|
+
*
|
|
5
|
+
* Requests the API answered from its not-found handler: no route of the
|
|
6
|
+
* running build matches the method and path. With a bearer token they come
|
|
7
|
+
* from the application itself — typically a web build calling a route its API
|
|
8
|
+
* lacks after a deploy ("Cannot GET /api/coach/messages") — and the API
|
|
9
|
+
* degrades the verdict; without one they are usually internet scanners and
|
|
10
|
+
* are only counted.
|
|
11
|
+
*
|
|
12
|
+
* Shows the summary's `unknownRoutes.topRoutes` (at most 5, bearer requests
|
|
13
|
+
* first, as the API ranked them): `METHOD /path`, the request count, and an
|
|
14
|
+
* "app" chip (some requests carried a bearer) or an "anonymous" one. The
|
|
15
|
+
* page renders it only when the block is present and counted a request
|
|
16
|
+
* (`hasUnknownRoutes`); it is a compact list at every width, so it fits a
|
|
17
|
+
* 390px phone without a table.
|
|
18
|
+
*/
|
|
19
|
+
import { Box, Chip, List, ListItem, Typography } from '@mui/material';
|
|
20
|
+
import { DashboardPanel } from './DashboardPanel.js';
|
|
21
|
+
import { UNKNOWN_ROUTES_ANCHOR } from '../../../headless/lib/unknownRoutes.js';
|
|
22
|
+
import { useTelemetryTokens } from '../../../theme/telemetryTokens.js';
|
|
23
|
+
export const UNKNOWN_ROUTES_TITLE = 'Unknown API routes';
|
|
24
|
+
function routeTitle(item) {
|
|
25
|
+
return `${item.count.toLocaleString()} requests: ${item.bearer.toLocaleString()} from the app (with a bearer token), ${item.anonymous.toLocaleString()} anonymous`;
|
|
26
|
+
}
|
|
27
|
+
function SourceChip({ item }) {
|
|
28
|
+
const fromApp = item.bearer > 0;
|
|
29
|
+
return (_jsx(Chip, { size: "small", label: fromApp ? 'app' : 'anonymous', color: fromApp ? 'warning' : 'default', variant: "outlined", "data-testid": "unknown-route-source", sx: { height: 22, fontSize: '0.75rem' } }));
|
|
30
|
+
}
|
|
31
|
+
export function UnknownRoutesPanel({ unknownRoutes, sql, actions = [], isRefreshing = false }) {
|
|
32
|
+
const { requests, bearer, anonymous, topRoutes, truncated } = unknownRoutes;
|
|
33
|
+
const tokens = useTelemetryTokens();
|
|
34
|
+
return (_jsxs(DashboardPanel, { id: "panel-unknown-routes", anchorId: UNKNOWN_ROUTES_ANCHOR, title: UNKNOWN_ROUTES_TITLE, actions: actions, sql: sql, isRefreshing: isRefreshing, isEmpty: topRoutes.length === 0, emptyMessage: "No unknown routes listed for this window.", children: [_jsxs(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 1 }, "data-testid": "unknown-routes-summary", children: [requests.toLocaleString(), " ", requests === 1 ? 'request' : 'requests', " to routes this API does not have:", ' ', _jsxs(Box, { component: "span", sx: { color: bearer > 0 ? tokens.status.warn : undefined, fontWeight: bearer > 0 ? 600 : undefined }, children: [bearer.toLocaleString(), " from the app"] }), ", ", anonymous.toLocaleString(), " anonymous.", bearer > 0 && ' Requests from the app usually mean the web and API versions differ, e.g. after a deploy.'] }), _jsx(List, { disablePadding: true, "aria-label": UNKNOWN_ROUTES_TITLE, children: topRoutes.map((item, index) => (_jsxs(ListItem, { divider: index < topRoutes.length - 1, title: routeTitle(item), sx: { px: 0, py: 0.75, gap: 1, alignItems: 'center' }, children: [_jsxs(Typography, { variant: "body2", sx: { fontFamily: 'monospace', flex: 1, minWidth: 0, overflowWrap: 'anywhere' }, children: [_jsx("strong", { children: item.method ?? '—' }), " ", item.route ?? '—'] }), _jsx(SourceChip, { item: item }), _jsx(Typography, { variant: "body2", sx: { minWidth: 40, textAlign: 'right', fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' }, "aria-label": `${item.count.toLocaleString()} requests`, children: item.count.toLocaleString() })] }, `${item.method}-${item.route}-${index}`))) }), truncated && (_jsx(Typography, { variant: "caption", color: "text.secondary", sx: { display: 'block', mt: 0.5 }, children: "More unknown routes were requested; the most-hit are listed." }))] }));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=UnknownRoutesPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnknownRoutesPanel.js","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/UnknownRoutesPanel.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAEzD,SAAS,UAAU,CAAC,IAA2B;IAC7C,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,wCAAwC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,YAAY,CAAC;AACrK,CAAC;AAED,SAAS,UAAU,CAAC,EAAE,IAAI,EAAmC;IAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EACpC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EACtC,OAAO,EAAC,UAAU,iBACN,sBAAsB,EAClC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,GACvC,CACH,CAAC;AACJ,CAAC;AAUD,MAAM,UAAU,kBAAkB,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,YAAY,GAAG,KAAK,EAA2B;IACpH,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;IAC5E,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,OAAO,CACL,MAAC,cAAc,IACb,EAAE,EAAC,sBAAsB,EACzB,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,EAC/B,YAAY,EAAC,2CAA2C,aAExD,MAAC,UAAU,IAAC,OAAO,EAAC,OAAO,EAAC,KAAK,EAAC,gBAAgB,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,iBAAc,wBAAwB,aACnG,QAAQ,CAAC,cAAc,EAAE,OAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,wCAAoC,GAAG,EAC3G,MAAC,GAAG,IAAC,SAAS,EAAC,MAAM,EAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,aACvH,MAAM,CAAC,cAAc,EAAE,qBACpB,QACH,SAAS,CAAC,cAAc,EAAE,iBAC5B,MAAM,GAAG,CAAC,IAAI,2FAA2F,IAC/F,EACb,KAAC,IAAI,IAAC,cAAc,sBAAa,oBAAoB,YAClD,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,MAAC,QAAQ,IAEP,OAAO,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EACrC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EACvB,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,aAErD,MAAC,UAAU,IACT,OAAO,EAAC,OAAO,EACf,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,aAE/E,2BAAS,IAAI,CAAC,MAAM,IAAI,GAAG,GAAU,OAAE,IAAI,CAAC,KAAK,IAAI,GAAG,IAC7C,EACb,KAAC,UAAU,IAAC,IAAI,EAAE,IAAI,GAAI,EAC1B,KAAC,UAAU,IACT,OAAO,EAAC,OAAO,EACf,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,gBACtF,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,YAEpD,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,GACjB,KAlBR,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,EAAE,CAmBnC,CACZ,CAAC,GACG,EACN,SAAS,IAAI,CACZ,KAAC,UAAU,IAAC,OAAO,EAAC,SAAS,EAAC,KAAK,EAAC,gBAAgB,EAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,6EAEzE,CACd,IACc,CAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type AlertColor } from '@mui/material';
|
|
2
|
+
import type { SvgIconComponent } from '@mui/icons-material';
|
|
3
|
+
import type { DashboardVerdictLevel } from '../../../headless/services/telemetryDashboard.js';
|
|
4
|
+
import type { TelemetryErrorInfo } from '../../../headless/hooks/useTelemetryExplorer.js';
|
|
5
|
+
interface LevelMeta {
|
|
6
|
+
label: string;
|
|
7
|
+
Icon: SvgIconComponent;
|
|
8
|
+
/** `null` = neutral grey (no data). */
|
|
9
|
+
severity: AlertColor | null;
|
|
10
|
+
}
|
|
11
|
+
export declare const VERDICT_META: Record<DashboardVerdictLevel, LevelMeta>;
|
|
12
|
+
export interface VerdictBannerProps {
|
|
13
|
+
verdict: {
|
|
14
|
+
level: DashboardVerdictLevel;
|
|
15
|
+
reasons: string[];
|
|
16
|
+
} | null;
|
|
17
|
+
isLoading?: boolean;
|
|
18
|
+
error?: TelemetryErrorInfo | null;
|
|
19
|
+
onRetry?: () => void;
|
|
20
|
+
/** Phone layout: one line, tap to expand. */
|
|
21
|
+
compact?: boolean;
|
|
22
|
+
/** One button on the banner (#579: "Explain this"). */
|
|
23
|
+
action?: {
|
|
24
|
+
label: string;
|
|
25
|
+
onClick: () => void;
|
|
26
|
+
};
|
|
27
|
+
/** A link after a reason (#602: to the section it is about), or null for none. */
|
|
28
|
+
reasonAction?: (reason: string) => {
|
|
29
|
+
label: string;
|
|
30
|
+
onClick: () => void;
|
|
31
|
+
} | null;
|
|
32
|
+
}
|
|
33
|
+
export declare function VerdictBanner({ verdict, isLoading, error, onRetry, compact, action, reasonAction, }: VerdictBannerProps): import("react").JSX.Element;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=VerdictBanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerdictBanner.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/VerdictBanner.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAA8D,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAM5G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AAC9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAG1F,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,gBAAgB,CAAC;IACvB,uCAAuC;IACvC,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAKjE,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE;QAAE,KAAK,EAAE,qBAAqB,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IAChD,kFAAkF;IAClF,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAClF;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAiB,EACjB,KAAY,EACZ,OAAO,EACP,OAAe,EACf,MAAM,EACN,YAAY,GACb,EAAE,kBAAkB,+BA+GpB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The Telemetry Dashboard's verdict — issue #578, epic #576.
|
|
4
|
+
*
|
|
5
|
+
* The first thing on the page answers "is anything wrong?". The level and its
|
|
6
|
+
* reasons are the API's (`summary.verdict`); this only presents them. Every
|
|
7
|
+
* level carries an icon AND a word, never colour alone, and the banner is a
|
|
8
|
+
* polite live region, so a verdict that changes on auto-refresh is announced.
|
|
9
|
+
*
|
|
10
|
+
* On phones it collapses to one line (level + first reason) and expands on
|
|
11
|
+
* tap (`aria-expanded`).
|
|
12
|
+
*
|
|
13
|
+
* `action` (#579) adds one button to the banner — the dashboard's "Explain
|
|
14
|
+
* this", which opens the assistant with the verdict prefilled.
|
|
15
|
+
*
|
|
16
|
+
* `reasonAction` (#602) adds a link after a reason — "Show Database" — that
|
|
17
|
+
* takes the reader to the section the reason is about (the page decides which
|
|
18
|
+
* reasons have one, and only for sections on screen).
|
|
19
|
+
*/
|
|
20
|
+
import { useId, useState } from 'react';
|
|
21
|
+
import { Alert, Box, Button, ButtonBase, Link, Skeleton, Typography } from '@mui/material';
|
|
22
|
+
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutlined';
|
|
23
|
+
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
|
|
24
|
+
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlineOutlined';
|
|
25
|
+
import CloudOffOutlinedIcon from '@mui/icons-material/CloudOffOutlined';
|
|
26
|
+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
27
|
+
import { PanelError } from './DashboardPanel.js';
|
|
28
|
+
export const VERDICT_META = {
|
|
29
|
+
healthy: { label: 'Healthy', Icon: CheckCircleOutlineIcon, severity: 'success' },
|
|
30
|
+
degraded: { label: 'Degraded', Icon: WarningAmberIcon, severity: 'warning' },
|
|
31
|
+
critical: { label: 'Critical', Icon: ErrorOutlineIcon, severity: 'error' },
|
|
32
|
+
no_data: { label: 'No telemetry received', Icon: CloudOffOutlinedIcon, severity: null },
|
|
33
|
+
};
|
|
34
|
+
export function VerdictBanner({ verdict, isLoading = false, error = null, onRetry, compact = false, action, reasonAction, }) {
|
|
35
|
+
const [expanded, setExpanded] = useState(false);
|
|
36
|
+
const reasonsId = useId();
|
|
37
|
+
if (error)
|
|
38
|
+
return _jsx(PanelError, { error: error, onRetry: onRetry });
|
|
39
|
+
if (isLoading || !verdict) {
|
|
40
|
+
return _jsx(Skeleton, { variant: "rounded", height: compact ? 48 : 64, "data-testid": "verdict-skeleton" });
|
|
41
|
+
}
|
|
42
|
+
const meta = VERDICT_META[verdict.level] ?? VERDICT_META.no_data;
|
|
43
|
+
const reasons = verdict.reasons;
|
|
44
|
+
const neutral = meta.severity === null;
|
|
45
|
+
const canExpand = compact && reasons.length > 0;
|
|
46
|
+
const reasonList = (hidden) => reasons.length > 0 && (_jsx(Box, { component: "ul", id: reasonsId, hidden: hidden, sx: { m: 0, mt: 0.5, pl: 2.5 }, children: reasons.map((reason, index) => {
|
|
47
|
+
const link = reasonAction?.(reason) ?? null;
|
|
48
|
+
return (_jsxs(Typography, { component: "li", variant: "body2", sx: { wordBreak: 'break-word' }, children: [reason, link && (_jsxs(_Fragment, { children: [' ', _jsx(Link, { component: "button", type: "button", variant: "body2", color: "inherit", onClick: link.onClick, sx: { fontWeight: 600, verticalAlign: 'baseline', textAlign: 'left' }, children: link.label })] }))] }, `${index}-${reason}`));
|
|
49
|
+
}) }));
|
|
50
|
+
return (_jsx(Alert, { role: "status", "aria-live": "polite", "data-testid": "verdict-banner", "data-level": verdict.level, severity: meta.severity ?? 'info', icon: _jsx(meta.Icon, { "aria-hidden": true }), action: action ? (_jsx(Button, { color: "inherit", size: "small", onClick: action.onClick, sx: { minHeight: 44, whiteSpace: 'nowrap', alignSelf: 'center' }, children: action.label })) : undefined, sx: {
|
|
51
|
+
minWidth: 0,
|
|
52
|
+
'& .MuiAlert-message': { minWidth: 0, flex: 1 },
|
|
53
|
+
...(neutral && {
|
|
54
|
+
bgcolor: 'action.hover',
|
|
55
|
+
color: 'text.primary',
|
|
56
|
+
'& .MuiAlert-icon': { color: 'text.secondary' },
|
|
57
|
+
}),
|
|
58
|
+
}, children: canExpand ? (_jsxs(_Fragment, { children: [_jsxs(ButtonBase, { onClick: () => setExpanded((open) => !open), "aria-expanded": expanded, "aria-controls": reasonsId, sx: {
|
|
59
|
+
display: 'flex',
|
|
60
|
+
width: '100%',
|
|
61
|
+
minHeight: 44,
|
|
62
|
+
justifyContent: 'space-between',
|
|
63
|
+
textAlign: 'left',
|
|
64
|
+
gap: 1,
|
|
65
|
+
borderRadius: 1,
|
|
66
|
+
}, children: [_jsxs(Typography, { variant: "body2", noWrap: !expanded, sx: { minWidth: 0, flex: 1 }, children: [_jsx("strong", { children: meta.label }), !expanded && ` · ${reasons[0]}`] }), _jsx(ExpandMoreIcon, { "aria-hidden": true, fontSize: "small", sx: { transform: expanded ? 'rotate(180deg)' : 'none', transition: 'transform 150ms' } })] }), reasonList(!expanded)] })) : (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "subtitle1", component: "p", sx: { fontWeight: 600, lineHeight: 1.4 }, children: meta.label }), reasonList(false)] })) }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=VerdictBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerdictBanner.js","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/VerdictBanner.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ZoomBrushProps {
|
|
2
|
+
/** The band values, in order (bucket start timestamps). */
|
|
3
|
+
values: string[];
|
|
4
|
+
drag: boolean;
|
|
5
|
+
tap: boolean;
|
|
6
|
+
onSelect: (startIndex: number, endIndex: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function ZoomBrush({ values, drag, tap, onSelect }: ZoomBrushProps): import("react").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=ZoomBrush.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoomBrush.d.ts","sourceRoot":"","sources":["../../../../../src/telemetry/ui/components/dashboard/ZoomBrush.tsx"],"names":[],"mappings":"AAsBA,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAQD,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,cAAc,sCAwGxE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Zoom by selection over a band-scaled time chart — issue #578, epic #576.
|
|
4
|
+
*
|
|
5
|
+
* `@mui/x-charts`' community brush reports coordinates, not a data range, so
|
|
6
|
+
* this is a small overlay of our own: a transparent rect over the drawing area
|
|
7
|
+
* that maps pointer x to the nearest bucket through the chart's own x scale.
|
|
8
|
+
*
|
|
9
|
+
* - `drag`: press, drag across buckets, release → `onSelect(first, last)`.
|
|
10
|
+
* - `tap`: press and release in place → `onSelect(i, i)` (one bucket).
|
|
11
|
+
*
|
|
12
|
+
* Rendered as a CHILD of the chart surface (it reads the chart context).
|
|
13
|
+
* `touch-action: pan-y` keeps vertical page scrolling working on touch
|
|
14
|
+
* screens while a horizontal drag selects. Keyboard users zoom with the range
|
|
15
|
+
* selector instead; this is a pointer shortcut, not the only way in.
|
|
16
|
+
*/
|
|
17
|
+
import { useRef, useState } from 'react';
|
|
18
|
+
import { useTheme } from '@mui/material';
|
|
19
|
+
import { useDrawingArea, useXScale } from '@mui/x-charts/hooks';
|
|
20
|
+
/** Pixels a pointer must travel before a press counts as a drag, not a tap. */
|
|
21
|
+
const DRAG_THRESHOLD_PX = 6;
|
|
22
|
+
export function ZoomBrush({ values, drag, tap, onSelect }) {
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
const area = useDrawingArea();
|
|
25
|
+
const scale = useXScale();
|
|
26
|
+
const press = useRef(null);
|
|
27
|
+
const [selection, setSelection] = useState(null);
|
|
28
|
+
if (!drag && !tap)
|
|
29
|
+
return null;
|
|
30
|
+
if (values.length === 0 || area.width <= 0 || typeof scale?.bandwidth !== 'function')
|
|
31
|
+
return null;
|
|
32
|
+
const bandwidth = scale.bandwidth();
|
|
33
|
+
const indexAt = (clientX, target) => {
|
|
34
|
+
const svg = target.ownerSVGElement ?? target;
|
|
35
|
+
const x = clientX - svg.getBoundingClientRect().left;
|
|
36
|
+
let best = 0;
|
|
37
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
38
|
+
values.forEach((value, index) => {
|
|
39
|
+
const start = scale(value);
|
|
40
|
+
if (start === undefined)
|
|
41
|
+
return;
|
|
42
|
+
const distance = Math.abs(start + bandwidth / 2 - x);
|
|
43
|
+
if (distance < bestDistance) {
|
|
44
|
+
bestDistance = distance;
|
|
45
|
+
best = index;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return best;
|
|
49
|
+
};
|
|
50
|
+
const onPointerDown = (event) => {
|
|
51
|
+
if (event.button !== 0)
|
|
52
|
+
return;
|
|
53
|
+
const index = indexAt(event.clientX, event.currentTarget);
|
|
54
|
+
press.current = { index, x: event.clientX, pointerId: event.pointerId };
|
|
55
|
+
if (drag) {
|
|
56
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
57
|
+
setSelection({ a: index, b: index });
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const onPointerMove = (event) => {
|
|
61
|
+
if (!drag || !press.current || press.current.pointerId !== event.pointerId)
|
|
62
|
+
return;
|
|
63
|
+
const index = indexAt(event.clientX, event.currentTarget);
|
|
64
|
+
setSelection((current) => (current && current.b !== index ? { a: current.a, b: index } : current));
|
|
65
|
+
};
|
|
66
|
+
const finish = (event) => {
|
|
67
|
+
const started = press.current;
|
|
68
|
+
press.current = null;
|
|
69
|
+
setSelection(null);
|
|
70
|
+
if (!started || started.pointerId !== event.pointerId)
|
|
71
|
+
return;
|
|
72
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
73
|
+
const moved = Math.abs(event.clientX - started.x) >= DRAG_THRESHOLD_PX;
|
|
74
|
+
const index = indexAt(event.clientX, event.currentTarget);
|
|
75
|
+
if (drag && moved && index !== started.index) {
|
|
76
|
+
onSelect(Math.min(started.index, index), Math.max(started.index, index));
|
|
77
|
+
}
|
|
78
|
+
else if (tap && !moved) {
|
|
79
|
+
onSelect(started.index, started.index);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const cancel = () => {
|
|
83
|
+
press.current = null;
|
|
84
|
+
setSelection(null);
|
|
85
|
+
};
|
|
86
|
+
let highlight = null;
|
|
87
|
+
if (selection && selection.a !== selection.b) {
|
|
88
|
+
const first = Math.min(selection.a, selection.b);
|
|
89
|
+
const last = Math.max(selection.a, selection.b);
|
|
90
|
+
const x1 = scale(values[first]) ?? area.left;
|
|
91
|
+
const x2 = (scale(values[last]) ?? area.left) + bandwidth;
|
|
92
|
+
highlight = (_jsx("rect", { "data-testid": "zoom-selection", x: x1, y: area.top, width: Math.max(0, x2 - x1), height: area.height, fill: theme.palette.primary.main, fillOpacity: 0.15, stroke: theme.palette.primary.main, strokeOpacity: 0.5, pointerEvents: "none" }));
|
|
93
|
+
}
|
|
94
|
+
return (_jsxs("g", { children: [highlight, _jsx("rect", { "data-testid": "zoom-brush", x: area.left, y: area.top, width: area.width, height: area.height, fill: "transparent", style: { touchAction: 'pan-y', cursor: drag ? 'crosshair' : 'pointer' }, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: finish, onPointerCancel: cancel })] }));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ZoomBrush.js.map
|