@openchoreo/backstage-plugin-openchoreo-observability 1.2.0-rc.1 → 1.2.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @openchoreo/backstage-plugin-openchoreo-observability
2
2
 
3
+ ## 1.2.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 56b4e95: Adapt the tracing views to the OpenTelemetry span status model. The
8
+ observability API now returns a span's `status` as a `SpanStatus` object
9
+ (`code` of `ok`/`error`/`unset` plus an optional `message`) instead of a plain
10
+ status string. The waterfall tooltip now shows the span's status code, the span
11
+ details panel gains a dedicated Status section (alongside Attributes and Resource
12
+ Attributes) that surfaces the status message, and error spans stay highlighted
13
+ based on the status code. This also prevents the span tooltip from crashing when
14
+ the status is an object.
15
+ - 56b4e95: Fix the error stripe not rendering on error rows in the traces table. The red
16
+ "contains errors" indicator was drawn by CSS targeting table cells (`td`/`th`)
17
+ that no longer exist after the table moved to a div-based virtualized layout,
18
+ and the span that did render (the tooltip's hover target) had no fill colour.
19
+ The stripe is now drawn on the rendered element, so error traces show the red
20
+ stripe again.
21
+ - Updated dependencies [b52e578]
22
+ - Updated dependencies [4d7ebff]
23
+ - @openchoreo/backstage-plugin-react@1.2.0-next.2
24
+ - @openchoreo/backstage-plugin-common@1.2.0-next.2
25
+
3
26
  ## 1.2.0-next.3
4
27
 
5
28
  ### Minor Changes
@@ -210,6 +210,7 @@ class ObservabilityClient {
210
210
  endTime: data.endTime ?? "",
211
211
  durationNs: data.durationNs ?? 0,
212
212
  parentSpanId: data.parentSpanId,
213
+ status: data.status,
213
214
  attributes: data.attributes,
214
215
  resourceAttributes: data.resourceAttributes
215
216
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ObservabilityApi.esm.js","sources":["../../src/api/ObservabilityApi.ts"],"sourcesContent":["import {\n createApiRef,\n DiscoveryApi,\n FetchApi,\n} from '@backstage/core-plugin-api';\nimport {\n ResourceMetrics,\n HttpMetrics,\n MetricType,\n Trace,\n Span,\n SpanDetails,\n RCAReportSummary,\n RCAReportDetailed,\n AlertSummary,\n IncidentSummary,\n FinOpsReportSummary,\n FinOpsReportDetailed,\n} from '../types';\nimport { LogsResponse } from '../components/RuntimeLogs/types';\nimport { EventsResponse } from '../components/RuntimeEvents/types';\nimport { ObserverUrlCache } from './ObserverUrlCache';\n\nexport interface ObservabilityApi {\n getRuntimeLogs(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n logLevels?: string[];\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<LogsResponse>;\n\n getRuntimeEvents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<EventsResponse>;\n\n getMetrics(\n environmentName: string,\n componentName: string,\n namespaceName: string,\n projectName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n step?: string;\n type?: MetricType;\n },\n ): Promise<ResourceMetrics | HttpMetrics>;\n\n getTraces(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n traces: Trace[];\n total: number;\n tookMs: number;\n }>;\n\n getTraceSpans(\n traceId: string,\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n },\n ): Promise<{\n spans: Span[];\n total: number;\n tookMs: number;\n }>;\n\n getSpanDetails(\n traceId: string,\n spanId: string,\n namespaceName: string,\n environmentName: string,\n ): Promise<SpanDetails>;\n\n getRCAReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n },\n ): Promise<{\n reports: RCAReportSummary[];\n totalCount?: number;\n }>;\n\n getRCAReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<RCAReportDetailed>;\n\n getIncidents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n incidents: IncidentSummary[];\n total: number;\n }>;\n\n getAlerts(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n alerts: AlertSummary[];\n total: number;\n }>;\n\n updateIncidentStatus(\n incidentId: string,\n status: 'acknowledged' | 'resolved',\n namespaceName: string,\n environmentName: string,\n ): Promise<void>;\n\n getFinOpsReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n sort?: string;\n },\n ): Promise<{\n reports: FinOpsReportSummary[];\n totalCount?: number;\n }>;\n\n getFinOpsReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<FinOpsReportDetailed>;\n}\n\nexport const observabilityApiRef = createApiRef<ObservabilityApi>({\n id: 'plugin.openchoreo-observability.service',\n});\n\nconst DIRECT_HEADER = { 'x-openchoreo-direct': 'true' };\n\nexport class ObservabilityClient implements ObservabilityApi {\n private readonly fetchApi: FetchApi;\n private readonly urlCache: ObserverUrlCache;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.fetchApi = options.fetchApi;\n this.urlCache = new ObserverUrlCache(options);\n }\n\n async getMetrics(\n environmentName: string,\n componentName: string,\n namespaceName: string,\n projectName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n step?: string;\n type?: MetricType;\n },\n ): Promise<ResourceMetrics | HttpMetrics> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const searchScope = {\n namespace: namespaceName,\n project: projectName,\n component: componentName,\n environment: environmentName,\n };\n\n const baseBody = {\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n searchScope,\n ...(options?.step ? { step: options.step } : {}),\n };\n\n const fetchOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n };\n\n const metricType = options?.type ?? 'resource';\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/metrics/query`,\n {\n ...fetchOptions,\n body: JSON.stringify({ ...baseBody, metric: metricType }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch metrics: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n switch (metricType) {\n case 'resource':\n return {\n cpuUsage: {\n cpuUsage: data.cpuUsage ?? [],\n cpuRequests: data.cpuRequests ?? [],\n cpuLimits: data.cpuLimits ?? [],\n },\n memoryUsage: {\n memoryUsage: data.memoryUsage ?? [],\n memoryRequests: data.memoryRequests ?? [],\n memoryLimits: data.memoryLimits ?? [],\n },\n };\n case 'http':\n return {\n networkThroughput: {\n requestCount: data.requestCount ?? [],\n successfulRequestCount: data.successfulRequestCount ?? [],\n unsuccessfulRequestCount: data.unsuccessfulRequestCount ?? [],\n },\n networkLatency: {\n meanLatency: data.meanLatency ?? [],\n latencyP50: data.latencyP50 ?? [],\n latencyP90: data.latencyP90 ?? [],\n latencyP99: data.latencyP99 ?? [],\n },\n };\n default:\n throw new Error(`Unsupported metric type: ${metricType}`);\n }\n }\n\n async getTraces(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n traces: Trace[];\n total: number;\n tookMs: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch traces: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n traces: (data.traces ?? []).map((t: any) => ({\n traceId: t.traceId ?? '',\n traceName: t.traceName,\n spanCount: t.spanCount ?? 0,\n rootSpanId: t.rootSpanId,\n rootSpanName: t.rootSpanName,\n rootSpanKind: t.rootSpanKind,\n startTime: t.startTime ?? '',\n endTime: t.endTime ?? '',\n durationNs: t.durationNs ?? 0,\n hasErrors: t.hasErrors ?? false,\n })),\n total: data.total ?? 0,\n tookMs: data.tookMs ?? 0,\n };\n }\n\n async getTraceSpans(\n traceId: string,\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n },\n ): Promise<{\n spans: Span[];\n total: number;\n tookMs: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/${encodeURIComponent(\n traceId,\n )}/spans/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: 1000,\n sortOrder: 'asc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error ||\n `Failed to fetch spans for trace ${traceId}: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n spans: (data.spans ?? []).map((s: any) => ({\n spanId: s.spanId ?? '',\n spanName: s.spanName ?? '',\n spanKind: s.spanKind,\n startTime: s.startTime ?? '',\n endTime: s.endTime ?? '',\n durationNs: s.durationNs ?? 0,\n parentSpanId: s.parentSpanId,\n status: s.status,\n })),\n total: data.total ?? 0,\n tookMs: data.tookMs ?? 0,\n };\n }\n\n async getSpanDetails(\n traceId: string,\n spanId: string,\n namespaceName: string,\n environmentName: string,\n ): Promise<SpanDetails> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/${encodeURIComponent(\n traceId,\n )}/spans/${encodeURIComponent(spanId)}`,\n {\n headers: { ...DIRECT_HEADER },\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error ||\n `Failed to fetch span details for span ${spanId}: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n spanId: data.spanId ?? '',\n spanName: data.spanName ?? '',\n spanKind: data.spanKind,\n startTime: data.startTime ?? '',\n endTime: data.endTime ?? '',\n durationNs: data.durationNs ?? 0,\n parentSpanId: data.parentSpanId,\n attributes: data.attributes,\n resourceAttributes: data.resourceAttributes,\n };\n }\n\n async getRCAReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n },\n ): Promise<{\n reports: RCAReportSummary[];\n totalCount?: number;\n }> {\n const { rcaAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!rcaAgentUrl) {\n throw new Error('RCA service is not configured');\n }\n\n const url = new URL(`${rcaAgentUrl}/api/v1/rca-agent/reports`);\n url.searchParams.set('namespace', namespaceName);\n url.searchParams.set('project', projectName);\n url.searchParams.set('environment', environmentName);\n if (options?.startTime)\n url.searchParams.set('startTime', options.startTime);\n if (options?.endTime) url.searchParams.set('endTime', options.endTime);\n if (options?.status) url.searchParams.set('status', options.status);\n if (options?.limit !== undefined)\n url.searchParams.set('limit', String(options.limit));\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `RCA service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('RCA service is not configured')) {\n throw new Error('RCA service is not configured');\n }\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch RCA reports: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n reports: data.reports || [],\n totalCount: data.totalCount,\n };\n }\n\n async getRCAReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<RCAReportDetailed> {\n const { rcaAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!rcaAgentUrl) {\n throw new Error('RCA service is not configured');\n }\n\n const url = new URL(\n `${rcaAgentUrl}/api/v1/rca-agent/reports/${encodeURIComponent(reportId)}`,\n );\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `RCA service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('RCA service is not configured')) {\n throw new Error('RCA service is not configured');\n }\n if (error.includes('RCA report not found')) {\n throw new Error('RCA report not found');\n }\n throw new Error(\n error || `Failed to fetch RCA report: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async getIncidents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n incidents: IncidentSummary[];\n total: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/incidents/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch incidents: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n const validStatuses = ['active', 'acknowledged', 'resolved'];\n return {\n incidents: (data.incidents ?? [])\n .filter((i: any) => validStatuses.includes(i.status))\n .map(\n (i: any): IncidentSummary => ({\n incidentId: i.incidentId ?? '',\n alertId: i.alertId ?? '',\n status: i.status,\n description: i.description,\n notes: i.notes,\n timestamp: i.timestamp,\n triggeredAt: i.triggeredAt,\n acknowledgedAt: i.acknowledgedAt,\n resolvedAt: i.resolvedAt,\n incidentTriggerAiRca: i.incidentTriggerAiRca ?? false,\n incidentTriggerAiCostAnalysis:\n i.incidentTriggerAiCostAnalysis ?? false,\n projectName: i.labels?.projectName,\n componentName: i.labels?.componentName,\n environmentName: i.labels?.environmentName,\n namespaceName: i.labels?.namespaceName,\n }),\n ),\n total: data.total ?? 0,\n };\n }\n\n async getAlerts(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n alerts: AlertSummary[];\n total: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/alerts/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n component: componentName,\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch alerts: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n return {\n alerts: (data.alerts ?? []).map(\n (a: any): AlertSummary => ({\n timestamp: a.timestamp,\n alertId: a.alertId ?? '',\n alertValue: a.alertValue,\n ruleName: a.metadata?.alertRule?.name,\n ruleDescription: a.metadata?.alertRule?.description,\n severity: a.metadata?.alertRule?.severity,\n sourceType: a.metadata?.alertRule?.source?.type,\n sourceQuery: a.metadata?.alertRule?.source?.query,\n sourceMetric: a.metadata?.alertRule?.source?.metric,\n projectName: a.metadata?.labels?.projectName,\n componentName: a.metadata?.labels?.componentName,\n environmentName: a.metadata?.labels?.environmentName,\n namespaceName: a.metadata?.labels?.namespaceName,\n notificationChannels: a.notificationChannels ?? [],\n incidentEnabled: a.incidentEnabled ?? false,\n }),\n ),\n total: data.total ?? 0,\n };\n }\n\n async getRuntimeLogs(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n logLevels?: string[];\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<LogsResponse> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/logs/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ||\n new Date(Date.now() - 60 * 60 * 1000).toISOString(),\n endTime: options?.endTime || new Date().toISOString(),\n limit: options?.limit || 100,\n sortOrder: options?.sortOrder || 'desc',\n ...(options?.logLevels &&\n options.logLevels.length > 0 && { logLevels: options.logLevels }),\n ...(options?.searchQuery && {\n searchPhrase: options.searchQuery,\n }),\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error ||\n `Failed to fetch runtime logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async getRuntimeEvents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<EventsResponse> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/events/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ||\n new Date(Date.now() - 60 * 60 * 1000).toISOString(),\n endTime: options?.endTime || new Date().toISOString(),\n limit: options?.limit || 100,\n sortOrder: options?.sortOrder || 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error ||\n `Failed to fetch events: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async updateIncidentStatus(\n incidentId: string,\n status: 'acknowledged' | 'resolved',\n namespaceName: string,\n environmentName: string,\n ): Promise<void> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/incidents/${encodeURIComponent(incidentId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({ status }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error || `Failed to update incident: ${response.statusText}`,\n );\n }\n }\n\n async getFinOpsReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n sort?: string;\n },\n ): Promise<{\n reports: FinOpsReportSummary[];\n totalCount?: number;\n }> {\n const { finopsAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!finopsAgentUrl) {\n throw new Error('FinOps service is not configured');\n }\n\n const url = new URL(`${finopsAgentUrl}/api/v1alpha1/reports`);\n url.searchParams.set('namespace', namespaceName);\n url.searchParams.set('project', projectName);\n url.searchParams.set('environment', environmentName);\n if (options?.startTime)\n url.searchParams.set('startTime', options.startTime);\n if (options?.endTime) url.searchParams.set('endTime', options.endTime);\n if (options?.status) url.searchParams.set('status', options.status);\n if (options?.limit !== undefined)\n url.searchParams.set('limit', String(options.limit));\n if (options?.sort) url.searchParams.set('sort', options.sort);\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `FinOps service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('FinOps service is not configured')) {\n throw new Error('FinOps service is not configured');\n }\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch FinOps reports: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n reports: data.reports || [],\n totalCount: data.totalCount,\n };\n }\n\n async getFinOpsReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<FinOpsReportDetailed> {\n const { finopsAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!finopsAgentUrl) {\n throw new Error('FinOps service is not configured');\n }\n\n const url = new URL(\n `${finopsAgentUrl}/api/v1alpha1/reports/${encodeURIComponent(reportId)}`,\n );\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `FinOps service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('FinOps service is not configured')) {\n throw new Error('FinOps service is not configured');\n }\n if (error.includes('FinOps report not found')) {\n throw new Error('FinOps report not found');\n }\n throw new Error(\n error || `Failed to fetch FinOps report: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n private async parseError(response: Response): Promise<string> {\n try {\n const error = await response.json();\n return (\n error.error ||\n error.message ||\n `${response.status} ${response.statusText}`\n );\n } catch {\n return `${response.status} ${response.statusText}`;\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObservabilityApi.esm.js","sources":["../../src/api/ObservabilityApi.ts"],"sourcesContent":["import {\n createApiRef,\n DiscoveryApi,\n FetchApi,\n} from '@backstage/core-plugin-api';\nimport {\n ResourceMetrics,\n HttpMetrics,\n MetricType,\n Trace,\n Span,\n SpanDetails,\n RCAReportSummary,\n RCAReportDetailed,\n AlertSummary,\n IncidentSummary,\n FinOpsReportSummary,\n FinOpsReportDetailed,\n} from '../types';\nimport { LogsResponse } from '../components/RuntimeLogs/types';\nimport { EventsResponse } from '../components/RuntimeEvents/types';\nimport { ObserverUrlCache } from './ObserverUrlCache';\n\nexport interface ObservabilityApi {\n getRuntimeLogs(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n logLevels?: string[];\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<LogsResponse>;\n\n getRuntimeEvents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<EventsResponse>;\n\n getMetrics(\n environmentName: string,\n componentName: string,\n namespaceName: string,\n projectName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n step?: string;\n type?: MetricType;\n },\n ): Promise<ResourceMetrics | HttpMetrics>;\n\n getTraces(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n traces: Trace[];\n total: number;\n tookMs: number;\n }>;\n\n getTraceSpans(\n traceId: string,\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n },\n ): Promise<{\n spans: Span[];\n total: number;\n tookMs: number;\n }>;\n\n getSpanDetails(\n traceId: string,\n spanId: string,\n namespaceName: string,\n environmentName: string,\n ): Promise<SpanDetails>;\n\n getRCAReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n },\n ): Promise<{\n reports: RCAReportSummary[];\n totalCount?: number;\n }>;\n\n getRCAReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<RCAReportDetailed>;\n\n getIncidents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n incidents: IncidentSummary[];\n total: number;\n }>;\n\n getAlerts(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n alerts: AlertSummary[];\n total: number;\n }>;\n\n updateIncidentStatus(\n incidentId: string,\n status: 'acknowledged' | 'resolved',\n namespaceName: string,\n environmentName: string,\n ): Promise<void>;\n\n getFinOpsReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n sort?: string;\n },\n ): Promise<{\n reports: FinOpsReportSummary[];\n totalCount?: number;\n }>;\n\n getFinOpsReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<FinOpsReportDetailed>;\n}\n\nexport const observabilityApiRef = createApiRef<ObservabilityApi>({\n id: 'plugin.openchoreo-observability.service',\n});\n\nconst DIRECT_HEADER = { 'x-openchoreo-direct': 'true' };\n\nexport class ObservabilityClient implements ObservabilityApi {\n private readonly fetchApi: FetchApi;\n private readonly urlCache: ObserverUrlCache;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.fetchApi = options.fetchApi;\n this.urlCache = new ObserverUrlCache(options);\n }\n\n async getMetrics(\n environmentName: string,\n componentName: string,\n namespaceName: string,\n projectName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n step?: string;\n type?: MetricType;\n },\n ): Promise<ResourceMetrics | HttpMetrics> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const searchScope = {\n namespace: namespaceName,\n project: projectName,\n component: componentName,\n environment: environmentName,\n };\n\n const baseBody = {\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n searchScope,\n ...(options?.step ? { step: options.step } : {}),\n };\n\n const fetchOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n };\n\n const metricType = options?.type ?? 'resource';\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/metrics/query`,\n {\n ...fetchOptions,\n body: JSON.stringify({ ...baseBody, metric: metricType }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch metrics: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n switch (metricType) {\n case 'resource':\n return {\n cpuUsage: {\n cpuUsage: data.cpuUsage ?? [],\n cpuRequests: data.cpuRequests ?? [],\n cpuLimits: data.cpuLimits ?? [],\n },\n memoryUsage: {\n memoryUsage: data.memoryUsage ?? [],\n memoryRequests: data.memoryRequests ?? [],\n memoryLimits: data.memoryLimits ?? [],\n },\n };\n case 'http':\n return {\n networkThroughput: {\n requestCount: data.requestCount ?? [],\n successfulRequestCount: data.successfulRequestCount ?? [],\n unsuccessfulRequestCount: data.unsuccessfulRequestCount ?? [],\n },\n networkLatency: {\n meanLatency: data.meanLatency ?? [],\n latencyP50: data.latencyP50 ?? [],\n latencyP90: data.latencyP90 ?? [],\n latencyP99: data.latencyP99 ?? [],\n },\n };\n default:\n throw new Error(`Unsupported metric type: ${metricType}`);\n }\n }\n\n async getTraces(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n traces: Trace[];\n total: number;\n tookMs: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch traces: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n traces: (data.traces ?? []).map((t: any) => ({\n traceId: t.traceId ?? '',\n traceName: t.traceName,\n spanCount: t.spanCount ?? 0,\n rootSpanId: t.rootSpanId,\n rootSpanName: t.rootSpanName,\n rootSpanKind: t.rootSpanKind,\n startTime: t.startTime ?? '',\n endTime: t.endTime ?? '',\n durationNs: t.durationNs ?? 0,\n hasErrors: t.hasErrors ?? false,\n })),\n total: data.total ?? 0,\n tookMs: data.tookMs ?? 0,\n };\n }\n\n async getTraceSpans(\n traceId: string,\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n },\n ): Promise<{\n spans: Span[];\n total: number;\n tookMs: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/${encodeURIComponent(\n traceId,\n )}/spans/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: 1000,\n sortOrder: 'asc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error ||\n `Failed to fetch spans for trace ${traceId}: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n spans: (data.spans ?? []).map((s: any) => ({\n spanId: s.spanId ?? '',\n spanName: s.spanName ?? '',\n spanKind: s.spanKind,\n startTime: s.startTime ?? '',\n endTime: s.endTime ?? '',\n durationNs: s.durationNs ?? 0,\n parentSpanId: s.parentSpanId,\n status: s.status,\n })),\n total: data.total ?? 0,\n tookMs: data.tookMs ?? 0,\n };\n }\n\n async getSpanDetails(\n traceId: string,\n spanId: string,\n namespaceName: string,\n environmentName: string,\n ): Promise<SpanDetails> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/traces/${encodeURIComponent(\n traceId,\n )}/spans/${encodeURIComponent(spanId)}`,\n {\n headers: { ...DIRECT_HEADER },\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error ||\n `Failed to fetch span details for span ${spanId}: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n spanId: data.spanId ?? '',\n spanName: data.spanName ?? '',\n spanKind: data.spanKind,\n startTime: data.startTime ?? '',\n endTime: data.endTime ?? '',\n durationNs: data.durationNs ?? 0,\n parentSpanId: data.parentSpanId,\n status: data.status,\n attributes: data.attributes,\n resourceAttributes: data.resourceAttributes,\n };\n }\n\n async getRCAReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n },\n ): Promise<{\n reports: RCAReportSummary[];\n totalCount?: number;\n }> {\n const { rcaAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!rcaAgentUrl) {\n throw new Error('RCA service is not configured');\n }\n\n const url = new URL(`${rcaAgentUrl}/api/v1/rca-agent/reports`);\n url.searchParams.set('namespace', namespaceName);\n url.searchParams.set('project', projectName);\n url.searchParams.set('environment', environmentName);\n if (options?.startTime)\n url.searchParams.set('startTime', options.startTime);\n if (options?.endTime) url.searchParams.set('endTime', options.endTime);\n if (options?.status) url.searchParams.set('status', options.status);\n if (options?.limit !== undefined)\n url.searchParams.set('limit', String(options.limit));\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `RCA service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('RCA service is not configured')) {\n throw new Error('RCA service is not configured');\n }\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch RCA reports: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n reports: data.reports || [],\n totalCount: data.totalCount,\n };\n }\n\n async getRCAReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<RCAReportDetailed> {\n const { rcaAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!rcaAgentUrl) {\n throw new Error('RCA service is not configured');\n }\n\n const url = new URL(\n `${rcaAgentUrl}/api/v1/rca-agent/reports/${encodeURIComponent(reportId)}`,\n );\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `RCA service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('RCA service is not configured')) {\n throw new Error('RCA service is not configured');\n }\n if (error.includes('RCA report not found')) {\n throw new Error('RCA report not found');\n }\n throw new Error(\n error || `Failed to fetch RCA report: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async getIncidents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n incidents: IncidentSummary[];\n total: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/incidents/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch incidents: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n const validStatuses = ['active', 'acknowledged', 'resolved'];\n return {\n incidents: (data.incidents ?? [])\n .filter((i: any) => validStatuses.includes(i.status))\n .map(\n (i: any): IncidentSummary => ({\n incidentId: i.incidentId ?? '',\n alertId: i.alertId ?? '',\n status: i.status,\n description: i.description,\n notes: i.notes,\n timestamp: i.timestamp,\n triggeredAt: i.triggeredAt,\n acknowledgedAt: i.acknowledgedAt,\n resolvedAt: i.resolvedAt,\n incidentTriggerAiRca: i.incidentTriggerAiRca ?? false,\n incidentTriggerAiCostAnalysis:\n i.incidentTriggerAiCostAnalysis ?? false,\n projectName: i.labels?.projectName,\n componentName: i.labels?.componentName,\n environmentName: i.labels?.environmentName,\n namespaceName: i.labels?.namespaceName,\n }),\n ),\n total: data.total ?? 0,\n };\n }\n\n async getAlerts(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n limit?: number;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<{\n alerts: AlertSummary[];\n total: number;\n }> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/alerts/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ?? new Date(Date.now() - 3600000).toISOString(),\n endTime: options?.endTime ?? new Date().toISOString(),\n limit: options?.limit ?? 100,\n sortOrder: options?.sortOrder ?? 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n component: componentName,\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch alerts: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n return {\n alerts: (data.alerts ?? []).map(\n (a: any): AlertSummary => ({\n timestamp: a.timestamp,\n alertId: a.alertId ?? '',\n alertValue: a.alertValue,\n ruleName: a.metadata?.alertRule?.name,\n ruleDescription: a.metadata?.alertRule?.description,\n severity: a.metadata?.alertRule?.severity,\n sourceType: a.metadata?.alertRule?.source?.type,\n sourceQuery: a.metadata?.alertRule?.source?.query,\n sourceMetric: a.metadata?.alertRule?.source?.metric,\n projectName: a.metadata?.labels?.projectName,\n componentName: a.metadata?.labels?.componentName,\n environmentName: a.metadata?.labels?.environmentName,\n namespaceName: a.metadata?.labels?.namespaceName,\n notificationChannels: a.notificationChannels ?? [],\n incidentEnabled: a.incidentEnabled ?? false,\n }),\n ),\n total: data.total ?? 0,\n };\n }\n\n async getRuntimeLogs(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n logLevels?: string[];\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<LogsResponse> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/logs/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ||\n new Date(Date.now() - 60 * 60 * 1000).toISOString(),\n endTime: options?.endTime || new Date().toISOString(),\n limit: options?.limit || 100,\n sortOrder: options?.sortOrder || 'desc',\n ...(options?.logLevels &&\n options.logLevels.length > 0 && { logLevels: options.logLevels }),\n ...(options?.searchQuery && {\n searchPhrase: options.searchQuery,\n }),\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error ||\n `Failed to fetch runtime logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async getRuntimeEvents(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n componentName?: string,\n options?: {\n limit?: number;\n startTime?: string;\n endTime?: string;\n sortOrder?: 'asc' | 'desc';\n },\n ): Promise<EventsResponse> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1/events/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({\n startTime:\n options?.startTime ||\n new Date(Date.now() - 60 * 60 * 1000).toISOString(),\n endTime: options?.endTime || new Date().toISOString(),\n limit: options?.limit || 100,\n sortOrder: options?.sortOrder || 'desc',\n searchScope: {\n namespace: namespaceName,\n project: projectName,\n ...(componentName ? { component: componentName } : {}),\n environment: environmentName,\n },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error ||\n `Failed to fetch events: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n async updateIncidentStatus(\n incidentId: string,\n status: 'acknowledged' | 'resolved',\n namespaceName: string,\n environmentName: string,\n ): Promise<void> {\n const { observerUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n const response = await this.fetchApi.fetch(\n `${observerUrl}/api/v1alpha1/incidents/${encodeURIComponent(incidentId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...DIRECT_HEADER },\n body: JSON.stringify({ status }),\n },\n );\n\n if (!response.ok) {\n const error = await this.parseError(response);\n throw new Error(\n error || `Failed to update incident: ${response.statusText}`,\n );\n }\n }\n\n async getFinOpsReports(\n namespaceName: string,\n projectName: string,\n environmentName: string,\n options?: {\n startTime?: string;\n endTime?: string;\n status?: 'pending' | 'completed' | 'failed';\n limit?: number;\n sort?: string;\n },\n ): Promise<{\n reports: FinOpsReportSummary[];\n totalCount?: number;\n }> {\n const { finopsAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!finopsAgentUrl) {\n throw new Error('FinOps service is not configured');\n }\n\n const url = new URL(`${finopsAgentUrl}/api/v1alpha1/reports`);\n url.searchParams.set('namespace', namespaceName);\n url.searchParams.set('project', projectName);\n url.searchParams.set('environment', environmentName);\n if (options?.startTime)\n url.searchParams.set('startTime', options.startTime);\n if (options?.endTime) url.searchParams.set('endTime', options.endTime);\n if (options?.status) url.searchParams.set('status', options.status);\n if (options?.limit !== undefined)\n url.searchParams.set('limit', String(options.limit));\n if (options?.sort) url.searchParams.set('sort', options.sort);\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `FinOps service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('FinOps service is not configured')) {\n throw new Error('FinOps service is not configured');\n }\n if (error.includes('Observability is not configured for component')) {\n throw new Error('Observability is not enabled for this component');\n }\n throw new Error(\n error || `Failed to fetch FinOps reports: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return {\n reports: data.reports || [],\n totalCount: data.totalCount,\n };\n }\n\n async getFinOpsReport(\n reportId: string,\n environmentName: string,\n namespaceName: string,\n ): Promise<FinOpsReportDetailed> {\n const { finopsAgentUrl } = await this.urlCache.resolveUrls(\n namespaceName,\n environmentName,\n );\n\n if (!finopsAgentUrl) {\n throw new Error('FinOps service is not configured');\n }\n\n const url = new URL(\n `${finopsAgentUrl}/api/v1alpha1/reports/${encodeURIComponent(reportId)}`,\n );\n\n let response: Response;\n try {\n response = await this.fetchApi.fetch(url.toString(), {\n headers: { ...DIRECT_HEADER },\n });\n } catch (err) {\n throw new Error(\n `FinOps service is unreachable: ${\n err instanceof Error ? err.message : err\n }`,\n );\n }\n\n if (!response.ok) {\n const error = await this.parseError(response);\n if (error.includes('FinOps service is not configured')) {\n throw new Error('FinOps service is not configured');\n }\n if (error.includes('FinOps report not found')) {\n throw new Error('FinOps report not found');\n }\n throw new Error(\n error || `Failed to fetch FinOps report: ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n private async parseError(response: Response): Promise<string> {\n try {\n const error = await response.json();\n return (\n error.error ||\n error.message ||\n `${response.status} ${response.statusText}`\n );\n } catch {\n return `${response.status} ${response.statusText}`;\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -59,7 +59,7 @@ const TracesTable = ({
59
59
  return /* @__PURE__ */ jsxs(
60
60
  Box,
61
61
  {
62
- className: `${classes.traceRow} ${isRowExpanded ? classes.expandedRow : ""} ${trace.hasErrors ? classes.errorRow : ""}`,
62
+ className: `${classes.traceRow} ${isRowExpanded ? classes.expandedRow : ""}`,
63
63
  onClick: () => handleToggle(rowKey, trace.traceId),
64
64
  role: "row",
65
65
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"TracesTable.esm.js","sources":["../../../src/components/Traces/TracesTable.tsx"],"sourcesContent":["import { FC } from 'react';\nimport {\n Paper,\n IconButton,\n Tooltip,\n Box,\n Typography,\n CircularProgress,\n} from '@material-ui/core';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\nimport {\n VirtualizedLogList,\n useRowExpansion,\n} from '@openchoreo/backstage-plugin-react';\nimport { WaterfallView } from './WaterfallView';\nimport { useTracesTableStyles } from './styles';\nimport { Trace, Span, SpanDetails } from '../../types';\nimport { formatDuration } from './utils';\nimport { getColumnStyle, TracesColumn } from './columns';\n\ninterface TraceSpansHook {\n fetchSpans: (traceId: string) => Promise<void>;\n getSpans: (traceId: string) => Span[] | undefined;\n isLoading: (traceId: string) => boolean;\n getError: (traceId: string) => string | undefined;\n}\n\ninterface SpanDetailsHook {\n fetchSpanDetails: (traceId: string, spanId: string) => Promise<void>;\n getDetails: (traceId: string, spanId: string) => SpanDetails | undefined;\n isLoading: (traceId: string, spanId: string) => boolean;\n getError: (traceId: string, spanId: string) => string | undefined;\n}\n\ninterface TracesTableProps {\n traces: Trace[];\n traceSpans: TraceSpansHook;\n spanDetails: SpanDetailsHook;\n loading?: boolean;\n}\n\n// Matches the height the table scroll area used to have.\nconst TRACES_HEIGHT = 'calc(100vh - 320px)';\n\nconst HEADER_COLUMNS: {\n key: TracesColumn;\n label: string;\n align?: 'right';\n}[] = [\n { key: 'traceName', label: 'Trace Name' },\n { key: 'startTime', label: 'Start Time' },\n { key: 'endTime', label: 'End Time' },\n { key: 'duration', label: 'Duration' },\n { key: 'spanCount', label: 'Number of Spans' },\n { key: 'details', label: 'Details', align: 'right' },\n];\n\nexport const TracesTable: FC<TracesTableProps> = ({\n traces,\n traceSpans,\n spanDetails,\n loading = false,\n}) => {\n const classes = useTracesTableStyles();\n\n // Expanded rows are tracked here (not inside per-row state) so the state\n // survives the virtualizer unmounting rows that scroll off-screen.\n const { expanded, toggle } = useRowExpansion();\n\n const handleToggle = (rowKey: string, traceId: string) => {\n // Kick off the on-demand span fetch the first time a row is opened.\n // Gated on a non-empty traceId — an empty id means the row was given a\n // synthetic key for stability and the backend can't actually resolve\n // spans for it.\n if (!expanded.has(rowKey) && traceId) {\n traceSpans.fetchSpans(traceId);\n }\n toggle(rowKey);\n };\n\n const header = (\n <Box className={classes.headerRow} role=\"row\">\n {HEADER_COLUMNS.map(col => (\n <Box\n key={col.key}\n role=\"columnheader\"\n style={{\n ...getColumnStyle(col.key),\n textAlign: col.align,\n }}\n className={classes.headerColumn}\n >\n {col.label}\n </Box>\n ))}\n </Box>\n );\n\n const renderEmptyState = () => (\n <Box className={classes.emptyState}>\n <Typography variant=\"h6\" gutterBottom>\n No traces found\n </Typography>\n <Typography variant=\"body2\">\n Try adjusting your filters or time range to see more traces.\n </Typography>\n </Box>\n );\n\n // Synthetic key fallback for traces with a missing/empty traceId so\n // multiple ID-less rows don't collide on '' inside the virtualizer or the\n // expansion Set (observed for sampled-out / partial-span traces).\n const getRowKey = (index: number) =>\n traces[index].traceId || `__noid-${index}`;\n\n const renderTraceRow = (index: number) => {\n const trace = traces[index];\n const rowKey = getRowKey(index);\n const isRowExpanded = expanded.has(rowKey);\n const spans = traceSpans.getSpans(trace.traceId);\n const spansLoading = traceSpans.isLoading(trace.traceId);\n const spansError = traceSpans.getError(trace.traceId);\n\n return (\n <Box\n className={`${classes.traceRow} ${\n isRowExpanded ? classes.expandedRow : ''\n } ${trace.hasErrors ? classes.errorRow : ''}`}\n onClick={() => handleToggle(rowKey, trace.traceId)}\n role=\"row\"\n >\n <Box className={classes.traceRowMain}>\n <Box\n style={getColumnStyle('traceName')}\n className={`${classes.cell} ${classes.traceIdCell}`}\n >\n {trace.hasErrors && (\n <Tooltip title=\"This trace contains errors\" arrow>\n <span className={classes.errorStripe} role=\"presentation\" />\n </Tooltip>\n )}\n <Tooltip title={trace.traceId}>\n <span>\n {trace.traceName || `${trace.traceId.slice(0, 8)}...`}\n </span>\n </Tooltip>\n </Box>\n <Box\n style={getColumnStyle('startTime')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.startTime}\n </Box>\n <Box\n style={getColumnStyle('endTime')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.endTime}\n </Box>\n <Box\n style={getColumnStyle('duration')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {formatDuration(trace.durationNs)}\n </Box>\n <Box\n style={getColumnStyle('spanCount')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.spanCount}\n </Box>\n <Box\n style={{ ...getColumnStyle('details'), textAlign: 'right' }}\n className={classes.cell}\n >\n <IconButton\n size=\"small\"\n onClick={e => {\n e.stopPropagation();\n handleToggle(rowKey, trace.traceId);\n }}\n className={classes.expandIcon}\n >\n {isRowExpanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </IconButton>\n </Box>\n </Box>\n\n {isRowExpanded && (\n // Stop clicks inside the expanded waterfall from bubbling to the\n // outer row onClick (which would collapse the row the user is\n // trying to inspect).\n <div onClick={e => e.stopPropagation()} role=\"presentation\">\n {spansLoading && (\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n p={2}\n >\n <CircularProgress size={24} />\n </Box>\n )}\n {spansError && (\n <Box p={2}>\n <Typography variant=\"body2\" color=\"error\">\n Failed to load spans: {spansError}\n </Typography>\n </Box>\n )}\n {!spansLoading && !spansError && spans && (\n <WaterfallView\n traceId={trace.traceId}\n spans={spans}\n spanDetails={spanDetails}\n />\n )}\n </div>\n )}\n </Box>\n );\n };\n\n return (\n <Paper className={classes.tablePaper} role=\"table\" aria-label=\"Traces\">\n {traces.length === 0 ? (\n <>\n {header}\n {!loading && renderEmptyState()}\n </>\n ) : (\n <VirtualizedLogList\n itemCount={traces.length}\n maxHeight={TRACES_HEIGHT}\n estimatedRowHeight={32}\n // Trace IDs are stable and unique — perfect natural key. Falls back\n // to a per-index synthetic when the backend returns a trace without\n // an id (sampled-out, partial span), so several ID-less rows don't\n // collide on '' inside the virtualizer or the expansion Set.\n getItemKey={getRowKey}\n header={header}\n renderRow={renderTraceRow}\n />\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA2CA,MAAM,aAAA,GAAgB,qBAAA;AAEtB,MAAM,cAAA,GAIA;AAAA,EACJ,EAAE,GAAA,EAAK,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa;AAAA,EACxC,EAAE,GAAA,EAAK,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa;AAAA,EACxC,EAAE,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,UAAA,EAAW;AAAA,EACpC,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,UAAA,EAAW;AAAA,EACrC,EAAE,GAAA,EAAK,WAAA,EAAa,KAAA,EAAO,iBAAA,EAAkB;AAAA,EAC7C,EAAE,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,SAAA,EAAW,OAAO,OAAA;AAC7C,CAAA;AAEO,MAAM,cAAoC,CAAC;AAAA,EAChD,MAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA,GAAU;AACZ,CAAA,KAAM;AACJ,EAAA,MAAM,UAAU,oBAAA,EAAqB;AAIrC,EAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,eAAA,EAAgB;AAE7C,EAAA,MAAM,YAAA,GAAe,CAAC,MAAA,EAAgB,OAAA,KAAoB;AAKxD,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,MAAM,KAAK,OAAA,EAAS;AACpC,MAAA,UAAA,CAAW,WAAW,OAAO,CAAA;AAAA,IAC/B;AACA,IAAA,MAAA,CAAO,MAAM,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,MAAM,MAAA,mBACJ,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,WAAW,IAAA,EAAK,KAAA,EACrC,QAAA,EAAA,cAAA,CAAe,GAAA,CAAI,CAAA,GAAA,qBAClB,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MAEC,IAAA,EAAK,cAAA;AAAA,MACL,KAAA,EAAO;AAAA,QACL,GAAG,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAAA,QACzB,WAAW,GAAA,CAAI;AAAA,OACjB;AAAA,MACA,WAAW,OAAA,CAAQ,YAAA;AAAA,MAElB,QAAA,EAAA,GAAA,CAAI;AAAA,KAAA;AAAA,IARA,GAAA,CAAI;AAAA,GAUZ,CAAA,EACH,CAAA;AAGF,EAAA,MAAM,mBAAmB,sBACvB,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAK,YAAA,EAAY,MAAC,QAAA,EAAA,iBAAA,EAEtC,CAAA;AAAA,oBACA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,QAAA,EAAA,8DAAA,EAE5B;AAAA,GAAA,EACF,CAAA;AAMF,EAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KACjB,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,IAAW,UAAU,KAAK,CAAA,CAAA;AAE1C,EAAA,MAAM,cAAA,GAAiB,CAAC,KAAA,KAAkB;AACxC,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,UAAU,KAAK,CAAA;AAC9B,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA;AAC/C,IAAA,MAAM,YAAA,GAAe,UAAA,CAAW,SAAA,CAAU,KAAA,CAAM,OAAO,CAAA;AACvD,IAAA,MAAM,UAAA,GAAa,UAAA,CAAW,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA;AAEpD,IAAA,uBACE,IAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,CAAA,EAAG,OAAA,CAAQ,QAAQ,IAC5B,aAAA,GAAgB,OAAA,CAAQ,WAAA,GAAc,EACxC,CAAA,CAAA,EAAI,KAAA,CAAM,SAAA,GAAY,OAAA,CAAQ,WAAW,EAAE,CAAA,CAAA;AAAA,QAC3C,OAAA,EAAS,MAAM,YAAA,CAAa,MAAA,EAAQ,MAAM,OAAO,CAAA;AAAA,QACjD,IAAA,EAAK,KAAA;AAAA,QAEL,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,YAAA,EACtB,QAAA,EAAA;AAAA,4BAAA,IAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,eAAe,WAAW,CAAA;AAAA,gBACjC,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,QAAQ,WAAW,CAAA,CAAA;AAAA,gBAEhD,QAAA,EAAA;AAAA,kBAAA,KAAA,CAAM,SAAA,oBACL,GAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAM,8BAA6B,KAAA,EAAK,IAAA,EAC/C,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,WAAA,EAAa,IAAA,EAAK,gBAAe,CAAA,EAC5D,CAAA;AAAA,sCAED,OAAA,EAAA,EAAQ,KAAA,EAAO,KAAA,CAAM,OAAA,EACpB,8BAAC,MAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,SAAA,IAAa,CAAA,EAAG,MAAM,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAC,CAAC,OAClD,CAAA,EACF;AAAA;AAAA;AAAA,aACF;AAAA,4BACA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,eAAe,WAAW,CAAA;AAAA,gBACjC,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,QAAQ,SAAS,CAAA,CAAA;AAAA,gBAE9C,QAAA,EAAA,KAAA,CAAM;AAAA;AAAA,aACT;AAAA,4BACA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,eAAe,SAAS,CAAA;AAAA,gBAC/B,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,QAAQ,SAAS,CAAA,CAAA;AAAA,gBAE9C,QAAA,EAAA,KAAA,CAAM;AAAA;AAAA,aACT;AAAA,4BACA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,eAAe,UAAU,CAAA;AAAA,gBAChC,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,QAAQ,SAAS,CAAA,CAAA;AAAA,gBAE9C,QAAA,EAAA,cAAA,CAAe,MAAM,UAAU;AAAA;AAAA,aAClC;AAAA,4BACA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,eAAe,WAAW,CAAA;AAAA,gBACjC,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,QAAQ,SAAS,CAAA,CAAA;AAAA,gBAE9C,QAAA,EAAA,KAAA,CAAM;AAAA;AAAA,aACT;AAAA,4BACA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,OAAO,EAAE,GAAG,eAAe,SAAS,CAAA,EAAG,WAAW,OAAA,EAAQ;AAAA,gBAC1D,WAAW,OAAA,CAAQ,IAAA;AAAA,gBAEnB,QAAA,kBAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,OAAA;AAAA,oBACL,SAAS,CAAA,CAAA,KAAK;AACZ,sBAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,sBAAA,YAAA,CAAa,MAAA,EAAQ,MAAM,OAAO,CAAA;AAAA,oBACpC,CAAA;AAAA,oBACA,WAAW,OAAA,CAAQ,UAAA;AAAA,oBAElB,QAAA,EAAA,aAAA,mBAAgB,GAAA,CAAC,cAAA,EAAA,EAAe,CAAA,uBAAM,cAAA,EAAA,EAAe;AAAA;AAAA;AACxD;AAAA;AACF,WAAA,EACF,CAAA;AAAA,UAEC,aAAA;AAAA;AAAA;AAAA,0BAIC,IAAA,CAAC,SAAI,OAAA,EAAS,CAAA,CAAA,KAAK,EAAE,eAAA,EAAgB,EAAG,MAAK,cAAA,EAC1C,QAAA,EAAA;AAAA,YAAA,YAAA,oBACC,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,MAAA;AAAA,gBACR,cAAA,EAAe,QAAA;AAAA,gBACf,UAAA,EAAW,QAAA;AAAA,gBACX,CAAA,EAAG,CAAA;AAAA,gBAEH,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,aAC9B;AAAA,YAED,UAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAI,CAAA,EAAG,CAAA,EACN,+BAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,OAAA,EAAQ,QAAA,EAAA;AAAA,cAAA,wBAAA;AAAA,cACjB;AAAA,aAAA,EACzB,CAAA,EACF,CAAA;AAAA,YAED,CAAC,YAAA,IAAgB,CAAC,UAAA,IAAc,KAAA,oBAC/B,GAAA;AAAA,cAAC,aAAA;AAAA,cAAA;AAAA,gBACC,SAAS,KAAA,CAAM,OAAA;AAAA,gBACf,KAAA;AAAA,gBACA;AAAA;AAAA;AACF,WAAA,EAEJ;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ,CAAA;AAEA,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAK,OAAA,EAAQ,YAAA,EAAW,QAAA,EAC3D,QAAA,EAAA,MAAA,CAAO,MAAA,KAAW,CAAA,mBACjB,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,MAAA;AAAA,IACA,CAAC,WAAW,gBAAA;AAAiB,GAAA,EAChC,CAAA,mBAEA,GAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACC,WAAW,MAAA,CAAO,MAAA;AAAA,MAClB,SAAA,EAAW,aAAA;AAAA,MACX,kBAAA,EAAoB,EAAA;AAAA,MAKpB,UAAA,EAAY,SAAA;AAAA,MACZ,MAAA;AAAA,MACA,SAAA,EAAW;AAAA;AAAA,GACb,EAEJ,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TracesTable.esm.js","sources":["../../../src/components/Traces/TracesTable.tsx"],"sourcesContent":["import { FC } from 'react';\nimport {\n Paper,\n IconButton,\n Tooltip,\n Box,\n Typography,\n CircularProgress,\n} from '@material-ui/core';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\nimport {\n VirtualizedLogList,\n useRowExpansion,\n} from '@openchoreo/backstage-plugin-react';\nimport { WaterfallView } from './WaterfallView';\nimport { useTracesTableStyles } from './styles';\nimport { Trace, Span, SpanDetails } from '../../types';\nimport { formatDuration } from './utils';\nimport { getColumnStyle, TracesColumn } from './columns';\n\ninterface TraceSpansHook {\n fetchSpans: (traceId: string) => Promise<void>;\n getSpans: (traceId: string) => Span[] | undefined;\n isLoading: (traceId: string) => boolean;\n getError: (traceId: string) => string | undefined;\n}\n\ninterface SpanDetailsHook {\n fetchSpanDetails: (traceId: string, spanId: string) => Promise<void>;\n getDetails: (traceId: string, spanId: string) => SpanDetails | undefined;\n isLoading: (traceId: string, spanId: string) => boolean;\n getError: (traceId: string, spanId: string) => string | undefined;\n}\n\ninterface TracesTableProps {\n traces: Trace[];\n traceSpans: TraceSpansHook;\n spanDetails: SpanDetailsHook;\n loading?: boolean;\n}\n\n// Matches the height the table scroll area used to have.\nconst TRACES_HEIGHT = 'calc(100vh - 320px)';\n\nconst HEADER_COLUMNS: {\n key: TracesColumn;\n label: string;\n align?: 'right';\n}[] = [\n { key: 'traceName', label: 'Trace Name' },\n { key: 'startTime', label: 'Start Time' },\n { key: 'endTime', label: 'End Time' },\n { key: 'duration', label: 'Duration' },\n { key: 'spanCount', label: 'Number of Spans' },\n { key: 'details', label: 'Details', align: 'right' },\n];\n\nexport const TracesTable: FC<TracesTableProps> = ({\n traces,\n traceSpans,\n spanDetails,\n loading = false,\n}) => {\n const classes = useTracesTableStyles();\n\n // Expanded rows are tracked here (not inside per-row state) so the state\n // survives the virtualizer unmounting rows that scroll off-screen.\n const { expanded, toggle } = useRowExpansion();\n\n const handleToggle = (rowKey: string, traceId: string) => {\n // Kick off the on-demand span fetch the first time a row is opened.\n // Gated on a non-empty traceId — an empty id means the row was given a\n // synthetic key for stability and the backend can't actually resolve\n // spans for it.\n if (!expanded.has(rowKey) && traceId) {\n traceSpans.fetchSpans(traceId);\n }\n toggle(rowKey);\n };\n\n const header = (\n <Box className={classes.headerRow} role=\"row\">\n {HEADER_COLUMNS.map(col => (\n <Box\n key={col.key}\n role=\"columnheader\"\n style={{\n ...getColumnStyle(col.key),\n textAlign: col.align,\n }}\n className={classes.headerColumn}\n >\n {col.label}\n </Box>\n ))}\n </Box>\n );\n\n const renderEmptyState = () => (\n <Box className={classes.emptyState}>\n <Typography variant=\"h6\" gutterBottom>\n No traces found\n </Typography>\n <Typography variant=\"body2\">\n Try adjusting your filters or time range to see more traces.\n </Typography>\n </Box>\n );\n\n // Synthetic key fallback for traces with a missing/empty traceId so\n // multiple ID-less rows don't collide on '' inside the virtualizer or the\n // expansion Set (observed for sampled-out / partial-span traces).\n const getRowKey = (index: number) =>\n traces[index].traceId || `__noid-${index}`;\n\n const renderTraceRow = (index: number) => {\n const trace = traces[index];\n const rowKey = getRowKey(index);\n const isRowExpanded = expanded.has(rowKey);\n const spans = traceSpans.getSpans(trace.traceId);\n const spansLoading = traceSpans.isLoading(trace.traceId);\n const spansError = traceSpans.getError(trace.traceId);\n\n return (\n <Box\n className={`${classes.traceRow} ${\n isRowExpanded ? classes.expandedRow : ''\n }`}\n onClick={() => handleToggle(rowKey, trace.traceId)}\n role=\"row\"\n >\n <Box className={classes.traceRowMain}>\n <Box\n style={getColumnStyle('traceName')}\n className={`${classes.cell} ${classes.traceIdCell}`}\n >\n {trace.hasErrors && (\n <Tooltip title=\"This trace contains errors\" arrow>\n <span className={classes.errorStripe} role=\"presentation\" />\n </Tooltip>\n )}\n <Tooltip title={trace.traceId}>\n <span>\n {trace.traceName || `${trace.traceId.slice(0, 8)}...`}\n </span>\n </Tooltip>\n </Box>\n <Box\n style={getColumnStyle('startTime')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.startTime}\n </Box>\n <Box\n style={getColumnStyle('endTime')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.endTime}\n </Box>\n <Box\n style={getColumnStyle('duration')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {formatDuration(trace.durationNs)}\n </Box>\n <Box\n style={getColumnStyle('spanCount')}\n className={`${classes.cell} ${classes.traceCell}`}\n >\n {trace.spanCount}\n </Box>\n <Box\n style={{ ...getColumnStyle('details'), textAlign: 'right' }}\n className={classes.cell}\n >\n <IconButton\n size=\"small\"\n onClick={e => {\n e.stopPropagation();\n handleToggle(rowKey, trace.traceId);\n }}\n className={classes.expandIcon}\n >\n {isRowExpanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </IconButton>\n </Box>\n </Box>\n\n {isRowExpanded && (\n // Stop clicks inside the expanded waterfall from bubbling to the\n // outer row onClick (which would collapse the row the user is\n // trying to inspect).\n <div onClick={e => e.stopPropagation()} role=\"presentation\">\n {spansLoading && (\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n p={2}\n >\n <CircularProgress size={24} />\n </Box>\n )}\n {spansError && (\n <Box p={2}>\n <Typography variant=\"body2\" color=\"error\">\n Failed to load spans: {spansError}\n </Typography>\n </Box>\n )}\n {!spansLoading && !spansError && spans && (\n <WaterfallView\n traceId={trace.traceId}\n spans={spans}\n spanDetails={spanDetails}\n />\n )}\n </div>\n )}\n </Box>\n );\n };\n\n return (\n <Paper className={classes.tablePaper} role=\"table\" aria-label=\"Traces\">\n {traces.length === 0 ? (\n <>\n {header}\n {!loading && renderEmptyState()}\n </>\n ) : (\n <VirtualizedLogList\n itemCount={traces.length}\n maxHeight={TRACES_HEIGHT}\n estimatedRowHeight={32}\n // Trace IDs are stable and unique — perfect natural key. Falls back\n // to a per-index synthetic when the backend returns a trace without\n // an id (sampled-out, partial span), so several ID-less rows don't\n // collide on '' inside the virtualizer or the expansion Set.\n getItemKey={getRowKey}\n header={header}\n renderRow={renderTraceRow}\n />\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
5
5
  import ExpandLessIcon from '@material-ui/icons/ExpandLess';
6
6
  import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
7
7
  import { useWaterfallStyles } from './styles.esm.js';
8
- import { parseRfc3339NanoToNanoseconds, formatDuration, formatTimeFromString } from './utils.esm.js';
8
+ import { parseRfc3339NanoToNanoseconds, isSpanError, formatDuration, formatTimeFromString, getSpanStatusCode } from './utils.esm.js';
9
9
 
10
10
  function flattenObject(obj, prefix = "") {
11
11
  const rows = [];
@@ -83,12 +83,6 @@ const SpanDetailsPanel = ({ details, traceId }) => {
83
83
  { label: "End Time", value: formatTimeFromString(details.endTime) },
84
84
  { label: "Duration", value: formatDuration(details.durationNs) }
85
85
  ];
86
- let statusColor = "#94A3B8";
87
- if (details.status === "error") {
88
- statusColor = "#EF4444";
89
- } else if (details.status === "ok") {
90
- statusColor = "#10B981";
91
- }
92
86
  return /* @__PURE__ */ jsxs(Box, { children: [
93
87
  /* @__PURE__ */ jsxs(Box, { mb: 2, children: [
94
88
  /* @__PURE__ */ jsx(
@@ -134,37 +128,9 @@ const SpanDetailsPanel = ({ details, traceId }) => {
134
128
  children: value
135
129
  }
136
130
  )
137
- ] }, label)),
138
- details.status && /* @__PURE__ */ jsxs(Box, { display: "flex", style: { gap: 8, marginBottom: 2 }, children: [
139
- /* @__PURE__ */ jsx(
140
- Typography,
141
- {
142
- variant: "caption",
143
- style: {
144
- fontSize: "0.7rem",
145
- fontFamily: "monospace",
146
- fontWeight: 600,
147
- minWidth: 220,
148
- flexShrink: 0
149
- },
150
- children: "Status"
151
- }
152
- ),
153
- /* @__PURE__ */ jsx(
154
- Typography,
155
- {
156
- variant: "caption",
157
- style: {
158
- fontSize: "0.7rem",
159
- fontFamily: "monospace",
160
- fontWeight: 600,
161
- color: statusColor
162
- },
163
- children: details.status
164
- }
165
- )
166
- ] })
131
+ ] }, label))
167
132
  ] }),
133
+ /* @__PURE__ */ jsx(AttributeSection, { label: "Status", data: details.status }),
168
134
  /* @__PURE__ */ jsx(AttributeSection, { label: "Attributes", data: details.attributes }),
169
135
  /* @__PURE__ */ jsx(
170
136
  AttributeSection,
@@ -184,8 +150,8 @@ const WaterfallView = ({
184
150
  const theme = useTheme();
185
151
  const [collapsedSpans, setCollapsedSpans] = useState(/* @__PURE__ */ new Set());
186
152
  const [selectedSpanId, setSelectedSpanId] = useState(null);
187
- const getSpanColor = (spanName, depth, status) => {
188
- if (status === "error") return "#FCA5A5";
153
+ const getSpanColor = (spanName, depth, isError) => {
154
+ if (isError) return "#FCA5A5";
189
155
  const colors = [
190
156
  "#93C5FD",
191
157
  // blue-300
@@ -331,7 +297,11 @@ const WaterfallView = ({
331
297
  calculateWidth(span.startTime, span.endTime),
332
298
  0.5
333
299
  );
334
- const color = getSpanColor(span.spanName, span.depth, span.status);
300
+ const color = getSpanColor(
301
+ span.spanName,
302
+ span.depth,
303
+ isSpanError(span.status)
304
+ );
335
305
  const indent = span.depth * 20;
336
306
  const hasChildren = span.children.length > 0;
337
307
  const isCollapsed = collapsedSpans.has(span.spanId);
@@ -353,7 +323,7 @@ const WaterfallView = ({
353
323
  }
354
324
  ),
355
325
  !hasChildren && /* @__PURE__ */ jsx(Box, { style: { width: "20px" } }),
356
- span.status === "error" && /* @__PURE__ */ jsx(Tooltip, { title: "Span error", children: /* @__PURE__ */ jsx(ErrorOutlineIcon, { className: classes.spanErrorIcon }) }),
326
+ isSpanError(span.status) && /* @__PURE__ */ jsx(Tooltip, { title: "Span error", children: /* @__PURE__ */ jsx(ErrorOutlineIcon, { className: classes.spanErrorIcon }) }),
357
327
  /* @__PURE__ */ jsx(
358
328
  Box,
359
329
  {
@@ -496,17 +466,17 @@ const WaterfallView = ({
496
466
  }
497
467
  )
498
468
  ] }),
499
- span.status && /* @__PURE__ */ jsxs(Box, { className: classes.tooltipRow, children: [
469
+ getSpanStatusCode(span.status) && /* @__PURE__ */ jsxs(Box, { className: classes.tooltipRow, children: [
500
470
  /* @__PURE__ */ jsx(
501
471
  Typography,
502
472
  {
503
473
  variant: "caption",
504
474
  component: "span",
505
475
  className: classes.tooltipLabel,
506
- children: "Status:"
476
+ children: "Status Code:"
507
477
  }
508
478
  ),
509
- /* @__PURE__ */ jsx(Typography, { variant: "caption", children: span.status })
479
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: getSpanStatusCode(span.status) })
510
480
  ] })
511
481
  ] }),
512
482
  arrow: true,
@@ -1 +1 @@
1
- {"version":3,"file":"WaterfallView.esm.js","sources":["../../../src/components/Traces/WaterfallView.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Box,\n Typography,\n Tooltip,\n IconButton,\n Divider,\n useTheme,\n CircularProgress,\n} from '@material-ui/core';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\nimport ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';\nimport { useWaterfallStyles } from './styles';\nimport { Span, SpanDetails } from '../../types';\nimport {\n parseRfc3339NanoToNanoseconds,\n formatDuration,\n formatTimeFromString,\n} from './utils';\n\ninterface SpanDetailsHook {\n fetchSpanDetails: (traceId: string, spanId: string) => Promise<void>;\n getDetails: (traceId: string, spanId: string) => SpanDetails | undefined;\n isLoading: (traceId: string, spanId: string) => boolean;\n getError: (traceId: string, spanId: string) => string | undefined;\n}\n\ninterface WaterfallViewProps {\n traceId: string;\n spans: Span[];\n spanDetails: SpanDetailsHook;\n}\n\ninterface SpanWithDepth extends Span {\n depth: number;\n children: SpanWithDepth[];\n}\n\n/** Flatten a nested object into dot-separated key: value rows. */\nfunction flattenObject(\n obj: Record<string, unknown>,\n prefix = '',\n): Array<{ key: string; value: string }> {\n const rows: Array<{ key: string; value: string }> = [];\n for (const [k, v] of Object.entries(obj)) {\n const fullKey = prefix ? `${prefix}.${k}` : k;\n if (v !== null && typeof v === 'object' && !Array.isArray(v)) {\n rows.push(...flattenObject(v as Record<string, unknown>, fullKey));\n } else {\n rows.push({ key: fullKey, value: String(v ?? '') });\n }\n }\n return rows;\n}\n\ninterface AttributeSectionProps {\n label: string;\n data: Record<string, unknown> | undefined;\n}\n\nconst AttributeSection = ({ label, data }: AttributeSectionProps) => {\n const theme = useTheme();\n if (!data || Object.keys(data).length === 0) return null;\n const rows = flattenObject(data);\n return (\n <Box mb={2}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.65rem',\n fontWeight: 700,\n display: 'block',\n marginBottom: 4,\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n {label}\n </Typography>\n {rows.map(({ key, value }) => (\n <Box key={key} display=\"flex\" style={{ gap: 8, marginBottom: 2 }}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n minWidth: 220,\n flexShrink: 0,\n wordBreak: 'break-all',\n }}\n >\n {key}\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n wordBreak: 'break-word',\n }}\n >\n {value}\n </Typography>\n </Box>\n ))}\n </Box>\n );\n};\n\ninterface SpanDetailsPanelProps {\n details: SpanDetails;\n traceId: string;\n}\n\nconst SpanDetailsPanel = ({ details, traceId }: SpanDetailsPanelProps) => {\n const theme = useTheme();\n const coreFields: Array<{ label: string; value: string }> = [\n { label: 'Trace ID', value: traceId },\n { label: 'Span ID', value: details.spanId },\n { label: 'Span Name', value: details.spanName },\n ...(details.spanKind\n ? [{ label: 'Span Kind', value: details.spanKind }]\n : []),\n ...(details.parentSpanId\n ? [{ label: 'Parent Span ID', value: details.parentSpanId }]\n : []),\n { label: 'Start Time', value: formatTimeFromString(details.startTime) },\n { label: 'End Time', value: formatTimeFromString(details.endTime) },\n { label: 'Duration', value: formatDuration(details.durationNs) },\n ];\n\n let statusColor = '#94A3B8';\n if (details.status === 'error') {\n statusColor = '#EF4444';\n } else if (details.status === 'ok') {\n statusColor = '#10B981';\n }\n\n return (\n <Box>\n {/* Core span fields */}\n <Box mb={2}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.65rem',\n fontWeight: 700,\n display: 'block',\n marginBottom: 4,\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Span Info\n </Typography>\n {coreFields.map(({ label, value }) => (\n <Box key={label} display=\"flex\" style={{ gap: 8, marginBottom: 2 }}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n minWidth: 220,\n flexShrink: 0,\n }}\n >\n {label}\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n wordBreak: 'break-all',\n }}\n >\n {value}\n </Typography>\n </Box>\n ))}\n {details.status && (\n <Box display=\"flex\" style={{ gap: 8, marginBottom: 2 }}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n minWidth: 220,\n flexShrink: 0,\n }}\n >\n Status\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n color: statusColor,\n }}\n >\n {details.status}\n </Typography>\n </Box>\n )}\n </Box>\n\n <AttributeSection label=\"Attributes\" data={details.attributes} />\n <AttributeSection\n label=\"Resource Attributes\"\n data={details.resourceAttributes}\n />\n </Box>\n );\n};\n\nexport const WaterfallView = ({\n traceId,\n spans,\n spanDetails,\n}: WaterfallViewProps) => {\n const classes = useWaterfallStyles();\n const theme = useTheme();\n const [collapsedSpans, setCollapsedSpans] = useState<Set<string>>(new Set());\n const [selectedSpanId, setSelectedSpanId] = useState<string | null>(null);\n\n // Color palette for different span types\n const getSpanColor = (\n spanName: string,\n depth: number,\n status?: string,\n ): string => {\n if (status === 'error') return '#FCA5A5'; // light red\n\n const colors = [\n '#93C5FD', // blue-300\n '#CBD5E1', // slate-300\n '#C4B5FD', // violet-300\n '#6EE7B7', // emerald-300\n '#67E8F9', // cyan-300\n ];\n\n if (depth === 0) return colors[0];\n if (depth === 1) return colors[1];\n\n let hash = 0;\n for (let i = 0; i < spanName.length; i++) {\n hash = spanName.charCodeAt(i) + ((hash << 5) - hash);\n }\n return colors[Math.abs(hash) % colors.length];\n };\n\n const { spanTree, minTime, timeRange } = useMemo(() => {\n if (!spans || spans.length === 0) {\n return { spanTree: [], minTime: 0, timeRange: 0 };\n }\n\n const times = spans.flatMap(span => [\n parseRfc3339NanoToNanoseconds(span.startTime),\n parseRfc3339NanoToNanoseconds(span.endTime),\n ]);\n\n const min = Math.min(...times);\n const max = Math.max(...times);\n const range = max - min || 1;\n\n const spanMap = new Map<string, SpanWithDepth>();\n const rootSpans: SpanWithDepth[] = [];\n\n spans.forEach(span => {\n spanMap.set(span.spanId, { ...span, depth: 0, children: [] });\n });\n\n spans.forEach(span => {\n const spanWithDepth = spanMap.get(span.spanId)!;\n\n if (span.parentSpanId && spanMap.has(span.parentSpanId)) {\n const parent = spanMap.get(span.parentSpanId)!;\n parent.children.push(spanWithDepth);\n spanWithDepth.depth = parent.depth + 1;\n } else {\n rootSpans.push(spanWithDepth);\n }\n });\n\n if (rootSpans.length === 0) {\n const sortedSpans = [...spans].sort((a, b) => {\n const aStart = parseRfc3339NanoToNanoseconds(a.startTime);\n const bStart = parseRfc3339NanoToNanoseconds(b.startTime);\n return aStart - bStart;\n });\n\n if (sortedSpans.length > 0) {\n const rootSpan = spanMap.get(sortedSpans[0].spanId)!;\n rootSpans.push(rootSpan);\n rootSpan.depth = 0;\n\n sortedSpans.slice(1).forEach(span => {\n const spanWithDepth = spanMap.get(span.spanId)!;\n const spanStart = parseRfc3339NanoToNanoseconds(span.startTime);\n const spanEnd = parseRfc3339NanoToNanoseconds(span.endTime);\n\n let parent: SpanWithDepth | null = null;\n let maxDepth = -1;\n\n sortedSpans.slice(0, sortedSpans.indexOf(span)).forEach(prevSpan => {\n const prevSpanWithDepth = spanMap.get(prevSpan.spanId);\n if (!prevSpanWithDepth) return;\n\n const prevStart = parseRfc3339NanoToNanoseconds(prevSpan.startTime);\n const prevEnd = parseRfc3339NanoToNanoseconds(prevSpan.endTime);\n\n if (\n spanStart >= prevStart &&\n spanEnd <= prevEnd &&\n prevSpanWithDepth.depth > maxDepth\n ) {\n parent = prevSpanWithDepth;\n maxDepth = prevSpanWithDepth.depth;\n }\n });\n\n if (parent) {\n const parentSpan = parent as SpanWithDepth;\n parentSpan.children.push(spanWithDepth);\n spanWithDepth.depth = parentSpan.depth + 1;\n } else {\n rootSpans.push(spanWithDepth);\n spanWithDepth.depth = 0;\n }\n });\n }\n }\n\n return { spanTree: rootSpans, minTime: min, timeRange: range };\n }, [spans]);\n\n const visibleSpans = useMemo(() => {\n const getVisibleSpans = (nodes: SpanWithDepth[]): SpanWithDepth[] => {\n const result: SpanWithDepth[] = [];\n nodes.forEach((node: SpanWithDepth) => {\n result.push(node);\n if (!collapsedSpans.has(node.spanId)) {\n result.push(...getVisibleSpans(node.children));\n }\n });\n return result;\n };\n return getVisibleSpans(spanTree);\n }, [spanTree, collapsedSpans]);\n\n const toggleCollapse = (spanId: string) => {\n setCollapsedSpans(prev => {\n const newSet = new Set(prev);\n if (newSet.has(spanId)) {\n newSet.delete(spanId);\n } else {\n newSet.add(spanId);\n }\n return newSet;\n });\n };\n\n const handleSpanClick = (spanId: string) => {\n if (selectedSpanId === spanId) {\n setSelectedSpanId(null);\n return;\n }\n setSelectedSpanId(spanId);\n spanDetails.fetchSpanDetails(traceId, spanId);\n };\n\n if (spanTree.length === 0) {\n return (\n <Box className={classes.container}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n No spans available for this trace\n </Typography>\n </Box>\n );\n }\n\n const calculatePosition = (startTime: string): number => {\n const time = parseRfc3339NanoToNanoseconds(startTime);\n return ((time - minTime) / timeRange) * 100;\n };\n\n const calculateWidth = (startTime: string, endTime: string): number => {\n const start = parseRfc3339NanoToNanoseconds(startTime);\n const end = parseRfc3339NanoToNanoseconds(endTime);\n const duration = end - start;\n return (duration / timeRange) * 100;\n };\n\n const selectedSpan = selectedSpanId\n ? visibleSpans.find(s => s.spanId === selectedSpanId)\n : null;\n const selectedDetails = selectedSpanId\n ? spanDetails.getDetails(traceId, selectedSpanId)\n : null;\n const detailsLoading = selectedSpanId\n ? spanDetails.isLoading(traceId, selectedSpanId)\n : false;\n const detailsError = selectedSpanId\n ? spanDetails.getError(traceId, selectedSpanId)\n : null;\n\n return (\n <Box className={classes.container}>\n <Typography variant=\"subtitle2\" gutterBottom>\n Trace ID: {traceId}\n </Typography>\n <Box className={classes.timeline}>\n {visibleSpans.map(span => {\n const left = calculatePosition(span.startTime);\n const width = Math.max(\n calculateWidth(span.startTime, span.endTime),\n 0.5,\n );\n const color = getSpanColor(span.spanName, span.depth, span.status);\n const indent = span.depth * 20;\n const hasChildren = span.children.length > 0;\n const isCollapsed = collapsedSpans.has(span.spanId);\n const isSelected = selectedSpanId === span.spanId;\n\n return (\n <Box key={span.spanId} className={classes.spanRow}>\n <Box\n className={classes.spanLabel}\n style={{ paddingLeft: `${indent}px` }}\n >\n {hasChildren && (\n <IconButton\n size=\"small\"\n className={classes.collapseButton}\n onClick={() => toggleCollapse(span.spanId)}\n >\n {isCollapsed ? <ExpandMoreIcon /> : <ExpandLessIcon />}\n </IconButton>\n )}\n {!hasChildren && <Box style={{ width: '20px' }} />}\n {span.status === 'error' && (\n <Tooltip title=\"Span error\">\n <ErrorOutlineIcon className={classes.spanErrorIcon} />\n </Tooltip>\n )}\n <Box\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n }}\n title={span.spanName}\n >\n {span.spanName}\n </Box>\n </Box>\n <Box className={classes.spanBarContainer}>\n <Tooltip\n title={\n <Box className={classes.tooltipContent}>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n style={{\n fontWeight: 600,\n color: 'inherit',\n marginBottom: 8,\n }}\n >\n {span.spanName}\n </Typography>\n </Box>\n <Divider style={{ marginBottom: 8, marginTop: 4 }} />\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Span ID:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {span.spanId}\n </Typography>\n </Box>\n {span.spanKind && (\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Kind:\n </Typography>\n <Typography variant=\"caption\">\n {span.spanKind}\n </Typography>\n </Box>\n )}\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Start Time:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n fontSize: '0.7rem',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {formatTimeFromString(span.startTime)}\n </Typography>\n </Box>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n End Time:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n fontSize: '0.7rem',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {formatTimeFromString(span.endTime)}\n </Typography>\n </Box>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Duration:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{ fontWeight: 500 }}\n >\n {formatDuration(span.durationNs)}\n </Typography>\n </Box>\n {span.status && (\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Status:\n </Typography>\n <Typography variant=\"caption\">\n {span.status}\n </Typography>\n </Box>\n )}\n </Box>\n }\n arrow\n placement=\"top\"\n enterDelay={200}\n leaveDelay={100}\n >\n <Box\n className={classes.spanBar}\n style={{\n left: `${left}%`,\n width: `${width}%`,\n backgroundColor: color,\n outline: isSelected\n ? `2px solid ${theme.palette.primary.main}`\n : undefined,\n }}\n onClick={() => handleSpanClick(span.spanId)}\n >\n {width > 5 && formatDuration(span.durationNs)}\n </Box>\n </Tooltip>\n </Box>\n </Box>\n );\n })}\n </Box>\n\n {/* Span details panel — shown when a span bar is clicked */}\n {selectedSpanId && (\n <Box\n mt={2}\n p={2}\n style={{\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n backgroundColor: theme.palette.background.paper,\n }}\n >\n <Typography variant=\"subtitle2\" gutterBottom>\n Span Details{selectedSpan ? `: ${selectedSpan.spanName}` : ''}\n </Typography>\n <Divider style={{ marginBottom: 8 }} />\n\n {detailsLoading && (\n <Box display=\"flex\" alignItems=\"center\" style={{ gap: 8 }}>\n <CircularProgress size={16} />\n <Typography variant=\"body2\" color=\"textSecondary\">\n Loading span details...\n </Typography>\n </Box>\n )}\n\n {detailsError && (\n <Typography variant=\"body2\" color=\"error\">\n Failed to load span details: {detailsError}\n </Typography>\n )}\n\n {selectedDetails && !detailsLoading && (\n <SpanDetailsPanel details={selectedDetails} traceId={traceId} />\n )}\n\n {!detailsLoading && !detailsError && !selectedDetails && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Click a span bar to view its details.\n </Typography>\n )}\n </Box>\n )}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WaterfallView.esm.js","sources":["../../../src/components/Traces/WaterfallView.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Box,\n Typography,\n Tooltip,\n IconButton,\n Divider,\n useTheme,\n CircularProgress,\n} from '@material-ui/core';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\nimport ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';\nimport { useWaterfallStyles } from './styles';\nimport { Span, SpanDetails } from '../../types';\nimport {\n parseRfc3339NanoToNanoseconds,\n formatDuration,\n formatTimeFromString,\n isSpanError,\n getSpanStatusCode,\n} from './utils';\n\ninterface SpanDetailsHook {\n fetchSpanDetails: (traceId: string, spanId: string) => Promise<void>;\n getDetails: (traceId: string, spanId: string) => SpanDetails | undefined;\n isLoading: (traceId: string, spanId: string) => boolean;\n getError: (traceId: string, spanId: string) => string | undefined;\n}\n\ninterface WaterfallViewProps {\n traceId: string;\n spans: Span[];\n spanDetails: SpanDetailsHook;\n}\n\ninterface SpanWithDepth extends Span {\n depth: number;\n children: SpanWithDepth[];\n}\n\n/** Flatten a nested object into dot-separated key: value rows. */\nfunction flattenObject(\n obj: Record<string, unknown>,\n prefix = '',\n): Array<{ key: string; value: string }> {\n const rows: Array<{ key: string; value: string }> = [];\n for (const [k, v] of Object.entries(obj)) {\n const fullKey = prefix ? `${prefix}.${k}` : k;\n if (v !== null && typeof v === 'object' && !Array.isArray(v)) {\n rows.push(...flattenObject(v as Record<string, unknown>, fullKey));\n } else {\n rows.push({ key: fullKey, value: String(v ?? '') });\n }\n }\n return rows;\n}\n\ninterface AttributeSectionProps {\n label: string;\n data: Record<string, unknown> | undefined;\n}\n\nconst AttributeSection = ({ label, data }: AttributeSectionProps) => {\n const theme = useTheme();\n if (!data || Object.keys(data).length === 0) return null;\n const rows = flattenObject(data);\n return (\n <Box mb={2}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.65rem',\n fontWeight: 700,\n display: 'block',\n marginBottom: 4,\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n {label}\n </Typography>\n {rows.map(({ key, value }) => (\n <Box key={key} display=\"flex\" style={{ gap: 8, marginBottom: 2 }}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n minWidth: 220,\n flexShrink: 0,\n wordBreak: 'break-all',\n }}\n >\n {key}\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n wordBreak: 'break-word',\n }}\n >\n {value}\n </Typography>\n </Box>\n ))}\n </Box>\n );\n};\n\ninterface SpanDetailsPanelProps {\n details: SpanDetails;\n traceId: string;\n}\n\nconst SpanDetailsPanel = ({ details, traceId }: SpanDetailsPanelProps) => {\n const theme = useTheme();\n const coreFields: Array<{ label: string; value: string }> = [\n { label: 'Trace ID', value: traceId },\n { label: 'Span ID', value: details.spanId },\n { label: 'Span Name', value: details.spanName },\n ...(details.spanKind\n ? [{ label: 'Span Kind', value: details.spanKind }]\n : []),\n ...(details.parentSpanId\n ? [{ label: 'Parent Span ID', value: details.parentSpanId }]\n : []),\n { label: 'Start Time', value: formatTimeFromString(details.startTime) },\n { label: 'End Time', value: formatTimeFromString(details.endTime) },\n { label: 'Duration', value: formatDuration(details.durationNs) },\n ];\n\n return (\n <Box>\n {/* Core span fields */}\n <Box mb={2}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.65rem',\n fontWeight: 700,\n display: 'block',\n marginBottom: 4,\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Span Info\n </Typography>\n {coreFields.map(({ label, value }) => (\n <Box key={label} display=\"flex\" style={{ gap: 8, marginBottom: 2 }}>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n fontWeight: 600,\n minWidth: 220,\n flexShrink: 0,\n }}\n >\n {label}\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n wordBreak: 'break-all',\n }}\n >\n {value}\n </Typography>\n </Box>\n ))}\n </Box>\n\n <AttributeSection label=\"Status\" data={details.status} />\n <AttributeSection label=\"Attributes\" data={details.attributes} />\n <AttributeSection\n label=\"Resource Attributes\"\n data={details.resourceAttributes}\n />\n </Box>\n );\n};\n\nexport const WaterfallView = ({\n traceId,\n spans,\n spanDetails,\n}: WaterfallViewProps) => {\n const classes = useWaterfallStyles();\n const theme = useTheme();\n const [collapsedSpans, setCollapsedSpans] = useState<Set<string>>(new Set());\n const [selectedSpanId, setSelectedSpanId] = useState<string | null>(null);\n\n // Color palette for different span types\n const getSpanColor = (\n spanName: string,\n depth: number,\n isError: boolean,\n ): string => {\n if (isError) return '#FCA5A5'; // light red\n\n const colors = [\n '#93C5FD', // blue-300\n '#CBD5E1', // slate-300\n '#C4B5FD', // violet-300\n '#6EE7B7', // emerald-300\n '#67E8F9', // cyan-300\n ];\n\n if (depth === 0) return colors[0];\n if (depth === 1) return colors[1];\n\n let hash = 0;\n for (let i = 0; i < spanName.length; i++) {\n hash = spanName.charCodeAt(i) + ((hash << 5) - hash);\n }\n return colors[Math.abs(hash) % colors.length];\n };\n\n const { spanTree, minTime, timeRange } = useMemo(() => {\n if (!spans || spans.length === 0) {\n return { spanTree: [], minTime: 0, timeRange: 0 };\n }\n\n const times = spans.flatMap(span => [\n parseRfc3339NanoToNanoseconds(span.startTime),\n parseRfc3339NanoToNanoseconds(span.endTime),\n ]);\n\n const min = Math.min(...times);\n const max = Math.max(...times);\n const range = max - min || 1;\n\n const spanMap = new Map<string, SpanWithDepth>();\n const rootSpans: SpanWithDepth[] = [];\n\n spans.forEach(span => {\n spanMap.set(span.spanId, { ...span, depth: 0, children: [] });\n });\n\n spans.forEach(span => {\n const spanWithDepth = spanMap.get(span.spanId)!;\n\n if (span.parentSpanId && spanMap.has(span.parentSpanId)) {\n const parent = spanMap.get(span.parentSpanId)!;\n parent.children.push(spanWithDepth);\n spanWithDepth.depth = parent.depth + 1;\n } else {\n rootSpans.push(spanWithDepth);\n }\n });\n\n if (rootSpans.length === 0) {\n const sortedSpans = [...spans].sort((a, b) => {\n const aStart = parseRfc3339NanoToNanoseconds(a.startTime);\n const bStart = parseRfc3339NanoToNanoseconds(b.startTime);\n return aStart - bStart;\n });\n\n if (sortedSpans.length > 0) {\n const rootSpan = spanMap.get(sortedSpans[0].spanId)!;\n rootSpans.push(rootSpan);\n rootSpan.depth = 0;\n\n sortedSpans.slice(1).forEach(span => {\n const spanWithDepth = spanMap.get(span.spanId)!;\n const spanStart = parseRfc3339NanoToNanoseconds(span.startTime);\n const spanEnd = parseRfc3339NanoToNanoseconds(span.endTime);\n\n let parent: SpanWithDepth | null = null;\n let maxDepth = -1;\n\n sortedSpans.slice(0, sortedSpans.indexOf(span)).forEach(prevSpan => {\n const prevSpanWithDepth = spanMap.get(prevSpan.spanId);\n if (!prevSpanWithDepth) return;\n\n const prevStart = parseRfc3339NanoToNanoseconds(prevSpan.startTime);\n const prevEnd = parseRfc3339NanoToNanoseconds(prevSpan.endTime);\n\n if (\n spanStart >= prevStart &&\n spanEnd <= prevEnd &&\n prevSpanWithDepth.depth > maxDepth\n ) {\n parent = prevSpanWithDepth;\n maxDepth = prevSpanWithDepth.depth;\n }\n });\n\n if (parent) {\n const parentSpan = parent as SpanWithDepth;\n parentSpan.children.push(spanWithDepth);\n spanWithDepth.depth = parentSpan.depth + 1;\n } else {\n rootSpans.push(spanWithDepth);\n spanWithDepth.depth = 0;\n }\n });\n }\n }\n\n return { spanTree: rootSpans, minTime: min, timeRange: range };\n }, [spans]);\n\n const visibleSpans = useMemo(() => {\n const getVisibleSpans = (nodes: SpanWithDepth[]): SpanWithDepth[] => {\n const result: SpanWithDepth[] = [];\n nodes.forEach((node: SpanWithDepth) => {\n result.push(node);\n if (!collapsedSpans.has(node.spanId)) {\n result.push(...getVisibleSpans(node.children));\n }\n });\n return result;\n };\n return getVisibleSpans(spanTree);\n }, [spanTree, collapsedSpans]);\n\n const toggleCollapse = (spanId: string) => {\n setCollapsedSpans(prev => {\n const newSet = new Set(prev);\n if (newSet.has(spanId)) {\n newSet.delete(spanId);\n } else {\n newSet.add(spanId);\n }\n return newSet;\n });\n };\n\n const handleSpanClick = (spanId: string) => {\n if (selectedSpanId === spanId) {\n setSelectedSpanId(null);\n return;\n }\n setSelectedSpanId(spanId);\n spanDetails.fetchSpanDetails(traceId, spanId);\n };\n\n if (spanTree.length === 0) {\n return (\n <Box className={classes.container}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n No spans available for this trace\n </Typography>\n </Box>\n );\n }\n\n const calculatePosition = (startTime: string): number => {\n const time = parseRfc3339NanoToNanoseconds(startTime);\n return ((time - minTime) / timeRange) * 100;\n };\n\n const calculateWidth = (startTime: string, endTime: string): number => {\n const start = parseRfc3339NanoToNanoseconds(startTime);\n const end = parseRfc3339NanoToNanoseconds(endTime);\n const duration = end - start;\n return (duration / timeRange) * 100;\n };\n\n const selectedSpan = selectedSpanId\n ? visibleSpans.find(s => s.spanId === selectedSpanId)\n : null;\n const selectedDetails = selectedSpanId\n ? spanDetails.getDetails(traceId, selectedSpanId)\n : null;\n const detailsLoading = selectedSpanId\n ? spanDetails.isLoading(traceId, selectedSpanId)\n : false;\n const detailsError = selectedSpanId\n ? spanDetails.getError(traceId, selectedSpanId)\n : null;\n\n return (\n <Box className={classes.container}>\n <Typography variant=\"subtitle2\" gutterBottom>\n Trace ID: {traceId}\n </Typography>\n <Box className={classes.timeline}>\n {visibleSpans.map(span => {\n const left = calculatePosition(span.startTime);\n const width = Math.max(\n calculateWidth(span.startTime, span.endTime),\n 0.5,\n );\n const color = getSpanColor(\n span.spanName,\n span.depth,\n isSpanError(span.status),\n );\n const indent = span.depth * 20;\n const hasChildren = span.children.length > 0;\n const isCollapsed = collapsedSpans.has(span.spanId);\n const isSelected = selectedSpanId === span.spanId;\n\n return (\n <Box key={span.spanId} className={classes.spanRow}>\n <Box\n className={classes.spanLabel}\n style={{ paddingLeft: `${indent}px` }}\n >\n {hasChildren && (\n <IconButton\n size=\"small\"\n className={classes.collapseButton}\n onClick={() => toggleCollapse(span.spanId)}\n >\n {isCollapsed ? <ExpandMoreIcon /> : <ExpandLessIcon />}\n </IconButton>\n )}\n {!hasChildren && <Box style={{ width: '20px' }} />}\n {isSpanError(span.status) && (\n <Tooltip title=\"Span error\">\n <ErrorOutlineIcon className={classes.spanErrorIcon} />\n </Tooltip>\n )}\n <Box\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n }}\n title={span.spanName}\n >\n {span.spanName}\n </Box>\n </Box>\n <Box className={classes.spanBarContainer}>\n <Tooltip\n title={\n <Box className={classes.tooltipContent}>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n style={{\n fontWeight: 600,\n color: 'inherit',\n marginBottom: 8,\n }}\n >\n {span.spanName}\n </Typography>\n </Box>\n <Divider style={{ marginBottom: 8, marginTop: 4 }} />\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Span ID:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {span.spanId}\n </Typography>\n </Box>\n {span.spanKind && (\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Kind:\n </Typography>\n <Typography variant=\"caption\">\n {span.spanKind}\n </Typography>\n </Box>\n )}\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Start Time:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n fontSize: '0.7rem',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {formatTimeFromString(span.startTime)}\n </Typography>\n </Box>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n End Time:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{\n fontFamily: 'monospace',\n fontSize: '0.7rem',\n wordBreak: 'break-word',\n overflowWrap: 'break-word',\n flex: 1,\n minWidth: 0,\n }}\n >\n {formatTimeFromString(span.endTime)}\n </Typography>\n </Box>\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Duration:\n </Typography>\n <Typography\n variant=\"caption\"\n style={{ fontWeight: 500 }}\n >\n {formatDuration(span.durationNs)}\n </Typography>\n </Box>\n {getSpanStatusCode(span.status) && (\n <Box className={classes.tooltipRow}>\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.tooltipLabel}\n >\n Status Code:\n </Typography>\n <Typography variant=\"caption\">\n {getSpanStatusCode(span.status)}\n </Typography>\n </Box>\n )}\n </Box>\n }\n arrow\n placement=\"top\"\n enterDelay={200}\n leaveDelay={100}\n >\n <Box\n className={classes.spanBar}\n style={{\n left: `${left}%`,\n width: `${width}%`,\n backgroundColor: color,\n outline: isSelected\n ? `2px solid ${theme.palette.primary.main}`\n : undefined,\n }}\n onClick={() => handleSpanClick(span.spanId)}\n >\n {width > 5 && formatDuration(span.durationNs)}\n </Box>\n </Tooltip>\n </Box>\n </Box>\n );\n })}\n </Box>\n\n {/* Span details panel — shown when a span bar is clicked */}\n {selectedSpanId && (\n <Box\n mt={2}\n p={2}\n style={{\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n backgroundColor: theme.palette.background.paper,\n }}\n >\n <Typography variant=\"subtitle2\" gutterBottom>\n Span Details{selectedSpan ? `: ${selectedSpan.spanName}` : ''}\n </Typography>\n <Divider style={{ marginBottom: 8 }} />\n\n {detailsLoading && (\n <Box display=\"flex\" alignItems=\"center\" style={{ gap: 8 }}>\n <CircularProgress size={16} />\n <Typography variant=\"body2\" color=\"textSecondary\">\n Loading span details...\n </Typography>\n </Box>\n )}\n\n {detailsError && (\n <Typography variant=\"body2\" color=\"error\">\n Failed to load span details: {detailsError}\n </Typography>\n )}\n\n {selectedDetails && !detailsLoading && (\n <SpanDetailsPanel details={selectedDetails} traceId={traceId} />\n )}\n\n {!detailsLoading && !detailsError && !selectedDetails && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Click a span bar to view its details.\n </Typography>\n )}\n </Box>\n )}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AA0CA,SAAS,aAAA,CACP,GAAA,EACA,MAAA,GAAS,EAAA,EAC8B;AACvC,EAAA,MAAM,OAA8C,EAAC;AACrD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,MAAM,UAAU,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,GAAK,CAAA;AAC5C,IAAA,IAAI,CAAA,KAAM,QAAQ,OAAO,CAAA,KAAM,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AAC5D,MAAA,IAAA,CAAK,IAAA,CAAK,GAAG,aAAA,CAAc,CAAA,EAA8B,OAAO,CAAC,CAAA;AAAA,IACnE,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,IAAA,CAAK,EAAE,GAAA,EAAK,OAAA,EAAS,OAAO,MAAA,CAAO,CAAA,IAAK,EAAE,CAAA,EAAG,CAAA;AAAA,IACpD;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAOA,MAAM,gBAAA,GAAmB,CAAC,EAAE,KAAA,EAAO,MAAK,KAA6B;AACnE,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,IAAI,CAAC,QAAQ,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,IAAA;AACpD,EAAA,MAAM,IAAA,GAAO,cAAc,IAAI,CAAA;AAC/B,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,EAAA,EAAI,CAAA,EACP,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,SAAA;AAAA,UACV,UAAA,EAAY,GAAA;AAAA,UACZ,OAAA,EAAS,OAAA;AAAA,UACT,YAAA,EAAc,CAAA;AAAA,UACd,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,UAC1B,aAAA,EAAe,WAAA;AAAA,UACf,aAAA,EAAe;AAAA,SACjB;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,IACC,KAAK,GAAA,CAAI,CAAC,EAAE,GAAA,EAAK,OAAM,qBACtB,IAAA,CAAC,GAAA,EAAA,EAAc,OAAA,EAAQ,QAAO,KAAA,EAAO,EAAE,KAAK,CAAA,EAAG,YAAA,EAAc,GAAE,EAC7D,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,SAAA;AAAA,UACR,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,QAAA;AAAA,YACV,UAAA,EAAY,WAAA;AAAA,YACZ,UAAA,EAAY,GAAA;AAAA,YACZ,QAAA,EAAU,GAAA;AAAA,YACV,UAAA,EAAY,CAAA;AAAA,YACZ,SAAA,EAAW;AAAA,WACb;AAAA,UAEC,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,SAAA;AAAA,UACR,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,QAAA;AAAA,YACV,UAAA,EAAY,WAAA;AAAA,YACZ,SAAA,EAAW;AAAA,WACb;AAAA,UAEC,QAAA,EAAA;AAAA;AAAA;AACH,KAAA,EAAA,EAvBQ,GAwBV,CACD;AAAA,GAAA,EACH,CAAA;AAEJ,CAAA;AAOA,MAAM,gBAAA,GAAmB,CAAC,EAAE,OAAA,EAAS,SAAQ,KAA6B;AACxE,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,UAAA,GAAsD;AAAA,IAC1D,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,OAAA,EAAQ;AAAA,IACpC,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,QAAQ,MAAA,EAAO;AAAA,IAC1C,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,QAAQ,QAAA,EAAS;AAAA,IAC9C,GAAI,OAAA,CAAQ,QAAA,GACR,CAAC,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,OAAA,CAAQ,QAAA,EAAU,CAAA,GAChD,EAAC;AAAA,IACL,GAAI,OAAA,CAAQ,YAAA,GACR,CAAC,EAAE,KAAA,EAAO,gBAAA,EAAkB,KAAA,EAAO,OAAA,CAAQ,YAAA,EAAc,CAAA,GACzD,EAAC;AAAA,IACL,EAAE,KAAA,EAAO,YAAA,EAAc,OAAO,oBAAA,CAAqB,OAAA,CAAQ,SAAS,CAAA,EAAE;AAAA,IACtE,EAAE,KAAA,EAAO,UAAA,EAAY,OAAO,oBAAA,CAAqB,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,IAClE,EAAE,KAAA,EAAO,UAAA,EAAY,OAAO,cAAA,CAAe,OAAA,CAAQ,UAAU,CAAA;AAAE,GACjE;AAEA,EAAA,4BACG,GAAA,EAAA,EAEC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAA,EAAA,EAAI,IAAI,CAAA,EACP,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,SAAA;AAAA,UACR,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,SAAA;AAAA,YACV,UAAA,EAAY,GAAA;AAAA,YACZ,OAAA,EAAS,OAAA;AAAA,YACT,YAAA,EAAc,CAAA;AAAA,YACd,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,YAC1B,aAAA,EAAe,WAAA;AAAA,YACf,aAAA,EAAe;AAAA,WACjB;AAAA,UACD,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,MACC,WAAW,GAAA,CAAI,CAAC,EAAE,KAAA,EAAO,OAAM,qBAC9B,IAAA,CAAC,GAAA,EAAA,EAAgB,OAAA,EAAQ,QAAO,KAAA,EAAO,EAAE,KAAK,CAAA,EAAG,YAAA,EAAc,GAAE,EAC/D,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,SAAA;AAAA,YACR,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,QAAA;AAAA,cACV,UAAA,EAAY,WAAA;AAAA,cACZ,UAAA,EAAY,GAAA;AAAA,cACZ,QAAA,EAAU,GAAA;AAAA,cACV,UAAA,EAAY;AAAA,aACd;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBACA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,SAAA;AAAA,YACR,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,QAAA;AAAA,cACV,UAAA,EAAY,WAAA;AAAA,cACZ,SAAA,EAAW;AAAA,aACb;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA;AACH,OAAA,EAAA,EAtBQ,KAuBV,CACD;AAAA,KAAA,EACH,CAAA;AAAA,wBAEC,gBAAA,EAAA,EAAiB,KAAA,EAAM,QAAA,EAAS,IAAA,EAAM,QAAQ,MAAA,EAAQ,CAAA;AAAA,wBACtD,gBAAA,EAAA,EAAiB,KAAA,EAAM,YAAA,EAAa,IAAA,EAAM,QAAQ,UAAA,EAAY,CAAA;AAAA,oBAC/D,GAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,qBAAA;AAAA,QACN,MAAM,OAAA,CAAQ;AAAA;AAAA;AAChB,GAAA,EACF,CAAA;AAEJ,CAAA;AAEO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,OAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,KAA0B;AACxB,EAAA,MAAM,UAAU,kBAAA,EAAmB;AACnC,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,IAAI,QAAA,iBAAsB,IAAI,KAAK,CAAA;AAC3E,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAwB,IAAI,CAAA;AAGxE,EAAA,MAAM,YAAA,GAAe,CACnB,QAAA,EACA,KAAA,EACA,OAAA,KACW;AACX,IAAA,IAAI,SAAS,OAAO,SAAA;AAEpB,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,SAAA;AAAA;AAAA,MACA,SAAA;AAAA;AAAA,MACA,SAAA;AAAA;AAAA,MACA,SAAA;AAAA;AAAA,MACA;AAAA;AAAA,KACF;AAEA,IAAA,IAAI,KAAA,KAAU,CAAA,EAAG,OAAO,MAAA,CAAO,CAAC,CAAA;AAChC,IAAA,IAAI,KAAA,KAAU,CAAA,EAAG,OAAO,MAAA,CAAO,CAAC,CAAA;AAEhC,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,MAAA,IAAA,GAAO,QAAA,CAAS,UAAA,CAAW,CAAC,CAAA,IAAA,CAAM,QAAQ,CAAA,IAAK,IAAA,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,OAAO,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,EAC9C,CAAA;AAEA,EAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAS,SAAA,EAAU,GAAI,QAAQ,MAAM;AACrD,IAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAChC,MAAA,OAAO,EAAE,QAAA,EAAU,IAAI,OAAA,EAAS,CAAA,EAAG,WAAW,CAAA,EAAE;AAAA,IAClD;AAEA,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,CAAA,IAAA,KAAQ;AAAA,MAClC,6BAAA,CAA8B,KAAK,SAAS,CAAA;AAAA,MAC5C,6BAAA,CAA8B,KAAK,OAAO;AAAA,KAC3C,CAAA;AAED,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,CAAA;AAC7B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,CAAA;AAC7B,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,IAAO,CAAA;AAE3B,IAAA,MAAM,OAAA,uBAAc,GAAA,EAA2B;AAC/C,IAAA,MAAM,YAA6B,EAAC;AAEpC,IAAA,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AACpB,MAAA,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,CAAA,EAAG,QAAA,EAAU,EAAC,EAAG,CAAA;AAAA,IAC9D,CAAC,CAAA;AAED,IAAA,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AACpB,MAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAE7C,MAAA,IAAI,KAAK,YAAA,IAAgB,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA,EAAG;AACvD,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA;AAC5C,QAAA,MAAA,CAAO,QAAA,CAAS,KAAK,aAAa,CAAA;AAClC,QAAA,aAAA,CAAc,KAAA,GAAQ,OAAO,KAAA,GAAQ,CAAA;AAAA,MACvC,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,KAAK,aAAa,CAAA;AAAA,MAC9B;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,MAAA,MAAM,WAAA,GAAc,CAAC,GAAG,KAAK,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAC5C,QAAA,MAAM,MAAA,GAAS,6BAAA,CAA8B,CAAA,CAAE,SAAS,CAAA;AACxD,QAAA,MAAM,MAAA,GAAS,6BAAA,CAA8B,CAAA,CAAE,SAAS,CAAA;AACxD,QAAA,OAAO,MAAA,GAAS,MAAA;AAAA,MAClB,CAAC,CAAA;AAED,MAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,QAAA,MAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,WAAA,CAAY,CAAC,EAAE,MAAM,CAAA;AAClD,QAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AACvB,QAAA,QAAA,CAAS,KAAA,GAAQ,CAAA;AAEjB,QAAA,WAAA,CAAY,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAA,KAAQ;AACnC,UAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAC7C,UAAA,MAAM,SAAA,GAAY,6BAAA,CAA8B,IAAA,CAAK,SAAS,CAAA;AAC9D,UAAA,MAAM,OAAA,GAAU,6BAAA,CAA8B,IAAA,CAAK,OAAO,CAAA;AAE1D,UAAA,IAAI,MAAA,GAA+B,IAAA;AACnC,UAAA,IAAI,QAAA,GAAW,EAAA;AAEf,UAAA,WAAA,CAAY,KAAA,CAAM,GAAG,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAE,QAAQ,CAAA,QAAA,KAAY;AAClE,YAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA;AACrD,YAAA,IAAI,CAAC,iBAAA,EAAmB;AAExB,YAAA,MAAM,SAAA,GAAY,6BAAA,CAA8B,QAAA,CAAS,SAAS,CAAA;AAClE,YAAA,MAAM,OAAA,GAAU,6BAAA,CAA8B,QAAA,CAAS,OAAO,CAAA;AAE9D,YAAA,IACE,aAAa,SAAA,IACb,OAAA,IAAW,OAAA,IACX,iBAAA,CAAkB,QAAQ,QAAA,EAC1B;AACA,cAAA,MAAA,GAAS,iBAAA;AACT,cAAA,QAAA,GAAW,iBAAA,CAAkB,KAAA;AAAA,YAC/B;AAAA,UACF,CAAC,CAAA;AAED,UAAA,IAAI,MAAA,EAAQ;AACV,YAAA,MAAM,UAAA,GAAa,MAAA;AACnB,YAAA,UAAA,CAAW,QAAA,CAAS,KAAK,aAAa,CAAA;AACtC,YAAA,aAAA,CAAc,KAAA,GAAQ,WAAW,KAAA,GAAQ,CAAA;AAAA,UAC3C,CAAA,MAAO;AACL,YAAA,SAAA,CAAU,KAAK,aAAa,CAAA;AAC5B,YAAA,aAAA,CAAc,KAAA,GAAQ,CAAA;AAAA,UACxB;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,OAAA,EAAS,GAAA,EAAK,WAAW,KAAA,EAAM;AAAA,EAC/D,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA4C;AACnE,MAAA,MAAM,SAA0B,EAAC;AACjC,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAwB;AACrC,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AACpC,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,eAAA,CAAgB,IAAA,CAAK,QAAQ,CAAC,CAAA;AAAA,QAC/C;AAAA,MACF,CAAC,CAAA;AACD,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AACA,IAAA,OAAO,gBAAgB,QAAQ,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,QAAA,EAAU,cAAc,CAAC,CAAA;AAE7B,EAAA,MAAM,cAAA,GAAiB,CAAC,MAAA,KAAmB;AACzC,IAAA,iBAAA,CAAkB,CAAA,IAAA,KAAQ;AACxB,MAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA;AAC3B,MAAA,IAAI,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,EAAG;AACtB,QAAA,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,MACnB;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CAAC,MAAA,KAAmB;AAC1C,IAAA,IAAI,mBAAmB,MAAA,EAAQ;AAC7B,MAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,MAAM,CAAA;AACxB,IAAA,WAAA,CAAY,gBAAA,CAAiB,SAAS,MAAM,CAAA;AAAA,EAC9C,CAAA;AAEA,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,uBACE,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,SAAA,EACtB,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,mCAAA,EAElD,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,SAAA,KAA8B;AACvD,IAAA,MAAM,IAAA,GAAO,8BAA8B,SAAS,CAAA;AACpD,IAAA,OAAA,CAAS,IAAA,GAAO,WAAW,SAAA,GAAa,GAAA;AAAA,EAC1C,CAAA;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,SAAA,EAAmB,OAAA,KAA4B;AACrE,IAAA,MAAM,KAAA,GAAQ,8BAA8B,SAAS,CAAA;AACrD,IAAA,MAAM,GAAA,GAAM,8BAA8B,OAAO,CAAA;AACjD,IAAA,MAAM,WAAW,GAAA,GAAM,KAAA;AACvB,IAAA,OAAQ,WAAW,SAAA,GAAa,GAAA;AAAA,EAClC,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,iBACjB,YAAA,CAAa,IAAA,CAAK,OAAK,CAAA,CAAE,MAAA,KAAW,cAAc,CAAA,GAClD,IAAA;AACJ,EAAA,MAAM,kBAAkB,cAAA,GACpB,WAAA,CAAY,UAAA,CAAW,OAAA,EAAS,cAAc,CAAA,GAC9C,IAAA;AACJ,EAAA,MAAM,iBAAiB,cAAA,GACnB,WAAA,CAAY,SAAA,CAAU,OAAA,EAAS,cAAc,CAAA,GAC7C,KAAA;AACJ,EAAA,MAAM,eAAe,cAAA,GACjB,WAAA,CAAY,QAAA,CAAS,OAAA,EAAS,cAAc,CAAA,GAC5C,IAAA;AAEJ,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,SAAA,EACtB,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EAAY,YAAA,EAAY,IAAA,EAAC,QAAA,EAAA;AAAA,MAAA,YAAA;AAAA,MAChC;AAAA,KAAA,EACb,CAAA;AAAA,wBACC,GAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,QAAA,EACrB,QAAA,EAAA,YAAA,CAAa,IAAI,CAAA,IAAA,KAAQ;AACxB,MAAA,MAAM,IAAA,GAAO,iBAAA,CAAkB,IAAA,CAAK,SAAS,CAAA;AAC7C,MAAA,MAAM,QAAQ,IAAA,CAAK,GAAA;AAAA,QACjB,cAAA,CAAe,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,OAAO,CAAA;AAAA,QAC3C;AAAA,OACF;AACA,MAAA,MAAM,KAAA,GAAQ,YAAA;AAAA,QACZ,IAAA,CAAK,QAAA;AAAA,QACL,IAAA,CAAK,KAAA;AAAA,QACL,WAAA,CAAY,KAAK,MAAM;AAAA,OACzB;AACA,MAAA,MAAM,MAAA,GAAS,KAAK,KAAA,GAAQ,EAAA;AAC5B,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,MAAA,GAAS,CAAA;AAC3C,MAAA,MAAM,WAAA,GAAc,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAClD,MAAA,MAAM,UAAA,GAAa,mBAAmB,IAAA,CAAK,MAAA;AAE3C,MAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAsB,SAAA,EAAW,OAAA,CAAQ,OAAA,EACxC,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,WAAW,OAAA,CAAQ,SAAA;AAAA,YACnB,KAAA,EAAO,EAAE,WAAA,EAAa,CAAA,EAAG,MAAM,CAAA,EAAA,CAAA,EAAK;AAAA,YAEnC,QAAA,EAAA;AAAA,cAAA,WAAA,oBACC,GAAA;AAAA,gBAAC,UAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,OAAA;AAAA,kBACL,WAAW,OAAA,CAAQ,cAAA;AAAA,kBACnB,OAAA,EAAS,MAAM,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA;AAAA,kBAExC,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,cAAA,EAAA,EAAe,CAAA,uBAAM,cAAA,EAAA,EAAe;AAAA;AAAA,eACtD;AAAA,cAED,CAAC,+BAAe,GAAA,CAAC,GAAA,EAAA,EAAI,OAAO,EAAE,KAAA,EAAO,QAAO,EAAG,CAAA;AAAA,cAC/C,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA,oBACtB,GAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAM,YAAA,EACb,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAW,OAAA,CAAQ,eAAe,CAAA,EACtD,CAAA;AAAA,8BAEF,GAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO;AAAA,oBACL,QAAA,EAAU,QAAA;AAAA,oBACV,YAAA,EAAc,UAAA;AAAA,oBACd,UAAA,EAAY,QAAA;AAAA,oBACZ,IAAA,EAAM;AAAA,mBACR;AAAA,kBACA,OAAO,IAAA,CAAK,QAAA;AAAA,kBAEX,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR;AAAA;AAAA,SACF;AAAA,wBACA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,gBAAA,EACtB,QAAA,kBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,KAAA,kBACE,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,cAAA,EACtB,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,UAAA,EACtB,QAAA,kBAAA,GAAA;AAAA,gBAAC,UAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAQ,WAAA;AAAA,kBACR,SAAA,EAAU,MAAA;AAAA,kBACV,KAAA,EAAO;AAAA,oBACL,UAAA,EAAY,GAAA;AAAA,oBACZ,KAAA,EAAO,SAAA;AAAA,oBACP,YAAA,EAAc;AAAA,mBAChB;AAAA,kBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,eACR,EACF,CAAA;AAAA,8BACA,GAAA,CAAC,WAAQ,KAAA,EAAO,EAAE,cAAc,CAAA,EAAG,SAAA,EAAW,GAAE,EAAG,CAAA;AAAA,8BACnD,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,KAAA,EAAO;AAAA,sBACL,UAAA,EAAY,WAAA;AAAA,sBACZ,SAAA,EAAW,YAAA;AAAA,sBACX,YAAA,EAAc,YAAA;AAAA,sBACd,IAAA,EAAM,CAAA;AAAA,sBACN,QAAA,EAAU;AAAA,qBACZ;AAAA,oBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR,eAAA,EACF,CAAA;AAAA,cACC,KAAK,QAAA,oBACJ,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,SAAA,EACjB,eAAK,QAAA,EACR;AAAA,eAAA,EACF,CAAA;AAAA,8BAEF,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,KAAA,EAAO;AAAA,sBACL,UAAA,EAAY,WAAA;AAAA,sBACZ,QAAA,EAAU,QAAA;AAAA,sBACV,SAAA,EAAW,YAAA;AAAA,sBACX,YAAA,EAAc,YAAA;AAAA,sBACd,IAAA,EAAM,CAAA;AAAA,sBACN,QAAA,EAAU;AAAA,qBACZ;AAAA,oBAEC,QAAA,EAAA,oBAAA,CAAqB,KAAK,SAAS;AAAA;AAAA;AACtC,eAAA,EACF,CAAA;AAAA,8BACA,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,KAAA,EAAO;AAAA,sBACL,UAAA,EAAY,WAAA;AAAA,sBACZ,QAAA,EAAU,QAAA;AAAA,sBACV,SAAA,EAAW,YAAA;AAAA,sBACX,YAAA,EAAc,YAAA;AAAA,sBACd,IAAA,EAAM,CAAA;AAAA,sBACN,QAAA,EAAU;AAAA,qBACZ;AAAA,oBAEC,QAAA,EAAA,oBAAA,CAAqB,KAAK,OAAO;AAAA;AAAA;AACpC,eAAA,EACF,CAAA;AAAA,8BACA,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,KAAA,EAAO,EAAE,UAAA,EAAY,GAAA,EAAI;AAAA,oBAExB,QAAA,EAAA,cAAA,CAAe,KAAK,UAAU;AAAA;AAAA;AACjC,eAAA,EACF,CAAA;AAAA,cACC,iBAAA,CAAkB,KAAK,MAAM,CAAA,yBAC3B,GAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,UAAA,EACtB,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAQ,SAAA;AAAA,oBACR,SAAA,EAAU,MAAA;AAAA,oBACV,WAAW,OAAA,CAAQ,YAAA;AAAA,oBACpB,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,oCACC,UAAA,EAAA,EAAW,OAAA,EAAQ,WACjB,QAAA,EAAA,iBAAA,CAAkB,IAAA,CAAK,MAAM,CAAA,EAChC;AAAA,eAAA,EACF;AAAA,aAAA,EAEJ,CAAA;AAAA,YAEF,KAAA,EAAK,IAAA;AAAA,YACL,SAAA,EAAU,KAAA;AAAA,YACV,UAAA,EAAY,GAAA;AAAA,YACZ,UAAA,EAAY,GAAA;AAAA,YAEZ,QAAA,kBAAA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,WAAW,OAAA,CAAQ,OAAA;AAAA,gBACnB,KAAA,EAAO;AAAA,kBACL,IAAA,EAAM,GAAG,IAAI,CAAA,CAAA,CAAA;AAAA,kBACb,KAAA,EAAO,GAAG,KAAK,CAAA,CAAA,CAAA;AAAA,kBACf,eAAA,EAAiB,KAAA;AAAA,kBACjB,SAAS,UAAA,GACL,CAAA,UAAA,EAAa,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,CAAA,GACvC;AAAA,iBACN;AAAA,gBACA,OAAA,EAAS,MAAM,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAAA,gBAEzC,QAAA,EAAA,KAAA,GAAQ,CAAA,IAAK,cAAA,CAAe,IAAA,CAAK,UAAU;AAAA;AAAA;AAC9C;AAAA,SACF,EACF;AAAA,OAAA,EAAA,EApLQ,KAAK,MAqLf,CAAA;AAAA,IAEJ,CAAC,CAAA,EACH,CAAA;AAAA,IAGC,cAAA,oBACC,IAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,CAAA;AAAA,QACJ,CAAA,EAAG,CAAA;AAAA,QACH,KAAA,EAAO;AAAA,UACL,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,UAC1C,YAAA,EAAc,CAAA;AAAA,UACd,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,SAC5C;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EAAY,YAAA,EAAY,IAAA,EAAC,QAAA,EAAA;AAAA,YAAA,cAAA;AAAA,YAC9B,YAAA,GAAe,CAAA,EAAA,EAAK,YAAA,CAAa,QAAQ,CAAA,CAAA,GAAK;AAAA,WAAA,EAC7D,CAAA;AAAA,8BACC,OAAA,EAAA,EAAQ,KAAA,EAAO,EAAE,YAAA,EAAc,GAAE,EAAG,CAAA;AAAA,UAEpC,cAAA,oBACC,IAAA,CAAC,GAAA,EAAA,EAAI,OAAA,EAAQ,MAAA,EAAO,UAAA,EAAW,QAAA,EAAS,KAAA,EAAO,EAAE,GAAA,EAAK,CAAA,EAAE,EACtD,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,MAAM,EAAA,EAAI,CAAA;AAAA,gCAC3B,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,iBAAgB,QAAA,EAAA,yBAAA,EAElD;AAAA,WAAA,EACF,CAAA;AAAA,UAGD,gCACC,IAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,OAAM,OAAA,EAAQ,QAAA,EAAA;AAAA,YAAA,+BAAA;AAAA,YACV;AAAA,WAAA,EAChC,CAAA;AAAA,UAGD,mBAAmB,CAAC,cAAA,wBAClB,gBAAA,EAAA,EAAiB,OAAA,EAAS,iBAAiB,OAAA,EAAkB,CAAA;AAAA,UAG/D,CAAC,cAAA,IAAkB,CAAC,YAAA,IAAgB,CAAC,eAAA,oBACpC,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,uCAAA,EAElD;AAAA;AAAA;AAAA;AAEJ,GAAA,EAEJ,CAAA;AAEJ;;;;"}
@@ -68,6 +68,7 @@ const useTracesTableStyles = makeStyles((theme) => ({
68
68
  textOverflow: "ellipsis"
69
69
  },
70
70
  traceIdCell: {
71
+ position: "relative",
71
72
  fontSize: "0.75rem",
72
73
  fontFamily: "monospace",
73
74
  overflow: "hidden",
@@ -85,22 +86,9 @@ const useTracesTableStyles = makeStyles((theme) => ({
85
86
  fontSize: "1rem"
86
87
  }
87
88
  },
88
- errorRow: {
89
- "& > td:first-child, & > th:first-child": {
90
- position: "relative",
91
- borderLeft: "none !important",
92
- "&::before": {
93
- content: '""',
94
- position: "absolute",
95
- left: 0,
96
- top: "5%",
97
- bottom: "5%",
98
- width: "3px",
99
- backgroundColor: "#EF4444",
100
- borderRadius: "2px"
101
- }
102
- }
103
- },
89
+ // Absolutely positioned inside the (relative) trace-name cell. The span itself
90
+ // is a wide, transparent hit-area so the "contains errors" tooltip is easy to
91
+ // hover; the visible 3px stripe is drawn by the ::before.
104
92
  errorStripe: {
105
93
  position: "absolute",
106
94
  left: 0,
@@ -108,7 +96,17 @@ const useTracesTableStyles = makeStyles((theme) => ({
108
96
  bottom: "5%",
109
97
  width: "8px",
110
98
  cursor: "default",
111
- zIndex: 1
99
+ zIndex: 1,
100
+ "&::before": {
101
+ content: '""',
102
+ position: "absolute",
103
+ left: 0,
104
+ top: 0,
105
+ bottom: 0,
106
+ width: "3px",
107
+ backgroundColor: theme.palette.error.main,
108
+ borderRadius: "2px"
109
+ }
112
110
  }
113
111
  }));
114
112
  const useWaterfallStyles = makeStyles((theme) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"styles.esm.js","sources":["../../../src/components/Traces/styles.ts"],"sourcesContent":["import { makeStyles, Theme } from '@material-ui/core/styles';\n\nexport const useTracesActionsStyles = makeStyles((theme: Theme) => ({\n statsContainer: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2),\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n actionsContainer: {\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n },\n}));\n\nexport const useTracesTableStyles = makeStyles((theme: Theme) => ({\n tablePaper: {\n marginBottom: theme.spacing(0),\n paddingBottom: theme.spacing(1),\n },\n // Div-based header row, rendered inside the virtualized scroll container so\n // it shares the rows' content width (no scrollbar-gutter misalignment).\n // Sticky positioning replicates the original `<TableHead stickyHeader>`.\n headerRow: {\n display: 'flex',\n alignItems: 'center',\n position: 'sticky',\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n borderBottom: `1px solid ${theme.palette.grey[100]}`,\n },\n headerColumn: {\n fontWeight: 'bold',\n fontSize: '0.75rem',\n padding: '12px 8px',\n minWidth: 0,\n boxSizing: 'border-box',\n },\n traceRow: {\n cursor: 'pointer',\n borderBottom: `1px solid ${theme.palette.grey[100]}`,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n },\n // Flex container replacing the former <TableRow>. `alignItems: 'center'`\n // mirrors the default `vertical-align: middle` of MUI table cells.\n traceRowMain: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n cell: {\n padding: '4px 8px',\n minWidth: 0,\n boxSizing: 'border-box',\n fontSize: '0.75rem',\n },\n expandedRow: {\n backgroundColor: theme.palette.action.selected,\n },\n traceCell: {\n fontSize: '0.75rem',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n traceIdCell: {\n fontSize: '0.75rem',\n fontFamily: 'monospace',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n emptyState: {\n textAlign: 'center',\n padding: theme.spacing(4),\n color: theme.palette.text.secondary,\n },\n expandIcon: {\n cursor: 'pointer',\n padding: 0,\n '& .MuiSvgIcon-root': {\n fontSize: '1rem',\n },\n },\n errorRow: {\n '& > td:first-child, & > th:first-child': {\n position: 'relative',\n borderLeft: 'none !important',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n left: 0,\n top: '5%',\n bottom: '5%',\n width: '3px',\n backgroundColor: '#EF4444',\n borderRadius: '2px',\n },\n },\n },\n errorStripe: {\n position: 'absolute',\n left: 0,\n top: '5%',\n bottom: '5%',\n width: '8px',\n cursor: 'default',\n zIndex: 1,\n },\n}));\n\nexport const useWaterfallStyles = makeStyles((theme: Theme) => ({\n container: {\n padding: theme.spacing(2),\n backgroundColor:\n theme.palette.type === 'dark'\n ? theme.palette.background.default\n : '#fafafa',\n overflowX: 'auto',\n },\n timeline: {\n position: 'relative',\n marginTop: theme.spacing(1),\n },\n spanRow: {\n position: 'relative',\n marginBottom: theme.spacing(1),\n minHeight: '30px',\n display: 'flex',\n alignItems: 'center',\n },\n spanLabel: {\n width: '250px',\n minWidth: '250px',\n maxWidth: '250px',\n paddingRight: theme.spacing(1),\n fontSize: '0.875rem',\n fontWeight: 500,\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n collapseButton: {\n padding: 0,\n width: '20px',\n height: '20px',\n '& .MuiSvgIcon-root': {\n fontSize: '1rem',\n },\n },\n spanBarContainer: {\n position: 'relative',\n flex: 1,\n height: '24px',\n marginLeft: theme.spacing(1),\n },\n spanBar: {\n position: 'absolute',\n height: '20px',\n borderRadius: '4px',\n cursor: 'pointer',\n transition: 'opacity 0.2s',\n display: 'flex',\n alignItems: 'center',\n paddingLeft: theme.spacing(1),\n paddingRight: theme.spacing(1),\n fontSize: '0.75rem',\n fontWeight: 500,\n // Span bar background colors are pastel, designed for dark-on-light text\n // in both modes. Force dark text regardless of theme mode.\n color: 'rgba(0, 0, 0, 0.87)',\n '&:hover': {\n opacity: 0.8,\n zIndex: 10,\n },\n },\n tooltipContent: {\n padding: theme.spacing(1),\n minWidth: '280px',\n maxWidth: '450px',\n color: '#fff',\n },\n tooltipRow: {\n marginBottom: theme.spacing(0.5),\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n '&:last-child': {\n marginBottom: 0,\n },\n },\n tooltipLabel: {\n fontWeight: 600,\n color: '#fff',\n fontSize: '0.75rem',\n minWidth: '85px',\n flexShrink: 0,\n },\n spanErrorIcon: {\n color: '#F87171',\n fontSize: '0.875rem',\n flexShrink: 0,\n },\n}));\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"styles.esm.js","sources":["../../../src/components/Traces/styles.ts"],"sourcesContent":["import { makeStyles, Theme } from '@material-ui/core/styles';\n\nexport const useTracesActionsStyles = makeStyles((theme: Theme) => ({\n statsContainer: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2),\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n actionsContainer: {\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n },\n}));\n\nexport const useTracesTableStyles = makeStyles((theme: Theme) => ({\n tablePaper: {\n marginBottom: theme.spacing(0),\n paddingBottom: theme.spacing(1),\n },\n // Div-based header row, rendered inside the virtualized scroll container so\n // it shares the rows' content width (no scrollbar-gutter misalignment).\n // Sticky positioning replicates the original `<TableHead stickyHeader>`.\n headerRow: {\n display: 'flex',\n alignItems: 'center',\n position: 'sticky',\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n borderBottom: `1px solid ${theme.palette.grey[100]}`,\n },\n headerColumn: {\n fontWeight: 'bold',\n fontSize: '0.75rem',\n padding: '12px 8px',\n minWidth: 0,\n boxSizing: 'border-box',\n },\n traceRow: {\n cursor: 'pointer',\n borderBottom: `1px solid ${theme.palette.grey[100]}`,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n },\n // Flex container replacing the former <TableRow>. `alignItems: 'center'`\n // mirrors the default `vertical-align: middle` of MUI table cells.\n traceRowMain: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n cell: {\n padding: '4px 8px',\n minWidth: 0,\n boxSizing: 'border-box',\n fontSize: '0.75rem',\n },\n expandedRow: {\n backgroundColor: theme.palette.action.selected,\n },\n traceCell: {\n fontSize: '0.75rem',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n traceIdCell: {\n position: 'relative',\n fontSize: '0.75rem',\n fontFamily: 'monospace',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n emptyState: {\n textAlign: 'center',\n padding: theme.spacing(4),\n color: theme.palette.text.secondary,\n },\n expandIcon: {\n cursor: 'pointer',\n padding: 0,\n '& .MuiSvgIcon-root': {\n fontSize: '1rem',\n },\n },\n // Absolutely positioned inside the (relative) trace-name cell. The span itself\n // is a wide, transparent hit-area so the \"contains errors\" tooltip is easy to\n // hover; the visible 3px stripe is drawn by the ::before.\n errorStripe: {\n position: 'absolute',\n left: 0,\n top: '5%',\n bottom: '5%',\n width: '8px',\n cursor: 'default',\n zIndex: 1,\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n left: 0,\n top: 0,\n bottom: 0,\n width: '3px',\n backgroundColor: theme.palette.error.main,\n borderRadius: '2px',\n },\n },\n}));\n\nexport const useWaterfallStyles = makeStyles((theme: Theme) => ({\n container: {\n padding: theme.spacing(2),\n backgroundColor:\n theme.palette.type === 'dark'\n ? theme.palette.background.default\n : '#fafafa',\n overflowX: 'auto',\n },\n timeline: {\n position: 'relative',\n marginTop: theme.spacing(1),\n },\n spanRow: {\n position: 'relative',\n marginBottom: theme.spacing(1),\n minHeight: '30px',\n display: 'flex',\n alignItems: 'center',\n },\n spanLabel: {\n width: '250px',\n minWidth: '250px',\n maxWidth: '250px',\n paddingRight: theme.spacing(1),\n fontSize: '0.875rem',\n fontWeight: 500,\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n collapseButton: {\n padding: 0,\n width: '20px',\n height: '20px',\n '& .MuiSvgIcon-root': {\n fontSize: '1rem',\n },\n },\n spanBarContainer: {\n position: 'relative',\n flex: 1,\n height: '24px',\n marginLeft: theme.spacing(1),\n },\n spanBar: {\n position: 'absolute',\n height: '20px',\n borderRadius: '4px',\n cursor: 'pointer',\n transition: 'opacity 0.2s',\n display: 'flex',\n alignItems: 'center',\n paddingLeft: theme.spacing(1),\n paddingRight: theme.spacing(1),\n fontSize: '0.75rem',\n fontWeight: 500,\n // Span bar background colors are pastel, designed for dark-on-light text\n // in both modes. Force dark text regardless of theme mode.\n color: 'rgba(0, 0, 0, 0.87)',\n '&:hover': {\n opacity: 0.8,\n zIndex: 10,\n },\n },\n tooltipContent: {\n padding: theme.spacing(1),\n minWidth: '280px',\n maxWidth: '450px',\n color: '#fff',\n },\n tooltipRow: {\n marginBottom: theme.spacing(0.5),\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n '&:last-child': {\n marginBottom: 0,\n },\n },\n tooltipLabel: {\n fontWeight: 600,\n color: '#fff',\n fontSize: '0.75rem',\n minWidth: '85px',\n flexShrink: 0,\n },\n spanErrorIcon: {\n color: '#F87171',\n fontSize: '0.875rem',\n flexShrink: 0,\n },\n}));\n"],"names":[],"mappings":"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"}
@@ -14,6 +14,12 @@ function formatDuration(nanoseconds) {
14
14
  function formatTimeFromString(rfc3339Nano) {
15
15
  return rfc3339Nano.endsWith("Z") ? rfc3339Nano : `${rfc3339Nano}Z`;
16
16
  }
17
+ function getSpanStatusCode(status) {
18
+ return status?.code;
19
+ }
20
+ function isSpanError(status) {
21
+ return status?.code === "error";
22
+ }
17
23
 
18
- export { formatDuration, formatTimeFromString, parseRfc3339NanoToNanoseconds };
24
+ export { formatDuration, formatTimeFromString, getSpanStatusCode, isSpanError, parseRfc3339NanoToNanoseconds };
19
25
  //# sourceMappingURL=utils.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.esm.js","sources":["../../../src/components/Traces/utils.ts"],"sourcesContent":["export function parseRfc3339NanoToNanoseconds(rfc3339Nano: string): number {\n // Split timestamp into base and fractional parts and return nanoseconds\n const [base, fractional] = rfc3339Nano.replace('Z', '').split('.');\n const milliseconds = new Date(`${base}Z`).getTime();\n const nanos = fractional\n ? parseInt(fractional.padEnd(9, '0').slice(0, 9), 10)\n : 0;\n\n return milliseconds * 1_000_000 + nanos;\n}\n\nexport function nanosecondsToRfc3339Nano(nanoseconds: number): string {\n const milliseconds = Math.floor(nanoseconds / 1_000_000);\n const remainingNanos = nanoseconds % 1_000_000;\n\n const isoString = new Date(milliseconds).toISOString();\n const nanoPart = remainingNanos.toString().padStart(6, '0');\n\n return isoString.replace(/\\.\\d{3}Z$/, `.${nanoPart}000Z`);\n}\n\nexport function formatDuration(nanoseconds: number): string {\n if (nanoseconds < 1_000) return `${nanoseconds}ns`;\n if (nanoseconds < 1_000_000) return `${(nanoseconds / 1_000).toFixed(3)}μs`;\n if (nanoseconds < 1_000_000_000)\n return `${(nanoseconds / 1_000_000).toFixed(3)}ms`;\n return `${(nanoseconds / 1_000_000_000).toFixed(3)}s`;\n}\n\nexport function formatTime(nanoseconds: number): string {\n return new Date(Math.floor(nanoseconds / 1_000_000)).toISOString();\n}\n\nexport function formatTimeFromString(rfc3339Nano: string): string {\n return rfc3339Nano.endsWith('Z') ? rfc3339Nano : `${rfc3339Nano}Z`;\n}\n"],"names":[],"mappings":"AAAO,SAAS,8BAA8B,WAAA,EAA6B;AAEzE,EAAA,MAAM,CAAC,IAAA,EAAM,UAAU,CAAA,GAAI,WAAA,CAAY,QAAQ,GAAA,EAAK,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA;AACjE,EAAA,MAAM,gCAAe,IAAI,IAAA,CAAK,GAAG,IAAI,CAAA,CAAA,CAAG,GAAE,OAAA,EAAQ;AAClD,EAAA,MAAM,KAAA,GAAQ,UAAA,GACV,QAAA,CAAS,UAAA,CAAW,MAAA,CAAO,CAAA,EAAG,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAClD,CAAA;AAEJ,EAAA,OAAO,eAAe,GAAA,GAAY,KAAA;AACpC;AAYO,SAAS,eAAe,WAAA,EAA6B;AAC1D,EAAA,IAAI,WAAA,GAAc,GAAA,EAAO,OAAO,CAAA,EAAG,WAAW,CAAA,EAAA,CAAA;AAC9C,EAAA,IAAI,WAAA,GAAc,KAAW,OAAO,CAAA,EAAA,CAAI,cAAc,GAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,OAAA,CAAA;AACvE,EAAA,IAAI,WAAA,GAAc,GAAA;AAChB,IAAA,OAAO,CAAA,EAAA,CAAI,WAAA,GAAc,GAAA,EAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAChD,EAAA,OAAO,CAAA,EAAA,CAAI,WAAA,GAAc,GAAA,EAAe,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AACpD;AAMO,SAAS,qBAAqB,WAAA,EAA6B;AAChE,EAAA,OAAO,YAAY,QAAA,CAAS,GAAG,CAAA,GAAI,WAAA,GAAc,GAAG,WAAW,CAAA,CAAA,CAAA;AACjE;;;;"}
1
+ {"version":3,"file":"utils.esm.js","sources":["../../../src/components/Traces/utils.ts"],"sourcesContent":["import { SpanStatus } from '../../types';\n\nexport function parseRfc3339NanoToNanoseconds(rfc3339Nano: string): number {\n // Split timestamp into base and fractional parts and return nanoseconds\n const [base, fractional] = rfc3339Nano.replace('Z', '').split('.');\n const milliseconds = new Date(`${base}Z`).getTime();\n const nanos = fractional\n ? parseInt(fractional.padEnd(9, '0').slice(0, 9), 10)\n : 0;\n\n return milliseconds * 1_000_000 + nanos;\n}\n\nexport function nanosecondsToRfc3339Nano(nanoseconds: number): string {\n const milliseconds = Math.floor(nanoseconds / 1_000_000);\n const remainingNanos = nanoseconds % 1_000_000;\n\n const isoString = new Date(milliseconds).toISOString();\n const nanoPart = remainingNanos.toString().padStart(6, '0');\n\n return isoString.replace(/\\.\\d{3}Z$/, `.${nanoPart}000Z`);\n}\n\nexport function formatDuration(nanoseconds: number): string {\n if (nanoseconds < 1_000) return `${nanoseconds}ns`;\n if (nanoseconds < 1_000_000) return `${(nanoseconds / 1_000).toFixed(3)}μs`;\n if (nanoseconds < 1_000_000_000)\n return `${(nanoseconds / 1_000_000).toFixed(3)}ms`;\n return `${(nanoseconds / 1_000_000_000).toFixed(3)}s`;\n}\n\nexport function formatTime(nanoseconds: number): string {\n return new Date(Math.floor(nanoseconds / 1_000_000)).toISOString();\n}\n\nexport function formatTimeFromString(rfc3339Nano: string): string {\n return rfc3339Nano.endsWith('Z') ? rfc3339Nano : `${rfc3339Nano}Z`;\n}\n\n/** The OTel status code (`ok` | `error` | `unset`) of a span, if present. */\nexport function getSpanStatusCode(status?: SpanStatus): string | undefined {\n return status?.code;\n}\n\n/** Whether a span carries an error status. */\nexport function isSpanError(status?: SpanStatus): boolean {\n return status?.code === 'error';\n}\n"],"names":[],"mappings":"AAEO,SAAS,8BAA8B,WAAA,EAA6B;AAEzE,EAAA,MAAM,CAAC,IAAA,EAAM,UAAU,CAAA,GAAI,WAAA,CAAY,QAAQ,GAAA,EAAK,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA;AACjE,EAAA,MAAM,gCAAe,IAAI,IAAA,CAAK,GAAG,IAAI,CAAA,CAAA,CAAG,GAAE,OAAA,EAAQ;AAClD,EAAA,MAAM,KAAA,GAAQ,UAAA,GACV,QAAA,CAAS,UAAA,CAAW,MAAA,CAAO,CAAA,EAAG,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAClD,CAAA;AAEJ,EAAA,OAAO,eAAe,GAAA,GAAY,KAAA;AACpC;AAYO,SAAS,eAAe,WAAA,EAA6B;AAC1D,EAAA,IAAI,WAAA,GAAc,GAAA,EAAO,OAAO,CAAA,EAAG,WAAW,CAAA,EAAA,CAAA;AAC9C,EAAA,IAAI,WAAA,GAAc,KAAW,OAAO,CAAA,EAAA,CAAI,cAAc,GAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,OAAA,CAAA;AACvE,EAAA,IAAI,WAAA,GAAc,GAAA;AAChB,IAAA,OAAO,CAAA,EAAA,CAAI,WAAA,GAAc,GAAA,EAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAChD,EAAA,OAAO,CAAA,EAAA,CAAI,WAAA,GAAc,GAAA,EAAe,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AACpD;AAMO,SAAS,qBAAqB,WAAA,EAA6B;AAChE,EAAA,OAAO,YAAY,QAAA,CAAS,GAAG,CAAA,GAAI,WAAA,GAAc,GAAG,WAAW,CAAA,CAAA,CAAA;AACjE;AAGO,SAAS,kBAAkB,MAAA,EAAyC;AACzE,EAAA,OAAO,MAAA,EAAQ,IAAA;AACjB;AAGO,SAAS,YAAY,MAAA,EAA8B;AACxD,EAAA,OAAO,QAAQ,IAAA,KAAS,OAAA;AAC1B;;;;"}
@@ -1 +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';\nimport type { Environment } from '@openchoreo/backstage-plugin-react';\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 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 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":"AA+FO,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;;;;"}
1
+ {"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["import type {\n ObservabilityComponents,\n AIRCAAgentComponents,\n} from '@openchoreo/backstage-plugin-common';\nimport type { Environment } from '@openchoreo/backstage-plugin-react';\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\n// OTel span status ({ code: 'ok' | 'error' | 'unset', message? }) from the spec.\nexport type SpanStatus = ObservabilityComponents['schemas']['SpanStatus'];\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?: SpanStatus;\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 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 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":"AAkGO,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;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openchoreo/backstage-plugin-openchoreo-observability",
3
- "version": "1.2.0-rc.1",
3
+ "version": "1.2.0-rc.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
@@ -70,9 +70,9 @@
70
70
  "@material-ui/core": "4.12.4",
71
71
  "@material-ui/icons": "4.11.3",
72
72
  "@material-ui/lab": "4.0.0-alpha.61",
73
- "@openchoreo/backstage-design-system": "^1.2.0-rc.1",
74
- "@openchoreo/backstage-plugin-common": "^1.2.0-rc.1",
75
- "@openchoreo/backstage-plugin-react": "^1.2.0-rc.1",
73
+ "@openchoreo/backstage-design-system": "^1.2.0-rc.2",
74
+ "@openchoreo/backstage-plugin-common": "^1.2.0-rc.2",
75
+ "@openchoreo/backstage-plugin-react": "^1.2.0-rc.2",
76
76
  "react-markdown": "^9.0.1",
77
77
  "react-use": "17.6.0",
78
78
  "recharts": "3.4.1",
@@ -88,7 +88,7 @@
88
88
  "@backstage/core-app-api": "^1.20.1",
89
89
  "@backstage/dev-utils": "^1.1.23",
90
90
  "@backstage/test-utils": "^1.7.18",
91
- "@openchoreo/test-utils": "^1.2.0-rc.1",
91
+ "@openchoreo/test-utils": "^1.2.0-rc.2",
92
92
  "@testing-library/jest-dom": "6.9.1",
93
93
  "@testing-library/react": "14.3.1",
94
94
  "@testing-library/user-event": "14.6.1",