@openchoreo/backstage-plugin-openchoreo-observability 1.1.0
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 +5 -0
- package/README.md +22 -0
- package/dist/api/FinOpsAgentApi.esm.js +43 -0
- package/dist/api/FinOpsAgentApi.esm.js.map +1 -0
- package/dist/api/ObservabilityApi.esm.js +568 -0
- package/dist/api/ObservabilityApi.esm.js.map +1 -0
- package/dist/api/ObserverUrlCache.esm.js +59 -0
- package/dist/api/ObserverUrlCache.esm.js.map +1 -0
- package/dist/api/RCAAgentApi.esm.js +104 -0
- package/dist/api/RCAAgentApi.esm.js.map +1 -0
- package/dist/components/Alerts/AlertRow.esm.js +203 -0
- package/dist/components/Alerts/AlertRow.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsActions.esm.js +77 -0
- package/dist/components/Alerts/AlertsActions.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsFilter.esm.js +95 -0
- package/dist/components/Alerts/AlertsFilter.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsTable.esm.js +63 -0
- package/dist/components/Alerts/AlertsTable.esm.js.map +1 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js +251 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js.map +1 -0
- package/dist/components/Alerts/types.esm.js +4 -0
- package/dist/components/Alerts/types.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js +141 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js +128 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js +517 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js +149 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js.map +1 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js +112 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js.map +1 -0
- package/dist/components/CostAnalysis/index.esm.js +2 -0
- package/dist/components/CostAnalysis/index.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentRow.esm.js +258 -0
- package/dist/components/Incidents/IncidentRow.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsActions.esm.js +77 -0
- package/dist/components/Incidents/IncidentsActions.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js +144 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsTable.esm.js +68 -0
- package/dist/components/Incidents/IncidentsTable.esm.js.map +1 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js +283 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js.map +1 -0
- package/dist/components/Incidents/types.esm.js +8 -0
- package/dist/components/Incidents/types.esm.js.map +1 -0
- package/dist/components/Metrics/ChartTooltip.esm.js +53 -0
- package/dist/components/Metrics/ChartTooltip.esm.js.map +1 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js +109 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js.map +1 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js +99 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsActions.esm.js +30 -0
- package/dist/components/Metrics/MetricsActions.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsFilters.esm.js +49 -0
- package/dist/components/Metrics/MetricsFilters.esm.js.map +1 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js +196 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js.map +1 -0
- package/dist/components/Metrics/styles.esm.js +55 -0
- package/dist/components/Metrics/styles.esm.js.map +1 -0
- package/dist/components/Metrics/utils.esm.js +221 -0
- package/dist/components/Metrics/utils.esm.js.map +1 -0
- package/dist/components/RCA/RCAActions.esm.js +42 -0
- package/dist/components/RCA/RCAActions.esm.js.map +1 -0
- package/dist/components/RCA/RCAFilters.esm.js +100 -0
- package/dist/components/RCA/RCAFilters.esm.js.map +1 -0
- package/dist/components/RCA/RCAPage.esm.js +137 -0
- package/dist/components/RCA/RCAPage.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js +9 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js +94 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js +308 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js +113 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js +272 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js +48 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js +205 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js +121 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js +593 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js +35 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js +526 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js +70 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/styles.esm.js +467 -0
- package/dist/components/RCA/RCAReport/styles.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport.esm.js +109 -0
- package/dist/components/RCA/RCAReport.esm.js.map +1 -0
- package/dist/components/RCA/RCATable.esm.js +140 -0
- package/dist/components/RCA/RCATable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js +182 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js +106 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js +200 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js +91 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js +220 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js +222 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/styles.esm.js +256 -0
- package/dist/components/RuntimeLogs/styles.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/types.esm.js +16 -0
- package/dist/components/RuntimeLogs/types.esm.js.map +1 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js +280 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js.map +1 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js +165 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js.map +1 -0
- package/dist/components/Traces/TracesActions.esm.js +37 -0
- package/dist/components/Traces/TracesActions.esm.js.map +1 -0
- package/dist/components/Traces/TracesFilters.esm.js +121 -0
- package/dist/components/Traces/TracesFilters.esm.js.map +1 -0
- package/dist/components/Traces/TracesTable.esm.js +137 -0
- package/dist/components/Traces/TracesTable.esm.js.map +1 -0
- package/dist/components/Traces/WaterfallView.esm.js +567 -0
- package/dist/components/Traces/WaterfallView.esm.js.map +1 -0
- package/dist/components/Traces/styles.esm.js +198 -0
- package/dist/components/Traces/styles.esm.js.map +1 -0
- package/dist/components/Traces/utils.esm.js +19 -0
- package/dist/components/Traces/utils.esm.js.map +1 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js +25 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js.map +1 -0
- package/dist/hooks/useComponentAlerts.esm.js +80 -0
- package/dist/hooks/useComponentAlerts.esm.js.map +1 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js +55 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js.map +1 -0
- package/dist/hooks/useDebouncedSearch.esm.js +24 -0
- package/dist/hooks/useDebouncedSearch.esm.js.map +1 -0
- package/dist/hooks/useFilters.esm.js +29 -0
- package/dist/hooks/useFilters.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReport.esm.js +66 -0
- package/dist/hooks/useFinOpsReport.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReports.esm.js +70 -0
- package/dist/hooks/useFinOpsReports.esm.js.map +1 -0
- package/dist/hooks/useGetComponentsByProject.esm.js +57 -0
- package/dist/hooks/useGetComponentsByProject.esm.js.map +1 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js +53 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js.map +1 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js +40 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js.map +1 -0
- package/dist/hooks/useMetrics.esm.js +107 -0
- package/dist/hooks/useMetrics.esm.js.map +1 -0
- package/dist/hooks/useProjectIncidents.esm.js +111 -0
- package/dist/hooks/useProjectIncidents.esm.js.map +1 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js +185 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useRCAReportByAlert.esm.js +54 -0
- package/dist/hooks/useRCAReportByAlert.esm.js.map +1 -0
- package/dist/hooks/useRCAReports.esm.js +75 -0
- package/dist/hooks/useRCAReports.esm.js.map +1 -0
- package/dist/hooks/useRuntimeLogs.esm.js +147 -0
- package/dist/hooks/useRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useSpanDetails.esm.js +71 -0
- package/dist/hooks/useSpanDetails.esm.js.map +1 -0
- package/dist/hooks/useTraceSpans.esm.js +80 -0
- package/dist/hooks/useTraceSpans.esm.js.map +1 -0
- package/dist/hooks/useTraces.esm.js +112 -0
- package/dist/hooks/useTraces.esm.js.map +1 -0
- package/dist/hooks/useUpdateIncident.esm.js +50 -0
- package/dist/hooks/useUpdateIncident.esm.js.map +1 -0
- package/dist/hooks/useUrlFilters.esm.js +63 -0
- package/dist/hooks/useUrlFilters.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js +80 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js +87 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js +135 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +107 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/types.esm.js +18 -0
- package/dist/types.esm.js.map +1 -0
- package/dist/utils/applyResourceChange.esm.js +79 -0
- package/dist/utils/applyResourceChange.esm.js.map +1 -0
- package/dist/utils/urlTimeRange.esm.js +52 -0
- package/dist/utils/urlTimeRange.esm.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useParams, useNavigate } from 'react-router-dom';
|
|
4
|
+
import { Typography, Box } from '@material-ui/core';
|
|
5
|
+
import { Progress } from '@backstage/core-components';
|
|
6
|
+
import { Alert } from '@material-ui/lab';
|
|
7
|
+
import { useRcaPermission, ForbiddenState } from '@openchoreo/backstage-plugin-react';
|
|
8
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
9
|
+
import { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';
|
|
10
|
+
import { useApi, discoveryApiRef } from '@backstage/core-plugin-api';
|
|
11
|
+
import { useGetEnvironmentsByNamespace } from '../../hooks/useGetEnvironmentsByNamespace.esm.js';
|
|
12
|
+
import { useFilters } from '../../hooks/useFilters.esm.js';
|
|
13
|
+
import '../../utils/urlTimeRange.esm.js';
|
|
14
|
+
import '../../api/ObservabilityApi.esm.js';
|
|
15
|
+
import { useRCAReport } from '../../hooks/useRCAReportByAlert.esm.js';
|
|
16
|
+
import { rcaAgentApiRef } from '../../api/RCAAgentApi.esm.js';
|
|
17
|
+
import '../../api/FinOpsAgentApi.esm.js';
|
|
18
|
+
import { RCAReportView } from './RCAReport/RCAReportView.esm.js';
|
|
19
|
+
|
|
20
|
+
const RCAReportContent = () => {
|
|
21
|
+
const { reportId } = useParams();
|
|
22
|
+
const navigate = useNavigate();
|
|
23
|
+
const { entity } = useEntity();
|
|
24
|
+
const { filters } = useFilters();
|
|
25
|
+
const rcaAgentApi = useApi(rcaAgentApiRef);
|
|
26
|
+
const discoveryApi = useApi(discoveryApiRef);
|
|
27
|
+
const namespace = entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE];
|
|
28
|
+
const projectName = entity.metadata.name;
|
|
29
|
+
const { environments } = useGetEnvironmentsByNamespace(
|
|
30
|
+
namespace,
|
|
31
|
+
projectName
|
|
32
|
+
);
|
|
33
|
+
const environment = filters.environment || environments[0];
|
|
34
|
+
const {
|
|
35
|
+
report: detailedReport,
|
|
36
|
+
loading,
|
|
37
|
+
error
|
|
38
|
+
} = useRCAReport(reportId, environment?.name, entity);
|
|
39
|
+
const [backendBaseUrl, setBackendBaseUrl] = useState();
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
discoveryApi.getBaseUrl("openchoreo-observability-backend").then(setBackendBaseUrl).catch(() => {
|
|
42
|
+
});
|
|
43
|
+
}, [discoveryApi]);
|
|
44
|
+
const chatContext = {
|
|
45
|
+
namespaceName: namespace || "",
|
|
46
|
+
environmentName: environment?.name || "",
|
|
47
|
+
projectName,
|
|
48
|
+
rcaAgentApi,
|
|
49
|
+
backendBaseUrl
|
|
50
|
+
};
|
|
51
|
+
if (loading) {
|
|
52
|
+
return /* @__PURE__ */ jsx(Progress, {});
|
|
53
|
+
}
|
|
54
|
+
if (!reportId) {
|
|
55
|
+
return /* @__PURE__ */ jsx(Alert, { severity: "error", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", children: "Report ID is required" }) });
|
|
56
|
+
}
|
|
57
|
+
if (error) {
|
|
58
|
+
let errorMessage = error;
|
|
59
|
+
let severity = "error";
|
|
60
|
+
if (error.includes("RCA service is not configured")) {
|
|
61
|
+
errorMessage = "AI RCA is not configured. Enable it to view RCA reports.";
|
|
62
|
+
severity = "info";
|
|
63
|
+
} else if (error.includes("Observability is not enabled")) {
|
|
64
|
+
errorMessage = "Observability is not enabled for this environment. Enable observability and enable the AI RCA agent.";
|
|
65
|
+
severity = "info";
|
|
66
|
+
}
|
|
67
|
+
return /* @__PURE__ */ jsx(Box, { mt: 2, mb: 2, children: /* @__PURE__ */ jsx(Alert, { severity, children: /* @__PURE__ */ jsx(Typography, { variant: "body1", children: errorMessage }) }) });
|
|
68
|
+
}
|
|
69
|
+
if (!detailedReport) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const handleBack = () => {
|
|
73
|
+
navigate(-1);
|
|
74
|
+
};
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
RCAReportView,
|
|
77
|
+
{
|
|
78
|
+
report: detailedReport,
|
|
79
|
+
reportId,
|
|
80
|
+
onBack: handleBack,
|
|
81
|
+
chatContext
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
const RCAReport = () => {
|
|
86
|
+
const {
|
|
87
|
+
canViewRca,
|
|
88
|
+
loading: permissionLoading,
|
|
89
|
+
deniedTooltip,
|
|
90
|
+
permissionName
|
|
91
|
+
} = useRcaPermission();
|
|
92
|
+
if (permissionLoading) {
|
|
93
|
+
return /* @__PURE__ */ jsx(Progress, {});
|
|
94
|
+
}
|
|
95
|
+
if (!canViewRca) {
|
|
96
|
+
return /* @__PURE__ */ jsx(
|
|
97
|
+
ForbiddenState,
|
|
98
|
+
{
|
|
99
|
+
message: deniedTooltip,
|
|
100
|
+
permissionName,
|
|
101
|
+
variant: "fullpage"
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return /* @__PURE__ */ jsx(RCAReportContent, {});
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export { RCAReport };
|
|
109
|
+
//# sourceMappingURL=RCAReport.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RCAReport.esm.js","sources":["../../../src/components/RCA/RCAReport.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { Box, Typography } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { Alert } from '@material-ui/lab';\nimport {\n useRcaPermission,\n ForbiddenState,\n} from '@openchoreo/backstage-plugin-react';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport {\n useRCAReport,\n useFilters,\n useGetEnvironmentsByNamespace,\n} from '../../hooks';\nimport { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';\nimport { RCAReportView } from './RCAReport/RCAReportView';\nimport { useApi, discoveryApiRef } from '@backstage/core-plugin-api';\nimport { rcaAgentApiRef } from '../../api/RCAAgentApi';\n\nconst RCAReportContent = () => {\n const { reportId } = useParams<{ reportId: string }>();\n const navigate = useNavigate();\n const { entity } = useEntity();\n const { filters } = useFilters();\n const rcaAgentApi = useApi(rcaAgentApiRef);\n const discoveryApi = useApi(discoveryApiRef);\n const namespace = entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE];\n const projectName = entity.metadata.name as string;\n\n // Get environments to ensure we have environment data\n const { environments } = useGetEnvironmentsByNamespace(\n namespace,\n projectName,\n );\n const environment = filters.environment || environments[0];\n\n const {\n report: detailedReport,\n loading,\n error,\n } = useRCAReport(reportId, environment?.name, entity);\n\n const [backendBaseUrl, setBackendBaseUrl] = useState<string | undefined>();\n useEffect(() => {\n discoveryApi\n .getBaseUrl('openchoreo-observability-backend')\n .then(setBackendBaseUrl)\n .catch(() => {});\n }, [discoveryApi]);\n\n const chatContext = {\n namespaceName: namespace || '',\n environmentName: environment?.name || '',\n projectName,\n rcaAgentApi,\n backendBaseUrl,\n };\n\n if (loading) {\n return <Progress />;\n }\n\n if (!reportId) {\n return (\n <Alert severity=\"error\">\n <Typography variant=\"body1\">Report ID is required</Typography>\n </Alert>\n );\n }\n\n if (error) {\n let errorMessage = error;\n let severity: 'info' | 'error' = 'error';\n\n if (error.includes('RCA service is not configured')) {\n errorMessage = 'AI RCA is not configured. Enable it to view RCA reports.';\n severity = 'info';\n } else if (error.includes('Observability is not enabled')) {\n errorMessage =\n 'Observability is not enabled for this environment. Enable observability and enable the AI RCA agent.';\n severity = 'info';\n }\n\n return (\n <Box mt={2} mb={2}>\n <Alert severity={severity}>\n <Typography variant=\"body1\">{errorMessage}</Typography>\n </Alert>\n </Box>\n );\n }\n\n if (!detailedReport) {\n return null;\n }\n\n const handleBack = () => {\n navigate(-1);\n };\n\n return (\n <RCAReportView\n report={detailedReport}\n reportId={reportId}\n onBack={handleBack}\n chatContext={chatContext}\n />\n );\n};\n\nexport const RCAReport = () => {\n const {\n canViewRca,\n loading: permissionLoading,\n deniedTooltip,\n permissionName,\n } = useRcaPermission();\n\n if (permissionLoading) {\n return <Progress />;\n }\n\n if (!canViewRca) {\n return (\n <ForbiddenState\n message={deniedTooltip}\n permissionName={permissionName}\n variant=\"fullpage\"\n />\n );\n }\n\n return <RCAReportContent />;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
import { Table } from '@backstage/core-components';
|
|
4
|
+
import { makeStyles, Box, Typography, Tooltip, IconButton } from '@material-ui/core';
|
|
5
|
+
import DescriptionOutlinedIcon from '@material-ui/icons/DescriptionOutlined';
|
|
6
|
+
import Refresh from '@material-ui/icons/Refresh';
|
|
7
|
+
import { StatusBadge } from '@openchoreo/backstage-design-system';
|
|
8
|
+
import { FormattedText } from './RCAReport/FormattedText.esm.js';
|
|
9
|
+
|
|
10
|
+
const useStyles = makeStyles({
|
|
11
|
+
truncateSingleLine: {
|
|
12
|
+
display: "block",
|
|
13
|
+
overflow: "hidden",
|
|
14
|
+
textOverflow: "ellipsis",
|
|
15
|
+
whiteSpace: "nowrap",
|
|
16
|
+
maxWidth: "100%"
|
|
17
|
+
},
|
|
18
|
+
truncateTwoLines: {
|
|
19
|
+
display: "-webkit-box",
|
|
20
|
+
WebkitLineClamp: 2,
|
|
21
|
+
WebkitBoxOrient: "vertical",
|
|
22
|
+
overflow: "hidden",
|
|
23
|
+
textOverflow: "ellipsis",
|
|
24
|
+
maxWidth: "100%"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const RCATable = ({ reports, loading = false }) => {
|
|
28
|
+
const classes = useStyles();
|
|
29
|
+
const mapStatusToStatusType = (status) => {
|
|
30
|
+
switch (status) {
|
|
31
|
+
case "completed":
|
|
32
|
+
return "success";
|
|
33
|
+
case "failed":
|
|
34
|
+
return "failed";
|
|
35
|
+
case "pending":
|
|
36
|
+
return "pending";
|
|
37
|
+
default:
|
|
38
|
+
return "unknown";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const formatTimestamp = (timestamp) => {
|
|
42
|
+
if (!timestamp) return "N/A";
|
|
43
|
+
try {
|
|
44
|
+
return new Date(timestamp).toLocaleString();
|
|
45
|
+
} catch {
|
|
46
|
+
return timestamp;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const columns = [
|
|
50
|
+
{
|
|
51
|
+
title: "Timestamp",
|
|
52
|
+
field: "timestamp",
|
|
53
|
+
width: "13%",
|
|
54
|
+
render: (row) => {
|
|
55
|
+
const report = row;
|
|
56
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", className: classes.truncateSingleLine, children: formatTimestamp(report.timestamp) });
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: "Summary",
|
|
61
|
+
field: "summary",
|
|
62
|
+
width: "66%",
|
|
63
|
+
highlight: true,
|
|
64
|
+
render: (row) => {
|
|
65
|
+
const report = row;
|
|
66
|
+
if (report.status === "pending") {
|
|
67
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Generating RCA report..." });
|
|
68
|
+
}
|
|
69
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", className: classes.truncateTwoLines, children: report.summary ? /* @__PURE__ */ jsx(
|
|
70
|
+
FormattedText,
|
|
71
|
+
{
|
|
72
|
+
text: report.summary,
|
|
73
|
+
disableLinks: true,
|
|
74
|
+
disableMarkdown: true
|
|
75
|
+
}
|
|
76
|
+
) : "No summary available" });
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
title: "Report Status",
|
|
81
|
+
field: "status",
|
|
82
|
+
width: "14%",
|
|
83
|
+
render: (row) => {
|
|
84
|
+
const report = row;
|
|
85
|
+
const status = mapStatusToStatusType(report.status);
|
|
86
|
+
const labelMap = {
|
|
87
|
+
success: "Available",
|
|
88
|
+
pending: "Pending",
|
|
89
|
+
failed: "Failed"
|
|
90
|
+
};
|
|
91
|
+
return /* @__PURE__ */ jsx(StatusBadge, { status, label: labelMap[status] || status });
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: "Actions",
|
|
96
|
+
field: "actions",
|
|
97
|
+
width: "7%",
|
|
98
|
+
render: (row) => {
|
|
99
|
+
const report = row;
|
|
100
|
+
const isCompleted = report.status === "completed";
|
|
101
|
+
const isFailed = report.status === "failed";
|
|
102
|
+
return /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "center", children: [
|
|
103
|
+
isCompleted && /* @__PURE__ */ jsx(Tooltip, { title: "View report", children: /* @__PURE__ */ jsx(
|
|
104
|
+
IconButton,
|
|
105
|
+
{
|
|
106
|
+
size: "small",
|
|
107
|
+
component: Link,
|
|
108
|
+
to: `./${report.reportId}`,
|
|
109
|
+
"aria-label": "view report",
|
|
110
|
+
children: /* @__PURE__ */ jsx(DescriptionOutlinedIcon, { fontSize: "small" })
|
|
111
|
+
}
|
|
112
|
+
) }),
|
|
113
|
+
isFailed && /* @__PURE__ */ jsx(Tooltip, { title: "Rerun report", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconButton, { size: "small", "aria-label": "rerun report", disabled: true, children: /* @__PURE__ */ jsx(Refresh, { fontSize: "small" }) }) }) })
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
];
|
|
118
|
+
return /* @__PURE__ */ jsx(
|
|
119
|
+
Table,
|
|
120
|
+
{
|
|
121
|
+
options: {
|
|
122
|
+
search: false,
|
|
123
|
+
toolbar: false,
|
|
124
|
+
paging: false,
|
|
125
|
+
sorting: true,
|
|
126
|
+
padding: "default"
|
|
127
|
+
},
|
|
128
|
+
columns,
|
|
129
|
+
data: reports,
|
|
130
|
+
isLoading: loading,
|
|
131
|
+
emptyContent: /* @__PURE__ */ jsxs(Box, { textAlign: "center", padding: 4, children: [
|
|
132
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "No RCA reports found" }),
|
|
133
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Try adjusting your filters or time range to see more reports." })
|
|
134
|
+
] })
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export { RCATable };
|
|
140
|
+
//# sourceMappingURL=RCATable.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RCATable.esm.js","sources":["../../../src/components/RCA/RCATable.tsx"],"sourcesContent":["import { Link as RouterLink } from 'react-router-dom';\nimport { Table, TableColumn } from '@backstage/core-components';\nimport {\n Box,\n Typography,\n IconButton,\n Tooltip,\n makeStyles,\n} from '@material-ui/core';\nimport DescriptionOutlinedIcon from '@material-ui/icons/DescriptionOutlined';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport { StatusBadge, StatusType } from '@openchoreo/backstage-design-system';\nimport { RCAReportSummary } from '../../types';\nimport { FormattedText } from './RCAReport/FormattedText';\n\nconst useStyles = makeStyles({\n truncateSingleLine: {\n display: 'block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n },\n truncateTwoLines: {\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: '100%',\n },\n});\n\ninterface RCATableProps {\n reports: RCAReportSummary[];\n loading?: boolean;\n}\n\nexport const RCATable = ({ reports, loading = false }: RCATableProps) => {\n const classes = useStyles();\n const mapStatusToStatusType = (\n status?: 'pending' | 'completed' | 'failed',\n ): StatusType => {\n switch (status) {\n case 'completed':\n return 'success';\n case 'failed':\n return 'failed';\n case 'pending':\n return 'pending';\n default:\n return 'unknown';\n }\n };\n\n const formatTimestamp = (timestamp?: string): string => {\n if (!timestamp) return 'N/A';\n try {\n return new Date(timestamp).toLocaleString();\n } catch {\n return timestamp;\n }\n };\n\n const columns: TableColumn[] = [\n {\n title: 'Timestamp',\n field: 'timestamp',\n width: '13%',\n render: (row: any) => {\n const report = row as RCAReportSummary;\n return (\n <Typography variant=\"body2\" className={classes.truncateSingleLine}>\n {formatTimestamp(report.timestamp)}\n </Typography>\n );\n },\n },\n {\n title: 'Summary',\n field: 'summary',\n width: '66%',\n highlight: true,\n render: (row: any) => {\n const report = row as RCAReportSummary;\n if (report.status === 'pending') {\n return (\n <Typography variant=\"body2\">Generating RCA report...</Typography>\n );\n }\n return (\n <Typography variant=\"body2\" className={classes.truncateTwoLines}>\n {report.summary ? (\n <FormattedText\n text={report.summary}\n disableLinks\n disableMarkdown\n />\n ) : (\n 'No summary available'\n )}\n </Typography>\n );\n },\n },\n {\n title: 'Report Status',\n field: 'status',\n width: '14%',\n render: (row: any) => {\n const report = row as RCAReportSummary;\n const status = mapStatusToStatusType(report.status);\n const labelMap: Record<string, string> = {\n success: 'Available',\n pending: 'Pending',\n failed: 'Failed',\n };\n return (\n <StatusBadge status={status} label={labelMap[status] || status} />\n );\n },\n },\n {\n title: 'Actions',\n field: 'actions',\n width: '7%',\n render: (row: any) => {\n const report = row as RCAReportSummary;\n const isCompleted = report.status === 'completed';\n const isFailed = report.status === 'failed';\n return (\n <Box display=\"flex\" alignItems=\"center\" justifyContent=\"center\">\n {isCompleted && (\n <Tooltip title=\"View report\">\n <IconButton\n size=\"small\"\n component={RouterLink}\n to={`./${report.reportId}`}\n aria-label=\"view report\"\n >\n <DescriptionOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n {isFailed && (\n <Tooltip title=\"Rerun report\">\n <span>\n <IconButton size=\"small\" aria-label=\"rerun report\" disabled>\n <RefreshIcon fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n )}\n </Box>\n );\n },\n },\n ];\n\n return (\n <Table\n options={{\n search: false,\n toolbar: false,\n paging: false,\n sorting: true,\n padding: 'default',\n }}\n columns={columns}\n data={reports}\n isLoading={loading}\n emptyContent={\n <Box textAlign=\"center\" padding={4}>\n <Typography variant=\"h6\" gutterBottom>\n No RCA reports found\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Try adjusting your filters or time range to see more reports.\n </Typography>\n </Box>\n }\n />\n );\n};\n"],"names":["RouterLink","RefreshIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { TableRow, TableCell, Chip, Box, Typography, Tooltip, IconButton, Collapse } from '@material-ui/core';
|
|
4
|
+
import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined';
|
|
5
|
+
import { LogEntryField } from './types.esm.js';
|
|
6
|
+
import { useLogEntryStyles } from './styles.esm.js';
|
|
7
|
+
|
|
8
|
+
const LogEntry = ({
|
|
9
|
+
log,
|
|
10
|
+
selectedFields,
|
|
11
|
+
environmentName,
|
|
12
|
+
projectName,
|
|
13
|
+
componentName,
|
|
14
|
+
getLogsSnapshot,
|
|
15
|
+
renderRowAction
|
|
16
|
+
}) => {
|
|
17
|
+
const classes = useLogEntryStyles();
|
|
18
|
+
const [expanded, setExpanded] = useState(false);
|
|
19
|
+
const [copySuccess, setCopySuccess] = useState(false);
|
|
20
|
+
const handleRowClick = () => {
|
|
21
|
+
setExpanded(!expanded);
|
|
22
|
+
};
|
|
23
|
+
const handleCopyLog = async (event) => {
|
|
24
|
+
event.stopPropagation();
|
|
25
|
+
if (!navigator.clipboard?.writeText) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
await navigator.clipboard.writeText(log.log ?? "");
|
|
30
|
+
setCopySuccess(true);
|
|
31
|
+
setTimeout(() => setCopySuccess(false), 2e3);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const getLogLevelChipClass = (level) => {
|
|
36
|
+
switch (level) {
|
|
37
|
+
case "ERROR":
|
|
38
|
+
return classes.errorChip;
|
|
39
|
+
case "WARN":
|
|
40
|
+
return classes.warnChip;
|
|
41
|
+
case "INFO":
|
|
42
|
+
return classes.infoChip;
|
|
43
|
+
case "DEBUG":
|
|
44
|
+
return classes.debugChip;
|
|
45
|
+
case "UNDEFINED":
|
|
46
|
+
return classes.undefinedChip;
|
|
47
|
+
default:
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const formatTimestamp = (timestamp) => {
|
|
52
|
+
return new Date(timestamp).toLocaleString();
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
TableRow,
|
|
57
|
+
{
|
|
58
|
+
className: `${classes.logRow} ${expanded ? classes.expandedRow : ""}`,
|
|
59
|
+
onClick: handleRowClick,
|
|
60
|
+
children: selectedFields.map((field) => {
|
|
61
|
+
if (field === LogEntryField.Timestamp) {
|
|
62
|
+
return /* @__PURE__ */ jsx(TableCell, { className: classes.monospaceCell, children: formatTimestamp(log.timestamp ?? "") }, field);
|
|
63
|
+
}
|
|
64
|
+
if (field === LogEntryField.LogLevel) {
|
|
65
|
+
return /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
66
|
+
Chip,
|
|
67
|
+
{
|
|
68
|
+
label: log.level,
|
|
69
|
+
size: "small",
|
|
70
|
+
className: `${classes.logLevelChip} ${getLogLevelChipClass(
|
|
71
|
+
log.level ?? ""
|
|
72
|
+
)}`
|
|
73
|
+
}
|
|
74
|
+
) }, field);
|
|
75
|
+
}
|
|
76
|
+
if (field === LogEntryField.ComponentName) {
|
|
77
|
+
return /* @__PURE__ */ jsx(TableCell, { className: classes.monospaceCell, children: log.metadata?.componentName ?? componentName ?? "" }, field);
|
|
78
|
+
}
|
|
79
|
+
return /* @__PURE__ */ jsx(TableCell, { className: classes.logCell, children: /* @__PURE__ */ jsxs(Box, { className: classes.logCellContent, children: [
|
|
80
|
+
/* @__PURE__ */ jsx(Box, { className: classes.logTextContainer, children: /* @__PURE__ */ jsx(
|
|
81
|
+
Typography,
|
|
82
|
+
{
|
|
83
|
+
className: `${classes.logMessage} ${expanded ? classes.expandedLogMessage : ""}`,
|
|
84
|
+
children: log.log
|
|
85
|
+
}
|
|
86
|
+
) }),
|
|
87
|
+
/* @__PURE__ */ jsxs(
|
|
88
|
+
Box,
|
|
89
|
+
{
|
|
90
|
+
className: `${classes.logActionColumn} ${classes.hoverActionButton}`,
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx(Tooltip, { title: copySuccess ? "Copied!" : "Copy log message", children: /* @__PURE__ */ jsx(
|
|
93
|
+
IconButton,
|
|
94
|
+
{
|
|
95
|
+
className: classes.copyButton,
|
|
96
|
+
onClick: handleCopyLog,
|
|
97
|
+
size: "small",
|
|
98
|
+
children: /* @__PURE__ */ jsx(FileCopyOutlined, { fontSize: "inherit" })
|
|
99
|
+
}
|
|
100
|
+
) }),
|
|
101
|
+
renderRowAction?.(log, getLogsSnapshot)
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
] }) }, field);
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
),
|
|
109
|
+
expanded && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
|
|
110
|
+
TableCell,
|
|
111
|
+
{
|
|
112
|
+
colSpan: selectedFields.length,
|
|
113
|
+
style: { paddingBottom: 0, paddingTop: 0 },
|
|
114
|
+
children: /* @__PURE__ */ jsx(Collapse, { in: expanded, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsxs(Box, { className: classes.expandedContent, children: [
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
Typography,
|
|
117
|
+
{
|
|
118
|
+
className: classes.expandedSectionTitle,
|
|
119
|
+
gutterBottom: true,
|
|
120
|
+
children: "Full Log Message"
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
/* @__PURE__ */ jsx(Box, { className: classes.fullLogMessage, children: log.log }),
|
|
124
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataSection, children: [
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
Typography,
|
|
127
|
+
{
|
|
128
|
+
className: `${classes.metadataTitle} ${classes.expandedSectionTitle}`,
|
|
129
|
+
children: "Metadata"
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ jsx(Box, { className: classes.metadataBox, children: /* @__PURE__ */ jsxs(Box, { className: classes.metadataGrid, children: [
|
|
133
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
134
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Environment Name:" }),
|
|
135
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.environmentName ?? environmentName })
|
|
136
|
+
] }),
|
|
137
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
138
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Environment UID:" }),
|
|
139
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.environmentUid })
|
|
140
|
+
] }),
|
|
141
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
142
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Project Name:" }),
|
|
143
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.projectName ?? projectName })
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
146
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Project UID:" }),
|
|
147
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.projectUid })
|
|
148
|
+
] }),
|
|
149
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
150
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Component Name:" }),
|
|
151
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.componentName ?? componentName })
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
154
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Component UID:" }),
|
|
155
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.componentUid })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
158
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Pod Name:" }),
|
|
159
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.podName })
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Pod Namespace:" }),
|
|
163
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.podNamespace })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
166
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Namespace:" }),
|
|
167
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.namespaceName })
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.metadataItem, children: [
|
|
170
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataKey, children: "Container:" }),
|
|
171
|
+
/* @__PURE__ */ jsx("span", { className: classes.metadataValue, children: log.metadata?.containerName })
|
|
172
|
+
] })
|
|
173
|
+
] }) })
|
|
174
|
+
] })
|
|
175
|
+
] }) })
|
|
176
|
+
}
|
|
177
|
+
) })
|
|
178
|
+
] });
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export { LogEntry };
|
|
182
|
+
//# sourceMappingURL=LogEntry.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogEntry.esm.js","sources":["../../../src/components/RuntimeLogs/LogEntry.tsx"],"sourcesContent":["import { FC, MouseEvent, ReactNode, useState } from 'react';\nimport {\n TableRow,\n TableCell,\n Typography,\n Chip,\n Box,\n Collapse,\n IconButton,\n Tooltip,\n} from '@material-ui/core';\nimport FileCopyOutlined from '@material-ui/icons/FileCopyOutlined';\nimport { LogEntry as LogEntryType, LogEntryField } from './types';\nimport { useLogEntryStyles } from './styles';\n\n/**\n * Render-prop slot for a per-row action button (assistant integration,\n * \"open in external tool\", etc.). The host app supplies this from\n * outside the plugin so observability stays free of cross-plugin\n * coupling. When omitted, no action button is rendered.\n */\nexport type RenderLogRowAction = (\n log: LogEntryType,\n getLogsSnapshot?: () => LogEntryType[],\n) => ReactNode;\n\ninterface LogEntryProps {\n log: LogEntryType;\n selectedFields: LogEntryField[];\n environmentName?: string;\n projectName?: string;\n componentName?: string;\n /**\n * Stable callback (typically backed by a ref) returning the table's\n * current log rows. Forwarded to ``renderRowAction`` so an assistant\n * integration can skip a first round-trip by prefetching what the\n * user is staring at. The closure-via-ref shape keeps row re-renders\n * cheap when new logs stream in — children see a stable reference.\n */\n getLogsSnapshot?: () => LogEntryType[];\n renderRowAction?: RenderLogRowAction;\n}\n\nexport const LogEntry: FC<LogEntryProps> = ({\n log,\n selectedFields,\n environmentName,\n projectName,\n componentName,\n getLogsSnapshot,\n renderRowAction,\n}) => {\n const classes = useLogEntryStyles();\n const [expanded, setExpanded] = useState(false);\n const [copySuccess, setCopySuccess] = useState(false);\n\n const handleRowClick = () => {\n setExpanded(!expanded);\n };\n\n const handleCopyLog = async (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n\n // Check if clipboard API is available\n if (!navigator.clipboard?.writeText) {\n // Clipboard API not supported or not in secure context\n return;\n }\n\n try {\n await navigator.clipboard.writeText(log.log ?? '');\n setCopySuccess(true);\n setTimeout(() => setCopySuccess(false), 2000);\n } catch (err) {\n // Silent fail - clipboard operation failed\n // Could be due to permissions or other issues\n }\n };\n\n const getLogLevelChipClass = (level: string) => {\n switch (level) {\n case 'ERROR':\n return classes.errorChip;\n case 'WARN':\n return classes.warnChip;\n case 'INFO':\n return classes.infoChip;\n case 'DEBUG':\n return classes.debugChip;\n case 'UNDEFINED':\n return classes.undefinedChip;\n default:\n return '';\n }\n };\n\n const formatTimestamp = (timestamp: string): string => {\n return new Date(timestamp).toLocaleString();\n };\n\n return (\n <>\n <TableRow\n className={`${classes.logRow} ${expanded ? classes.expandedRow : ''}`}\n onClick={handleRowClick}\n >\n {selectedFields.map(field => {\n if (field === LogEntryField.Timestamp) {\n return (\n <TableCell key={field} className={classes.monospaceCell}>\n {formatTimestamp(log.timestamp ?? '')}\n </TableCell>\n );\n }\n\n if (field === LogEntryField.LogLevel) {\n return (\n <TableCell key={field}>\n <Chip\n label={log.level}\n size=\"small\"\n className={`${classes.logLevelChip} ${getLogLevelChipClass(\n log.level ?? '',\n )}`}\n />\n </TableCell>\n );\n }\n\n if (field === LogEntryField.ComponentName) {\n return (\n <TableCell key={field} className={classes.monospaceCell}>\n {log.metadata?.componentName ?? componentName ?? ''}\n </TableCell>\n );\n }\n\n return (\n <TableCell key={field} className={classes.logCell}>\n <Box className={classes.logCellContent}>\n <Box className={classes.logTextContainer}>\n <Typography\n className={`${classes.logMessage} ${\n expanded ? classes.expandedLogMessage : ''\n }`}\n >\n {log.log}\n </Typography>\n </Box>\n <Box\n className={`${classes.logActionColumn} ${classes.hoverActionButton}`}\n >\n <Tooltip title={copySuccess ? 'Copied!' : 'Copy log message'}>\n <IconButton\n className={classes.copyButton}\n onClick={handleCopyLog}\n size=\"small\"\n >\n <FileCopyOutlined fontSize=\"inherit\" />\n </IconButton>\n </Tooltip>\n {/* Host-supplied per-row action (e.g. assistant\n \"Investigate\" button). Injected from outside this\n plugin so observability owns no cross-plugin\n dependency. Falsy renderRowAction → nothing\n mounts, identical to the slot being absent. */}\n {renderRowAction?.(log, getLogsSnapshot)}\n </Box>\n </Box>\n </TableCell>\n );\n })}\n </TableRow>\n\n {expanded && (\n <TableRow>\n <TableCell\n colSpan={selectedFields.length}\n style={{ paddingBottom: 0, paddingTop: 0 }}\n >\n <Collapse in={expanded} timeout=\"auto\" unmountOnExit>\n <Box className={classes.expandedContent}>\n <Typography\n className={classes.expandedSectionTitle}\n gutterBottom\n >\n Full Log Message\n </Typography>\n <Box className={classes.fullLogMessage}>{log.log}</Box>\n\n <Box className={classes.metadataSection}>\n <Typography\n className={`${classes.metadataTitle} ${classes.expandedSectionTitle}`}\n >\n Metadata\n </Typography>\n\n <Box className={classes.metadataBox}>\n <Box className={classes.metadataGrid}>\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Environment Name:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.environmentName ?? environmentName}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Environment UID:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.environmentUid}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Project Name:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.projectName ?? projectName}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Project UID:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.projectUid}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Component Name:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.componentName ?? componentName}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Component UID:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.componentUid}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>Pod Name:</span>\n <span className={classes.metadataValue}>\n {log.metadata?.podName}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>\n Pod Namespace:\n </span>\n <span className={classes.metadataValue}>\n {log.metadata?.podNamespace}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>Namespace:</span>\n <span className={classes.metadataValue}>\n {log.metadata?.namespaceName}\n </span>\n </Box>\n\n <Box className={classes.metadataItem}>\n <span className={classes.metadataKey}>Container:</span>\n <span className={classes.metadataValue}>\n {log.metadata?.containerName}\n </span>\n </Box>\n </Box>\n </Box>\n </Box>\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, Typography, Tooltip, Button } from '@material-ui/core';
|
|
3
|
+
import Refresh from '@material-ui/icons/Refresh';
|
|
4
|
+
import FiberManualRecord from '@material-ui/icons/FiberManualRecord';
|
|
5
|
+
import { useLogsActionsStyles } from './styles.esm.js';
|
|
6
|
+
import ArrowUpward from '@material-ui/icons/ArrowUpward';
|
|
7
|
+
import ArrowDownward from '@material-ui/icons/ArrowDownward';
|
|
8
|
+
|
|
9
|
+
const formatDate = (date) => {
|
|
10
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
11
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
12
|
+
const year = date.getFullYear();
|
|
13
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
14
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
15
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
16
|
+
return `${day}/${month}/${year}, ${hours}:${minutes}:${seconds}`;
|
|
17
|
+
};
|
|
18
|
+
const LogsActions = ({
|
|
19
|
+
totalCount,
|
|
20
|
+
disabled,
|
|
21
|
+
onRefresh,
|
|
22
|
+
filters,
|
|
23
|
+
onFiltersChange,
|
|
24
|
+
lastUpdated
|
|
25
|
+
}) => {
|
|
26
|
+
const classes = useLogsActionsStyles();
|
|
27
|
+
const effectiveSortOrder = filters.sortOrder || "desc";
|
|
28
|
+
const handleSortToggle = () => {
|
|
29
|
+
const newSortOrder = effectiveSortOrder === "desc" ? "asc" : "desc";
|
|
30
|
+
onFiltersChange({ sortOrder: newSortOrder });
|
|
31
|
+
};
|
|
32
|
+
const handleLiveToggle = () => {
|
|
33
|
+
onFiltersChange({ isLive: !filters.isLive });
|
|
34
|
+
};
|
|
35
|
+
const displayDate = lastUpdated || /* @__PURE__ */ new Date();
|
|
36
|
+
return /* @__PURE__ */ jsxs(Box, { className: classes.statsContainer, children: [
|
|
37
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
38
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
|
|
39
|
+
"Total logs: ",
|
|
40
|
+
totalCount
|
|
41
|
+
] }),
|
|
42
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
|
|
43
|
+
"Last updated at: ",
|
|
44
|
+
formatDate(displayDate)
|
|
45
|
+
] })
|
|
46
|
+
] }),
|
|
47
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.actionsContainer, children: [
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
Tooltip,
|
|
50
|
+
{
|
|
51
|
+
title: effectiveSortOrder === "desc" ? "Sort Logs by Newest First" : "Sort Logs by Oldest First",
|
|
52
|
+
children: /* @__PURE__ */ jsx(
|
|
53
|
+
Button,
|
|
54
|
+
{
|
|
55
|
+
variant: "outlined",
|
|
56
|
+
onClick: handleSortToggle,
|
|
57
|
+
disabled,
|
|
58
|
+
size: "small",
|
|
59
|
+
startIcon: effectiveSortOrder === "desc" ? /* @__PURE__ */ jsx(ArrowUpward, {}) : /* @__PURE__ */ jsx(ArrowDownward, {}),
|
|
60
|
+
children: effectiveSortOrder === "desc" ? "Newest First" : "Oldest First"
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
/* @__PURE__ */ jsx(
|
|
66
|
+
Tooltip,
|
|
67
|
+
{
|
|
68
|
+
title: filters.isLive ? "Stop Live Updates" : "Start Live Updates",
|
|
69
|
+
children: /* @__PURE__ */ jsx(
|
|
70
|
+
Button,
|
|
71
|
+
{
|
|
72
|
+
variant: "outlined",
|
|
73
|
+
onClick: handleLiveToggle,
|
|
74
|
+
disabled,
|
|
75
|
+
size: "small",
|
|
76
|
+
startIcon: /* @__PURE__ */ jsx(
|
|
77
|
+
FiberManualRecord,
|
|
78
|
+
{
|
|
79
|
+
style: {
|
|
80
|
+
color: filters.isLive ? "#4caf50" : "inherit",
|
|
81
|
+
fontSize: "12px"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
children: "Live"
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsx(Tooltip, { title: "Refresh", children: /* @__PURE__ */ jsx(
|
|
91
|
+
Button,
|
|
92
|
+
{
|
|
93
|
+
variant: "outlined",
|
|
94
|
+
startIcon: /* @__PURE__ */ jsx(Refresh, {}),
|
|
95
|
+
onClick: onRefresh,
|
|
96
|
+
disabled,
|
|
97
|
+
size: "small",
|
|
98
|
+
children: "Refresh"
|
|
99
|
+
}
|
|
100
|
+
) })
|
|
101
|
+
] })
|
|
102
|
+
] });
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export { LogsActions };
|
|
106
|
+
//# sourceMappingURL=LogsActions.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogsActions.esm.js","sources":["../../../src/components/RuntimeLogs/LogsActions.tsx"],"sourcesContent":["import { Box, Typography, Button, Tooltip } from '@material-ui/core';\nimport Refresh from '@material-ui/icons/Refresh';\nimport FiberManualRecord from '@material-ui/icons/FiberManualRecord';\nimport { useLogsActionsStyles } from './styles';\nimport { RuntimeLogsFilters } from './types';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport ArrowDownward from '@material-ui/icons/ArrowDownward';\n\ninterface LogsActionsProps {\n totalCount: number;\n disabled: boolean;\n onRefresh: () => void;\n filters: RuntimeLogsFilters;\n onFiltersChange: (filters: Partial<RuntimeLogsFilters>) => void;\n lastUpdated?: Date;\n}\n\nconst formatDate = (date: Date): string => {\n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n return `${day}/${month}/${year}, ${hours}:${minutes}:${seconds}`;\n};\n\nexport const LogsActions = ({\n totalCount,\n disabled,\n onRefresh,\n filters,\n onFiltersChange,\n lastUpdated,\n}: LogsActionsProps) => {\n const classes = useLogsActionsStyles();\n\n const effectiveSortOrder = filters.sortOrder || 'desc';\n const handleSortToggle = () => {\n const newSortOrder = effectiveSortOrder === 'desc' ? 'asc' : 'desc';\n onFiltersChange({ sortOrder: newSortOrder });\n };\n\n const handleLiveToggle = () => {\n onFiltersChange({ isLive: !filters.isLive });\n };\n\n const displayDate = lastUpdated || new Date();\n\n return (\n <Box className={classes.statsContainer}>\n <Box>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Total logs: {totalCount}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Last updated at: {formatDate(displayDate)}\n </Typography>\n </Box>\n <Box className={classes.actionsContainer}>\n <Tooltip\n title={\n effectiveSortOrder === 'desc'\n ? 'Sort Logs by Newest First'\n : 'Sort Logs by Oldest First'\n }\n >\n <Button\n variant=\"outlined\"\n onClick={handleSortToggle}\n disabled={disabled}\n size=\"small\"\n startIcon={\n effectiveSortOrder === 'desc' ? (\n <ArrowUpward />\n ) : (\n <ArrowDownward />\n )\n }\n >\n {effectiveSortOrder === 'desc' ? 'Newest First' : 'Oldest First'}\n </Button>\n </Tooltip>\n <Tooltip\n title={filters.isLive ? 'Stop Live Updates' : 'Start Live Updates'}\n >\n <Button\n variant=\"outlined\"\n onClick={handleLiveToggle}\n disabled={disabled}\n size=\"small\"\n startIcon={\n <FiberManualRecord\n style={{\n color: filters.isLive ? '#4caf50' : 'inherit',\n fontSize: '12px',\n }}\n />\n }\n >\n Live\n </Button>\n </Tooltip>\n <Tooltip title=\"Refresh\">\n <Button\n variant=\"outlined\"\n startIcon={<Refresh />}\n onClick={onRefresh}\n disabled={disabled}\n size=\"small\"\n >\n Refresh\n </Button>\n </Tooltip>\n </Box>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|