@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.
Files changed (196) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +22 -0
  3. package/dist/api/FinOpsAgentApi.esm.js +43 -0
  4. package/dist/api/FinOpsAgentApi.esm.js.map +1 -0
  5. package/dist/api/ObservabilityApi.esm.js +568 -0
  6. package/dist/api/ObservabilityApi.esm.js.map +1 -0
  7. package/dist/api/ObserverUrlCache.esm.js +59 -0
  8. package/dist/api/ObserverUrlCache.esm.js.map +1 -0
  9. package/dist/api/RCAAgentApi.esm.js +104 -0
  10. package/dist/api/RCAAgentApi.esm.js.map +1 -0
  11. package/dist/components/Alerts/AlertRow.esm.js +203 -0
  12. package/dist/components/Alerts/AlertRow.esm.js.map +1 -0
  13. package/dist/components/Alerts/AlertsActions.esm.js +77 -0
  14. package/dist/components/Alerts/AlertsActions.esm.js.map +1 -0
  15. package/dist/components/Alerts/AlertsFilter.esm.js +95 -0
  16. package/dist/components/Alerts/AlertsFilter.esm.js.map +1 -0
  17. package/dist/components/Alerts/AlertsTable.esm.js +63 -0
  18. package/dist/components/Alerts/AlertsTable.esm.js.map +1 -0
  19. package/dist/components/Alerts/ObservabilityAlertsPage.esm.js +251 -0
  20. package/dist/components/Alerts/ObservabilityAlertsPage.esm.js.map +1 -0
  21. package/dist/components/Alerts/types.esm.js +4 -0
  22. package/dist/components/Alerts/types.esm.js.map +1 -0
  23. package/dist/components/CostAnalysis/CostAnalysisPage.esm.js +141 -0
  24. package/dist/components/CostAnalysis/CostAnalysisPage.esm.js.map +1 -0
  25. package/dist/components/CostAnalysis/CostAnalysisReport.esm.js +128 -0
  26. package/dist/components/CostAnalysis/CostAnalysisReport.esm.js.map +1 -0
  27. package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js +517 -0
  28. package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js.map +1 -0
  29. package/dist/components/CostAnalysis/CostAnalysisTable.esm.js +149 -0
  30. package/dist/components/CostAnalysis/CostAnalysisTable.esm.js.map +1 -0
  31. package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js +112 -0
  32. package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js.map +1 -0
  33. package/dist/components/CostAnalysis/index.esm.js +2 -0
  34. package/dist/components/CostAnalysis/index.esm.js.map +1 -0
  35. package/dist/components/Incidents/IncidentRow.esm.js +258 -0
  36. package/dist/components/Incidents/IncidentRow.esm.js.map +1 -0
  37. package/dist/components/Incidents/IncidentsActions.esm.js +77 -0
  38. package/dist/components/Incidents/IncidentsActions.esm.js.map +1 -0
  39. package/dist/components/Incidents/IncidentsFilter.esm.js +144 -0
  40. package/dist/components/Incidents/IncidentsFilter.esm.js.map +1 -0
  41. package/dist/components/Incidents/IncidentsTable.esm.js +68 -0
  42. package/dist/components/Incidents/IncidentsTable.esm.js.map +1 -0
  43. package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js +283 -0
  44. package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js.map +1 -0
  45. package/dist/components/Incidents/types.esm.js +8 -0
  46. package/dist/components/Incidents/types.esm.js.map +1 -0
  47. package/dist/components/Metrics/ChartTooltip.esm.js +53 -0
  48. package/dist/components/Metrics/ChartTooltip.esm.js.map +1 -0
  49. package/dist/components/Metrics/HTTPMetricsSection.esm.js +109 -0
  50. package/dist/components/Metrics/HTTPMetricsSection.esm.js.map +1 -0
  51. package/dist/components/Metrics/MetricGraphByComponent.esm.js +99 -0
  52. package/dist/components/Metrics/MetricGraphByComponent.esm.js.map +1 -0
  53. package/dist/components/Metrics/MetricsActions.esm.js +30 -0
  54. package/dist/components/Metrics/MetricsActions.esm.js.map +1 -0
  55. package/dist/components/Metrics/MetricsFilters.esm.js +49 -0
  56. package/dist/components/Metrics/MetricsFilters.esm.js.map +1 -0
  57. package/dist/components/Metrics/ObservabilityMetricsPage.esm.js +196 -0
  58. package/dist/components/Metrics/ObservabilityMetricsPage.esm.js.map +1 -0
  59. package/dist/components/Metrics/styles.esm.js +55 -0
  60. package/dist/components/Metrics/styles.esm.js.map +1 -0
  61. package/dist/components/Metrics/utils.esm.js +221 -0
  62. package/dist/components/Metrics/utils.esm.js.map +1 -0
  63. package/dist/components/RCA/RCAActions.esm.js +42 -0
  64. package/dist/components/RCA/RCAActions.esm.js.map +1 -0
  65. package/dist/components/RCA/RCAFilters.esm.js +100 -0
  66. package/dist/components/RCA/RCAFilters.esm.js.map +1 -0
  67. package/dist/components/RCA/RCAPage.esm.js +137 -0
  68. package/dist/components/RCA/RCAPage.esm.js.map +1 -0
  69. package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js +9 -0
  70. package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js.map +1 -0
  71. package/dist/components/RCA/RCAReport/FormattedText.esm.js +94 -0
  72. package/dist/components/RCA/RCAReport/FormattedText.esm.js.map +1 -0
  73. package/dist/components/RCA/RCAReport/RCAReportView.esm.js +308 -0
  74. package/dist/components/RCA/RCAReport/RCAReportView.esm.js.map +1 -0
  75. package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js +113 -0
  76. package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js.map +1 -0
  77. package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js +272 -0
  78. package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js.map +1 -0
  79. package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js +48 -0
  80. package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js.map +1 -0
  81. package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js +205 -0
  82. package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js.map +1 -0
  83. package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js +121 -0
  84. package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js.map +1 -0
  85. package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js +593 -0
  86. package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js.map +1 -0
  87. package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js +35 -0
  88. package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js.map +1 -0
  89. package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js +54 -0
  90. package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js.map +1 -0
  91. package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js +526 -0
  92. package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js.map +1 -0
  93. package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js +70 -0
  94. package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js.map +1 -0
  95. package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js +54 -0
  96. package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js.map +1 -0
  97. package/dist/components/RCA/RCAReport/styles.esm.js +467 -0
  98. package/dist/components/RCA/RCAReport/styles.esm.js.map +1 -0
  99. package/dist/components/RCA/RCAReport.esm.js +109 -0
  100. package/dist/components/RCA/RCAReport.esm.js.map +1 -0
  101. package/dist/components/RCA/RCATable.esm.js +140 -0
  102. package/dist/components/RCA/RCATable.esm.js.map +1 -0
  103. package/dist/components/RuntimeLogs/LogEntry.esm.js +182 -0
  104. package/dist/components/RuntimeLogs/LogEntry.esm.js.map +1 -0
  105. package/dist/components/RuntimeLogs/LogsActions.esm.js +106 -0
  106. package/dist/components/RuntimeLogs/LogsActions.esm.js.map +1 -0
  107. package/dist/components/RuntimeLogs/LogsFilter.esm.js +200 -0
  108. package/dist/components/RuntimeLogs/LogsFilter.esm.js.map +1 -0
  109. package/dist/components/RuntimeLogs/LogsTable.esm.js +91 -0
  110. package/dist/components/RuntimeLogs/LogsTable.esm.js.map +1 -0
  111. package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js +220 -0
  112. package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js.map +1 -0
  113. package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js +222 -0
  114. package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js.map +1 -0
  115. package/dist/components/RuntimeLogs/styles.esm.js +256 -0
  116. package/dist/components/RuntimeLogs/styles.esm.js.map +1 -0
  117. package/dist/components/RuntimeLogs/types.esm.js +16 -0
  118. package/dist/components/RuntimeLogs/types.esm.js.map +1 -0
  119. package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js +280 -0
  120. package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js.map +1 -0
  121. package/dist/components/Traces/ObservabilityTracesPage.esm.js +165 -0
  122. package/dist/components/Traces/ObservabilityTracesPage.esm.js.map +1 -0
  123. package/dist/components/Traces/TracesActions.esm.js +37 -0
  124. package/dist/components/Traces/TracesActions.esm.js.map +1 -0
  125. package/dist/components/Traces/TracesFilters.esm.js +121 -0
  126. package/dist/components/Traces/TracesFilters.esm.js.map +1 -0
  127. package/dist/components/Traces/TracesTable.esm.js +137 -0
  128. package/dist/components/Traces/TracesTable.esm.js.map +1 -0
  129. package/dist/components/Traces/WaterfallView.esm.js +567 -0
  130. package/dist/components/Traces/WaterfallView.esm.js.map +1 -0
  131. package/dist/components/Traces/styles.esm.js +198 -0
  132. package/dist/components/Traces/styles.esm.js.map +1 -0
  133. package/dist/components/Traces/utils.esm.js +19 -0
  134. package/dist/components/Traces/utils.esm.js.map +1 -0
  135. package/dist/hooks/useAutoSelectFirstEnvironment.esm.js +25 -0
  136. package/dist/hooks/useAutoSelectFirstEnvironment.esm.js.map +1 -0
  137. package/dist/hooks/useComponentAlerts.esm.js +80 -0
  138. package/dist/hooks/useComponentAlerts.esm.js.map +1 -0
  139. package/dist/hooks/useDataPlaneNetPolProvider.esm.js +55 -0
  140. package/dist/hooks/useDataPlaneNetPolProvider.esm.js.map +1 -0
  141. package/dist/hooks/useDebouncedSearch.esm.js +24 -0
  142. package/dist/hooks/useDebouncedSearch.esm.js.map +1 -0
  143. package/dist/hooks/useFilters.esm.js +29 -0
  144. package/dist/hooks/useFilters.esm.js.map +1 -0
  145. package/dist/hooks/useFinOpsReport.esm.js +66 -0
  146. package/dist/hooks/useFinOpsReport.esm.js.map +1 -0
  147. package/dist/hooks/useFinOpsReports.esm.js +70 -0
  148. package/dist/hooks/useFinOpsReports.esm.js.map +1 -0
  149. package/dist/hooks/useGetComponentsByProject.esm.js +57 -0
  150. package/dist/hooks/useGetComponentsByProject.esm.js.map +1 -0
  151. package/dist/hooks/useGetEnvironmentsByNamespace.esm.js +53 -0
  152. package/dist/hooks/useGetEnvironmentsByNamespace.esm.js.map +1 -0
  153. package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js +40 -0
  154. package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js.map +1 -0
  155. package/dist/hooks/useMetrics.esm.js +107 -0
  156. package/dist/hooks/useMetrics.esm.js.map +1 -0
  157. package/dist/hooks/useProjectIncidents.esm.js +111 -0
  158. package/dist/hooks/useProjectIncidents.esm.js.map +1 -0
  159. package/dist/hooks/useProjectRuntimeLogs.esm.js +185 -0
  160. package/dist/hooks/useProjectRuntimeLogs.esm.js.map +1 -0
  161. package/dist/hooks/useRCAReportByAlert.esm.js +54 -0
  162. package/dist/hooks/useRCAReportByAlert.esm.js.map +1 -0
  163. package/dist/hooks/useRCAReports.esm.js +75 -0
  164. package/dist/hooks/useRCAReports.esm.js.map +1 -0
  165. package/dist/hooks/useRuntimeLogs.esm.js +147 -0
  166. package/dist/hooks/useRuntimeLogs.esm.js.map +1 -0
  167. package/dist/hooks/useSpanDetails.esm.js +71 -0
  168. package/dist/hooks/useSpanDetails.esm.js.map +1 -0
  169. package/dist/hooks/useTraceSpans.esm.js +80 -0
  170. package/dist/hooks/useTraceSpans.esm.js.map +1 -0
  171. package/dist/hooks/useTraces.esm.js +112 -0
  172. package/dist/hooks/useTraces.esm.js.map +1 -0
  173. package/dist/hooks/useUpdateIncident.esm.js +50 -0
  174. package/dist/hooks/useUpdateIncident.esm.js.map +1 -0
  175. package/dist/hooks/useUrlFilters.esm.js +63 -0
  176. package/dist/hooks/useUrlFilters.esm.js.map +1 -0
  177. package/dist/hooks/useUrlFiltersForAlerts.esm.js +80 -0
  178. package/dist/hooks/useUrlFiltersForAlerts.esm.js.map +1 -0
  179. package/dist/hooks/useUrlFiltersForIncidents.esm.js +87 -0
  180. package/dist/hooks/useUrlFiltersForIncidents.esm.js.map +1 -0
  181. package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js +135 -0
  182. package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js.map +1 -0
  183. package/dist/index.d.ts +41 -0
  184. package/dist/index.esm.js +2 -0
  185. package/dist/index.esm.js.map +1 -0
  186. package/dist/plugin.esm.js +107 -0
  187. package/dist/plugin.esm.js.map +1 -0
  188. package/dist/routes.esm.js +8 -0
  189. package/dist/routes.esm.js.map +1 -0
  190. package/dist/types.esm.js +18 -0
  191. package/dist/types.esm.js.map +1 -0
  192. package/dist/utils/applyResourceChange.esm.js +79 -0
  193. package/dist/utils/applyResourceChange.esm.js.map +1 -0
  194. package/dist/utils/urlTimeRange.esm.js +52 -0
  195. package/dist/utils/urlTimeRange.esm.js.map +1 -0
  196. 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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"}