@datalayer/core 1.2.17 → 1.2.19
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.js +3 -27
- package/lib/components/billing/BillingEntitySelect.js +6 -48
- package/lib/components/checkout/StripeCheckout.js +33 -217
- 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/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.js +19 -63
- package/lib/components/principal/PrincipalAvatar.js +5 -25
- package/lib/components/principal/PrincipalBadge.js +3 -13
- package/lib/components/principal/PrincipalBanner.js +4 -32
- package/lib/components/principal/PrincipalDetailsOverlay.js +7 -23
- 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/useAuthorization.js +6 -1
- 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/Person.d.ts +9 -0
- package/lib/models/Person.js +23 -0
- package/lib/otel/index.d.ts +4 -0
- package/lib/otel/index.js +3 -0
- package/lib/otel/live/filter.d.ts +15 -0
- package/lib/otel/live/filter.js +16 -0
- package/lib/otel/live/index.d.ts +10 -0
- package/lib/otel/live/index.js +14 -0
- package/lib/otel/live/tracer.d.ts +94 -0
- package/lib/otel/live/tracer.js +223 -0
- package/lib/otel/live/useOtelLiveSpans.d.ts +6 -0
- package/lib/otel/live/useOtelLiveSpans.js +22 -0
- package/lib/otel/types.d.ts +17 -0
- package/lib/otel/views/OtelLive.js +4 -62
- package/lib/otel/views/OtelLiveSpans.d.ts +52 -0
- package/lib/otel/views/OtelLiveSpans.js +114 -0
- 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.d.ts +6 -0
- package/lib/otel/views/OtelSpanDetail.js +31 -81
- 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 +39 -87
- package/lib/otel/views/index.d.ts +3 -0
- package/lib/otel/views/index.js +2 -0
- package/lib/portable/index.d.ts +8 -0
- package/lib/portable/index.js +12 -0
- package/lib/state/substates/NavigationState.d.ts +6 -4
- package/lib/state/substates/NavigationState.js +6 -5
- 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 +2 -10
- package/lib/views/mcp/AlertRules.js +4 -9
- package/lib/views/mcp/ApprovalQueue.js +4 -21
- package/lib/views/mcp/AuditLog.js +7 -44
- package/lib/views/mcp/ConnectedAgents.js +1 -6
- package/lib/views/mcp/EnterpriseConsole.js +10 -23
- package/lib/views/mcp/IdentityProviders.js +7 -31
- package/lib/views/mcp/McpDashboard.js +14 -30
- package/lib/views/mcp/McpHome.js +7 -54
- package/lib/views/mcp/McpObservability.js +13 -85
- package/lib/views/mcp/NotebookRuns.js +5 -12
- package/lib/views/mcp/OrganizationPolicy.js +3 -9
- package/lib/views/mcp/OrganizationUsage.js +4 -11
- package/lib/views/mcp/PersonalPolicy.js +3 -3
- package/lib/views/mcp/Policies.js +5 -46
- package/lib/views/mcp/PolicyForm.js +1 -9
- package/lib/views/mcp/PolicyHistory.js +2 -8
- package/lib/views/mcp/RunDetail.js +3 -25
- package/lib/views/mcp/ScimProvisioning.js +3 -15
- package/lib/views/mcp/ServiceAgents.js +4 -17
- package/lib/views/mcp/TeamPolicies.js +7 -19
- package/lib/views/mcp/ToolAccess.js +15 -22
- 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
|
@@ -14,7 +14,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
* Available tables: `spans`, `metrics`, `logs`.
|
|
15
15
|
*/
|
|
16
16
|
import { useState, useCallback } from 'react';
|
|
17
|
-
import {
|
|
17
|
+
import { Box } from '@datalayer/primer-addons';
|
|
18
|
+
import { ActionList, ActionMenu, Button, Text, Textarea, Spinner, } from '@primer/react';
|
|
18
19
|
import { HistoryIcon, TableIcon, XCircleIcon, DownloadIcon, } from '@primer/octicons-react';
|
|
19
20
|
import { useOtelQuery } from '../hooks/index.js';
|
|
20
21
|
// ── Cookie helpers ────────────────────────────────────────────────
|
|
@@ -104,38 +105,7 @@ export const OtelSqlView = ({ token, baseUrl = '', }) => {
|
|
|
104
105
|
}
|
|
105
106
|
};
|
|
106
107
|
const columns = rows.length > 0 ? Object.keys(rows[0]) : [];
|
|
107
|
-
return (_jsxs(Box, { sx: {
|
|
108
|
-
display: 'flex',
|
|
109
|
-
flexDirection: 'column',
|
|
110
|
-
flex: 1,
|
|
111
|
-
minHeight: 0,
|
|
112
|
-
height: '100%',
|
|
113
|
-
gap: 3,
|
|
114
|
-
p: 4,
|
|
115
|
-
bg: 'canvas.default',
|
|
116
|
-
color: 'fg.default',
|
|
117
|
-
overflow: 'auto',
|
|
118
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, flexWrap: 'wrap' }, children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", children: "Preset queries" }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { children: PRESET_GROUPS.map(group => (_jsx(ActionList.Group, { title: group, children: PRESETS.filter(p => p.group === group).map(p => (_jsx(ActionList.Item, { onSelect: () => setSql(p.sql), children: p.label }, p.label))) }, group))) }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["\u2318 Enter to run \u00B7 Tables:", ' ', _jsx(Box, { as: "code", sx: { fontFamily: 'mono', fontSize: 0 }, children: "spans" }), ', ', _jsx(Box, { as: "code", sx: { fontFamily: 'mono', fontSize: 0 }, children: "metrics" }), ', ', _jsx(Box, { as: "code", sx: { fontFamily: 'mono', fontSize: 0 }, children: "logs" })] })] }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(Textarea, { "aria-label": "SQL query", value: sql, onChange: e => setSql(e.target.value), onKeyDown: handleKeyDown, placeholder: "SELECT \u2026 FROM spans LIMIT 20", rows: 5, resize: "vertical", sx: { fontFamily: 'mono', fontSize: 1, width: '100%' } }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Button, { variant: "primary", onClick: handleRun, disabled: loading, size: "small", children: loading ? 'Running…' : 'Run' }), loading && _jsx(Spinner, { size: "small" })] })] }), error && (_jsx(Box, { sx: {
|
|
119
|
-
p: 3,
|
|
120
|
-
bg: 'danger.subtle',
|
|
121
|
-
borderRadius: 2,
|
|
122
|
-
border: '1px solid',
|
|
123
|
-
borderColor: 'danger.muted',
|
|
124
|
-
}, children: _jsx(Text, { sx: { color: 'danger.fg', fontFamily: 'mono', fontSize: 1 }, children: error }) })), !error && rows.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(TableIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.default' }, children: "Results" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', ml: 1 }, children: ["(", rows.length, " row", rows.length !== 1 ? 's' : '', ")"] }), _jsxs(Box, { as: "button", onClick: clear, title: "Clear results", sx: {
|
|
125
|
-
ml: 'auto',
|
|
126
|
-
display: 'flex',
|
|
127
|
-
alignItems: 'center',
|
|
128
|
-
gap: 1,
|
|
129
|
-
px: 2,
|
|
130
|
-
py: '2px',
|
|
131
|
-
border: 'none',
|
|
132
|
-
borderRadius: 2,
|
|
133
|
-
bg: 'transparent',
|
|
134
|
-
color: 'fg.muted',
|
|
135
|
-
cursor: 'pointer',
|
|
136
|
-
fontSize: 0,
|
|
137
|
-
'&:hover': { color: 'danger.fg', bg: 'danger.subtle' },
|
|
138
|
-
}, children: [_jsx(XCircleIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "Clear" })] }), _jsxs(Box, { as: "button", onClick: () => {
|
|
108
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, height: "100%", gap: 3, p: 4, bg: "canvas.default", color: "fg.default", overflow: "auto", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", children: "Preset queries" }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { children: PRESET_GROUPS.map(group => (_jsx(ActionList.Group, { title: group, children: PRESETS.filter(p => p.group === group).map(p => (_jsx(ActionList.Item, { onSelect: () => setSql(p.sql), children: p.label }, p.label))) }, group))) }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["\u2318 Enter to run \u00B7 Tables:", ' ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "spans" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "metrics" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "logs" })] })] }), _jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsx(Textarea, { "aria-label": "SQL query", value: sql, onChange: e => setSql(e.target.value), onKeyDown: handleKeyDown, placeholder: "SELECT \u2026 FROM spans LIMIT 20", rows: 5, resize: "vertical", sx: { fontFamily: 'mono', fontSize: 1, width: '100%' } }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Button, { variant: "primary", onClick: handleRun, disabled: loading, size: "small", children: loading ? 'Running…' : 'Run' }), loading && _jsx(Spinner, { size: "small" })] })] }), error && (_jsx(Box, { p: 3, bg: "danger.subtle", borderRadius: 2, border: "1px solid", borderColor: "danger.muted", children: _jsx(Text, { sx: { color: 'danger.fg', fontFamily: 'mono', fontSize: 1 }, children: error }) })), !error && rows.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(TableIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.default' }, children: "Results" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', ml: 1 }, children: ["(", rows.length, " row", rows.length !== 1 ? 's' : '', ")"] }), _jsxs(Box, { as: "button", onClick: clear, title: "Clear results", ml: "auto", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'danger.fg', bg: 'danger.subtle' }, children: [_jsx(XCircleIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "Clear" })] }), _jsxs(Box, { as: "button", onClick: () => {
|
|
139
109
|
const header = columns.join(',');
|
|
140
110
|
const body = rows
|
|
141
111
|
.map(row => columns
|
|
@@ -158,76 +128,12 @@ export const OtelSqlView = ({ token, baseUrl = '', }) => {
|
|
|
158
128
|
a.download = 'otel-query-result.csv';
|
|
159
129
|
a.click();
|
|
160
130
|
URL.revokeObjectURL(url);
|
|
161
|
-
}, title: "Download as CSV", sx: {
|
|
162
|
-
display: 'flex',
|
|
163
|
-
alignItems: 'center',
|
|
164
|
-
gap: 1,
|
|
165
|
-
px: 2,
|
|
166
|
-
py: '2px',
|
|
167
|
-
border: 'none',
|
|
168
|
-
borderRadius: 2,
|
|
169
|
-
bg: 'transparent',
|
|
170
|
-
color: 'fg.muted',
|
|
171
|
-
cursor: 'pointer',
|
|
172
|
-
fontSize: 0,
|
|
173
|
-
'&:hover': { color: 'accent.fg', bg: 'accent.subtle' },
|
|
174
|
-
}, children: [_jsx(DownloadIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "CSV" })] })] }), _jsx(Box, { sx: {
|
|
175
|
-
flex: 1,
|
|
176
|
-
minHeight: 200,
|
|
177
|
-
overflow: 'auto',
|
|
178
|
-
border: '1px solid',
|
|
179
|
-
borderColor: 'border.default',
|
|
180
|
-
borderRadius: 2,
|
|
181
|
-
}, children: _jsxs(Box, { as: "table", sx: { width: '100%', borderCollapse: 'collapse' }, children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", sx: { bg: 'canvas.subtle' }, children: columns.map(col => (_jsx(Box, { as: "th", sx: {
|
|
182
|
-
px: 3,
|
|
183
|
-
py: 2,
|
|
184
|
-
textAlign: 'left',
|
|
185
|
-
fontWeight: 'bold',
|
|
186
|
-
fontSize: 0,
|
|
187
|
-
color: 'fg.muted',
|
|
188
|
-
borderBottom: '1px solid',
|
|
189
|
-
borderColor: 'border.default',
|
|
190
|
-
whiteSpace: 'nowrap',
|
|
191
|
-
}, children: col }, col))) }) }), _jsx(Box, { as: "tbody", children: rows.map((row, ri) => (_jsx(Box, { as: "tr", sx: {
|
|
192
|
-
'&:hover': { bg: 'canvas.subtle' },
|
|
131
|
+
}, title: "Download as CSV", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'accent.fg', bg: 'accent.subtle' }, children: [_jsx(DownloadIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "CSV" })] })] }), _jsx(Box, { flex: 1, minHeight: 200, overflow: "auto", border: "1px solid", borderColor: "border.default", borderRadius: 2, children: _jsxs(Box, { as: "table", width: "100%", borderCollapse: "collapse", children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", bg: "canvas.subtle", children: columns.map(col => (_jsx(Box, { as: "th", px: 3, py: 2, textAlign: "left", fontWeight: "bold", fontSize: 0, color: "fg.muted", borderBottom: "1px solid", borderColor: "border.default", whiteSpace: "nowrap", children: col }, col))) }) }), _jsx(Box, { as: "tbody", children: rows.map((row, ri) => (_jsx(Box, { as: "tr", hover: { bg: 'canvas.subtle' }, sx: {
|
|
193
132
|
'&:not(:last-child) td': {
|
|
194
133
|
borderBottom: '1px solid',
|
|
195
134
|
borderColor: 'border.muted',
|
|
196
135
|
},
|
|
197
|
-
}, children: columns.map(col => (_jsx(Box, { as: "td", sx: {
|
|
198
|
-
px: 3,
|
|
199
|
-
py: 2,
|
|
200
|
-
fontSize: 0,
|
|
201
|
-
fontFamily: 'mono',
|
|
202
|
-
maxWidth: '300px',
|
|
203
|
-
overflow: 'hidden',
|
|
204
|
-
textOverflow: 'ellipsis',
|
|
205
|
-
whiteSpace: 'nowrap',
|
|
206
|
-
}, children: String(row[col] ?? '') }, col))) }, ri))) })] }) })] })), !error && !loading && rows.length === 0 && (_jsx(Box, { sx: {
|
|
207
|
-
flex: 1,
|
|
208
|
-
display: 'flex',
|
|
209
|
-
alignItems: 'center',
|
|
210
|
-
justifyContent: 'center',
|
|
211
|
-
color: 'fg.muted',
|
|
212
|
-
}, children: _jsx(Text, { sx: { fontSize: 1 }, children: "Run a query to see results." }) })), history.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(HistoryIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "History" })] }), _jsx(Box, { sx: {
|
|
213
|
-
display: 'flex',
|
|
214
|
-
flexDirection: 'column',
|
|
215
|
-
border: '1px solid',
|
|
216
|
-
borderColor: 'border.default',
|
|
217
|
-
borderRadius: 2,
|
|
218
|
-
overflow: 'hidden',
|
|
219
|
-
}, children: history.map((entry, i) => (_jsxs(Box, { sx: {
|
|
220
|
-
display: 'flex',
|
|
221
|
-
alignItems: 'center',
|
|
222
|
-
gap: 2,
|
|
223
|
-
px: 3,
|
|
224
|
-
py: '6px',
|
|
225
|
-
cursor: 'pointer',
|
|
226
|
-
bg: i % 2 === 0 ? 'canvas.default' : 'canvas.subtle',
|
|
227
|
-
borderTop: i > 0 ? '1px solid' : 'none',
|
|
228
|
-
borderColor: 'border.muted',
|
|
229
|
-
'&:hover': { bg: 'accent.subtle' },
|
|
230
|
-
}, onClick: () => setSql(entry), children: [_jsx(Text, { sx: {
|
|
136
|
+
}, children: columns.map(col => (_jsx(Box, { as: "td", px: 3, py: 2, fontSize: 0, fontFamily: "mono", maxWidth: "300px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: String(row[col] ?? '') }, col))) }, ri))) })] }) })] })), !error && !loading && rows.length === 0 && (_jsx(Box, { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", children: _jsx(Text, { sx: { fontSize: 1 }, children: "Run a query to see results." }) })), history.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(HistoryIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "History" })] }), _jsx(Box, { display: "flex", flexDirection: "column", border: "1px solid", borderColor: "border.default", borderRadius: 2, overflow: "hidden", children: history.map((entry, i) => (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: "6px", cursor: "pointer", bg: i % 2 === 0 ? 'canvas.default' : 'canvas.subtle', borderTop: i > 0 ? '1px solid' : 'none', borderColor: "border.muted", hover: { bg: 'accent.subtle' }, onClick: () => setSql(entry), children: [_jsx(Text, { sx: {
|
|
231
137
|
fontFamily: 'mono',
|
|
232
138
|
fontSize: 0,
|
|
233
139
|
color: 'fg.default',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Box
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
|
+
import { Button, Spinner, Text } from '@primer/react';
|
|
3
4
|
import { SyncIcon } from '@primer/octicons-react';
|
|
4
5
|
import { useOtelSystem } from '../hooks/index.js';
|
|
5
6
|
// ── Helpers ───────────────────────────────────────────────────────
|
|
@@ -36,40 +37,9 @@ const GRID_SX = {
|
|
|
36
37
|
const StatCell = ({ label, value }) => (_jsxs(Box, { children: [_jsx(Text, { sx: LABEL_SX, children: label }), _jsx(Text, { sx: { fontSize: 1, fontFamily: 'mono' }, children: value })] }));
|
|
37
38
|
const SystemViewContent = ({ data }) => {
|
|
38
39
|
const { process: proc, disk, tables, total_distinct_users } = data;
|
|
39
|
-
return (_jsxs(Box, { children: [_jsxs(Box, {
|
|
40
|
-
width: '100%',
|
|
41
|
-
borderCollapse: 'collapse',
|
|
42
|
-
fontSize: 0,
|
|
43
|
-
fontFamily: 'mono',
|
|
44
|
-
}, children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", children: ['Table', 'Rows', 'Users', 'Disk'].map(h => (_jsx(Box, { as: "th", sx: {
|
|
45
|
-
textAlign: h === 'Table' ? 'left' : 'right',
|
|
46
|
-
pb: 1,
|
|
47
|
-
color: 'fg.muted',
|
|
48
|
-
fontWeight: 'bold',
|
|
49
|
-
borderBottom: '1px solid',
|
|
50
|
-
borderColor: 'border.default',
|
|
51
|
-
}, children: h }, h))) }) }), _jsx(Box, { as: "tbody", children: Object.entries(tables).map(([tbl, info]) => (_jsxs(Box, { as: "tr", children: [_jsx(Box, { as: "td", sx: { py: 1, pr: 3, color: 'accent.fg' }, children: tbl }), info?.error ? (_jsx(Box, { as: "td", colSpan: 3, sx: { color: 'danger.fg', py: 1 }, children: info.error })) : (_jsxs(_Fragment, { children: [_jsx(Box, { as: "td", sx: { textAlign: 'right', py: 1, pr: 3 }, children: (info.row_count ?? 0).toLocaleString() }), _jsx(Box, { as: "td", sx: { textAlign: 'right', py: 1, pr: 3 }, children: info.distinct_users ?? 0 }), _jsx(Box, { as: "td", sx: { textAlign: 'right', py: 1 }, children: fmtBytes(info.disk_bytes ?? 0) })] }))] }, tbl))) })] })] })), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Total distinct users across all tables:", ' ', _jsx(Text, { sx: { fontWeight: 'bold', color: 'fg.default' }, children: total_distinct_users ?? '?' })] })] }));
|
|
40
|
+
return (_jsxs(Box, { children: [_jsxs(Box, { ...CARD_SX, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', mb: 2, display: 'block' }, children: "Process" }), proc?.error ? (_jsx(Text, { sx: { color: 'attention.fg', fontSize: 0 }, children: proc.error })) : (_jsxs(Box, { ...GRID_SX, children: [_jsx(StatCell, { label: "RSS Memory", value: fmtBytes(proc?.memory_rss_bytes ?? 0) }), _jsx(StatCell, { label: "VMS Memory", value: fmtBytes(proc?.memory_vms_bytes ?? 0) }), _jsx(StatCell, { label: "CPU", value: `${(proc?.cpu_percent ?? 0).toFixed(1)} %` }), _jsx(StatCell, { label: "Threads", value: String(proc?.num_threads ?? '?') })] }))] }), _jsxs(Box, { ...CARD_SX, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', mb: 2, display: 'block' }, children: "Disk" }), disk?.error ? (_jsx(Text, { sx: { color: 'attention.fg', fontSize: 0 }, children: disk.error })) : (_jsxs(Box, { ...GRID_SX, children: [_jsx(StatCell, { label: "Data Dir", value: disk?.data_dir ?? '?' }), _jsx(StatCell, { label: "Total", value: fmtBytes(disk?.total_bytes ?? 0) }), _jsx(StatCell, { label: "Used", value: `${fmtBytes(disk?.used_bytes ?? 0)} (${(disk?.used_percent ?? 0).toFixed(1)}%)` }), _jsx(StatCell, { label: "Free", value: fmtBytes(disk?.free_bytes ?? 0) })] }))] }), tables && Object.keys(tables).length > 0 && (_jsxs(Box, { ...CARD_SX, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', mb: 2, display: 'block' }, children: "Tables" }), _jsxs(Box, { as: "table", width: "100%", borderCollapse: "collapse", fontSize: 0, fontFamily: "mono", children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", children: ['Table', 'Rows', 'Users', 'Disk'].map(h => (_jsx(Box, { as: "th", textAlign: h === 'Table' ? 'left' : 'right', pb: 1, color: "fg.muted", fontWeight: "bold", borderBottom: "1px solid", borderColor: "border.default", children: h }, h))) }) }), _jsx(Box, { as: "tbody", children: Object.entries(tables).map(([tbl, info]) => (_jsxs(Box, { as: "tr", children: [_jsx(Box, { as: "td", py: 1, pr: 3, color: "accent.fg", children: tbl }), info?.error ? (_jsx(Box, { as: "td", colSpan: 3, color: "danger.fg", py: 1, children: info.error })) : (_jsxs(_Fragment, { children: [_jsx(Box, { as: "td", textAlign: "right", py: 1, pr: 3, children: (info.row_count ?? 0).toLocaleString() }), _jsx(Box, { as: "td", textAlign: "right", py: 1, pr: 3, children: info.distinct_users ?? 0 }), _jsx(Box, { as: "td", textAlign: "right", py: 1, children: fmtBytes(info.disk_bytes ?? 0) })] }))] }, tbl))) })] })] })), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Total distinct users across all tables:", ' ', _jsx(Text, { sx: { fontWeight: 'bold', color: 'fg.default' }, children: total_distinct_users ?? '?' })] })] }));
|
|
52
41
|
};
|
|
53
42
|
export const OtelSystemView = ({ baseUrl = '', token, }) => {
|
|
54
43
|
const { data, loading, error, refresh } = useOtelSystem({ baseUrl, token });
|
|
55
|
-
return (_jsxs(Box, { sx: {
|
|
56
|
-
display: 'flex',
|
|
57
|
-
flexDirection: 'column',
|
|
58
|
-
flex: 1,
|
|
59
|
-
minHeight: 0,
|
|
60
|
-
overflow: 'auto',
|
|
61
|
-
p: 3,
|
|
62
|
-
}, children: [_jsxs(Box, { sx: {
|
|
63
|
-
display: 'flex',
|
|
64
|
-
alignItems: 'center',
|
|
65
|
-
justifyContent: 'space-between',
|
|
66
|
-
mb: 3,
|
|
67
|
-
flexShrink: 0,
|
|
68
|
-
}, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: "System Statistics" }), _jsx(Button, { size: "small", variant: "invisible", onClick: refresh, disabled: loading, leadingVisual: SyncIcon, children: "Refresh" })] }), loading && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading\u2026" })] })), !loading && error && (_jsx(Box, { sx: {
|
|
69
|
-
bg: 'danger.subtle',
|
|
70
|
-
border: '1px solid',
|
|
71
|
-
borderColor: 'danger.muted',
|
|
72
|
-
borderRadius: 2,
|
|
73
|
-
p: 3,
|
|
74
|
-
}, children: _jsx(Text, { sx: { color: 'danger.fg', fontSize: 1 }, children: error }) })), !loading && !error && data && _jsx(SystemViewContent, { data: data }), !loading && !error && !data && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No data available." }))] }));
|
|
44
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "auto", p: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 3, flexShrink: 0, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: "System Statistics" }), _jsx(Button, { size: "small", variant: "invisible", onClick: refresh, disabled: loading, leadingVisual: SyncIcon, children: "Refresh" })] }), loading && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading\u2026" })] })), !loading && error && (_jsx(Box, { bg: "danger.subtle", border: "1px solid", borderColor: "danger.muted", borderRadius: 2, p: 3, children: _jsx(Text, { sx: { color: 'danger.fg', fontSize: 1 }, children: error }) })), !loading && !error && data && _jsx(SystemViewContent, { data: data }), !loading && !error && !data && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No data available." }))] }));
|
|
75
45
|
};
|
|
@@ -12,7 +12,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
12
12
|
* @module otel/OtelTimeline
|
|
13
13
|
*/
|
|
14
14
|
import { useMemo } from 'react';
|
|
15
|
-
import { Box
|
|
15
|
+
import { Box } from '@datalayer/primer-addons';
|
|
16
|
+
import { Text } from '@primer/react';
|
|
16
17
|
import { toMs, formatDuration, serviceColor } from '../utils.js';
|
|
17
18
|
export const OtelTimeline = ({ spans, barHeight = 24, selectedSpanId, onSelectSpan, }) => {
|
|
18
19
|
const { minTime, maxTime, sortedSpans } = useMemo(() => {
|
|
@@ -37,9 +38,9 @@ export const OtelTimeline = ({ spans, barHeight = 24, selectedSpanId, onSelectSp
|
|
|
37
38
|
}, [spans]);
|
|
38
39
|
const totalDuration = maxTime - minTime || 1;
|
|
39
40
|
if (sortedSpans.length === 0) {
|
|
40
|
-
return (_jsx(Box, {
|
|
41
|
+
return (_jsx(Box, { p: 3, color: "fg.muted", textAlign: "center", children: _jsx(Text, { children: "No spans to display." }) }));
|
|
41
42
|
}
|
|
42
|
-
return (_jsxs(Box, {
|
|
43
|
+
return (_jsxs(Box, { width: "100%", overflowX: "auto", py: 1, children: [sortedSpans.map(span => {
|
|
43
44
|
const startOffset = ((toMs(span.start_time) - minTime) / totalDuration) * 100;
|
|
44
45
|
const width = Math.max(((span.duration_ms || toMs(span.end_time) - toMs(span.start_time)) /
|
|
45
46
|
totalDuration) *
|
|
@@ -47,18 +48,7 @@ export const OtelTimeline = ({ spans, barHeight = 24, selectedSpanId, onSelectSp
|
|
|
47
48
|
const color = serviceColor(span.service_name);
|
|
48
49
|
const isSelected = selectedSpanId === span.span_id;
|
|
49
50
|
const indent = (span.depth ?? 0) * 16;
|
|
50
|
-
return (_jsxs(Box, { sx: {
|
|
51
|
-
display: 'flex',
|
|
52
|
-
alignItems: 'center',
|
|
53
|
-
height: barHeight,
|
|
54
|
-
mb: '2px',
|
|
55
|
-
cursor: 'pointer',
|
|
56
|
-
bg: isSelected ? 'accent.subtle' : 'canvas.default',
|
|
57
|
-
borderRadius: 1,
|
|
58
|
-
':hover': {
|
|
59
|
-
bg: isSelected ? 'accent.subtle' : 'canvas.subtle',
|
|
60
|
-
},
|
|
61
|
-
}, onClick: () => onSelectSpan?.(span), title: `${span.service_name} / ${span.span_name} — ${formatDuration(span.duration_ms)}`, children: [_jsx(Text, { sx: {
|
|
51
|
+
return (_jsxs(Box, { display: "flex", alignItems: "center", height: barHeight, mb: "2px", cursor: "pointer", bg: isSelected ? 'accent.subtle' : 'canvas.default', borderRadius: 1, hover: { bg: isSelected ? 'accent.subtle' : 'canvas.subtle' }, onClick: () => onSelectSpan?.(span), title: `${span.service_name} / ${span.span_name} — ${formatDuration(span.duration_ms)}`, children: [_jsx(Text, { sx: {
|
|
62
52
|
width: 200,
|
|
63
53
|
minWidth: 200,
|
|
64
54
|
pl: `${indent}px`,
|
|
@@ -69,18 +59,7 @@ export const OtelTimeline = ({ spans, barHeight = 24, selectedSpanId, onSelectSp
|
|
|
69
59
|
fontSize: 1,
|
|
70
60
|
fontFamily: 'mono',
|
|
71
61
|
color: 'fg.muted',
|
|
72
|
-
}, children: span.span_name }), _jsx(Box, {
|
|
73
|
-
position: 'absolute',
|
|
74
|
-
left: `${startOffset}%`,
|
|
75
|
-
width: `${width}%`,
|
|
76
|
-
height: barHeight - 6,
|
|
77
|
-
top: '3px',
|
|
78
|
-
bg: color,
|
|
79
|
-
borderRadius: 1,
|
|
80
|
-
opacity: isSelected ? 1 : 0.8,
|
|
81
|
-
border: isSelected ? '2px solid' : 'none',
|
|
82
|
-
borderColor: 'accent.emphasis',
|
|
83
|
-
} }) }), _jsx(Text, { sx: {
|
|
62
|
+
}, children: span.span_name }), _jsx(Box, { flex: 1, position: "relative", height: "100%", children: _jsx(Box, { position: "absolute", left: `${startOffset}%`, width: `${width}%`, height: barHeight - 6, top: "3px", bg: color, borderRadius: 1, opacity: isSelected ? 1 : 0.8, border: isSelected ? '2px solid' : 'none', borderColor: "accent.emphasis" }) }), _jsx(Text, { sx: {
|
|
84
63
|
minWidth: 64,
|
|
85
64
|
textAlign: 'right',
|
|
86
65
|
pl: 1,
|
|
@@ -88,14 +67,5 @@ export const OtelTimeline = ({ spans, barHeight = 24, selectedSpanId, onSelectSp
|
|
|
88
67
|
fontFamily: 'mono',
|
|
89
68
|
color: 'fg.muted',
|
|
90
69
|
}, children: formatDuration(span.duration_ms) })] }, span.span_id));
|
|
91
|
-
}), _jsxs(Box, { sx: {
|
|
92
|
-
borderTop: '1px solid',
|
|
93
|
-
borderColor: 'border.default',
|
|
94
|
-
mt: 2,
|
|
95
|
-
pt: 2,
|
|
96
|
-
display: 'flex',
|
|
97
|
-
justifyContent: 'space-between',
|
|
98
|
-
fontSize: 0,
|
|
99
|
-
color: 'fg.muted',
|
|
100
|
-
}, children: [_jsxs(Text, { children: [sortedSpans.length, " span", sortedSpans.length !== 1 ? 's' : ''] }), _jsxs(Text, { sx: { fontFamily: 'mono' }, children: ["Total: ", formatDuration(totalDuration)] })] })] }));
|
|
70
|
+
}), _jsxs(Box, { borderTop: "1px solid", borderColor: "border.default", mt: 2, pt: 2, display: "flex", justifyContent: "space-between", fontSize: 0, color: "fg.muted", children: [_jsxs(Text, { children: [sortedSpans.length, " span", sortedSpans.length !== 1 ? 's' : ''] }), _jsxs(Text, { sx: { fontFamily: 'mono' }, children: ["Total: ", formatDuration(totalDuration)] })] })] }));
|
|
101
71
|
};
|
|
@@ -17,7 +17,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
17
17
|
* @module otel/OtelTimelineRangeSlider
|
|
18
18
|
*/
|
|
19
19
|
import { useCallback, useRef, useState, useMemo } from 'react';
|
|
20
|
-
import { Box
|
|
20
|
+
import { Box } from '@datalayer/primer-addons';
|
|
21
|
+
import { Text } from '@primer/react';
|
|
21
22
|
// ── Helpers ─────────────────────────────────────────────────────────
|
|
22
23
|
function clamp(v, min, max) {
|
|
23
24
|
return Math.max(min, Math.min(max, v));
|
|
@@ -172,156 +173,22 @@ export const OtelTimelineRangeSlider = ({ timelineStart, timelineEnd, selectedSt
|
|
|
172
173
|
const RAIL_HEIGHT = height - 24; // Reserve 24px for tick labels
|
|
173
174
|
const HANDLE_WIDTH = 10;
|
|
174
175
|
const HANDLE_HEIGHT = RAIL_HEIGHT;
|
|
175
|
-
return (_jsxs(Box, {
|
|
176
|
-
width: '100%',
|
|
177
|
-
height,
|
|
178
|
-
px: 3,
|
|
179
|
-
py: 1,
|
|
180
|
-
userSelect: 'none',
|
|
181
|
-
bg: 'canvas.subtle',
|
|
182
|
-
borderBottom: '1px solid',
|
|
183
|
-
borderColor: 'border.default',
|
|
184
|
-
}, children: [_jsxs(Box, { ref: railRef, onClick: handleRailClick, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, sx: {
|
|
185
|
-
position: 'relative',
|
|
186
|
-
width: '100%',
|
|
187
|
-
height: RAIL_HEIGHT,
|
|
188
|
-
cursor: 'pointer',
|
|
189
|
-
}, children: [_jsx(Box, { sx: {
|
|
190
|
-
position: 'absolute',
|
|
191
|
-
inset: 0,
|
|
192
|
-
bg: 'canvas.inset',
|
|
193
|
-
borderRadius: 1,
|
|
194
|
-
border: '1px solid',
|
|
195
|
-
borderColor: 'border.muted',
|
|
196
|
-
} }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'track'), sx: {
|
|
197
|
-
position: 'absolute',
|
|
198
|
-
top: 0,
|
|
199
|
-
bottom: 0,
|
|
200
|
-
left: `${startPct}%`,
|
|
201
|
-
width: `${endPct - startPct}%`,
|
|
202
|
-
bg: 'accent.muted',
|
|
203
|
-
opacity: 0.45,
|
|
204
|
-
borderTop: '2px solid',
|
|
205
|
-
borderBottom: '2px solid',
|
|
206
|
-
borderColor: 'accent.fg',
|
|
207
|
-
cursor: 'grab',
|
|
208
|
-
zIndex: 2,
|
|
209
|
-
transition: isDragging
|
|
210
|
-
? 'none'
|
|
211
|
-
: 'left 0.05s ease, width 0.05s ease',
|
|
212
|
-
':active': { cursor: 'grabbing' },
|
|
213
|
-
} }), histogram &&
|
|
176
|
+
return (_jsxs(Box, { width: "100%", height: height, px: 3, py: 1, userSelect: "none", bg: "canvas.subtle", borderBottom: "1px solid", borderColor: "border.default", children: [_jsxs(Box, { ref: railRef, onClick: handleRailClick, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, position: "relative", width: "100%", height: RAIL_HEIGHT, cursor: "pointer", children: [_jsx(Box, { position: "absolute", inset: 0, bg: "canvas.inset", borderRadius: 1, border: "1px solid", borderColor: "border.muted" }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'track'), position: "absolute", top: 0, bottom: 0, left: `${startPct}%`, width: `${endPct - startPct}%`, bg: "accent.muted", opacity: 0.45, borderTop: "2px solid", borderBottom: "2px solid", borderColor: "accent.fg", cursor: "grab", zIndex: 2, transition: isDragging ? 'none' : 'left 0.05s ease, width 0.05s ease', active: { cursor: 'grabbing' } }), histogram &&
|
|
214
177
|
histMax > 0 &&
|
|
215
178
|
histogram.map((h, i) => {
|
|
216
179
|
const pct = ((h.time.getTime() - tlStart) / tlRange) * 100;
|
|
217
180
|
const barWidth = 100 / (histogram.length || 1);
|
|
218
181
|
const barH = (h.count / histMax) * 100;
|
|
219
|
-
return (_jsx(Box, {
|
|
220
|
-
|
|
221
|
-
bottom: 0,
|
|
222
|
-
left: `${pct}%`,
|
|
223
|
-
width: `${barWidth}%`,
|
|
224
|
-
height: `${barH}%`,
|
|
225
|
-
bg: 'accent.fg',
|
|
226
|
-
opacity: 0.35,
|
|
227
|
-
borderRadius: '1px 1px 0 0',
|
|
228
|
-
pointerEvents: 'none',
|
|
229
|
-
zIndex: 4,
|
|
230
|
-
} }, i));
|
|
231
|
-
}), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'start'), sx: {
|
|
232
|
-
position: 'absolute',
|
|
233
|
-
top: 0,
|
|
234
|
-
left: `${startPct}%`,
|
|
235
|
-
width: HANDLE_WIDTH,
|
|
236
|
-
height: HANDLE_HEIGHT,
|
|
237
|
-
ml: `-${HANDLE_WIDTH / 2}px`,
|
|
238
|
-
bg: 'accent.fg',
|
|
239
|
-
borderRadius: 1,
|
|
240
|
-
cursor: 'ew-resize',
|
|
241
|
-
zIndex: 3,
|
|
242
|
-
display: 'flex',
|
|
243
|
-
alignItems: 'center',
|
|
244
|
-
justifyContent: 'center',
|
|
245
|
-
transition: isDragging ? 'none' : 'left 0.05s ease',
|
|
246
|
-
boxShadow: 'shadow.medium',
|
|
247
|
-
':hover': { bg: 'accent.emphasis' },
|
|
248
|
-
}, children: _jsx(Box, { sx: {
|
|
249
|
-
width: '2px',
|
|
250
|
-
height: '40%',
|
|
251
|
-
bg: 'fg.onEmphasis',
|
|
252
|
-
borderRadius: 1,
|
|
253
|
-
} }) }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'end'), sx: {
|
|
254
|
-
position: 'absolute',
|
|
255
|
-
top: 0,
|
|
256
|
-
left: `${endPct}%`,
|
|
257
|
-
width: HANDLE_WIDTH,
|
|
258
|
-
height: HANDLE_HEIGHT,
|
|
259
|
-
ml: `-${HANDLE_WIDTH / 2}px`,
|
|
260
|
-
bg: 'accent.fg',
|
|
261
|
-
borderRadius: 1,
|
|
262
|
-
cursor: 'ew-resize',
|
|
263
|
-
zIndex: 3,
|
|
264
|
-
display: 'flex',
|
|
265
|
-
alignItems: 'center',
|
|
266
|
-
justifyContent: 'center',
|
|
267
|
-
transition: isDragging ? 'none' : 'left 0.05s ease',
|
|
268
|
-
boxShadow: 'shadow.medium',
|
|
269
|
-
':hover': { bg: 'accent.emphasis' },
|
|
270
|
-
}, children: _jsx(Box, { sx: {
|
|
271
|
-
width: '2px',
|
|
272
|
-
height: '40%',
|
|
273
|
-
bg: 'fg.onEmphasis',
|
|
274
|
-
borderRadius: 1,
|
|
275
|
-
} }) }), hoverPct !== null && !isDragging && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
276
|
-
position: 'absolute',
|
|
277
|
-
top: 0,
|
|
278
|
-
left: `${hoverPct}%`,
|
|
279
|
-
width: '1px',
|
|
280
|
-
height: RAIL_HEIGHT,
|
|
281
|
-
borderLeft: '1px dashed',
|
|
282
|
-
borderColor: 'fg.default',
|
|
283
|
-
opacity: 0.55,
|
|
284
|
-
pointerEvents: 'none',
|
|
285
|
-
zIndex: 5,
|
|
286
|
-
} }), _jsx(Box, { sx: {
|
|
287
|
-
position: 'absolute',
|
|
288
|
-
top: -36,
|
|
289
|
-
left: `${hoverPct}%`,
|
|
290
|
-
transform: 'translateX(-50%)',
|
|
291
|
-
bg: 'canvas.overlay',
|
|
292
|
-
border: '1px solid',
|
|
293
|
-
borderColor: 'border.default',
|
|
294
|
-
borderRadius: 2,
|
|
295
|
-
px: 2,
|
|
296
|
-
py: '2px',
|
|
297
|
-
pointerEvents: 'none',
|
|
298
|
-
zIndex: 10,
|
|
299
|
-
boxShadow: 'shadow.medium',
|
|
300
|
-
whiteSpace: 'nowrap',
|
|
301
|
-
}, children: _jsx(Text, { sx: {
|
|
182
|
+
return (_jsx(Box, { position: "absolute", bottom: 0, left: `${pct}%`, width: `${barWidth}%`, height: `${barH}%`, bg: "accent.fg", opacity: 0.35, borderRadius: "1px 1px 0 0", pointerEvents: "none", zIndex: 4 }, i));
|
|
183
|
+
}), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'start'), position: "absolute", top: 0, left: `${startPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'end'), position: "absolute", top: 0, left: `${endPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), hoverPct !== null && !isDragging && (_jsxs(_Fragment, { children: [_jsx(Box, { position: "absolute", top: 0, left: `${hoverPct}%`, width: "1px", height: RAIL_HEIGHT, borderLeft: "1px dashed", borderColor: "fg.default", opacity: 0.55, pointerEvents: "none", zIndex: 5 }), _jsx(Box, { position: "absolute", top: -36, left: `${hoverPct}%`, transform: "translateX(-50%)", bg: "canvas.overlay", border: "1px solid", borderColor: "border.default", borderRadius: 2, px: 2, py: "2px", pointerEvents: "none", zIndex: 10, boxShadow: "shadow.medium", whiteSpace: "nowrap", children: _jsx(Text, { sx: {
|
|
302
184
|
fontSize: '11px',
|
|
303
185
|
color: 'fg.default',
|
|
304
186
|
fontFamily: 'mono',
|
|
305
187
|
lineHeight: '18px',
|
|
306
188
|
}, children: formatHoverDate(hoverPct) }) })] })), ticks.map((t, i) => {
|
|
307
189
|
const pct = ((t.getTime() - tlStart) / tlRange) * 100;
|
|
308
|
-
return (_jsx(Box, {
|
|
309
|
-
|
|
310
|
-
top: 0,
|
|
311
|
-
left: `${pct}%`,
|
|
312
|
-
width: '1px',
|
|
313
|
-
height: RAIL_HEIGHT,
|
|
314
|
-
bg: 'border.muted',
|
|
315
|
-
pointerEvents: 'none',
|
|
316
|
-
opacity: 0.5,
|
|
317
|
-
zIndex: 1,
|
|
318
|
-
} }, i));
|
|
319
|
-
})] }), _jsx(Box, { sx: {
|
|
320
|
-
position: 'relative',
|
|
321
|
-
width: '100%',
|
|
322
|
-
height: 20,
|
|
323
|
-
mt: '2px',
|
|
324
|
-
}, children: ticks.map((t, i) => {
|
|
190
|
+
return (_jsx(Box, { position: "absolute", top: 0, left: `${pct}%`, width: "1px", height: RAIL_HEIGHT, bg: "border.muted", pointerEvents: "none", opacity: 0.5, zIndex: 1 }, i));
|
|
191
|
+
})] }), _jsx(Box, { position: "relative", width: "100%", height: 20, mt: "2px", children: ticks.map((t, i) => {
|
|
325
192
|
const pct = ((t.getTime() - tlStart) / tlRange) * 100;
|
|
326
193
|
return (_jsx(Text, { sx: {
|
|
327
194
|
position: 'absolute',
|