@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
|
@@ -93,7 +93,8 @@ export const SERVICE_TONE = {
|
|
|
93
93
|
};
|
|
94
94
|
/** The bar colour of a span, by the service that emitted it and how it ended. */
|
|
95
95
|
export const toneOf = (span) => {
|
|
96
|
-
if (span.status_code === 'STATUS_CODE_ERROR' ||
|
|
96
|
+
if (span.status_code === 'STATUS_CODE_ERROR' ||
|
|
97
|
+
span.status_code === 'ERROR') {
|
|
97
98
|
return 'danger.emphasis';
|
|
98
99
|
}
|
|
99
100
|
return SERVICE_TONE[span.service_name] ?? 'neutral.emphasis';
|
|
@@ -105,28 +106,12 @@ export const TraceTimeline = ({ tree, traceId, live = false, }) => {
|
|
|
105
106
|
? 'No spans yet. They arrive as the services report them.'
|
|
106
107
|
: 'This run reported no spans. A run started before tracing reached the service that ran it has none.' }));
|
|
107
108
|
}
|
|
108
|
-
return (_jsxs(Box, {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
minWidth: 0,
|
|
114
|
-
}, children: [_jsx(Box, { sx: { pl: row.depth, minWidth: 0 }, children: _jsx(Truncate, { title: `${row.span.span_name} · ${row.span.service_name}`, sx: { fontSize: 0, maxWidth: '100%' }, children: row.span.span_name }) }), _jsx(Box, { sx: {
|
|
115
|
-
position: 'relative',
|
|
116
|
-
height: '0.75rem',
|
|
117
|
-
bg: 'canvas.subtle',
|
|
118
|
-
borderRadius: 1,
|
|
119
|
-
minWidth: 0,
|
|
120
|
-
}, children: _jsx(Box, { sx: {
|
|
121
|
-
position: 'absolute',
|
|
122
|
-
top: 0,
|
|
123
|
-
bottom: 0,
|
|
124
|
-
left: `${row.left}%`,
|
|
125
|
-
width: `${row.width}%`,
|
|
126
|
-
bg: toneOf(row.span),
|
|
127
|
-
borderRadius: 1,
|
|
128
|
-
}, title: `${row.span.service_name} · ${durationLabel(row.span.duration_ms)}` }) }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontVariantNumeric: 'tabular-nums' }, children: durationLabel(row.span.duration_ms) })] }, row.span.span_id)))] }));
|
|
109
|
+
return (_jsxs(Box, { display: "grid", gap: 1, minWidth: 0, children: [traceId && (_jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, color: 'fg.muted' }, children: traceId })), rows.map(row => (_jsxs(Box, { display: "grid", gridTemplateColumns: "minmax(0, 14rem) 1fr auto", gap: 2, alignItems: "center", minWidth: 0, children: [_jsx(Box, { pl: row.depth, minWidth: 0, children: _jsx(Truncate, { title: `${row.span.span_name} · ${row.span.service_name}`, sx: { fontSize: 0, maxWidth: '100%' }, children: row.span.span_name }) }), _jsx(Box, { position: "relative", height: "0.75rem", bg: "canvas.subtle", borderRadius: 1, minWidth: 0, children: _jsx(Box, { position: "absolute", top: 0, bottom: 0, left: `${row.left}%`, width: `${row.width}%`, bg: toneOf(row.span), borderRadius: 1, title: `${row.span.service_name} · ${durationLabel(row.span.duration_ms)}` }) }), _jsx(Text, { sx: {
|
|
110
|
+
fontSize: 0,
|
|
111
|
+
color: 'fg.muted',
|
|
112
|
+
fontVariantNumeric: 'tabular-nums',
|
|
113
|
+
}, children: durationLabel(row.span.duration_ms) })] }, row.span.span_id)))] }));
|
|
129
114
|
};
|
|
130
115
|
/** The timeline under its own heading, as the Runs detail draws it. */
|
|
131
|
-
export const TraceTimelineSection = (props) => (_jsxs(Box, { children: [_jsxs(Box, {
|
|
116
|
+
export const TraceTimelineSection = (props) => (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", mb: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "Where the time went" }), props.live && (_jsx(Label, { size: "small", variant: "success", children: "Live" }))] }), _jsx(TraceTimeline, { ...props })] }));
|
|
132
117
|
export default TraceTimeline;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelLive } from '../../otel/index.js';
|
|
4
|
-
export const DashboardView = ({ baseUrl = '', wsBaseUrl, token, autoRefreshMs = 5000, defaultSignal = 'traces', limit = 200, onSignalRef, }) => (_jsx(Box, {
|
|
4
|
+
export const DashboardView = ({ baseUrl = '', wsBaseUrl, token, autoRefreshMs = 5000, defaultSignal = 'traces', limit = 200, onSignalRef, }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelLive, { baseUrl: baseUrl, wsBaseUrl: wsBaseUrl, token: token, autoRefreshMs: autoRefreshMs, defaultSignal: defaultSignal, limit: limit, onSignalRef: onSignalRef }) }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelLive } from '../../otel/index.js';
|
|
4
|
-
export const LogsView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, {
|
|
4
|
+
export const LogsView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelLive, { baseUrl: baseUrl, token: token, autoRefreshMs: autoRefreshMs, defaultSignal: "logs", limit: limit }) }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelLive } from '../../otel/index.js';
|
|
4
|
-
export const MetricsView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, {
|
|
4
|
+
export const MetricsView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelLive, { baseUrl: baseUrl, token: token, autoRefreshMs: autoRefreshMs, defaultSignal: "metrics", limit: limit }) }));
|
|
@@ -11,7 +11,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
11
|
* pass `onSignOut` to wire up your own logout action.
|
|
12
12
|
*/
|
|
13
13
|
import { useState, useCallback, useRef } from 'react';
|
|
14
|
-
import { Box
|
|
14
|
+
import { Box } from '@datalayer/primer-addons';
|
|
15
|
+
import { Text, Button, Dialog } from '@primer/react';
|
|
15
16
|
import { TelescopeIcon, SignOutIcon } from '@primer/octicons-react';
|
|
16
17
|
import { UserBadge } from '../profile/index.js';
|
|
17
18
|
export const OtelHeader = ({ baseUrl = '', token, trailing, onNavigate, onSignOut, showGenerateButtons = true, showAccountControls = true, }) => {
|
|
@@ -58,48 +59,13 @@ export const OtelHeader = ({ baseUrl = '', token, trailing, onNavigate, onSignOu
|
|
|
58
59
|
setDialogOpen(true);
|
|
59
60
|
}
|
|
60
61
|
}, [baseUrl, token, onNavigate]);
|
|
61
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Box, { as: "header",
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
gap: 3,
|
|
65
|
-
px: 3,
|
|
66
|
-
py: 2,
|
|
67
|
-
bg: 'canvas.inset',
|
|
68
|
-
borderBottom: '1px solid',
|
|
69
|
-
borderColor: 'border.default',
|
|
70
|
-
flexShrink: 0,
|
|
71
|
-
// Allow overflow visible so the JWT popover can extend below the header.
|
|
72
|
-
overflow: 'visible',
|
|
73
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(TelescopeIcon, { size: 20 }), _jsx(Text, { sx: { fontWeight: 'bold', fontSize: 2 }, children: "Datalayer OTEL" })] }), _jsx(Box, { sx: { flex: 1 } }), showGenerateButtons && (_jsxs(_Fragment, { children: [_jsx(Button, { ref: returnFocusRef, size: "small", variant: "primary", disabled: generating, onClick: () => generate('traces', 3), children: "+ Traces" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('ai-traces', 3), children: "+ AI Traces" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('logs', 10), children: "+ Logs" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('metrics', 5), children: "+ Metrics" })] })), trailing, showAccountControls && token && _jsx(UserBadge, { token: token }), showAccountControls && onSignOut && (_jsx(Button, { size: "small", variant: "invisible", onClick: onSignOut, sx: { color: 'fg.muted' }, leadingVisual: SignOutIcon, children: "Sign out" }))] }), dialogOpen && (_jsxs(Dialog, { title: dialogTitle, onClose: () => setDialogOpen(false), footerButtons: [
|
|
62
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { as: "header", display: "flex", alignItems: "center", gap: 3, px: 3, py: 2, bg: "canvas.inset", borderBottom: "1px solid", borderColor: "border.default", flexShrink: 0,
|
|
63
|
+
// Allow overflow visible so the JWT popover can extend below the header.
|
|
64
|
+
overflow: "visible", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(TelescopeIcon, { size: 20 }), _jsx(Text, { sx: { fontWeight: 'bold', fontSize: 2 }, children: "Datalayer OTEL" })] }), _jsx(Box, { flex: 1 }), showGenerateButtons && (_jsxs(_Fragment, { children: [_jsx(Button, { ref: returnFocusRef, size: "small", variant: "primary", disabled: generating, onClick: () => generate('traces', 3), children: "+ Traces" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('ai-traces', 3), children: "+ AI Traces" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('logs', 10), children: "+ Logs" }), _jsx(Button, { size: "small", variant: "primary", disabled: generating, onClick: () => generate('metrics', 5), children: "+ Metrics" })] })), trailing, showAccountControls && token && _jsx(UserBadge, { token: token }), showAccountControls && onSignOut && (_jsx(Button, { size: "small", variant: "invisible", onClick: onSignOut, sx: { color: 'fg.muted' }, leadingVisual: SignOutIcon, children: "Sign out" }))] }), dialogOpen && (_jsxs(Dialog, { title: dialogTitle, onClose: () => setDialogOpen(false), footerButtons: [
|
|
74
65
|
{
|
|
75
66
|
content: 'Close',
|
|
76
67
|
onClick: () => setDialogOpen(false),
|
|
77
68
|
buttonType: 'default',
|
|
78
69
|
},
|
|
79
|
-
], children: [_jsxs(Box, { sx: {
|
|
80
|
-
fontFamily: 'mono',
|
|
81
|
-
fontSize: 1,
|
|
82
|
-
p: 2,
|
|
83
|
-
mt: 1,
|
|
84
|
-
bg: 'canvas.inset',
|
|
85
|
-
borderRadius: 2,
|
|
86
|
-
overflow: 'auto',
|
|
87
|
-
color: 'fg.default',
|
|
88
|
-
whiteSpace: 'pre-wrap',
|
|
89
|
-
wordBreak: 'break-all',
|
|
90
|
-
border: '1px solid',
|
|
91
|
-
borderColor: 'border.default',
|
|
92
|
-
}, children: dialogRequest })] }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Response" }), _jsx(Box, { as: "pre", sx: {
|
|
93
|
-
fontFamily: 'mono',
|
|
94
|
-
fontSize: 1,
|
|
95
|
-
p: 2,
|
|
96
|
-
mt: 1,
|
|
97
|
-
bg: 'canvas.subtle',
|
|
98
|
-
borderRadius: 2,
|
|
99
|
-
overflow: 'auto',
|
|
100
|
-
maxHeight: 300,
|
|
101
|
-
color: dialogVariant === 'error' ? 'danger.fg' : 'fg.default',
|
|
102
|
-
whiteSpace: 'pre-wrap',
|
|
103
|
-
wordBreak: 'break-all',
|
|
104
|
-
}, children: dialogBody })] })] }))] }));
|
|
70
|
+
], children: [_jsxs(Box, { mb: 2, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Request" }), _jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.inset", borderRadius: 2, overflow: "auto", color: "fg.default", whiteSpace: "pre-wrap", wordBreak: "break-all", border: "1px solid", borderColor: "border.default", children: dialogRequest })] }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Response" }), _jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.subtle", borderRadius: 2, overflow: "auto", maxHeight: 300, color: dialogVariant === 'error' ? 'danger.fg' : 'fg.default', whiteSpace: "pre-wrap", wordBreak: "break-all", children: dialogBody })] })] }))] }));
|
|
105
71
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelSqlView } from '../../otel/index.js';
|
|
4
|
-
export const SqlView = ({ baseUrl = '', token }) => (_jsx(Box, {
|
|
4
|
+
export const SqlView = ({ baseUrl = '', token }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelSqlView, { baseUrl: baseUrl, token: token }) }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelSystemView } from '../../otel/index.js';
|
|
4
|
-
export const SystemView = ({ baseUrl = '', token, }) => (_jsx(Box, {
|
|
4
|
+
export const SystemView = ({ baseUrl = '', token, }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelSystemView, { baseUrl: baseUrl, token: token }) }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { OtelLive } from '../../otel/index.js';
|
|
4
|
-
export const TracesView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, {
|
|
4
|
+
export const TracesView = ({ baseUrl = '', token, autoRefreshMs = 5000, limit = 200, }) => (_jsx(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(OtelLive, { baseUrl: baseUrl, token: token, autoRefreshMs: autoRefreshMs, defaultSignal: "traces", limit: limit }) }));
|
|
@@ -15,7 +15,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
15
15
|
* @module views/profile
|
|
16
16
|
*/
|
|
17
17
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
18
|
-
import { Box
|
|
18
|
+
import { Box } from '@datalayer/primer-addons';
|
|
19
|
+
import { Text } from '@primer/react';
|
|
19
20
|
import { parseJwtPayload, getDatalayerJwtUser, getDatalayerDisplayName, } from '../../utils/Jwt.js';
|
|
20
21
|
import { getRelativeTime } from '../../utils/Date.js';
|
|
21
22
|
// ── Component ─────────────────────────────────────────────────────
|
|
@@ -64,7 +65,7 @@ export const UserBadge = ({ token, variant = 'full', showExpandToggle = true, ex
|
|
|
64
65
|
expiredNotifiedForTokenRef.current = token;
|
|
65
66
|
onTokenExpired();
|
|
66
67
|
}, [expired, onTokenExpired, open, token]);
|
|
67
|
-
return (_jsxs(Box, {
|
|
68
|
+
return (_jsxs(Box, { position: "relative", onMouseEnter: handleEnter, onMouseLeave: handleLeave, children: [_jsx(Text, { sx: {
|
|
68
69
|
fontSize: 1,
|
|
69
70
|
color: triggerColor,
|
|
70
71
|
cursor: 'default',
|
|
@@ -72,63 +73,7 @@ export const UserBadge = ({ token, variant = 'full', showExpandToggle = true, ex
|
|
|
72
73
|
borderColor: 'border.muted',
|
|
73
74
|
pb: '1px',
|
|
74
75
|
userSelect: 'none',
|
|
75
|
-
}, children: displayName }), open && claims && (_jsxs(Box, { sx: {
|
|
76
|
-
position: 'absolute',
|
|
77
|
-
top: 'calc(100% + 4px)',
|
|
78
|
-
right: 0,
|
|
79
|
-
zIndex: 100,
|
|
80
|
-
width: '400px',
|
|
81
|
-
bg: 'canvas.overlay',
|
|
82
|
-
border: '1px solid',
|
|
83
|
-
borderColor: 'border.default',
|
|
84
|
-
borderRadius: 2,
|
|
85
|
-
boxShadow: 'shadow.large',
|
|
86
|
-
overflow: 'hidden',
|
|
87
|
-
}, children: [_jsxs(Box, { sx: {
|
|
88
|
-
px: 3,
|
|
89
|
-
py: 2,
|
|
90
|
-
bg: 'canvas.inset',
|
|
91
|
-
borderBottom: '1px solid',
|
|
92
|
-
borderColor: 'border.default',
|
|
93
|
-
display: 'flex',
|
|
94
|
-
alignItems: 'center',
|
|
95
|
-
justifyContent: 'space-between',
|
|
96
|
-
gap: 2,
|
|
97
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: popoverDisplayName || 'User' }), variant === 'small' && showExpandToggle && (_jsx(Box, { as: "button", type: "button", onClick: () => setExpanded(v => !v), "aria-label": expanded ? 'Hide full JWT claims' : 'Show full JWT claims', "aria-expanded": expanded, title: expanded ? 'Hide full JWT claims' : 'Show full JWT claims', sx: {
|
|
98
|
-
appearance: 'none',
|
|
99
|
-
border: '1px solid',
|
|
100
|
-
borderColor: 'border.default',
|
|
101
|
-
borderRadius: 1,
|
|
102
|
-
bg: 'canvas.default',
|
|
103
|
-
color: 'fg.default',
|
|
104
|
-
fontSize: 1,
|
|
105
|
-
lineHeight: 1,
|
|
106
|
-
width: '20px',
|
|
107
|
-
height: '20px',
|
|
108
|
-
display: 'inline-flex',
|
|
109
|
-
alignItems: 'center',
|
|
110
|
-
justifyContent: 'center',
|
|
111
|
-
cursor: 'pointer',
|
|
112
|
-
p: 0,
|
|
113
|
-
'&:hover': {
|
|
114
|
-
bg: 'canvas.subtle',
|
|
115
|
-
},
|
|
116
|
-
}, children: expanded ? '−' : '+' }))] }), claims.user && (_jsx(Box, { sx: {
|
|
117
|
-
px: 3,
|
|
118
|
-
py: 2,
|
|
119
|
-
borderBottom: '1px solid',
|
|
120
|
-
borderColor: 'border.muted',
|
|
121
|
-
}, children: _jsxs(Box, { sx: {
|
|
122
|
-
display: 'grid',
|
|
123
|
-
gridTemplateColumns: '90px 1fr',
|
|
124
|
-
gap: 1,
|
|
125
|
-
fontSize: 0,
|
|
126
|
-
}, children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "First name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.firstName }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Last name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.lastName }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Display name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: getDatalayerDisplayName(claims.user, claims.user.handle) }), claims.user.email && (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "Email" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.email })] })), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Handle" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.handle }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "UID" }), _jsx(Text, { sx: { fontFamily: 'mono', wordBreak: 'break-all' }, children: claims.user.uid }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Issued" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: new Date(claims.iat * 1000).toISOString() }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Expires" }), _jsxs(Box, { sx: {
|
|
127
|
-
display: 'flex',
|
|
128
|
-
alignItems: 'center',
|
|
129
|
-
gap: 2,
|
|
130
|
-
minWidth: 0,
|
|
131
|
-
}, children: [_jsx(Text, { sx: {
|
|
76
|
+
}, children: displayName }), open && claims && (_jsxs(Box, { position: "absolute", top: "calc(100% + 4px)", right: 0, zIndex: 100, width: "400px", bg: "canvas.overlay", border: "1px solid", borderColor: "border.default", borderRadius: 2, boxShadow: "shadow.large", overflow: "hidden", children: [_jsxs(Box, { px: 3, py: 2, bg: "canvas.inset", borderBottom: "1px solid", borderColor: "border.default", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: popoverDisplayName || 'User' }), variant === 'small' && showExpandToggle && (_jsx(Box, { as: "button", type: "button", onClick: () => setExpanded(v => !v), "aria-label": expanded ? 'Hide full JWT claims' : 'Show full JWT claims', "aria-expanded": expanded, title: expanded ? 'Hide full JWT claims' : 'Show full JWT claims', appearance: "none", border: "1px solid", borderColor: "border.default", borderRadius: 1, bg: "canvas.default", color: "fg.default", fontSize: 1, lineHeight: 1, width: "20px", height: "20px", display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer", p: 0, hover: { bg: 'canvas.subtle' }, children: expanded ? '−' : '+' }))] }), claims.user && (_jsx(Box, { px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.muted", children: _jsxs(Box, { display: "grid", gridTemplateColumns: "90px 1fr", gap: 1, fontSize: 0, children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "First name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.firstName }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Last name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.lastName }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Display name" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: getDatalayerDisplayName(claims.user, claims.user.handle) }), claims.user.email && (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "Email" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.email })] })), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Handle" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: claims.user.handle }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "UID" }), _jsx(Text, { sx: { fontFamily: 'mono', wordBreak: 'break-all' }, children: claims.user.uid }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Issued" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: new Date(claims.iat * 1000).toISOString() }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Expires" }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, minWidth: 0, children: [_jsx(Text, { sx: {
|
|
132
77
|
fontFamily: 'mono',
|
|
133
78
|
overflow: 'hidden',
|
|
134
79
|
textOverflow: 'ellipsis',
|
|
@@ -153,44 +98,7 @@ export const UserBadge = ({ token, variant = 'full', showExpandToggle = true, ex
|
|
|
153
98
|
: warning
|
|
154
99
|
? 'attention.muted'
|
|
155
100
|
: 'success.muted';
|
|
156
|
-
return (_jsx(Box, {
|
|
157
|
-
|
|
158
|
-
fontSize: 0,
|
|
159
|
-
px: 1,
|
|
160
|
-
py: '1px',
|
|
161
|
-
bg,
|
|
162
|
-
color: fg,
|
|
163
|
-
borderRadius: 1,
|
|
164
|
-
border: '1px solid',
|
|
165
|
-
borderColor: border,
|
|
166
|
-
whiteSpace: 'nowrap',
|
|
167
|
-
}, children: getRelativeTime(expDate) }));
|
|
168
|
-
})()] })] }) })), (claims.user?.roles ?? claims.roles ?? []).length > 0 && (_jsxs(Box, { sx: {
|
|
169
|
-
px: 3,
|
|
170
|
-
py: 2,
|
|
171
|
-
borderBottom: '1px solid',
|
|
172
|
-
borderColor: 'border.muted',
|
|
173
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block', mb: 1 }, children: "Roles" }), _jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: (claims.user?.roles ?? claims.roles ?? []).map(r => (_jsx(Box, { sx: {
|
|
174
|
-
fontSize: 0,
|
|
175
|
-
fontFamily: 'mono',
|
|
176
|
-
px: 1,
|
|
177
|
-
py: '1px',
|
|
178
|
-
bg: 'accent.subtle',
|
|
179
|
-
color: 'accent.fg',
|
|
180
|
-
borderRadius: 1,
|
|
181
|
-
border: '1px solid',
|
|
182
|
-
borderColor: 'accent.muted',
|
|
183
|
-
}, children: r }, r))) })] })), (variant === 'full' || expanded) && (_jsx(Box, { as: "pre", sx: {
|
|
184
|
-
m: 0,
|
|
185
|
-
px: 3,
|
|
186
|
-
py: 2,
|
|
187
|
-
fontFamily: 'mono',
|
|
188
|
-
fontSize: 0,
|
|
189
|
-
color: 'fg.default',
|
|
190
|
-
bg: 'canvas.inset',
|
|
191
|
-
overflow: 'auto',
|
|
192
|
-
maxHeight: '220px',
|
|
193
|
-
whiteSpace: 'pre',
|
|
194
|
-
}, children: JSON.stringify(claims, null, 2) }))] }))] }));
|
|
101
|
+
return (_jsx(Box, { flexShrink: 0, fontSize: 0, px: 1, py: "1px", bg: bg, color: fg, borderRadius: 1, border: "1px solid", borderColor: border, whiteSpace: "nowrap", children: getRelativeTime(expDate) }));
|
|
102
|
+
})()] })] }) })), (claims.user?.roles ?? claims.roles ?? []).length > 0 && (_jsxs(Box, { px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.muted", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block', mb: 1 }, children: "Roles" }), _jsx(Box, { display: "flex", flexWrap: "wrap", gap: 1, children: (claims.user?.roles ?? claims.roles ?? []).map(r => (_jsx(Box, { fontSize: 0, fontFamily: "mono", px: 1, py: "1px", bg: "accent.subtle", color: "accent.fg", borderRadius: 1, border: "1px solid", borderColor: "accent.muted", children: r }, r))) })] })), (variant === 'full' || expanded) && (_jsx(Box, { as: "pre", m: 0, px: 3, py: 2, fontFamily: "mono", fontSize: 0, color: "fg.default", bg: "canvas.inset", overflow: "auto", maxHeight: "220px", whiteSpace: "pre", children: JSON.stringify(claims, null, 2) }))] }))] }));
|
|
195
103
|
};
|
|
196
104
|
export default UserBadge;
|
|
@@ -131,20 +131,11 @@ export const SecretEdit = ({ secretsListRoute = '/settings/secrets', } = {}) =>
|
|
|
131
131
|
};
|
|
132
132
|
return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { children: _jsx(Heading, { sx: { fontSize: 3 }, children: "Secret" }) }), _jsxs(Box, { display: "flex", children: [_jsxs(Box, { children: [_jsx(BoringAvatar, { displayName: secret?.name, size: 100, style: { paddingRight: 10 } }), _jsx(Text, { as: "h2", sx: { paddingTop: 3 }, children: secret?.name }), _jsx(Box, { mt: 3, children: _jsx(Label, { size: "large", children: secret?.variant }) })] }), _jsxs(Box, { ml: 10, children: [_jsxs(Box, { sx: { label: { marginTop: 2 } }, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: formValues.name, onChange: secretNameChanged }), validationResult.name === false && (_jsx(FormControl.Validation, { variant: "error", children: "Name must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, value: formValues.description, onChange: secretDescriptionChanged, rows: 5 }), validationResult.description === false && (_jsx(FormControl.Validation, { variant: "error", children: "Description must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Value" }), _jsx(TextInput, { placeholder: "Value", monospace: true, size: "large", contrast: !passwordVisible, disabled: !passwordVisible, onChange: secretValueChanged, type: passwordVisible ? 'text' : 'password', value: formValues.value, trailingAction: _jsx(TextInput.Action, { onClick: () => {
|
|
133
133
|
setPasswordVisible(!passwordVisible);
|
|
134
|
-
}, icon: passwordVisible ? EyeClosedIcon : EyeIcon, "aria-label": passwordVisible ? 'Hide secret' : 'Reveal secret', sx: { color: 'var(--fgColor-muted)' } }), sx: { overflow: 'visible' } }), validationResult.value === false && (_jsx(FormControl.Validation, { variant: "error", children: "Value must have more than 1 and less than 4096 characters." }))] }), _jsx(Box, {
|
|
134
|
+
}, icon: passwordVisible ? EyeClosedIcon : EyeIcon, "aria-label": passwordVisible ? 'Hide secret' : 'Reveal secret', sx: { color: 'var(--fgColor-muted)' } }), sx: { overflow: 'visible' } }), validationResult.value === false && (_jsx(FormControl.Validation, { variant: "error", children: "Value must have more than 1 and less than 4096 characters." }))] }), _jsx(Box, { marginTop: 3, children: _jsx(Button, { variant: "primary", disabled: !validationResult.name || !validationResult.description, onClick: submitUpdate, children: "Update secret" }) })] }), _jsxs(Box, { marginTop: 3, children: [_jsx(Heading, { as: "h2", sx: {
|
|
135
135
|
fontSize: 4,
|
|
136
136
|
fontWeight: 'normal',
|
|
137
137
|
color: 'danger.fg',
|
|
138
138
|
mb: 2,
|
|
139
|
-
}, children: "Danger zone" }), _jsxs(Box, { sx: {
|
|
140
|
-
border: '1px solid',
|
|
141
|
-
borderColor: 'danger.emphasis',
|
|
142
|
-
borderRadius: 2,
|
|
143
|
-
p: 3,
|
|
144
|
-
display: 'flex',
|
|
145
|
-
alignItems: 'center',
|
|
146
|
-
justifyContent: 'space-between',
|
|
147
|
-
gap: 3,
|
|
148
|
-
}, children: [_jsxs(Box, { sx: { display: 'grid', gap: 1 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'danger.fg' }, children: "Confirm the secret name to delete" }), _jsx(FormControl, { children: _jsx(TextInput, { block: true, value: formValues.nameConfirm, onChange: secretNameConfirmChanged }) }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "This operation is not reversible." })] }), _jsx(Button, { variant: "danger", disabled: !validationResult.nameConfirm, onClick: submitDelete, children: "Delete secret" })] })] })] })] })] }));
|
|
139
|
+
}, children: "Danger zone" }), _jsxs(Box, { border: "1px solid", borderColor: "danger.emphasis", borderRadius: 2, p: 3, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 3, children: [_jsxs(Box, { display: "grid", gap: 1, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'danger.fg' }, children: "Confirm the secret name to delete" }), _jsx(FormControl, { children: _jsx(TextInput, { block: true, value: formValues.nameConfirm, onChange: secretNameConfirmChanged }) }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "This operation is not reversible." })] }), _jsx(Button, { variant: "danger", disabled: !validationResult.nameConfirm, onClick: submitDelete, children: "Delete secret" })] })] })] })] })] }));
|
|
149
140
|
};
|
|
150
141
|
export default SecretEdit;
|
|
@@ -93,7 +93,7 @@ export const SecretNew = ({ secretsListRoute = '/settings/secrets', } = {}) => {
|
|
|
93
93
|
},
|
|
94
94
|
});
|
|
95
95
|
};
|
|
96
|
-
return (_jsxs(Box, { children: [_jsx(PageHeader, { children: _jsx(PageHeader.TitleArea, { variant: "large", children: _jsx(PageHeader.Title, { children: "New Secret" }) }) }), _jsx(Box, { display: "grid", gridTemplateColumns: "1fr 1fr",
|
|
96
|
+
return (_jsxs(Box, { children: [_jsx(PageHeader, { children: _jsx(PageHeader.TitleArea, { variant: "large", children: _jsx(PageHeader.Title, { children: "New Secret" }) }) }), _jsx(Box, { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 3, children: _jsx(Box, { children: _jsxs(Box, { sx: { label: { marginTop: 2 } }, children: [_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Secret type" }), _jsxs(Select, { name: "type", value: formValues.variant, onChange: secretVariantChanged, children: [_jsx(Select.Option, { value: "generic", children: "Generic" }), _jsx(Select.Option, { value: "password", children: "Password" }), _jsx(Select.Option, { value: "key", children: "Key" }), _jsx(Select.Option, { value: "token", children: "Token" })] }), _jsx(FormControl.Caption, { children: "Pick the most appropriate secret type." })] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: formValues.name, onChange: secretNameChanged, autoFocus: true }), _jsx(FormControl.Caption, { children: "Hint: The secret name is a short name that identifies in a unique way your secret." }), validationResult.name === false && (_jsx(FormControl.Validation, { variant: "error", children: "Name length must be between 2 and 32 characters." }))] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, value: formValues.description, onChange: secretDescriptionChanged, rows: 3 }), validationResult.description === false && (_jsx(FormControl.Validation, { variant: "error", children: "Description must have more than 2 characters." }))] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Value" }), _jsx(Textarea, { block: true, value: formValues.value, onChange: secretValueChanged, rows: 5 }), validationResult.value === false && (_jsx(FormControl.Validation, { variant: "error", children: "Value must have more than 1 and less than 4096 characters." }))] }), _jsx(Button, { variant: "primary", disabled: !validationResult.value ||
|
|
97
97
|
!validationResult.name ||
|
|
98
98
|
!validationResult.description, sx: { marginTop: 2 }, onClick: e => {
|
|
99
99
|
e.preventDefault();
|