@mastra/playground-ui 38.0.1-alpha.2 → 38.1.0-alpha.3
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/CHANGELOG.md +57 -0
- package/dist/components/Columns.cjs.js +1 -1
- package/dist/components/Columns.es.js +1 -1
- package/dist/ee/signals/components/signal-details-page.cjs.js +224 -87
- package/dist/ee/signals/components/signal-details-page.cjs.js.map +1 -1
- package/dist/ee/signals/components/signal-details-page.es.js +225 -88
- package/dist/ee/signals/components/signal-details-page.es.js.map +1 -1
- package/dist/ee/signals/components/signals-entity-filter.cjs.js +27 -0
- package/dist/ee/signals/components/signals-entity-filter.cjs.js.map +1 -0
- package/dist/ee/signals/components/signals-entity-filter.d.ts +2 -0
- package/dist/ee/signals/components/signals-entity-filter.es.js +23 -0
- package/dist/ee/signals/components/signals-entity-filter.es.js.map +1 -0
- package/dist/ee/signals/components/signals-overview-page.cjs.js +158 -56
- package/dist/ee/signals/components/signals-overview-page.cjs.js.map +1 -1
- package/dist/ee/signals/components/signals-overview-page.es.js +160 -58
- package/dist/ee/signals/components/signals-overview-page.es.js.map +1 -1
- package/dist/ee/signals/components.cjs.js +2 -2
- package/dist/ee/signals/components.es.js +1 -1
- package/dist/ee/signals/hooks/use-entity-learning-config.cjs.js +27 -0
- package/dist/ee/signals/hooks/use-entity-learning-config.cjs.js.map +1 -0
- package/dist/ee/signals/hooks/use-entity-learning-config.d.ts +2 -0
- package/dist/ee/signals/hooks/use-entity-learning-config.es.js +23 -0
- package/dist/ee/signals/hooks/use-entity-learning-config.es.js.map +1 -0
- package/dist/ee/signals/hooks/use-entity-learning.cjs.js +113 -0
- package/dist/ee/signals/hooks/use-entity-learning.cjs.js.map +1 -0
- package/dist/ee/signals/hooks/use-entity-learning.d.ts +2 -0
- package/dist/ee/signals/hooks/use-entity-learning.es.js +100 -0
- package/dist/ee/signals/hooks/use-entity-learning.es.js.map +1 -0
- package/dist/ee/signals/hooks.cjs.js +21 -0
- package/dist/ee/signals/hooks.cjs.js.map +1 -0
- package/dist/ee/signals/hooks.d.ts +2 -0
- package/dist/ee/signals/hooks.es.js +3 -0
- package/dist/ee/signals/hooks.es.js.map +1 -0
- package/dist/ee/signals/services/entity-learning-service.cjs.js +97 -0
- package/dist/ee/signals/services/entity-learning-service.cjs.js.map +1 -0
- package/dist/ee/signals/services/entity-learning-service.d.ts +2 -0
- package/dist/ee/signals/services/entity-learning-service.es.js +93 -0
- package/dist/ee/signals/services/entity-learning-service.es.js.map +1 -0
- package/dist/ee/signals/services/entity-learning-types.cjs.js +3 -0
- package/dist/ee/signals/services/entity-learning-types.cjs.js.map +1 -0
- package/dist/ee/signals/services/entity-learning-types.d.ts +1 -0
- package/dist/ee/signals/services/entity-learning-types.es.js +2 -0
- package/dist/ee/signals/services/entity-learning-types.es.js.map +1 -0
- package/dist/ee/signals/services.cjs.js +10 -0
- package/dist/ee/signals/services.cjs.js.map +1 -0
- package/dist/ee/signals/services.d.ts +2 -0
- package/dist/ee/signals/services.es.js +2 -0
- package/dist/ee/signals/services.es.js.map +1 -0
- package/dist/ee/signals/signals-data.cjs.js +34 -180
- package/dist/ee/signals/signals-data.cjs.js.map +1 -1
- package/dist/ee/signals/signals-data.es.js +33 -180
- package/dist/ee/signals/signals-data.es.js.map +1 -1
- package/dist/ee/signals.cjs.js +19 -5
- package/dist/ee/signals.cjs.js.map +1 -1
- package/dist/ee/signals.es.js +5 -3
- package/dist/ee/signals.es.js.map +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +16 -11
- package/dist/ee/topics/components/topic-trace-summary-list.cjs.js.map +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.es.js +16 -11
- package/dist/ee/topics/components/topic-trace-summary-list.es.js.map +1 -1
- package/dist/index.cjs.js +20 -9
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +16 -0
- package/dist/index.es.js +6 -5
- package/dist/index.es.js.map +1 -1
- package/dist/{multi-column-BFzWhWNb.js → multi-column-BR3a4MvZ.js} +1 -2
- package/dist/{multi-column-BFzWhWNb.js.map → multi-column-BR3a4MvZ.js.map} +1 -1
- package/dist/{multi-column-C7amy3AM.cjs → multi-column-DGAsiBPq.cjs} +1 -2
- package/dist/{multi-column-C7amy3AM.cjs.map → multi-column-DGAsiBPq.cjs.map} +1 -1
- package/dist/primitives/form-element.cjs.js.map +1 -1
- package/dist/primitives/form-element.es.js.map +1 -1
- package/dist/src/ds/components/ButtonsGroup/buttons-group.stories.d.ts +1 -1
- package/dist/src/ee/signals/components/index.d.ts +1 -1
- package/dist/src/ee/signals/components/signal-details-page.d.ts +29 -20
- package/dist/src/ee/signals/components/signals-entity-filter.d.ts +13 -0
- package/dist/src/ee/signals/components/signals-overview-page.d.ts +15 -9
- package/dist/src/ee/signals/hooks/index.d.ts +2 -0
- package/dist/src/ee/signals/hooks/use-entity-learning-config.d.ts +14 -0
- package/dist/src/ee/signals/hooks/use-entity-learning.d.ts +26 -0
- package/dist/src/ee/signals/index.d.ts +2 -1
- package/dist/src/ee/signals/services/entity-learning-service.d.ts +40 -0
- package/dist/src/ee/signals/services/entity-learning-types.d.ts +136 -0
- package/dist/src/ee/signals/services/index.d.ts +2 -0
- package/dist/src/ee/signals/signals-data.d.ts +10 -2
- package/dist/src/ee/signals/types.d.ts +10 -8
- package/dist/src/index.d.ts +0 -1
- package/package.json +7 -7
- package/dist/components/Searchbar.cjs.js +0 -11
- package/dist/components/Searchbar.cjs.js.map +0 -1
- package/dist/components/Searchbar.d.ts +0 -2
- package/dist/components/Searchbar.es.js +0 -2
- package/dist/components/Searchbar.es.js.map +0 -1
- package/dist/ee/signals/components/signal-details-utils.cjs.js +0 -12
- package/dist/ee/signals/components/signal-details-utils.cjs.js.map +0 -1
- package/dist/ee/signals/components/signal-details-utils.d.ts +0 -2
- package/dist/ee/signals/components/signal-details-utils.es.js +0 -8
- package/dist/ee/signals/components/signal-details-utils.es.js.map +0 -1
- package/dist/ee/signals/signals-chart-data.cjs.js +0 -34
- package/dist/ee/signals/signals-chart-data.cjs.js.map +0 -1
- package/dist/ee/signals/signals-chart-data.d.ts +0 -2
- package/dist/ee/signals/signals-chart-data.es.js +0 -30
- package/dist/ee/signals/signals-chart-data.es.js.map +0 -1
- package/dist/searchbar-B42oQGrT.cjs +0 -105
- package/dist/searchbar-B42oQGrT.cjs.map +0 -1
- package/dist/searchbar-CY4dg-Im.js +0 -102
- package/dist/searchbar-CY4dg-Im.js.map +0 -1
- package/dist/src/ds/components/Searchbar/index.d.ts +0 -1
- package/dist/src/ds/components/Searchbar/searchbar.d.ts +0 -16
- package/dist/src/ds/components/Searchbar/searchbar.stories.d.ts +0 -14
- package/dist/src/ee/signals/components/signal-details-utils.d.ts +0 -1
- package/dist/src/ee/signals/signals-chart-data.d.ts +0 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# @mastra/playground-ui
|
|
2
2
|
|
|
3
|
+
## 38.1.0-alpha.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Removed the `Searchbar` component from `@mastra/playground-ui`. Compose search inputs with `InputGroup` instead so search remains a documented use case of the existing input composition primitive. ([#18727](https://github.com/mastra-ai/mastra/pull/18727))
|
|
8
|
+
|
|
9
|
+
**Before**
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Searchbar } from '@mastra/playground-ui/components/Searchbar';
|
|
13
|
+
|
|
14
|
+
<Searchbar label="Search tools" placeholder="Search tools..." onSearch={setSearch} />;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**After**
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { InputGroup, InputGroupAddon, InputGroupInput } from '@mastra/playground-ui/components/InputGroup';
|
|
21
|
+
import { SearchIcon } from 'lucide-react';
|
|
22
|
+
|
|
23
|
+
<InputGroup variant="outline">
|
|
24
|
+
<InputGroupAddon align="inline-start">
|
|
25
|
+
<SearchIcon />
|
|
26
|
+
</InputGroupAddon>
|
|
27
|
+
<InputGroupInput
|
|
28
|
+
type="search"
|
|
29
|
+
aria-label="Search tools"
|
|
30
|
+
placeholder="Search tools..."
|
|
31
|
+
onChange={event => setSearch(event.target.value)}
|
|
32
|
+
/>
|
|
33
|
+
</InputGroup>;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **Signals now show live Entity-Learning data** ([#18699](https://github.com/mastra-ai/mastra/pull/18699))
|
|
37
|
+
|
|
38
|
+
The Signals page is no longer static. Select an agent reported by the platform and Signals fetches that agent's signals and their clusters live from the Entity-Learning API, replacing the previous hardcoded mock data. Each available signal loads its real clusters (topics) and traces, with a scatter-plot chart for the selected topics.
|
|
39
|
+
|
|
40
|
+
**What changed**
|
|
41
|
+
- Added an agent filter at the top of the Signals page, mirroring the traces filter, so you can inspect signals for any agent on the server.
|
|
42
|
+
- The Signals overview and details pages now render live Entity-Learning topics, examples, and points directly, with shape-matching skeletons while data loads, centered empty states, and explicit error states.
|
|
43
|
+
- Clicking a cluster card opens its topic by default, and the Signals breadcrumbs preserve the selected entity and topic query params on back-navigation.
|
|
44
|
+
- Signals detail navigation keeps selected clusters, trace examples, and chart filters in sync when moving between signals or entities.
|
|
45
|
+
|
|
46
|
+
**Gating**
|
|
47
|
+
|
|
48
|
+
Studio's served HTML exposes `MASTRA_ORGANIZATION_ID`, `MASTRA_PLATFORM_PROJECT_ID`, and `MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT` to the browser so the Signals page can call the Entity-Learning API. The route is gated on the platform observability config, and the `MASTRA_SIGNALS_UI` flag guards the sidebar Signals nav link.
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Fixed the Signals page showing empty clusters for every signal except the most recently clustered one. Cluster queries no longer pin the entity-wide latest run id: the API resolves the latest run per signal, and the details page reuses the run resolved by the topics response for its examples and points queries. ([#18786](https://github.com/mastra-ai/mastra/pull/18786))
|
|
53
|
+
|
|
54
|
+
- Updated dependencies [[`700619b`](https://github.com/mastra-ai/mastra/commit/700619b61d572e592cbaaf758121d168844ca4d2), [`0c3d4bc`](https://github.com/mastra-ai/mastra/commit/0c3d4bcae13ea3699d379403e6f350d5cf4efe9f), [`17369b2`](https://github.com/mastra-ai/mastra/commit/17369b25250561e9ed994ae509be1d15bfb33bcb), [`bcae929`](https://github.com/mastra-ai/mastra/commit/bcae929945cbf265bd9f327cc715ecafa072b5b9), [`b33822e`](https://github.com/mastra-ai/mastra/commit/b33822e8d470884954b02f7b0745407ee4ef74b1), [`d5c11e3`](https://github.com/mastra-ai/mastra/commit/d5c11e3ba5045969caa7272a7bd1fd141c93ab6c), [`ff80671`](https://github.com/mastra-ai/mastra/commit/ff8067185e208b27198b4e5b71803013175c3643), [`dab1257`](https://github.com/mastra-ai/mastra/commit/dab1257b64e4ed576dc5038bb7a3f7072338bc9f), [`705ff39`](https://github.com/mastra-ai/mastra/commit/705ff3969e57214ff2fdaf3815d751dd558886ed), [`e6fbd5b`](https://github.com/mastra-ai/mastra/commit/e6fbd5bfdc28e92c0c0433f29aa1bc152d3430f6), [`6f2026c`](https://github.com/mastra-ai/mastra/commit/6f2026cdf114ff1e21e49133ca774ec7d5085059), [`ff80671`](https://github.com/mastra-ai/mastra/commit/ff8067185e208b27198b4e5b71803013175c3643), [`f890eda`](https://github.com/mastra-ai/mastra/commit/f890eda2c8a2ae83d9b30bc6d85842f93b6c266b)]:
|
|
55
|
+
- @mastra/core@1.49.0-alpha.3
|
|
56
|
+
- @mastra/memory@1.22.1-alpha.1
|
|
57
|
+
- @mastra/client-js@1.29.1-alpha.3
|
|
58
|
+
- @mastra/react@1.2.2-alpha.3
|
|
59
|
+
|
|
3
60
|
## 38.0.1-alpha.2
|
|
4
61
|
|
|
5
62
|
### Patch Changes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as Column, a as Columns, M as MultiColumn } from '../multi-column-
|
|
1
|
+
export { C as Column, a as Columns, M as MultiColumn } from '../multi-column-BR3a4MvZ.js';
|
|
2
2
|
//# sourceMappingURL=Columns.es.js.map
|
|
@@ -3,33 +3,36 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
const lucideReact = require('lucide-react');
|
|
6
7
|
const React = require('react');
|
|
7
|
-
require('
|
|
8
|
-
require('
|
|
9
|
-
const
|
|
10
|
-
require('../../../domains/traces/trace-filters.cjs.js');
|
|
8
|
+
const Button = require('../../../Button-66ghjQV8.cjs');
|
|
9
|
+
const dataList = require('../../../data-list-DDQRmA6L.cjs');
|
|
10
|
+
const inputGroup = require('../../../input-group-CF6DB97L.cjs');
|
|
11
11
|
const scatterPlotChart = require('../../../scatter-plot-chart-CFZO31md.cjs');
|
|
12
|
+
const skeleton = require('../../../skeleton-D5zq7rhk.cjs');
|
|
12
13
|
const tabsTab = require('../../../tabs-tab-B7Ziuuh8.cjs');
|
|
13
14
|
const tabsContent = require('../../../tabs-content-ohtjaVdC.cjs');
|
|
14
|
-
const utils_colors = require('../../../utils/colors.cjs.js');
|
|
15
15
|
const utils_cn = require('../../../cn-vA5sWo9W.cjs');
|
|
16
16
|
const ee_topics_components_topicsLayout = require('../../topics/components/topics-layout.cjs.js');
|
|
17
|
-
const ee_topics_components_topicTraceSummaryList = require('../../topics/components/topic-trace-summary-list.cjs.js');
|
|
18
17
|
const ee_topics_components_topicTraceDetailsPanel = require('../../topics/components/topic-trace-details-panel.cjs.js');
|
|
19
|
-
const
|
|
18
|
+
const ee_signals_hooks_useEntityLearning = require('../hooks/use-entity-learning.cjs.js');
|
|
20
19
|
const ee_signals_signalsData = require('../signals-data.cjs.js');
|
|
21
20
|
|
|
22
|
-
const SignalTraceSummaryList = ee_topics_components_topicTraceSummaryList.TopicTraceSummaryList;
|
|
23
21
|
const SignalTraceDetailsPanel = ee_topics_components_topicTraceDetailsPanel.TopicTraceDetailsPanel;
|
|
24
22
|
const SignalsLayout = ee_topics_components_topicsLayout.TopicsLayout;
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
function clusterColor(topicId) {
|
|
24
|
+
let hash = 0;
|
|
25
|
+
for (let i = 0; i < topicId.length; i++) {
|
|
26
|
+
hash = topicId.charCodeAt(i) + ((hash << 5) - hash);
|
|
27
|
+
hash = hash & hash;
|
|
28
|
+
}
|
|
29
|
+
const hue = Math.abs(hash * 137.508) % 360;
|
|
30
|
+
return `hsl(${hue}, 70%, 55%)`;
|
|
28
31
|
}
|
|
29
32
|
function SignalClusterSidebar({
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
topics,
|
|
34
|
+
selectedTopicIds,
|
|
35
|
+
onTopicSelect,
|
|
33
36
|
multiple = false,
|
|
34
37
|
ariaLabel = "Signal clusters"
|
|
35
38
|
}) {
|
|
@@ -38,8 +41,8 @@ function SignalClusterSidebar({
|
|
|
38
41
|
{
|
|
39
42
|
className: "min-h-0 w-72 shrink-0 overflow-y-auto border-r border-border1/60 pr-4 py-4",
|
|
40
43
|
"aria-label": ariaLabel,
|
|
41
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", role: multiple ? "group" : void 0, children:
|
|
42
|
-
const selected =
|
|
44
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", role: multiple ? "group" : void 0, children: topics.map((topic) => {
|
|
45
|
+
const selected = selectedTopicIds.includes(topic.topicId);
|
|
43
46
|
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
44
47
|
"button",
|
|
45
48
|
{
|
|
@@ -48,13 +51,13 @@ function SignalClusterSidebar({
|
|
|
48
51
|
"aria-checked": multiple ? selected : void 0,
|
|
49
52
|
"aria-pressed": multiple ? void 0 : selected,
|
|
50
53
|
className: "group cursor-pointer w-full rounded-xl px-3 py-2 text-left transition-colors hover:bg-surface3 aria-pressed:bg-surface3 aria-checked:bg-surface3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent1",
|
|
51
|
-
onClick: () =>
|
|
54
|
+
onClick: () => onTopicSelect(topic.topicId),
|
|
52
55
|
children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start gap-2", children: [
|
|
53
56
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
54
57
|
"span",
|
|
55
58
|
{
|
|
56
59
|
className: utils_cn.cn("mt-1.5 h-2 w-2 shrink-0 rounded-full", multiple && !selected && "invisible"),
|
|
57
|
-
style: { backgroundColor:
|
|
60
|
+
style: { backgroundColor: clusterColor(topic.topicId) }
|
|
58
61
|
}
|
|
59
62
|
),
|
|
60
63
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 space-y-1", children: [
|
|
@@ -65,7 +68,7 @@ function SignalClusterSidebar({
|
|
|
65
68
|
"block text-sm font-medium",
|
|
66
69
|
multiple && !selected ? "text-neutral3" : "text-neutral5"
|
|
67
70
|
),
|
|
68
|
-
children:
|
|
71
|
+
children: topic.name
|
|
69
72
|
}
|
|
70
73
|
),
|
|
71
74
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -75,44 +78,123 @@ function SignalClusterSidebar({
|
|
|
75
78
|
"line-clamp-2 block text-sm",
|
|
76
79
|
multiple && !selected ? "text-neutral1" : "text-neutral2"
|
|
77
80
|
),
|
|
78
|
-
children:
|
|
81
|
+
children: topic.description
|
|
79
82
|
}
|
|
80
83
|
)
|
|
81
84
|
] })
|
|
82
85
|
] })
|
|
83
86
|
}
|
|
84
|
-
) },
|
|
87
|
+
) }, topic.topicId);
|
|
85
88
|
}) })
|
|
86
89
|
}
|
|
87
90
|
);
|
|
88
91
|
}
|
|
92
|
+
function SignalTraceListSkeleton({ rows = 8 }) {
|
|
93
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 px-2 py-1", "aria-label": "Loading traces", "aria-busy": "true", children: Array.from({ length: rows }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-9 w-full rounded-lg" }, index)) });
|
|
94
|
+
}
|
|
95
|
+
function SignalClusterSidebarSkeleton({ rows = 5 }) {
|
|
96
|
+
return /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "min-h-0 w-72 shrink-0 overflow-y-auto border-r border-border1/60 pr-4 py-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: Array.from({ length: rows }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2 px-3 py-2", children: [
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "mt-1.5 h-2 w-2 shrink-0 rounded-full" }),
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [
|
|
99
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-1/2" }),
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-full" })
|
|
101
|
+
] })
|
|
102
|
+
] }, index)) }) });
|
|
103
|
+
}
|
|
104
|
+
function SignalDetailsSkeleton() {
|
|
105
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex h-full min-w-0 flex-col gap-4", "aria-label": "Loading signal", "aria-busy": "true", children: [
|
|
106
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-2", children: [
|
|
107
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-7 w-48" }),
|
|
108
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-64" })
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-6 border-b border-border1/60", children: [
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "mb-2 h-5 w-20" }),
|
|
112
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "mb-2 h-5 w-16" })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 gap-6 overflow-hidden", children: [
|
|
115
|
+
/* @__PURE__ */ jsxRuntime.jsx(SignalClusterSidebarSkeleton, {}),
|
|
116
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-4 py-4", children: [
|
|
117
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-9 w-full rounded-lg" }),
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsx(SignalTraceListSkeleton, {})
|
|
119
|
+
] })
|
|
120
|
+
] })
|
|
121
|
+
] });
|
|
122
|
+
}
|
|
89
123
|
function SignalTraceListTab({
|
|
90
|
-
|
|
124
|
+
examples,
|
|
91
125
|
selectedTraceId,
|
|
92
|
-
onTraceSelect
|
|
126
|
+
onTraceSelect,
|
|
127
|
+
loading = false,
|
|
128
|
+
pageSize = 25
|
|
93
129
|
}) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
);
|
|
130
|
+
const [search, setSearch] = React.useState("");
|
|
131
|
+
const [page, setPage] = React.useState(1);
|
|
132
|
+
const filtered = React.useMemo(() => {
|
|
133
|
+
const query = search.trim().toLowerCase();
|
|
134
|
+
if (!query) return examples;
|
|
135
|
+
return examples.filter((example) => example.signalText.toLowerCase().includes(query));
|
|
136
|
+
}, [examples, search]);
|
|
137
|
+
const visible = React.useMemo(() => filtered.slice(0, page * pageSize), [filtered, page, pageSize]);
|
|
138
|
+
const hasMore = visible.length < filtered.length;
|
|
139
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex min-h-0 flex-1 flex-col gap-4", "aria-label": "Topic trace summaries", children: [
|
|
140
|
+
/* @__PURE__ */ jsxRuntime.jsxs(inputGroup.InputGroup, { variant: "outline", children: [
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsx(inputGroup.InputGroupAddon, { align: "inline-start", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, {}) }),
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
143
|
+
inputGroup.InputGroupInput,
|
|
144
|
+
{
|
|
145
|
+
type: "search",
|
|
146
|
+
"aria-label": "Search traces",
|
|
147
|
+
placeholder: "Search traces",
|
|
148
|
+
onChange: (event) => {
|
|
149
|
+
setSearch(event.target.value);
|
|
150
|
+
setPage(1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
] }),
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
156
|
+
dataList.DataList,
|
|
157
|
+
{
|
|
158
|
+
columns: "minmax(12rem,1fr)",
|
|
159
|
+
className: "min-h-0 flex-1 overflow-hidden rounded-lg border border-border1/60",
|
|
160
|
+
children: [
|
|
161
|
+
/* @__PURE__ */ jsxRuntime.jsx(dataList.DataList.Top, { children: /* @__PURE__ */ jsxRuntime.jsx(dataList.DataList.TopCells, { children: /* @__PURE__ */ jsxRuntime.jsx(dataList.DataList.TopCell, { children: "Trace summary" }) }) }),
|
|
162
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx(SignalTraceListSkeleton, {}) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(dataList.DataList.NoMatch, { message: "No traces match this subtopic." }) : visible.map((example) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
+
dataList.DataList.RowButton,
|
|
164
|
+
{
|
|
165
|
+
featured: selectedTraceId === example.traceId,
|
|
166
|
+
onClick: () => onTraceSelect(example.traceId),
|
|
167
|
+
"aria-pressed": selectedTraceId === example.traceId,
|
|
168
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(dataList.DataList.TextCell, { children: example.signalText })
|
|
169
|
+
},
|
|
170
|
+
example.exampleId
|
|
171
|
+
))
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
hasMore && !loading ? /* @__PURE__ */ jsxRuntime.jsxs(Button.Button, { variant: "outline", size: "sm", onClick: () => setPage((currentPage) => currentPage + 1), children: [
|
|
176
|
+
"Load more traces (",
|
|
177
|
+
visible.length,
|
|
178
|
+
" of ",
|
|
179
|
+
filtered.length,
|
|
180
|
+
")"
|
|
181
|
+
] }) : null
|
|
182
|
+
] });
|
|
102
183
|
}
|
|
103
|
-
function SignalChartTab({
|
|
104
|
-
const
|
|
105
|
-
() =>
|
|
106
|
-
|
|
184
|
+
function SignalChartTab({ topics, points, selectedTopicIds, onTopicToggle }) {
|
|
185
|
+
const chartData = React.useMemo(
|
|
186
|
+
() => points.filter(
|
|
187
|
+
(point) => point.topicId !== void 0 && selectedTopicIds.includes(point.topicId)
|
|
188
|
+
).map((point) => ({ ...point, color: clusterColor(point.topicId) })),
|
|
189
|
+
[points, selectedTopicIds]
|
|
107
190
|
);
|
|
108
|
-
const chartData = React.useMemo(() => ee_signals_signalsChartData.getSignalChartData(selectedClusters), [selectedClusters]);
|
|
109
191
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-w-0 gap-6", children: [
|
|
110
192
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111
193
|
SignalClusterSidebar,
|
|
112
194
|
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
195
|
+
topics,
|
|
196
|
+
selectedTopicIds,
|
|
197
|
+
onTopicSelect: onTopicToggle,
|
|
116
198
|
multiple: true,
|
|
117
199
|
ariaLabel: "Chart cluster filters"
|
|
118
200
|
}
|
|
@@ -121,29 +203,30 @@ function SignalChartTab({ signal, selectedClusterIds, onClusterToggle }) {
|
|
|
121
203
|
scatterPlotChart.ScatterPlotChart,
|
|
122
204
|
{
|
|
123
205
|
data: chartData,
|
|
124
|
-
xKey: "
|
|
125
|
-
yKey: "
|
|
126
|
-
nameKey: "
|
|
206
|
+
xKey: "x",
|
|
207
|
+
yKey: "y",
|
|
208
|
+
nameKey: "topicId",
|
|
127
209
|
colorKey: "color",
|
|
128
210
|
height: "100%",
|
|
129
211
|
className: "h-full",
|
|
130
|
-
xLabel: "
|
|
131
|
-
yLabel: "
|
|
132
|
-
formatX: (value) => `${value}ms`,
|
|
133
|
-
formatY: (value) => `${value} spans`
|
|
212
|
+
xLabel: "X",
|
|
213
|
+
yLabel: "Y"
|
|
134
214
|
}
|
|
135
215
|
) })
|
|
136
216
|
] });
|
|
137
217
|
}
|
|
138
218
|
function SignalClusterTabs({
|
|
139
|
-
|
|
140
|
-
|
|
219
|
+
topics,
|
|
220
|
+
examples,
|
|
221
|
+
examplesLoading,
|
|
222
|
+
points,
|
|
223
|
+
selectedTopicId,
|
|
141
224
|
selectedTraceId,
|
|
142
|
-
|
|
225
|
+
selectedChartTopicIds,
|
|
143
226
|
activeTab,
|
|
144
227
|
onActiveTabChange,
|
|
145
|
-
|
|
146
|
-
|
|
228
|
+
onTopicSelect,
|
|
229
|
+
onChartTopicToggle,
|
|
147
230
|
onTraceSelect
|
|
148
231
|
}) {
|
|
149
232
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -159,18 +242,12 @@ function SignalClusterTabs({
|
|
|
159
242
|
/* @__PURE__ */ jsxRuntime.jsx(tabsTab.Tab, { value: "chart", children: "Chart" })
|
|
160
243
|
] }),
|
|
161
244
|
/* @__PURE__ */ jsxRuntime.jsx(tabsContent.TabContent, { value: "trace-list", className: "min-h-0 flex-1 overflow-hidden py-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-w-0 gap-6", children: [
|
|
162
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
-
SignalClusterSidebar,
|
|
164
|
-
{
|
|
165
|
-
signal,
|
|
166
|
-
selectedClusterIds: [selectedCluster.id],
|
|
167
|
-
onClusterSelect
|
|
168
|
-
}
|
|
169
|
-
),
|
|
245
|
+
/* @__PURE__ */ jsxRuntime.jsx(SignalClusterSidebar, { topics, selectedTopicIds: [selectedTopicId], onTopicSelect }),
|
|
170
246
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1 overflow-hidden py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
171
247
|
SignalTraceListTab,
|
|
172
248
|
{
|
|
173
|
-
|
|
249
|
+
examples,
|
|
250
|
+
loading: examplesLoading,
|
|
174
251
|
selectedTraceId,
|
|
175
252
|
onTraceSelect
|
|
176
253
|
}
|
|
@@ -179,54 +256,114 @@ function SignalClusterTabs({
|
|
|
179
256
|
/* @__PURE__ */ jsxRuntime.jsx(tabsContent.TabContent, { value: "chart", className: "min-h-0 flex-1 overflow-hidden py-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
180
257
|
SignalChartTab,
|
|
181
258
|
{
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
259
|
+
topics,
|
|
260
|
+
points,
|
|
261
|
+
selectedTopicIds: selectedChartTopicIds,
|
|
262
|
+
onTopicToggle: onChartTopicToggle
|
|
185
263
|
}
|
|
186
264
|
) })
|
|
187
265
|
]
|
|
188
266
|
}
|
|
189
267
|
);
|
|
190
268
|
}
|
|
191
|
-
function SignalDetailsPage({
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
269
|
+
function SignalDetailsPage({
|
|
270
|
+
signalId,
|
|
271
|
+
entity,
|
|
272
|
+
selectedTraceId,
|
|
273
|
+
initialTopicId,
|
|
274
|
+
tracePanel,
|
|
275
|
+
onTraceSelect
|
|
276
|
+
}) {
|
|
277
|
+
const { data: entities = [], isLoading: entitiesLoading, isError: entitiesError } = ee_signals_hooks_useEntityLearning.useEntities();
|
|
278
|
+
const resolvedEntity = entities.find((item) => item.entityId === entity?.entityId);
|
|
279
|
+
const {
|
|
280
|
+
data: topicsData,
|
|
281
|
+
isLoading: topicsLoading,
|
|
282
|
+
isError: topicsError
|
|
283
|
+
} = ee_signals_hooks_useEntityLearning.useEntityTopics(resolvedEntity?.entityId, signalId);
|
|
284
|
+
const topics = React.useMemo(() => topicsData?.topics ?? [], [topicsData?.topics]);
|
|
285
|
+
const runId = topicsData?.run?.runId;
|
|
286
|
+
const topicSelectionScope = `${signalId ?? ""}:${entity?.entityId ?? ""}:${runId ?? ""}:${initialTopicId ?? ""}`;
|
|
287
|
+
const chartSelectionScope = `${signalId ?? ""}:${entity?.entityId ?? ""}:${runId ?? ""}`;
|
|
288
|
+
const topicIds = React.useMemo(() => topics.map((topic) => topic.topicId), [topics]);
|
|
289
|
+
const topicIdSet = React.useMemo(() => new Set(topicIds), [topicIds]);
|
|
290
|
+
const [selectedTopic, setSelectedTopic] = React.useState(() => ({
|
|
291
|
+
scope: topicSelectionScope,
|
|
292
|
+
topicId: initialTopicId ?? null
|
|
293
|
+
}));
|
|
294
|
+
const [selectedChartTopics, setSelectedChartTopics] = React.useState(() => ({
|
|
295
|
+
scope: chartSelectionScope,
|
|
296
|
+
topicIds: null
|
|
297
|
+
}));
|
|
198
298
|
const [activeTab, setActiveTab] = React.useState("trace-list");
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
299
|
+
const requestedTopicId = selectedTopic.scope === topicSelectionScope ? selectedTopic.topicId : initialTopicId ?? null;
|
|
300
|
+
const resolvedTopicId = requestedTopicId && topicIdSet.has(requestedTopicId) ? requestedTopicId : topics[0]?.topicId;
|
|
301
|
+
const selectedTopicData = topics.find((topic) => topic.topicId === resolvedTopicId);
|
|
302
|
+
const examplesEnabled = Boolean(resolvedEntity?.entityId && signalId && runId && selectedTopicData);
|
|
303
|
+
const pointsEnabled = Boolean(resolvedEntity?.entityId && signalId && runId);
|
|
304
|
+
const chartTopicIds = selectedChartTopics.scope === chartSelectionScope && selectedChartTopics.topicIds ? selectedChartTopics.topicIds.filter((topicId) => topicIdSet.has(topicId)) : topicIds;
|
|
305
|
+
const {
|
|
306
|
+
data: examplesData,
|
|
307
|
+
isLoading: examplesLoading,
|
|
308
|
+
isFetching: examplesFetching,
|
|
309
|
+
isError: examplesError
|
|
310
|
+
} = ee_signals_hooks_useEntityLearning.useEntityTopicExamples(
|
|
311
|
+
resolvedEntity?.entityId,
|
|
312
|
+
selectedTopicData?.topicId,
|
|
313
|
+
examplesEnabled && runId && signalId ? { signalName: signalId, runId } : void 0
|
|
314
|
+
);
|
|
315
|
+
const examples = examplesData?.examples ?? [];
|
|
316
|
+
const examplesPending = examplesLoading || examplesFetching && examplesData === void 0;
|
|
317
|
+
const { data: pointsData, isError: pointsError } = ee_signals_hooks_useEntityLearning.useEntityPoints(
|
|
318
|
+
resolvedEntity?.entityId,
|
|
319
|
+
pointsEnabled && runId && signalId ? { signalName: signalId, runId, includeOutliers: true } : void 0
|
|
320
|
+
);
|
|
321
|
+
const points = pointsData?.points ?? [];
|
|
322
|
+
const handleTraceSelect = (traceId) => {
|
|
323
|
+
if (!signalId) return;
|
|
324
|
+
onTraceSelect(signalId, traceId);
|
|
205
325
|
};
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
(current) => current.includes(clusterId) ? current.filter((id) => id !== clusterId) : [...current, clusterId]
|
|
209
|
-
);
|
|
326
|
+
const handleTopicSelect = (topicId) => {
|
|
327
|
+
setSelectedTopic({ scope: topicSelectionScope, topicId });
|
|
210
328
|
};
|
|
211
|
-
|
|
329
|
+
const handleChartTopicToggle = (topicId) => {
|
|
330
|
+
setSelectedChartTopics((current) => {
|
|
331
|
+
const base = current.scope === chartSelectionScope && current.topicIds ? current.topicIds : topicIds;
|
|
332
|
+
return {
|
|
333
|
+
scope: chartSelectionScope,
|
|
334
|
+
topicIds: base.includes(topicId) ? base.filter((id) => id !== topicId) : [...base, topicId]
|
|
335
|
+
};
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
if (entitiesLoading || topicsLoading) {
|
|
339
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SignalsLayout, { sidebar: null, children: /* @__PURE__ */ jsxRuntime.jsx(SignalDetailsSkeleton, {}) });
|
|
340
|
+
}
|
|
341
|
+
if (entitiesError || topicsError || examplesEnabled && examplesError || pointsEnabled && pointsError) {
|
|
342
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SignalsLayout, { sidebar: null, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-md text-accent2", children: "Failed to load this signal from the observability endpoint." }) });
|
|
343
|
+
}
|
|
344
|
+
if (!resolvedEntity || !selectedTopicData) {
|
|
212
345
|
return /* @__PURE__ */ jsxRuntime.jsx(SignalsLayout, { sidebar: null, children: "Signal not found" });
|
|
213
346
|
}
|
|
347
|
+
const signalName = ee_signals_signalsData.getSignalCatalogEntry(signalId ?? "").name;
|
|
214
348
|
return /* @__PURE__ */ jsxRuntime.jsx(SignalsLayout, { sidebar: null, tracePanel: activeTab === "trace-list" ? tracePanel : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex h-full min-w-0 flex-col gap-4", children: [
|
|
215
349
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-1", children: [
|
|
216
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-icon-xl font-semibold text-neutral6", children:
|
|
350
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-icon-xl font-semibold text-neutral6", children: signalName }),
|
|
217
351
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-sm text-neutral3", children: "Explore trace patterns by cluster." })
|
|
218
352
|
] }),
|
|
219
353
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
220
354
|
SignalClusterTabs,
|
|
221
355
|
{
|
|
222
|
-
|
|
223
|
-
|
|
356
|
+
topics,
|
|
357
|
+
examples,
|
|
358
|
+
examplesLoading: examplesPending,
|
|
359
|
+
points,
|
|
360
|
+
selectedTopicId: selectedTopicData.topicId,
|
|
224
361
|
selectedTraceId,
|
|
225
|
-
|
|
362
|
+
selectedChartTopicIds: chartTopicIds,
|
|
226
363
|
activeTab,
|
|
227
364
|
onActiveTabChange: setActiveTab,
|
|
228
|
-
|
|
229
|
-
|
|
365
|
+
onTopicSelect: handleTopicSelect,
|
|
366
|
+
onChartTopicToggle: handleChartTopicToggle,
|
|
230
367
|
onTraceSelect: handleTraceSelect
|
|
231
368
|
}
|
|
232
369
|
) })
|