@datalayer/core 1.2.18 → 1.2.20
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/lib/cli-login.js +5 -51
- package/lib/components/anonymous/AnonymousKeyExpired.js +1 -15
- package/lib/components/anonymous/AnonymousKeyTimer.js +5 -15
- package/lib/components/auth/SignIn.js +2 -2
- package/lib/components/avatars/UserAvatar.d.ts +10 -11
- package/lib/components/avatars/UserAvatar.js +23 -52
- package/lib/components/avatars/UserProfileAvatar.js +1 -1
- package/lib/components/avatars/avatarChoice.d.ts +42 -0
- package/lib/components/avatars/avatarChoice.js +65 -0
- package/lib/components/avatars/index.d.ts +1 -0
- package/lib/components/avatars/index.js +1 -0
- package/lib/components/billing/BillingEntitySelect.js +6 -48
- package/lib/components/checkout/StripeCheckout.js +33 -217
- package/lib/components/collaboration/LiveEditorCollaborators.d.ts +3 -4
- package/lib/components/collaboration/LiveEditorCollaborators.js +7 -5
- package/lib/components/contents/ContentSourceCard.js +2 -11
- package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +1 -1
- package/lib/components/contents/HomeFolderObjectsBrowser.js +11 -35
- package/lib/components/display/CenteredSpinner.js +1 -6
- package/lib/components/display/DatalayerBox.js +2 -14
- package/lib/components/emoji/faceEmojis.js +48 -0
- package/lib/components/emoji/fluent/loaders.js +46 -0
- package/lib/components/emoji/fluent/svg/1f30a.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f30a.js +5 -0
- package/lib/components/emoji/fluent/svg/1f310.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f310.js +5 -0
- package/lib/components/emoji/fluent/svg/1f324.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f324.js +5 -0
- package/lib/components/emoji/fluent/svg/1f326.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f326.js +5 -0
- package/lib/components/emoji/fluent/svg/1f327.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f327.js +5 -0
- package/lib/components/emoji/fluent/svg/1f33e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f33e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f372.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f372.js +5 -0
- package/lib/components/emoji/fluent/svg/1f373.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f373.js +5 -0
- package/lib/components/emoji/fluent/svg/1f39b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f39b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3ab.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3ab.js +5 -0
- package/lib/components/emoji/fluent/svg/1f41b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f41b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f441.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f441.js +5 -0
- package/lib/components/emoji/fluent/svg/1f465.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f465.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4b9.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4b9.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4be.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4be.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c4.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c4.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4d3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4d3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4d6.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4d6.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4dc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4dc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f500.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f500.js +5 -0
- package/lib/components/emoji/fluent/svg/1f501.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f501.js +5 -0
- package/lib/components/emoji/fluent/svg/1f504.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f504.js +5 -0
- package/lib/components/emoji/fluent/svg/1f52d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f52d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f552.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f552.js +5 -0
- package/lib/components/emoji/fluent/svg/1f58b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f58b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5b2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5b2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5c3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5c3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5d1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5d1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5dc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5dc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f604.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f604.js +5 -0
- package/lib/components/emoji/fluent/svg/1f917.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f917.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2696.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2696.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa79.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa79.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa9d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa9d.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa9f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa9f.js +5 -0
- package/lib/components/emoji/fluent/svg/23f3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/23f3.js +5 -0
- package/lib/components/emoji/fluent/svg/2611.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2611.js +5 -0
- package/lib/components/emoji/fluent/svg/2702.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2702.js +5 -0
- package/lib/components/emoji/fluent/svg/270f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/270f.js +5 -0
- package/lib/components/emoji/fluent/svg/2728.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2728.js +5 -0
- package/lib/components/emoji/fluent/svg/2b1c.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2b1c.js +5 -0
- package/lib/components/flashes/FlashClosable.js +2 -17
- package/lib/components/mcp/ClientBadge.js +1 -1
- package/lib/components/mcp/McpErrorBlankslate.js +1 -1
- package/lib/components/mcp/ScopeList.js +1 -1
- package/lib/components/notebooks/JupyterNotebook.js +1 -2
- package/lib/components/principal/Principal.js +2 -10
- package/lib/components/principal/PrincipalAppearance.d.ts +24 -1
- package/lib/components/principal/PrincipalAppearance.js +107 -80
- package/lib/components/principal/PrincipalAvatar.d.ts +5 -7
- package/lib/components/principal/PrincipalAvatar.js +12 -38
- package/lib/components/principal/PrincipalBadge.js +3 -13
- package/lib/components/principal/PrincipalBanner.js +4 -32
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +4 -7
- package/lib/components/principal/PrincipalDetailsOverlay.js +8 -24
- package/lib/components/principal/PrincipalHoverCard.js +15 -18
- package/lib/components/principal/PrincipalSwitcherMenu.js +15 -83
- package/lib/components/progress/ConsumptionBar.js +1 -1
- package/lib/components/sharing/ShareAccessComponent.js +21 -229
- package/lib/components/sharing/SharingEditor.js +1 -1
- package/lib/components/spaces/SpaceDetailsOverlay.js +4 -35
- package/lib/components/spaces/SpaceDisplay.js +1 -8
- package/lib/components/storage/ContentsBrowser.js +3 -26
- package/lib/components/storage/ContentsTable.js +4 -23
- package/lib/components/students/StudentResultCircle.js +7 -29
- package/lib/components/timeline/Timeline.js +4 -36
- package/lib/hooks/layouts/LayoutBackdrop.js +2 -1
- package/lib/hooks/layouts/LayoutScreencapture.js +1 -1
- package/lib/hooks/libraryApp.d.ts +6 -1
- package/lib/hooks/libraryApp.js +10 -1
- package/lib/hooks/unlinkIAMProvider.d.ts +22 -0
- package/lib/hooks/unlinkIAMProvider.js +24 -0
- package/lib/hooks/useAuthorization.js +6 -1
- package/lib/hooks/useCache.d.ts +8 -1
- package/lib/hooks/useCache.js +35 -4
- package/lib/hooks/useNavigate.js +8 -2
- package/lib/mocks/components/FlashMock.js +3 -8
- package/lib/mocks/views/DashboardMock.js +6 -72
- package/lib/mocks/views/FormMock.js +3 -2
- package/lib/mocks/views/TableMock.js +3 -2
- package/lib/mocks/views/WipMock.js +2 -1
- package/lib/models/IAMProviderLinked.d.ts +9 -0
- package/lib/models/IAMProviderLinked.js +34 -5
- package/lib/models/McpTask.d.ts +18 -1
- package/lib/models/McpTask.js +15 -0
- package/lib/models/Person.d.ts +9 -0
- package/lib/models/Person.js +23 -0
- package/lib/models/Profile.d.ts +2 -2
- package/lib/models/User.js +5 -12
- package/lib/models/UserOnboarding.d.ts +9 -0
- package/lib/models/UserOnboarding.js +33 -0
- package/lib/otel/views/OtelLive.js +4 -62
- package/lib/otel/views/OtelLiveSpans.js +4 -29
- package/lib/otel/views/OtelLogsList.js +13 -64
- package/lib/otel/views/OtelMetricsChart.js +4 -19
- package/lib/otel/views/OtelMetricsList.js +8 -77
- package/lib/otel/views/OtelSearchBar.js +3 -12
- package/lib/otel/views/OtelSpanDetail.js +9 -79
- package/lib/otel/views/OtelSpanTree.js +7 -57
- package/lib/otel/views/OtelSqlView.js +5 -99
- package/lib/otel/views/OtelSystemView.js +4 -34
- package/lib/otel/views/OtelTimeline.js +7 -37
- package/lib/otel/views/OtelTimelineRangeSlider.js +7 -140
- package/lib/otel/views/OtelTracesList.js +12 -76
- package/lib/portable/index.d.ts +9 -0
- package/lib/portable/index.js +14 -0
- package/lib/portable/states.d.ts +39 -0
- package/lib/portable/states.js +71 -0
- package/lib/state/substates/NavigationState.d.ts +10 -6
- package/lib/state/substates/NavigationState.js +18 -8
- package/lib/views/api-keys/APIKeyEdit.js +2 -11
- package/lib/views/api-keys/APIKeyNew.js +3 -19
- package/lib/views/api-keys/APIKeys.js +6 -11
- package/lib/views/api-keys/APIKeysStandalone.js +1 -1
- package/lib/views/datasources/DatasourceDetail.d.ts +1 -1
- package/lib/views/datasources/DatasourceDetail.js +24 -17
- package/lib/views/datasources/DatasourceNew.js +2 -6
- package/lib/views/datasources/Datasources.js +2 -14
- package/lib/views/iam/SignInSimple.js +8 -64
- package/lib/views/mcp/AdmittedClients.js +3 -16
- package/lib/views/mcp/AlertDestinations.js +3 -11
- package/lib/views/mcp/AlertRules.js +4 -9
- package/lib/views/mcp/ApprovalQueue.js +5 -22
- package/lib/views/mcp/AuditLog.js +7 -44
- package/lib/views/mcp/ConnectedAgents.js +1 -6
- package/lib/views/mcp/EnterpriseConsole.js +11 -24
- package/lib/views/mcp/IdentityProviders.js +7 -31
- package/lib/views/mcp/McpDashboard.js +15 -31
- package/lib/views/mcp/McpHome.js +8 -55
- package/lib/views/mcp/McpObservability.js +14 -86
- package/lib/views/mcp/NotebookRuns.js +6 -13
- package/lib/views/mcp/OrganizationPolicy.js +3 -9
- package/lib/views/mcp/OrganizationUsage.js +5 -12
- package/lib/views/mcp/PersonalPolicy.js +3 -3
- package/lib/views/mcp/Policies.js +6 -47
- package/lib/views/mcp/PolicyForm.js +1 -9
- package/lib/views/mcp/PolicyHistory.js +2 -8
- package/lib/views/mcp/RunDetail.d.ts +1 -1
- package/lib/views/mcp/RunDetail.js +7 -26
- package/lib/views/mcp/ScimProvisioning.js +4 -16
- package/lib/views/mcp/ServiceAgents.js +4 -17
- package/lib/views/mcp/TeamPolicies.js +7 -19
- package/lib/views/mcp/ToolAccess.js +16 -23
- package/lib/views/mcp/TraceTimeline.js +8 -23
- package/lib/views/otel/DashboardView.js +2 -2
- package/lib/views/otel/LogsView.js +2 -2
- package/lib/views/otel/MetricsView.js +2 -2
- package/lib/views/otel/OtelHeader.js +6 -40
- package/lib/views/otel/SqlView.js +2 -2
- package/lib/views/otel/SystemView.js +2 -2
- package/lib/views/otel/TracesView.js +2 -2
- package/lib/views/profile/UserBadge.js +6 -98
- package/lib/views/secrets/SecretEdit.js +2 -11
- package/lib/views/secrets/SecretNew.js +1 -1
- package/package.json +1 -1
|
@@ -12,56 +12,28 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
* @module otel/OtelLogsList
|
|
13
13
|
*/
|
|
14
14
|
import React, { useState } from 'react';
|
|
15
|
-
import { Box
|
|
15
|
+
import { Box } from '@datalayer/primer-addons';
|
|
16
|
+
import { Text, Label, Spinner } from '@primer/react';
|
|
16
17
|
import { Blankslate } from '@primer/react/experimental';
|
|
17
18
|
import { LogIcon } from '@primer/octicons-react';
|
|
18
19
|
import { formatTime, severityVariant } from '../utils.js';
|
|
19
20
|
// ── helpers ─────────────────────────────────────────────────────────
|
|
20
21
|
/** Severity badge using Primer Label, centered in its grid cell. */
|
|
21
|
-
const Severity = ({ text }) => (_jsx(Box, {
|
|
22
|
+
const Severity = ({ text }) => (_jsx(Box, { display: "flex", alignItems: "center", justifyContent: "center", children: _jsx(Label, { size: "small", variant: severityVariant(text), children: text }) }));
|
|
22
23
|
/** Expandable row detail for a single log record. */
|
|
23
|
-
const LogDetail = ({ log }) => (_jsxs(Box, { sx: {
|
|
24
|
-
gridColumn: '1 / -1',
|
|
25
|
-
bg: 'canvas.subtle',
|
|
26
|
-
borderBottom: '1px solid',
|
|
27
|
-
borderColor: 'border.default',
|
|
28
|
-
p: 3,
|
|
29
|
-
}, children: [_jsxs(Box, { sx: { mb: 2 }, children: [_jsx(Text, { sx: {
|
|
24
|
+
const LogDetail = ({ log }) => (_jsxs(Box, { gridColumn: "1 / -1", bg: "canvas.subtle", borderBottom: "1px solid", borderColor: "border.default", p: 3, children: [_jsxs(Box, { mb: 2, children: [_jsx(Text, { sx: {
|
|
30
25
|
fontSize: 0,
|
|
31
26
|
fontWeight: 'bold',
|
|
32
27
|
color: 'fg.muted',
|
|
33
28
|
display: 'block',
|
|
34
29
|
mb: 1,
|
|
35
|
-
}, children: "Body" }), _jsx(Box, { as: "pre", sx: {
|
|
36
|
-
fontSize: 1,
|
|
37
|
-
fontFamily: 'mono',
|
|
38
|
-
whiteSpace: 'pre-wrap',
|
|
39
|
-
wordBreak: 'break-word',
|
|
40
|
-
m: 0,
|
|
41
|
-
bg: 'canvas.default',
|
|
42
|
-
border: '1px solid',
|
|
43
|
-
borderColor: 'border.default',
|
|
44
|
-
borderRadius: 2,
|
|
45
|
-
p: 2,
|
|
46
|
-
}, children: log.body })] }), log.trace_id && (_jsxs(Box, { sx: { display: 'flex', gap: 3, mb: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontWeight: 'bold' }, children: "trace_id" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: log.trace_id }), log.span_id && (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontWeight: 'bold' }, children: "span_id" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: log.span_id })] }))] })), log.attributes && Object.keys(log.attributes).length > 0 && (_jsxs(Box, { children: [_jsx(Text, { sx: {
|
|
30
|
+
}, children: "Body" }), _jsx(Box, { as: "pre", fontSize: 1, fontFamily: "mono", whiteSpace: "pre-wrap", wordBreak: "break-word", m: 0, bg: "canvas.default", border: "1px solid", borderColor: "border.default", borderRadius: 2, p: 2, children: log.body })] }), log.trace_id && (_jsxs(Box, { display: "flex", gap: 3, mb: 2, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontWeight: 'bold' }, children: "trace_id" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: log.trace_id }), log.span_id && (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontWeight: 'bold' }, children: "span_id" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: log.span_id })] }))] })), log.attributes && Object.keys(log.attributes).length > 0 && (_jsxs(Box, { children: [_jsx(Text, { sx: {
|
|
47
31
|
fontSize: 0,
|
|
48
32
|
fontWeight: 'bold',
|
|
49
33
|
color: 'fg.muted',
|
|
50
34
|
display: 'block',
|
|
51
35
|
mb: 1,
|
|
52
|
-
}, children: "Attributes" }), _jsx(Box, { sx: {
|
|
53
|
-
bg: 'canvas.default',
|
|
54
|
-
border: '1px solid',
|
|
55
|
-
borderColor: 'border.default',
|
|
56
|
-
borderRadius: 2,
|
|
57
|
-
p: 2,
|
|
58
|
-
}, children: Object.entries(log.attributes).map(([k, v]) => (_jsxs(Box, { sx: {
|
|
59
|
-
display: 'flex',
|
|
60
|
-
gap: 2,
|
|
61
|
-
py: 1,
|
|
62
|
-
borderBottom: '1px solid',
|
|
63
|
-
borderColor: 'border.muted',
|
|
64
|
-
}, children: [_jsx(Text, { sx: {
|
|
36
|
+
}, children: "Attributes" }), _jsx(Box, { bg: "canvas.default", border: "1px solid", borderColor: "border.default", borderRadius: 2, p: 2, children: Object.entries(log.attributes).map(([k, v]) => (_jsxs(Box, { display: "flex", gap: 2, py: 1, borderBottom: "1px solid", borderColor: "border.muted", children: [_jsx(Text, { sx: {
|
|
65
37
|
color: 'accent.fg',
|
|
66
38
|
fontSize: 0,
|
|
67
39
|
fontFamily: 'mono',
|
|
@@ -76,23 +48,12 @@ export const OtelLogsList = ({ logs, loading, selectedLogIndex, onSelectLog, })
|
|
|
76
48
|
const [expandedIdx, setExpandedIdx] = useState(null);
|
|
77
49
|
const colTemplate = '140px 80px 160px 1fr';
|
|
78
50
|
if (loading && logs.length === 0) {
|
|
79
|
-
return (_jsx(Box, {
|
|
51
|
+
return (_jsx(Box, { display: "flex", justifyContent: "center", p: 5, children: _jsx(Spinner, { size: "medium" }) }));
|
|
80
52
|
}
|
|
81
53
|
if (!loading && logs.length === 0) {
|
|
82
54
|
return (_jsxs(Blankslate, { children: [_jsx(Blankslate.Visual, { children: _jsx(LogIcon, { size: 24 }) }), _jsx(Blankslate.Heading, { children: "No log records found" }), _jsx(Blankslate.Description, { children: "Send some log data first." })] }));
|
|
83
55
|
}
|
|
84
|
-
return (_jsxs(Box, {
|
|
85
|
-
display: 'grid',
|
|
86
|
-
gridTemplateColumns: colTemplate,
|
|
87
|
-
bg: 'canvas.subtle',
|
|
88
|
-
borderBottom: '2px solid',
|
|
89
|
-
borderColor: 'border.default',
|
|
90
|
-
px: 3,
|
|
91
|
-
py: 1,
|
|
92
|
-
position: 'sticky',
|
|
93
|
-
top: 0,
|
|
94
|
-
zIndex: 1,
|
|
95
|
-
}, children: ['Time', 'Severity', 'Service', 'Body'].map(h => (_jsx(Text, { sx: {
|
|
56
|
+
return (_jsxs(Box, { flex: 1, minHeight: 0, overflow: "auto", children: [_jsx(Box, { display: "grid", gridTemplateColumns: colTemplate, bg: "canvas.subtle", borderBottom: "2px solid", borderColor: "border.default", px: 3, py: 1, position: "sticky", top: 0, zIndex: 1, children: ['Time', 'Severity', 'Service', 'Body'].map(h => (_jsx(Text, { sx: {
|
|
96
57
|
fontSize: 0,
|
|
97
58
|
fontWeight: 'bold',
|
|
98
59
|
color: 'fg.muted',
|
|
@@ -102,23 +63,11 @@ export const OtelLogsList = ({ logs, loading, selectedLogIndex, onSelectLog, })
|
|
|
102
63
|
}, children: h }, h))) }), logs.map((log, idx) => {
|
|
103
64
|
const selected = idx === selectedLogIndex;
|
|
104
65
|
const expanded = idx === expandedIdx;
|
|
105
|
-
return (_jsxs(React.Fragment, { children: [_jsxs(Box, {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
borderBottom: '1px solid',
|
|
111
|
-
borderColor: 'border.muted',
|
|
112
|
-
cursor: 'pointer',
|
|
113
|
-
bg: selected
|
|
114
|
-
? 'accent.subtle'
|
|
115
|
-
: expanded
|
|
116
|
-
? 'canvas.subtle'
|
|
117
|
-
: 'canvas.default',
|
|
118
|
-
':hover': {
|
|
119
|
-
bg: selected || expanded ? undefined : 'canvas.subtle',
|
|
120
|
-
},
|
|
121
|
-
}, onClick: () => {
|
|
66
|
+
return (_jsxs(React.Fragment, { children: [_jsxs(Box, { display: "grid", gridTemplateColumns: colTemplate, px: 3, py: "5px", borderBottom: "1px solid", borderColor: "border.muted", cursor: "pointer", bg: selected
|
|
67
|
+
? 'accent.subtle'
|
|
68
|
+
: expanded
|
|
69
|
+
? 'canvas.subtle'
|
|
70
|
+
: 'canvas.default', hover: { bg: selected || expanded ? undefined : 'canvas.subtle' }, onClick: () => {
|
|
122
71
|
setExpandedIdx(expanded ? null : idx);
|
|
123
72
|
onSelectLog?.(log, idx);
|
|
124
73
|
}, children: [_jsx(Text, { sx: { fontSize: 1, fontFamily: 'mono', color: 'fg.default' }, children: formatTime(log.timestamp) }), _jsx(Severity, { text: log.severity_text }), _jsx(Text, { sx: {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as echarts from 'echarts';
|
|
3
3
|
import ReactECharts from 'echarts-for-react';
|
|
4
|
-
import { Box
|
|
4
|
+
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Text, Label } from '@primer/react';
|
|
5
6
|
// ── Gradient palette ────────────────────────────────────────────────
|
|
6
7
|
const SERIES_COLORS = [
|
|
7
8
|
{
|
|
@@ -269,30 +270,14 @@ export const OtelMetricsChart = ({ metrics, height = 240, }) => {
|
|
|
269
270
|
const byType = groupByType(metrics);
|
|
270
271
|
// Sort types in a stable, user-friendly order.
|
|
271
272
|
const sortedTypes = [...byType.keys()].sort((a, b) => (TYPE_ORDER[a] ?? 99) - (TYPE_ORDER[b] ?? 99));
|
|
272
|
-
return (_jsx(Box, {
|
|
273
|
-
display: 'grid',
|
|
274
|
-
gridTemplateColumns: '1fr 1fr',
|
|
275
|
-
gap: 2,
|
|
276
|
-
}, children: sortedTypes.map(mtype => {
|
|
273
|
+
return (_jsx(Box, { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 2, children: sortedTypes.map(mtype => {
|
|
277
274
|
const nameMap = byType.get(mtype);
|
|
278
275
|
const option = buildOption(mtype, nameMap);
|
|
279
276
|
const stats = computeStats(nameMap);
|
|
280
277
|
const durationMs = stats.startTs !== null && stats.endTs !== null
|
|
281
278
|
? stats.endTs - stats.startTs
|
|
282
279
|
: null;
|
|
283
|
-
return (_jsxs(Box, { children: [_jsxs(Box, { sx: {
|
|
284
|
-
display: 'flex',
|
|
285
|
-
alignItems: 'center',
|
|
286
|
-
gap: 2,
|
|
287
|
-
px: 1,
|
|
288
|
-
mb: 1,
|
|
289
|
-
}, children: [_jsx(Label, { size: "small", variant: typeVariant(mtype), children: mtype }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.muted' }, children: typeTitle(mtype) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["(", [...nameMap.keys()].join(', '), ")"] })] }), _jsxs(Box, { sx: {
|
|
290
|
-
display: 'flex',
|
|
291
|
-
alignItems: 'center',
|
|
292
|
-
gap: 3,
|
|
293
|
-
px: 1,
|
|
294
|
-
mb: 1,
|
|
295
|
-
}, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Sum:" }), ' ', stats.total.toLocaleString(undefined, {
|
|
280
|
+
return (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 1, mb: 1, children: [_jsx(Label, { size: "small", variant: typeVariant(mtype), children: mtype }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.muted' }, children: typeTitle(mtype) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["(", [...nameMap.keys()].join(', '), ")"] })] }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 3, px: 1, mb: 1, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Sum:" }), ' ', stats.total.toLocaleString(undefined, {
|
|
296
281
|
maximumFractionDigits: 4,
|
|
297
282
|
})] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Points:" }), ' ', stats.count] }), stats.startTs !== null && stats.endTs !== null && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Interval:" }), ' ', formatTs(stats.startTs), " \u2192 ", formatTs(stats.endTs), durationMs !== null && durationMs > 0 && (_jsxs(Text, { as: "span", sx: { color: 'fg.subtle' }, children: [' ', "(", formatDuration(durationMs), ")"] }))] }))] }), _jsx(ReactECharts, { echarts: echarts, option: option, style: { width: '100%', height: `${height}px` }, notMerge: true })] }, mtype));
|
|
298
283
|
}) }));
|
|
@@ -12,7 +12,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
* @module otel/OtelMetricsList
|
|
13
13
|
*/
|
|
14
14
|
import { useMemo, useState } from 'react';
|
|
15
|
-
import { Box
|
|
15
|
+
import { Box } from '@datalayer/primer-addons';
|
|
16
|
+
import { Text, Label, Spinner, CounterLabel, SegmentedControl, } from '@primer/react';
|
|
16
17
|
import { Blankslate } from '@primer/react/experimental';
|
|
17
18
|
import { MeterIcon, ChevronDownIcon, ChevronRightIcon, GraphIcon, TableIcon, } from '@primer/octicons-react';
|
|
18
19
|
import { formatTime } from '../utils.js';
|
|
@@ -70,27 +71,7 @@ const MetricGroup = ({ name, points }) => {
|
|
|
70
71
|
const endTs = timestamps.length > 0 ? Math.max(...timestamps) : null;
|
|
71
72
|
return { min, max, avg, latest, startTs, endTs };
|
|
72
73
|
}, [points]);
|
|
73
|
-
return (_jsxs(Box, { sx: {
|
|
74
|
-
borderBottom: '1px solid',
|
|
75
|
-
borderColor: 'border.default',
|
|
76
|
-
}, children: [_jsxs(Box, { onClick: () => setExpanded(!expanded), sx: {
|
|
77
|
-
display: 'grid',
|
|
78
|
-
gridTemplateColumns: '20px 1fr auto auto auto auto',
|
|
79
|
-
gap: 3,
|
|
80
|
-
alignItems: 'center',
|
|
81
|
-
px: 3,
|
|
82
|
-
py: 2,
|
|
83
|
-
cursor: 'pointer',
|
|
84
|
-
':hover': { bg: 'canvas.subtle' },
|
|
85
|
-
}, children: [expanded ? (_jsx(ChevronDownIcon, { size: 16 })) : (_jsx(ChevronRightIcon, { size: 16 })), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 0 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: name }), first?.metric_type && (_jsx(Label, { size: "small", variant: typeVariant(first.metric_type), children: first.metric_type })), first?.unit && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["(", first.unit, ")"] }))] }), stats.startTs !== null && stats.endTs !== null && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle', fontFamily: 'mono' }, children: [formatTime(new Date(stats.startTs).toISOString()), stats.startTs !== stats.endTs && (_jsxs(_Fragment, { children: [" \u2192 ", formatTime(new Date(stats.endTs).toISOString())] }))] }))] }), _jsxs(Box, { sx: { textAlign: 'right' }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "latest" }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', fontFamily: 'mono', ml: 1 }, children: formatValue(stats.latest, first?.unit) })] }), _jsxs(Box, { sx: { textAlign: 'right' }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "avg" }), _jsx(Text, { sx: { fontSize: 1, fontFamily: 'mono', ml: 1 }, children: stats.avg.toFixed(2) })] }), _jsxs(Box, { sx: { textAlign: 'right' }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "min/max" }), _jsxs(Text, { sx: { fontSize: 1, fontFamily: 'mono', ml: 1 }, children: [stats.min.toFixed(1), "\u2013", stats.max.toFixed(1)] })] }), _jsx(CounterLabel, { children: points.length })] }), expanded && (_jsxs(Box, { sx: { bg: 'canvas.subtle' }, children: [_jsxs(Box, { sx: {
|
|
86
|
-
display: 'grid',
|
|
87
|
-
gridTemplateColumns: '20px 180px 1fr 140px 160px',
|
|
88
|
-
gap: 3,
|
|
89
|
-
px: 3,
|
|
90
|
-
py: 1,
|
|
91
|
-
borderTop: '1px solid',
|
|
92
|
-
borderColor: 'border.muted',
|
|
93
|
-
}, children: [_jsx(Box, {}), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "Time" }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "Service" }), _jsx(Text, { sx: {
|
|
74
|
+
return (_jsxs(Box, { borderBottom: "1px solid", borderColor: "border.default", children: [_jsxs(Box, { onClick: () => setExpanded(!expanded), display: "grid", gridTemplateColumns: "20px 1fr auto auto auto auto", gap: 3, alignItems: "center", px: 3, py: 2, cursor: "pointer", hover: { bg: 'canvas.subtle' }, children: [expanded ? (_jsx(ChevronDownIcon, { size: 16 })) : (_jsx(ChevronRightIcon, { size: 16 })), _jsxs(Box, { display: "flex", flexDirection: "column", gap: 0, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: name }), first?.metric_type && (_jsx(Label, { size: "small", variant: typeVariant(first.metric_type), children: first.metric_type })), first?.unit && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["(", first.unit, ")"] }))] }), stats.startTs !== null && stats.endTs !== null && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle', fontFamily: 'mono' }, children: [formatTime(new Date(stats.startTs).toISOString()), stats.startTs !== stats.endTs && (_jsxs(_Fragment, { children: [" \u2192 ", formatTime(new Date(stats.endTs).toISOString())] }))] }))] }), _jsxs(Box, { textAlign: "right", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "latest" }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', fontFamily: 'mono', ml: 1 }, children: formatValue(stats.latest, first?.unit) })] }), _jsxs(Box, { textAlign: "right", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "avg" }), _jsx(Text, { sx: { fontSize: 1, fontFamily: 'mono', ml: 1 }, children: stats.avg.toFixed(2) })] }), _jsxs(Box, { textAlign: "right", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "min/max" }), _jsxs(Text, { sx: { fontSize: 1, fontFamily: 'mono', ml: 1 }, children: [stats.min.toFixed(1), "\u2013", stats.max.toFixed(1)] })] }), _jsx(CounterLabel, { children: points.length })] }), expanded && (_jsxs(Box, { bg: "canvas.subtle", children: [_jsxs(Box, { display: "grid", gridTemplateColumns: "20px 180px 1fr 140px 160px", gap: 3, px: 3, py: 1, borderTop: "1px solid", borderColor: "border.muted", children: [_jsx(Box, {}), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "Time" }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "Service" }), _jsx(Text, { sx: {
|
|
94
75
|
fontSize: 0,
|
|
95
76
|
fontWeight: 'bold',
|
|
96
77
|
color: 'fg.muted',
|
|
@@ -108,31 +89,15 @@ const MetricRow = ({ metric }) => {
|
|
|
108
89
|
const attrCount = metric.attributes
|
|
109
90
|
? Object.keys(metric.attributes).length
|
|
110
91
|
: 0;
|
|
111
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
|
|
112
|
-
display: 'grid',
|
|
113
|
-
gridTemplateColumns: '20px 180px 1fr 140px 160px',
|
|
114
|
-
gap: 3,
|
|
115
|
-
alignItems: 'center',
|
|
116
|
-
px: 3,
|
|
117
|
-
py: 1,
|
|
118
|
-
borderTop: '1px solid',
|
|
119
|
-
borderColor: 'border.muted',
|
|
120
|
-
':hover': { bg: 'canvas.inset' },
|
|
121
|
-
}, children: [_jsx(Box, {}), _jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono', color: 'fg.muted' }, children: formatTime(metric.timestamp) }), _jsx(Text, { sx: { fontSize: 0 }, children: metric.service_name }), _jsx(Text, { sx: {
|
|
92
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "grid", gridTemplateColumns: "20px 180px 1fr 140px 160px", gap: 3, alignItems: "center", px: 3, py: 1, borderTop: "1px solid", borderColor: "border.muted", hover: { bg: 'canvas.inset' }, children: [_jsx(Box, {}), _jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono', color: 'fg.muted' }, children: formatTime(metric.timestamp) }), _jsx(Text, { sx: { fontSize: 0 }, children: metric.service_name }), _jsx(Text, { sx: {
|
|
122
93
|
fontSize: 1,
|
|
123
94
|
fontFamily: 'mono',
|
|
124
95
|
fontWeight: 'bold',
|
|
125
96
|
textAlign: 'right',
|
|
126
|
-
}, children: formatValue(metric.value, metric.unit) }), _jsx(Box, {
|
|
97
|
+
}, children: formatValue(metric.value, metric.unit) }), _jsx(Box, { textAlign: "right", children: attrCount > 0 ? (_jsxs(Label, { size: "small", variant: "secondary", onClick: (e) => {
|
|
127
98
|
e.stopPropagation();
|
|
128
99
|
setShowAttrs(!showAttrs);
|
|
129
|
-
}, sx: { cursor: 'pointer' }, children: [attrCount, " attr", attrCount !== 1 ? 's' : ''] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014" })) })] }), showAttrs && metric.attributes && (_jsx(Box, {
|
|
130
|
-
m: 0,
|
|
131
|
-
fontSize: 0,
|
|
132
|
-
fontFamily: 'mono',
|
|
133
|
-
whiteSpace: 'pre-wrap',
|
|
134
|
-
wordBreak: 'break-word',
|
|
135
|
-
}, children: JSON.stringify(metric.attributes, null, 2) }) }))] }));
|
|
100
|
+
}, sx: { cursor: 'pointer' }, children: [attrCount, " attr", attrCount !== 1 ? 's' : ''] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014" })) })] }), showAttrs && metric.attributes && (_jsx(Box, { px: 5, py: 2, bg: "canvas.inset", children: _jsx(Box, { as: "pre", m: 0, fontSize: 0, fontFamily: "mono", whiteSpace: "pre-wrap", wordBreak: "break-word", children: JSON.stringify(metric.attributes, null, 2) }) }))] }));
|
|
136
101
|
};
|
|
137
102
|
// ── OtelMetricsList ─────────────────────────────────────────────────
|
|
138
103
|
const COOKIE_KEY = 'otel_metrics_view';
|
|
@@ -163,46 +128,12 @@ export const OtelMetricsList = ({ metrics, loading = false, }) => {
|
|
|
163
128
|
};
|
|
164
129
|
const grouped = useMemo(() => groupByName(metrics), [metrics]);
|
|
165
130
|
if (loading) {
|
|
166
|
-
return (_jsx(Box, {
|
|
167
|
-
display: 'flex',
|
|
168
|
-
justifyContent: 'center',
|
|
169
|
-
alignItems: 'center',
|
|
170
|
-
p: 5,
|
|
171
|
-
}, children: _jsx(Spinner, { size: "medium" }) }));
|
|
131
|
+
return (_jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", p: 5, children: _jsx(Spinner, { size: "medium" }) }));
|
|
172
132
|
}
|
|
173
133
|
if (metrics.length === 0) {
|
|
174
134
|
return (_jsxs(Blankslate, { children: [_jsx(Blankslate.Visual, { children: _jsx(MeterIcon, { size: 20 }) }), _jsx(Blankslate.Heading, { children: "No metrics yet" }), _jsx(Blankslate.Description, { children: "Generate some metrics or adjust the filters above." })] }));
|
|
175
135
|
}
|
|
176
|
-
return (_jsxs(Box, { sx: {
|
|
177
|
-
display: 'flex',
|
|
178
|
-
flexDirection: 'column',
|
|
179
|
-
flex: 1,
|
|
180
|
-
minHeight: 0,
|
|
181
|
-
overflow: 'hidden',
|
|
182
|
-
}, children: [_jsx(Box, { sx: {
|
|
183
|
-
flexShrink: 0,
|
|
184
|
-
display: 'flex',
|
|
185
|
-
alignItems: 'center',
|
|
186
|
-
justifyContent: 'flex-end',
|
|
187
|
-
px: 3,
|
|
188
|
-
py: 2,
|
|
189
|
-
bg: 'canvas.subtle',
|
|
190
|
-
borderBottom: '1px solid',
|
|
191
|
-
borderColor: 'border.default',
|
|
192
|
-
zIndex: 0,
|
|
193
|
-
}, children: _jsxs(SegmentedControl, { "aria-label": "Metrics view", size: "small", onChange: (idx) => handleViewChange(idx === 0 ? 'chart' : 'table'), children: [_jsx(SegmentedControl.IconButton, { icon: GraphIcon, "aria-label": "Chart", selected: view === 'chart' }), _jsx(SegmentedControl.IconButton, { icon: TableIcon, "aria-label": "Table", selected: view === 'table' })] }) }), _jsx(Box, { sx: { flex: 1, minHeight: 0, overflow: 'auto' }, children: view === 'chart' ? (_jsx(Box, { sx: { px: 3, py: 2 }, children: _jsx(OtelMetricsChart, { metrics: metrics, height: 280 }) })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
|
|
194
|
-
display: 'grid',
|
|
195
|
-
gridTemplateColumns: '20px 1fr auto auto auto auto',
|
|
196
|
-
gap: 3,
|
|
197
|
-
px: 3,
|
|
198
|
-
py: 1,
|
|
199
|
-
bg: 'canvas.subtle',
|
|
200
|
-
borderBottom: '2px solid',
|
|
201
|
-
borderColor: 'border.default',
|
|
202
|
-
position: 'sticky',
|
|
203
|
-
top: 0,
|
|
204
|
-
zIndex: 1,
|
|
205
|
-
}, children: [_jsx(Box, {}), ['Metric Name', 'Latest', 'Average', 'Min/Max', 'Points'].map((h, i) => (_jsx(Text, { sx: {
|
|
136
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "hidden", children: [_jsx(Box, { flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "flex-end", px: 3, py: 2, bg: "canvas.subtle", borderBottom: "1px solid", borderColor: "border.default", zIndex: 0, children: _jsxs(SegmentedControl, { "aria-label": "Metrics view", size: "small", onChange: (idx) => handleViewChange(idx === 0 ? 'chart' : 'table'), children: [_jsx(SegmentedControl.IconButton, { icon: GraphIcon, "aria-label": "Chart", selected: view === 'chart' }), _jsx(SegmentedControl.IconButton, { icon: TableIcon, "aria-label": "Table", selected: view === 'table' })] }) }), _jsx(Box, { flex: 1, minHeight: 0, overflow: "auto", children: view === 'chart' ? (_jsx(Box, { px: 3, py: 2, children: _jsx(OtelMetricsChart, { metrics: metrics, height: 280 }) })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "grid", gridTemplateColumns: "20px 1fr auto auto auto auto", gap: 3, px: 3, py: 1, bg: "canvas.subtle", borderBottom: "2px solid", borderColor: "border.default", position: "sticky", top: 0, zIndex: 1, children: [_jsx(Box, {}), ['Metric Name', 'Latest', 'Average', 'Min/Max', 'Points'].map((h, i) => (_jsx(Text, { sx: {
|
|
206
137
|
fontSize: 0,
|
|
207
138
|
fontWeight: 'bold',
|
|
208
139
|
color: 'fg.muted',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
|
+
import { SegmentedControl, ActionMenu, ActionList, TextInput, Button, } from '@primer/react';
|
|
3
4
|
import { SyncIcon, SearchIcon } from '@primer/octicons-react';
|
|
4
5
|
const SIGNALS = [
|
|
5
6
|
{ value: 'traces', label: 'Traces' },
|
|
@@ -8,15 +9,5 @@ const SIGNALS = [
|
|
|
8
9
|
];
|
|
9
10
|
export const OtelSearchBar = ({ signal, onSignalChange, services, selectedService, onServiceChange, query, onQueryChange, onRefresh, loading, }) => {
|
|
10
11
|
const safeServices = Array.isArray(services) ? services : [];
|
|
11
|
-
return (_jsxs(Box, {
|
|
12
|
-
display: 'flex',
|
|
13
|
-
alignItems: 'center',
|
|
14
|
-
gap: 2,
|
|
15
|
-
px: 3,
|
|
16
|
-
py: 2,
|
|
17
|
-
bg: 'canvas.subtle',
|
|
18
|
-
borderBottom: '1px solid',
|
|
19
|
-
borderColor: 'border.default',
|
|
20
|
-
flexWrap: 'wrap',
|
|
21
|
-
}, children: [_jsx(SegmentedControl, { "aria-label": "Signal type", size: "small", onChange: idx => onSignalChange(SIGNALS[idx].value), children: SIGNALS.map(s => (_jsx(SegmentedControl.Button, { selected: s.value === signal, "aria-label": s.label, children: s.label }, s.value))) }), _jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", variant: "invisible", children: selectedService || 'All services' }), _jsx(ActionMenu.Overlay, { width: "auto", children: _jsxs(ActionList, { selectionVariant: "single", children: [_jsx(ActionList.Item, { selected: selectedService === '', onSelect: () => onServiceChange(''), children: "All services" }), safeServices.length > 0 && _jsx(ActionList.Divider, {}), safeServices.map(svc => (_jsx(ActionList.Item, { selected: selectedService === svc, onSelect: () => onServiceChange(svc), children: svc }, svc)))] }) })] }), _jsx(Box, { sx: { flex: 1, minWidth: 180 }, children: _jsx(TextInput, { leadingVisual: SearchIcon, value: query, onChange: e => onQueryChange(e.target.value), placeholder: "Search spans, logs, metrics\u2026", size: "small", block: true, "aria-label": "Search telemetry" }) }), onRefresh && (_jsx(Button, { size: "small", leadingVisual: SyncIcon, onClick: onRefresh, disabled: loading, "aria-label": "Refresh", children: "Refresh" }))] }));
|
|
12
|
+
return (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: 2, bg: "canvas.subtle", borderBottom: "1px solid", borderColor: "border.default", flexWrap: "wrap", children: [_jsx(SegmentedControl, { "aria-label": "Signal type", size: "small", onChange: idx => onSignalChange(SIGNALS[idx].value), children: SIGNALS.map(s => (_jsx(SegmentedControl.Button, { selected: s.value === signal, "aria-label": s.label, children: s.label }, s.value))) }), _jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", variant: "invisible", children: selectedService || 'All services' }), _jsx(ActionMenu.Overlay, { width: "auto", children: _jsxs(ActionList, { selectionVariant: "single", children: [_jsx(ActionList.Item, { selected: selectedService === '', onSelect: () => onServiceChange(''), children: "All services" }), safeServices.length > 0 && _jsx(ActionList.Divider, {}), safeServices.map(svc => (_jsx(ActionList.Item, { selected: selectedService === svc, onSelect: () => onServiceChange(svc), children: svc }, svc)))] }) })] }), _jsx(Box, { flex: 1, minWidth: 180, children: _jsx(TextInput, { leadingVisual: SearchIcon, value: query, onChange: e => onQueryChange(e.target.value), placeholder: "Search spans, logs, metrics\u2026", size: "small", block: true, "aria-label": "Search telemetry" }) }), onRefresh && (_jsx(Button, { size: "small", leadingVisual: SyncIcon, onClick: onRefresh, disabled: loading, "aria-label": "Refresh", children: "Refresh" }))] }));
|
|
22
13
|
};
|
|
@@ -12,7 +12,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
12
12
|
* @module otel/OtelSpanDetail
|
|
13
13
|
*/
|
|
14
14
|
import { useMemo, useState } from 'react';
|
|
15
|
-
import { Box
|
|
15
|
+
import { Box } from '@datalayer/primer-addons';
|
|
16
|
+
import { Text, IconButton, UnderlineNav, CounterLabel, Label, } from '@primer/react';
|
|
16
17
|
import { XIcon, ChevronDownIcon, ChevronRightIcon, } from '@primer/octicons-react';
|
|
17
18
|
import { formatDuration, buildSpanTree } from '../utils.js';
|
|
18
19
|
import { OtelSpanTree } from './OtelSpanTree.js';
|
|
@@ -21,13 +22,7 @@ import { OtelSpanTree } from './OtelSpanTree.js';
|
|
|
21
22
|
const MetadataRow = ({ label, value, mono = false }) => {
|
|
22
23
|
if (value === undefined || value === null || value === '')
|
|
23
24
|
return null;
|
|
24
|
-
return (_jsxs(Box, { sx: {
|
|
25
|
-
display: 'flex',
|
|
26
|
-
py: 1,
|
|
27
|
-
borderBottom: '1px solid',
|
|
28
|
-
borderColor: 'border.muted',
|
|
29
|
-
gap: 2,
|
|
30
|
-
}, children: [_jsx(Text, { sx: {
|
|
25
|
+
return (_jsxs(Box, { display: "flex", py: 1, borderBottom: "1px solid", borderColor: "border.muted", gap: 2, children: [_jsx(Text, { sx: {
|
|
31
26
|
width: 140,
|
|
32
27
|
minWidth: 140,
|
|
33
28
|
color: 'fg.muted',
|
|
@@ -44,22 +39,7 @@ const CollapsibleSection = ({ title, data, defaultOpen = false }) => {
|
|
|
44
39
|
const [open, setOpen] = useState(defaultOpen);
|
|
45
40
|
if (!data || Object.keys(data).length === 0)
|
|
46
41
|
return null;
|
|
47
|
-
return (_jsxs(Box, { sx: {
|
|
48
|
-
display: 'flex',
|
|
49
|
-
alignItems: 'center',
|
|
50
|
-
gap: 1,
|
|
51
|
-
cursor: 'pointer',
|
|
52
|
-
py: 1,
|
|
53
|
-
userSelect: 'none',
|
|
54
|
-
}, onClick: () => setOpen(!open), children: [open ? _jsx(ChevronDownIcon, { size: 16 }) : _jsx(ChevronRightIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: title }), _jsx(CounterLabel, { children: Object.keys(data).length })] }), open && (_jsx(Box, { sx: {
|
|
55
|
-
bg: 'canvas.subtle',
|
|
56
|
-
borderRadius: 2,
|
|
57
|
-
border: '1px solid',
|
|
58
|
-
borderColor: 'border.default',
|
|
59
|
-
p: 2,
|
|
60
|
-
mt: 1,
|
|
61
|
-
overflowX: 'auto',
|
|
62
|
-
}, children: Object.entries(data).map(([key, val]) => (_jsx(AttributeRow, { attrKey: key, value: val, depth: 0 }, key))) }))] }));
|
|
42
|
+
return (_jsxs(Box, { mt: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, cursor: "pointer", py: 1, userSelect: "none", onClick: () => setOpen(!open), children: [open ? _jsx(ChevronDownIcon, { size: 16 }) : _jsx(ChevronRightIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: title }), _jsx(CounterLabel, { children: Object.keys(data).length })] }), open && (_jsx(Box, { bg: "canvas.subtle", borderRadius: 2, border: "1px solid", borderColor: "border.default", p: 2, mt: 1, overflowX: "auto", children: Object.entries(data).map(([key, val]) => (_jsx(AttributeRow, { attrKey: key, value: val, depth: 0 }, key))) }))] }));
|
|
63
43
|
};
|
|
64
44
|
/**
|
|
65
45
|
* A value as the detail unfolds it: JSON text of an object or an array (the
|
|
@@ -87,24 +67,7 @@ const AttributeRow = ({ attrKey, value: given, depth }) => {
|
|
|
87
67
|
const isObject = typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
88
68
|
const isArray = Array.isArray(value);
|
|
89
69
|
const isNested = isObject || isArray;
|
|
90
|
-
return (_jsxs(Box, { sx: {
|
|
91
|
-
borderBottom: depth === 0 ? '1px solid' : 'none',
|
|
92
|
-
borderColor: 'border.muted',
|
|
93
|
-
pb: depth === 0 ? 1 : 0,
|
|
94
|
-
mb: depth === 0 ? 1 : 0,
|
|
95
|
-
}, children: [_jsxs(Box, { sx: {
|
|
96
|
-
display: 'flex',
|
|
97
|
-
gap: 2,
|
|
98
|
-
py: 1,
|
|
99
|
-
pl: depth * 16 + 'px',
|
|
100
|
-
alignItems: 'flex-start',
|
|
101
|
-
}, children: [isNested ? (_jsx(Box, { sx: {
|
|
102
|
-
cursor: 'pointer',
|
|
103
|
-
color: 'fg.muted',
|
|
104
|
-
userSelect: 'none',
|
|
105
|
-
width: 16,
|
|
106
|
-
flexShrink: 0,
|
|
107
|
-
}, onClick: () => setOpen(!open), children: open ? (_jsx(ChevronDownIcon, { size: 12 })) : (_jsx(ChevronRightIcon, { size: 12 })) })) : (_jsx(Box, { sx: { width: 16, flexShrink: 0 } })), _jsx(Text, { sx: {
|
|
70
|
+
return (_jsxs(Box, { borderBottom: depth === 0 ? '1px solid' : 'none', borderColor: "border.muted", pb: depth === 0 ? 1 : 0, mb: depth === 0 ? 1 : 0, children: [_jsxs(Box, { display: "flex", gap: 2, py: 1, pl: depth * 16 + 'px', alignItems: "flex-start", children: [isNested ? (_jsx(Box, { cursor: "pointer", color: "fg.muted", userSelect: "none", width: 16, flexShrink: 0, onClick: () => setOpen(!open), children: open ? (_jsx(ChevronDownIcon, { size: 12 })) : (_jsx(ChevronRightIcon, { size: 12 })) })) : (_jsx(Box, { width: 16, flexShrink: 0 })), _jsx(Text, { sx: {
|
|
108
71
|
color: 'accent.fg',
|
|
109
72
|
fontSize: 1,
|
|
110
73
|
fontFamily: 'mono',
|
|
@@ -127,7 +90,7 @@ const AttributeRow = ({ attrKey, value: given, depth }) => {
|
|
|
127
90
|
export const OtelSpanDetail = ({ span, traceSpans, onClose, }) => {
|
|
128
91
|
const [activeTab, setActiveTab] = useState('details');
|
|
129
92
|
if (!span) {
|
|
130
|
-
return (_jsx(Box, {
|
|
93
|
+
return (_jsx(Box, { p: 5, color: "fg.muted", textAlign: "center", children: _jsx(Text, { children: "Select a span to view details." }) }));
|
|
131
94
|
}
|
|
132
95
|
// Separate gen_ai attributes from other attributes
|
|
133
96
|
const genAiAttrs = {};
|
|
@@ -144,49 +107,16 @@ export const OtelSpanDetail = ({ span, traceSpans, onClose, }) => {
|
|
|
144
107
|
}
|
|
145
108
|
// Build tree from traceSpans for tree tab
|
|
146
109
|
const tree = traceSpans && traceSpans.length > 0 ? buildSpanTree(traceSpans) : undefined;
|
|
147
|
-
return (_jsxs(Box, { sx: {
|
|
148
|
-
height: '100%',
|
|
149
|
-
overflow: 'auto',
|
|
150
|
-
borderLeft: '1px solid',
|
|
151
|
-
borderColor: 'border.default',
|
|
152
|
-
bg: 'canvas.default',
|
|
153
|
-
display: 'flex',
|
|
154
|
-
flexDirection: 'column',
|
|
155
|
-
}, children: [_jsxs(Box, { sx: {
|
|
156
|
-
px: 3,
|
|
157
|
-
py: 2,
|
|
158
|
-
borderBottom: '1px solid',
|
|
159
|
-
borderColor: 'border.default',
|
|
160
|
-
display: 'flex',
|
|
161
|
-
justifyContent: 'space-between',
|
|
162
|
-
alignItems: 'center',
|
|
163
|
-
bg: 'canvas.subtle',
|
|
164
|
-
flexShrink: 0,
|
|
165
|
-
}, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: span.span_name }), onClose && (_jsx(IconButton, { icon: XIcon, "aria-label": "Close detail panel", variant: "invisible", size: "small", onClick: onClose }))] }), _jsxs(UnderlineNav, { "aria-label": "Span detail tabs", children: [_jsx(UnderlineNav.Item, { "aria-current": activeTab === 'details' ? 'page' : undefined, onClick: () => setActiveTab('details'), children: "Details" }), tree && (_jsx(UnderlineNav.Item, { "aria-current": activeTab === 'tree' ? 'page' : undefined, onClick: () => setActiveTab('tree'), children: "Trace Tree" })), _jsx(UnderlineNav.Item, { "aria-current": activeTab === 'raw' ? 'page' : undefined, onClick: () => setActiveTab('raw'), children: "Raw Data" })] }), _jsxs(Box, { sx: { flex: 1, overflow: 'auto' }, children: [activeTab === 'details' && (_jsxs(Box, { sx: { p: 3 }, children: [_jsx(MetadataRow, { label: "span_name", value: span.span_name }), _jsx(MetadataRow, { label: "service_name", value: span.service_name }), _jsx(MetadataRow, { label: "otel_scope_name", value: span.otel_scope_name }), _jsx(MetadataRow, { label: "kind", value: span.kind }), _jsx(MetadataRow, { label: "trace_id", value: span.trace_id, mono: true }), _jsx(MetadataRow, { label: "span_id", value: span.span_id, mono: true }), _jsx(MetadataRow, { label: "parent_span_id", value: span.parent_span_id, mono: true }), _jsx(MetadataRow, { label: "duration", value: formatDuration(span.duration_ms) }), _jsx(MetadataRow, { label: "start_time", value: span.start_time, mono: true }), _jsx(MetadataRow, { label: "end_time", value: span.end_time, mono: true }), _jsx(MetadataRow, { label: "status_code", value: span.status_code }), _jsx(MetadataRow, { label: "status_message", value: span.status_message }), _jsx(CollapsibleSection, { title: "Arguments", data: genAiAttrs, defaultOpen: Object.keys(genAiAttrs).length > 0 }), _jsx(CollapsibleSection, { title: "Attributes", data: otherAttrs }), span.events && span.events.length > 0 && (_jsxs(Box, { sx: { mt: 3 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: "Events" }), _jsx(CounterLabel, { children: span.events.length })] }), span.events.map((ev, idx) => (_jsxs(Box, { sx: {
|
|
166
|
-
bg: 'canvas.subtle',
|
|
167
|
-
borderRadius: 2,
|
|
168
|
-
border: '1px solid',
|
|
169
|
-
borderColor: 'border.default',
|
|
170
|
-
p: 2,
|
|
171
|
-
mt: 2,
|
|
172
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', gap: 2 }, children: [_jsx(Label, { children: ev.name }), _jsx(Text, { sx: {
|
|
110
|
+
return (_jsxs(Box, { height: "100%", overflow: "auto", borderLeft: "1px solid", borderColor: "border.default", bg: "canvas.default", display: "flex", flexDirection: "column", children: [_jsxs(Box, { px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.default", display: "flex", justifyContent: "space-between", alignItems: "center", bg: "canvas.subtle", flexShrink: 0, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: span.span_name }), onClose && (_jsx(IconButton, { icon: XIcon, "aria-label": "Close detail panel", variant: "invisible", size: "small", onClick: onClose }))] }), _jsxs(UnderlineNav, { "aria-label": "Span detail tabs", children: [_jsx(UnderlineNav.Item, { "aria-current": activeTab === 'details' ? 'page' : undefined, onClick: () => setActiveTab('details'), children: "Details" }), tree && (_jsx(UnderlineNav.Item, { "aria-current": activeTab === 'tree' ? 'page' : undefined, onClick: () => setActiveTab('tree'), children: "Trace Tree" })), _jsx(UnderlineNav.Item, { "aria-current": activeTab === 'raw' ? 'page' : undefined, onClick: () => setActiveTab('raw'), children: "Raw Data" })] }), _jsxs(Box, { flex: 1, overflow: "auto", children: [activeTab === 'details' && (_jsxs(Box, { p: 3, children: [_jsx(MetadataRow, { label: "span_name", value: span.span_name }), _jsx(MetadataRow, { label: "service_name", value: span.service_name }), _jsx(MetadataRow, { label: "otel_scope_name", value: span.otel_scope_name }), _jsx(MetadataRow, { label: "kind", value: span.kind }), _jsx(MetadataRow, { label: "trace_id", value: span.trace_id, mono: true }), _jsx(MetadataRow, { label: "span_id", value: span.span_id, mono: true }), _jsx(MetadataRow, { label: "parent_span_id", value: span.parent_span_id, mono: true }), _jsx(MetadataRow, { label: "duration", value: formatDuration(span.duration_ms) }), _jsx(MetadataRow, { label: "start_time", value: span.start_time, mono: true }), _jsx(MetadataRow, { label: "end_time", value: span.end_time, mono: true }), _jsx(MetadataRow, { label: "status_code", value: span.status_code }), _jsx(MetadataRow, { label: "status_message", value: span.status_message }), _jsx(CollapsibleSection, { title: "Arguments", data: genAiAttrs, defaultOpen: Object.keys(genAiAttrs).length > 0 }), _jsx(CollapsibleSection, { title: "Attributes", data: otherAttrs }), span.events && span.events.length > 0 && (_jsxs(Box, { mt: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: "Events" }), _jsx(CounterLabel, { children: span.events.length })] }), span.events.map((ev, idx) => (_jsxs(Box, { bg: "canvas.subtle", borderRadius: 2, border: "1px solid", borderColor: "border.default", p: 2, mt: 2, children: [_jsxs(Box, { display: "flex", gap: 2, children: [_jsx(Label, { children: ev.name }), _jsx(Text, { sx: {
|
|
173
111
|
fontSize: 0,
|
|
174
112
|
color: 'fg.muted',
|
|
175
113
|
fontFamily: 'mono',
|
|
176
|
-
}, children: ev.timestamp })] }), ev.attributes && Object.keys(ev.attributes).length > 0 && (_jsx(Box, {
|
|
114
|
+
}, children: ev.timestamp })] }), ev.attributes && Object.keys(ev.attributes).length > 0 && (_jsx(Box, { mt: 1, children: Object.entries(ev.attributes).map(([k, v]) => (_jsx(AttributeRow, { attrKey: k, value: v, depth: 0 }, k))) }))] }, idx)))] })), span.links && span.links.length > 0 && (_jsxs(Box, { mt: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: "Links" }), _jsx(CounterLabel, { children: span.links.length })] }), span.links.map((link, idx) => (_jsxs(Text, { sx: {
|
|
177
115
|
display: 'block',
|
|
178
116
|
fontSize: 1,
|
|
179
117
|
fontFamily: 'mono',
|
|
180
118
|
py: 1,
|
|
181
119
|
borderBottom: '1px solid',
|
|
182
120
|
borderColor: 'border.muted',
|
|
183
|
-
}, children: ["trace: ", link.trace_id, " \u2192 span: ", link.span_id] }, idx)))] }))] })), activeTab === 'tree' && tree && (_jsx(OtelSpanTree, { spans: tree, selectedSpanId: span.span_id, defaultExpandDepth: 4 })), activeTab === 'raw' && (_jsx(Box, { as: "pre",
|
|
184
|
-
p: 3,
|
|
185
|
-
fontSize: 0,
|
|
186
|
-
fontFamily: 'mono',
|
|
187
|
-
whiteSpace: 'pre-wrap',
|
|
188
|
-
wordBreak: 'break-word',
|
|
189
|
-
m: 0,
|
|
190
|
-
bg: 'canvas.subtle',
|
|
191
|
-
}, children: JSON.stringify(span, null, 2) }))] })] }));
|
|
121
|
+
}, children: ["trace: ", link.trace_id, " \u2192 span: ", link.span_id] }, idx)))] }))] })), activeTab === 'tree' && tree && (_jsx(OtelSpanTree, { spans: tree, selectedSpanId: span.span_id, defaultExpandDepth: 4 })), activeTab === 'raw' && (_jsx(Box, { as: "pre", p: 3, fontSize: 0, fontFamily: "mono", whiteSpace: "pre-wrap", wordBreak: "break-word", m: 0, bg: "canvas.subtle", children: JSON.stringify(span, null, 2) }))] })] }));
|
|
192
122
|
};
|
|
@@ -12,7 +12,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
* @module otel/OtelSpanTree
|
|
13
13
|
*/
|
|
14
14
|
import { useState, useMemo, useCallback } from 'react';
|
|
15
|
-
import { Box
|
|
15
|
+
import { Box } from '@datalayer/primer-addons';
|
|
16
|
+
import { Text } from '@primer/react';
|
|
16
17
|
import { ChevronDownIcon, ChevronRightIcon } from '@primer/octicons-react';
|
|
17
18
|
import { formatDuration, serviceColor, toMs } from '../utils.js';
|
|
18
19
|
const INDENT_PX = 20;
|
|
@@ -23,61 +24,18 @@ const SpanNode = ({ span, depth, selectedSpanId, onSelectSpan, expandedIds, togg
|
|
|
23
24
|
const color = serviceColor(span.service_name);
|
|
24
25
|
const startPct = ((toMs(span.start_time) - traceMinTime) / traceDuration) * 100;
|
|
25
26
|
const widthPct = Math.max(((span.duration_ms || 0) / traceDuration) * 100, 0.5);
|
|
26
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Box, {
|
|
27
|
-
display: 'flex',
|
|
28
|
-
alignItems: 'center',
|
|
29
|
-
height: 28,
|
|
30
|
-
pl: `${depth * INDENT_PX}px`,
|
|
31
|
-
pr: 2,
|
|
32
|
-
cursor: 'pointer',
|
|
33
|
-
bg: isSelected ? 'accent.subtle' : 'canvas.default',
|
|
34
|
-
borderBottom: '1px solid',
|
|
35
|
-
borderColor: 'border.muted',
|
|
36
|
-
':hover': {
|
|
37
|
-
bg: isSelected ? 'accent.subtle' : 'canvas.subtle',
|
|
38
|
-
},
|
|
39
|
-
}, onClick: () => onSelectSpan?.(span), children: [_jsx(Box, { sx: {
|
|
40
|
-
width: 20,
|
|
41
|
-
textAlign: 'center',
|
|
42
|
-
color: 'fg.muted',
|
|
43
|
-
userSelect: 'none',
|
|
44
|
-
flexShrink: 0,
|
|
45
|
-
cursor: hasChildren ? 'pointer' : 'default',
|
|
46
|
-
}, onClick: e => {
|
|
27
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "flex", alignItems: "center", height: 28, pl: `${depth * INDENT_PX}px`, pr: 2, cursor: "pointer", bg: isSelected ? 'accent.subtle' : 'canvas.default', borderBottom: "1px solid", borderColor: "border.muted", hover: { bg: isSelected ? 'accent.subtle' : 'canvas.subtle' }, onClick: () => onSelectSpan?.(span), children: [_jsx(Box, { width: 20, textAlign: "center", color: "fg.muted", userSelect: "none", flexShrink: 0, cursor: hasChildren ? 'pointer' : 'default', onClick: e => {
|
|
47
28
|
e.stopPropagation();
|
|
48
29
|
if (hasChildren)
|
|
49
30
|
toggleExpanded(span.span_id);
|
|
50
|
-
}, children: hasChildren ? (isExpanded ? (_jsx(ChevronDownIcon, { size: 12 })) : (_jsx(ChevronRightIcon, { size: 12 }))) : (_jsx(Text, { sx: { color: 'fg.subtle', fontSize: 0 }, children: "\u00B7" })) }), _jsx(Box, { sx: {
|
|
51
|
-
width: 8,
|
|
52
|
-
height: 8,
|
|
53
|
-
borderRadius: '50%',
|
|
54
|
-
bg: color,
|
|
55
|
-
flexShrink: 0,
|
|
56
|
-
mr: 1,
|
|
57
|
-
} }), _jsx(Text, { sx: {
|
|
31
|
+
}, children: hasChildren ? (isExpanded ? (_jsx(ChevronDownIcon, { size: 12 })) : (_jsx(ChevronRightIcon, { size: 12 }))) : (_jsx(Text, { sx: { color: 'fg.subtle', fontSize: 0 }, children: "\u00B7" })) }), _jsx(Box, { width: 8, height: 8, borderRadius: "50%", bg: color, flexShrink: 0, mr: 1 }), _jsx(Text, { sx: {
|
|
58
32
|
flex: '0 0 200px',
|
|
59
33
|
overflow: 'hidden',
|
|
60
34
|
textOverflow: 'ellipsis',
|
|
61
35
|
whiteSpace: 'nowrap',
|
|
62
36
|
fontSize: 1,
|
|
63
37
|
fontWeight: isSelected ? 'bold' : 'normal',
|
|
64
|
-
}, title: `${span.service_name} / ${span.span_name}`, children: span.span_name }), _jsx(Box, { sx: {
|
|
65
|
-
flex: 1,
|
|
66
|
-
position: 'relative',
|
|
67
|
-
height: 12,
|
|
68
|
-
bg: 'canvas.subtle',
|
|
69
|
-
borderRadius: 1,
|
|
70
|
-
mx: 2,
|
|
71
|
-
overflow: 'hidden',
|
|
72
|
-
}, children: _jsx(Box, { sx: {
|
|
73
|
-
position: 'absolute',
|
|
74
|
-
left: `${startPct}%`,
|
|
75
|
-
width: `${widthPct}%`,
|
|
76
|
-
height: '100%',
|
|
77
|
-
bg: color,
|
|
78
|
-
borderRadius: 1,
|
|
79
|
-
opacity: isSelected ? 1 : 0.7,
|
|
80
|
-
} }) }), _jsx(Text, { sx: {
|
|
38
|
+
}, title: `${span.service_name} / ${span.span_name}`, children: span.span_name }), _jsx(Box, { flex: 1, position: "relative", height: 12, bg: "canvas.subtle", borderRadius: 1, mx: 2, overflow: "hidden", children: _jsx(Box, { position: "absolute", left: `${startPct}%`, width: `${widthPct}%`, height: "100%", bg: color, borderRadius: 1, opacity: isSelected ? 1 : 0.7 }) }), _jsx(Text, { sx: {
|
|
81
39
|
minWidth: 60,
|
|
82
40
|
textAlign: 'right',
|
|
83
41
|
fontSize: 0,
|
|
@@ -139,17 +97,9 @@ export const OtelSpanTree = ({ spans, selectedSpanId, onSelectSpan, defaultExpan
|
|
|
139
97
|
return { traceMinTime: min, traceDuration: max - min || 1 };
|
|
140
98
|
}, [spans]);
|
|
141
99
|
if (spans.length === 0) {
|
|
142
|
-
return (_jsx(Box, {
|
|
100
|
+
return (_jsx(Box, { p: 3, color: "fg.muted", textAlign: "center", children: _jsx(Text, { children: "No span tree to display." }) }));
|
|
143
101
|
}
|
|
144
|
-
return (_jsxs(Box, {
|
|
145
|
-
display: 'flex',
|
|
146
|
-
alignItems: 'center',
|
|
147
|
-
height: 28,
|
|
148
|
-
px: 2,
|
|
149
|
-
borderBottom: '2px solid',
|
|
150
|
-
borderColor: 'border.default',
|
|
151
|
-
bg: 'canvas.subtle',
|
|
152
|
-
}, children: [_jsx(Box, { sx: { width: 20 } }), _jsx(Box, { sx: { width: 8, mr: 1 } }), _jsx(Text, { sx: {
|
|
102
|
+
return (_jsxs(Box, { width: "100%", overflow: "auto", children: [_jsxs(Box, { display: "flex", alignItems: "center", height: 28, px: 2, borderBottom: "2px solid", borderColor: "border.default", bg: "canvas.subtle", children: [_jsx(Box, { width: 20 }), _jsx(Box, { width: 8, mr: 1 }), _jsx(Text, { sx: {
|
|
153
103
|
flex: '0 0 200px',
|
|
154
104
|
fontSize: 0,
|
|
155
105
|
fontWeight: 'bold',
|