@openchoreo/backstage-plugin-openchoreo-observability 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.md +22 -0
- package/dist/api/FinOpsAgentApi.esm.js +43 -0
- package/dist/api/FinOpsAgentApi.esm.js.map +1 -0
- package/dist/api/ObservabilityApi.esm.js +568 -0
- package/dist/api/ObservabilityApi.esm.js.map +1 -0
- package/dist/api/ObserverUrlCache.esm.js +59 -0
- package/dist/api/ObserverUrlCache.esm.js.map +1 -0
- package/dist/api/RCAAgentApi.esm.js +104 -0
- package/dist/api/RCAAgentApi.esm.js.map +1 -0
- package/dist/components/Alerts/AlertRow.esm.js +203 -0
- package/dist/components/Alerts/AlertRow.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsActions.esm.js +77 -0
- package/dist/components/Alerts/AlertsActions.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsFilter.esm.js +95 -0
- package/dist/components/Alerts/AlertsFilter.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsTable.esm.js +63 -0
- package/dist/components/Alerts/AlertsTable.esm.js.map +1 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js +251 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js.map +1 -0
- package/dist/components/Alerts/types.esm.js +4 -0
- package/dist/components/Alerts/types.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js +141 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js +128 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js +517 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js +149 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js.map +1 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js +112 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js.map +1 -0
- package/dist/components/CostAnalysis/index.esm.js +2 -0
- package/dist/components/CostAnalysis/index.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentRow.esm.js +258 -0
- package/dist/components/Incidents/IncidentRow.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsActions.esm.js +77 -0
- package/dist/components/Incidents/IncidentsActions.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js +144 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsTable.esm.js +68 -0
- package/dist/components/Incidents/IncidentsTable.esm.js.map +1 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js +283 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js.map +1 -0
- package/dist/components/Incidents/types.esm.js +8 -0
- package/dist/components/Incidents/types.esm.js.map +1 -0
- package/dist/components/Metrics/ChartTooltip.esm.js +53 -0
- package/dist/components/Metrics/ChartTooltip.esm.js.map +1 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js +109 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js.map +1 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js +99 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsActions.esm.js +30 -0
- package/dist/components/Metrics/MetricsActions.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsFilters.esm.js +49 -0
- package/dist/components/Metrics/MetricsFilters.esm.js.map +1 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js +196 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js.map +1 -0
- package/dist/components/Metrics/styles.esm.js +55 -0
- package/dist/components/Metrics/styles.esm.js.map +1 -0
- package/dist/components/Metrics/utils.esm.js +221 -0
- package/dist/components/Metrics/utils.esm.js.map +1 -0
- package/dist/components/RCA/RCAActions.esm.js +42 -0
- package/dist/components/RCA/RCAActions.esm.js.map +1 -0
- package/dist/components/RCA/RCAFilters.esm.js +100 -0
- package/dist/components/RCA/RCAFilters.esm.js.map +1 -0
- package/dist/components/RCA/RCAPage.esm.js +137 -0
- package/dist/components/RCA/RCAPage.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js +9 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js +94 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js +308 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js +113 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js +272 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js +48 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js +205 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js +121 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js +593 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js +35 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js +526 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js +70 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/styles.esm.js +467 -0
- package/dist/components/RCA/RCAReport/styles.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport.esm.js +109 -0
- package/dist/components/RCA/RCAReport.esm.js.map +1 -0
- package/dist/components/RCA/RCATable.esm.js +140 -0
- package/dist/components/RCA/RCATable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js +182 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js +106 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js +200 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js +91 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js +220 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js +222 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/styles.esm.js +256 -0
- package/dist/components/RuntimeLogs/styles.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/types.esm.js +16 -0
- package/dist/components/RuntimeLogs/types.esm.js.map +1 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js +280 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js.map +1 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js +165 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js.map +1 -0
- package/dist/components/Traces/TracesActions.esm.js +37 -0
- package/dist/components/Traces/TracesActions.esm.js.map +1 -0
- package/dist/components/Traces/TracesFilters.esm.js +121 -0
- package/dist/components/Traces/TracesFilters.esm.js.map +1 -0
- package/dist/components/Traces/TracesTable.esm.js +137 -0
- package/dist/components/Traces/TracesTable.esm.js.map +1 -0
- package/dist/components/Traces/WaterfallView.esm.js +567 -0
- package/dist/components/Traces/WaterfallView.esm.js.map +1 -0
- package/dist/components/Traces/styles.esm.js +198 -0
- package/dist/components/Traces/styles.esm.js.map +1 -0
- package/dist/components/Traces/utils.esm.js +19 -0
- package/dist/components/Traces/utils.esm.js.map +1 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js +25 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js.map +1 -0
- package/dist/hooks/useComponentAlerts.esm.js +80 -0
- package/dist/hooks/useComponentAlerts.esm.js.map +1 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js +55 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js.map +1 -0
- package/dist/hooks/useDebouncedSearch.esm.js +24 -0
- package/dist/hooks/useDebouncedSearch.esm.js.map +1 -0
- package/dist/hooks/useFilters.esm.js +29 -0
- package/dist/hooks/useFilters.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReport.esm.js +66 -0
- package/dist/hooks/useFinOpsReport.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReports.esm.js +70 -0
- package/dist/hooks/useFinOpsReports.esm.js.map +1 -0
- package/dist/hooks/useGetComponentsByProject.esm.js +57 -0
- package/dist/hooks/useGetComponentsByProject.esm.js.map +1 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js +53 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js.map +1 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js +40 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js.map +1 -0
- package/dist/hooks/useMetrics.esm.js +107 -0
- package/dist/hooks/useMetrics.esm.js.map +1 -0
- package/dist/hooks/useProjectIncidents.esm.js +111 -0
- package/dist/hooks/useProjectIncidents.esm.js.map +1 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js +185 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useRCAReportByAlert.esm.js +54 -0
- package/dist/hooks/useRCAReportByAlert.esm.js.map +1 -0
- package/dist/hooks/useRCAReports.esm.js +75 -0
- package/dist/hooks/useRCAReports.esm.js.map +1 -0
- package/dist/hooks/useRuntimeLogs.esm.js +147 -0
- package/dist/hooks/useRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useSpanDetails.esm.js +71 -0
- package/dist/hooks/useSpanDetails.esm.js.map +1 -0
- package/dist/hooks/useTraceSpans.esm.js +80 -0
- package/dist/hooks/useTraceSpans.esm.js.map +1 -0
- package/dist/hooks/useTraces.esm.js +112 -0
- package/dist/hooks/useTraces.esm.js.map +1 -0
- package/dist/hooks/useUpdateIncident.esm.js +50 -0
- package/dist/hooks/useUpdateIncident.esm.js.map +1 -0
- package/dist/hooks/useUrlFilters.esm.js +63 -0
- package/dist/hooks/useUrlFilters.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js +80 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js +87 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js +135 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +107 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/types.esm.js +18 -0
- package/dist/types.esm.js.map +1 -0
- package/dist/utils/applyResourceChange.esm.js +79 -0
- package/dist/utils/applyResourceChange.esm.js.map +1 -0
- package/dist/utils/urlTimeRange.esm.js +52 -0
- package/dist/utils/urlTimeRange.esm.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { rootRouteRef } from './routes.esm.js';
|
|
3
|
+
import { ObservabilityClient, observabilityApiRef } from './api/ObservabilityApi.esm.js';
|
|
4
|
+
import { RCAAgentClient, rcaAgentApiRef } from './api/RCAAgentApi.esm.js';
|
|
5
|
+
import { FinOpsAgentClient, finopsAgentApiRef } from './api/FinOpsAgentApi.esm.js';
|
|
6
|
+
|
|
7
|
+
const openchoreoObservabilityPlugin = createPlugin({
|
|
8
|
+
id: "openchoreo-observability",
|
|
9
|
+
routes: {
|
|
10
|
+
root: rootRouteRef
|
|
11
|
+
},
|
|
12
|
+
apis: [
|
|
13
|
+
createApiFactory({
|
|
14
|
+
api: observabilityApiRef,
|
|
15
|
+
deps: {
|
|
16
|
+
discoveryApi: discoveryApiRef,
|
|
17
|
+
fetchApi: fetchApiRef
|
|
18
|
+
},
|
|
19
|
+
factory: ({ discoveryApi, fetchApi }) => new ObservabilityClient({ discoveryApi, fetchApi })
|
|
20
|
+
}),
|
|
21
|
+
createApiFactory({
|
|
22
|
+
api: rcaAgentApiRef,
|
|
23
|
+
deps: {
|
|
24
|
+
discoveryApi: discoveryApiRef,
|
|
25
|
+
fetchApi: fetchApiRef
|
|
26
|
+
},
|
|
27
|
+
factory: ({ discoveryApi, fetchApi }) => new RCAAgentClient({ discoveryApi, fetchApi })
|
|
28
|
+
}),
|
|
29
|
+
createApiFactory({
|
|
30
|
+
api: finopsAgentApiRef,
|
|
31
|
+
deps: {
|
|
32
|
+
discoveryApi: discoveryApiRef,
|
|
33
|
+
fetchApi: fetchApiRef
|
|
34
|
+
},
|
|
35
|
+
factory: ({ discoveryApi, fetchApi }) => new FinOpsAgentClient({ discoveryApi, fetchApi })
|
|
36
|
+
})
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
const ObservabilityMetrics = openchoreoObservabilityPlugin.provide(
|
|
40
|
+
createRoutableExtension({
|
|
41
|
+
name: "ObservabilityMetrics",
|
|
42
|
+
component: () => import('./components/Metrics/ObservabilityMetricsPage.esm.js').then(
|
|
43
|
+
(m) => m.ObservabilityMetricsPage
|
|
44
|
+
),
|
|
45
|
+
mountPoint: rootRouteRef
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
const ObservabilityTraces = openchoreoObservabilityPlugin.provide(
|
|
49
|
+
createRoutableExtension({
|
|
50
|
+
name: "ObservabilityTraces",
|
|
51
|
+
component: () => import('./components/Traces/ObservabilityTracesPage.esm.js').then(
|
|
52
|
+
(m) => m.ObservabilityTracesPage
|
|
53
|
+
),
|
|
54
|
+
mountPoint: rootRouteRef
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
const ObservabilityRCA = openchoreoObservabilityPlugin.provide(
|
|
58
|
+
createRoutableExtension({
|
|
59
|
+
name: "ObservabilityRCA",
|
|
60
|
+
component: () => import('./components/RCA/RCAPage.esm.js').then((m) => m.RCAPage),
|
|
61
|
+
mountPoint: rootRouteRef
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
const ObservabilityRuntimeLogs = openchoreoObservabilityPlugin.provide(
|
|
65
|
+
createRoutableExtension({
|
|
66
|
+
name: "ObservabilityRuntimeLogs",
|
|
67
|
+
component: () => import('./components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js').then(
|
|
68
|
+
(m) => m.ObservabilityRuntimeLogsPage
|
|
69
|
+
),
|
|
70
|
+
mountPoint: rootRouteRef
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
const ObservabilityProjectRuntimeLogs = openchoreoObservabilityPlugin.provide(
|
|
74
|
+
createRoutableExtension({
|
|
75
|
+
name: "ObservabilityProjectRuntimeLogs",
|
|
76
|
+
component: () => import('./components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js').then((m) => m.ObservabilityProjectRuntimeLogsPage),
|
|
77
|
+
mountPoint: rootRouteRef
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
const ObservabilityAlerts = openchoreoObservabilityPlugin.provide(
|
|
81
|
+
createRoutableExtension({
|
|
82
|
+
name: "ObservabilityAlerts",
|
|
83
|
+
component: () => import('./components/Alerts/ObservabilityAlertsPage.esm.js').then(
|
|
84
|
+
(m) => m.ObservabilityAlertsPage
|
|
85
|
+
),
|
|
86
|
+
mountPoint: rootRouteRef
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
const ObservabilityProjectIncidents = openchoreoObservabilityPlugin.provide(
|
|
90
|
+
createRoutableExtension({
|
|
91
|
+
name: "ObservabilityProjectIncidents",
|
|
92
|
+
component: () => import('./components/Incidents/ObservabilityProjectIncidentsPage.esm.js').then(
|
|
93
|
+
(m) => m.ObservabilityProjectIncidentsPage
|
|
94
|
+
),
|
|
95
|
+
mountPoint: rootRouteRef
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
const ObservabilityCostAnalysis = openchoreoObservabilityPlugin.provide(
|
|
99
|
+
createRoutableExtension({
|
|
100
|
+
name: "ObservabilityCostAnalysis",
|
|
101
|
+
component: () => import('./components/CostAnalysis/index.esm.js').then((m) => m.CostAnalysisPage),
|
|
102
|
+
mountPoint: rootRouteRef
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
export { ObservabilityAlerts, ObservabilityCostAnalysis, ObservabilityMetrics, ObservabilityProjectIncidents, ObservabilityProjectRuntimeLogs, ObservabilityRCA, ObservabilityRuntimeLogs, ObservabilityTraces, openchoreoObservabilityPlugin };
|
|
107
|
+
//# sourceMappingURL=plugin.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createPlugin,\n createRoutableExtension,\n createApiFactory,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport {\n observabilityApiRef,\n ObservabilityClient,\n} from './api/ObservabilityApi';\nimport { rcaAgentApiRef, RCAAgentClient } from './api/RCAAgentApi';\nimport { finopsAgentApiRef, FinOpsAgentClient } from './api/FinOpsAgentApi';\n\nexport const openchoreoObservabilityPlugin = createPlugin({\n id: 'openchoreo-observability',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: observabilityApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new ObservabilityClient({ discoveryApi, fetchApi }),\n }),\n createApiFactory({\n api: rcaAgentApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new RCAAgentClient({ discoveryApi, fetchApi }),\n }),\n createApiFactory({\n api: finopsAgentApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new FinOpsAgentClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\nexport const ObservabilityMetrics = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityMetrics',\n component: () =>\n import('./components/Metrics/ObservabilityMetricsPage').then(\n m => m.ObservabilityMetricsPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ObservabilityTraces = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityTraces',\n component: () =>\n import('./components/Traces/ObservabilityTracesPage').then(\n m => m.ObservabilityTracesPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ObservabilityRCA = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityRCA',\n component: () => import('./components/RCA/RCAPage').then(m => m.RCAPage),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ObservabilityRuntimeLogs = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityRuntimeLogs',\n component: () =>\n import('./components/RuntimeLogs/ObservabilityRuntimeLogsPage').then(\n m => m.ObservabilityRuntimeLogsPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ObservabilityProjectRuntimeLogs =\n openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityProjectRuntimeLogs',\n component: () =>\n import(\n './components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage'\n ).then(m => m.ObservabilityProjectRuntimeLogsPage),\n mountPoint: rootRouteRef,\n }),\n );\n\nexport const ObservabilityAlerts = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityAlerts',\n component: () =>\n import('./components/Alerts/ObservabilityAlertsPage').then(\n m => m.ObservabilityAlertsPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ObservabilityProjectIncidents =\n openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityProjectIncidents',\n component: () =>\n import('./components/Incidents/ObservabilityProjectIncidentsPage').then(\n m => m.ObservabilityProjectIncidentsPage,\n ),\n mountPoint: rootRouteRef,\n }),\n );\n\nexport const ObservabilityCostAnalysis = openchoreoObservabilityPlugin.provide(\n createRoutableExtension({\n name: 'ObservabilityCostAnalysis',\n component: () =>\n import('./components/CostAnalysis').then(m => m.CostAnalysisPage),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'openchoreo-observability',\n});\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA,CAAe;AAAA,EACzC,EAAA,EAAI;AACN,CAAC;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const TIME_RANGE_OPTIONS = [
|
|
2
|
+
{ value: "10m", label: "Last 10 minutes" },
|
|
3
|
+
{ value: "30m", label: "Last 30 minutes" },
|
|
4
|
+
{ value: "1h", label: "Last 1 hour" },
|
|
5
|
+
{ value: "24h", label: "Last 24 hours" },
|
|
6
|
+
{ value: "7d", label: "Last 7 days" },
|
|
7
|
+
{ value: "14d", label: "Last 14 days" },
|
|
8
|
+
{ value: "30d", label: "Last 30 days" },
|
|
9
|
+
{ value: "custom", label: "Custom range" }
|
|
10
|
+
];
|
|
11
|
+
const RCA_STATUS_OPTIONS = [
|
|
12
|
+
{ value: "completed", label: "Completed" },
|
|
13
|
+
{ value: "pending", label: "Pending" },
|
|
14
|
+
{ value: "failed", label: "Failed" }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export { RCA_STATUS_OPTIONS, TIME_RANGE_OPTIONS };
|
|
18
|
+
//# sourceMappingURL=types.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["import type {\n ObservabilityComponents,\n AIRCAAgentComponents,\n} from '@openchoreo/backstage-plugin-common';\n\n// Use generated types from OpenAPI spec\nexport type MetricsTimeSeriesItem =\n ObservabilityComponents['schemas']['MetricsTimeSeriesItem'];\n\nexport type CpuUsageMetrics = {\n cpuUsage: MetricsTimeSeriesItem[];\n cpuRequests: MetricsTimeSeriesItem[];\n cpuLimits: MetricsTimeSeriesItem[];\n};\n\nexport type MemoryUsageMetrics = {\n memoryUsage: MetricsTimeSeriesItem[];\n memoryRequests: MetricsTimeSeriesItem[];\n memoryLimits: MetricsTimeSeriesItem[];\n};\n\nexport type NetworkThroughputMetrics = {\n requestCount: MetricsTimeSeriesItem[];\n successfulRequestCount: MetricsTimeSeriesItem[];\n unsuccessfulRequestCount: MetricsTimeSeriesItem[];\n};\n\nexport type NetworkLatencyMetrics = {\n meanLatency: MetricsTimeSeriesItem[];\n latencyP50: MetricsTimeSeriesItem[];\n latencyP90: MetricsTimeSeriesItem[];\n latencyP99: MetricsTimeSeriesItem[];\n};\n\nexport type ResourceMetrics = {\n cpuUsage: CpuUsageMetrics;\n memoryUsage: MemoryUsageMetrics;\n};\n\nexport type HttpMetrics = {\n networkThroughput: NetworkThroughputMetrics;\n networkLatency: NetworkLatencyMetrics;\n};\n\nexport type MetricType = 'resource' | 'http';\n\nexport interface Span {\n spanId: string;\n spanName: string;\n spanKind?: string;\n startTime: string;\n endTime: string;\n durationNs: number;\n parentSpanId?: string;\n status?: 'ok' | 'error' | 'unset';\n}\n\nexport interface SpanDetails extends Span {\n attributes?: Record<string, unknown>;\n resourceAttributes?: Record<string, unknown>;\n}\n\nexport interface Trace {\n traceId: string;\n traceName?: string;\n spanCount: number;\n rootSpanId?: string;\n rootSpanName?: string;\n rootSpanKind?: string;\n startTime: string;\n endTime: string;\n durationNs: number;\n hasErrors?: boolean;\n}\n\nexport interface TimeRangeOption {\n value: string;\n label: string;\n}\n\nexport const TIME_RANGE_OPTIONS: TimeRangeOption[] = [\n { value: '10m', label: 'Last 10 minutes' },\n { value: '30m', label: 'Last 30 minutes' },\n { value: '1h', label: 'Last 1 hour' },\n { value: '24h', label: 'Last 24 hours' },\n { value: '7d', label: 'Last 7 days' },\n { value: '14d', label: 'Last 14 days' },\n { value: '30d', label: 'Last 30 days' },\n { value: 'custom', label: 'Custom range' },\n];\n\nexport interface Filters {\n environment: Environment;\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 searchQuery?: string;\n rcaStatus?: RCAStatus;\n}\n\nexport interface Environment {\n uid?: string;\n name: string;\n namespace: string;\n displayName?: string;\n description?: string;\n organization?: string;\n dataPlaneRef?: { kind?: string; name?: string };\n isProduction: boolean;\n dnsPrefix?: string;\n createdAt: string;\n status?: string;\n}\n\nexport type RCAStatus = 'pending' | 'completed' | 'failed';\n\nexport interface RCAStatusOption {\n value: RCAStatus;\n label: string;\n}\n\nexport const RCA_STATUS_OPTIONS: RCAStatusOption[] = [\n { value: 'completed', label: 'Completed' },\n { value: 'pending', label: 'Pending' },\n { value: 'failed', label: 'Failed' },\n];\n\n// Use generated types from AI RCA Agent API\nexport type RCAReportSummary =\n AIRCAAgentComponents['schemas']['RCAReportSummary'];\nexport type RCAReportDetailed =\n AIRCAAgentComponents['schemas']['RCAReportDetailed'];\n\n// Alerts & Incidents shared types\n\nexport interface AlertSummary {\n timestamp?: string;\n alertId: string;\n alertValue?: string;\n ruleName?: string;\n ruleDescription?: string;\n severity?: 'info' | 'warning' | 'critical';\n sourceType?: 'log' | 'metric';\n sourceQuery?: string;\n sourceMetric?: string;\n projectName?: string;\n componentName?: string;\n environmentName?: string;\n namespaceName?: string;\n notificationChannels?: string[];\n incidentEnabled?: boolean;\n}\n\nexport interface IncidentSummary {\n incidentId: string;\n alertId: string;\n status: 'active' | 'acknowledged' | 'resolved';\n description?: string;\n notes?: string;\n timestamp?: string;\n triggeredAt?: string;\n acknowledgedAt?: string;\n resolvedAt?: string;\n incidentTriggerAiRca?: boolean;\n incidentTriggerAiCostAnalysis?: boolean;\n projectName?: string;\n componentName?: string;\n environmentName?: string;\n namespaceName?: string;\n}\n\n// -- FinOps / Cost Analysis types (from finops-agent OpenAPI spec) --\n\nexport type FinOpsReportStatus = 'pending' | 'completed' | 'failed';\n\nexport interface FinOpsReportSummary {\n reportId: string;\n namespace: string;\n project: string;\n environment?: string | null;\n component?: string | null;\n timestamp: string;\n summary?: string | null;\n status: FinOpsReportStatus;\n}\n\nexport interface FinOpsReportDetailed {\n reportId: string;\n namespace: string;\n project: string;\n environment?: string | null;\n component?: string | null;\n timestamp: string;\n status: FinOpsReportStatus;\n report?: FinOpsReport | null;\n}\n\nexport interface FinOpsReport {\n component: string;\n namespace: string;\n project: string;\n analysis_period: string;\n budgeted_cost: CostBreakdown;\n actual_cost: CostBreakdown;\n resource_metrics: FinOpsResourceMetrics;\n overprovisioning: OverprovisioningAssessment;\n summary: string;\n investigation_path: InvestigationStep[];\n recommended_actions?: FinOpsRemediationAction[];\n}\n\nexport interface CostBreakdown {\n total_cost: number;\n currency: string;\n is_estimated: boolean;\n}\n\nexport interface FinOpsResourceMetrics {\n cpu_request?: string | null;\n cpu_limit?: string | null;\n cpu_actual_avg?: string | null;\n cpu_actual_peak?: string | null;\n memory_request?: string | null;\n memory_limit?: string | null;\n memory_actual_avg?: string | null;\n memory_actual_peak?: string | null;\n data_available?: boolean;\n}\n\nexport interface OverprovisioningAssessment {\n is_overprovisioned: boolean;\n cpu_utilization_pct?: number | null;\n memory_utilization_pct?: number | null;\n analysis: string;\n recommendation?: ResourceRecommendation | null;\n}\n\nexport interface ResourceRecommendation {\n cpu_request: string;\n cpu_limit: string;\n memory_request: string;\n memory_limit: string;\n rationale: string;\n release_binding?: string | null;\n}\n\nexport interface FinOpsFieldChange {\n json_pointer: string;\n value: string | number | boolean;\n}\n\nexport interface FinOpsResourceChange {\n release_binding: string;\n fields: FinOpsFieldChange[];\n}\n\nexport interface FinOpsRemediationAction {\n description: string;\n rationale: string;\n status: 'revised' | 'applied' | 'dismissed';\n change: FinOpsResourceChange | null;\n}\n\nexport interface InvestigationStep {\n action: string;\n outcome: string;\n rationale?: string | null;\n}\n"],"names":[],"mappings":"AAgFO,MAAM,kBAAA,GAAwC;AAAA,EACnD,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,EACzC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,EACzC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,aAAA,EAAc;AAAA,EACpC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,eAAA,EAAgB;AAAA,EACvC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,aAAA,EAAc;AAAA,EACpC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,cAAA,EAAe;AAAA,EACtC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,cAAA,EAAe;AAAA,EACtC,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,cAAA;AAC5B;AAmCO,MAAM,kBAAA,GAAwC;AAAA,EACnD,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,WAAA,EAAY;AAAA,EACzC,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,SAAA,EAAU;AAAA,EACrC,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,QAAA;AAC5B;;;;"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const ALLOWED_OVERRIDE_CATEGORIES = /* @__PURE__ */ new Set([
|
|
2
|
+
"workloadOverrides",
|
|
3
|
+
"traitEnvironmentConfigs",
|
|
4
|
+
"componentTypeEnvironmentConfigs"
|
|
5
|
+
]);
|
|
6
|
+
function applyJsonPointer(doc, pointer, value) {
|
|
7
|
+
const keys = pointer.replace(/^\//, "").split("/");
|
|
8
|
+
if (keys.length < 3 || keys[0] !== "spec" || !ALLOWED_OVERRIDE_CATEGORIES.has(keys[1])) {
|
|
9
|
+
throw new Error(`Invalid pointer: '${pointer}'`);
|
|
10
|
+
}
|
|
11
|
+
let current = doc;
|
|
12
|
+
for (const key of keys.slice(0, -1)) {
|
|
13
|
+
if (current[key] === null || current[key] === void 0 || typeof current[key] !== "object") {
|
|
14
|
+
current[key] = {};
|
|
15
|
+
}
|
|
16
|
+
current = current[key];
|
|
17
|
+
}
|
|
18
|
+
const last = keys.at(-1);
|
|
19
|
+
current[last] = value;
|
|
20
|
+
}
|
|
21
|
+
function applyEnvChange(doc, key, value) {
|
|
22
|
+
const env = doc.spec?.workloadOverrides?.container?.env ?? [];
|
|
23
|
+
const existing = env.find((e) => e.key === key);
|
|
24
|
+
if (existing) {
|
|
25
|
+
existing.value = value;
|
|
26
|
+
} else {
|
|
27
|
+
env.push({ key, value });
|
|
28
|
+
doc.spec ??= {};
|
|
29
|
+
doc.spec.workloadOverrides ??= {};
|
|
30
|
+
doc.spec.workloadOverrides.container ??= {};
|
|
31
|
+
doc.spec.workloadOverrides.container.env = env;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function applyFileChange(doc, key, mountPath, value) {
|
|
35
|
+
const files = doc.spec?.workloadOverrides?.container?.files ?? [];
|
|
36
|
+
const existing = files.find((f) => f.key === key && f.mountPath === mountPath);
|
|
37
|
+
if (existing) {
|
|
38
|
+
existing.value = value;
|
|
39
|
+
} else {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`File mount '${key}' at '${mountPath}' not found in binding`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function applyResourceChange(opts) {
|
|
46
|
+
const { backendBaseUrl, fetchApi, namespaceName, change } = opts;
|
|
47
|
+
const bindingUrl = `${backendBaseUrl}/release-binding?namespaceName=${encodeURIComponent(
|
|
48
|
+
namespaceName
|
|
49
|
+
)}&bindingName=${encodeURIComponent(change.release_binding)}`;
|
|
50
|
+
const getResponse = await fetchApi.fetch(bindingUrl);
|
|
51
|
+
if (!getResponse.ok) {
|
|
52
|
+
const detail = getResponse.status === 404 ? `Release binding '${change.release_binding}' not found` : `Failed to get release binding: ${getResponse.statusText}`;
|
|
53
|
+
throw new Error(detail);
|
|
54
|
+
}
|
|
55
|
+
const binding = await getResponse.json();
|
|
56
|
+
const updated = structuredClone(binding);
|
|
57
|
+
for (const e of change.env ?? []) {
|
|
58
|
+
applyEnvChange(updated, e.key, e.value);
|
|
59
|
+
}
|
|
60
|
+
for (const f of change.files ?? []) {
|
|
61
|
+
applyFileChange(updated, f.key, f.mount_path, f.value);
|
|
62
|
+
}
|
|
63
|
+
for (const f of change.fields ?? []) {
|
|
64
|
+
applyJsonPointer(updated, f.json_pointer, f.value);
|
|
65
|
+
}
|
|
66
|
+
const putResponse = await fetchApi.fetch(bindingUrl, {
|
|
67
|
+
method: "PUT",
|
|
68
|
+
body: JSON.stringify({ metadata: updated.metadata, spec: updated.spec }),
|
|
69
|
+
headers: { "Content-Type": "application/json" }
|
|
70
|
+
});
|
|
71
|
+
if (!putResponse.ok) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Failed to update release binding: ${putResponse.statusText}`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { applyEnvChange, applyFileChange, applyJsonPointer, applyResourceChange };
|
|
79
|
+
//# sourceMappingURL=applyResourceChange.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyResourceChange.esm.js","sources":["../../src/utils/applyResourceChange.ts"],"sourcesContent":["import type { FetchApi } from '@backstage/core-plugin-api';\n\ntype PrimitiveValue = string | number | boolean;\n\nexport interface FieldChangeDef {\n json_pointer: string;\n value: PrimitiveValue;\n}\n\nexport interface ResourceChangeDef {\n release_binding: string;\n fields?: FieldChangeDef[];\n env?: Array<{ key: string; value: string }>;\n files?: Array<{ key: string; mount_path: string; value: string }>;\n}\n\nconst ALLOWED_OVERRIDE_CATEGORIES = new Set([\n 'workloadOverrides',\n 'traitEnvironmentConfigs',\n 'componentTypeEnvironmentConfigs',\n]);\n\nexport function applyJsonPointer(doc: any, pointer: string, value: any): void {\n const keys = pointer.replace(/^\\//, '').split('/');\n if (\n keys.length < 3 ||\n keys[0] !== 'spec' ||\n !ALLOWED_OVERRIDE_CATEGORIES.has(keys[1])\n ) {\n throw new Error(`Invalid pointer: '${pointer}'`);\n }\n let current = doc;\n for (const key of keys.slice(0, -1)) {\n if (\n current[key] === null ||\n current[key] === undefined ||\n typeof current[key] !== 'object'\n ) {\n current[key] = {};\n }\n current = current[key];\n }\n const last = keys.at(-1)!;\n current[last] = value;\n}\n\nexport function applyEnvChange(doc: any, key: string, value: string): void {\n const env: { key: string; value: string }[] =\n doc.spec?.workloadOverrides?.container?.env ?? [];\n const existing = env.find(e => e.key === key);\n if (existing) {\n existing.value = value;\n } else {\n env.push({ key, value });\n doc.spec ??= {};\n doc.spec.workloadOverrides ??= {};\n doc.spec.workloadOverrides.container ??= {};\n doc.spec.workloadOverrides.container.env = env;\n }\n}\n\nexport function applyFileChange(\n doc: any,\n key: string,\n mountPath: string,\n value: string,\n): void {\n const files: { key: string; value: string; mountPath: string }[] =\n doc.spec?.workloadOverrides?.container?.files ?? [];\n const existing = files.find(f => f.key === key && f.mountPath === mountPath);\n if (existing) {\n existing.value = value;\n } else {\n throw new Error(\n `File mount '${key}' at '${mountPath}' not found in binding`,\n );\n }\n}\n\n/**\n * GET a release binding, apply the given changes, and PUT it back.\n * Used by the finops apply button for deterministic field-only patches\n * (no user-editable overrides).\n */\nexport async function applyResourceChange(opts: {\n backendBaseUrl: string;\n fetchApi: FetchApi;\n namespaceName: string;\n change: ResourceChangeDef;\n}): Promise<void> {\n const { backendBaseUrl, fetchApi, namespaceName, change } = opts;\n\n const bindingUrl = `${backendBaseUrl}/release-binding?namespaceName=${encodeURIComponent(\n namespaceName,\n )}&bindingName=${encodeURIComponent(change.release_binding)}`;\n\n const getResponse = await fetchApi.fetch(bindingUrl);\n if (!getResponse.ok) {\n const detail =\n getResponse.status === 404\n ? `Release binding '${change.release_binding}' not found`\n : `Failed to get release binding: ${getResponse.statusText}`;\n throw new Error(detail);\n }\n\n const binding = await getResponse.json();\n const updated = structuredClone(binding);\n\n for (const e of change.env ?? []) {\n applyEnvChange(updated, e.key, e.value);\n }\n for (const f of change.files ?? []) {\n applyFileChange(updated, f.key, f.mount_path, f.value);\n }\n for (const f of change.fields ?? []) {\n applyJsonPointer(updated, f.json_pointer, f.value);\n }\n\n const putResponse = await fetchApi.fetch(bindingUrl, {\n method: 'PUT',\n body: JSON.stringify({ metadata: updated.metadata, spec: updated.spec }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!putResponse.ok) {\n throw new Error(\n `Failed to update release binding: ${putResponse.statusText}`,\n );\n }\n}\n"],"names":[],"mappings":"AAgBA,MAAM,2BAAA,uBAAkC,GAAA,CAAI;AAAA,EAC1C,mBAAA;AAAA,EACA,yBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEM,SAAS,gBAAA,CAAiB,GAAA,EAAU,OAAA,EAAiB,KAAA,EAAkB;AAC5E,EAAA,MAAM,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA,CAAE,MAAM,GAAG,CAAA;AACjD,EAAA,IACE,IAAA,CAAK,MAAA,GAAS,CAAA,IACd,IAAA,CAAK,CAAC,CAAA,KAAM,MAAA,IACZ,CAAC,2BAAA,CAA4B,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,EACxC;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,GAAU,GAAA;AACd,EAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAG;AACnC,IAAA,IACE,OAAA,CAAQ,GAAG,CAAA,KAAM,IAAA,IACjB,OAAA,CAAQ,GAAG,CAAA,KAAM,MAAA,IACjB,OAAO,OAAA,CAAQ,GAAG,CAAA,KAAM,QAAA,EACxB;AACA,MAAA,OAAA,CAAQ,GAAG,IAAI,EAAC;AAAA,IAClB;AACA,IAAA,OAAA,GAAU,QAAQ,GAAG,CAAA;AAAA,EACvB;AACA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA;AACvB,EAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,KAAA;AAClB;AAEO,SAAS,cAAA,CAAe,GAAA,EAAU,GAAA,EAAa,KAAA,EAAqB;AACzE,EAAA,MAAM,MACJ,GAAA,CAAI,IAAA,EAAM,iBAAA,EAAmB,SAAA,EAAW,OAAO,EAAC;AAClD,EAAA,MAAM,WAAW,GAAA,CAAI,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,QAAQ,GAAG,CAAA;AAC5C,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,KAAA,GAAQ,KAAA;AAAA,EACnB,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,GAAA,EAAK,KAAA,EAAO,CAAA;AACvB,IAAA,GAAA,CAAI,SAAS,EAAC;AACd,IAAA,GAAA,CAAI,IAAA,CAAK,sBAAsB,EAAC;AAChC,IAAA,GAAA,CAAI,IAAA,CAAK,iBAAA,CAAkB,SAAA,KAAc,EAAC;AAC1C,IAAA,GAAA,CAAI,IAAA,CAAK,iBAAA,CAAkB,SAAA,CAAU,GAAA,GAAM,GAAA;AAAA,EAC7C;AACF;AAEO,SAAS,eAAA,CACd,GAAA,EACA,GAAA,EACA,SAAA,EACA,KAAA,EACM;AACN,EAAA,MAAM,QACJ,GAAA,CAAI,IAAA,EAAM,iBAAA,EAAmB,SAAA,EAAW,SAAS,EAAC;AACpD,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,SAAA,KAAc,SAAS,CAAA;AAC3E,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,KAAA,GAAQ,KAAA;AAAA,EACnB,CAAA,MAAO;AACL,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,YAAA,EAAe,GAAG,CAAA,MAAA,EAAS,SAAS,CAAA,sBAAA;AAAA,KACtC;AAAA,EACF;AACF;AAOA,eAAsB,oBAAoB,IAAA,EAKxB;AAChB,EAAA,MAAM,EAAE,cAAA,EAAgB,QAAA,EAAU,aAAA,EAAe,QAAO,GAAI,IAAA;AAE5D,EAAA,MAAM,UAAA,GAAa,CAAA,EAAG,cAAc,CAAA,+BAAA,EAAkC,kBAAA;AAAA,IACpE;AAAA,GACD,CAAA,aAAA,EAAgB,kBAAA,CAAmB,MAAA,CAAO,eAAe,CAAC,CAAA,CAAA;AAE3D,EAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA;AACnD,EAAA,IAAI,CAAC,YAAY,EAAA,EAAI;AACnB,IAAA,MAAM,MAAA,GACJ,WAAA,CAAY,MAAA,KAAW,GAAA,GACnB,CAAA,iBAAA,EAAoB,OAAO,eAAe,CAAA,WAAA,CAAA,GAC1C,CAAA,+BAAA,EAAkC,WAAA,CAAY,UAAU,CAAA,CAAA;AAC9D,IAAA,MAAM,IAAI,MAAM,MAAM,CAAA;AAAA,EACxB;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,IAAA,EAAK;AACvC,EAAA,MAAM,OAAA,GAAU,gBAAgB,OAAO,CAAA;AAEvC,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,GAAA,IAAO,EAAC,EAAG;AAChC,IAAA,cAAA,CAAe,OAAA,EAAS,CAAA,CAAE,GAAA,EAAK,CAAA,CAAE,KAAK,CAAA;AAAA,EACxC;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,KAAA,IAAS,EAAC,EAAG;AAClC,IAAA,eAAA,CAAgB,SAAS,CAAA,CAAE,GAAA,EAAK,CAAA,CAAE,UAAA,EAAY,EAAE,KAAK,CAAA;AAAA,EACvD;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG;AACnC,IAAA,gBAAA,CAAiB,OAAA,EAAS,CAAA,CAAE,YAAA,EAAc,CAAA,CAAE,KAAK,CAAA;AAAA,EACnD;AAEA,EAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,KAAA,CAAM,UAAA,EAAY;AAAA,IACnD,MAAA,EAAQ,KAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,QAAA,EAAU,QAAQ,QAAA,EAAU,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAM,CAAA;AAAA,IACvE,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,GAC/C,CAAA;AAED,EAAA,IAAI,CAAC,YAAY,EAAA,EAAI;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kCAAA,EAAqC,YAAY,UAAU,CAAA;AAAA,KAC7D;AAAA,EACF;AACF;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { TIME_RANGE_OPTIONS } from '../types.esm.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_TIME_RANGE = "10m";
|
|
4
|
+
const VALID_TIME_RANGES = new Set(TIME_RANGE_OPTIONS.map((o) => o.value));
|
|
5
|
+
const isValidIso = (value) => !!value && !Number.isNaN(new Date(value).getTime());
|
|
6
|
+
function parseUrlTimeRange(searchParams) {
|
|
7
|
+
const raw = searchParams.get("timeRange") || DEFAULT_TIME_RANGE;
|
|
8
|
+
let timeRange = VALID_TIME_RANGES.has(raw) ? raw : DEFAULT_TIME_RANGE;
|
|
9
|
+
let customStartTime;
|
|
10
|
+
let customEndTime;
|
|
11
|
+
if (timeRange === "custom") {
|
|
12
|
+
const from = searchParams.get("from");
|
|
13
|
+
const to = searchParams.get("to");
|
|
14
|
+
if (isValidIso(from) && isValidIso(to)) {
|
|
15
|
+
customStartTime = from;
|
|
16
|
+
customEndTime = to;
|
|
17
|
+
} else {
|
|
18
|
+
timeRange = DEFAULT_TIME_RANGE;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { timeRange, customStartTime, customEndTime };
|
|
22
|
+
}
|
|
23
|
+
function writeUrlTimeRange(params, next) {
|
|
24
|
+
if (next.timeRange !== void 0) {
|
|
25
|
+
if (next.timeRange === DEFAULT_TIME_RANGE) {
|
|
26
|
+
params.delete("timeRange");
|
|
27
|
+
} else {
|
|
28
|
+
params.set("timeRange", next.timeRange);
|
|
29
|
+
}
|
|
30
|
+
if (next.timeRange !== "custom") {
|
|
31
|
+
params.delete("from");
|
|
32
|
+
params.delete("to");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (next.customStartTime !== void 0) {
|
|
36
|
+
if (next.customStartTime) {
|
|
37
|
+
params.set("from", next.customStartTime);
|
|
38
|
+
} else {
|
|
39
|
+
params.delete("from");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (next.customEndTime !== void 0) {
|
|
43
|
+
if (next.customEndTime) {
|
|
44
|
+
params.set("to", next.customEndTime);
|
|
45
|
+
} else {
|
|
46
|
+
params.delete("to");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { parseUrlTimeRange, writeUrlTimeRange };
|
|
52
|
+
//# sourceMappingURL=urlTimeRange.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlTimeRange.esm.js","sources":["../../src/utils/urlTimeRange.ts"],"sourcesContent":["import { TIME_RANGE_OPTIONS } from '../types';\n\nconst DEFAULT_TIME_RANGE = '10m';\nconst VALID_TIME_RANGES = new Set(TIME_RANGE_OPTIONS.map(o => o.value));\n\nconst isValidIso = (value: string | null): value is string =>\n !!value && !Number.isNaN(new Date(value).getTime());\n\nexport interface UrlTimeRange {\n timeRange: string;\n customStartTime?: string;\n customEndTime?: string;\n}\n\n/**\n * Parse `timeRange` + `from`/`to` query params with validation.\n * If `timeRange === 'custom'` but `from`/`to` are missing or unparseable,\n * falls back to the default preset.\n */\nexport function parseUrlTimeRange(searchParams: URLSearchParams): UrlTimeRange {\n const raw = searchParams.get('timeRange') || DEFAULT_TIME_RANGE;\n let timeRange = VALID_TIME_RANGES.has(raw) ? raw : DEFAULT_TIME_RANGE;\n let customStartTime: string | undefined;\n let customEndTime: string | undefined;\n if (timeRange === 'custom') {\n const from = searchParams.get('from');\n const to = searchParams.get('to');\n if (isValidIso(from) && isValidIso(to)) {\n customStartTime = from;\n customEndTime = to;\n } else {\n timeRange = DEFAULT_TIME_RANGE;\n }\n }\n return { timeRange, customStartTime, customEndTime };\n}\n\n/**\n * Apply a partial time-range update to a URLSearchParams instance in place.\n * Switching away from `custom` clears stale `from`/`to`. Default preset is\n * elided from the URL so it stays clean.\n */\nexport function writeUrlTimeRange(\n params: URLSearchParams,\n next: Partial<UrlTimeRange>,\n): void {\n if (next.timeRange !== undefined) {\n if (next.timeRange === DEFAULT_TIME_RANGE) {\n params.delete('timeRange');\n } else {\n params.set('timeRange', next.timeRange);\n }\n if (next.timeRange !== 'custom') {\n params.delete('from');\n params.delete('to');\n }\n }\n if (next.customStartTime !== undefined) {\n if (next.customStartTime) {\n params.set('from', next.customStartTime);\n } else {\n params.delete('from');\n }\n }\n if (next.customEndTime !== undefined) {\n if (next.customEndTime) {\n params.set('to', next.customEndTime);\n } else {\n params.delete('to');\n }\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kBAAA,GAAqB,KAAA;AAC3B,MAAM,iBAAA,GAAoB,IAAI,GAAA,CAAI,kBAAA,CAAmB,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA;AAEtE,MAAM,UAAA,GAAa,CAAC,KAAA,KAClB,CAAC,CAAC,KAAA,IAAS,CAAC,MAAA,CAAO,KAAA,CAAM,IAAI,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA;AAa7C,SAAS,kBAAkB,YAAA,EAA6C;AAC7E,EAAA,MAAM,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,WAAW,CAAA,IAAK,kBAAA;AAC7C,EAAA,IAAI,SAAA,GAAY,iBAAA,CAAkB,GAAA,CAAI,GAAG,IAAI,GAAA,GAAM,kBAAA;AACnD,EAAA,IAAI,eAAA;AACJ,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACpC,IAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAChC,IAAA,IAAI,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,EAAE,CAAA,EAAG;AACtC,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,aAAA,GAAgB,EAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,SAAA,GAAY,kBAAA;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO,EAAE,SAAA,EAAW,eAAA,EAAiB,aAAA,EAAc;AACrD;AAOO,SAAS,iBAAA,CACd,QACA,IAAA,EACM;AACN,EAAA,IAAI,IAAA,CAAK,cAAc,MAAA,EAAW;AAChC,IAAA,IAAI,IAAA,CAAK,cAAc,kBAAA,EAAoB;AACzC,MAAA,MAAA,CAAO,OAAO,WAAW,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,SAAS,CAAA;AAAA,IACxC;AACA,IAAA,IAAI,IAAA,CAAK,cAAc,QAAA,EAAU;AAC/B,MAAA,MAAA,CAAO,OAAO,MAAM,CAAA;AACpB,MAAA,MAAA,CAAO,OAAO,IAAI,CAAA;AAAA,IACpB;AAAA,EACF;AACA,EAAA,IAAI,IAAA,CAAK,oBAAoB,MAAA,EAAW;AACtC,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,IAAA,CAAK,eAAe,CAAA;AAAA,IACzC,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,IAAI,IAAA,CAAK,kBAAkB,MAAA,EAAW;AACpC,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,IAAA,CAAK,aAAa,CAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,OAAO,IAAI,CAAA;AAAA,IACpB;AAAA,EACF;AACF;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openchoreo/backstage-plugin-openchoreo-observability",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"main": "dist/index.esm.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/openchoreo/backstage-plugins.git",
|
|
15
|
+
"directory": "plugins/openchoreo-observability"
|
|
16
|
+
},
|
|
17
|
+
"backstage": {
|
|
18
|
+
"role": "frontend-plugin",
|
|
19
|
+
"pluginId": "openchoreo-observability",
|
|
20
|
+
"pluginPackages": [
|
|
21
|
+
"@openchoreo/backstage-plugin-openchoreo-observability"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"scripts": {
|
|
26
|
+
"start": "backstage-cli package start",
|
|
27
|
+
"build": "backstage-cli package build",
|
|
28
|
+
"lint": "backstage-cli package lint",
|
|
29
|
+
"test": "backstage-cli package test",
|
|
30
|
+
"clean": "backstage-cli package clean",
|
|
31
|
+
"prepack": "backstage-cli package prepack",
|
|
32
|
+
"postpack": "backstage-cli package postpack"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@backstage/catalog-model": "^1.7.5",
|
|
36
|
+
"@backstage/core-components": "^0.18.1",
|
|
37
|
+
"@backstage/core-plugin-api": "^1.11.0",
|
|
38
|
+
"@backstage/plugin-catalog-react": "^1.21.2",
|
|
39
|
+
"@backstage/theme": "^0.6.8",
|
|
40
|
+
"@date-io/date-fns": "1.3.13",
|
|
41
|
+
"@material-ui/core": "4.12.4",
|
|
42
|
+
"@material-ui/icons": "4.11.3",
|
|
43
|
+
"@material-ui/lab": "4.0.0-alpha.61",
|
|
44
|
+
"@material-ui/pickers": "3.3.11",
|
|
45
|
+
"@openchoreo/backstage-design-system": "^1.1.0",
|
|
46
|
+
"@openchoreo/backstage-plugin-common": "^1.1.0",
|
|
47
|
+
"@openchoreo/backstage-plugin-react": "^1.1.0",
|
|
48
|
+
"date-fns": "2.30.0",
|
|
49
|
+
"react-markdown": "^9.0.1",
|
|
50
|
+
"react-use": "17.6.0",
|
|
51
|
+
"recharts": "3.4.1",
|
|
52
|
+
"remark-gfm": "^4.0.1",
|
|
53
|
+
"remend": "^1.0.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"react": "^18.0.0",
|
|
57
|
+
"react-router-dom": "^6.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@backstage/cli": "^0.34.3",
|
|
61
|
+
"@backstage/core-app-api": "^1.19.0",
|
|
62
|
+
"@backstage/dev-utils": "^1.1.14",
|
|
63
|
+
"@backstage/test-utils": "^1.7.11",
|
|
64
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
65
|
+
"@testing-library/react": "14.3.1",
|
|
66
|
+
"@testing-library/user-event": "14.6.1",
|
|
67
|
+
"msw": "1.3.5",
|
|
68
|
+
"react": "18.3.1"
|
|
69
|
+
},
|
|
70
|
+
"files": [
|
|
71
|
+
"dist"
|
|
72
|
+
],
|
|
73
|
+
"typesVersions": {
|
|
74
|
+
"*": {
|
|
75
|
+
"package.json": [
|
|
76
|
+
"package.json"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"module": "./dist/index.esm.js"
|
|
81
|
+
}
|