@kb-labs/studio-app 0.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/dist/index.html +1 -0
  2. package/dist/main.80b70197.css +2 -0
  3. package/dist/main.80b70197.css.map +1 -0
  4. package/dist/main.ad42ef4a.js +522 -0
  5. package/dist/main.ad42ef4a.js.map +1 -0
  6. package/dist/mf-manifest.json +241 -0
  7. package/dist/mf-stats.json +271 -0
  8. package/package.json +56 -39
  9. package/server.js +68 -0
  10. package/.env.example +0 -10
  11. package/UI-KIT-COMPONENTS.md +0 -783
  12. package/UI-KIT-PLAN.md +0 -326
  13. package/eslint-rules/no-direct-antd-import.js +0 -151
  14. package/eslint.config.ts +0 -27
  15. package/index.html +0 -17
  16. package/postcss.config.js +0 -7
  17. package/public/favicon.ico +0 -0
  18. package/rspack.config.mjs +0 -118
  19. package/src/App.tsx +0 -46
  20. package/src/components/devtools/devtools-log-feed.module.css +0 -165
  21. package/src/components/devtools/devtools-log-feed.tsx +0 -300
  22. package/src/components/devtools/devtools-panel.module.css +0 -121
  23. package/src/components/devtools/devtools-panel.tsx +0 -115
  24. package/src/components/empty-state.tsx +0 -28
  25. package/src/components/error-boundary.tsx +0 -210
  26. package/src/components/health-banner.module.css +0 -103
  27. package/src/components/health-banner.tsx +0 -134
  28. package/src/components/health-indicator.tsx +0 -12
  29. package/src/components/page-header.tsx +0 -49
  30. package/src/components/page-transition.tsx +0 -24
  31. package/src/components/role-switcher.tsx +0 -148
  32. package/src/components/run-badge.tsx +0 -13
  33. package/src/components/ui/icons.tsx +0 -509
  34. package/src/components/ui/index.ts +0 -25
  35. package/src/components/ui/kb-config-provider.tsx +0 -130
  36. package/src/components/ui/kb-header.module.css +0 -51
  37. package/src/components/ui/kb-header.tsx +0 -112
  38. package/src/components/ui/kb-notification-bell.module.css +0 -103
  39. package/src/components/ui/kb-notification-bell.tsx +0 -199
  40. package/src/components/ui/kb-page-layout.tsx +0 -66
  41. package/src/components/ui/kb-quick-search.module.css +0 -86
  42. package/src/components/ui/kb-quick-search.tsx +0 -196
  43. package/src/components/ui/kb-sidebar.module.css +0 -47
  44. package/src/components/ui/kb-sidebar.tsx +0 -196
  45. package/src/components/ui/kb-stat-card.module.css +0 -21
  46. package/src/components/ui/kb-stat-card.tsx +0 -22
  47. package/src/components/ui/kb-stat-grid.tsx +0 -22
  48. package/src/components/ui/kb-status-bar.module.css +0 -49
  49. package/src/components/ui/kb-status-bar.tsx +0 -145
  50. package/src/components/ui/kb-system-health-indicator.tsx +0 -229
  51. package/src/components/ui/kb-theme-toggle.tsx +0 -42
  52. package/src/components/ui/theme-adapter.ts +0 -812
  53. package/src/components/ui/theme-transition-overlay.tsx +0 -70
  54. package/src/components/ui/utils.ts +0 -6
  55. package/src/components/widget-error-boundary.tsx +0 -172
  56. package/src/config/env.ts +0 -5
  57. package/src/config/feature-flags.ts +0 -482
  58. package/src/config/studio.config.schema.ts +0 -88
  59. package/src/config/studio.config.ts +0 -84
  60. package/src/env.d.ts +0 -23
  61. package/src/hooks/use-command-palette.ts +0 -6
  62. package/src/hooks/use-devtools-store.ts +0 -25
  63. package/src/hooks/use-feature-flags.ts +0 -101
  64. package/src/index.css +0 -10
  65. package/src/layouts/dashboard-grid.tsx +0 -122
  66. package/src/layouts/index.ts +0 -12
  67. package/src/layouts/two-pane.tsx +0 -134
  68. package/src/main.tsx +0 -15
  69. package/src/modules/analytics/components/analytics-daily-stats-chart.tsx +0 -257
  70. package/src/modules/analytics/components/analytics-date-range-picker.tsx +0 -121
  71. package/src/modules/analytics/pages/analytics-cache-page.tsx +0 -285
  72. package/src/modules/analytics/pages/analytics-embeddings-page.tsx +0 -274
  73. package/src/modules/analytics/pages/analytics-events-page.tsx +0 -425
  74. package/src/modules/analytics/pages/analytics-llm-page.tsx +0 -434
  75. package/src/modules/analytics/pages/analytics-overview-page.tsx +0 -336
  76. package/src/modules/analytics/pages/analytics-page.tsx +0 -20
  77. package/src/modules/analytics/pages/analytics-storage-page.tsx +0 -344
  78. package/src/modules/analytics/pages/analytics-vectorstore-page.tsx +0 -279
  79. package/src/modules/analytics/routes/index.tsx +0 -133
  80. package/src/modules/analytics/utils/formatters.test.ts +0 -148
  81. package/src/modules/analytics/utils/formatters.ts +0 -100
  82. package/src/modules/auth/pages/login-page.module.css +0 -113
  83. package/src/modules/auth/pages/login-page.tsx +0 -80
  84. package/src/modules/auth/routes/index.tsx +0 -24
  85. package/src/modules/dashboard/components/ActivityTimelineWidget.tsx +0 -199
  86. package/src/modules/dashboard/components/AiInsightsWidget.tsx +0 -358
  87. package/src/modules/dashboard/components/AnimatedMetricCard.css +0 -88
  88. package/src/modules/dashboard/components/AnimatedMetricCard.tsx +0 -125
  89. package/src/modules/dashboard/components/HeroMetricCard.css +0 -114
  90. package/src/modules/dashboard/components/HeroMetricCard.tsx +0 -152
  91. package/src/modules/dashboard/components/HeroMetricsWidget.tsx +0 -146
  92. package/src/modules/dashboard/components/SystemResourcesWidget.tsx +0 -197
  93. package/src/modules/dashboard/components/dashboard-empty.tsx +0 -22
  94. package/src/modules/dashboard/components/dashboard-kpis-widget.tsx +0 -59
  95. package/src/modules/dashboard/components/dashboard-kpis.tsx +0 -13
  96. package/src/modules/dashboard/components/dashboard-latency-percentiles-widget.tsx +0 -85
  97. package/src/modules/dashboard/components/dashboard-metrics-widget.tsx +0 -78
  98. package/src/modules/dashboard/components/dashboard-plugins-widget.tsx +0 -67
  99. package/src/modules/dashboard/components/dashboard-requests-widget.tsx +0 -62
  100. package/src/modules/dashboard/layouts/dashboard-layout.tsx +0 -16
  101. package/src/modules/dashboard/pages/ai-insights-page.tsx +0 -563
  102. package/src/modules/dashboard/pages/dashboard-animations.css +0 -317
  103. package/src/modules/dashboard/pages/dashboard-page.tsx +0 -13
  104. package/src/modules/dashboard/routes/index.tsx +0 -70
  105. package/src/modules/observability/pages/devkit-page.tsx +0 -263
  106. package/src/modules/observability/pages/incident-detail-page.tsx +0 -571
  107. package/src/modules/observability/pages/incidents-page.tsx +0 -370
  108. package/src/modules/observability/pages/log-detail-page.tsx +0 -508
  109. package/src/modules/observability/pages/logs-page.tsx +0 -1129
  110. package/src/modules/observability/pages/prometheus-metrics-page.tsx +0 -486
  111. package/src/modules/observability/pages/state-broker-page.tsx +0 -229
  112. package/src/modules/observability/pages/system-events-page.tsx +0 -255
  113. package/src/modules/observability/routes/index.tsx +0 -133
  114. package/src/modules/plugins/components/marketplace-card.tsx +0 -153
  115. package/src/modules/plugins/components/plugin-ai-assistant-modal.tsx +0 -374
  116. package/src/modules/plugins/components/plugin-card.tsx +0 -136
  117. package/src/modules/plugins/components/plugin-detail/capabilities-summary.tsx +0 -101
  118. package/src/modules/plugins/components/plugin-detail/cli-commands-table.tsx +0 -101
  119. package/src/modules/plugins/components/plugin-detail/index.ts +0 -7
  120. package/src/modules/plugins/components/plugin-detail/jobs-table.tsx +0 -64
  121. package/src/modules/plugins/components/plugin-detail/permissions/env-permissions.tsx +0 -30
  122. package/src/modules/plugins/components/plugin-detail/permissions/filesystem-permissions.tsx +0 -68
  123. package/src/modules/plugins/components/plugin-detail/permissions/index.ts +0 -6
  124. package/src/modules/plugins/components/plugin-detail/permissions/network-permissions.tsx +0 -43
  125. package/src/modules/plugins/components/plugin-detail/permissions/platform-services.tsx +0 -242
  126. package/src/modules/plugins/components/plugin-detail/permissions/resource-quotas.tsx +0 -96
  127. package/src/modules/plugins/components/plugin-detail/permissions/shell-permissions.tsx +0 -55
  128. package/src/modules/plugins/components/plugin-detail/permissions-view.tsx +0 -47
  129. package/src/modules/plugins/components/plugin-detail/plugin-header.tsx +0 -169
  130. package/src/modules/plugins/components/plugin-detail/rest-routes-table.tsx +0 -159
  131. package/src/modules/plugins/components/plugin-detail/workflows-table.tsx +0 -40
  132. package/src/modules/plugins/components/plugin-grid.tsx +0 -20
  133. package/src/modules/plugins/components/plugin-table.tsx +0 -178
  134. package/src/modules/plugins/pages/marketplace-page.tsx +0 -200
  135. package/src/modules/plugins/pages/plugin-detail-page.tsx +0 -1145
  136. package/src/modules/plugins/routes/index.tsx +0 -48
  137. package/src/modules/plugins/utils/index.ts +0 -1
  138. package/src/modules/plugins/utils/schema-helpers.ts +0 -21
  139. package/src/modules/settings/components/api-routes-viewer.tsx +0 -415
  140. package/src/modules/settings/components/appearance-settings.tsx +0 -200
  141. package/src/modules/settings/components/configuration-settings.tsx +0 -321
  142. package/src/modules/settings/components/data-privacy-settings.tsx +0 -111
  143. package/src/modules/settings/components/experimental-settings.tsx +0 -243
  144. package/src/modules/settings/components/navigation-settings.tsx +0 -198
  145. package/src/modules/settings/components/notifications-settings.tsx +0 -40
  146. package/src/modules/settings/pages/settings-page.tsx +0 -298
  147. package/src/modules/settings/routes/index.tsx +0 -47
  148. package/src/pages/README-assistant.md +0 -91
  149. package/src/pages/login-page.tsx +0 -177
  150. package/src/pages/not-found-page.tsx +0 -85
  151. package/src/providers/auth-provider.tsx +0 -40
  152. package/src/providers/command-palette-provider.tsx +0 -193
  153. package/src/providers/data-sources-provider.tsx +0 -27
  154. package/src/providers/devtools-provider.tsx +0 -72
  155. package/src/providers/navigation-items-provider.tsx +0 -38
  156. package/src/providers/registry-v2-provider.tsx +0 -93
  157. package/src/providers/settings-provider.tsx +0 -158
  158. package/src/router.tsx +0 -302
  159. package/src/routes/helpers.tsx +0 -25
  160. package/src/routes/plugin-page-v2.tsx +0 -52
  161. package/src/routes/types.ts +0 -18
  162. package/src/styles/antd-overrides.css +0 -211
  163. package/src/styles/base.css +0 -190
  164. package/src/styles/settings.css +0 -75
  165. package/src/styles/variables.css +0 -94
  166. package/src/utils/analytics.ts +0 -183
  167. package/src/utils/apply-navigation-categories.ts +0 -83
  168. package/src/utils/commands.ts +0 -252
  169. package/src/utils/export.ts +0 -174
  170. package/src/utils/format-date.ts +0 -166
  171. package/src/utils/logger.ts +0 -110
  172. package/tailwind.config.ts +0 -13
  173. package/tsconfig.json +0 -13
  174. package/vitest-setup.ts +0 -1
  175. /package/{public → dist}/favicon.svg +0 -0
