@datalayer/core 1.2.18 → 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/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 +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
|
@@ -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 { Text } from '@primer/react';
|
|
3
4
|
const statusStyles = {
|
|
4
5
|
done: {
|
|
5
6
|
dotBackground: 'success.emphasis',
|
|
@@ -42,44 +43,11 @@ export const Timeline = ({ items, renderTimestamp }) => {
|
|
|
42
43
|
if (!items.length) {
|
|
43
44
|
return null;
|
|
44
45
|
}
|
|
45
|
-
return (_jsx(Box, {
|
|
46
|
-
overflowX: 'auto',
|
|
47
|
-
pb: 1,
|
|
48
|
-
}, children: _jsx(Box, { sx: {
|
|
49
|
-
display: 'flex',
|
|
50
|
-
alignItems: 'stretch',
|
|
51
|
-
minWidth: 'max-content',
|
|
52
|
-
}, children: items.map((item, index) => {
|
|
46
|
+
return (_jsx(Box, { overflowX: "auto", pb: 1, children: _jsx(Box, { display: "flex", alignItems: "stretch", minWidth: "max-content", children: items.map((item, index) => {
|
|
53
47
|
const status = item.status || 'neutral';
|
|
54
48
|
const style = statusStyles[status];
|
|
55
49
|
const hasNext = index < items.length - 1;
|
|
56
|
-
return (_jsxs(Box, { sx: {
|
|
57
|
-
display: 'flex',
|
|
58
|
-
flexDirection: 'column',
|
|
59
|
-
minWidth: 220,
|
|
60
|
-
flex: hasNext ? '0 0 220px' : '0 0 auto',
|
|
61
|
-
pr: hasNext ? 0 : 1,
|
|
62
|
-
}, children: [_jsxs(Box, { sx: {
|
|
63
|
-
display: 'flex',
|
|
64
|
-
alignItems: 'center',
|
|
65
|
-
minHeight: 28,
|
|
66
|
-
mb: 2,
|
|
67
|
-
}, children: [_jsx(Box, { sx: {
|
|
68
|
-
width: 16,
|
|
69
|
-
height: 16,
|
|
70
|
-
borderRadius: '50%',
|
|
71
|
-
border: '2px solid',
|
|
72
|
-
borderColor: style.dotBorder,
|
|
73
|
-
bg: style.dotBackground,
|
|
74
|
-
boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.2)',
|
|
75
|
-
} }), hasNext ? (_jsx(Box, { sx: {
|
|
76
|
-
flex: 1,
|
|
77
|
-
height: 4,
|
|
78
|
-
ml: 2,
|
|
79
|
-
mr: 2,
|
|
80
|
-
borderRadius: 999,
|
|
81
|
-
bg: style.lineColor,
|
|
82
|
-
} })) : null] }), _jsx(Text, { as: "p", sx: { fontWeight: 600, color: style.titleColor, mb: 1 }, children: item.title }), _jsx(Text, { as: "p", sx: {
|
|
50
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", minWidth: 220, flex: hasNext ? '0 0 220px' : '0 0 auto', pr: hasNext ? 0 : 1, children: [_jsxs(Box, { display: "flex", alignItems: "center", minHeight: 28, mb: 2, children: [_jsx(Box, { width: 16, height: 16, borderRadius: "50%", border: "2px solid", borderColor: style.dotBorder, bg: style.dotBackground, boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.2)" }), hasNext ? (_jsx(Box, { flex: 1, height: 4, ml: 2, mr: 2, borderRadius: 999, bg: style.lineColor })) : null] }), _jsx(Text, { as: "p", sx: { fontWeight: 600, color: style.titleColor, mb: 1 }, children: item.title }), _jsx(Text, { as: "p", sx: {
|
|
83
51
|
fontSize: 0,
|
|
84
52
|
color: 'fg.muted',
|
|
85
53
|
mb: item.subtitle ? 1 : 0,
|
|
@@ -4,7 +4,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useEffect } from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { Heading, Spinner } from '@primer/react';
|
|
8
9
|
import { useBackdrop } from '../index.js';
|
|
9
10
|
import { useLayoutStore } from '../../state/index.js';
|
|
10
11
|
const BackdropContent = (props) => {
|
|
@@ -4,7 +4,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useEffect } from 'react';
|
|
7
|
-
import { Box } from '@primer
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
8
|
import { useScreencapture, useToast } from '../index.js';
|
|
9
9
|
import { lazyWithPreload, WithSuspense } from '../../utils/index.js';
|
|
10
10
|
import { useLayoutStore } from '../../state/index.js';
|
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
* projection carries them: `face_s` (the JSON of its `id`, `emoji`, `avatar`
|
|
7
7
|
* and `banner`, each only when set), `app_kind_s` and `runs_live_b` — an app
|
|
8
8
|
* that runs live can be tried before it is cloned: not a decision, and naming
|
|
9
|
-
* the agent it runs on.
|
|
9
|
+
* the agent it runs on. One of Datalayer's examples, published from the
|
|
10
|
+
* catalogue, also says which (`catalogue_example_s`), beside `publisher_s:
|
|
11
|
+
* datalayer` — the Library projects both only for an item of the `datalayer`
|
|
12
|
+
* organization's spaces whose metadata says `catalogueExample` (STUDIO E-10).
|
|
10
13
|
*
|
|
11
14
|
* @module hooks/libraryApp
|
|
12
15
|
*/
|
|
@@ -30,6 +33,8 @@ export type LibraryAppFields = {
|
|
|
30
33
|
appKind?: LibraryAppKind;
|
|
31
34
|
/** Whether it can be tried before it is cloned. */
|
|
32
35
|
runsLive: boolean;
|
|
36
|
+
/** The example of the catalogue it is, when it is one of Datalayer's. */
|
|
37
|
+
catalogueExample?: string;
|
|
33
38
|
};
|
|
34
39
|
/** The face `face_s` carries; a value that is not a face's JSON is refused. */
|
|
35
40
|
export declare function libraryAppFaceOf(value: unknown): LibraryAppFace | undefined;
|
package/lib/hooks/libraryApp.js
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* projection carries them: `face_s` (the JSON of its `id`, `emoji`, `avatar`
|
|
11
11
|
* and `banner`, each only when set), `app_kind_s` and `runs_live_b` — an app
|
|
12
12
|
* that runs live can be tried before it is cloned: not a decision, and naming
|
|
13
|
-
* the agent it runs on.
|
|
13
|
+
* the agent it runs on. One of Datalayer's examples, published from the
|
|
14
|
+
* catalogue, also says which (`catalogue_example_s`), beside `publisher_s:
|
|
15
|
+
* datalayer` — the Library projects both only for an item of the `datalayer`
|
|
16
|
+
* organization's spaces whose metadata says `catalogueExample` (STUDIO E-10).
|
|
14
17
|
*
|
|
15
18
|
* @module hooks/libraryApp
|
|
16
19
|
*/
|
|
@@ -50,10 +53,16 @@ export function libraryAppFieldsOf(raw) {
|
|
|
50
53
|
!LIBRARY_APP_KINDS.includes(kind)) {
|
|
51
54
|
throw new Error(`An app's kind is not one of ${LIBRARY_APP_KINDS}: ${String(kind)}`);
|
|
52
55
|
}
|
|
56
|
+
const example = raw.catalogue_example_s;
|
|
57
|
+
if (example !== undefined &&
|
|
58
|
+
(typeof example !== 'string' || example.trim() === '')) {
|
|
59
|
+
throw new Error(`An app's example is not an example's id: ${String(example)}`);
|
|
60
|
+
}
|
|
53
61
|
const face = libraryAppFaceOf(raw.face_s);
|
|
54
62
|
return {
|
|
55
63
|
...(face ? { face } : {}),
|
|
56
64
|
...(kind ? { appKind: kind } : {}),
|
|
57
65
|
runsLive: raw.runs_live_b === true,
|
|
66
|
+
...(example ? { catalogueExample: example } : {}),
|
|
58
67
|
};
|
|
59
68
|
}
|
|
@@ -35,8 +35,13 @@ export const useAuthorization = () => {
|
|
|
35
35
|
const checkIsPlatformMember = (user) => {
|
|
36
36
|
return user.roles.includes(PlatformRoles.Member.handle);
|
|
37
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Whether the user sees the features that are not released yet: a Platform
|
|
40
|
+
* Features Previewer, or a Platform Admin — an admin previews everything.
|
|
41
|
+
*/
|
|
38
42
|
const checkIsPlatformFeaturesPreviewer = (user) => {
|
|
39
|
-
return user.roles.includes(PlatformRoles.FeaturesPreviewer.handle)
|
|
43
|
+
return (user.roles.includes(PlatformRoles.FeaturesPreviewer.handle) ||
|
|
44
|
+
checkIsPlatformAdmin(user));
|
|
40
45
|
};
|
|
41
46
|
const checkIsPlatformUsageReviewer = (user) => {
|
|
42
47
|
return user.roles.includes(PlatformRoles.UsageReviewer.handle);
|
|
@@ -4,16 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { AlertIcon } from '@primer/octicons-react';
|
|
7
|
-
import { Box
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { Button, Flash } from '@primer/react';
|
|
8
9
|
import { useNavigate } from '../../hooks/index.js';
|
|
9
10
|
export const FlashMock = () => {
|
|
10
11
|
const navigate = useNavigate();
|
|
11
|
-
return (_jsx(Flash, { variant: "warning", style: { marginBottom: 10 }, children: _jsxs(Box, {
|
|
12
|
-
display: 'flex',
|
|
13
|
-
alignItems: 'center',
|
|
14
|
-
justifyContent: 'space-between',
|
|
15
|
-
gap: 3,
|
|
16
|
-
width: '100%',
|
|
17
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(AlertIcon, {}), _jsx("span", { children: "This is placeholder content. Contact us to learn more about this feature." })] }), _jsx(Button, { size: "small", onClick: () => navigate('/contact'), children: "Contact Us" })] }) }));
|
|
12
|
+
return (_jsx(Flash, { variant: "warning", style: { marginBottom: 10 }, children: _jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 3, width: "100%", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(AlertIcon, {}), _jsx("span", { children: "This is placeholder content. Contact us to learn more about this feature." })] }), _jsx(Button, { size: "small", onClick: () => navigate('/contact'), children: "Contact Us" })] }) }));
|
|
18
13
|
};
|
|
19
14
|
export default FlashMock;
|
|
@@ -3,36 +3,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { Box
|
|
6
|
+
import { Box } from '@datalayer/primer-addons';
|
|
7
|
+
import { Link, Text, LabelGroup, Label, ActionMenu, ActionList, } from '@primer/react';
|
|
7
8
|
import { ArrowRightIcon, CloudIcon, StarIcon, DotFillIcon, RepoForkedIcon, LinkIcon, } from '@primer/octicons-react';
|
|
8
9
|
import { ReactJsIcon } from '@datalayer/icons-react';
|
|
9
10
|
import { lazyWithPreload, WithSuspense } from '../../utils/index.js';
|
|
10
11
|
import { ECHART_MOCK_1, ECHART_MOCK_2, ECHART_MOCK_3, FlashMock, } from '../../mocks/index.js';
|
|
11
12
|
const ReactECharts = WithSuspense(lazyWithPreload(() => import('echarts-for-react')), true);
|
|
12
13
|
export const DashboardMock = () => {
|
|
13
|
-
return (_jsxs(_Fragment, { children: [_jsx(Box, { mb: 3, children: _jsx(FlashMock, {}) }), _jsxs(Box, { sx: {
|
|
14
|
-
display: 'grid',
|
|
15
|
-
gridTemplateColumns: '1fr 1fr 1fr',
|
|
16
|
-
gap: 4,
|
|
17
|
-
}, children: [_jsxs(Box, { sx: {
|
|
18
|
-
gridColumn: '1 / 3',
|
|
19
|
-
minHeight: '200px',
|
|
20
|
-
}, children: [_jsxs(Box, { sx: {
|
|
21
|
-
display: 'flex',
|
|
22
|
-
alignItems: 'center',
|
|
23
|
-
justifyContent: 'space-between',
|
|
24
|
-
paddingRight: 4,
|
|
25
|
-
}, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "My latest work" }), _jsxs(Link, { children: ["View all work", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { sx: {
|
|
26
|
-
display: 'grid',
|
|
27
|
-
gridTemplateColumns: '1fr 1fr',
|
|
28
|
-
gap: 4,
|
|
29
|
-
}, children: [_jsxs(Box, { sx: {
|
|
30
|
-
borderColor: 'border.default',
|
|
31
|
-
borderStyle: 'solid',
|
|
32
|
-
borderWidth: '1',
|
|
33
|
-
borderRadius: '2',
|
|
34
|
-
padding: 4,
|
|
35
|
-
}, children: [_jsxs(Text, { as: "h3", sx: { paddingBottom: 2 }, children: ["clouder ", _jsx(Label, { children: "Public" })] }), _jsxs(Text, { as: "p", sx: { color: 'fg.subtle', fontWeight: 'semibold' }, children: [_jsx(CloudIcon
|
|
14
|
+
return (_jsxs(_Fragment, { children: [_jsx(Box, { mb: 3, children: _jsx(FlashMock, {}) }), _jsxs(Box, { display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 4, children: [_jsxs(Box, { gridColumn: "1 / 3", minHeight: "200px", children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", paddingRight: 4, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "My latest work" }), _jsxs(Link, { children: ["View all work", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4, children: [_jsxs(Box, { borderColor: "border.default", borderStyle: "solid", borderWidth: "1", borderRadius: "2", padding: 4, children: [_jsxs(Text, { as: "h3", sx: { paddingBottom: 2 }, children: ["clouder ", _jsx(Label, { children: "Public" })] }), _jsxs(Text, { as: "p", sx: { color: 'fg.subtle', fontWeight: 'semibold' }, children: [_jsx(CloudIcon
|
|
36
15
|
// sx={{ margin: "0 4px" }}
|
|
37
16
|
, {}), "Create, manage and share Kubernetes clusters."] }), _jsxs(LabelGroup, { sx: { paddingTop: 2, paddingBottom: 2 }, children: [_jsx(Label, { variant: "accent", children: "Kubernetes" }), _jsx(Label, { variant: "accent", children: "cloud" }), _jsx(Label, { variant: "accent", children: "kubernets-cluster" }), _jsx(Label, { variant: "accent", children: "datalayer" })] }), _jsxs(Text, { as: "p", sx: {
|
|
38
17
|
color: 'fg.subtle',
|
|
@@ -47,13 +26,7 @@ export const DashboardMock = () => {
|
|
|
47
26
|
// sx={{ marginRight: 1, marginBottom: "3px" }}
|
|
48
27
|
, {}), "3"] }), _jsxs(Text, { children: [_jsx(StarIcon
|
|
49
28
|
// sx={{ marginRight: 1, marginBottom: "3px" }}
|
|
50
|
-
, {}), "11"] })] })] }), _jsxs(Box, { sx: {
|
|
51
|
-
borderColor: 'border.default',
|
|
52
|
-
borderStyle: 'solid',
|
|
53
|
-
borderWidth: '1',
|
|
54
|
-
borderRadius: '2',
|
|
55
|
-
padding: 4,
|
|
56
|
-
}, children: [_jsxs(Text, { as: "h3", sx: { paddingBottom: 2 }, children: ["jupyter-ui ", _jsx(Label, { children: "Public" })] }), _jsxs(Text, { as: "p", children: [_jsx(ReactJsIcon, { style: { margin: '0 4px' } }), "React.js components 100% compatible with Jupyter.", ' ', _jsx(Link, { href: "https://jupyter-ui-storybook.datalayer.tech", children: "https://jupyter-ui-storybook.datalayer.tech" })] }), _jsxs(LabelGroup, { sx: { paddingTop: 2, paddingBottom: 2 }, children: [_jsx(Label, { variant: "accent", children: "data-science" }), _jsx(Label, { variant: "accent", children: "data" }), _jsx(Label, { variant: "accent", children: "ui" }), _jsx(Label, { variant: "accent", children: "jupyter" }), _jsx(Label, { children: "+4" })] }), _jsxs(Text, { as: "p", sx: {
|
|
29
|
+
, {}), "11"] })] })] }), _jsxs(Box, { borderColor: "border.default", borderStyle: "solid", borderWidth: "1", borderRadius: "2", padding: 4, children: [_jsxs(Text, { as: "h3", sx: { paddingBottom: 2 }, children: ["jupyter-ui ", _jsx(Label, { children: "Public" })] }), _jsxs(Text, { as: "p", children: [_jsx(ReactJsIcon, { style: { margin: '0 4px' } }), "React.js components 100% compatible with Jupyter.", ' ', _jsx(Link, { href: "https://jupyter-ui-storybook.datalayer.tech", children: "https://jupyter-ui-storybook.datalayer.tech" })] }), _jsxs(LabelGroup, { sx: { paddingTop: 2, paddingBottom: 2 }, children: [_jsx(Label, { variant: "accent", children: "data-science" }), _jsx(Label, { variant: "accent", children: "data" }), _jsx(Label, { variant: "accent", children: "ui" }), _jsx(Label, { variant: "accent", children: "jupyter" }), _jsx(Label, { children: "+4" })] }), _jsxs(Text, { as: "p", sx: {
|
|
57
30
|
color: 'fg.subtle',
|
|
58
31
|
'> *': { paddingLeft: 1, paddingRight: 1 },
|
|
59
32
|
}, children: [_jsxs(Text, { children: [_jsx(DotFillIcon
|
|
@@ -68,51 +41,12 @@ export const DashboardMock = () => {
|
|
|
68
41
|
// sx={{ marginRight: 1, marginBottom: "3px" }}
|
|
69
42
|
, {}), "3"] }), _jsxs(Text, { children: [_jsx(StarIcon
|
|
70
43
|
// sx={{ marginRight: 1, marginBottom: "3px" }}
|
|
71
|
-
, {}), "11"] })] })] })] })] }), _jsxs(Box, { sx: {
|
|
72
|
-
gridColumn: '3 / 4',
|
|
73
|
-
gridRow: '1 / 3',
|
|
74
|
-
minHeight: '200px',
|
|
75
|
-
}, children: [_jsxs(Box, { sx: {
|
|
76
|
-
display: 'flex',
|
|
77
|
-
alignItems: 'center',
|
|
78
|
-
justifyContent: 'space-between',
|
|
79
|
-
paddingRight: 4,
|
|
80
|
-
}, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "Usage" }), _jsxs(Link, { children: ["More Usage", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { sx: {
|
|
81
|
-
borderColor: 'border.default',
|
|
82
|
-
borderStyle: 'solid',
|
|
83
|
-
borderWidth: '1',
|
|
84
|
-
borderRadius: '2',
|
|
85
|
-
padding: 4,
|
|
86
|
-
}, children: [_jsxs(Box, { sx: {
|
|
87
|
-
display: 'inline-flex',
|
|
88
|
-
flexDirection: 'row',
|
|
89
|
-
alignItems: 'center',
|
|
90
|
-
}, children: [_jsx(Text, { as: "h3", sx: { marginRight: '20px' }, children: "Kernels Activity" }), _jsxs(ActionMenu, { children: [_jsxs(ActionMenu.Button, { children: [_jsx(Box, { sx: { color: 'fg.muted', display: 'inline-block' }, children: "View:" }), ' ', 'All kernels'] }), _jsx(ActionMenu.Overlay, { width: "auto", children: _jsx(ActionList, { selectionVariant: "single", children: _jsx(ActionList.Item, { selected: true, children: "All kernels" }) }) })] })] }), _jsx(Text, { as: "h3", children: "Credits usage" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle' }, children: "Amount today" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle' }, children: "Balance yesterday" }), _jsx(Text, { as: "h3", children: "Last invoice" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle', fontSize: '3', fontWeight: 'bold' }, children: "$216" })] })] }), _jsxs(Box, { sx: {
|
|
91
|
-
gridColumn: '1 / 3',
|
|
92
|
-
minHeight: '200px',
|
|
93
|
-
}, children: [_jsxs(Box, { sx: {
|
|
94
|
-
display: 'flex',
|
|
95
|
-
alignItems: 'center',
|
|
96
|
-
justifyContent: 'space-between',
|
|
97
|
-
paddingRight: 4,
|
|
98
|
-
}, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "Trending Notebooks" }), _jsxs(Link, { children: ["All Notebooks", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { sx: {
|
|
99
|
-
borderColor: 'border.default',
|
|
100
|
-
borderStyle: 'solid',
|
|
101
|
-
borderWidth: '1',
|
|
102
|
-
borderRadius: '2',
|
|
103
|
-
display: 'grid',
|
|
104
|
-
gridTemplateColumns: '1fr 1fr',
|
|
44
|
+
, {}), "11"] })] })] })] })] }), _jsxs(Box, { gridColumn: "3 / 4", gridRow: "1 / 3", minHeight: "200px", children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", paddingRight: 4, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "Usage" }), _jsxs(Link, { children: ["More Usage", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { borderColor: "border.default", borderStyle: "solid", borderWidth: "1", borderRadius: "2", padding: 4, children: [_jsxs(Box, { display: "inline-flex", flexDirection: "row", alignItems: "center", children: [_jsx(Text, { as: "h3", sx: { marginRight: '20px' }, children: "Kernels Activity" }), _jsxs(ActionMenu, { children: [_jsxs(ActionMenu.Button, { children: [_jsx(Box, { color: "fg.muted", display: "inline-block", children: "View:" }), ' ', 'All kernels'] }), _jsx(ActionMenu.Overlay, { width: "auto", children: _jsx(ActionList, { selectionVariant: "single", children: _jsx(ActionList.Item, { selected: true, children: "All kernels" }) }) })] })] }), _jsx(Text, { as: "h3", children: "Credits usage" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle' }, children: "Amount today" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle' }, children: "Balance yesterday" }), _jsx(Text, { as: "h3", children: "Last invoice" }), _jsx(Text, { as: "p", sx: { color: 'fg.subtle', fontSize: '3', fontWeight: 'bold' }, children: "$216" })] })] }), _jsxs(Box, { gridColumn: "1 / 3", minHeight: "200px", children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", paddingRight: 4, children: [_jsx(Text, { as: "h2", sx: { borderLeft: '4px solid #28b899', paddingLeft: 2 }, children: "Trending Notebooks" }), _jsxs(Link, { children: ["All Notebooks", _jsx(ArrowRightIcon, {})] })] }), _jsxs(Box, { borderColor: "border.default", borderStyle: "solid", borderWidth: "1", borderRadius: "2", display: "grid", gridTemplateColumns: "1fr 1fr", sx: {
|
|
105
45
|
'> :not(:last-child)': {
|
|
106
46
|
borderRightColor: 'border.default',
|
|
107
47
|
borderRightStyle: 'solid',
|
|
108
48
|
borderRightWidth: '1',
|
|
109
49
|
},
|
|
110
|
-
}, children: [_jsxs(Box, { sx: {
|
|
111
|
-
padding: 4,
|
|
112
|
-
}, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { sx: { height: '300px', maxWidth: '380px' }, children: [_jsx(ReactECharts, { option: ECHART_MOCK_1 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] }), _jsxs(Box, { sx: {
|
|
113
|
-
padding: 4,
|
|
114
|
-
}, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { sx: { height: '300px', maxWidth: '380px' }, children: [_jsx(ReactECharts, { option: ECHART_MOCK_3 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] }), _jsxs(Box, { sx: {
|
|
115
|
-
padding: 4,
|
|
116
|
-
}, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { sx: { height: '300px', maxWidth: '380px' }, children: [_jsx(ReactECharts, { option: ECHART_MOCK_2 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] })] })] })] })] }));
|
|
50
|
+
}, children: [_jsxs(Box, { padding: 4, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { height: "300px", maxWidth: "380px", children: [_jsx(ReactECharts, { option: ECHART_MOCK_1 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] }), _jsxs(Box, { padding: 4, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { height: "300px", maxWidth: "380px", children: [_jsx(ReactECharts, { option: ECHART_MOCK_3 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] }), _jsxs(Box, { padding: 4, children: [_jsx(Text, { as: "h3", children: "Notebook name abc" }), _jsx(Text, { sx: { color: 'fg.subtle' }, children: "Subtitle comes here" }), _jsxs(Box, { height: "300px", maxWidth: "380px", children: [_jsx(ReactECharts, { option: ECHART_MOCK_2 }), ";"] }), _jsxs(Text, { as: "p", sx: { display: 'flex', justifyContent: 'space-between' }, children: [_jsx(Link, { children: "Link to somewhere" }), _jsxs(Link, { children: ["Second link", _jsx(LinkIcon, {})] })] })] })] })] })] })] }));
|
|
117
51
|
};
|
|
118
52
|
export default DashboardMock;
|
|
@@ -4,7 +4,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useState } from 'react';
|
|
7
|
-
import { Box
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { FormControl, TextInputWithTokens, Autocomplete, Select, Textarea, Heading, } from '@primer/react';
|
|
8
9
|
export const FormMock = (props) => {
|
|
9
10
|
const { title } = props;
|
|
10
11
|
const [tokens, setTokens] = useState([
|
|
@@ -15,7 +16,7 @@ export const FormMock = (props) => {
|
|
|
15
16
|
const onTokenRemove = tokenId => {
|
|
16
17
|
setTokens(tokens.filter(token => token.id !== tokenId));
|
|
17
18
|
};
|
|
18
|
-
return (_jsxs(Box, { display: "grid",
|
|
19
|
+
return (_jsxs(Box, { display: "grid", gap: 3, children: [_jsx(Heading, { children: title }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "TextInputWithTokens" }), _jsx(TextInputWithTokens, { onTokenRemove: onTokenRemove, tokens: tokens })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Autocomplete" }), _jsxs(Autocomplete, { children: [_jsx(Autocomplete.Input, { block: true }), _jsx(Autocomplete.Overlay, { children: _jsx(Autocomplete.Menu, { items: [
|
|
19
20
|
{ text: 'css', id: '0' },
|
|
20
21
|
{ text: 'css-in-js', id: '1' },
|
|
21
22
|
{ text: 'styled-system', id: '2' },
|
|
@@ -3,7 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { Box
|
|
6
|
+
import { Box } from '@datalayer/primer-addons';
|
|
7
|
+
import { LabelGroup, ActionMenu, ActionList, IconButton, Label, RelativeTime, } from '@primer/react';
|
|
7
8
|
import { Table, DataTable } from '@primer/react/experimental';
|
|
8
9
|
import { KebabHorizontalIcon, DownloadIcon } from '@primer/octicons-react';
|
|
9
10
|
import { VisuallyHidden } from './../../components/display/index.js';
|
|
@@ -101,7 +102,7 @@ function uppercase(input) {
|
|
|
101
102
|
}
|
|
102
103
|
export const TableMock = (props) => {
|
|
103
104
|
const { title } = props;
|
|
104
|
-
return (_jsx(Box, { display: "grid",
|
|
105
|
+
return (_jsx(Box, { display: "grid", gap: 3, children: _jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h2", id: "repositories", children: title }), _jsx(Table.Subtitle, { as: "p", id: "repositories-subtitle", children: "A subtitle could appear here to give extra context to the data." }), _jsx(DataTable, { "aria-labelledby": "repositories", "aria-describedby": "repositories-subtitle", data: data, columns: [
|
|
105
106
|
{
|
|
106
107
|
header: 'Repository',
|
|
107
108
|
field: 'name',
|
|
@@ -3,7 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { Box
|
|
6
|
+
import { Box } from '@datalayer/primer-addons';
|
|
7
|
+
import { PageHeader, Flash, PageLayout } from '@primer/react';
|
|
7
8
|
import { ConstructionIcon } from '@datalayer/icons-react';
|
|
8
9
|
export const WipMock = (props) => {
|
|
9
10
|
const { title } = props;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** The signed-in person, as a shell needs one. */
|
|
2
|
+
export type Person = {
|
|
3
|
+
uid: string;
|
|
4
|
+
handle: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
avatarIcon?: string;
|
|
7
|
+
};
|
|
8
|
+
/** The person in IAM's `GET /api/iam/v1/me` answer (`me`); undefined without a uid and a handle. */
|
|
9
|
+
export declare function personOf(raw: unknown): Person | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/** The person in IAM's `GET /api/iam/v1/me` answer (`me`); undefined without a uid and a handle. */
|
|
6
|
+
export function personOf(raw) {
|
|
7
|
+
if (!raw || typeof raw !== 'object') {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
const user = raw;
|
|
11
|
+
const handle = typeof user.handle_s === 'string' ? user.handle_s : '';
|
|
12
|
+
const uid = typeof user.uid === 'string' ? user.uid : '';
|
|
13
|
+
if (!handle || !uid) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const names = [user.first_name_t, user.last_name_t].filter((part) => typeof part === 'string' && part.trim() !== '');
|
|
17
|
+
return {
|
|
18
|
+
uid,
|
|
19
|
+
handle,
|
|
20
|
+
displayName: names.length ? names.join(' ') : handle,
|
|
21
|
+
avatarIcon: typeof user.avatar_icon_s === 'string' ? user.avatar_icon_s : undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -13,7 +13,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
13
13
|
* @module otel/OtelLive
|
|
14
14
|
*/
|
|
15
15
|
import { useState, useCallback, useMemo, useEffect, useRef, } from 'react';
|
|
16
|
-
import { Box
|
|
16
|
+
import { Box } from '@datalayer/primer-addons';
|
|
17
|
+
import { Text, Button, Label } from '@primer/react';
|
|
17
18
|
import { GitBranchIcon, ClockIcon } from '@primer/octicons-react';
|
|
18
19
|
import { getOtelConsumeUrl } from '../../state/substates/CoreState.js';
|
|
19
20
|
import { useOtelTraces, useOtelTrace, useOtelLogs, useOtelMetrics, useOtelServices, useOtelWebSocket, } from '../hooks/index.js';
|
|
@@ -287,70 +288,11 @@ export const OtelLive = ({ baseUrl = getOtelConsumeUrl(), wsBaseUrl, token, auto
|
|
|
287
288
|
return ts >= s && ts <= e;
|
|
288
289
|
});
|
|
289
290
|
}, [metrics, isRangeActive, rangeStart, rangeEnd]);
|
|
290
|
-
return (_jsxs(Box, {
|
|
291
|
-
display: 'flex',
|
|
292
|
-
flexDirection: 'column',
|
|
293
|
-
flex: 1,
|
|
294
|
-
minHeight: 0,
|
|
295
|
-
height: '100%',
|
|
296
|
-
color: 'fg.default',
|
|
297
|
-
bg: 'canvas.default',
|
|
298
|
-
border: '1px solid',
|
|
299
|
-
borderColor: 'border.default',
|
|
300
|
-
borderRadius: 2,
|
|
301
|
-
overflow: 'hidden',
|
|
302
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0 }, children: [_jsx(Box, { sx: { flex: 1 }, children: _jsx(OtelSearchBar, { signal: signal, onSignalChange: setSignal, services: effectiveServices, selectedService: service, onServiceChange: setService, query: query, onQueryChange: setQuery, onRefresh: handleRefresh, loading: signal === 'traces'
|
|
291
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, height: "100%", color: "fg.default", bg: "canvas.default", border: "1px solid", borderColor: "border.default", borderRadius: 2, overflow: "hidden", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 0, children: [_jsx(Box, { flex: 1, children: _jsx(OtelSearchBar, { signal: signal, onSignalChange: setSignal, services: effectiveServices, selectedService: service, onServiceChange: setService, query: query, onQueryChange: setQuery, onRefresh: handleRefresh, loading: signal === 'traces'
|
|
303
292
|
? tracesLoading
|
|
304
293
|
: signal === 'logs'
|
|
305
294
|
? logsLoading
|
|
306
|
-
: metricsLoading }) }), _jsx(Box, {
|
|
307
|
-
px: 3,
|
|
308
|
-
pt: 2,
|
|
309
|
-
pb: 1,
|
|
310
|
-
borderBottom: '1px solid',
|
|
311
|
-
borderColor: 'border.default',
|
|
312
|
-
bg: 'canvas.subtle',
|
|
313
|
-
flexShrink: 0,
|
|
314
|
-
position: 'relative',
|
|
315
|
-
zIndex: 0,
|
|
316
|
-
}, children: _jsx(OtelTimelineRangeSlider, { timelineStart: timelineBounds.start, timelineEnd: timelineBounds.end, selectedStart: rangeStart, selectedEnd: rangeEnd, onRangeChange: handleRangeChange, histogram: histogram, height: 48, tickCount: 6 }) })), _jsxs(Box, { sx: { display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden' }, children: [_jsxs(Box, { sx: {
|
|
317
|
-
display: 'flex',
|
|
318
|
-
flexDirection: 'column',
|
|
319
|
-
flex: hasDetail ? '0 0 55%' : '1 1 100%',
|
|
320
|
-
minHeight: 0,
|
|
321
|
-
overflow: 'hidden',
|
|
322
|
-
}, children: [signal === 'traces' && (_jsx(OtelTracesList, { spans: filteredTraces, loading: tracesLoading, selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect })), signal === 'logs' && (_jsx(OtelLogsList, { logs: filteredLogs, loading: logsLoading, selectedLogIndex: selectedLogIdx, onSelectLog: handleLogSelect })), signal === 'metrics' && (_jsx(OtelMetricsList, { metrics: filteredMetrics, loading: metricsLoading }))] }), hasDetail && (_jsxs(Box, { sx: {
|
|
323
|
-
flex: '0 0 45%',
|
|
324
|
-
minHeight: 0,
|
|
325
|
-
overflow: 'auto',
|
|
326
|
-
borderLeft: '1px solid',
|
|
327
|
-
borderColor: 'border.default',
|
|
328
|
-
}, children: [signal === 'traces' && selectedSpan && (_jsx(OtelSpanDetail, { span: selectedSpan, traceSpans: traceSpans ?? undefined, onClose: handleCloseDetail })), signal === 'logs' && selectedLogIdx !== null && logs && (_jsxs(Box, { sx: { p: 3 }, children: [_jsxs(Box, { sx: {
|
|
329
|
-
display: 'flex',
|
|
330
|
-
justifyContent: 'space-between',
|
|
331
|
-
mb: 3,
|
|
332
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 2 }, children: "Log Detail" }), _jsx(Button, { size: "small", variant: "invisible", onClick: handleCloseDetail, children: "\u2715" })] }), _jsx(Box, { as: "pre", sx: {
|
|
333
|
-
m: 0,
|
|
334
|
-
fontSize: 1,
|
|
335
|
-
fontFamily: 'mono',
|
|
336
|
-
whiteSpace: 'pre-wrap',
|
|
337
|
-
wordBreak: 'break-word',
|
|
338
|
-
}, children: JSON.stringify(logs[selectedLogIdx], null, 2) })] }))] }))] }), signal === 'traces' && selectedSpan && spanTree.length > 0 && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
|
|
339
|
-
display: 'flex',
|
|
340
|
-
gap: 1,
|
|
341
|
-
px: 3,
|
|
342
|
-
py: 1,
|
|
343
|
-
bg: 'canvas.subtle',
|
|
344
|
-
borderTop: '1px solid',
|
|
345
|
-
borderColor: 'border.default',
|
|
346
|
-
flexShrink: 0,
|
|
347
|
-
}, children: [_jsx(Button, { size: "small", variant: bottomPane === 'timeline' ? 'primary' : 'invisible', leadingVisual: ClockIcon, onClick: () => toggleBottomPane('timeline'), children: "Timeline" }), _jsx(Button, { size: "small", variant: bottomPane === 'tree' ? 'primary' : 'invisible', leadingVisual: GitBranchIcon, onClick: () => toggleBottomPane('tree'), children: "Span Tree" })] }), bottomPane && (_jsxs(Box, { sx: {
|
|
348
|
-
height: 260,
|
|
349
|
-
overflow: 'auto',
|
|
350
|
-
borderTop: '1px solid',
|
|
351
|
-
borderColor: 'border.default',
|
|
352
|
-
flexShrink: 0,
|
|
353
|
-
}, children: [bottomPane === 'timeline' && (_jsx(OtelTimeline, { spans: traceSpans ?? [], selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect })), bottomPane === 'tree' && (_jsx(OtelSpanTree, { spans: spanTree, selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect, defaultExpandDepth: 3 }))] }))] }))] }));
|
|
295
|
+
: metricsLoading }) }), _jsx(Box, { pr: 2, flexShrink: 0, children: _jsx(Label, { variant: wsConnected ? 'success' : 'secondary', size: "small", children: wsConnected ? '● Live' : '○ Polling' }) })] }), timelineBounds && rangeStart && rangeEnd && (_jsx(Box, { px: 3, pt: 2, pb: 1, borderBottom: "1px solid", borderColor: "border.default", bg: "canvas.subtle", flexShrink: 0, position: "relative", zIndex: 0, children: _jsx(OtelTimelineRangeSlider, { timelineStart: timelineBounds.start, timelineEnd: timelineBounds.end, selectedStart: rangeStart, selectedEnd: rangeEnd, onRangeChange: handleRangeChange, histogram: histogram, height: 48, tickCount: 6 }) })), _jsxs(Box, { display: "flex", flex: 1, minHeight: 0, overflow: "hidden", children: [_jsxs(Box, { display: "flex", flexDirection: "column", flex: hasDetail ? '0 0 55%' : '1 1 100%', minHeight: 0, overflow: "hidden", children: [signal === 'traces' && (_jsx(OtelTracesList, { spans: filteredTraces, loading: tracesLoading, selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect })), signal === 'logs' && (_jsx(OtelLogsList, { logs: filteredLogs, loading: logsLoading, selectedLogIndex: selectedLogIdx, onSelectLog: handleLogSelect })), signal === 'metrics' && (_jsx(OtelMetricsList, { metrics: filteredMetrics, loading: metricsLoading }))] }), hasDetail && (_jsxs(Box, { flex: "0 0 45%", minHeight: 0, overflow: "auto", borderLeft: "1px solid", borderColor: "border.default", children: [signal === 'traces' && selectedSpan && (_jsx(OtelSpanDetail, { span: selectedSpan, traceSpans: traceSpans ?? undefined, onClose: handleCloseDetail })), signal === 'logs' && selectedLogIdx !== null && logs && (_jsxs(Box, { p: 3, children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", mb: 3, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 2 }, children: "Log Detail" }), _jsx(Button, { size: "small", variant: "invisible", onClick: handleCloseDetail, children: "\u2715" })] }), _jsx(Box, { as: "pre", m: 0, fontSize: 1, fontFamily: "mono", whiteSpace: "pre-wrap", wordBreak: "break-word", children: JSON.stringify(logs[selectedLogIdx], null, 2) })] }))] }))] }), signal === 'traces' && selectedSpan && spanTree.length > 0 && (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "flex", gap: 1, px: 3, py: 1, bg: "canvas.subtle", borderTop: "1px solid", borderColor: "border.default", flexShrink: 0, children: [_jsx(Button, { size: "small", variant: bottomPane === 'timeline' ? 'primary' : 'invisible', leadingVisual: ClockIcon, onClick: () => toggleBottomPane('timeline'), children: "Timeline" }), _jsx(Button, { size: "small", variant: bottomPane === 'tree' ? 'primary' : 'invisible', leadingVisual: GitBranchIcon, onClick: () => toggleBottomPane('tree'), children: "Span Tree" })] }), bottomPane && (_jsxs(Box, { height: 260, overflow: "auto", borderTop: "1px solid", borderColor: "border.default", flexShrink: 0, children: [bottomPane === 'timeline' && (_jsx(OtelTimeline, { spans: traceSpans ?? [], selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect })), bottomPane === 'tree' && (_jsx(OtelSpanTree, { spans: spanTree, selectedSpanId: selectedSpan?.span_id, onSelectSpan: handleSpanSelect, defaultExpandDepth: 3 }))] }))] }))] }));
|
|
354
296
|
};
|
|
355
297
|
// ── Client-side filter helpers ──────────────────────────────────────
|
|
356
298
|
function filterSpans(spans, q) {
|
|
@@ -16,7 +16,8 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
16
16
|
* @module otel/views/OtelLiveSpans
|
|
17
17
|
*/
|
|
18
18
|
import { useMemo, useState } from 'react';
|
|
19
|
-
import {
|
|
19
|
+
import { Box } from '@datalayer/primer-addons';
|
|
20
|
+
import { ActionList, ActionMenu, Button, Text } from '@primer/react';
|
|
20
21
|
import { DownloadIcon, PauseIcon, PlayIcon, TrashIcon, } from '@primer/octicons-react';
|
|
21
22
|
import { toMs } from '../utils.js';
|
|
22
23
|
import { spansOfService } from '../live/filter.js';
|
|
@@ -93,22 +94,7 @@ export const OtelLiveSpans = ({ tracer, spans: given, service, facets = DEFAULT_
|
|
|
93
94
|
? everything.filter(span => span.trace_id === selectedSpan.trace_id)
|
|
94
95
|
: [], [everything, selectedSpan]);
|
|
95
96
|
const side = detailPlacement === 'side' && !compact;
|
|
96
|
-
return (_jsxs(Box, { "data-otel-live-spans": "", sx: {
|
|
97
|
-
border: '1px solid',
|
|
98
|
-
borderColor: 'border.default',
|
|
99
|
-
borderRadius: 2,
|
|
100
|
-
bg: 'canvas.default',
|
|
101
|
-
color: 'fg.default',
|
|
102
|
-
minWidth: 0,
|
|
103
|
-
}, children: [_jsxs(Box, { role: "toolbar", "aria-label": label, sx: {
|
|
104
|
-
display: 'flex',
|
|
105
|
-
flexWrap: 'wrap',
|
|
106
|
-
gap: 2,
|
|
107
|
-
alignItems: 'center',
|
|
108
|
-
p: 2,
|
|
109
|
-
borderBottom: '1px solid',
|
|
110
|
-
borderColor: 'border.default',
|
|
111
|
-
}, children: [facets.map((facet, index) => (_jsx(FacetMenu, { facet: facet, options: options[index] ?? [], selected: selected[index] ?? new Set(), onChange: next => setSelected(prev => facets.map((_, at) => at === index ? next : (prev[at] ?? new Set()))) }, facet.label))), _jsx(Box, { sx: { flex: 1 } }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, "data-otel-span-count": "", children: [rows.length === shown.length
|
|
97
|
+
return (_jsxs(Box, { "data-otel-live-spans": "", border: "1px solid", borderColor: "border.default", borderRadius: 2, bg: "canvas.default", color: "fg.default", minWidth: 0, children: [_jsxs(Box, { role: "toolbar", "aria-label": label, display: "flex", flexWrap: "wrap", gap: 2, alignItems: "center", p: 2, borderBottom: "1px solid", borderColor: "border.default", children: [facets.map((facet, index) => (_jsx(FacetMenu, { facet: facet, options: options[index] ?? [], selected: selected[index] ?? new Set(), onChange: next => setSelected(prev => facets.map((_, at) => at === index ? next : (prev[at] ?? new Set()))) }, facet.label))), _jsx(Box, { flex: 1 }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, "data-otel-span-count": "", children: [rows.length === shown.length
|
|
112
98
|
? `${rows.length} ${rows.length === 1 ? 'span' : 'spans'}`
|
|
113
99
|
: `${rows.length} of ${shown.length}`, waiting > 0 ? ` · ${waiting} new` : ''] }), _jsx(Button, { size: "small", leadingVisual: held ? PlayIcon : PauseIcon, "aria-pressed": held !== null, onClick: () => setHeld(held ? null : recorded), "data-otel-pause": "", children: held ? 'Resume' : 'Pause' }), _jsx(Button, { size: "small", leadingVisual: TrashIcon, onClick: () => {
|
|
114
100
|
setHeld(null);
|
|
@@ -123,17 +109,6 @@ export const OtelLiveSpans = ({ tracer, spans: given, service, facets = DEFAULT_
|
|
|
123
109
|
}, "data-otel-clear": "", children: "Clear" }), _jsx(Button, { size: "small", leadingVisual: DownloadIcon, disabled: !recorded.length, onClick: () => download(exportName, {
|
|
124
110
|
exportedAt: new Date().toISOString(),
|
|
125
111
|
spans: [...recorded],
|
|
126
|
-
}), "data-otel-export": "", children: "Export" })] }), _jsxs(Box, {
|
|
127
|
-
display: side ? 'grid' : 'block',
|
|
128
|
-
gridTemplateColumns: side
|
|
129
|
-
? 'minmax(0, 3fr) minmax(0, 2fr)'
|
|
130
|
-
: undefined,
|
|
131
|
-
}, children: [_jsx(Box, { sx: { maxHeight, overflowY: 'auto', minWidth: 0 }, children: _jsx(OtelTracesList, { spans: rows, selectedSpanId: selectedSpanId, onSelectSpan: span => setSelectedSpanId(span.span_id), emptyText: emptyText, compact: compact, defaultExpanded: true, renderSpanMark: renderSpanMark, describeSpan: describeSpan }) }), selectedSpan && (_jsx(Box, { "data-otel-live-detail": "", sx: {
|
|
132
|
-
maxHeight,
|
|
133
|
-
overflowY: 'auto',
|
|
134
|
-
minWidth: 0,
|
|
135
|
-
borderTop: side ? 'none' : '1px solid',
|
|
136
|
-
borderColor: 'border.default',
|
|
137
|
-
}, children: _jsx(OtelSpanDetail, { span: selectedSpan, traceSpans: traceSpans, onClose: () => setSelectedSpanId(null) }) }))] })] }));
|
|
112
|
+
}), "data-otel-export": "", children: "Export" })] }), _jsxs(Box, { display: side ? 'grid' : 'block', gridTemplateColumns: side ? 'minmax(0, 3fr) minmax(0, 2fr)' : undefined, children: [_jsx(Box, { maxHeight: maxHeight, overflowY: "auto", minWidth: 0, children: _jsx(OtelTracesList, { spans: rows, selectedSpanId: selectedSpanId, onSelectSpan: span => setSelectedSpanId(span.span_id), emptyText: emptyText, compact: compact, defaultExpanded: true, renderSpanMark: renderSpanMark, describeSpan: describeSpan }) }), selectedSpan && (_jsx(Box, { "data-otel-live-detail": "", maxHeight: maxHeight, overflowY: "auto", minWidth: 0, borderTop: side ? 'none' : '1px solid', borderColor: "border.default", children: _jsx(OtelSpanDetail, { span: selectedSpan, traceSpans: traceSpans, onClose: () => setSelectedSpanId(null) }) }))] })] }));
|
|
138
113
|
};
|
|
139
114
|
export default OtelLiveSpans;
|