@mastra/playground-ui 21.0.1-alpha.0 → 21.0.1-alpha.1

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 CHANGED
@@ -1,5 +1,34 @@
1
1
  # @mastra/playground-ui
2
2
 
3
+ ## 21.0.1-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated scores metrics to use aggregate and time series APIs instead of fetching raw scores. Scores Over Time chart now always shows hourly data points regardless of the selected time range. Avg Score KPI uses weighted averages via the aggregate API. Updated metrics card layout to use flexible row heights and refined chart legend styling. ([#14937](https://github.com/mastra-ai/mastra/pull/14937))
8
+
9
+ - Fixed deep links for scorer, observability, and agent trace dialogs. ([#14970](https://github.com/mastra-ai/mastra/pull/14970))
10
+
11
+ Developers can now share and reload URLs that keep the selected trace, scoring tab, span, and score in Studio.
12
+
13
+ **Before**
14
+ `/observability`
15
+ `/agents/chef-agent/traces`
16
+ `/evaluation/scorers/response-quality`
17
+
18
+ **After**
19
+ `/observability?traceId=...&spanId=...&tab=scores&scoreId=...`
20
+ `/agents/chef-agent/traces?traceId=...&spanId=...&tab=scores&scoreId=...`
21
+ `/evaluation/scorers/response-quality?entity=...&scoreId=...`
22
+
23
+ This makes review links reliable across the scorer page, observability, and the agent traces view.
24
+
25
+ - Fixed light theme visibility for metrics charts: CartesianGrid lines now adapt to the current theme, and HorizontalBars use reduced opacity in light mode so labels remain readable. Updated MetricsCard minimum height. ([#14975](https://github.com/mastra-ai/mastra/pull/14975))
26
+
27
+ - Updated dependencies [[`81e4259`](https://github.com/mastra-ai/mastra/commit/81e425939b4ceeb4f586e9b6d89c3b1c1f2d2fe7), [`951b8a1`](https://github.com/mastra-ai/mastra/commit/951b8a1b5ef7e1474c59dc4f2b9fc1a8b1e508b6)]:
28
+ - @mastra/core@1.22.0-alpha.1
29
+ - @mastra/client-js@1.12.1-alpha.1
30
+ - @mastra/react@0.2.22-alpha.1
31
+
3
32
  ## 21.0.1-alpha.0
4
33
 
5
34
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -19774,8 +19774,9 @@ function ScoreDialog({
19774
19774
  usageContext = "scorerPage"
19775
19775
  }) {
19776
19776
  const [datasetDialogOpen, setDatasetDialogOpen] = React.useState(false);
19777
- const { Link } = useLinkComponent();
19777
+ const { Link, paths } = useLinkComponent();
19778
19778
  const isCodeBased = isCodeBasedScorer$1(score);
19779
+ const scorerDetailHref = score?.scorerId && score?.entityId ? `${paths.scorerLink(score.scorerId)}?entity=${encodeURIComponent(score.entityId)}&scoreId=${encodeURIComponent(score.id)}` : void 0;
19779
19780
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19780
19781
  /* @__PURE__ */ jsxRuntime.jsxs(
19781
19782
  SideDialog,
@@ -19838,7 +19839,7 @@ function ScoreDialog({
19838
19839
  ...usageContext === "SpanDialog" ? [
19839
19840
  {
19840
19841
  label: "Scorer",
19841
- value: score?.scorer?.name || "-",
19842
+ value: scorerDetailHref ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href: scorerDetailHref, children: score?.scorer?.name || "-" }) : score?.scorer?.name || "-",
19842
19843
  key: "scorer-name"
19843
19844
  }
19844
19845
  ] : [],
@@ -34486,7 +34487,10 @@ function TraceDialog({
34486
34487
  if (initialSpanId) {
34487
34488
  setSelectedSpanId(initialSpanId);
34488
34489
  setDialogIsOpen(true);
34490
+ return;
34489
34491
  }
34492
+ setSelectedSpanId(void 0);
34493
+ setDialogIsOpen(false);
34490
34494
  }, [initialSpanId]);
34491
34495
  React.useEffect(() => {
34492
34496
  if (spanScoresPage > 0) {
@@ -34517,11 +34521,17 @@ function TraceDialog({
34517
34521
  });
34518
34522
  const handleSpanClick = (id) => {
34519
34523
  if (selectedSpanId === id) {
34524
+ if (traceId) {
34525
+ navigate(computeTraceLink(traceId));
34526
+ }
34520
34527
  setSelectedSpanId(void 0);
34521
- } else {
34522
- setSelectedSpanId(id);
34523
- setSpanDialogDefaultTab("details");
34524
- setDialogIsOpen(true);
34528
+ return;
34529
+ }
34530
+ setSelectedSpanId(id);
34531
+ setSpanDialogDefaultTab("details");
34532
+ setDialogIsOpen(true);
34533
+ if (traceId) {
34534
+ navigate(computeTraceLink(traceId, id));
34525
34535
  }
34526
34536
  };
34527
34537
  const handleToScoring = () => {
@@ -39754,11 +39764,31 @@ function BulkAddToDatasetBar({
39754
39764
  ] })
39755
39765
  ] });
39756
39766
  }
39757
- function AgentTracesPanel({ agentId }) {
39767
+ function AgentTracesPanel({
39768
+ agentId,
39769
+ basePath,
39770
+ initialTraceId,
39771
+ initialSpanId,
39772
+ initialSpanTab,
39773
+ initialScoreId
39774
+ }) {
39758
39775
  const client = react.useMastraClient();
39759
39776
  const filters = useAgentTracesFilters(agentId);
39760
- const [selectedTraceId, setSelectedTraceId] = React.useState();
39761
- const [dialogIsOpen, setDialogIsOpen] = React.useState(false);
39777
+ const { navigate } = useLinkComponent();
39778
+ const buildTraceUrl = React.useCallback(
39779
+ (traceId, spanId, scoreId, tab) => {
39780
+ const params = new URLSearchParams();
39781
+ if (traceId) params.set("traceId", traceId);
39782
+ if (spanId) params.set("spanId", spanId);
39783
+ if (tab) params.set("tab", tab);
39784
+ if (scoreId) params.set("scoreId", scoreId);
39785
+ const query = params.toString();
39786
+ return query ? `${basePath ?? `/agents/${agentId}/traces`}?${query}` : basePath ?? `/agents/${agentId}/traces`;
39787
+ },
39788
+ [agentId, basePath]
39789
+ );
39790
+ const [selectedTraceId, setSelectedTraceId] = React.useState(initialTraceId);
39791
+ const [dialogIsOpen, setDialogIsOpen] = React.useState(Boolean(initialTraceId));
39762
39792
  const [checkedTraceIds, setCheckedTraceIds] = React.useState(/* @__PURE__ */ new Set());
39763
39793
  const [sort, setSort] = React.useState(null);
39764
39794
  const {
@@ -39871,20 +39901,31 @@ function AgentTracesPanel({ agentId }) {
39871
39901
  return next.size === prev.size ? prev : next;
39872
39902
  });
39873
39903
  }, [displayTraces, checkedTraceIds.size]);
39904
+ React.useEffect(() => {
39905
+ if (initialTraceId) {
39906
+ setSelectedTraceId(initialTraceId);
39907
+ setDialogIsOpen(true);
39908
+ return;
39909
+ }
39910
+ setSelectedTraceId(void 0);
39911
+ setDialogIsOpen(false);
39912
+ }, [initialTraceId]);
39874
39913
  const { batchInsertItems } = useDatasetMutations();
39875
39914
  const allSelected = displayTraces.length > 0 && displayTraces.every((t) => checkedTraceIds.has(t.traceId));
39876
39915
  const someSelected = checkedTraceIds.size > 0;
39877
39916
  const handleTraceClick = React.useCallback(
39878
39917
  (traceId) => {
39879
39918
  if (selectedTraceId === traceId) {
39919
+ navigate(buildTraceUrl());
39880
39920
  setSelectedTraceId(void 0);
39881
39921
  setDialogIsOpen(false);
39882
39922
  } else {
39923
+ navigate(buildTraceUrl(traceId));
39883
39924
  setSelectedTraceId(traceId);
39884
39925
  setDialogIsOpen(true);
39885
39926
  }
39886
39927
  },
39887
- [selectedTraceId]
39928
+ [buildTraceUrl, navigate, selectedTraceId]
39888
39929
  );
39889
39930
  const handleCheckToggle = React.useCallback((traceId, checked) => {
39890
39931
  setCheckedTraceIds((prev) => {
@@ -39923,14 +39964,16 @@ function AgentTracesPanel({ agentId }) {
39923
39964
  },
39924
39965
  [displayTraces, checkedTraceIds, batchInsertItems]
39925
39966
  );
39926
- const computeTraceLink = React.useCallback((traceId, spanId) => {
39927
- return `/observability?traceId=${traceId}${spanId ? `&spanId=${spanId}` : ""}`;
39928
- }, []);
39967
+ const computeTraceLink = React.useCallback(
39968
+ (traceId, spanId, tab) => buildTraceUrl(traceId, spanId, void 0, tab),
39969
+ [buildTraceUrl]
39970
+ );
39929
39971
  const toNextTrace = React.useMemo(
39930
39972
  () => getToNextEntryFn({
39931
39973
  entries: displayTraces.map((t) => ({ id: t.traceId })),
39932
39974
  id: selectedTraceId,
39933
39975
  update: (id) => {
39976
+ navigate(buildTraceUrl(id));
39934
39977
  setSelectedTraceId(id);
39935
39978
  setDialogIsOpen(true);
39936
39979
  }
@@ -39942,6 +39985,7 @@ function AgentTracesPanel({ agentId }) {
39942
39985
  entries: displayTraces.map((t) => ({ id: t.traceId })),
39943
39986
  id: selectedTraceId,
39944
39987
  update: (id) => {
39988
+ navigate(buildTraceUrl(id));
39945
39989
  setSelectedTraceId(id);
39946
39990
  setDialogIsOpen(true);
39947
39991
  }
@@ -40043,6 +40087,7 @@ function AgentTracesPanel({ agentId }) {
40043
40087
  traceDetails: selectedTrace?.spans?.find((s) => s.traceId === selectedTraceId && !s.parentSpanId),
40044
40088
  isOpen: dialogIsOpen,
40045
40089
  onClose: () => {
40090
+ navigate(buildTraceUrl());
40046
40091
  setDialogIsOpen(false);
40047
40092
  setSelectedTraceId(void 0);
40048
40093
  },
@@ -40050,6 +40095,9 @@ function AgentTracesPanel({ agentId }) {
40050
40095
  onPrevious: toPreviousTrace,
40051
40096
  isLoadingSpans: isSelectedTraceLoading,
40052
40097
  computeTraceLink,
40098
+ initialSpanId,
40099
+ initialSpanTab,
40100
+ initialScoreId,
40053
40101
  scorers: scorersMap,
40054
40102
  isLoadingScorers
40055
40103
  }
@@ -41906,7 +41954,7 @@ function MetricsCardRoot({ children, className }) {
41906
41954
  DashboardCard,
41907
41955
  {
41908
41956
  className: cn(
41909
- "flex-1 grid grid-rows-[4rem_20rem] gap-2 min-w-80 md:min-w-[22rem] lg:min-w-[24rem] xl:min-w-[26rem] 2xl:min-w-[30rem] 3xl:min-w-[32rem]",
41957
+ "flex-1 grid grid-rows-[4rem_1fr] min-h-72 gap-2 min-w-80 md:min-w-[22rem] lg:min-w-[24rem] xl:min-w-[26rem] 2xl:min-w-[30rem]",
41910
41958
  className
41911
41959
  ),
41912
41960
  children
@@ -42057,12 +42105,12 @@ function MetricsLineChart({
42057
42105
  yDomain
42058
42106
  }) {
42059
42107
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
42060
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap w-full items-end gap-4 gap-y-1 mb-4", children: series.map((s) => {
42108
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap w-full items-end gap-4 gap-y-1 mb-4 ", children: series.map((s) => {
42061
42109
  const aggregated = s.aggregate?.(data);
42062
42110
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-baseline gap-2", children: [
42063
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-2 shrink-0 rounded-full translate-y-[-1px]", style: { backgroundColor: s.color } }),
42111
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-2 shrink-0 rounded-full -translate-y-px", style: { backgroundColor: s.color } }),
42064
42112
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-sm text-neutral3 truncate max-w-24", children: s.label }),
42065
- aggregated && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-lg text-neutral4", children: [
42113
+ aggregated && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-sm text-neutral4", children: [
42066
42114
  aggregated.value,
42067
42115
  aggregated.suffix && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-sm text-neutral2", children: [
42068
42116
  " ",
@@ -42072,7 +42120,15 @@ function MetricsLineChart({
42072
42120
  ] }, s.dataKey);
42073
42121
  }) }),
42074
42122
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data, children: [
42075
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { stroke: "rgba(255,255,255,0.08)", vertical: false }),
42123
+ /* @__PURE__ */ jsxRuntime.jsx(
42124
+ recharts.CartesianGrid,
42125
+ {
42126
+ stroke: "currentColor",
42127
+ strokeOpacity: 0.08,
42128
+ vertical: false,
42129
+ className: "text-black dark:text-white"
42130
+ }
42131
+ ),
42076
42132
  /* @__PURE__ */ jsxRuntime.jsx(
42077
42133
  recharts.XAxis,
42078
42134
  {
@@ -42183,24 +42239,25 @@ function useAvgScoreKpiMetrics() {
42183
42239
  if (scorerIds.length === 0) {
42184
42240
  return { value: null, previousValue: null, changePercent: null };
42185
42241
  }
42186
- const allResults = await Promise.all(
42187
- scorerIds.map((scorerId) => client.listScoresByScorerId({ scorerId, perPage: 100 }))
42242
+ const filters = {
42243
+ timestamp: { start: timestamp.start, end: timestamp.end }
42244
+ };
42245
+ const results = await Promise.all(
42246
+ scorerIds.map(async (scorerId) => {
42247
+ const [avg2, count] = await Promise.all([
42248
+ client.getScoreAggregate({ scorerId, aggregation: "avg", filters }),
42249
+ client.getScoreAggregate({ scorerId, aggregation: "count", filters })
42250
+ ]);
42251
+ return { avg: avg2.value ?? 0, count: count.value ?? 0 };
42252
+ })
42188
42253
  );
42189
- const startMs = timestamp.start.getTime();
42190
- const endMs = timestamp.end.getTime();
42191
- const allScoreValues = [];
42192
- for (const result of allResults) {
42193
- for (const s of result?.scores ?? []) {
42194
- const ts = new Date(s.createdAt).getTime();
42195
- if (ts >= startMs && ts <= endMs) {
42196
- allScoreValues.push(s.score);
42197
- }
42198
- }
42199
- }
42200
- if (allScoreValues.length === 0) {
42254
+ const withData = results.filter((r) => r.count > 0);
42255
+ if (withData.length === 0) {
42201
42256
  return { value: null, previousValue: null, changePercent: null };
42202
42257
  }
42203
- const avg = allScoreValues.reduce((sum, v) => sum + v, 0) / allScoreValues.length;
42258
+ const totalCount = withData.reduce((sum, r) => sum + r.count, 0);
42259
+ const weightedSum = withData.reduce((sum, r) => sum + r.avg * r.count, 0);
42260
+ const avg = weightedSum / totalCount;
42204
42261
  return { value: Math.round(avg * 100) / 100, previousValue: null, changePercent: null };
42205
42262
  }
42206
42263
  });
@@ -42479,78 +42536,84 @@ function useScoresMetrics() {
42479
42536
  return reactQuery.useQuery({
42480
42537
  queryKey: ["metrics", "scores-card", datePreset, customRange],
42481
42538
  queryFn: async () => {
42539
+ const filters = {
42540
+ timestamp: { start: timestamp.start, end: timestamp.end }
42541
+ };
42482
42542
  const scorersMap = await client.listScorers();
42483
42543
  const scorerIds = Object.keys(scorersMap ?? {});
42484
42544
  if (scorerIds.length === 0) {
42485
42545
  return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };
42486
42546
  }
42487
- const allResults = await Promise.all(
42488
- // Limited to 100 most recent scores per scorer; pagination not yet implemented
42489
- scorerIds.map((scorerId) => client.listScoresByScorerId({ scorerId, perPage: 100 }))
42547
+ const summaryResults = await Promise.all(
42548
+ scorerIds.map(async (scorerId) => {
42549
+ const [avg, min, max, count] = await Promise.all([
42550
+ client.getScoreAggregate({ scorerId, aggregation: "avg", filters }),
42551
+ client.getScoreAggregate({ scorerId, aggregation: "min", filters }),
42552
+ client.getScoreAggregate({ scorerId, aggregation: "max", filters }),
42553
+ client.getScoreAggregate({ scorerId, aggregation: "count", filters })
42554
+ ]);
42555
+ return {
42556
+ scorer: scorerId,
42557
+ avg: avg.value ?? 0,
42558
+ min: min.value ?? 0,
42559
+ max: max.value ?? 0,
42560
+ count: count.value ?? 0
42561
+ };
42562
+ })
42490
42563
  );
42491
- const startMs = timestamp.start.getTime();
42492
- const endMs = timestamp.end.getTime();
42493
- const allScores = [];
42494
- for (let i = 0; i < scorerIds.length; i++) {
42495
- const scores = allResults[i]?.scores ?? [];
42496
- for (const s of scores) {
42497
- const ts = new Date(s.createdAt).getTime();
42498
- if (ts >= startMs && ts <= endMs) {
42499
- allScores.push({
42500
- scorerId: scorerIds[i],
42501
- score: s.score,
42502
- createdAt: s.createdAt
42503
- });
42504
- }
42505
- }
42506
- }
42507
- if (allScores.length === 0) {
42508
- return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };
42509
- }
42510
- const byScorer = /* @__PURE__ */ new Map();
42511
- for (const s of allScores) {
42512
- if (!byScorer.has(s.scorerId)) byScorer.set(s.scorerId, []);
42513
- byScorer.get(s.scorerId).push(s.score);
42514
- }
42515
- const summaryData = Array.from(byScorer.entries()).map(([scorer, vals]) => ({
42516
- scorer,
42517
- avg: vals.reduce((a, b) => a + b, 0) / vals.length,
42518
- min: Math.min(...vals),
42519
- max: Math.max(...vals),
42520
- count: vals.length
42521
- }));
42564
+ const summaryData = summaryResults.filter((s) => s.count > 0);
42522
42565
  const scorerNames = summaryData.map((s) => s.scorer);
42523
- const avgScore = summaryData.reduce((s, d) => s + d.avg, 0) / summaryData.length;
42524
- const bucketMap = /* @__PURE__ */ new Map();
42525
- for (const s of allScores) {
42526
- const ts = new Date(s.createdAt);
42527
- const bucket = Math.floor(ts.getTime() / 36e5) * 36e5;
42528
- if (!bucketMap.has(bucket)) bucketMap.set(bucket, /* @__PURE__ */ new Map());
42529
- const scorerMap = bucketMap.get(bucket);
42530
- if (!scorerMap.has(s.scorerId)) scorerMap.set(s.scorerId, []);
42531
- scorerMap.get(s.scorerId).push(s.score);
42566
+ if (summaryData.length === 0) {
42567
+ return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };
42532
42568
  }
42533
- const overTimeData = Array.from(bucketMap.entries()).sort(([a], [b]) => a - b).map(([bucket, scorerMap]) => {
42534
- const point = {
42535
- time: new Date(bucket).toLocaleTimeString("en-US", {
42536
- hour: "2-digit",
42537
- minute: "2-digit",
42538
- hour12: false
42569
+ const totalWeighted = summaryData.reduce((s, d) => s + d.avg * d.count, 0);
42570
+ const totalCount = summaryData.reduce((s, d) => s + d.count, 0);
42571
+ const avgScore = totalCount ? Math.round(totalWeighted / totalCount * 100) / 100 : 0;
42572
+ const interval = "1h";
42573
+ const timeSeriesResults = await Promise.all(
42574
+ scorerNames.map(
42575
+ (scorerId) => client.getScoreTimeSeries({
42576
+ scorerId,
42577
+ interval,
42578
+ aggregation: "avg",
42579
+ filters
42539
42580
  })
42540
- };
42541
- for (const name of scorerNames) {
42542
- const vals = scorerMap.get(name);
42543
- if (vals && vals.length > 0) {
42544
- point[name] = +(vals.reduce((a, b) => a + b, 0) / vals.length).toFixed(2);
42581
+ )
42582
+ );
42583
+ const bucketMap = /* @__PURE__ */ new Map();
42584
+ const rangeSpansDays = timestamp.end.toDateString() !== timestamp.start.toDateString();
42585
+ for (let i = 0; i < scorerNames.length; i++) {
42586
+ const scorerId = scorerNames[i];
42587
+ const series = timeSeriesResults[i]?.series ?? [];
42588
+ for (const s of series) {
42589
+ for (const point of s.points) {
42590
+ const ts = new Date(point.timestamp);
42591
+ const key = ts.toISOString();
42592
+ if (!bucketMap.has(key)) {
42593
+ bucketMap.set(key, {
42594
+ time: rangeSpansDays ? ts.toLocaleString("en-US", {
42595
+ month: "short",
42596
+ day: "numeric",
42597
+ hour: "2-digit",
42598
+ minute: "2-digit",
42599
+ hour12: false
42600
+ }) : ts.toLocaleTimeString("en-US", {
42601
+ hour: "2-digit",
42602
+ minute: "2-digit",
42603
+ hour12: false
42604
+ })
42605
+ });
42606
+ }
42607
+ bucketMap.get(key)[scorerId] = +point.value.toFixed(2);
42545
42608
  }
42546
42609
  }
42547
- return point;
42548
- });
42610
+ }
42611
+ const overTimeData = Array.from(bucketMap.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, point]) => point);
42549
42612
  return {
42550
42613
  summaryData,
42551
42614
  overTimeData,
42552
42615
  scorerNames,
42553
- avgScore: Math.round(avgScore * 100) / 100
42616
+ avgScore
42554
42617
  };
42555
42618
  }
42556
42619
  });
@@ -42595,7 +42658,7 @@ function ScoresCard() {
42595
42658
  /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "over-time", children: "Over Time" }),
42596
42659
  /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "summary", children: "Summary" })
42597
42660
  ] }),
42598
- /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "over-time", children: data.overTimeData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(MetricsLineChart, { data: data.overTimeData, series, yDomain: [0, 1] }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No time series data yet" }) }),
42661
+ /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "over-time", className: "pb-0", children: data.overTimeData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(MetricsLineChart, { data: data.overTimeData, series, yDomain: [0, 1] }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No time series data yet" }) }),
42599
42662
  /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "summary", children: /* @__PURE__ */ jsxRuntime.jsx(
42600
42663
  MetricsDataTable,
42601
42664
  {
@@ -42733,7 +42796,7 @@ function HorizontalBars({
42733
42796
  "div",
42734
42797
  {
42735
42798
  className: cn(
42736
- "absolute inset-y-0",
42799
+ "absolute inset-y-0 opacity-40 dark:opacity-100",
42737
42800
  si === 0 && "rounded-l",
42738
42801
  isLastWithValue && "rounded-r"
42739
42802
  ),
@@ -42749,7 +42812,7 @@ function HorizontalBars({
42749
42812
  return /* @__PURE__ */ jsxRuntime.jsx(
42750
42813
  "div",
42751
42814
  {
42752
- className: "absolute inset-y-0 left-0 rounded",
42815
+ className: "absolute inset-y-0 left-0 rounded opacity-40 dark:opacity-100",
42753
42816
  style: { width: `${pct}%`, backgroundColor: seg.color }
42754
42817
  },
42755
42818
  seg.label
@@ -43845,6 +43908,9 @@ function SpanScoreList({
43845
43908
  const score = scoresData?.scores?.find((s) => s?.id === scoreId);
43846
43909
  setSelectedScore(score);
43847
43910
  setDialogIsOpen(true);
43911
+ if (traceId) {
43912
+ navigate(`${computeTraceLink(traceId, spanId)}&tab=scores&scoreId=${encodeURIComponent(scoreId)}`);
43913
+ }
43848
43914
  };
43849
43915
  if (isLoadingScoresData) {
43850
43916
  return /* @__PURE__ */ jsxRuntime.jsx(EntryListSkeleton, { columns: traceScoresListColumns });