@parca/profile 0.19.75 → 0.19.76
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 +4 -0
- package/dist/MetricsGraph/UtilizationMetrics/index.d.ts.map +1 -1
- package/dist/MetricsGraph/UtilizationMetrics/index.js +4 -1
- package/dist/MetricsGraph/index.d.ts +1 -0
- package/dist/MetricsGraph/index.d.ts.map +1 -1
- package/dist/MetricsGraph/index.js +6 -2
- package/dist/ProfileSelector/MetricsGraphSection.d.ts.map +1 -1
- package/dist/ProfileSelector/MetricsGraphSection.js +6 -6
- package/dist/ProfileSelector/index.d.ts +2 -1
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +25 -19
- package/dist/hooks/useQueryState.js +2 -1
- package/dist/useSumBy.js +1 -1
- package/package.json +2 -2
- package/src/MetricsGraph/UtilizationMetrics/index.tsx +4 -1
- package/src/MetricsGraph/index.tsx +7 -2
- package/src/ProfileSelector/MetricsGraphSection.tsx +17 -19
- package/src/ProfileSelector/index.tsx +25 -16
- package/src/hooks/useQueryState.ts +2 -2
- package/src/useSumBy.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.19.76](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.75...@parca/profile@0.19.76) (2025-11-19)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
6
10
|
## [0.19.75](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.74...@parca/profile@0.19.75) (2025-11-18)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/MetricsGraph/UtilizationMetrics/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACL,aAAa,EAId,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAC,KAAK,kBAAkB,IAAI,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAI9E,UAAU,WAAW;IACnB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAYD,KAAK,KAAK,GAAG,WAAW,GAAG;IACzB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,eAAe,CAAC,EAAE,CAChB,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KAAK,IAAI,CAAC;CAChF,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/MetricsGraph/UtilizationMetrics/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACL,aAAa,EAId,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAC,KAAK,kBAAkB,IAAI,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAI9E,UAAU,WAAW;IACnB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAYD,KAAK,KAAK,GAAG,WAAW,GAAG;IACzB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,eAAe,CAAC,EAAE,CAChB,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KAAK,IAAI,CAAC;CAChF,CAAC;AA4TF,QAAA,MAAM,kBAAkB,GAAI,6KAWzB,KAAK,KAAG,GAAG,CAAC,OAwCd,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -122,7 +122,10 @@ const _getYAxisUnit = (name) => {
|
|
|
122
122
|
};
|
|
123
123
|
const RawUtilizationMetrics = ({ data, originalData, setTimeRange, width, height, margin, humanReadableName, from, to, yAxisUnit, contextMenuItems, onSeriesClick, }) => {
|
|
124
124
|
const { timezone } = useParcaContext();
|
|
125
|
-
return (_jsx(MetricsGraph, { data: data,
|
|
125
|
+
return (_jsx(MetricsGraph, { data: data.map((val, idx) => ({
|
|
126
|
+
...val,
|
|
127
|
+
highlighted: originalData?.[idx]?.isSelected ?? false,
|
|
128
|
+
})), from: from, to: to, setTimeRange: setTimeRange, onSampleClick: closestPoint => {
|
|
126
129
|
if (onSeriesClick != null) {
|
|
127
130
|
onSeriesClick(closestPoint.seriesIndex);
|
|
128
131
|
}
|
|
@@ -29,6 +29,7 @@ export interface HighlightedSeries {
|
|
|
29
29
|
export interface Series {
|
|
30
30
|
id: string;
|
|
31
31
|
values: Array<[number, number]>;
|
|
32
|
+
highlighted?: boolean;
|
|
32
33
|
}
|
|
33
34
|
declare const MetricsGraph: ({ data, from, to, onSampleClick, setTimeRange, yAxisLabel, yAxisUnit, width, height, margin, selectedPoint, contextMenuItems, renderTooltipContent, }: Props) => JSX.Element;
|
|
34
35
|
export default MetricsGraph;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MetricsGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAOrF,OAAO,EAAC,aAAa,EAAkB,MAAM,mBAAmB,CAAC;AAMjE,OAA2B,EACzB,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAI9B,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,CAAC,YAAY,EAAE,WAAW,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC9C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CACrF;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MetricsGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAOrF,OAAO,EAAC,aAAa,EAAkB,MAAM,mBAAmB,CAAC;AAMjE,OAA2B,EACzB,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAI9B,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,CAAC,YAAY,EAAE,WAAW,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC9C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CACrF;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,YAAY,GAAI,uJAcnB,KAAK,KAAG,GAAG,CAAC,OA+Bd,CAAC;AAEF,eAAe,YAAY,CAAC;AAC5B,YAAY,EAAC,wBAAwB,EAAE,eAAe,EAAE,kBAAkB,EAAC,CAAC;AAE5E,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,IAKnD,CAAC;AAKF,eAAO,MAAM,eAAe,GAAI,uJAc7B,KAAK,KAAG,GAAG,CAAC,OAibd,CAAC"}
|
|
@@ -85,7 +85,10 @@ export const RawMetricsGraph = ({ data, from, to, onSampleClick, setTimeRange, y
|
|
|
85
85
|
}, [series]);
|
|
86
86
|
const l = d3.line(d => xScale(d[0]), d => yScale(d[1]));
|
|
87
87
|
const closestPoint = useMemo(() => {
|
|
88
|
-
//
|
|
88
|
+
// Guard against empty series
|
|
89
|
+
if (series.length === 0) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
89
92
|
const closestPointPerSeries = series.map(function (s) {
|
|
90
93
|
const distances = s.values.map(d => {
|
|
91
94
|
const x = xScale(d[0]) + margin / 2; // d[0] is timestamp_ms
|
|
@@ -219,7 +222,8 @@ export const RawMetricsGraph = ({ data, from, to, onSampleClick, setTimeRange, y
|
|
|
219
222
|
transform: `translate(0, ${yScale(d)})`, children: [_jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x2: -6 }), _jsx("text", { fill: "currentColor", x: -9, dy: '0.32em', children: valueFormatter(d, yAxisUnit, decimals) })] }, `tick-${i}`), _jsx("g", { children: _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: xScale(from), x2: xScale(to), y1: yScale(d), y2: yScale(d) }) }, `grid-${i}`)] }, `${i.toString()}-${d.toString()}`));
|
|
220
223
|
}), _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: 0, x2: 0, y1: 0, y2: height - margin }), _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: xScale(to), x2: xScale(to), y1: 0, y2: height - margin }), _jsx("g", { transform: `translate(${-margin}, ${(height - margin) / 2}) rotate(270)`, children: _jsx("text", { fill: "currentColor", dy: "-0.7em", className: "text-sm capitalize", textAnchor: "middle", children: yAxisLabel }) })] }), _jsxs("g", { className: "x axis", fill: "none", fontSize: "10", textAnchor: "middle", transform: `translate(0,${height - margin})`, children: [xScale.ticks(5).map((d, i) => (_jsxs(Fragment, { children: [_jsxs("g", { className: "tick",
|
|
221
224
|
/* eslint-disable-next-line @typescript-eslint/restrict-template-expressions */
|
|
222
|
-
transform: `translate(${xScale(d)}, 0)`, children: [_jsx("line", { y2: 6, className: "stroke-gray-300 dark:stroke-gray-500" }), _jsx("text", { fill: "currentColor", dy: ".71em", y: 9, children: formatDate(d, formatForTimespan(from, to), timezone) })] }, `tick-${i}`), _jsx("g", { children: _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: xScale(d), x2: xScale(d), y1: 0, y2: -height + margin }) }, `grid-${i}`)] }, `${i.toString()}-${d.toString()}`))), _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: 0, x2: graphWidth, y1: 0, y2: 0 }), _jsx("g", { transform: `translate(${(width - 2.5 * margin) / 2}, ${margin / 2})`, children: _jsx("text", { fill: "currentColor", dy: ".71em", y: 5, className: "text-sm", children: "Time" }) })] }), _jsx("g", { className: "lines fill-transparent", transform: graphTransform, width: graphWidth - 100, children: series.map((s, i) => (_jsx("g", { className: "line", children: _jsx(MetricsSeries, { data: s, line: l, color: color(s.id), strokeWidth: hovering && highlighted != null && i === highlighted.seriesIndex
|
|
225
|
+
transform: `translate(${xScale(d)}, 0)`, children: [_jsx("line", { y2: 6, className: "stroke-gray-300 dark:stroke-gray-500" }), _jsx("text", { fill: "currentColor", dy: ".71em", y: 9, children: formatDate(d, formatForTimespan(from, to), timezone) })] }, `tick-${i}`), _jsx("g", { children: _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: xScale(d), x2: xScale(d), y1: 0, y2: -height + margin }) }, `grid-${i}`)] }, `${i.toString()}-${d.toString()}`))), _jsx("line", { className: "stroke-gray-300 dark:stroke-gray-500", x1: 0, x2: graphWidth, y1: 0, y2: 0 }), _jsx("g", { transform: `translate(${(width - 2.5 * margin) / 2}, ${margin / 2})`, children: _jsx("text", { fill: "currentColor", dy: ".71em", y: 5, className: "text-sm", children: "Time" }) })] }), _jsx("g", { className: "lines fill-transparent", transform: graphTransform, width: graphWidth - 100, children: series.map((s, i) => (_jsx("g", { className: "line", children: _jsx(MetricsSeries, { data: s, line: l, color: color(s.id), strokeWidth: (hovering && highlighted != null && i === highlighted.seriesIndex) ||
|
|
226
|
+
s.highlighted === true
|
|
223
227
|
? lineStrokeHover
|
|
224
228
|
: lineStroke, xScale: xScale, yScale: yScale }) }, s.id))) }), hovering && highlighted != null && (_jsx("g", { className: "circle-group", ref: metricPointRef, style: { fill: color(series[highlighted.seriesIndex]?.id ?? '0') }, transform: graphTransform, children: _jsx(MetricsCircle, { cx: highlighted.x, cy: highlighted.y }) })), selected != null && (_jsx("g", { className: "circle-group", style: selected?.seriesIndex != null
|
|
225
229
|
? { fill: color(series[selected.seriesIndex]?.id ?? '0') }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricsGraphSection.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/MetricsGraphSection.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAQ,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACxD,OAAO,EAAC,aAAa,EAAmB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAC,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAKpC,OAAO,EAAC,cAAc,EAAE,KAAK,kBAAkB,IAAI,sBAAsB,EAAC,MAAM,SAAS,CAAC;AAE1F,UAAU,wBAAwB;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gCAAgC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAChF,KAAK,EAAE,KAAK,CAAC;IACb,qBAAqB,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3E,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,IAAI,EAAE,sBAAsB,EAAE,CAAC;KAChC,CAAC,CAAC;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,yBAAyB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,mBAAmB,CAAC,EAClC,gBAAgB,EAChB,gCAAgC,EAChC,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,KAAK,EACL,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,GAC1B,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"MetricsGraphSection.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/MetricsGraphSection.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAQ,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACxD,OAAO,EAAC,aAAa,EAAmB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAC,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAKpC,OAAO,EAAC,cAAc,EAAE,KAAK,kBAAkB,IAAI,sBAAsB,EAAC,MAAM,SAAS,CAAC;AAE1F,UAAU,wBAAwB;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gCAAgC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAChF,KAAK,EAAE,KAAK,CAAC;IACb,qBAAqB,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3E,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,IAAI,EAAE,sBAAsB,EAAE,CAAC;KAChC,CAAC,CAAC;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,yBAAyB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,mBAAmB,CAAC,EAClC,gBAAgB,EAChB,gCAAgC,EAChC,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,KAAK,EACL,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,GAC1B,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CA4MxC"}
|
|
@@ -91,12 +91,12 @@ export function MetricsGraphSection({ showMetricsGraph, setDisplayHideMetricsGra
|
|
|
91
91
|
return (_jsxs("div", { children: [utilizationMetrics.map(({ name, humanReadableName, data }) => {
|
|
92
92
|
if (name !== 'gpu_pcie_throughput_transmit_bytes' &&
|
|
93
93
|
name !== 'gpu_pcie_throughput_receive_bytes') {
|
|
94
|
-
return (_jsx(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
return (_jsx(UtilizationMetricsGraph, { data: data, setTimeRange: handleTimeRangeChange, utilizationMetricsLoading: utilizationMetricsLoading, humanReadableName: humanReadableName, from: querySelection.from, to: querySelection.to, yAxisUnit: "percentage", addLabelMatcher: addLabelMatcher, onSeriesClick: seriesIndex => {
|
|
95
|
+
// For generic UtilizationMetrics, just pass the series index
|
|
96
|
+
if (onUtilizationSeriesSelect != null) {
|
|
97
|
+
onUtilizationSeriesSelect(seriesIndex);
|
|
98
|
+
}
|
|
99
|
+
} }, name));
|
|
100
100
|
}
|
|
101
101
|
return null;
|
|
102
102
|
}), throughputMetrics.length > 0 && (_jsx(AreaChart, { transmitData: throughputMetrics.find(metric => metric.name === 'gpu_pcie_throughput_transmit_bytes')
|
|
@@ -53,6 +53,7 @@ interface ProfileSelectorProps extends ProfileSelectorFeatures {
|
|
|
53
53
|
utilizationMetricsLoading?: boolean;
|
|
54
54
|
utilizationLabels?: UtilizationLabels;
|
|
55
55
|
onUtilizationSeriesSelect?: (seriesIndex: number) => void;
|
|
56
|
+
onSearchHook?: () => void;
|
|
56
57
|
}
|
|
57
58
|
export interface IProfileTypesResult {
|
|
58
59
|
loading: boolean;
|
|
@@ -60,6 +61,6 @@ export interface IProfileTypesResult {
|
|
|
60
61
|
error?: RpcError;
|
|
61
62
|
}
|
|
62
63
|
export declare const useProfileTypes: (client: QueryServiceClient, start?: number, end?: number) => IProfileTypesResult;
|
|
63
|
-
declare const ProfileSelector: ({ queryClient, closeProfile, enforcedProfileName, comparing, navigateTo, showMetricsGraph, showSumBySelector, showProfileTypeSelector, disableExplorativeQuerying, setDisplayHideMetricsGraphButton, suffix, utilizationMetrics, utilizationMetricsLoading, utilizationLabels, onUtilizationSeriesSelect, }: ProfileSelectorProps) => JSX.Element;
|
|
64
|
+
declare const ProfileSelector: ({ queryClient, closeProfile, enforcedProfileName, comparing, navigateTo, showMetricsGraph, showSumBySelector, showProfileTypeSelector, disableExplorativeQuerying, setDisplayHideMetricsGraphButton, suffix, utilizationMetrics, utilizationMetricsLoading, utilizationLabels, onUtilizationSeriesSelect, onSearchHook, }: ProfileSelectorProps) => JSX.Element;
|
|
64
65
|
export default ProfileSelector;
|
|
65
66
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAoD,MAAM,OAAO,CAAC;AAElG,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAsB,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAoD,MAAM,OAAO,CAAC;AAElG,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAsB,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAY5F,OAAO,EAAyB,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAW/E,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,uBAAuB;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE;QACR,MAAM,EAAE,KAAK,CAAC;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;KACJ,CAAC;IACF,OAAO,EAAE,KAAK,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,2BAA2B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,UAAU,oBAAqB,SAAQ,uBAAuB;IAC5D,WAAW,EAAE,kBAAkB,CAAC;IAChC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,gCAAgC,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,KAAK,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,IAAI,EAAE,kBAAkB,EAAE,CAAC;KAC5B,CAAC,CAAC;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,yBAAyB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAC1B,QAAQ,kBAAkB,EAC1B,QAAQ,MAAM,EACd,MAAM,MAAM,KACX,mBAsBF,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,2TAiBtB,oBAAoB,KAAG,GAAG,CAAC,OA8N7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -12,7 +12,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
15
|
-
import { DateTimeRange, IconButton, useGrpcMetadata, useParcaContext, useURLState, } from '@parca/components';
|
|
15
|
+
import { DateTimeRange, IconButton, useGrpcMetadata, useParcaContext, useURLState, useURLStateBatch, } from '@parca/components';
|
|
16
16
|
import { CloseIcon } from '@parca/icons';
|
|
17
17
|
import { Query } from '@parca/parser';
|
|
18
18
|
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
@@ -45,10 +45,11 @@ export const useProfileTypes = (client, start, end) => {
|
|
|
45
45
|
});
|
|
46
46
|
return { loading: isLoading, data, error: error };
|
|
47
47
|
};
|
|
48
|
-
const ProfileSelector = ({ queryClient, closeProfile, enforcedProfileName, comparing, navigateTo, showMetricsGraph = true, showSumBySelector = true, showProfileTypeSelector = true, disableExplorativeQuerying = false, setDisplayHideMetricsGraphButton, suffix, utilizationMetrics, utilizationMetricsLoading, utilizationLabels, onUtilizationSeriesSelect, }) => {
|
|
48
|
+
const ProfileSelector = ({ queryClient, closeProfile, enforcedProfileName, comparing, navigateTo, showMetricsGraph = true, showSumBySelector = true, showProfileTypeSelector = true, disableExplorativeQuerying = false, setDisplayHideMetricsGraphButton, suffix, utilizationMetrics, utilizationMetricsLoading, utilizationLabels, onUtilizationSeriesSelect, onSearchHook, }) => {
|
|
49
49
|
const { heightStyle } = useMetricsGraphDimensions(comparing, utilizationMetrics != null);
|
|
50
50
|
const { viewComponent } = useParcaContext();
|
|
51
51
|
const [queryBrowserMode, setQueryBrowserMode] = useURLState('query_browser_mode');
|
|
52
|
+
const batchUpdates = useURLStateBatch();
|
|
52
53
|
// Use the new useQueryState hook - reads directly from URL params
|
|
53
54
|
const { querySelection, draftSelection, setDraftExpression, setDraftTimeRange, setDraftSumBy, setDraftProfileName, setDraftMatchers, commitDraft, profileSelection, setProfileSelection, sumByLoading, } = useQueryState({ suffix });
|
|
54
55
|
// Use draft state for local state instead of committed state
|
|
@@ -88,23 +89,28 @@ const ProfileSelector = ({ queryClient, closeProfile, enforcedProfileName, compa
|
|
|
88
89
|
const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(queryExpressionString);
|
|
89
90
|
const selectedProfileName = query.profileName();
|
|
90
91
|
const setQueryExpression = (updateTs = false) => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
batchUpdates(() => {
|
|
93
|
+
if (onSearchHook != null) {
|
|
94
|
+
onSearchHook();
|
|
95
|
+
}
|
|
96
|
+
// When updateTs is true, re-evaluate the time range to current values
|
|
97
|
+
if (updateTs) {
|
|
98
|
+
// Force re-evaluation of time range (important for relative ranges like "last 15 minutes")
|
|
99
|
+
const currentFrom = timeRangeSelection.getFromMs(true);
|
|
100
|
+
const currentTo = timeRangeSelection.getToMs(true);
|
|
101
|
+
const currentRangeKey = timeRangeSelection.getRangeKey();
|
|
102
|
+
// Commit with refreshed time range
|
|
103
|
+
commitDraft({
|
|
104
|
+
from: currentFrom,
|
|
105
|
+
to: currentTo,
|
|
106
|
+
timeSelection: currentRangeKey,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Commit the draft with existing values
|
|
111
|
+
commitDraft();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
108
114
|
};
|
|
109
115
|
const setMatchersString = (matchers) => {
|
|
110
116
|
// Update draft state only
|
|
@@ -114,12 +114,13 @@ export const useQueryState = (options = {}) => {
|
|
|
114
114
|
const draftMergeTo = isDelta
|
|
115
115
|
? (BigInt(draftTimeRange.getToMs()) * 1000000n).toString()
|
|
116
116
|
: undefined;
|
|
117
|
+
const finalSumBy = draftSumBy ?? computedSumByFromURL;
|
|
117
118
|
return {
|
|
118
119
|
expression: draftExpression ?? defaultExpression,
|
|
119
120
|
from: draftTimeRange.getFromMs(),
|
|
120
121
|
to: draftTimeRange.getToMs(),
|
|
121
122
|
timeSelection: draftTimeRange.getRangeKey(),
|
|
122
|
-
sumBy:
|
|
123
|
+
sumBy: finalSumBy, // Use draft if set, otherwise fallback to computed
|
|
123
124
|
...(draftMergeFrom !== undefined &&
|
|
124
125
|
draftMergeFrom !== '' &&
|
|
125
126
|
draftMergeTo !== undefined &&
|
package/dist/useSumBy.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.76",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@floating-ui/react": "^0.27.12",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"access": "public",
|
|
80
80
|
"registry": "https://registry.npmjs.org/"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "11845257fa22f46033a9c1c5526721619b7aa2b7"
|
|
83
83
|
}
|
|
@@ -201,7 +201,10 @@ const RawUtilizationMetrics = ({
|
|
|
201
201
|
|
|
202
202
|
return (
|
|
203
203
|
<MetricsGraph
|
|
204
|
-
data={data
|
|
204
|
+
data={data.map((val, idx) => ({
|
|
205
|
+
...val,
|
|
206
|
+
highlighted: originalData?.[idx]?.isSelected ?? false,
|
|
207
|
+
}))}
|
|
205
208
|
from={from}
|
|
206
209
|
to={to}
|
|
207
210
|
setTimeRange={setTimeRange}
|
|
@@ -63,6 +63,7 @@ export interface HighlightedSeries {
|
|
|
63
63
|
export interface Series {
|
|
64
64
|
id: string; // opaque string used to determine line color
|
|
65
65
|
values: Array<[number, number]>; // [timestamp_ms, value]
|
|
66
|
+
highlighted?: boolean;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
const MetricsGraph = ({
|
|
@@ -200,7 +201,10 @@ export const RawMetricsGraph = ({
|
|
|
200
201
|
);
|
|
201
202
|
|
|
202
203
|
const closestPoint = useMemo(() => {
|
|
203
|
-
//
|
|
204
|
+
// Guard against empty series
|
|
205
|
+
if (series.length === 0) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
204
208
|
|
|
205
209
|
const closestPointPerSeries = series.map(function (s) {
|
|
206
210
|
const distances = s.values.map(d => {
|
|
@@ -530,7 +534,8 @@ export const RawMetricsGraph = ({
|
|
|
530
534
|
line={l}
|
|
531
535
|
color={color(s.id)}
|
|
532
536
|
strokeWidth={
|
|
533
|
-
hovering && highlighted != null && i === highlighted.seriesIndex
|
|
537
|
+
(hovering && highlighted != null && i === highlighted.seriesIndex) ||
|
|
538
|
+
s.highlighted === true
|
|
534
539
|
? lineStrokeHover
|
|
535
540
|
: lineStroke
|
|
536
541
|
}
|
|
@@ -174,25 +174,23 @@ export function MetricsGraphSection({
|
|
|
174
174
|
name !== 'gpu_pcie_throughput_receive_bytes'
|
|
175
175
|
) {
|
|
176
176
|
return (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
/>
|
|
195
|
-
</>
|
|
177
|
+
<UtilizationMetricsGraph
|
|
178
|
+
key={name}
|
|
179
|
+
data={data}
|
|
180
|
+
setTimeRange={handleTimeRangeChange}
|
|
181
|
+
utilizationMetricsLoading={utilizationMetricsLoading}
|
|
182
|
+
humanReadableName={humanReadableName}
|
|
183
|
+
from={querySelection.from}
|
|
184
|
+
to={querySelection.to}
|
|
185
|
+
yAxisUnit="percentage"
|
|
186
|
+
addLabelMatcher={addLabelMatcher}
|
|
187
|
+
onSeriesClick={seriesIndex => {
|
|
188
|
+
// For generic UtilizationMetrics, just pass the series index
|
|
189
|
+
if (onUtilizationSeriesSelect != null) {
|
|
190
|
+
onUtilizationSeriesSelect(seriesIndex);
|
|
191
|
+
}
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
196
194
|
);
|
|
197
195
|
}
|
|
198
196
|
return null;
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
useGrpcMetadata,
|
|
23
23
|
useParcaContext,
|
|
24
24
|
useURLState,
|
|
25
|
+
useURLStateBatch,
|
|
25
26
|
} from '@parca/components';
|
|
26
27
|
import {CloseIcon} from '@parca/icons';
|
|
27
28
|
import {Query} from '@parca/parser';
|
|
@@ -92,6 +93,7 @@ interface ProfileSelectorProps extends ProfileSelectorFeatures {
|
|
|
92
93
|
utilizationMetricsLoading?: boolean;
|
|
93
94
|
utilizationLabels?: UtilizationLabels;
|
|
94
95
|
onUtilizationSeriesSelect?: (seriesIndex: number) => void;
|
|
96
|
+
onSearchHook?: () => void;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
export interface IProfileTypesResult {
|
|
@@ -144,10 +146,12 @@ const ProfileSelector = ({
|
|
|
144
146
|
utilizationMetricsLoading,
|
|
145
147
|
utilizationLabels,
|
|
146
148
|
onUtilizationSeriesSelect,
|
|
149
|
+
onSearchHook,
|
|
147
150
|
}: ProfileSelectorProps): JSX.Element => {
|
|
148
151
|
const {heightStyle} = useMetricsGraphDimensions(comparing, utilizationMetrics != null);
|
|
149
152
|
const {viewComponent} = useParcaContext();
|
|
150
153
|
const [queryBrowserMode, setQueryBrowserMode] = useURLState('query_browser_mode');
|
|
154
|
+
const batchUpdates = useURLStateBatch();
|
|
151
155
|
|
|
152
156
|
// Use the new useQueryState hook - reads directly from URL params
|
|
153
157
|
const {
|
|
@@ -227,22 +231,27 @@ const ProfileSelector = ({
|
|
|
227
231
|
const selectedProfileName = query.profileName();
|
|
228
232
|
|
|
229
233
|
const setQueryExpression = (updateTs = false): void => {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
234
|
+
batchUpdates(() => {
|
|
235
|
+
if (onSearchHook != null) {
|
|
236
|
+
onSearchHook();
|
|
237
|
+
}
|
|
238
|
+
// When updateTs is true, re-evaluate the time range to current values
|
|
239
|
+
if (updateTs) {
|
|
240
|
+
// Force re-evaluation of time range (important for relative ranges like "last 15 minutes")
|
|
241
|
+
const currentFrom = timeRangeSelection.getFromMs(true);
|
|
242
|
+
const currentTo = timeRangeSelection.getToMs(true);
|
|
243
|
+
const currentRangeKey = timeRangeSelection.getRangeKey();
|
|
244
|
+
// Commit with refreshed time range
|
|
245
|
+
commitDraft({
|
|
246
|
+
from: currentFrom,
|
|
247
|
+
to: currentTo,
|
|
248
|
+
timeSelection: currentRangeKey,
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
// Commit the draft with existing values
|
|
252
|
+
commitDraft();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
246
255
|
};
|
|
247
256
|
|
|
248
257
|
const setMatchersString = (matchers: string): void => {
|
|
@@ -150,7 +150,6 @@ export const useQueryState = (options: UseQueryStateOptions = {}): UseQueryState
|
|
|
150
150
|
draftTo !== '' ? parseInt(draftTo) : defaultTo
|
|
151
151
|
);
|
|
152
152
|
}, [draftTimeSelection, draftFrom, draftTo, defaultTimeSelection, defaultFrom, defaultTo]);
|
|
153
|
-
|
|
154
153
|
// Use combined sumBy hook for fetching labels and computing defaults (based on committed state)
|
|
155
154
|
const {sumBy: computedSumByFromURL, isLoading: sumBySelectionLoading} = useSumBy(
|
|
156
155
|
queryClient,
|
|
@@ -201,12 +200,13 @@ export const useQueryState = (options: UseQueryStateOptions = {}): UseQueryState
|
|
|
201
200
|
? (BigInt(draftTimeRange.getToMs()) * 1_000_000n).toString()
|
|
202
201
|
: undefined;
|
|
203
202
|
|
|
203
|
+
const finalSumBy = draftSumBy ?? computedSumByFromURL;
|
|
204
204
|
return {
|
|
205
205
|
expression: draftExpression ?? defaultExpression,
|
|
206
206
|
from: draftTimeRange.getFromMs(),
|
|
207
207
|
to: draftTimeRange.getToMs(),
|
|
208
208
|
timeSelection: draftTimeRange.getRangeKey(),
|
|
209
|
-
sumBy:
|
|
209
|
+
sumBy: finalSumBy, // Use draft if set, otherwise fallback to computed
|
|
210
210
|
...(draftMergeFrom !== undefined &&
|
|
211
211
|
draftMergeFrom !== '' &&
|
|
212
212
|
draftMergeTo !== undefined &&
|