@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.
Files changed (107) hide show
  1. package/lib/cli-login.js +5 -51
  2. package/lib/components/anonymous/AnonymousKeyExpired.js +1 -15
  3. package/lib/components/anonymous/AnonymousKeyTimer.js +5 -15
  4. package/lib/components/auth/SignIn.js +2 -2
  5. package/lib/components/avatars/UserAvatar.js +3 -27
  6. package/lib/components/billing/BillingEntitySelect.js +6 -48
  7. package/lib/components/checkout/StripeCheckout.js +33 -217
  8. package/lib/components/contents/ContentSourceCard.js +2 -11
  9. package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +1 -1
  10. package/lib/components/contents/HomeFolderObjectsBrowser.js +11 -35
  11. package/lib/components/display/CenteredSpinner.js +1 -6
  12. package/lib/components/display/DatalayerBox.js +2 -14
  13. package/lib/components/flashes/FlashClosable.js +2 -17
  14. package/lib/components/mcp/ClientBadge.js +1 -1
  15. package/lib/components/mcp/McpErrorBlankslate.js +1 -1
  16. package/lib/components/mcp/ScopeList.js +1 -1
  17. package/lib/components/notebooks/JupyterNotebook.js +1 -2
  18. package/lib/components/principal/Principal.js +2 -10
  19. package/lib/components/principal/PrincipalAppearance.js +19 -63
  20. package/lib/components/principal/PrincipalAvatar.js +5 -25
  21. package/lib/components/principal/PrincipalBadge.js +3 -13
  22. package/lib/components/principal/PrincipalBanner.js +4 -32
  23. package/lib/components/principal/PrincipalDetailsOverlay.js +7 -23
  24. package/lib/components/principal/PrincipalHoverCard.js +15 -18
  25. package/lib/components/principal/PrincipalSwitcherMenu.js +15 -83
  26. package/lib/components/progress/ConsumptionBar.js +1 -1
  27. package/lib/components/sharing/ShareAccessComponent.js +21 -229
  28. package/lib/components/sharing/SharingEditor.js +1 -1
  29. package/lib/components/spaces/SpaceDetailsOverlay.js +4 -35
  30. package/lib/components/spaces/SpaceDisplay.js +1 -8
  31. package/lib/components/storage/ContentsBrowser.js +3 -26
  32. package/lib/components/storage/ContentsTable.js +4 -23
  33. package/lib/components/students/StudentResultCircle.js +7 -29
  34. package/lib/components/timeline/Timeline.js +4 -36
  35. package/lib/hooks/layouts/LayoutBackdrop.js +2 -1
  36. package/lib/hooks/layouts/LayoutScreencapture.js +1 -1
  37. package/lib/hooks/libraryApp.d.ts +6 -1
  38. package/lib/hooks/libraryApp.js +10 -1
  39. package/lib/hooks/useAuthorization.js +6 -1
  40. package/lib/mocks/components/FlashMock.js +3 -8
  41. package/lib/mocks/views/DashboardMock.js +6 -72
  42. package/lib/mocks/views/FormMock.js +3 -2
  43. package/lib/mocks/views/TableMock.js +3 -2
  44. package/lib/mocks/views/WipMock.js +2 -1
  45. package/lib/models/Person.d.ts +9 -0
  46. package/lib/models/Person.js +23 -0
  47. package/lib/otel/views/OtelLive.js +4 -62
  48. package/lib/otel/views/OtelLiveSpans.js +4 -29
  49. package/lib/otel/views/OtelLogsList.js +13 -64
  50. package/lib/otel/views/OtelMetricsChart.js +4 -19
  51. package/lib/otel/views/OtelMetricsList.js +8 -77
  52. package/lib/otel/views/OtelSearchBar.js +3 -12
  53. package/lib/otel/views/OtelSpanDetail.js +9 -79
  54. package/lib/otel/views/OtelSpanTree.js +7 -57
  55. package/lib/otel/views/OtelSqlView.js +5 -99
  56. package/lib/otel/views/OtelSystemView.js +4 -34
  57. package/lib/otel/views/OtelTimeline.js +7 -37
  58. package/lib/otel/views/OtelTimelineRangeSlider.js +7 -140
  59. package/lib/otel/views/OtelTracesList.js +12 -76
  60. package/lib/portable/index.d.ts +8 -0
  61. package/lib/portable/index.js +12 -0
  62. package/lib/state/substates/NavigationState.d.ts +6 -4
  63. package/lib/state/substates/NavigationState.js +6 -5
  64. package/lib/views/api-keys/APIKeyEdit.js +2 -11
  65. package/lib/views/api-keys/APIKeyNew.js +3 -19
  66. package/lib/views/api-keys/APIKeys.js +6 -11
  67. package/lib/views/api-keys/APIKeysStandalone.js +1 -1
  68. package/lib/views/datasources/DatasourceDetail.d.ts +1 -1
  69. package/lib/views/datasources/DatasourceDetail.js +24 -17
  70. package/lib/views/datasources/DatasourceNew.js +2 -6
  71. package/lib/views/datasources/Datasources.js +2 -14
  72. package/lib/views/iam/SignInSimple.js +8 -64
  73. package/lib/views/mcp/AdmittedClients.js +3 -16
  74. package/lib/views/mcp/AlertDestinations.js +2 -10
  75. package/lib/views/mcp/AlertRules.js +4 -9
  76. package/lib/views/mcp/ApprovalQueue.js +4 -21
  77. package/lib/views/mcp/AuditLog.js +7 -44
  78. package/lib/views/mcp/ConnectedAgents.js +1 -6
  79. package/lib/views/mcp/EnterpriseConsole.js +10 -23
  80. package/lib/views/mcp/IdentityProviders.js +7 -31
  81. package/lib/views/mcp/McpDashboard.js +14 -30
  82. package/lib/views/mcp/McpHome.js +7 -54
  83. package/lib/views/mcp/McpObservability.js +13 -85
  84. package/lib/views/mcp/NotebookRuns.js +5 -12
  85. package/lib/views/mcp/OrganizationPolicy.js +3 -9
  86. package/lib/views/mcp/OrganizationUsage.js +4 -11
  87. package/lib/views/mcp/PersonalPolicy.js +3 -3
  88. package/lib/views/mcp/Policies.js +5 -46
  89. package/lib/views/mcp/PolicyForm.js +1 -9
  90. package/lib/views/mcp/PolicyHistory.js +2 -8
  91. package/lib/views/mcp/RunDetail.js +3 -25
  92. package/lib/views/mcp/ScimProvisioning.js +3 -15
  93. package/lib/views/mcp/ServiceAgents.js +4 -17
  94. package/lib/views/mcp/TeamPolicies.js +7 -19
  95. package/lib/views/mcp/ToolAccess.js +15 -22
  96. package/lib/views/mcp/TraceTimeline.js +8 -23
  97. package/lib/views/otel/DashboardView.js +2 -2
  98. package/lib/views/otel/LogsView.js +2 -2
  99. package/lib/views/otel/MetricsView.js +2 -2
  100. package/lib/views/otel/OtelHeader.js +6 -40
  101. package/lib/views/otel/SqlView.js +2 -2
  102. package/lib/views/otel/SystemView.js +2 -2
  103. package/lib/views/otel/TracesView.js +2 -2
  104. package/lib/views/profile/UserBadge.js +6 -98
  105. package/lib/views/secrets/SecretEdit.js +2 -11
  106. package/lib/views/secrets/SecretNew.js +1 -1
  107. 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, Text } from '@primer/react';
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, { sx: {
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 { Heading, Box, Spinner } from '@primer/react';
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/react';
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;
@@ -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, Button, Flash } from '@primer/react';
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, { sx: {
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, Link, Text, LabelGroup, Label, ActionMenu, ActionList, } from '@primer/react';
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, FormControl, TextInputWithTokens, Autocomplete, Select, Textarea, Heading, } from '@primer/react';
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", sx: { 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
+ 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, LabelGroup, ActionMenu, ActionList, IconButton, Label, RelativeTime, } from '@primer/react';
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", sx: { 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
+ 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, PageHeader, Flash, PageLayout } from '@primer/react';
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, Text, Button, Label } from '@primer/react';
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, { sx: {
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, { sx: { pr: 2, flexShrink: 0 }, children: _jsx(Label, { variant: wsConnected ? 'success' : 'secondary', size: "small", children: wsConnected ? '● Live' : '○ Polling' }) })] }), timelineBounds && rangeStart && rangeEnd && (_jsx(Box, { sx: {
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 { ActionList, ActionMenu, Box, Button, Text } from '@primer/react';
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, { sx: {
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;