@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,200 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Grid, TextField, FormControl, InputLabel, Select, MenuItem, Checkbox, Divider } from '@material-ui/core';
3
+ import { Skeleton } from '@material-ui/lab';
4
+ import { useDebouncedSearch } from '../../hooks/useDebouncedSearch.esm.js';
5
+ import { TimeRangeFilter } from '../TimeRangeFilter/TimeRangeFilter.esm.js';
6
+ import { SELECTED_FIELDS, LogEntryField, LOG_LEVELS } from './types.esm.js';
7
+
8
+ const LogsFilter = ({
9
+ filters,
10
+ onFiltersChange,
11
+ environments,
12
+ environmentsLoading,
13
+ components = [],
14
+ componentsLoading = false,
15
+ disabled = false
16
+ }) => {
17
+ const [searchInput, handleSearchChange] = useDebouncedSearch(
18
+ filters.searchQuery,
19
+ (value) => onFiltersChange({ searchQuery: value })
20
+ );
21
+ const handleEnvironmentChange = (event) => {
22
+ onFiltersChange({ environment: event.target.value });
23
+ };
24
+ const handleComponentChange = (event) => {
25
+ onFiltersChange({ components: event.target.value });
26
+ };
27
+ const handleLogLevelSelectChange = (event) => {
28
+ const value = event.target.value;
29
+ if (value.includes("ALL")) return;
30
+ onFiltersChange({ logLevel: value });
31
+ };
32
+ const handleAllLogLevelsToggle = () => {
33
+ if (filters.logLevel.length === LOG_LEVELS.length) {
34
+ onFiltersChange({ logLevel: [] });
35
+ } else {
36
+ onFiltersChange({ logLevel: [...LOG_LEVELS] });
37
+ }
38
+ };
39
+ const handleSelectedFieldsChange = (event) => {
40
+ let selectedFields = event.target.value;
41
+ if (!selectedFields.includes(LogEntryField.Log)) {
42
+ selectedFields = [...selectedFields, LogEntryField.Log];
43
+ }
44
+ onFiltersChange({
45
+ selectedFields: SELECTED_FIELDS.filter(
46
+ (field) => selectedFields.includes(field)
47
+ )
48
+ });
49
+ };
50
+ return /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
51
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 4, children: /* @__PURE__ */ jsx(
52
+ TextField,
53
+ {
54
+ fullWidth: true,
55
+ placeholder: "Search Logs...",
56
+ variant: "outlined",
57
+ value: searchInput,
58
+ onChange: handleSearchChange,
59
+ disabled
60
+ }
61
+ ) }),
62
+ components.length > 0 && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(
63
+ FormControl,
64
+ {
65
+ fullWidth: true,
66
+ disabled: disabled || componentsLoading,
67
+ variant: "outlined",
68
+ children: [
69
+ /* @__PURE__ */ jsx(InputLabel, { id: "components-label", children: "Components" }),
70
+ componentsLoading ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 56 }) : /* @__PURE__ */ jsx(
71
+ Select,
72
+ {
73
+ multiple: true,
74
+ value: filters.components || [],
75
+ onChange: handleComponentChange,
76
+ labelId: "components-label",
77
+ label: "Components",
78
+ renderValue: (selected) => {
79
+ const selectedArray = selected;
80
+ if (selectedArray.length === 0) return "All";
81
+ return selectedArray.join(", ");
82
+ },
83
+ children: components.map((component) => /* @__PURE__ */ jsxs(MenuItem, { value: component.name, children: [
84
+ /* @__PURE__ */ jsx(
85
+ Checkbox,
86
+ {
87
+ checked: (filters.components || []).indexOf(component.name) > -1
88
+ }
89
+ ),
90
+ component.displayName || component.name
91
+ ] }, component.name))
92
+ }
93
+ )
94
+ ]
95
+ }
96
+ ) }),
97
+ !components.length && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(FormControl, { fullWidth: true, disabled, variant: "outlined", children: [
98
+ /* @__PURE__ */ jsx(InputLabel, { id: "selected-fields-label", children: "Selected Fields" }),
99
+ /* @__PURE__ */ jsx(
100
+ Select,
101
+ {
102
+ multiple: true,
103
+ value: filters.selectedFields,
104
+ onChange: handleSelectedFieldsChange,
105
+ labelId: "selected-fields-label",
106
+ label: "Selected Fields",
107
+ renderValue: (selected) => selected.join(", "),
108
+ children: SELECTED_FIELDS.map((field) => /* @__PURE__ */ jsxs(
109
+ MenuItem,
110
+ {
111
+ value: field,
112
+ disabled: field === LogEntryField.Log,
113
+ children: [
114
+ /* @__PURE__ */ jsx(
115
+ Checkbox,
116
+ {
117
+ checked: filters.selectedFields.includes(field),
118
+ disabled: field === LogEntryField.Log
119
+ }
120
+ ),
121
+ field
122
+ ]
123
+ },
124
+ field
125
+ ))
126
+ }
127
+ )
128
+ ] }) }),
129
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(FormControl, { fullWidth: true, disabled, variant: "outlined", children: [
130
+ /* @__PURE__ */ jsx(InputLabel, { id: "log-levels-label", children: "Log Levels" }),
131
+ /* @__PURE__ */ jsxs(
132
+ Select,
133
+ {
134
+ multiple: true,
135
+ value: filters.logLevel,
136
+ onChange: handleLogLevelSelectChange,
137
+ labelId: "log-levels-label",
138
+ label: "Log Levels",
139
+ renderValue: (selected) => {
140
+ const levels = selected;
141
+ if (levels.length === 0) return "None";
142
+ if (levels.length === LOG_LEVELS.length) return "All";
143
+ return levels.join(", ");
144
+ },
145
+ children: [
146
+ /* @__PURE__ */ jsxs(MenuItem, { value: "ALL", onMouseDown: handleAllLogLevelsToggle, children: [
147
+ /* @__PURE__ */ jsx(
148
+ Checkbox,
149
+ {
150
+ checked: filters.logLevel.length === LOG_LEVELS.length,
151
+ indeterminate: filters.logLevel.length > 0 && filters.logLevel.length < LOG_LEVELS.length
152
+ }
153
+ ),
154
+ "All"
155
+ ] }),
156
+ /* @__PURE__ */ jsx(Divider, {}),
157
+ LOG_LEVELS.map((level) => /* @__PURE__ */ jsxs(MenuItem, { value: level, children: [
158
+ /* @__PURE__ */ jsx(Checkbox, { checked: filters.logLevel.includes(level) }),
159
+ level
160
+ ] }, level))
161
+ ]
162
+ }
163
+ )
164
+ ] }) }),
165
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(
166
+ FormControl,
167
+ {
168
+ fullWidth: true,
169
+ disabled: disabled || environmentsLoading,
170
+ variant: "outlined",
171
+ children: [
172
+ /* @__PURE__ */ jsx(InputLabel, { id: "environment-label", children: "Environment" }),
173
+ environmentsLoading ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 56 }) : /* @__PURE__ */ jsx(
174
+ Select,
175
+ {
176
+ value: filters.environment,
177
+ onChange: handleEnvironmentChange,
178
+ labelId: "environment-label",
179
+ label: "Environment",
180
+ children: environments.map((env) => /* @__PURE__ */ jsx(MenuItem, { value: env.name, children: env.displayName || env.name }, env.name))
181
+ }
182
+ )
183
+ ]
184
+ }
185
+ ) }),
186
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsx(
187
+ TimeRangeFilter,
188
+ {
189
+ value: filters.timeRange,
190
+ customStartTime: filters.customStartTime,
191
+ customEndTime: filters.customEndTime,
192
+ onChange: onFiltersChange,
193
+ disabled
194
+ }
195
+ ) })
196
+ ] });
197
+ };
198
+
199
+ export { LogsFilter };
200
+ //# sourceMappingURL=LogsFilter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogsFilter.esm.js","sources":["../../../src/components/RuntimeLogs/LogsFilter.tsx"],"sourcesContent":["import { FC, ChangeEvent } from 'react';\nimport {\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Checkbox,\n Divider,\n Grid,\n TextField,\n} from '@material-ui/core';\nimport { Skeleton } from '@material-ui/lab';\nimport { Component } from '../../hooks/useGetComponentsByProject';\nimport { useDebouncedSearch } from '../../hooks/useDebouncedSearch';\nimport { type Environment } from '../../types';\nimport { TimeRangeFilter } from '../TimeRangeFilter';\nimport {\n RuntimeLogsFilters,\n LOG_LEVELS,\n SELECTED_FIELDS,\n LogEntryField,\n} from './types';\n\ninterface LogsFilterProps {\n filters: RuntimeLogsFilters;\n onFiltersChange: (filters: Partial<RuntimeLogsFilters>) => void;\n environments: Environment[];\n environmentsLoading: boolean;\n components?: Component[];\n componentsLoading?: boolean;\n disabled?: boolean;\n}\n\nexport const LogsFilter: FC<LogsFilterProps> = ({\n filters,\n onFiltersChange,\n environments,\n environmentsLoading,\n components = [],\n componentsLoading = false,\n disabled = false,\n}) => {\n const [searchInput, handleSearchChange] = useDebouncedSearch(\n filters.searchQuery,\n value => onFiltersChange({ searchQuery: value }),\n );\n\n const handleEnvironmentChange = (event: ChangeEvent<{ value: unknown }>) => {\n onFiltersChange({ environment: event.target.value as string });\n };\n\n const handleComponentChange = (event: ChangeEvent<{ value: unknown }>) => {\n onFiltersChange({ components: event.target.value as string[] });\n };\n\n const handleLogLevelSelectChange = (\n event: ChangeEvent<{ value: unknown }>,\n ) => {\n const value = event.target.value as string[];\n // 'ALL' being present means the \"All\" item was clicked — already handled\n // by onMouseDown on that MenuItem, so skip to avoid overwriting it\n if (value.includes('ALL')) return;\n onFiltersChange({ logLevel: value });\n };\n\n const handleAllLogLevelsToggle = () => {\n if (filters.logLevel.length === LOG_LEVELS.length) {\n onFiltersChange({ logLevel: [] });\n } else {\n onFiltersChange({ logLevel: [...LOG_LEVELS] });\n }\n };\n\n const handleSelectedFieldsChange = (\n event: ChangeEvent<{ value: unknown }>,\n ) => {\n let selectedFields = event.target.value as LogEntryField[];\n // Ensure Log field is always included\n if (!selectedFields.includes(LogEntryField.Log)) {\n selectedFields = [...selectedFields, LogEntryField.Log];\n }\n // sort by the order of the SELECTED_FIELDS array\n // Customizing the order of the selected fields is not supported yet\n onFiltersChange({\n selectedFields: SELECTED_FIELDS.filter(field =>\n selectedFields.includes(field),\n ),\n });\n };\n\n return (\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <TextField\n fullWidth\n placeholder=\"Search Logs...\"\n variant=\"outlined\"\n value={searchInput}\n onChange={handleSearchChange}\n disabled={disabled}\n />\n </Grid>\n\n {/* Components filter is only shown if there are components - Project level logs */}\n {components.length > 0 && (\n <Grid item xs={12} md={2}>\n <FormControl\n fullWidth\n disabled={disabled || componentsLoading}\n variant=\"outlined\"\n >\n <InputLabel id=\"components-label\">Components</InputLabel>\n {componentsLoading ? (\n <Skeleton variant=\"rect\" height={56} />\n ) : (\n <Select\n multiple\n value={filters.components || []}\n onChange={handleComponentChange}\n labelId=\"components-label\"\n label=\"Components\"\n renderValue={selected => {\n const selectedArray = selected as string[];\n if (selectedArray.length === 0) return 'All';\n return selectedArray.join(', ');\n }}\n >\n {components.map(component => (\n <MenuItem key={component.name} value={component.name}>\n <Checkbox\n checked={\n (filters.components || []).indexOf(component.name) > -1\n }\n />\n {component.displayName || component.name}\n </MenuItem>\n ))}\n </Select>\n )}\n </FormControl>\n </Grid>\n )}\n\n {!components.length && (\n <Grid item xs={12} md={2}>\n <FormControl fullWidth disabled={disabled} variant=\"outlined\">\n <InputLabel id=\"selected-fields-label\">Selected Fields</InputLabel>\n <Select\n multiple\n value={filters.selectedFields}\n onChange={handleSelectedFieldsChange}\n labelId=\"selected-fields-label\"\n label=\"Selected Fields\"\n renderValue={selected => (selected as LogEntryField[]).join(', ')}\n >\n {SELECTED_FIELDS.map((field: LogEntryField) => (\n <MenuItem\n key={field}\n value={field}\n disabled={field === LogEntryField.Log}\n >\n <Checkbox\n checked={filters.selectedFields.includes(field)}\n disabled={field === LogEntryField.Log}\n />\n {field}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n )}\n\n <Grid item xs={12} md={2}>\n <FormControl fullWidth disabled={disabled} variant=\"outlined\">\n <InputLabel id=\"log-levels-label\">Log Levels</InputLabel>\n <Select\n multiple\n value={filters.logLevel}\n onChange={handleLogLevelSelectChange}\n labelId=\"log-levels-label\"\n label=\"Log Levels\"\n renderValue={selected => {\n const levels = selected as string[];\n if (levels.length === 0) return 'None';\n if (levels.length === LOG_LEVELS.length) return 'All';\n return levels.join(', ');\n }}\n >\n <MenuItem value=\"ALL\" onMouseDown={handleAllLogLevelsToggle}>\n <Checkbox\n checked={filters.logLevel.length === LOG_LEVELS.length}\n indeterminate={\n filters.logLevel.length > 0 &&\n filters.logLevel.length < LOG_LEVELS.length\n }\n />\n All\n </MenuItem>\n <Divider />\n {LOG_LEVELS.map(level => (\n <MenuItem key={level} value={level}>\n <Checkbox checked={filters.logLevel.includes(level)} />\n {level}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12} md={2}>\n <FormControl\n fullWidth\n disabled={disabled || environmentsLoading}\n variant=\"outlined\"\n >\n <InputLabel id=\"environment-label\">Environment</InputLabel>\n {environmentsLoading ? (\n <Skeleton variant=\"rect\" height={56} />\n ) : (\n <Select\n value={filters.environment}\n onChange={handleEnvironmentChange}\n labelId=\"environment-label\"\n label=\"Environment\"\n >\n {environments.map(env => (\n <MenuItem key={env.name} value={env.name}>\n {env.displayName || env.name}\n </MenuItem>\n ))}\n </Select>\n )}\n </FormControl>\n </Grid>\n\n <Grid item xs={12} md={2}>\n <TimeRangeFilter\n value={filters.timeRange}\n customStartTime={filters.customStartTime}\n customEndTime={filters.customEndTime}\n onChange={onFiltersChange}\n disabled={disabled}\n />\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAiCO,MAAM,aAAkC,CAAC;AAAA,EAC9C,OAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAa,EAAC;AAAA,EACd,iBAAA,GAAoB,KAAA;AAAA,EACpB,QAAA,GAAW;AACb,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,WAAA,EAAa,kBAAkB,CAAA,GAAI,kBAAA;AAAA,IACxC,OAAA,CAAQ,WAAA;AAAA,IACR,CAAA,KAAA,KAAS,eAAA,CAAgB,EAAE,WAAA,EAAa,OAAO;AAAA,GACjD;AAEA,EAAA,MAAM,uBAAA,GAA0B,CAAC,KAAA,KAA2C;AAC1E,IAAA,eAAA,CAAgB,EAAE,WAAA,EAAa,KAAA,CAAM,MAAA,CAAO,OAAiB,CAAA;AAAA,EAC/D,CAAA;AAEA,EAAA,MAAM,qBAAA,GAAwB,CAAC,KAAA,KAA2C;AACxE,IAAA,eAAA,CAAgB,EAAE,UAAA,EAAY,KAAA,CAAM,MAAA,CAAO,OAAmB,CAAA;AAAA,EAChE,CAAA;AAEA,EAAA,MAAM,0BAAA,GAA6B,CACjC,KAAA,KACG;AACH,IAAA,MAAM,KAAA,GAAQ,MAAM,MAAA,CAAO,KAAA;AAG3B,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,eAAA,CAAgB,EAAE,QAAA,EAAU,KAAA,EAAO,CAAA;AAAA,EACrC,CAAA;AAEA,EAAA,MAAM,2BAA2B,MAAM;AACrC,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ;AACjD,MAAA,eAAA,CAAgB,EAAE,QAAA,EAAU,EAAC,EAAG,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,eAAA,CAAgB,EAAE,QAAA,EAAU,CAAC,GAAG,UAAU,GAAG,CAAA;AAAA,IAC/C;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,0BAAA,GAA6B,CACjC,KAAA,KACG;AACH,IAAA,IAAI,cAAA,GAAiB,MAAM,MAAA,CAAO,KAAA;AAElC,IAAA,IAAI,CAAC,cAAA,CAAe,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA,EAAG;AAC/C,MAAA,cAAA,GAAiB,CAAC,GAAG,cAAA,EAAgB,aAAA,CAAc,GAAG,CAAA;AAAA,IACxD;AAGA,IAAA,eAAA,CAAgB;AAAA,MACd,gBAAgB,eAAA,CAAgB,MAAA;AAAA,QAAO,CAAA,KAAA,KACrC,cAAA,CAAe,QAAA,CAAS,KAAK;AAAA;AAC/B,KACD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EACvB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EACrB,QAAA,kBAAA,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAS,IAAA;AAAA,QACT,WAAA,EAAY,gBAAA;AAAA,QACZ,OAAA,EAAQ,UAAA;AAAA,QACR,KAAA,EAAO,WAAA;AAAA,QACP,QAAA,EAAU,kBAAA;AAAA,QACV;AAAA;AAAA,KACF,EACF,CAAA;AAAA,IAGC,UAAA,CAAW,MAAA,GAAS,CAAA,oBACnB,GAAA,CAAC,IAAA,EAAA,EAAK,MAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,IAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAS,IAAA;AAAA,QACT,UAAU,QAAA,IAAY,iBAAA;AAAA,QACtB,OAAA,EAAQ,UAAA;AAAA,QAER,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,kBAAA,EAAmB,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,UAC3C,oCACC,GAAA,CAAC,QAAA,EAAA,EAAS,SAAQ,MAAA,EAAO,MAAA,EAAQ,IAAI,CAAA,mBAErC,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAQ,IAAA;AAAA,cACR,KAAA,EAAO,OAAA,CAAQ,UAAA,IAAc,EAAC;AAAA,cAC9B,QAAA,EAAU,qBAAA;AAAA,cACV,OAAA,EAAQ,kBAAA;AAAA,cACR,KAAA,EAAM,YAAA;AAAA,cACN,aAAa,CAAA,QAAA,KAAY;AACvB,gBAAA,MAAM,aAAA,GAAgB,QAAA;AACtB,gBAAA,IAAI,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AACvC,gBAAA,OAAO,aAAA,CAAc,KAAK,IAAI,CAAA;AAAA,cAChC,CAAA;AAAA,cAEC,qBAAW,GAAA,CAAI,CAAA,SAAA,0BACb,QAAA,EAAA,EAA8B,KAAA,EAAO,UAAU,IAAA,EAC9C,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAA,CACG,QAAQ,UAAA,IAAc,IAAI,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,GAAI;AAAA;AAAA,iBAEzD;AAAA,gBACC,SAAA,CAAU,eAAe,SAAA,CAAU;AAAA,eAAA,EAAA,EANvB,SAAA,CAAU,IAOzB,CACD;AAAA;AAAA;AACH;AAAA;AAAA,KAEJ,EACF,CAAA;AAAA,IAGD,CAAC,UAAA,CAAW,MAAA,oBACX,GAAA,CAAC,IAAA,EAAA,EAAK,MAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,GACrB,QAAA,kBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,WAAS,IAAA,EAAC,QAAA,EAAoB,SAAQ,UAAA,EACjD,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,uBAAA,EAAwB,QAAA,EAAA,iBAAA,EAAe,CAAA;AAAA,sBACtD,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,QAAA,EAAQ,IAAA;AAAA,UACR,OAAO,OAAA,CAAQ,cAAA;AAAA,UACf,QAAA,EAAU,0BAAA;AAAA,UACV,OAAA,EAAQ,uBAAA;AAAA,UACR,KAAA,EAAM,iBAAA;AAAA,UACN,WAAA,EAAa,CAAA,QAAA,KAAa,QAAA,CAA6B,IAAA,CAAK,IAAI,CAAA;AAAA,UAE/D,QAAA,EAAA,eAAA,CAAgB,GAAA,CAAI,CAAC,KAAA,qBACpB,IAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,KAAA,EAAO,KAAA;AAAA,cACP,QAAA,EAAU,UAAU,aAAA,CAAc,GAAA;AAAA,cAElC,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAS,OAAA,CAAQ,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA;AAAA,oBAC9C,QAAA,EAAU,UAAU,aAAA,CAAc;AAAA;AAAA,iBACpC;AAAA,gBACC;AAAA;AAAA,aAAA;AAAA,YARI;AAAA,WAUR;AAAA;AAAA;AACH,KAAA,EACF,CAAA,EACF,CAAA;AAAA,oBAGF,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAS,IAAA,EAAC,QAAA,EAAoB,SAAQ,UAAA,EACjD,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,kBAAA,EAAmB,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,sBAC5C,IAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,QAAA,EAAQ,IAAA;AAAA,UACR,OAAO,OAAA,CAAQ,QAAA;AAAA,UACf,QAAA,EAAU,0BAAA;AAAA,UACV,OAAA,EAAQ,kBAAA;AAAA,UACR,KAAA,EAAM,YAAA;AAAA,UACN,aAAa,CAAA,QAAA,KAAY;AACvB,YAAA,MAAM,MAAA,GAAS,QAAA;AACf,YAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAChC,YAAA,IAAI,MAAA,CAAO,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ,OAAO,KAAA;AAChD,YAAA,OAAO,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,UACzB,CAAA;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,KAAA,EAAM,WAAA,EAAa,wBAAA,EACjC,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,OAAA,CAAQ,QAAA,CAAS,MAAA,KAAW,UAAA,CAAW,MAAA;AAAA,kBAChD,aAAA,EACE,QAAQ,QAAA,CAAS,MAAA,GAAS,KAC1B,OAAA,CAAQ,QAAA,CAAS,SAAS,UAAA,CAAW;AAAA;AAAA,eAEzC;AAAA,cAAE;AAAA,aAAA,EAEJ,CAAA;AAAA,gCACC,OAAA,EAAA,EAAQ,CAAA;AAAA,YACR,WAAW,GAAA,CAAI,CAAA,KAAA,qBACd,IAAA,CAAC,QAAA,EAAA,EAAqB,OAAO,KAAA,EAC3B,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,YAAS,OAAA,EAAS,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG,CAAA;AAAA,cACpD;AAAA,aAAA,EAAA,EAFY,KAGf,CACD;AAAA;AAAA;AAAA;AACH,KAAA,EACF,CAAA,EACF,CAAA;AAAA,wBAEC,IAAA,EAAA,EAAK,IAAA,EAAI,MAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EACrB,QAAA,kBAAA,IAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAS,IAAA;AAAA,QACT,UAAU,QAAA,IAAY,mBAAA;AAAA,QACtB,OAAA,EAAQ,UAAA;AAAA,QAER,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAG,mBAAA,EAAoB,QAAA,EAAA,aAAA,EAAW,CAAA;AAAA,UAC7C,sCACC,GAAA,CAAC,QAAA,EAAA,EAAS,SAAQ,MAAA,EAAO,MAAA,EAAQ,IAAI,CAAA,mBAErC,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAO,OAAA,CAAQ,WAAA;AAAA,cACf,QAAA,EAAU,uBAAA;AAAA,cACV,OAAA,EAAQ,mBAAA;AAAA,cACR,KAAA,EAAM,aAAA;AAAA,cAEL,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAA,GAAA,qBAChB,GAAA,CAAC,YAAwB,KAAA,EAAO,GAAA,CAAI,IAAA,EACjC,QAAA,EAAA,GAAA,CAAI,WAAA,IAAe,GAAA,CAAI,IAAA,EAAA,EADX,GAAA,CAAI,IAEnB,CACD;AAAA;AAAA;AACH;AAAA;AAAA,KAEJ,EACF,CAAA;AAAA,wBAEC,IAAA,EAAA,EAAK,IAAA,EAAI,MAAC,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EACrB,QAAA,kBAAA,GAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,OAAO,OAAA,CAAQ,SAAA;AAAA,QACf,iBAAiB,OAAA,CAAQ,eAAA;AAAA,QACzB,eAAe,OAAA,CAAQ,aAAA;AAAA,QACvB,QAAA,EAAU,eAAA;AAAA,QACV;AAAA;AAAA,KACF,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,91 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useRef, useEffect, useCallback } from 'react';
3
+ import { Paper, Box, Table, TableHead, TableRow, TableCell, TableBody, CircularProgress, Typography } from '@material-ui/core';
4
+ import { Skeleton } from '@material-ui/lab';
5
+ import { LogEntryField } from './types.esm.js';
6
+ import { LogEntry } from './LogEntry.esm.js';
7
+ import { useLogsTableStyles } from './styles.esm.js';
8
+
9
+ const LogsTable = ({
10
+ selectedFields,
11
+ logs,
12
+ loading,
13
+ hasMore,
14
+ loadingRef,
15
+ environmentName,
16
+ projectName,
17
+ componentName,
18
+ renderRowAction
19
+ }) => {
20
+ const classes = useLogsTableStyles();
21
+ const logsRef = useRef(logs);
22
+ useEffect(() => {
23
+ logsRef.current = logs;
24
+ }, [logs]);
25
+ const getLogsSnapshot = useCallback(() => logsRef.current, []);
26
+ const totalColumns = selectedFields.length;
27
+ const renderLoadingSkeletons = () => {
28
+ return Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxs(TableRow, { children: [
29
+ selectedFields.includes(LogEntryField.Timestamp) && /* @__PURE__ */ jsx(TableCell, { width: "15%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
30
+ selectedFields.includes(LogEntryField.LogLevel) && /* @__PURE__ */ jsx(TableCell, { width: "10%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
31
+ selectedFields.includes(LogEntryField.ComponentName) && /* @__PURE__ */ jsx(TableCell, { width: "15%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
32
+ selectedFields.includes(LogEntryField.Log) && /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) })
33
+ ] }, `skeleton-${index}`));
34
+ };
35
+ const renderEmptyState = () => {
36
+ if (loading) {
37
+ return null;
38
+ }
39
+ return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: totalColumns, children: /* @__PURE__ */ jsxs(Box, { className: classes.emptyState, children: [
40
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "No logs found" }),
41
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Try adjusting your filters or time range to see more logs." })
42
+ ] }) }) });
43
+ };
44
+ return /* @__PURE__ */ jsx(Paper, { className: classes.tablePaper, children: /* @__PURE__ */ jsx(Box, { className: classes.tableContainer, children: /* @__PURE__ */ jsxs(Table, { className: classes.table, stickyHeader: true, children: [
45
+ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: selectedFields.map((field) => {
46
+ let width;
47
+ if (field === LogEntryField.Timestamp) {
48
+ width = "15%";
49
+ } else if (field === LogEntryField.LogLevel) {
50
+ width = "10%";
51
+ } else if (field === LogEntryField.ComponentName) {
52
+ width = "15%";
53
+ } else {
54
+ width = selectedFields.includes(LogEntryField.ComponentName) ? "60%" : "75%";
55
+ }
56
+ return /* @__PURE__ */ jsx(
57
+ TableCell,
58
+ {
59
+ className: classes.headerCell,
60
+ width,
61
+ children: field
62
+ },
63
+ field
64
+ );
65
+ }) }) }),
66
+ /* @__PURE__ */ jsxs(TableBody, { children: [
67
+ logs.length === 0 && !loading && renderEmptyState(),
68
+ logs.length === 0 && loading && renderLoadingSkeletons(),
69
+ logs.map((log, index) => /* @__PURE__ */ jsx(
70
+ LogEntry,
71
+ {
72
+ log,
73
+ selectedFields,
74
+ environmentName,
75
+ projectName,
76
+ componentName,
77
+ getLogsSnapshot,
78
+ renderRowAction
79
+ },
80
+ `${log.timestamp}-${index}`
81
+ )),
82
+ hasMore && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: totalColumns, children: /* @__PURE__ */ jsx("div", { className: classes.loadingContainer, ref: loadingRef, children: loading ? /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", children: [
83
+ /* @__PURE__ */ jsx(CircularProgress, { size: 20 }),
84
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", style: { marginLeft: 8 }, children: "Loading more logs..." })
85
+ ] }) : /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Scroll to load more logs" }) }) }) })
86
+ ] })
87
+ ] }) }) });
88
+ };
89
+
90
+ export { LogsTable };
91
+ //# sourceMappingURL=LogsTable.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogsTable.esm.js","sources":["../../../src/components/RuntimeLogs/LogsTable.tsx"],"sourcesContent":["import { RefObject, FC, useCallback, useEffect, useRef } from 'react';\nimport {\n Table,\n TableHead,\n TableBody,\n TableRow,\n TableCell,\n Paper,\n Box,\n Typography,\n CircularProgress,\n} from '@material-ui/core';\nimport { Skeleton } from '@material-ui/lab';\nimport { LogEntryField, LogEntry as LogEntryType } from './types';\nimport { LogEntry, RenderLogRowAction } from './LogEntry';\nimport { useLogsTableStyles } from './styles';\n\ninterface LogsTableProps {\n selectedFields: LogEntryField[];\n logs: LogEntryType[];\n loading: boolean;\n hasMore: boolean;\n loadingRef: RefObject<HTMLDivElement>;\n environmentName?: string;\n projectName?: string;\n componentName?: string;\n renderRowAction?: RenderLogRowAction;\n}\n\nexport const LogsTable: FC<LogsTableProps> = ({\n selectedFields,\n logs,\n loading,\n hasMore,\n loadingRef,\n environmentName,\n projectName,\n componentName,\n renderRowAction,\n}) => {\n const classes = useLogsTableStyles();\n\n // Ref-backed snapshot accessor so per-row buttons can read the\n // *current* logs list without their parent component re-rendering\n // every time a new log batch arrives. Each LogEntry receives a\n // stable callback reference; only the rows whose own props change\n // re-render. The ref is updated after every render so the closure\n // always returns the freshest list.\n const logsRef = useRef<LogEntryType[]>(logs);\n useEffect(() => {\n logsRef.current = logs;\n }, [logs]);\n const getLogsSnapshot = useCallback(() => logsRef.current, []);\n\n const totalColumns = selectedFields.length;\n const renderLoadingSkeletons = () => {\n return Array.from({ length: 5 }).map((_, index) => (\n <TableRow key={`skeleton-${index}`}>\n {selectedFields.includes(LogEntryField.Timestamp) && (\n <TableCell width=\"15%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.LogLevel) && (\n <TableCell width=\"10%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.ComponentName) && (\n <TableCell width=\"15%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.Log) && (\n <TableCell>\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n </TableRow>\n ));\n };\n\n const renderEmptyState = () => {\n if (loading) {\n return null;\n }\n\n return (\n <TableRow>\n <TableCell colSpan={totalColumns}>\n <Box className={classes.emptyState}>\n <Typography variant=\"h6\" gutterBottom>\n No logs found\n </Typography>\n <Typography variant=\"body2\">\n Try adjusting your filters or time range to see more logs.\n </Typography>\n </Box>\n </TableCell>\n </TableRow>\n );\n };\n\n return (\n <Paper className={classes.tablePaper}>\n <Box className={classes.tableContainer}>\n <Table className={classes.table} stickyHeader>\n <TableHead>\n <TableRow>\n {selectedFields.map(field => {\n let width: string | undefined;\n\n if (field === LogEntryField.Timestamp) {\n width = '15%';\n } else if (field === LogEntryField.LogLevel) {\n width = '10%';\n } else if (field === LogEntryField.ComponentName) {\n width = '15%';\n } else {\n width = selectedFields.includes(LogEntryField.ComponentName)\n ? '60%'\n : '75%';\n }\n\n return (\n <TableCell\n key={field}\n className={classes.headerCell}\n width={width}\n >\n {field}\n </TableCell>\n );\n })}\n </TableRow>\n </TableHead>\n <TableBody>\n {logs.length === 0 && !loading && renderEmptyState()}\n\n {logs.length === 0 && loading && renderLoadingSkeletons()}\n\n {logs.map((log, index) => (\n <LogEntry\n key={`${log.timestamp}-${index}`}\n log={log}\n selectedFields={selectedFields}\n environmentName={environmentName}\n projectName={projectName}\n componentName={componentName}\n getLogsSnapshot={getLogsSnapshot}\n renderRowAction={renderRowAction}\n />\n ))}\n\n {hasMore && (\n <TableRow>\n <TableCell colSpan={totalColumns}>\n <div className={classes.loadingContainer} ref={loadingRef}>\n {loading ? (\n <Box display=\"flex\" alignItems=\"center\">\n <CircularProgress size={20} />\n <Typography variant=\"body2\" style={{ marginLeft: 8 }}>\n Loading more logs...\n </Typography>\n </Box>\n ) : (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Scroll to load more logs\n </Typography>\n )}\n </div>\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </Box>\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,220 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useMemo, useState, useRef, useEffect } from 'react';
3
+ import { Box, Typography, Button } from '@material-ui/core';
4
+ import { Progress } from '@backstage/core-components';
5
+ import { Alert } from '@material-ui/lab';
6
+ import { useEntity } from '@backstage/plugin-catalog-react';
7
+ import { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';
8
+ import { LogsFilter } from './LogsFilter.esm.js';
9
+ import { LogsTable } from './LogsTable.esm.js';
10
+ import { LogsActions } from './LogsActions.esm.js';
11
+ import '@backstage/core-plugin-api';
12
+ import { useGetEnvironmentsByNamespace } from '../../hooks/useGetEnvironmentsByNamespace.esm.js';
13
+ import 'react-router-dom';
14
+ import '../../utils/urlTimeRange.esm.js';
15
+ import '../../api/ObservabilityApi.esm.js';
16
+ import { useLogsPermission, ForbiddenState, useInfiniteScroll } from '@openchoreo/backstage-plugin-react';
17
+ import { useGetComponentsByProject } from '../../hooks/useGetComponentsByProject.esm.js';
18
+ import { useProjectRuntimeLogs } from '../../hooks/useProjectRuntimeLogs.esm.js';
19
+ import { useUrlFiltersForRuntimeLogs } from '../../hooks/useUrlFiltersForRuntimeLogs.esm.js';
20
+ import '../../api/RCAAgentApi.esm.js';
21
+ import '../../api/FinOpsAgentApi.esm.js';
22
+ import { useRuntimeLogsStyles } from './styles.esm.js';
23
+ import { LogEntryField } from './types.esm.js';
24
+
25
+ const ObservabilityProjectRuntimeLogsContent = ({
26
+ renderRowAction
27
+ }) => {
28
+ const classes = useRuntimeLogsStyles();
29
+ const { entity } = useEntity();
30
+ const namespace = entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE] || "";
31
+ const projectName = entity.metadata.name || "";
32
+ const {
33
+ environments,
34
+ loading: environmentsLoading,
35
+ error: environmentsError
36
+ } = useGetEnvironmentsByNamespace(namespace, projectName);
37
+ const {
38
+ components,
39
+ loading: componentsLoading,
40
+ error: componentsError
41
+ } = useGetComponentsByProject(entity);
42
+ const { filters, updateFilters } = useUrlFiltersForRuntimeLogs({
43
+ environments
44
+ });
45
+ const selectedEnvironment = environments.find(
46
+ (env) => env.name === filters.environment
47
+ );
48
+ const tableSelectedFields = useMemo(() => {
49
+ const withoutComponent = filters.selectedFields.filter(
50
+ (field) => field !== LogEntryField.ComponentName
51
+ );
52
+ const logIndex = withoutComponent.indexOf(LogEntryField.Log);
53
+ if (logIndex === -1) {
54
+ return [...withoutComponent, LogEntryField.ComponentName];
55
+ }
56
+ return [
57
+ ...withoutComponent.slice(0, logIndex),
58
+ LogEntryField.ComponentName,
59
+ ...withoutComponent.slice(logIndex)
60
+ ];
61
+ }, [filters.selectedFields]);
62
+ const [lastUpdated, setLastUpdated] = useState(/* @__PURE__ */ new Date());
63
+ const {
64
+ logs,
65
+ loading: logsLoading,
66
+ error: logsError,
67
+ totalCount,
68
+ hasMore,
69
+ fetchLogs,
70
+ loadMore,
71
+ refresh,
72
+ clearLogs
73
+ } = useProjectRuntimeLogs(filters, entity, {
74
+ environmentName: filters.environment,
75
+ namespaceName: namespace,
76
+ projectName,
77
+ limit: 50
78
+ });
79
+ const { loadingRef } = useInfiniteScroll(loadMore, hasMore, logsLoading);
80
+ const previousFiltersRef = useRef(null);
81
+ useEffect(() => {
82
+ const currentFilters = {
83
+ environment: filters.environment,
84
+ logLevel: filters.logLevel,
85
+ timeRange: filters.timeRange,
86
+ customStartTime: filters.customStartTime,
87
+ customEndTime: filters.customEndTime,
88
+ searchQuery: filters.searchQuery,
89
+ sortOrder: filters.sortOrder,
90
+ components: filters.components || []
91
+ };
92
+ const filtersChanged = previousFiltersRef.current === null || JSON.stringify(previousFiltersRef.current) !== JSON.stringify(currentFilters);
93
+ if (filters.environment && selectedEnvironment && namespace && projectName && filtersChanged) {
94
+ if (filters.logLevel.length === 0) {
95
+ clearLogs();
96
+ } else {
97
+ fetchLogs(true);
98
+ setLastUpdated(/* @__PURE__ */ new Date());
99
+ }
100
+ previousFiltersRef.current = currentFilters;
101
+ }
102
+ }, [
103
+ filters.environment,
104
+ filters.logLevel,
105
+ filters.timeRange,
106
+ filters.customStartTime,
107
+ filters.customEndTime,
108
+ filters.searchQuery,
109
+ filters.sortOrder,
110
+ filters.components,
111
+ fetchLogs,
112
+ clearLogs,
113
+ selectedEnvironment,
114
+ namespace,
115
+ projectName
116
+ ]);
117
+ useEffect(() => {
118
+ if (!logsLoading) {
119
+ setLastUpdated(/* @__PURE__ */ new Date());
120
+ }
121
+ }, [logsLoading]);
122
+ const handleRefresh = () => {
123
+ refresh();
124
+ setLastUpdated(/* @__PURE__ */ new Date());
125
+ };
126
+ const handleFiltersChange = (newFilters) => {
127
+ updateFilters(newFilters);
128
+ };
129
+ const renderError = (error) => {
130
+ const isObservabilityDisabled = error.includes(
131
+ "Observability is not enabled"
132
+ );
133
+ return /* @__PURE__ */ jsxs(
134
+ Alert,
135
+ {
136
+ severity: isObservabilityDisabled ? "info" : "error",
137
+ className: classes.errorContainer,
138
+ children: [
139
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", children: isObservabilityDisabled ? "Observability is not enabled for this project in the current environment. Enable observability to view runtime logs." : error }),
140
+ !isObservabilityDisabled && /* @__PURE__ */ jsx(Button, { onClick: handleRefresh, color: "inherit", size: "small", children: "Retry" })
141
+ ]
142
+ }
143
+ );
144
+ };
145
+ if (environmentsError) {
146
+ return /* @__PURE__ */ jsx(Box, { children: renderError(environmentsError) });
147
+ }
148
+ if (componentsError) {
149
+ return /* @__PURE__ */ jsx(Box, { children: renderError(componentsError) });
150
+ }
151
+ return /* @__PURE__ */ jsxs(Box, { children: [
152
+ /* @__PURE__ */ jsx(
153
+ LogsFilter,
154
+ {
155
+ filters,
156
+ onFiltersChange: handleFiltersChange,
157
+ environments,
158
+ environmentsLoading,
159
+ components,
160
+ componentsLoading,
161
+ disabled: logsLoading
162
+ }
163
+ ),
164
+ logsError && renderError(logsError),
165
+ !filters.environment && !environmentsLoading && environments.length === 0 && /* @__PURE__ */ jsx(Alert, { severity: "info", className: classes.errorContainer, children: /* @__PURE__ */ jsx(Typography, { variant: "body1", children: "No environments found for this project." }) }),
166
+ filters.environment && /* @__PURE__ */ jsxs(Fragment, { children: [
167
+ /* @__PURE__ */ jsx(
168
+ LogsActions,
169
+ {
170
+ totalCount,
171
+ disabled: logsLoading || !filters.environment,
172
+ onRefresh: handleRefresh,
173
+ filters,
174
+ onFiltersChange: handleFiltersChange,
175
+ lastUpdated
176
+ }
177
+ ),
178
+ /* @__PURE__ */ jsx(
179
+ LogsTable,
180
+ {
181
+ selectedFields: tableSelectedFields,
182
+ logs,
183
+ loading: logsLoading,
184
+ hasMore,
185
+ loadingRef,
186
+ environmentName: selectedEnvironment?.displayName || selectedEnvironment?.name,
187
+ projectName,
188
+ renderRowAction
189
+ }
190
+ )
191
+ ] })
192
+ ] });
193
+ };
194
+ const ObservabilityProjectRuntimeLogsPage = ({
195
+ renderRowAction
196
+ }) => {
197
+ const {
198
+ canViewLogs,
199
+ loading: permissionLoading,
200
+ deniedTooltip,
201
+ permissionName
202
+ } = useLogsPermission();
203
+ if (permissionLoading) {
204
+ return /* @__PURE__ */ jsx(Progress, {});
205
+ }
206
+ if (!canViewLogs) {
207
+ return /* @__PURE__ */ jsx(
208
+ ForbiddenState,
209
+ {
210
+ message: deniedTooltip,
211
+ permissionName,
212
+ variant: "fullpage"
213
+ }
214
+ );
215
+ }
216
+ return /* @__PURE__ */ jsx(ObservabilityProjectRuntimeLogsContent, { renderRowAction });
217
+ };
218
+
219
+ export { ObservabilityProjectRuntimeLogsPage };
220
+ //# sourceMappingURL=ObservabilityProjectRuntimeLogsPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObservabilityProjectRuntimeLogsPage.esm.js","sources":["../../../src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Box, Typography, Button } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { Alert } from '@material-ui/lab';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';\nimport { LogsFilter } from './LogsFilter';\nimport { LogsTable } from './LogsTable';\nimport { LogsActions } from './LogsActions';\nimport {\n useGetEnvironmentsByNamespace,\n useGetComponentsByProject,\n useProjectRuntimeLogs,\n useUrlFiltersForRuntimeLogs,\n} from '../../hooks';\nimport {\n useInfiniteScroll,\n useLogsPermission,\n ForbiddenState,\n} from '@openchoreo/backstage-plugin-react';\nimport { useRuntimeLogsStyles } from './styles';\nimport { LogEntryField } from './types';\nimport type { RenderLogRowAction } from './LogEntry';\n\nexport interface ObservabilityProjectRuntimeLogsPageProps {\n renderRowAction?: RenderLogRowAction;\n}\n\nconst ObservabilityProjectRuntimeLogsContent = ({\n renderRowAction,\n}: ObservabilityProjectRuntimeLogsPageProps) => {\n const classes = useRuntimeLogsStyles();\n const { entity } = useEntity();\n\n const namespace =\n entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE] || '';\n const projectName = entity.metadata.name || '';\n\n const {\n environments,\n loading: environmentsLoading,\n error: environmentsError,\n } = useGetEnvironmentsByNamespace(namespace, projectName);\n\n const {\n components,\n loading: componentsLoading,\n error: componentsError,\n } = useGetComponentsByProject(entity);\n\n const { filters, updateFilters } = useUrlFiltersForRuntimeLogs({\n environments,\n });\n\n const selectedEnvironment = environments.find(\n env => env.name === filters.environment,\n );\n const tableSelectedFields = useMemo(() => {\n const withoutComponent = filters.selectedFields.filter(\n field => field !== LogEntryField.ComponentName,\n );\n const logIndex = withoutComponent.indexOf(LogEntryField.Log);\n\n if (logIndex === -1) {\n return [...withoutComponent, LogEntryField.ComponentName];\n }\n\n return [\n ...withoutComponent.slice(0, logIndex),\n LogEntryField.ComponentName,\n ...withoutComponent.slice(logIndex),\n ];\n }, [filters.selectedFields]);\n\n const [lastUpdated, setLastUpdated] = useState<Date>(new Date());\n\n const {\n logs,\n loading: logsLoading,\n error: logsError,\n totalCount,\n hasMore,\n fetchLogs,\n loadMore,\n refresh,\n clearLogs,\n } = useProjectRuntimeLogs(filters, entity, {\n environmentName: filters.environment,\n namespaceName: namespace,\n projectName,\n limit: 50,\n });\n\n const { loadingRef } = useInfiniteScroll(loadMore, hasMore, logsLoading);\n\n const previousFiltersRef = useRef<{\n environment: string;\n logLevel: string[];\n timeRange: string;\n customStartTime?: string;\n customEndTime?: string;\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n components: string[];\n } | null>(null);\n\n useEffect(() => {\n const currentFilters = {\n environment: filters.environment,\n logLevel: filters.logLevel,\n timeRange: filters.timeRange,\n customStartTime: filters.customStartTime,\n customEndTime: filters.customEndTime,\n searchQuery: filters.searchQuery,\n sortOrder: filters.sortOrder,\n components: filters.components || [],\n };\n\n const filtersChanged =\n previousFiltersRef.current === null ||\n JSON.stringify(previousFiltersRef.current) !==\n JSON.stringify(currentFilters);\n\n if (\n filters.environment &&\n selectedEnvironment &&\n namespace &&\n projectName &&\n filtersChanged\n ) {\n if (filters.logLevel.length === 0) {\n clearLogs();\n } else {\n fetchLogs(true);\n setLastUpdated(new Date());\n }\n previousFiltersRef.current = currentFilters;\n }\n }, [\n filters.environment,\n filters.logLevel,\n filters.timeRange,\n filters.customStartTime,\n filters.customEndTime,\n filters.searchQuery,\n filters.sortOrder,\n filters.components,\n fetchLogs,\n clearLogs,\n selectedEnvironment,\n namespace,\n projectName,\n ]);\n\n useEffect(() => {\n if (!logsLoading) {\n setLastUpdated(new Date());\n }\n }, [logsLoading]);\n\n const handleRefresh = () => {\n refresh();\n setLastUpdated(new Date());\n };\n\n const handleFiltersChange = (newFilters: Partial<typeof filters>) => {\n updateFilters(newFilters);\n };\n\n const renderError = (error: string) => {\n const isObservabilityDisabled = error.includes(\n 'Observability is not enabled',\n );\n\n return (\n <Alert\n severity={isObservabilityDisabled ? 'info' : 'error'}\n className={classes.errorContainer}\n >\n <Typography variant=\"body1\">\n {isObservabilityDisabled\n ? 'Observability is not enabled for this project in the current environment. Enable observability to view runtime logs.'\n : error}\n </Typography>\n {!isObservabilityDisabled && (\n <Button onClick={handleRefresh} color=\"inherit\" size=\"small\">\n Retry\n </Button>\n )}\n </Alert>\n );\n };\n\n if (environmentsError) {\n return <Box>{renderError(environmentsError)}</Box>;\n }\n\n if (componentsError) {\n return <Box>{renderError(componentsError)}</Box>;\n }\n\n return (\n <Box>\n <LogsFilter\n filters={filters}\n onFiltersChange={handleFiltersChange}\n environments={environments}\n environmentsLoading={environmentsLoading}\n components={components}\n componentsLoading={componentsLoading}\n disabled={logsLoading}\n />\n\n {logsError && renderError(logsError)}\n\n {!filters.environment &&\n !environmentsLoading &&\n environments.length === 0 && (\n <Alert severity=\"info\" className={classes.errorContainer}>\n <Typography variant=\"body1\">\n No environments found for this project.\n </Typography>\n </Alert>\n )}\n\n {filters.environment && (\n <>\n <LogsActions\n totalCount={totalCount}\n disabled={logsLoading || !filters.environment}\n onRefresh={handleRefresh}\n filters={filters}\n onFiltersChange={handleFiltersChange}\n lastUpdated={lastUpdated}\n />\n\n <LogsTable\n selectedFields={tableSelectedFields}\n logs={logs}\n loading={logsLoading}\n hasMore={hasMore}\n loadingRef={loadingRef}\n environmentName={\n selectedEnvironment?.displayName || selectedEnvironment?.name\n }\n projectName={projectName}\n renderRowAction={renderRowAction}\n />\n </>\n )}\n </Box>\n );\n};\n\nexport const ObservabilityProjectRuntimeLogsPage = ({\n renderRowAction,\n}: ObservabilityProjectRuntimeLogsPageProps) => {\n const {\n canViewLogs,\n loading: permissionLoading,\n deniedTooltip,\n permissionName,\n } = useLogsPermission();\n\n if (permissionLoading) {\n return <Progress />;\n }\n\n if (!canViewLogs) {\n return (\n <ForbiddenState\n message={deniedTooltip}\n permissionName={permissionName}\n variant=\"fullpage\"\n />\n );\n }\n\n return (\n <ObservabilityProjectRuntimeLogsContent renderRowAction={renderRowAction} />\n );\n};\n"],"names":[],"mappings":"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"}