@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,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,8 @@
1
+ import { createRouteRef } from '@backstage/core-plugin-api';
2
+
3
+ const rootRouteRef = createRouteRef({
4
+ id: "openchoreo-observability"
5
+ });
6
+
7
+ export { rootRouteRef };
8
+ //# sourceMappingURL=routes.esm.js.map
@@ -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":"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"}
@@ -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
+ }