@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,272 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useEffect, useCallback, Children } from 'react';
|
|
3
|
+
import { Box, Typography, TextField, InputAdornment, IconButton } from '@material-ui/core';
|
|
4
|
+
import ChatOutlinedIcon from '@material-ui/icons/ChatOutlined';
|
|
5
|
+
import SendIcon from '@material-ui/icons/Send';
|
|
6
|
+
import StopIcon from '@material-ui/icons/Stop';
|
|
7
|
+
import DeleteOutlineIcon from '@material-ui/icons/DeleteOutline';
|
|
8
|
+
import { InfoCard } from '@backstage/core-components';
|
|
9
|
+
import ReactMarkdown from 'react-markdown';
|
|
10
|
+
import remarkGfm from 'remark-gfm';
|
|
11
|
+
import remend from 'remend';
|
|
12
|
+
import { useRCAReportStyles } from '../styles.esm.js';
|
|
13
|
+
import { FormattedText } from '../FormattedText.esm.js';
|
|
14
|
+
|
|
15
|
+
function processChildren(children) {
|
|
16
|
+
return Children.map(children, (child) => {
|
|
17
|
+
if (typeof child === "string") {
|
|
18
|
+
return /* @__PURE__ */ jsx(FormattedText, { text: child, disableMarkdown: true, disableLinks: true });
|
|
19
|
+
}
|
|
20
|
+
return child;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function escapeEntityTags(text) {
|
|
24
|
+
return text.replace(/<((?:comp|proj|env|ns):[^>]+)>/g, "{{$1}}");
|
|
25
|
+
}
|
|
26
|
+
const markdownComponents = {
|
|
27
|
+
p: ({ children }) => /* @__PURE__ */ jsx("p", { children: processChildren(children) }),
|
|
28
|
+
li: ({ children }) => /* @__PURE__ */ jsx("li", { children: processChildren(children) }),
|
|
29
|
+
td: ({ children }) => /* @__PURE__ */ jsx("td", { children: processChildren(children) }),
|
|
30
|
+
th: ({ children }) => /* @__PURE__ */ jsx("th", { children: processChildren(children) }),
|
|
31
|
+
strong: ({ children }) => /* @__PURE__ */ jsx("strong", { children: processChildren(children) }),
|
|
32
|
+
em: ({ children }) => /* @__PURE__ */ jsx("em", { children: processChildren(children) }),
|
|
33
|
+
code: ({ children }) => /* @__PURE__ */ jsx("code", { children: processChildren(children) }),
|
|
34
|
+
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { children: processChildren(children) }),
|
|
35
|
+
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { children: processChildren(children) }),
|
|
36
|
+
h3: ({ children }) => /* @__PURE__ */ jsx("h3", { children: processChildren(children) }),
|
|
37
|
+
h4: ({ children }) => /* @__PURE__ */ jsx("h4", { children: processChildren(children) }),
|
|
38
|
+
h5: ({ children }) => /* @__PURE__ */ jsx("h5", { children: processChildren(children) }),
|
|
39
|
+
h6: ({ children }) => /* @__PURE__ */ jsx("h6", { children: processChildren(children) })
|
|
40
|
+
};
|
|
41
|
+
const ChatPanelSection = ({ reportId, chatContext }) => {
|
|
42
|
+
const classes = useRCAReportStyles();
|
|
43
|
+
const [chatMessage, setChatMessage] = useState("");
|
|
44
|
+
const [isSending, setIsSending] = useState(false);
|
|
45
|
+
const [streamingContent, setStreamingContent] = useState("");
|
|
46
|
+
const [toolStatus, setToolStatus] = useState(null);
|
|
47
|
+
const [chatError, setChatError] = useState(null);
|
|
48
|
+
const abortControllerRef = useRef(null);
|
|
49
|
+
const chatMessagesRef = useRef(null);
|
|
50
|
+
const chatStorageKey = `rca-chat:${reportId}`;
|
|
51
|
+
const [messages, setMessages] = useState(() => {
|
|
52
|
+
try {
|
|
53
|
+
const stored = localStorage.getItem(chatStorageKey);
|
|
54
|
+
return stored ? JSON.parse(stored) : [];
|
|
55
|
+
} catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (messages.length > 0) {
|
|
61
|
+
localStorage.setItem(chatStorageKey, JSON.stringify(messages));
|
|
62
|
+
}
|
|
63
|
+
}, [messages, chatStorageKey]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (chatMessagesRef.current) {
|
|
66
|
+
chatMessagesRef.current.scrollTop = chatMessagesRef.current.scrollHeight;
|
|
67
|
+
}
|
|
68
|
+
}, [messages, streamingContent]);
|
|
69
|
+
const handleSendMessage = useCallback(async () => {
|
|
70
|
+
if (!chatMessage.trim() || isSending) return;
|
|
71
|
+
const trimmedMessage = chatMessage.trim();
|
|
72
|
+
const userMessage = { role: "user", content: trimmedMessage };
|
|
73
|
+
const updatedMessages = [...messages, userMessage];
|
|
74
|
+
const messagesToSend = [
|
|
75
|
+
...messages,
|
|
76
|
+
{
|
|
77
|
+
role: "user",
|
|
78
|
+
content: `[${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
79
|
+
${trimmedMessage}`
|
|
80
|
+
}
|
|
81
|
+
];
|
|
82
|
+
setMessages(updatedMessages);
|
|
83
|
+
setChatMessage("");
|
|
84
|
+
setIsSending(true);
|
|
85
|
+
setStreamingContent("");
|
|
86
|
+
setToolStatus(null);
|
|
87
|
+
setChatError(null);
|
|
88
|
+
const controller = new AbortController();
|
|
89
|
+
abortControllerRef.current = controller;
|
|
90
|
+
try {
|
|
91
|
+
await chatContext.rcaAgentApi.streamRCAChat(
|
|
92
|
+
{
|
|
93
|
+
reportId: reportId || "",
|
|
94
|
+
namespace: chatContext.namespaceName,
|
|
95
|
+
project: chatContext.projectName,
|
|
96
|
+
environment: chatContext.environmentName,
|
|
97
|
+
messages: messagesToSend
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
namespaceName: chatContext.namespaceName,
|
|
101
|
+
environmentName: chatContext.environmentName
|
|
102
|
+
},
|
|
103
|
+
(event) => {
|
|
104
|
+
switch (event.type) {
|
|
105
|
+
case "message_chunk":
|
|
106
|
+
setStreamingContent((prev) => prev + event.content);
|
|
107
|
+
setToolStatus(null);
|
|
108
|
+
break;
|
|
109
|
+
case "tool_call":
|
|
110
|
+
setToolStatus(event.activeForm || "Digging deeper...");
|
|
111
|
+
break;
|
|
112
|
+
case "done":
|
|
113
|
+
setMessages((prev) => [
|
|
114
|
+
...prev,
|
|
115
|
+
{ role: "assistant", content: event.message }
|
|
116
|
+
]);
|
|
117
|
+
setStreamingContent("");
|
|
118
|
+
setToolStatus(null);
|
|
119
|
+
break;
|
|
120
|
+
case "error":
|
|
121
|
+
setChatError(event.message);
|
|
122
|
+
setStreamingContent("");
|
|
123
|
+
setToolStatus(null);
|
|
124
|
+
break;
|
|
125
|
+
case "actions":
|
|
126
|
+
break;
|
|
127
|
+
default:
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
controller.signal
|
|
132
|
+
);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
135
|
+
if (streamingContent) {
|
|
136
|
+
setMessages((prev) => [
|
|
137
|
+
...prev,
|
|
138
|
+
{ role: "assistant", content: `${streamingContent} (cancelled)` }
|
|
139
|
+
]);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
setChatError(
|
|
143
|
+
err instanceof Error ? err.message : "Failed to send message"
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
} finally {
|
|
147
|
+
setIsSending(false);
|
|
148
|
+
setStreamingContent("");
|
|
149
|
+
setToolStatus(null);
|
|
150
|
+
abortControllerRef.current = null;
|
|
151
|
+
}
|
|
152
|
+
}, [
|
|
153
|
+
chatMessage,
|
|
154
|
+
isSending,
|
|
155
|
+
messages,
|
|
156
|
+
chatContext,
|
|
157
|
+
reportId,
|
|
158
|
+
streamingContent
|
|
159
|
+
]);
|
|
160
|
+
const handleCancelSend = useCallback(() => {
|
|
161
|
+
abortControllerRef.current?.abort();
|
|
162
|
+
}, []);
|
|
163
|
+
const handleClearChat = useCallback(() => {
|
|
164
|
+
abortControllerRef.current?.abort();
|
|
165
|
+
setChatMessage("");
|
|
166
|
+
setMessages([]);
|
|
167
|
+
setStreamingContent("");
|
|
168
|
+
setToolStatus(null);
|
|
169
|
+
setChatError(null);
|
|
170
|
+
setIsSending(false);
|
|
171
|
+
localStorage.removeItem(chatStorageKey);
|
|
172
|
+
}, [chatStorageKey]);
|
|
173
|
+
const handleKeyPress = useCallback(
|
|
174
|
+
(e) => {
|
|
175
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
176
|
+
e.preventDefault();
|
|
177
|
+
handleSendMessage();
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
[handleSendMessage]
|
|
181
|
+
);
|
|
182
|
+
return /* @__PURE__ */ jsx(Box, { className: classes.chatPanelWrapper, children: /* @__PURE__ */ jsx(
|
|
183
|
+
InfoCard,
|
|
184
|
+
{
|
|
185
|
+
title: /* @__PURE__ */ jsxs("span", { className: classes.cardTitle, children: [
|
|
186
|
+
/* @__PURE__ */ jsx(ChatOutlinedIcon, { className: classes.cardTitleIcon }),
|
|
187
|
+
"Chat with RCA Agent"
|
|
188
|
+
] }),
|
|
189
|
+
action: /* @__PURE__ */ jsx(Box, { display: "flex", alignItems: "center", height: "100%", children: /* @__PURE__ */ jsx(
|
|
190
|
+
IconButton,
|
|
191
|
+
{
|
|
192
|
+
size: "small",
|
|
193
|
+
onClick: handleClearChat,
|
|
194
|
+
title: "Clear chat",
|
|
195
|
+
style: { padding: 4 },
|
|
196
|
+
children: /* @__PURE__ */ jsx(DeleteOutlineIcon, { fontSize: "small" })
|
|
197
|
+
}
|
|
198
|
+
) }),
|
|
199
|
+
className: classes.chatPanel,
|
|
200
|
+
children: /* @__PURE__ */ jsxs(Box, { className: classes.chatContent, children: [
|
|
201
|
+
/* @__PURE__ */ jsxs("div", { className: classes.chatMessages, ref: chatMessagesRef, children: [
|
|
202
|
+
/* @__PURE__ */ jsx("div", { style: { marginTop: "auto" } }),
|
|
203
|
+
messages.length === 0 && !streamingContent && !toolStatus ? /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", align: "center", children: "Ask follow-up questions, search logs, or explore related issues" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
204
|
+
messages.map((msg, index) => /* @__PURE__ */ jsx(
|
|
205
|
+
Box,
|
|
206
|
+
{
|
|
207
|
+
className: msg.role === "user" ? classes.chatMessageUser : classes.chatMessageAssistant,
|
|
208
|
+
children: /* @__PURE__ */ jsx(Box, { className: classes.markdownContent, children: /* @__PURE__ */ jsx(
|
|
209
|
+
ReactMarkdown,
|
|
210
|
+
{
|
|
211
|
+
remarkPlugins: [remarkGfm],
|
|
212
|
+
components: markdownComponents,
|
|
213
|
+
children: escapeEntityTags(msg.content)
|
|
214
|
+
}
|
|
215
|
+
) })
|
|
216
|
+
},
|
|
217
|
+
index
|
|
218
|
+
)),
|
|
219
|
+
streamingContent && /* @__PURE__ */ jsx(Box, { className: classes.chatMessageAssistant, children: /* @__PURE__ */ jsx(Box, { className: classes.markdownContent, children: /* @__PURE__ */ jsx(
|
|
220
|
+
ReactMarkdown,
|
|
221
|
+
{
|
|
222
|
+
remarkPlugins: [remarkGfm],
|
|
223
|
+
components: markdownComponents,
|
|
224
|
+
children: escapeEntityTags(remend(streamingContent))
|
|
225
|
+
}
|
|
226
|
+
) }) })
|
|
227
|
+
] })
|
|
228
|
+
] }),
|
|
229
|
+
chatError && /* @__PURE__ */ jsx(Box, { className: classes.chatError, children: /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "error", children: chatError }) }),
|
|
230
|
+
isSending && !streamingContent && /* @__PURE__ */ jsx(Box, { className: classes.statusStrip, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: classes.statusText, children: toolStatus || "Thinking..." }) }),
|
|
231
|
+
/* @__PURE__ */ jsx(Box, { className: classes.chatInputArea, children: /* @__PURE__ */ jsx(
|
|
232
|
+
TextField,
|
|
233
|
+
{
|
|
234
|
+
fullWidth: true,
|
|
235
|
+
variant: "outlined",
|
|
236
|
+
size: "small",
|
|
237
|
+
placeholder: "Type your question...",
|
|
238
|
+
value: chatMessage,
|
|
239
|
+
onChange: (e) => setChatMessage(e.target.value),
|
|
240
|
+
onKeyPress: handleKeyPress,
|
|
241
|
+
disabled: isSending,
|
|
242
|
+
className: isSending && !streamingContent ? classes.inputPulsing : void 0,
|
|
243
|
+
InputProps: {
|
|
244
|
+
endAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: isSending ? /* @__PURE__ */ jsx(
|
|
245
|
+
IconButton,
|
|
246
|
+
{
|
|
247
|
+
size: "small",
|
|
248
|
+
onClick: handleCancelSend,
|
|
249
|
+
title: "Cancel",
|
|
250
|
+
className: isSending && !streamingContent ? classes.buttonPulsing : void 0,
|
|
251
|
+
children: /* @__PURE__ */ jsx(StopIcon, { fontSize: "small" })
|
|
252
|
+
}
|
|
253
|
+
) : /* @__PURE__ */ jsx(
|
|
254
|
+
IconButton,
|
|
255
|
+
{
|
|
256
|
+
size: "small",
|
|
257
|
+
color: "primary",
|
|
258
|
+
disabled: !chatMessage.trim(),
|
|
259
|
+
onClick: handleSendMessage,
|
|
260
|
+
children: /* @__PURE__ */ jsx(SendIcon, {})
|
|
261
|
+
}
|
|
262
|
+
) })
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
) })
|
|
266
|
+
] })
|
|
267
|
+
}
|
|
268
|
+
) });
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
export { ChatPanelSection };
|
|
272
|
+
//# sourceMappingURL=ChatPanelSection.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatPanelSection.esm.js","sources":["../../../../../src/components/RCA/RCAReport/sections/ChatPanelSection.tsx"],"sourcesContent":["import {\n Children,\n useState,\n useCallback,\n useRef,\n useEffect,\n type ReactNode,\n} from 'react';\nimport {\n Typography,\n Box,\n IconButton,\n TextField,\n InputAdornment,\n} from '@material-ui/core';\nimport ChatOutlinedIcon from '@material-ui/icons/ChatOutlined';\nimport SendIcon from '@material-ui/icons/Send';\nimport StopIcon from '@material-ui/icons/Stop';\nimport DeleteOutlineIcon from '@material-ui/icons/DeleteOutline';\nimport { InfoCard } from '@backstage/core-components';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remend from 'remend';\nimport { useRCAReportStyles } from '../styles';\nimport { FormattedText } from '../FormattedText';\nimport type {\n RCAAgentApi,\n ChatMessage,\n StreamEvent,\n} from '../../../../api/RCAAgentApi';\n\n// Process React children, replacing string nodes with FormattedText\n// Use disableMarkdown since the parent ReactMarkdown already parsed the markdown\nfunction processChildren(children: ReactNode): ReactNode {\n return Children.map(children, child => {\n if (typeof child === 'string') {\n return <FormattedText text={child} disableMarkdown disableLinks />;\n }\n return child;\n });\n}\n\n// Convert <tag:name> to {{tag:name}} so ReactMarkdown doesn't strip them as HTML\nfunction escapeEntityTags(text: string): string {\n return text.replace(/<((?:comp|proj|env|ns):[^>]+)>/g, '{{$1}}');\n}\n\n// Custom ReactMarkdown components that process entity tags and timestamps\nconst markdownComponents = {\n p: ({ children }: { children?: ReactNode }) => (\n <p>{processChildren(children)}</p>\n ),\n li: ({ children }: { children?: ReactNode }) => (\n <li>{processChildren(children)}</li>\n ),\n td: ({ children }: { children?: ReactNode }) => (\n <td>{processChildren(children)}</td>\n ),\n th: ({ children }: { children?: ReactNode }) => (\n <th>{processChildren(children)}</th>\n ),\n strong: ({ children }: { children?: ReactNode }) => (\n <strong>{processChildren(children)}</strong>\n ),\n em: ({ children }: { children?: ReactNode }) => (\n <em>{processChildren(children)}</em>\n ),\n code: ({ children }: { children?: ReactNode }) => (\n <code>{processChildren(children)}</code>\n ),\n h1: ({ children }: { children?: ReactNode }) => (\n <h1>{processChildren(children)}</h1>\n ),\n h2: ({ children }: { children?: ReactNode }) => (\n <h2>{processChildren(children)}</h2>\n ),\n h3: ({ children }: { children?: ReactNode }) => (\n <h3>{processChildren(children)}</h3>\n ),\n h4: ({ children }: { children?: ReactNode }) => (\n <h4>{processChildren(children)}</h4>\n ),\n h5: ({ children }: { children?: ReactNode }) => (\n <h5>{processChildren(children)}</h5>\n ),\n h6: ({ children }: { children?: ReactNode }) => (\n <h6>{processChildren(children)}</h6>\n ),\n};\n\ninterface ChatContext {\n namespaceName: string;\n environmentName: string;\n projectName: string;\n rcaAgentApi: RCAAgentApi;\n}\n\ninterface ChatPanelProps {\n reportId: string;\n chatContext: ChatContext;\n}\n\nexport const ChatPanelSection = ({ reportId, chatContext }: ChatPanelProps) => {\n const classes = useRCAReportStyles();\n const [chatMessage, setChatMessage] = useState('');\n const [isSending, setIsSending] = useState(false);\n const [streamingContent, setStreamingContent] = useState('');\n const [toolStatus, setToolStatus] = useState<string | null>(null);\n const [chatError, setChatError] = useState<string | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n const chatMessagesRef = useRef<HTMLDivElement>(null);\n\n // localStorage key for persisting chat messages\n const chatStorageKey = `rca-chat:${reportId}`;\n\n // Load messages from localStorage on mount\n const [messages, setMessages] = useState<ChatMessage[]>(() => {\n try {\n const stored = localStorage.getItem(chatStorageKey);\n return stored ? JSON.parse(stored) : [];\n } catch {\n return [];\n }\n });\n\n // Persist messages to localStorage when they change\n useEffect(() => {\n if (messages.length > 0) {\n localStorage.setItem(chatStorageKey, JSON.stringify(messages));\n }\n }, [messages, chatStorageKey]);\n\n // Auto-scroll chat pane to bottom when messages change or streaming content updates\n useEffect(() => {\n if (chatMessagesRef.current) {\n chatMessagesRef.current.scrollTop = chatMessagesRef.current.scrollHeight;\n }\n }, [messages, streamingContent]);\n\n const handleSendMessage = useCallback(async () => {\n if (!chatMessage.trim() || isSending) return;\n\n const trimmedMessage = chatMessage.trim();\n const userMessage: ChatMessage = { role: 'user', content: trimmedMessage };\n const updatedMessages = [...messages, userMessage];\n const messagesToSend = [\n ...messages,\n {\n role: 'user' as const,\n content: `[${new Date().toISOString()}] \\n${trimmedMessage}`,\n },\n ];\n\n setMessages(updatedMessages);\n setChatMessage('');\n setIsSending(true);\n setStreamingContent('');\n setToolStatus(null);\n setChatError(null);\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n try {\n await chatContext.rcaAgentApi.streamRCAChat(\n {\n reportId: reportId || '',\n namespace: chatContext.namespaceName,\n project: chatContext.projectName,\n environment: chatContext.environmentName,\n messages: messagesToSend,\n },\n {\n namespaceName: chatContext.namespaceName,\n environmentName: chatContext.environmentName,\n },\n (event: StreamEvent) => {\n switch (event.type) {\n case 'message_chunk':\n setStreamingContent(prev => prev + event.content);\n setToolStatus(null);\n break;\n case 'tool_call':\n setToolStatus(event.activeForm || 'Digging deeper...');\n break;\n case 'done':\n // Finalize the assistant message\n setMessages(prev => [\n ...prev,\n { role: 'assistant', content: event.message },\n ]);\n setStreamingContent('');\n setToolStatus(null);\n break;\n case 'error':\n setChatError(event.message);\n setStreamingContent('');\n setToolStatus(null);\n break;\n case 'actions':\n // TODO: Handle actions\n break;\n default:\n // Unknown event type, ignore\n break;\n }\n },\n controller.signal,\n );\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // User cancelled - add partial content as message if any\n if (streamingContent) {\n setMessages(prev => [\n ...prev,\n { role: 'assistant', content: `${streamingContent} (cancelled)` },\n ]);\n }\n } else {\n setChatError(\n err instanceof Error ? err.message : 'Failed to send message',\n );\n }\n } finally {\n setIsSending(false);\n setStreamingContent('');\n setToolStatus(null);\n abortControllerRef.current = null;\n }\n }, [\n chatMessage,\n isSending,\n messages,\n chatContext,\n reportId,\n streamingContent,\n ]);\n\n const handleCancelSend = useCallback(() => {\n abortControllerRef.current?.abort();\n }, []);\n\n const handleClearChat = useCallback(() => {\n // Abort any ongoing stream first\n abortControllerRef.current?.abort();\n setChatMessage('');\n setMessages([]);\n setStreamingContent('');\n setToolStatus(null);\n setChatError(null);\n setIsSending(false);\n // Remove from localStorage\n localStorage.removeItem(chatStorageKey);\n }, [chatStorageKey]);\n\n const handleKeyPress = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSendMessage();\n }\n },\n [handleSendMessage],\n );\n\n return (\n <Box className={classes.chatPanelWrapper}>\n <InfoCard\n title={\n <span className={classes.cardTitle}>\n <ChatOutlinedIcon className={classes.cardTitleIcon} />\n Chat with RCA Agent\n </span>\n }\n action={\n <Box display=\"flex\" alignItems=\"center\" height=\"100%\">\n <IconButton\n size=\"small\"\n onClick={handleClearChat}\n title=\"Clear chat\"\n style={{ padding: 4 }}\n >\n <DeleteOutlineIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n }\n className={classes.chatPanel}\n >\n <Box className={classes.chatContent}>\n <div className={classes.chatMessages} ref={chatMessagesRef}>\n {/* To push messages to bottom */}\n <div style={{ marginTop: 'auto' }} />\n {messages.length === 0 && !streamingContent && !toolStatus ? (\n <Typography variant=\"body2\" color=\"textSecondary\" align=\"center\">\n Ask follow-up questions, search logs, or explore related issues\n </Typography>\n ) : (\n <>\n {messages.map((msg, index) => (\n <Box\n key={index}\n className={\n msg.role === 'user'\n ? classes.chatMessageUser\n : classes.chatMessageAssistant\n }\n >\n <Box className={classes.markdownContent}>\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {escapeEntityTags(msg.content)}\n </ReactMarkdown>\n </Box>\n </Box>\n ))}\n {streamingContent && (\n <Box className={classes.chatMessageAssistant}>\n <Box className={classes.markdownContent}>\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {escapeEntityTags(remend(streamingContent))}\n </ReactMarkdown>\n </Box>\n </Box>\n )}\n </>\n )}\n </div>\n {chatError && (\n <Box className={classes.chatError}>\n <Typography variant=\"body2\" color=\"error\">\n {chatError}\n </Typography>\n </Box>\n )}\n {isSending && !streamingContent && (\n <Box className={classes.statusStrip}>\n <Typography variant=\"caption\" className={classes.statusText}>\n {toolStatus || 'Thinking...'}\n </Typography>\n </Box>\n )}\n <Box className={classes.chatInputArea}>\n <TextField\n fullWidth\n variant=\"outlined\"\n size=\"small\"\n placeholder=\"Type your question...\"\n value={chatMessage}\n onChange={e => setChatMessage(e.target.value)}\n onKeyPress={handleKeyPress}\n disabled={isSending}\n className={\n isSending && !streamingContent\n ? classes.inputPulsing\n : undefined\n }\n InputProps={{\n endAdornment: (\n <InputAdornment position=\"end\">\n {isSending ? (\n <IconButton\n size=\"small\"\n onClick={handleCancelSend}\n title=\"Cancel\"\n className={\n isSending && !streamingContent\n ? classes.buttonPulsing\n : undefined\n }\n >\n <StopIcon fontSize=\"small\" />\n </IconButton>\n ) : (\n <IconButton\n size=\"small\"\n color=\"primary\"\n disabled={!chatMessage.trim()}\n onClick={handleSendMessage}\n >\n <SendIcon />\n </IconButton>\n )}\n </InputAdornment>\n ),\n }}\n />\n </Box>\n </Box>\n </InfoCard>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { List, ListItem, ListItemText, Divider } from '@material-ui/core';
|
|
4
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
5
|
+
import { FormattedText } from '../FormattedText.esm.js';
|
|
6
|
+
|
|
7
|
+
const useStyles = makeStyles((theme) => ({
|
|
8
|
+
list: {
|
|
9
|
+
padding: 0,
|
|
10
|
+
margin: 0
|
|
11
|
+
},
|
|
12
|
+
listItem: {
|
|
13
|
+
padding: theme.spacing(1, 0)
|
|
14
|
+
},
|
|
15
|
+
primary: {
|
|
16
|
+
fontWeight: 500,
|
|
17
|
+
fontSize: theme.typography.body1.fontSize,
|
|
18
|
+
color: theme.palette.text.primary
|
|
19
|
+
},
|
|
20
|
+
secondary: {
|
|
21
|
+
fontSize: theme.typography.caption.fontSize
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
const ExcludedCausesSection = ({
|
|
25
|
+
excludedCauses
|
|
26
|
+
}) => {
|
|
27
|
+
const classes = useStyles();
|
|
28
|
+
if (!excludedCauses || excludedCauses.length === 0) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return /* @__PURE__ */ jsx(List, { className: classes.list, disablePadding: true, children: excludedCauses.map((cause, idx) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
32
|
+
/* @__PURE__ */ jsx(ListItem, { className: classes.listItem, disableGutters: true, children: /* @__PURE__ */ jsx(
|
|
33
|
+
ListItemText,
|
|
34
|
+
{
|
|
35
|
+
primary: /* @__PURE__ */ jsx(FormattedText, { text: cause.description || "", disableMarkdown: true }),
|
|
36
|
+
secondary: cause.rationale ? /* @__PURE__ */ jsx(FormattedText, { text: cause.rationale }) : void 0,
|
|
37
|
+
classes: {
|
|
38
|
+
primary: classes.primary,
|
|
39
|
+
secondary: classes.secondary
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
) }),
|
|
43
|
+
idx < excludedCauses.length - 1 && /* @__PURE__ */ jsx(Divider, { component: "li" })
|
|
44
|
+
] }, idx)) });
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { ExcludedCausesSection };
|
|
48
|
+
//# sourceMappingURL=ExcludedCausesSection.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExcludedCausesSection.esm.js","sources":["../../../../../src/components/RCA/RCAReport/sections/ExcludedCausesSection.tsx"],"sourcesContent":["import { Fragment } from 'react';\nimport { List, ListItem, ListItemText, Divider } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { FormattedText } from '../FormattedText';\nimport type { AIRCAAgentComponents } from '@openchoreo/backstage-plugin-common';\n\ntype ExcludedCause = AIRCAAgentComponents['schemas']['ExcludedCause'];\n\ninterface ExcludedCausesSectionProps {\n excludedCauses?: ExcludedCause[];\n}\n\nconst useStyles = makeStyles(theme => ({\n list: {\n padding: 0,\n margin: 0,\n },\n listItem: {\n padding: theme.spacing(1, 0),\n },\n primary: {\n fontWeight: 500,\n fontSize: theme.typography.body1.fontSize,\n color: theme.palette.text.primary,\n },\n secondary: {\n fontSize: theme.typography.caption.fontSize,\n },\n}));\n\nexport const ExcludedCausesSection = ({\n excludedCauses,\n}: ExcludedCausesSectionProps) => {\n const classes = useStyles();\n\n if (!excludedCauses || excludedCauses.length === 0) {\n return null;\n }\n\n return (\n <List className={classes.list} disablePadding>\n {excludedCauses.map((cause, idx) => (\n <Fragment key={idx}>\n <ListItem className={classes.listItem} disableGutters>\n <ListItemText\n primary={\n <FormattedText text={cause.description || ''} disableMarkdown />\n }\n secondary={\n cause.rationale ? (\n <FormattedText text={cause.rationale} />\n ) : undefined\n }\n classes={{\n primary: classes.primary,\n secondary: classes.secondary,\n }}\n />\n </ListItem>\n {idx < excludedCauses.length - 1 && <Divider component=\"li\" />}\n </Fragment>\n ))}\n </List>\n );\n};\n"],"names":[],"mappings":";;;;;;AAYA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,OAAA,EAAS,CAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,CAAC;AAAA,GAC7B;AAAA,EACA,OAAA,EAAS;AAAA,IACP,UAAA,EAAY,GAAA;AAAA,IACZ,QAAA,EAAU,KAAA,CAAM,UAAA,CAAW,KAAA,CAAM,QAAA;AAAA,IACjC,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAAA,GAC5B;AAAA,EACA,SAAA,EAAW;AAAA,IACT,QAAA,EAAU,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ;AAAA;AAEvC,CAAA,CAAE,CAAA;AAEK,MAAM,wBAAwB,CAAC;AAAA,EACpC;AACF,CAAA,KAAkC;AAChC,EAAA,MAAM,UAAU,SAAA,EAAU;AAE1B,EAAA,IAAI,CAAC,cAAA,IAAkB,cAAA,CAAe,MAAA,KAAW,CAAA,EAAG;AAClD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,cAAA,EAAc,IAAA,EAC1C,QAAA,EAAA,cAAA,CAAe,GAAA,CAAI,CAAC,KAAA,EAAO,GAAA,0BACzB,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAW,OAAA,CAAQ,QAAA,EAAU,gBAAc,IAAA,EACnD,QAAA,kBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,OAAA,sBACG,aAAA,EAAA,EAAc,IAAA,EAAM,MAAM,WAAA,IAAe,EAAA,EAAI,iBAAe,IAAA,EAAC,CAAA;AAAA,QAEhE,SAAA,EACE,MAAM,SAAA,mBACJ,GAAA,CAAC,iBAAc,IAAA,EAAM,KAAA,CAAM,WAAW,CAAA,GACpC,MAAA;AAAA,QAEN,OAAA,EAAS;AAAA,UACP,SAAS,OAAA,CAAQ,OAAA;AAAA,UACjB,WAAW,OAAA,CAAQ;AAAA;AACrB;AAAA,KACF,EACF,CAAA;AAAA,IACC,MAAM,cAAA,CAAe,MAAA,GAAS,qBAAK,GAAA,CAAC,OAAA,EAAA,EAAQ,WAAU,IAAA,EAAK;AAAA,GAAA,EAAA,EAjB/C,GAkBf,CACD,CAAA,EACH,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, Typography, Tooltip } from '@material-ui/core';
|
|
3
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
4
|
+
import { InfoCard } from '@backstage/core-components';
|
|
5
|
+
import ReportProblemOutlinedIcon from '@material-ui/icons/ReportProblemOutlined';
|
|
6
|
+
import { FormattedText } from '../FormattedText.esm.js';
|
|
7
|
+
import { useRCAReportStyles } from '../styles.esm.js';
|
|
8
|
+
|
|
9
|
+
const useAlertStyles = makeStyles((theme) => ({
|
|
10
|
+
sectionLabel: {
|
|
11
|
+
color: theme.palette.text.secondary,
|
|
12
|
+
fontSize: theme.typography.caption.fontSize,
|
|
13
|
+
textTransform: "uppercase",
|
|
14
|
+
letterSpacing: "0.5px",
|
|
15
|
+
fontWeight: 500,
|
|
16
|
+
marginBottom: theme.spacing(1)
|
|
17
|
+
},
|
|
18
|
+
propertyGrid: {
|
|
19
|
+
display: "flex",
|
|
20
|
+
flexDirection: "column",
|
|
21
|
+
gap: theme.spacing(1.5)
|
|
22
|
+
},
|
|
23
|
+
twoColumnGrid: {
|
|
24
|
+
display: "grid",
|
|
25
|
+
gridTemplateColumns: "1fr 1fr",
|
|
26
|
+
gap: theme.spacing(1.5)
|
|
27
|
+
},
|
|
28
|
+
propertyRow: {
|
|
29
|
+
display: "flex",
|
|
30
|
+
alignItems: "baseline",
|
|
31
|
+
gap: theme.spacing(2)
|
|
32
|
+
},
|
|
33
|
+
propertyKey: {
|
|
34
|
+
fontWeight: 500,
|
|
35
|
+
color: theme.palette.text.secondary,
|
|
36
|
+
fontSize: theme.typography.body2.fontSize,
|
|
37
|
+
minWidth: 100,
|
|
38
|
+
flexShrink: 0
|
|
39
|
+
},
|
|
40
|
+
propertyValue: {
|
|
41
|
+
color: theme.palette.text.primary,
|
|
42
|
+
fontSize: theme.typography.body2.fontSize,
|
|
43
|
+
wordBreak: "break-word"
|
|
44
|
+
},
|
|
45
|
+
propertyValueHighlight: {
|
|
46
|
+
fontWeight: 500,
|
|
47
|
+
color: theme.palette.warning.main
|
|
48
|
+
},
|
|
49
|
+
thresholdLabel: {
|
|
50
|
+
color: theme.palette.text.secondary
|
|
51
|
+
},
|
|
52
|
+
severityCritical: {
|
|
53
|
+
color: theme.palette.error.main,
|
|
54
|
+
fontWeight: 500,
|
|
55
|
+
textTransform: "uppercase"
|
|
56
|
+
},
|
|
57
|
+
severityWarning: {
|
|
58
|
+
color: theme.palette.warning.main,
|
|
59
|
+
fontWeight: 500,
|
|
60
|
+
textTransform: "uppercase"
|
|
61
|
+
},
|
|
62
|
+
severityNormal: {
|
|
63
|
+
color: theme.palette.success.main,
|
|
64
|
+
fontWeight: 500,
|
|
65
|
+
textTransform: "uppercase"
|
|
66
|
+
}
|
|
67
|
+
}));
|
|
68
|
+
const getSeverityClass = (severity, classes) => {
|
|
69
|
+
switch (severity) {
|
|
70
|
+
case "critical":
|
|
71
|
+
return classes.severityCritical;
|
|
72
|
+
case "warning":
|
|
73
|
+
return classes.severityWarning;
|
|
74
|
+
default:
|
|
75
|
+
return classes.severityNormal;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const formatMetricName = (metric) => {
|
|
79
|
+
return metric.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
80
|
+
};
|
|
81
|
+
const AlertDetails = ({
|
|
82
|
+
alertContext,
|
|
83
|
+
summary,
|
|
84
|
+
formatTimestamp,
|
|
85
|
+
classes
|
|
86
|
+
}) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
87
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.propertyGrid, children: [
|
|
88
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Alert" }),
|
|
90
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: alertContext.alert_name })
|
|
91
|
+
] }),
|
|
92
|
+
alertContext.alert_description && /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
93
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Description" }),
|
|
94
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: alertContext.alert_description })
|
|
95
|
+
] })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.twoColumnGrid, style: { marginTop: 12 }, children: [
|
|
98
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
99
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Triggered At" }),
|
|
100
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: formatTimestamp(alertContext.triggered_at) })
|
|
101
|
+
] }),
|
|
102
|
+
alertContext.source_type === "metric" && alertContext.source_metric && /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
103
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Metric" }),
|
|
104
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: formatMetricName(alertContext.source_metric) })
|
|
105
|
+
] })
|
|
106
|
+
] }),
|
|
107
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.twoColumnGrid, style: { marginTop: 12 }, children: [
|
|
108
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
109
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Component" }),
|
|
110
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: /* @__PURE__ */ jsx(FormattedText, { text: alertContext.component }) })
|
|
111
|
+
] }),
|
|
112
|
+
alertContext.severity && /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
113
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Severity" }),
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
Typography,
|
|
116
|
+
{
|
|
117
|
+
className: `${classes.propertyValue} ${getSeverityClass(
|
|
118
|
+
alertContext.severity,
|
|
119
|
+
classes
|
|
120
|
+
)}`,
|
|
121
|
+
children: alertContext.severity
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
] }),
|
|
125
|
+
alertContext.source_type && /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
126
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Source" }),
|
|
127
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: alertContext.source_type })
|
|
128
|
+
] }),
|
|
129
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
130
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Value" }),
|
|
131
|
+
/* @__PURE__ */ jsxs(Typography, { className: classes.propertyValue, children: [
|
|
132
|
+
/* @__PURE__ */ jsxs("span", { className: classes.propertyValueHighlight, children: [
|
|
133
|
+
alertContext.trigger_value,
|
|
134
|
+
alertContext.source_type === "metric" ? "%" : " occurrences"
|
|
135
|
+
] }),
|
|
136
|
+
alertContext.condition && /* @__PURE__ */ jsxs("span", { children: [
|
|
137
|
+
" ",
|
|
138
|
+
"(",
|
|
139
|
+
/* @__PURE__ */ jsx("span", { className: classes.thresholdLabel, children: "Threshold:" }),
|
|
140
|
+
" ",
|
|
141
|
+
alertContext.condition.operator,
|
|
142
|
+
" ",
|
|
143
|
+
alertContext.condition.threshold,
|
|
144
|
+
alertContext.source_type === "metric" ? "%" : "",
|
|
145
|
+
" in",
|
|
146
|
+
" ",
|
|
147
|
+
alertContext.condition.window,
|
|
148
|
+
")"
|
|
149
|
+
] })
|
|
150
|
+
] })
|
|
151
|
+
] })
|
|
152
|
+
] }),
|
|
153
|
+
alertContext.source_type === "log" && alertContext.source_query && /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, style: { marginTop: 12 }, children: [
|
|
154
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Log Pattern" }),
|
|
155
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: alertContext.source_query })
|
|
156
|
+
] }),
|
|
157
|
+
summary && /* @__PURE__ */ jsx(Box, { className: classes.propertyGrid, style: { marginTop: 12 }, children: /* @__PURE__ */ jsxs(Box, { className: classes.propertyRow, children: [
|
|
158
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyKey, children: "Summary" }),
|
|
159
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.propertyValue, children: /* @__PURE__ */ jsx(FormattedText, { text: summary }) })
|
|
160
|
+
] }) })
|
|
161
|
+
] });
|
|
162
|
+
const IncidentOverviewSection = ({
|
|
163
|
+
summary,
|
|
164
|
+
alertContext,
|
|
165
|
+
reportId,
|
|
166
|
+
reportTimestamp,
|
|
167
|
+
formatTimestamp
|
|
168
|
+
}) => {
|
|
169
|
+
const classes = useRCAReportStyles();
|
|
170
|
+
const alertClasses = useAlertStyles();
|
|
171
|
+
return /* @__PURE__ */ jsx(Box, { className: classes.infoCardSpacing, children: /* @__PURE__ */ jsx(
|
|
172
|
+
InfoCard,
|
|
173
|
+
{
|
|
174
|
+
title: /* @__PURE__ */ jsxs("span", { className: classes.cardTitle, children: [
|
|
175
|
+
/* @__PURE__ */ jsx(ReportProblemOutlinedIcon, { className: classes.cardTitleIcon }),
|
|
176
|
+
"Incident Overview"
|
|
177
|
+
] }),
|
|
178
|
+
children: alertContext ? /* @__PURE__ */ jsx(
|
|
179
|
+
AlertDetails,
|
|
180
|
+
{
|
|
181
|
+
alertContext,
|
|
182
|
+
summary,
|
|
183
|
+
formatTimestamp,
|
|
184
|
+
classes: alertClasses
|
|
185
|
+
}
|
|
186
|
+
) : /* @__PURE__ */ jsxs(Box, { className: alertClasses.propertyGrid, children: [
|
|
187
|
+
/* @__PURE__ */ jsxs(Box, { className: alertClasses.propertyRow, children: [
|
|
188
|
+
/* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyKey, children: "Report ID" }),
|
|
189
|
+
/* @__PURE__ */ jsx(Tooltip, { title: reportId, placement: "top", children: /* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyValue, children: reportId }) })
|
|
190
|
+
] }),
|
|
191
|
+
reportTimestamp && /* @__PURE__ */ jsxs(Box, { className: alertClasses.propertyRow, children: [
|
|
192
|
+
/* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyKey, children: "Generated At" }),
|
|
193
|
+
/* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyValue, children: formatTimestamp(reportTimestamp) })
|
|
194
|
+
] }),
|
|
195
|
+
summary && /* @__PURE__ */ jsxs(Box, { className: alertClasses.propertyRow, children: [
|
|
196
|
+
/* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyKey, children: "Summary" }),
|
|
197
|
+
/* @__PURE__ */ jsx(Typography, { className: alertClasses.propertyValue, children: /* @__PURE__ */ jsx(FormattedText, { text: summary }) })
|
|
198
|
+
] })
|
|
199
|
+
] })
|
|
200
|
+
}
|
|
201
|
+
) });
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export { IncidentOverviewSection };
|
|
205
|
+
//# sourceMappingURL=IncidentOverviewSection.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IncidentOverviewSection.esm.js","sources":["../../../../../src/components/RCA/RCAReport/sections/IncidentOverviewSection.tsx"],"sourcesContent":["import { Box, Typography, Tooltip } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { InfoCard } from '@backstage/core-components';\nimport ReportProblemOutlinedIcon from '@material-ui/icons/ReportProblemOutlined';\nimport { FormattedText } from '../FormattedText';\nimport { useRCAReportStyles } from '../styles';\nimport type { AIRCAAgentComponents } from '@openchoreo/backstage-plugin-common';\n\ntype ReportAlertContext = AIRCAAgentComponents['schemas']['ReportAlertContext'];\n\ninterface IncidentOverviewSectionProps {\n summary: string;\n alertContext?: ReportAlertContext;\n reportId: string;\n reportTimestamp?: string;\n formatTimestamp: (timestamp?: string) => string;\n}\n\n// Styles for alert details subsection\nconst useAlertStyles = makeStyles(theme => ({\n sectionLabel: {\n color: theme.palette.text.secondary,\n fontSize: theme.typography.caption.fontSize,\n textTransform: 'uppercase',\n letterSpacing: '0.5px',\n fontWeight: 500,\n marginBottom: theme.spacing(1),\n },\n propertyGrid: {\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1.5),\n },\n twoColumnGrid: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: theme.spacing(1.5),\n },\n propertyRow: {\n display: 'flex',\n alignItems: 'baseline',\n gap: theme.spacing(2),\n },\n propertyKey: {\n fontWeight: 500,\n color: theme.palette.text.secondary,\n fontSize: theme.typography.body2.fontSize,\n minWidth: 100,\n flexShrink: 0,\n },\n propertyValue: {\n color: theme.palette.text.primary,\n fontSize: theme.typography.body2.fontSize,\n wordBreak: 'break-word',\n },\n propertyValueHighlight: {\n fontWeight: 500,\n color: theme.palette.warning.main,\n },\n thresholdLabel: {\n color: theme.palette.text.secondary,\n },\n severityCritical: {\n color: theme.palette.error.main,\n fontWeight: 500,\n textTransform: 'uppercase',\n },\n severityWarning: {\n color: theme.palette.warning.main,\n fontWeight: 500,\n textTransform: 'uppercase',\n },\n severityNormal: {\n color: theme.palette.success.main,\n fontWeight: 500,\n textTransform: 'uppercase',\n },\n}));\n\nconst getSeverityClass = (\n severity: string,\n classes: ReturnType<typeof useAlertStyles>,\n): string => {\n switch (severity) {\n case 'critical':\n return classes.severityCritical;\n case 'warning':\n return classes.severityWarning;\n default:\n return classes.severityNormal;\n }\n};\n\nconst formatMetricName = (metric: string): string => {\n return metric\n .split('_')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n};\n\n// Alert Details subsection component\nconst AlertDetails = ({\n alertContext,\n summary,\n formatTimestamp,\n classes,\n}: {\n alertContext: ReportAlertContext;\n summary: string;\n formatTimestamp: (timestamp?: string) => string;\n classes: ReturnType<typeof useAlertStyles>;\n}) => (\n <>\n {/* Full-width fields */}\n <Box className={classes.propertyGrid}>\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Alert</Typography>\n <Typography className={classes.propertyValue}>\n {alertContext.alert_name}\n </Typography>\n </Box>\n\n {alertContext.alert_description && (\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Description</Typography>\n <Typography className={classes.propertyValue}>\n {alertContext.alert_description}\n </Typography>\n </Box>\n )}\n </Box>\n\n {/* Two-column grid for Triggered At and Metric */}\n <Box className={classes.twoColumnGrid} style={{ marginTop: 12 }}>\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Triggered At</Typography>\n <Typography className={classes.propertyValue}>\n {formatTimestamp(alertContext.triggered_at)}\n </Typography>\n </Box>\n\n {alertContext.source_type === 'metric' && alertContext.source_metric && (\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Metric</Typography>\n <Typography className={classes.propertyValue}>\n {formatMetricName(alertContext.source_metric)}\n </Typography>\n </Box>\n )}\n </Box>\n\n {/* Two-column grid for other shorter fields */}\n <Box className={classes.twoColumnGrid} style={{ marginTop: 12 }}>\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Component</Typography>\n <Typography className={classes.propertyValue}>\n <FormattedText text={alertContext.component} />\n </Typography>\n </Box>\n\n {alertContext.severity && (\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Severity</Typography>\n <Typography\n className={`${classes.propertyValue} ${getSeverityClass(\n alertContext.severity,\n classes,\n )}`}\n >\n {alertContext.severity}\n </Typography>\n </Box>\n )}\n\n {alertContext.source_type && (\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Source</Typography>\n <Typography className={classes.propertyValue}>\n {alertContext.source_type}\n </Typography>\n </Box>\n )}\n\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Value</Typography>\n <Typography className={classes.propertyValue}>\n <span className={classes.propertyValueHighlight}>\n {alertContext.trigger_value}\n {alertContext.source_type === 'metric' ? '%' : ' occurrences'}\n </span>\n {alertContext.condition && (\n <span>\n {' '}\n (<span className={classes.thresholdLabel}>Threshold:</span>{' '}\n {alertContext.condition.operator}{' '}\n {alertContext.condition.threshold}\n {alertContext.source_type === 'metric' ? '%' : ''} in{' '}\n {alertContext.condition.window})\n </span>\n )}\n </Typography>\n </Box>\n </Box>\n\n {/* Log alert: show query pattern */}\n {alertContext.source_type === 'log' && alertContext.source_query && (\n <Box className={classes.propertyRow} style={{ marginTop: 12 }}>\n <Typography className={classes.propertyKey}>Log Pattern</Typography>\n <Typography className={classes.propertyValue}>\n {alertContext.source_query}\n </Typography>\n </Box>\n )}\n\n {/* Summary */}\n {summary && (\n <Box className={classes.propertyGrid} style={{ marginTop: 12 }}>\n <Box className={classes.propertyRow}>\n <Typography className={classes.propertyKey}>Summary</Typography>\n <Typography className={classes.propertyValue}>\n <FormattedText text={summary} />\n </Typography>\n </Box>\n </Box>\n )}\n </>\n);\n\nexport const IncidentOverviewSection = ({\n summary,\n alertContext,\n reportId,\n reportTimestamp,\n formatTimestamp,\n}: IncidentOverviewSectionProps) => {\n const classes = useRCAReportStyles();\n const alertClasses = useAlertStyles();\n\n return (\n <Box className={classes.infoCardSpacing}>\n <InfoCard\n title={\n <span className={classes.cardTitle}>\n <ReportProblemOutlinedIcon className={classes.cardTitleIcon} />\n Incident Overview\n </span>\n }\n >\n {alertContext ? (\n <AlertDetails\n alertContext={alertContext}\n summary={summary}\n formatTimestamp={formatTimestamp}\n classes={alertClasses}\n />\n ) : (\n <Box className={alertClasses.propertyGrid}>\n <Box className={alertClasses.propertyRow}>\n <Typography className={alertClasses.propertyKey}>\n Report ID\n </Typography>\n <Tooltip title={reportId} placement=\"top\">\n <Typography className={alertClasses.propertyValue}>\n {reportId}\n </Typography>\n </Tooltip>\n </Box>\n {reportTimestamp && (\n <Box className={alertClasses.propertyRow}>\n <Typography className={alertClasses.propertyKey}>\n Generated At\n </Typography>\n <Typography className={alertClasses.propertyValue}>\n {formatTimestamp(reportTimestamp)}\n </Typography>\n </Box>\n )}\n {summary && (\n <Box className={alertClasses.propertyRow}>\n <Typography className={alertClasses.propertyKey}>\n Summary\n </Typography>\n <Typography className={alertClasses.propertyValue}>\n <FormattedText text={summary} />\n </Typography>\n </Box>\n )}\n </Box>\n )}\n </InfoCard>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|