@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 @@
1
+ {"version":3,"file":"ObservabilityProjectIncidentsPage.esm.js","sources":["../../../src/components/Incidents/ObservabilityProjectIncidentsPage.tsx"],"sourcesContent":["import { useEffect, useRef, useMemo, useState, useCallback } from 'react';\nimport { Box, Typography, Button, Snackbar } from '@material-ui/core';\nimport { EmptyState, Progress, WarningIcon } from '@backstage/core-components';\nimport { Alert } from '@material-ui/lab';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';\nimport { IncidentsFilter } from './IncidentsFilter';\nimport { IncidentsTable } from './IncidentsTable';\nimport { IncidentsActions } from './IncidentsActions';\nimport {\n useGetEnvironmentsByNamespace,\n useGetComponentsByProject,\n useProjectIncidents,\n useUrlFiltersForIncidents,\n useUpdateIncident,\n} from '../../hooks';\nimport { useIncidentsPermission } from '@openchoreo/backstage-plugin-react';\nimport { useRuntimeLogsStyles } from '../RuntimeLogs/styles';\nimport type { IncidentSummary } from '../../types';\n\nconst ObservabilityProjectIncidentsContent = () => {\n const classes = useRuntimeLogsStyles();\n const { entity } = useEntity();\n\n const namespace =\n entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE] || '';\n const projectName = entity.metadata.name || '';\n\n const {\n environments,\n loading: environmentsLoading,\n error: environmentsError,\n } = useGetEnvironmentsByNamespace(namespace, projectName);\n\n const {\n components,\n loading: componentsLoading,\n error: componentsError,\n } = useGetComponentsByProject(entity);\n\n const { filters, updateFilters } = useUrlFiltersForIncidents({\n environments,\n });\n\n const selectedEnvironment = environments.find(\n env => env.name === filters.environment,\n );\n\n const [lastUpdated, setLastUpdated] = useState<Date>(new Date());\n const [updatingIncidentId, setUpdatingIncidentId] = useState<string | null>(\n null,\n );\n const [snackbarMessage, setSnackbarMessage] = useState<string | null>(null);\n\n const { updateIncident } = useUpdateIncident();\n\n const {\n incidents,\n loading: incidentsLoading,\n error: incidentsError,\n fetchIncidents,\n refresh,\n } = useProjectIncidents(entity, {\n environment: filters.environment,\n timeRange: filters.timeRange,\n customStartTime: filters.customStartTime,\n customEndTime: filters.customEndTime,\n components: filters.components,\n sortOrder: filters.sortOrder || 'desc',\n });\n\n const previousFiltersRef = useRef<{\n environment: string;\n timeRange: string;\n customStartTime?: string;\n customEndTime?: string;\n components: string[];\n sortOrder?: 'asc' | 'desc';\n } | null>(null);\n\n useEffect(() => {\n const currentFilters = {\n environment: filters.environment,\n timeRange: filters.timeRange,\n customStartTime: filters.customStartTime,\n customEndTime: filters.customEndTime,\n components: filters.components || [],\n sortOrder: filters.sortOrder,\n };\n const filtersChanged =\n previousFiltersRef.current === null ||\n JSON.stringify(previousFiltersRef.current) !==\n JSON.stringify(currentFilters);\n\n if (\n filters.environment &&\n selectedEnvironment &&\n namespace &&\n projectName &&\n filtersChanged\n ) {\n fetchIncidents(true);\n setLastUpdated(new Date());\n previousFiltersRef.current = currentFilters;\n }\n }, [\n filters.environment,\n filters.timeRange,\n filters.customStartTime,\n filters.customEndTime,\n filters.components,\n filters.sortOrder,\n fetchIncidents,\n selectedEnvironment,\n namespace,\n projectName,\n ]);\n\n useEffect(() => {\n if (!incidentsLoading) setLastUpdated(new Date());\n }, [incidentsLoading]);\n\n const handleRefresh = () => {\n refresh();\n setLastUpdated(new Date());\n };\n\n const handleFiltersChange = (newFilters: Partial<typeof filters>) => {\n updateFilters(newFilters);\n };\n\n const filteredIncidents = useMemo((): IncidentSummary[] => {\n let result = incidents;\n if (filters.status && filters.status.length > 0) {\n result = result.filter(\n i =>\n i.status &&\n filters.status!.some(\n s => s.toLowerCase() === (i.status || '').toLowerCase(),\n ),\n );\n }\n if (filters.searchQuery) {\n const q = filters.searchQuery.toLowerCase();\n result = result.filter(\n i =>\n (i.description || '').toLowerCase().includes(q) ||\n (i.incidentId || '').toLowerCase().includes(q) ||\n (i.alertId || '').toLowerCase().includes(q) ||\n (i.componentName || '').toLowerCase().includes(q),\n );\n }\n return result;\n }, [incidents, filters.status, filters.searchQuery]);\n\n // Open the RCA Reports tab of this project entity in a new browser tab,\n // pre-filtered by environment, time range, and alert ID.\n const handleViewRCA = useCallback(\n (incident: IncidentSummary) => {\n const catalogNs = entity.metadata.namespace || 'default';\n const params = new URLSearchParams({\n ...(filters.environment ? { env: filters.environment } : {}),\n ...(filters.timeRange ? { timeRange: filters.timeRange } : {}),\n ...(incident.alertId ? { q: incident.alertId } : {}),\n });\n const query = params.toString();\n const url = `/catalog/${catalogNs}/system/${projectName}/rca-reports${\n query ? `?${query}` : ''\n }`;\n window.open(url, '_blank', 'noopener,noreferrer');\n },\n [entity, projectName, filters.environment, filters.timeRange],\n );\n\n // Open the Cost Analysis tab of this project entity in a new browser tab,\n // pre-filtered by environment and time range.\n const handleViewCostAnalysis = useCallback(\n (_incident: IncidentSummary) => {\n const catalogNs = entity.metadata.namespace || 'default';\n const params = new URLSearchParams({\n ...(filters.environment ? { env: filters.environment } : {}),\n ...(filters.timeRange ? { timeRange: filters.timeRange } : {}),\n });\n const query = params.toString();\n const url = `/catalog/${catalogNs}/system/${projectName}/cost-analysis${\n query ? `?${query}` : ''\n }`;\n window.open(url, '_blank', 'noopener,noreferrer');\n },\n [entity, projectName, filters.environment, filters.timeRange],\n );\n\n const handleAcknowledge = useCallback(\n async (incident: IncidentSummary) => {\n setUpdatingIncidentId(incident.incidentId);\n try {\n await updateIncident(incident, 'acknowledged');\n refresh();\n setLastUpdated(new Date());\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n setSnackbarMessage(\n `Failed to acknowledge incident ${incident.incidentId}: ${detail}`,\n );\n } finally {\n setUpdatingIncidentId(null);\n }\n },\n [updateIncident, refresh],\n );\n\n const handleResolve = useCallback(\n async (incident: IncidentSummary) => {\n setUpdatingIncidentId(incident.incidentId);\n try {\n await updateIncident(incident, 'resolved');\n refresh();\n setLastUpdated(new Date());\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n setSnackbarMessage(\n `Failed to resolve incident ${incident.incidentId}: ${detail}`,\n );\n } finally {\n setUpdatingIncidentId(null);\n }\n },\n [updateIncident, refresh],\n );\n\n const renderError = (error: string) => {\n const isObservabilityDisabled = error.includes(\n 'Observability is not enabled',\n );\n return (\n <Alert\n severity={isObservabilityDisabled ? 'info' : 'error'}\n className={classes.errorContainer}\n >\n <Typography variant=\"body1\">\n {isObservabilityDisabled\n ? 'Observability is not enabled for this project. Enable observability to view incidents.'\n : error}\n </Typography>\n {!isObservabilityDisabled && (\n <Button onClick={handleRefresh} color=\"inherit\" size=\"small\">\n Retry\n </Button>\n )}\n </Alert>\n );\n };\n\n if (environmentsError) {\n return <Box>{renderError(environmentsError)}</Box>;\n }\n\n if (componentsError) {\n return <Box>{renderError(componentsError)}</Box>;\n }\n\n return (\n <Box>\n <IncidentsFilter\n filters={filters}\n onFiltersChange={handleFiltersChange}\n environments={environments}\n environmentsLoading={environmentsLoading}\n components={components}\n componentsLoading={componentsLoading}\n disabled={incidentsLoading}\n />\n\n {incidentsError && renderError(incidentsError)}\n\n {!filters.environment &&\n !environmentsLoading &&\n environments.length === 0 && (\n <Alert severity=\"info\" className={classes.errorContainer}>\n <Typography variant=\"body1\">\n No environments found for this project.\n </Typography>\n </Alert>\n )}\n\n {filters.environment && (\n <>\n <IncidentsActions\n totalCount={filteredIncidents.length}\n disabled={incidentsLoading || !filters.environment}\n onRefresh={handleRefresh}\n filters={filters}\n onFiltersChange={handleFiltersChange}\n lastUpdated={lastUpdated}\n />\n\n <IncidentsTable\n incidents={filteredIncidents}\n loading={incidentsLoading}\n namespaceName={namespace}\n projectName={projectName}\n environmentName={\n selectedEnvironment?.displayName || selectedEnvironment?.name\n }\n onViewRCA={handleViewRCA}\n onViewCostAnalysis={handleViewCostAnalysis}\n onAcknowledge={handleAcknowledge}\n onResolve={handleResolve}\n updatingIncidentId={updatingIncidentId}\n />\n </>\n )}\n\n <Snackbar\n open={!!snackbarMessage}\n autoHideDuration={6000}\n onClose={() => setSnackbarMessage(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert severity=\"error\" onClose={() => setSnackbarMessage(null)}>\n {snackbarMessage}\n </Alert>\n </Snackbar>\n </Box>\n );\n};\n\nexport const ObservabilityProjectIncidentsPage = () => {\n const {\n canViewIncidents,\n loading: permissionLoading,\n deniedTooltip,\n } = useIncidentsPermission();\n\n if (permissionLoading) return <Progress />;\n\n if (!canViewIncidents) {\n return (\n <EmptyState\n missing=\"data\"\n title=\"Permission Denied\"\n description={\n <Box display=\"flex\" alignItems=\"center\" gridGap={8}>\n <WarningIcon />\n {deniedTooltip}\n </Box>\n }\n />\n );\n }\n\n return <ObservabilityProjectIncidentsContent />;\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ const INCIDENT_STATUSES = [
2
+ "active",
3
+ "acknowledged",
4
+ "resolved"
5
+ ];
6
+
7
+ export { INCIDENT_STATUSES };
8
+ //# sourceMappingURL=types.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.esm.js","sources":["../../../src/components/Incidents/types.ts"],"sourcesContent":["export interface IncidentsFilters {\n environment: string;\n timeRange: string;\n /** ISO start time, used when `timeRange === 'custom'` */\n customStartTime?: string;\n /** ISO end time, used when `timeRange === 'custom'` */\n customEndTime?: string;\n components?: string[];\n sortOrder?: 'asc' | 'desc';\n status?: string[];\n searchQuery?: string;\n}\n\nexport const INCIDENT_STATUSES = [\n 'active',\n 'acknowledged',\n 'resolved',\n] as const;\n"],"names":[],"mappings":"AAaO,MAAM,iBAAA,GAAoB;AAAA,EAC/B,QAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF;;;;"}
@@ -0,0 +1,53 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTheme } from '@material-ui/core/styles';
3
+
4
+ const ChartTooltip = ({
5
+ active,
6
+ payload,
7
+ label,
8
+ labelFormatter,
9
+ formatter
10
+ }) => {
11
+ const theme = useTheme();
12
+ if (!active || !payload?.length) return null;
13
+ return /* @__PURE__ */ jsxs(
14
+ "div",
15
+ {
16
+ style: {
17
+ background: theme.palette.background.paper,
18
+ border: `1px solid ${theme.palette.divider}`,
19
+ borderRadius: theme.shape.borderRadius,
20
+ padding: theme.spacing(1, 1.5)
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ jsx(
24
+ "p",
25
+ {
26
+ style: {
27
+ margin: `0 0 ${theme.spacing(0.5)}px`,
28
+ color: theme.palette.text.secondary,
29
+ fontSize: 12
30
+ },
31
+ children: labelFormatter ? labelFormatter(label) : label
32
+ }
33
+ ),
34
+ payload.map((entry) => /* @__PURE__ */ jsxs(
35
+ "p",
36
+ {
37
+ style: { margin: `${theme.spacing(0.5)}px 0`, color: entry.color },
38
+ children: [
39
+ entry.name,
40
+ " :",
41
+ " ",
42
+ formatter && entry.value !== void 0 ? formatter(entry.value) : entry.value
43
+ ]
44
+ },
45
+ entry.dataKey
46
+ ))
47
+ ]
48
+ }
49
+ );
50
+ };
51
+
52
+ export { ChartTooltip };
53
+ //# sourceMappingURL=ChartTooltip.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartTooltip.esm.js","sources":["../../../src/components/Metrics/ChartTooltip.tsx"],"sourcesContent":["import { useTheme } from '@material-ui/core/styles';\n\ninterface TooltipEntry {\n dataKey?: string | number;\n name?: string;\n value?: number;\n color?: string;\n}\n\ninterface ChartTooltipProps {\n active?: boolean;\n payload?: TooltipEntry[];\n label?: any;\n labelFormatter?: (label: any) => string;\n formatter?: (value: number) => string;\n}\n\nexport const ChartTooltip = ({\n active,\n payload,\n label,\n labelFormatter,\n formatter,\n}: ChartTooltipProps) => {\n const theme = useTheme();\n\n if (!active || !payload?.length) return null;\n\n return (\n <div\n style={{\n background: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: theme.shape.borderRadius,\n padding: theme.spacing(1, 1.5),\n }}\n >\n <p\n style={{\n margin: `0 0 ${theme.spacing(0.5)}px`,\n color: theme.palette.text.secondary,\n fontSize: 12,\n }}\n >\n {labelFormatter ? labelFormatter(label) : label}\n </p>\n {payload.map((entry: TooltipEntry) => (\n <p\n key={entry.dataKey}\n style={{ margin: `${theme.spacing(0.5)}px 0`, color: entry.color }}\n >\n {entry.name} :{' '}\n {formatter && entry.value !== undefined\n ? formatter(entry.value)\n : entry.value}\n </p>\n ))}\n </div>\n );\n};\n"],"names":[],"mappings":";;;AAiBO,MAAM,eAAe,CAAC;AAAA,EAC3B,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,KAAyB;AACvB,EAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS,QAAQ,OAAO,IAAA;AAExC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,KAAA;AAAA,QACrC,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,QAC1C,YAAA,EAAc,MAAM,KAAA,CAAM,YAAA;AAAA,QAC1B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,GAAG;AAAA,OAC/B;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO;AAAA,cACL,MAAA,EAAQ,CAAA,IAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAC,CAAA,EAAA,CAAA;AAAA,cACjC,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,cAC1B,QAAA,EAAU;AAAA,aACZ;AAAA,YAEC,QAAA,EAAA,cAAA,GAAiB,cAAA,CAAe,KAAK,CAAA,GAAI;AAAA;AAAA,SAC5C;AAAA,QACC,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,qBACZ,IAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YAEC,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAC,CAAA,IAAA,CAAA,EAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM;AAAA,YAEhE,QAAA,EAAA;AAAA,cAAA,KAAA,CAAM,IAAA;AAAA,cAAK,IAAA;AAAA,cAAG,GAAA;AAAA,cACd,SAAA,IAAa,MAAM,KAAA,KAAU,MAAA,GAC1B,UAAU,KAAA,CAAM,KAAK,IACrB,KAAA,CAAM;AAAA;AAAA,WAAA;AAAA,UANL,KAAA,CAAM;AAAA,SAQd;AAAA;AAAA;AAAA,GACH;AAEJ;;;;"}
@@ -0,0 +1,109 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useRef, useEffect } from 'react';
3
+ import { Grid, Typography, Button, Card, CardHeader, Divider, CardContent } from '@material-ui/core';
4
+ import { Alert } from '@material-ui/lab';
5
+ import { MetricGraphByComponent } from './MetricGraphByComponent.esm.js';
6
+ import '@openchoreo/backstage-plugin-common';
7
+ import { useDataPlaneNetPolProvider } from '../../hooks/useDataPlaneNetPolProvider.esm.js';
8
+ import '@backstage/core-plugin-api';
9
+ import 'react-router-dom';
10
+ import '../../utils/urlTimeRange.esm.js';
11
+ import { useMetrics } from '../../hooks/useMetrics.esm.js';
12
+ import '../../api/ObservabilityApi.esm.js';
13
+ import '@openchoreo/backstage-plugin-react';
14
+ import '@backstage/plugin-catalog-react';
15
+ import '../../api/RCAAgentApi.esm.js';
16
+ import '../../api/FinOpsAgentApi.esm.js';
17
+
18
+ const HTTPMetricsSection = ({
19
+ filters,
20
+ entity,
21
+ namespaceName,
22
+ project
23
+ }) => {
24
+ const { networkPolicyProvider, loading: netPolLoading } = useDataPlaneNetPolProvider(
25
+ namespaceName,
26
+ filters.environment?.dataPlaneRef
27
+ );
28
+ const httpEnabled = networkPolicyProvider === "cilium";
29
+ const { metrics, error, fetchMetrics } = useMetrics(
30
+ filters,
31
+ entity,
32
+ namespaceName,
33
+ project,
34
+ "http"
35
+ );
36
+ const httpMetrics = metrics;
37
+ const previousFiltersRef = useRef({
38
+ environment: void 0,
39
+ timeRange: void 0
40
+ });
41
+ useEffect(() => {
42
+ if (!httpEnabled) {
43
+ return;
44
+ }
45
+ const currentFilters = {
46
+ environment: filters.environment?.name,
47
+ timeRange: filters.timeRange
48
+ };
49
+ const filtersChanged = JSON.stringify(previousFiltersRef.current) !== JSON.stringify(currentFilters);
50
+ if (filters.environment && filters.timeRange && filtersChanged) {
51
+ fetchMetrics(true);
52
+ }
53
+ previousFiltersRef.current = currentFilters;
54
+ }, [httpEnabled, filters.environment, filters.timeRange, fetchMetrics]);
55
+ if (netPolLoading || !httpEnabled) {
56
+ return null;
57
+ }
58
+ if (error) {
59
+ const isMetricsModuleError = error.toLowerCase().includes("metrics module");
60
+ return /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(Alert, { severity: "error", children: [
61
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", children: isMetricsModuleError ? "HTTP metrics are unavailable. Check the metrics module configuration." : "Failed to load HTTP metrics." }),
62
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: error }),
63
+ !isMetricsModuleError && /* @__PURE__ */ jsx(
64
+ Button,
65
+ {
66
+ onClick: () => fetchMetrics(true),
67
+ color: "inherit",
68
+ size: "small",
69
+ children: "Retry"
70
+ }
71
+ )
72
+ ] }) });
73
+ }
74
+ const throughputData = httpMetrics?.networkThroughput || {};
75
+ const latencyData = httpMetrics?.networkLatency || {};
76
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
77
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsxs(Card, { children: [
78
+ /* @__PURE__ */ jsx(CardHeader, { title: "Network Throughput" }),
79
+ /* @__PURE__ */ jsx(Divider, {}),
80
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(
81
+ MetricGraphByComponent,
82
+ {
83
+ usageData: throughputData,
84
+ usageType: "networkThroughput",
85
+ timeRange: filters.timeRange,
86
+ customStartTime: filters.customStartTime,
87
+ customEndTime: filters.customEndTime
88
+ }
89
+ ) })
90
+ ] }) }),
91
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsxs(Card, { children: [
92
+ /* @__PURE__ */ jsx(CardHeader, { title: "Network Latency" }),
93
+ /* @__PURE__ */ jsx(Divider, {}),
94
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(
95
+ MetricGraphByComponent,
96
+ {
97
+ usageData: latencyData,
98
+ usageType: "networkLatency",
99
+ timeRange: filters.timeRange,
100
+ customStartTime: filters.customStartTime,
101
+ customEndTime: filters.customEndTime
102
+ }
103
+ ) })
104
+ ] }) })
105
+ ] });
106
+ };
107
+
108
+ export { HTTPMetricsSection };
109
+ //# sourceMappingURL=HTTPMetricsSection.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HTTPMetricsSection.esm.js","sources":["../../../src/components/Metrics/HTTPMetricsSection.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n Divider,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { MetricGraphByComponent } from './MetricGraphByComponent';\nimport {\n Filters,\n HttpMetrics,\n NetworkLatencyMetrics,\n NetworkThroughputMetrics,\n} from '../../types';\nimport { Entity } from '@backstage/catalog-model';\nimport { useMetrics, useDataPlaneNetPolProvider } from '../../hooks';\n\ntype HTTPMetricsSectionProps = {\n filters: Filters;\n entity: Entity;\n namespaceName: string;\n project: string;\n};\n\nexport const HTTPMetricsSection = ({\n filters,\n entity,\n namespaceName,\n project,\n}: HTTPMetricsSectionProps) => {\n const { networkPolicyProvider, loading: netPolLoading } =\n useDataPlaneNetPolProvider(\n namespaceName,\n filters.environment?.dataPlaneRef,\n );\n const httpEnabled = networkPolicyProvider === 'cilium';\n const { metrics, error, fetchMetrics } = useMetrics(\n filters,\n entity,\n namespaceName,\n project,\n 'http',\n );\n const httpMetrics = metrics as HttpMetrics;\n\n const previousFiltersRef = useRef({\n environment: undefined as string | undefined,\n timeRange: undefined as string | undefined,\n });\n\n useEffect(() => {\n if (!httpEnabled) {\n return;\n }\n\n const currentFilters = {\n environment: filters.environment?.name,\n timeRange: filters.timeRange,\n };\n\n const filtersChanged =\n JSON.stringify(previousFiltersRef.current) !==\n JSON.stringify(currentFilters);\n\n if (filters.environment && filters.timeRange && filtersChanged) {\n fetchMetrics(true);\n }\n\n previousFiltersRef.current = currentFilters;\n }, [httpEnabled, filters.environment, filters.timeRange, fetchMetrics]);\n\n if (netPolLoading || !httpEnabled) {\n return null;\n }\n\n if (error) {\n const isMetricsModuleError = error.toLowerCase().includes('metrics module');\n\n return (\n <Grid item xs={12}>\n <Alert severity=\"error\">\n <Typography variant=\"body1\">\n {isMetricsModuleError\n ? 'HTTP metrics are unavailable. Check the metrics module configuration.'\n : 'Failed to load HTTP metrics.'}\n </Typography>\n <Typography variant=\"body2\">{error}</Typography>\n {!isMetricsModuleError && (\n <Button\n onClick={() => fetchMetrics(true)}\n color=\"inherit\"\n size=\"small\"\n >\n Retry\n </Button>\n )}\n </Alert>\n </Grid>\n );\n }\n\n const throughputData =\n httpMetrics?.networkThroughput || ({} as NetworkThroughputMetrics);\n const latencyData =\n httpMetrics?.networkLatency || ({} as NetworkLatencyMetrics);\n\n return (\n <>\n <Grid item xs={12} md={6}>\n <Card>\n <CardHeader title=\"Network Throughput\" />\n <Divider />\n <CardContent>\n <MetricGraphByComponent\n usageData={throughputData}\n usageType=\"networkThroughput\"\n timeRange={filters.timeRange}\n customStartTime={filters.customStartTime}\n customEndTime={filters.customEndTime}\n />\n </CardContent>\n </Card>\n </Grid>\n <Grid item xs={12} md={6}>\n <Card>\n <CardHeader title=\"Network Latency\" />\n <Divider />\n <CardContent>\n <MetricGraphByComponent\n usageData={latencyData}\n usageType=\"networkLatency\"\n timeRange={filters.timeRange}\n customStartTime={filters.customStartTime}\n customEndTime={filters.customEndTime}\n />\n </CardContent>\n </Card>\n </Grid>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useMemo } from 'react';
3
+ import { LineChart, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Line } from 'recharts';
4
+ import { transformMetricsData, calculateTimeDomain, getMetricConfigs, formatAxisTime, formatMetricValue, formatTooltipTime, getLineOpacity, formatMetricName } from './utils.esm.js';
5
+ import { useMetricGraphStyles } from './styles.esm.js';
6
+ import { ChartTooltip } from './ChartTooltip.esm.js';
7
+
8
+ const MetricGraphByComponent = ({
9
+ usageData,
10
+ usageType,
11
+ timeRange,
12
+ customStartTime,
13
+ customEndTime
14
+ }) => {
15
+ const classes = useMetricGraphStyles();
16
+ const [hoveringDataKey, setHoveringDataKey] = useState();
17
+ const transformedData = useMemo(
18
+ () => transformMetricsData(usageData),
19
+ [usageData]
20
+ );
21
+ const { ticks, daysRange, domain } = useMemo(
22
+ () => calculateTimeDomain(transformedData, timeRange, 5, {
23
+ startTime: customStartTime,
24
+ endTime: customEndTime
25
+ }),
26
+ [transformedData, timeRange, customStartTime, customEndTime]
27
+ );
28
+ const metrics = useMemo(() => getMetricConfigs(usageType), [usageType]);
29
+ const handleMouseEnter = (payload) => setHoveringDataKey(payload.dataKey);
30
+ const handleMouseLeave = () => setHoveringDataKey(void 0);
31
+ return /* @__PURE__ */ jsxs("div", { className: classes.chartContainer, children: [
32
+ transformedData.length === 0 && /* @__PURE__ */ jsx("div", { className: classes.emptyOverlay, children: "No data available" }),
33
+ /* @__PURE__ */ jsxs(
34
+ LineChart,
35
+ {
36
+ className: classes.lineChart,
37
+ responsive: true,
38
+ data: transformedData,
39
+ children: [
40
+ /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3" }),
41
+ /* @__PURE__ */ jsx(
42
+ XAxis,
43
+ {
44
+ dataKey: "timestamp",
45
+ type: "number",
46
+ domain,
47
+ tickFormatter: (ts) => formatAxisTime(ts, daysRange),
48
+ ticks,
49
+ tick: { fontSize: 12 }
50
+ }
51
+ ),
52
+ /* @__PURE__ */ jsx(
53
+ YAxis,
54
+ {
55
+ width: "auto",
56
+ tickFormatter: (v) => formatMetricValue(v, usageType)
57
+ }
58
+ ),
59
+ /* @__PURE__ */ jsx(
60
+ Tooltip,
61
+ {
62
+ content: /* @__PURE__ */ jsx(
63
+ ChartTooltip,
64
+ {
65
+ labelFormatter: formatTooltipTime,
66
+ formatter: (value) => formatMetricValue(value, usageType)
67
+ }
68
+ )
69
+ }
70
+ ),
71
+ /* @__PURE__ */ jsx(
72
+ Legend,
73
+ {
74
+ onMouseEnter: handleMouseEnter,
75
+ onMouseLeave: handleMouseLeave
76
+ }
77
+ ),
78
+ Object.entries(metrics).map(([, { key, color }]) => /* @__PURE__ */ jsx(
79
+ Line,
80
+ {
81
+ type: "monotone",
82
+ dataKey: key,
83
+ name: formatMetricName(key),
84
+ strokeOpacity: getLineOpacity(key, hoveringDataKey),
85
+ stroke: color,
86
+ dot: false,
87
+ activeDot: { r: 4 },
88
+ connectNulls: false
89
+ },
90
+ key
91
+ ))
92
+ ]
93
+ }
94
+ )
95
+ ] });
96
+ };
97
+
98
+ export { MetricGraphByComponent };
99
+ //# sourceMappingURL=MetricGraphByComponent.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricGraphByComponent.esm.js","sources":["../../../src/components/Metrics/MetricGraphByComponent.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n LineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n LegendPayload,\n} from 'recharts';\nimport { DataKey } from 'recharts/types/util/types';\nimport {\n CpuUsageMetrics,\n MemoryUsageMetrics,\n NetworkLatencyMetrics,\n NetworkThroughputMetrics,\n} from '../../types';\nimport {\n formatAxisTime,\n formatTooltipTime,\n formatMetricValue,\n calculateTimeDomain,\n transformMetricsData,\n getMetricConfigs,\n getLineOpacity,\n formatMetricName,\n} from './utils';\nimport { useMetricGraphStyles } from './styles';\nimport { ChartTooltip } from './ChartTooltip';\n\nexport const MetricGraphByComponent = ({\n usageData,\n usageType,\n timeRange,\n customStartTime,\n customEndTime,\n}: {\n usageData:\n | CpuUsageMetrics\n | MemoryUsageMetrics\n | NetworkThroughputMetrics\n | NetworkLatencyMetrics;\n usageType: 'cpu' | 'memory' | 'networkThroughput' | 'networkLatency';\n timeRange?: string;\n customStartTime?: string;\n customEndTime?: string;\n}) => {\n const classes = useMetricGraphStyles();\n const [hoveringDataKey, setHoveringDataKey] = useState<\n DataKey<any> | undefined\n >();\n\n const transformedData = useMemo(\n () => transformMetricsData(usageData),\n [usageData],\n );\n\n const { ticks, daysRange, domain } = useMemo(\n () =>\n calculateTimeDomain(transformedData, timeRange, 5, {\n startTime: customStartTime,\n endTime: customEndTime,\n }),\n [transformedData, timeRange, customStartTime, customEndTime],\n );\n\n const metrics = useMemo(() => getMetricConfigs(usageType), [usageType]);\n\n const handleMouseEnter = (payload: LegendPayload) =>\n setHoveringDataKey(payload.dataKey);\n\n const handleMouseLeave = () => setHoveringDataKey(undefined);\n\n return (\n <div className={classes.chartContainer}>\n {transformedData.length === 0 && (\n <div className={classes.emptyOverlay}>No data available</div>\n )}\n <LineChart\n className={classes.lineChart}\n responsive\n data={transformedData}\n >\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis\n dataKey=\"timestamp\"\n type=\"number\"\n domain={domain}\n tickFormatter={ts => formatAxisTime(ts, daysRange)}\n ticks={ticks}\n tick={{ fontSize: 12 }}\n />\n <YAxis\n width=\"auto\"\n tickFormatter={v => formatMetricValue(v, usageType)}\n />\n <Tooltip\n content={\n <ChartTooltip\n labelFormatter={formatTooltipTime}\n formatter={(value: number) => formatMetricValue(value, usageType)}\n />\n }\n />\n <Legend\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n />\n {Object.entries(metrics).map(([, { key, color }]) => (\n <Line\n key={key}\n type=\"monotone\"\n dataKey={key}\n name={formatMetricName(key)}\n strokeOpacity={getLineOpacity(key, hoveringDataKey)}\n stroke={color}\n dot={false}\n activeDot={{ r: 4 }}\n connectNulls={false}\n />\n ))}\n </LineChart>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Box, Typography, Button } from '@material-ui/core';
3
+ import Refresh from '@material-ui/icons/Refresh';
4
+ import { useMetricsActionsStyles } from './styles.esm.js';
5
+
6
+ const MetricsActions = ({
7
+ disabled,
8
+ onRefresh
9
+ }) => {
10
+ const classes = useMetricsActionsStyles();
11
+ return /* @__PURE__ */ jsxs(Box, { className: classes.statsContainer, children: [
12
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
13
+ "Last updated at: ",
14
+ (/* @__PURE__ */ new Date()).toLocaleString()
15
+ ] }) }),
16
+ /* @__PURE__ */ jsx(Box, { className: classes.actionsContainer, children: /* @__PURE__ */ jsx(
17
+ Button,
18
+ {
19
+ variant: "outlined",
20
+ startIcon: /* @__PURE__ */ jsx(Refresh, {}),
21
+ onClick: onRefresh,
22
+ disabled,
23
+ children: "Refresh"
24
+ }
25
+ ) })
26
+ ] });
27
+ };
28
+
29
+ export { MetricsActions };
30
+ //# sourceMappingURL=MetricsActions.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricsActions.esm.js","sources":["../../../src/components/Metrics/MetricsActions.tsx"],"sourcesContent":["import { Box, Typography, Button } from '@material-ui/core';\nimport Refresh from '@material-ui/icons/Refresh';\nimport { useMetricsActionsStyles } from './styles';\n\ninterface MetricsActionsProps {\n disabled: boolean;\n onRefresh: () => void;\n}\n\nexport const MetricsActions = ({\n disabled,\n onRefresh,\n}: MetricsActionsProps) => {\n const classes = useMetricsActionsStyles();\n return (\n <Box className={classes.statsContainer}>\n <Box>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Last updated at: {new Date().toLocaleString()}\n </Typography>\n </Box>\n <Box className={classes.actionsContainer}>\n <Button\n variant=\"outlined\"\n startIcon={<Refresh />}\n onClick={onRefresh}\n disabled={disabled}\n >\n Refresh\n </Button>\n {/* TODO: Add Auto Refresh Button */}\n </Box>\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;AASO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,QAAA;AAAA,EACA;AACF,CAAA,KAA2B;AACzB,EAAA,MAAM,UAAU,uBAAA,EAAwB;AACxC,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,cAAA,EACtB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,OACC,QAAA,kBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,OAAM,eAAA,EAAgB,QAAA,EAAA;AAAA,MAAA,mBAAA;AAAA,MAAA,iBAC9B,IAAI,IAAA,EAAK,EAAE,cAAA;AAAe,KAAA,EAC9C,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,gBAAA,EACtB,QAAA,kBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,UAAA;AAAA,QACR,SAAA,sBAAY,OAAA,EAAA,EAAQ,CAAA;AAAA,QACpB,OAAA,EAAS,SAAA;AAAA,QACT,QAAA;AAAA,QACD,QAAA,EAAA;AAAA;AAAA,KAED,EAEF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,49 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Grid, FormControl, InputLabel, Select, MenuItem } from '@material-ui/core';
3
+ import { TimeRangeFilter } from '../TimeRangeFilter/TimeRangeFilter.esm.js';
4
+
5
+ const MetricsFilters = ({
6
+ filters,
7
+ onFiltersChange,
8
+ environments,
9
+ disabled = false
10
+ }) => {
11
+ const handleEnvironmentChange = (event) => {
12
+ const selectedEnvironment = environments.find(
13
+ (env) => env.uid === event.target.value
14
+ );
15
+ if (selectedEnvironment) {
16
+ onFiltersChange({ environment: selectedEnvironment });
17
+ }
18
+ };
19
+ return /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, children: [
20
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 3 }),
21
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 3 }),
22
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 3, children: /* @__PURE__ */ jsxs(FormControl, { fullWidth: true, disabled, variant: "outlined", children: [
23
+ /* @__PURE__ */ jsx(InputLabel, { id: "environment-label", children: "Environment" }),
24
+ /* @__PURE__ */ jsx(
25
+ Select,
26
+ {
27
+ value: filters.environment?.uid || "",
28
+ onChange: handleEnvironmentChange,
29
+ labelId: "environment-label",
30
+ label: "Environment",
31
+ children: environments.map((environment) => /* @__PURE__ */ jsx(MenuItem, { value: environment.uid, children: environment.displayName || environment.name }, environment.uid))
32
+ }
33
+ )
34
+ ] }) }),
35
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 3, children: /* @__PURE__ */ jsx(
36
+ TimeRangeFilter,
37
+ {
38
+ value: filters.timeRange,
39
+ customStartTime: filters.customStartTime,
40
+ customEndTime: filters.customEndTime,
41
+ onChange: onFiltersChange,
42
+ disabled
43
+ }
44
+ ) })
45
+ ] });
46
+ };
47
+
48
+ export { MetricsFilters };
49
+ //# sourceMappingURL=MetricsFilters.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricsFilters.esm.js","sources":["../../../src/components/Metrics/MetricsFilters.tsx"],"sourcesContent":["import {\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Grid,\n} from '@material-ui/core';\nimport { Filters, Environment } from '../../types';\nimport { TimeRangeFilter } from '../TimeRangeFilter';\n\ninterface MetricsFiltersProps {\n filters: Filters;\n onFiltersChange: (filters: Partial<Filters>) => void;\n environments: Environment[];\n disabled?: boolean;\n}\n\nexport const MetricsFilters = ({\n filters,\n onFiltersChange,\n environments,\n disabled = false,\n}: MetricsFiltersProps) => {\n const handleEnvironmentChange = (\n event: React.ChangeEvent<{ value: unknown }>,\n ) => {\n const selectedEnvironment = environments.find(\n env => env.uid === (event.target.value as string),\n );\n if (selectedEnvironment) {\n onFiltersChange({ environment: selectedEnvironment });\n }\n };\n\n return (\n <Grid container spacing={3}>\n <Grid item xs={12} md={3}>\n {/* TODO: Add Filters for Metrics */}\n </Grid>\n\n <Grid item xs={12} md={3}>\n {/* TODO: Add Filters for Metrics */}\n </Grid>\n\n <Grid item xs={12} md={3}>\n <FormControl fullWidth disabled={disabled} variant=\"outlined\">\n <InputLabel id=\"environment-label\">Environment</InputLabel>\n <Select\n value={filters.environment?.uid || ''}\n onChange={handleEnvironmentChange}\n labelId=\"environment-label\"\n label=\"Environment\"\n >\n {environments.map((environment: Environment) => (\n <MenuItem key={environment.uid} value={environment.uid}>\n {environment.displayName || environment.name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12} md={3}>\n <TimeRangeFilter\n value={filters.timeRange}\n customStartTime={filters.customStartTime}\n customEndTime={filters.customEndTime}\n onChange={onFiltersChange}\n disabled={disabled}\n />\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;AAiBO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,OAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA,GAAW;AACb,CAAA,KAA2B;AACzB,EAAA,MAAM,uBAAA,GAA0B,CAC9B,KAAA,KACG;AACH,IAAA,MAAM,sBAAsB,YAAA,CAAa,IAAA;AAAA,MACvC,CAAA,GAAA,KAAO,GAAA,CAAI,GAAA,KAAS,KAAA,CAAM,MAAA,CAAO;AAAA,KACnC;AACA,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,eAAA,CAAgB,EAAE,WAAA,EAAa,mBAAA,EAAqB,CAAA;AAAA,IACtD;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EACvB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAEvB,CAAA;AAAA,wBAEC,IAAA,EAAA,EAAK,IAAA,EAAI,MAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAEvB,CAAA;AAAA,oBAEA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAS,IAAA,EAAC,QAAA,EAAoB,SAAQ,UAAA,EACjD,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,mBAAA,EAAoB,QAAA,EAAA,aAAA,EAAW,CAAA;AAAA,sBAC9C,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,OAAA,CAAQ,WAAA,EAAa,GAAA,IAAO,EAAA;AAAA,UACnC,QAAA,EAAU,uBAAA;AAAA,UACV,OAAA,EAAQ,mBAAA;AAAA,UACR,KAAA,EAAM,aAAA;AAAA,UAEL,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAC,WAAA,yBAChB,QAAA,EAAA,EAA+B,KAAA,EAAO,WAAA,CAAY,GAAA,EAChD,sBAAY,WAAA,IAAe,WAAA,CAAY,IAAA,EAAA,EAD3B,WAAA,CAAY,GAE3B,CACD;AAAA;AAAA;AACH,KAAA,EACF,CAAA,EACF,CAAA;AAAA,wBAEC,IAAA,EAAA,EAAK,IAAA,EAAI,MAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EACrB,QAAA,kBAAA,GAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,OAAO,OAAA,CAAQ,SAAA;AAAA,QACf,iBAAiB,OAAA,CAAQ,eAAA;AAAA,QACzB,eAAe,OAAA,CAAQ,aAAA;AAAA,QACvB,QAAA,EAAU,eAAA;AAAA,QACV;AAAA;AAAA,KACF,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}