@@ -1,508 +0,0 @@
1
- import {
2
- UICard,
3
- UIAlert,
4
- UIBadge,
5
- UITag,
6
- UITypographyText,
7
- UITypographyParagraph,
8
- UISpace,
9
- UIButton,
10
- UIDescriptions,
11
- UIDescriptionsItem,
12
- UITooltip,
13
- UIMessage,
14
- UISpin,
15
- UITimeline,
16
- UIEmptyState,
17
- UIIcon,
18
- } from '@kb-labs/studio-ui-kit';
19
- import { useState, useEffect } from 'react';
20
- import { useParams, useNavigate } from 'react-router-dom';
21
- import { useDataSources } from '../../../providers/data-sources-provider';
22
- import type { LogRecord } from '@kb-labs/studio-data-client';
23
- import { UIPage, UIPageHeader } from '@kb-labs/studio-ui-kit';
24
-
25
- /**
26
- * Format timestamp to full datetime with milliseconds
27
- */
28
- function formatDateTime(timestamp: string | number): string {
29
- const date = new Date(typeof timestamp === 'number' ? timestamp : timestamp);
30
- return date.toLocaleString('en-US', {
31
- year: 'numeric',
32
- month: '2-digit',
33
- day: '2-digit',
34
- hour: '2-digit',
35
- minute: '2-digit',
36
- second: '2-digit',
37
- hour12: false,
38
- }) + '.' + date.getMilliseconds().toString().padStart(3, '0');
39
- }
40
-
41
- /**
42
- * Format relative time (e.g., "2 minutes ago")
43
- */
44
- function formatRelativeTime(timestamp: string | number): string {
45
- const ms = typeof timestamp === 'number' ? timestamp : new Date(timestamp).getTime();
46
- const seconds = Math.floor((Date.now() - ms) / 1000);
47
-
48
- if (seconds < 60) {return `${seconds}s ago`;}
49
- if (seconds < 3600) {return `${Math.floor(seconds / 60)}m ago`;}
50
- if (seconds < 86400) {return `${Math.floor(seconds / 3600)}h ago`;}
51
- return `${Math.floor(seconds / 86400)}d ago`;
52
- }
53
-
54
- /**
55
- * Get log level icon
56
- */
57
- function getLevelIcon(level: LogRecord['level'] | string) {
58
- switch (level) {
59
- case 'trace':
60
- case 'debug':
61
- return <UIIcon name="BugOutlined" style={{ fontSize: 20, color: '#8c8c8c' }} />;
62
- case 'info':
63
- return <UIIcon name="InfoCircleOutlined" style={{ fontSize: 20, color: '#1890ff' }} />;
64
- case 'warn':
65
- return <UIIcon name="WarningOutlined" style={{ fontSize: 20, color: '#faad14' }} />;
66
- case 'error':
67
- case 'fatal':
68
- default:
69
- return <UIIcon name="CloseCircleOutlined" style={{ fontSize: 20, color: '#ff4d4f' }} />;
70
- }
71
- }
72
-
73
- /**
74
- * Get log level tag color
75
- */
76
- function getLevelColor(level: LogRecord['level'] | string): string {
77
- switch (level) {
78
- case 'trace':
79
- case 'debug':
80
- return 'default';
81
- case 'info':
82
- return 'blue';
83
- case 'warn':
84
- return 'orange';
85
- case 'error':
86
- case 'fatal':
87
- default:
88
- return 'red';
89
- }
90
- }
91
-
92
- /**
93
- * Copy text to clipboard
94
- */
95
- function copyToClipboard(text: string, label: string) {
96
- navigator.clipboard.writeText(text);
97
- UIMessage.success(`${label} copied to clipboard`);
98
- }
99
-
100
- /**
101
- * Log Detail Page
102
- *
103
- * Shows detailed view of a single log with:
104
- * - Full log context (message, level, source, timestamp)
105
- * - Error details (stack trace if available)
106
- * - Related logs timeline (based on correlation IDs)
107
- * - All log metadata fields
108
- */
109
- export function LogDetailPage() {
110
- const { id } = useParams<{ id: string }>();
111
- const navigate = useNavigate();
112
- const sources = useDataSources();
113
-
114
- const [loading, setLoading] = useState(true);
115
- const [error, setError] = useState<Error | null>(null);
116
- const [log, setLog] = useState<LogRecord | null>(null);
117
- const [relatedLogs, setRelatedLogs] = useState<LogRecord[]>([]);
118
- const [correlationKeys, setCorrelationKeys] = useState<any>(null);
119
-
120
- useEffect(() => {
121
- if (!id) {return;}
122
-
123
- const loadLog = async () => {
124
- setLoading(true);
125
- setError(null);
126
-
127
- try {
128
- // Fetch log with related logs
129
- const response = await sources.observability.getLog(id, true);
130
-
131
- setLog(response.log);
132
- setRelatedLogs(response.related || []);
133
- } catch (err: any) {
134
- setError(err);
135
- } finally {
136
- setLoading(false);
137
- }
138
- };
139
-
140
- loadLog();
141
- }, [id, sources.observability]);
142
-
143
- // Load correlation keys separately if we have the log
144
- useEffect(() => {
145
- if (!id || !log) {return;}
146
-
147
- const loadRelated = async () => {
148
- try {
149
- const response = await sources.observability.getRelatedLogs(id);
150
- setCorrelationKeys(response.correlationKeys);
151
- } catch (err) {
152
- // Silent fail - correlation keys are nice-to-have
153
- console.error('Failed to load correlation keys:', err);
154
- }
155
- };
156
-
157
- loadRelated();
158
- }, [id, log, sources.observability]);
159
-
160
- if (loading) {
161
- return (
162
- <UIPage>
163
- <div style={{ textAlign: 'center', padding: '100px 0' }}>
164
- <UISpin size="large" tip="Loading log details..." />
165
- </div>
166
- </UIPage>
167
- );
168
- }
169
-
170
- if (error || !log) {
171
- return (
172
- <UIPage>
173
- <UIPageHeader
174
- title="Log Not Found"
175
- description="The requested log could not be found"
176
- onBack={() => navigate('/observability/logs')}
177
- />
178
- <UIAlert
179
- message={error ? 'Error loading log' : 'Log not found'}
180
- description={error ? error.message : `Log with ID '${id}' does not exist`}
181
- variant="error"
182
- showIcon
183
- />
184
- </UIPage>
185
- );
186
- }
187
-
188
- // Extract correlation ID fields (not part of LogRecord type, accessed via index signature)
189
- const logTraceId = log.traceId as string | undefined;
190
- const logRequestId = log.requestId as string | undefined;
191
- const logSessionId = log.sessionId as string | undefined;
192
-
193
- // Extract error details if present
194
- const errorDetails = (log.err || log.error) as { name?: string; message?: string; stack?: string } | undefined;
195
- const hasError = !!errorDetails;
196
-
197
- // Build metadata fields (exclude standard fields and error)
198
- const metadataFields: Record<string, unknown> = { ...log };
199
- delete metadataFields['time'];
200
- delete metadataFields['level'];
201
- delete metadataFields['msg'];
202
- delete metadataFields['plugin'];
203
- delete metadataFields['err'];
204
- delete metadataFields['error'];
205
- delete metadataFields['traceId'];
206
- delete metadataFields['executionId'];
207
- delete metadataFields['requestId'];
208
- delete metadataFields['sessionId'];
209
-
210
- return (
211
- <UIPage>
212
- <UIPageHeader
213
- title="Log Details"
214
- description={`Viewing log from ${formatRelativeTime(log.time)}`}
215
- onBack={() => navigate('/observability/logs')}
216
- actions={[
217
- <UIButton
218
- key="copy-link"
219
- icon={<UIIcon name="LinkOutlined" />}
220
- onClick={() => copyToClipboard(window.location.href, 'Link')}
221
- >
222
- Copy Link
223
- </UIButton>,
224
- <UIButton
225
- key="copy-json"
226
- icon={<UIIcon name="CopyOutlined" />}
227
- onClick={() => copyToClipboard(JSON.stringify(log, null, 2), 'JSON')}
228
- >
229
- Export JSON
230
- </UIButton>,
231
- ]}
232
- />
233
-
234
- {/* Log Overview Card */}
235
- <UICard
236
- style={{ marginBottom: 16 }}
237
- title={
238
- <UISpace>
239
- {getLevelIcon(log.level)}
240
- <span>Log Overview</span>
241
- <UITag color={getLevelColor(log.level)}>{log.level.toUpperCase()}</UITag>
242
- </UISpace>
243
- }
244
- >
245
- <UIDescriptions column={2} bordered>
246
- <UIDescriptionsItem label="Timestamp">
247
- <UISpace>
248
- <UIIcon name="ClockCircleOutlined" />
249
- <UITypographyText code>{formatDateTime(log.time)}</UITypographyText>
250
- <UITypographyText type="secondary">({formatRelativeTime(log.time)})</UITypographyText>
251
- </UISpace>
252
- </UIDescriptionsItem>
253
-
254
- <UIDescriptionsItem label="Source">
255
- <UITag color="purple">{String(log.plugin || log.source || 'unknown')}</UITag>
256
- </UIDescriptionsItem>
257
-
258
- <UIDescriptionsItem label="Message" span={2}>
259
- <UITypographyText strong style={{ fontSize: 14 }}>
260
- {String(log.msg || '(no message)')}
261
- </UITypographyText>
262
- </UIDescriptionsItem>
263
-
264
- {/* Correlation IDs */}
265
- {logTraceId && (
266
- <UIDescriptionsItem label="Trace ID">
267
- <UISpace>
268
- <UITypographyText code>{logTraceId}</UITypographyText>
269
- <UITooltip title="Copy trace ID">
270
- <UIButton
271
- size="small"
272
- icon={<UIIcon name="CopyOutlined" />}
273
- onClick={() => copyToClipboard(logTraceId, 'Trace ID')}
274
- />
275
- </UITooltip>
276
- </UISpace>
277
- </UIDescriptionsItem>
278
- )}
279
-
280
- {Boolean(log.executionId) && (
281
- <UIDescriptionsItem label="Execution ID">
282
- <UISpace>
283
- <UITypographyText code>{String(log.executionId)}</UITypographyText>
284
- <UITooltip title="Copy execution ID">
285
- <UIButton
286
- size="small"
287
- icon={<UIIcon name="CopyOutlined" />}
288
- onClick={() => copyToClipboard(String(log.executionId), 'Execution ID')}
289
- />
290
- </UITooltip>
291
- </UISpace>
292
- </UIDescriptionsItem>
293
- )}
294
-
295
- {logRequestId && (
296
- <UIDescriptionsItem label="Request ID">
297
- <UISpace>
298
- <UITypographyText code>{logRequestId}</UITypographyText>
299
- <UITooltip title="Copy request ID">
300
- <UIButton
301
- size="small"
302
- icon={<UIIcon name="CopyOutlined" />}
303
- onClick={() => copyToClipboard(logRequestId, 'Request ID')}
304
- />
305
- </UITooltip>
306
- </UISpace>
307
- </UIDescriptionsItem>
308
- )}
309
-
310
- {logSessionId && (
311
- <UIDescriptionsItem label="Session ID">
312
- <UISpace>
313
- <UITypographyText code>{logSessionId}</UITypographyText>
314
- <UITooltip title="Copy session ID">
315
- <UIButton
316
- size="small"
317
- icon={<UIIcon name="CopyOutlined" />}
318
- onClick={() => copyToClipboard(logSessionId, 'Session ID')}
319
- />
320
- </UITooltip>
321
- </UISpace>
322
- </UIDescriptionsItem>
323
- )}
324
- </UIDescriptions>
325
- </UICard>
326
-
327
- {/* Error Details Card (if error exists) */}
328
- {hasError && (
329
- <UICard
330
- style={{ marginBottom: 16 }}
331
- title={
332
- <UISpace>
333
- <UIIcon name="CloseCircleOutlined" style={{ color: '#ff4d4f' }} />
334
- <span>Error Details</span>
335
- </UISpace>
336
- }
337
- type="inner"
338
- >
339
- <UISpace direction="vertical" style={{ width: '100%' }} size="middle">
340
- {errorDetails.name && (
341
- <div>
342
- <UITypographyText type="secondary">Error Type:</UITypographyText>
343
- <br />
344
- <UITag color="red">{errorDetails.name}</UITag>
345
- </div>
346
- )}
347
-
348
- {errorDetails.message && (
349
- <div>
350
- <UITypographyText type="secondary">Error Message:</UITypographyText>
351
- <br />
352
- <UITypographyText strong>{errorDetails.message}</UITypographyText>
353
- </div>
354
- )}
355
-
356
- {errorDetails.stack && (
357
- <div>
358
- <UITypographyText type="secondary">Stack Trace:</UITypographyText>
359
- <UITypographyParagraph
360
- copyable
361
- code
362
- style={{
363
- marginTop: 8,
364
- backgroundColor: '#fafafa',
365
- padding: 12,
366
- borderRadius: 4,
367
- fontSize: 12,
368
- fontFamily: 'monospace',
369
- whiteSpace: 'pre-wrap',
370
- maxHeight: 300,
371
- overflow: 'auto',
372
- }}
373
- >
374
- {errorDetails.stack}
375
- </UITypographyParagraph>
376
- </div>
377
- )}
378
- </UISpace>
379
- </UICard>
380
- )}
381
-
382
- {/* Related Logs Timeline */}
383
- <UICard
384
- style={{ marginBottom: 16 }}
385
- title={
386
- <UISpace>
387
- <UIIcon name="ClockCircleOutlined" />
388
- <span>Related Logs Timeline</span>
389
- {relatedLogs.length > 0 && (
390
- <UIBadge count={relatedLogs.length} style={{ backgroundColor: '#52c41a' }} />
391
- )}
392
- </UISpace>
393
- }
394
- >
395
- {relatedLogs.length === 0 ? (
396
- <UIEmptyState
397
- description="No related logs found"
398
- image={UIEmptyState.PRESENTED_IMAGE_SIMPLE}
399
- />
400
- ) : (
401
- <>
402
- {correlationKeys && (
403
- <UIAlert
404
- message="Correlation Keys"
405
- description={
406
- <UISpace wrap>
407
- {correlationKeys.requestId && (
408
- <UITag>Request: {correlationKeys.requestId}</UITag>
409
- )}
410
- {correlationKeys.traceId && (
411
- <UITag>Trace: {correlationKeys.traceId}</UITag>
412
- )}
413
- {correlationKeys.executionId && (
414
- <UITag>Execution: {correlationKeys.executionId}</UITag>
415
- )}
416
- {correlationKeys.sessionId && (
417
- <UITag>Session: {correlationKeys.sessionId}</UITag>
418
- )}
419
- </UISpace>
420
- }
421
- variant="info"
422
- style={{ marginBottom: 16 }}
423
- closable
424
- />
425
- )}
426
-
427
- <UITimeline
428
- mode="left"
429
- items={relatedLogs.map((relatedLog) => {
430
- const isCurrentLog = relatedLog.id === id;
431
-
432
- return {
433
- color: isCurrentLog ? 'red' : getLevelColor(relatedLog.level),
434
- dot: isCurrentLog ? (
435
- <UIBadge variant="info" />
436
- ) : (
437
- getLevelIcon(relatedLog.level)
438
- ),
439
- label: (
440
- <UITypographyText type="secondary" style={{ fontSize: 12 }}>
441
- {formatDateTime(relatedLog.time)}
442
- </UITypographyText>
443
- ),
444
- children: (
445
- <UICard
446
- size="small"
447
- style={{
448
- backgroundColor: isCurrentLog ? '#fff7e6' : undefined,
449
- borderColor: isCurrentLog ? '#ffa940' : undefined,
450
- }}
451
- >
452
- <UISpace direction="vertical" style={{ width: '100%' }} size="small">
453
- <UISpace>
454
- <UITag color={getLevelColor(relatedLog.level)}>
455
- {relatedLog.level.toUpperCase()}
456
- </UITag>
457
- {relatedLog.plugin && (
458
- <UITag color="purple">{String(relatedLog.plugin)}</UITag>
459
- )}
460
- {isCurrentLog && (
461
- <UITag color="orange">YOU ARE HERE</UITag>
462
- )}
463
- </UISpace>
464
- <UITypographyText>{String(relatedLog.msg || '(no message)')}</UITypographyText>
465
- {relatedLog.err && (
466
- <UITag color="red" icon={<UIIcon name="CloseCircleOutlined" />}>
467
- {String(relatedLog.err.name || 'Error')}
468
- </UITag>
469
- )}
470
- </UISpace>
471
- </UICard>
472
- ),
473
- };
474
- })}
475
- />
476
- </>
477
- )}
478
- </UICard>
479
-
480
- {/* All Log Fields */}
481
- <UICard
482
- title={
483
- <UISpace>
484
- <UIIcon name="FileTextOutlined" />
485
- <span>All Log Fields</span>
486
- </UISpace>
487
- }
488
- >
489
- <UITypographyParagraph
490
- copyable
491
- code
492
- style={{
493
- backgroundColor: '#fafafa',
494
- padding: 16,
495
- borderRadius: 4,
496
- fontSize: 12,
497
- fontFamily: 'monospace',
498
- whiteSpace: 'pre-wrap',
499
- maxHeight: 500,
500
- overflow: 'auto',
501
- }}
502
- >
503
- {JSON.stringify(log, null, 2)}
504
- </UITypographyParagraph>
505
- </UICard>
506
- </UIPage>
507
- );
508
- }