@parca/profile 0.16.413 → 0.16.415
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 +8 -0
- package/dist/MatchersInput/index.d.ts.map +1 -1
- package/dist/MatchersInput/index.js +22 -22
- package/dist/ProfileExplorer/index.d.ts.map +1 -1
- package/dist/ProfileExplorer/index.js +27 -8
- package/dist/ProfileMetricsGraph/index.d.ts +0 -1
- package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
- package/dist/ProfileMetricsGraph/index.js +1 -1
- package/dist/ProfileSelector/index.d.ts +1 -1
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +21 -18
- package/dist/ProfileSelector/useAutoQuerySelector.d.ts +2 -1
- package/dist/ProfileSelector/useAutoQuerySelector.d.ts.map +1 -1
- package/dist/ProfileSelector/useAutoQuerySelector.js +8 -3
- package/dist/useGrpcQuery/index.d.ts +2 -1
- package/dist/useGrpcQuery/index.d.ts.map +1 -1
- package/dist/useGrpcQuery/index.js +2 -1
- package/dist/useSumBy.d.ts +10 -4
- package/dist/useSumBy.d.ts.map +1 -1
- package/dist/useSumBy.js +60 -47
- package/package.json +2 -2
- package/src/MatchersInput/index.tsx +23 -25
- package/src/ProfileExplorer/index.tsx +34 -8
- package/src/ProfileMetricsGraph/index.tsx +1 -2
- package/src/ProfileSelector/index.tsx +31 -30
- package/src/ProfileSelector/useAutoQuerySelector.ts +9 -2
- package/src/useGrpcQuery/index.ts +3 -1
- package/src/useSumBy.ts +84 -60
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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.16.415](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.414...@parca/profile@0.16.415) (2024-07-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.414](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.413...@parca/profile@0.16.414) (2024-07-22)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.413](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.412...@parca/profile@0.16.413) (2024-07-22)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MatchersInput/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,cAAc,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MatchersInput/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,cAAc,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAMpC,UAAU,kBAAkB;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,aAAa,WAChB,kBAAkB,eACb,MAAM,UACX,MAAM,QACR,MAAM,KACX,aAyBF,CAAC;AAEF,QAAA,MAAM,aAAa,6EAMhB,kBAAkB,KAAG,GAAG,CAAC,OAoL3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -17,31 +17,31 @@ import TextareaAutosize from 'react-textarea-autosize';
|
|
|
17
17
|
import { useGrpcMetadata } from '@parca/components';
|
|
18
18
|
import { Query } from '@parca/parser';
|
|
19
19
|
import { millisToProtoTimestamp, sanitizeLabelValue } from '@parca/utilities';
|
|
20
|
+
import useGrpcQuery from '../useGrpcQuery';
|
|
20
21
|
import SuggestionsList, { Suggestion, Suggestions } from './SuggestionsList';
|
|
21
22
|
export const useLabelNames = (client, profileType, start, end) => {
|
|
22
|
-
const [loading, setLoading] = useState(true);
|
|
23
|
-
const [result, setResult] = useState({});
|
|
24
23
|
const metadata = useGrpcMetadata();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
24
|
+
const { data, isLoading, error } = useGrpcQuery({
|
|
25
|
+
key: ['labelNames', profileType],
|
|
26
|
+
queryFn: async () => {
|
|
27
|
+
const request = { match: [] };
|
|
28
|
+
if (start !== undefined && end !== undefined) {
|
|
29
|
+
request.start = millisToProtoTimestamp(start);
|
|
30
|
+
request.end = millisToProtoTimestamp(end);
|
|
31
|
+
}
|
|
32
|
+
if (profileType !== undefined) {
|
|
33
|
+
request.profileType = profileType;
|
|
34
|
+
}
|
|
35
|
+
const { response } = await client.labels(request, { meta: metadata });
|
|
36
|
+
return response;
|
|
37
|
+
},
|
|
38
|
+
options: {
|
|
39
|
+
enabled: profileType !== undefined && profileType !== '',
|
|
40
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
41
|
+
keepPreviousData: false,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return { result: { response: data, error: error }, loading: isLoading };
|
|
45
45
|
};
|
|
46
46
|
const MatchersInput = ({ queryClient, setMatchersString, runQuery, currentQuery, profileType, }) => {
|
|
47
47
|
const inputRef = useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAGjD,OAAO,EAA4B,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAGjD,OAAO,EAA4B,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAQlF,UAAU,oBAAoB;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAaD,eAAO,MAAM,sBAAsB,eAAgB,MAAM,GAAG,EAAE,KAAG,MAGhE,CAAC;AAyWF,QAAA,MAAM,eAAe,8CAIlB,oBAAoB,KAAG,GAAG,CAAC,OAkB7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -18,6 +18,7 @@ import { createStore } from '@parca/store';
|
|
|
18
18
|
import { capitalizeOnlyFirstLetter } from '@parca/utilities';
|
|
19
19
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
20
20
|
import { useProfileTypes } from '../ProfileSelector';
|
|
21
|
+
import { sumByToParam, useSumByFromParams } from '../useSumBy';
|
|
21
22
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
22
23
|
import ProfileExplorerSingle from './ProfileExplorerSingle';
|
|
23
24
|
const ErrorContent = ({ errorMessage }) => {
|
|
@@ -38,6 +39,19 @@ const sanitizeDateRange = (time_selection_a, from_a, to_a) => {
|
|
|
38
39
|
return { time_selection_a: range.getRangeKey(), from_a, to_a };
|
|
39
40
|
};
|
|
40
41
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
42
|
+
const filterEmptyParams = (o) => {
|
|
43
|
+
return Object.fromEntries(Object.entries(o)
|
|
44
|
+
.filter(([_, value]) => value !== '' && value !== undefined && (Array.isArray(value) ? value.length > 0 : true))
|
|
45
|
+
.map(([key, value]) => {
|
|
46
|
+
if (typeof value === 'string') {
|
|
47
|
+
return [key, value];
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
return [key, value];
|
|
51
|
+
}
|
|
52
|
+
return [key, value];
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
41
55
|
const filterSuffix = (o, suffix) => Object.fromEntries(Object.entries(o)
|
|
42
56
|
.filter(([key]) => !key.endsWith(suffix))
|
|
43
57
|
.map(([key, value]) => {
|
|
@@ -78,6 +92,8 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
78
92
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
79
93
|
const [profileA, setProfileA] = useState(null);
|
|
80
94
|
const [profileB, setProfileB] = useState(null);
|
|
95
|
+
const sumByA = useSumByFromParams(sum_by_a);
|
|
96
|
+
const sumByB = useSumByFromParams(sum_by_b);
|
|
81
97
|
useEffect(() => {
|
|
82
98
|
const mergeFrom = merge_from_a ?? undefined;
|
|
83
99
|
const mergeTo = merge_to_a ?? undefined;
|
|
@@ -134,7 +150,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
134
150
|
from: parseInt(from_a),
|
|
135
151
|
to: parseInt(to_a),
|
|
136
152
|
timeSelection: time_selection_a,
|
|
137
|
-
sumBy:
|
|
153
|
+
sumBy: sumByA,
|
|
138
154
|
};
|
|
139
155
|
// Show the SingleProfileExplorer when not comparing
|
|
140
156
|
if (compare_a !== 'true' && compare_b !== 'true') {
|
|
@@ -149,17 +165,18 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
149
165
|
return navigateTo('/',
|
|
150
166
|
// Filtering the _a suffix causes us to reset potential profile
|
|
151
167
|
// selection when running a new query.
|
|
152
|
-
{
|
|
168
|
+
filterEmptyParams({
|
|
153
169
|
...filterSuffix(queryParams, '_a'),
|
|
154
170
|
...{
|
|
155
171
|
expression_a: encodeURIComponent(q.expression),
|
|
156
172
|
from_a: q.from.toString(),
|
|
157
173
|
to_a: q.to.toString(),
|
|
158
174
|
time_selection_a: q.timeSelection,
|
|
175
|
+
sum_by_a: sumByToParam(q.sumBy),
|
|
159
176
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
160
177
|
...mergeParams,
|
|
161
178
|
},
|
|
162
|
-
});
|
|
179
|
+
}));
|
|
163
180
|
};
|
|
164
181
|
const selectProfile = (p) => {
|
|
165
182
|
queryParams.expression_a = encodeURIComponent(queryParams.expression_a);
|
|
@@ -176,7 +193,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
176
193
|
from: parseInt(from_b),
|
|
177
194
|
to: parseInt(to_b),
|
|
178
195
|
timeSelection: time_selection_b,
|
|
179
|
-
sumBy:
|
|
196
|
+
sumBy: sumByB,
|
|
180
197
|
};
|
|
181
198
|
const selectQueryA = (q) => {
|
|
182
199
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
@@ -189,7 +206,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
189
206
|
return navigateTo('/',
|
|
190
207
|
// Filtering the _a suffix causes us to reset potential profile
|
|
191
208
|
// selection when running a new query.
|
|
192
|
-
{
|
|
209
|
+
filterEmptyParams({
|
|
193
210
|
...filterSuffix(queryParams, '_a'),
|
|
194
211
|
...{
|
|
195
212
|
compare_a: 'true',
|
|
@@ -199,11 +216,12 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
199
216
|
from_a: q.from.toString(),
|
|
200
217
|
to_a: q.to.toString(),
|
|
201
218
|
time_selection_a: q.timeSelection,
|
|
219
|
+
sum_by_a: sumByToParam(q.sumBy),
|
|
202
220
|
filter_by_function: filter_by_function ?? '',
|
|
203
221
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
204
222
|
...mergeParams,
|
|
205
223
|
},
|
|
206
|
-
});
|
|
224
|
+
}));
|
|
207
225
|
};
|
|
208
226
|
const selectQueryB = (q) => {
|
|
209
227
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
@@ -216,7 +234,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
216
234
|
return navigateTo('/',
|
|
217
235
|
// Filtering the _b suffix causes us to reset potential profile
|
|
218
236
|
// selection when running a new query.
|
|
219
|
-
{
|
|
237
|
+
filterEmptyParams({
|
|
220
238
|
...filterSuffix(queryParams, '_b'),
|
|
221
239
|
...{
|
|
222
240
|
compare_b: 'true',
|
|
@@ -226,11 +244,12 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
226
244
|
from_b: q.from.toString(),
|
|
227
245
|
to_b: q.to.toString(),
|
|
228
246
|
time_selection_b: q.timeSelection,
|
|
247
|
+
sum_by_b: sumByToParam(q.sumBy),
|
|
229
248
|
filter_by_function: filter_by_function ?? '',
|
|
230
249
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
231
250
|
...mergeParams,
|
|
232
251
|
},
|
|
233
|
-
});
|
|
252
|
+
}));
|
|
234
253
|
};
|
|
235
254
|
const closeProfile = (card) => {
|
|
236
255
|
let newQueryParameters = queryParams;
|
|
@@ -9,7 +9,6 @@ export declare const ProfileMetricsEmptyState: ({ message }: ProfileMetricsEmpty
|
|
|
9
9
|
interface ProfileMetricsGraphProps {
|
|
10
10
|
queryClient: QueryServiceClient;
|
|
11
11
|
queryExpression: string;
|
|
12
|
-
dirtyQueryExpression: string;
|
|
13
12
|
profile: ProfileSelection | null;
|
|
14
13
|
from: number;
|
|
15
14
|
to: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAW,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAY,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAK5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,gBAAe,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAW,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAY,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAK5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,gBAAe,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CACf,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,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAYD,eAAO,MAAM,aAAa,WAChB,kBAAkB,mBACT,MAAM,SAChB,MAAM,OACR,MAAM,SACJ,MAAM,EAAE,qBAEd,gBA+CF,CAAC;AAEF,QAAA,MAAM,mBAAmB,sIAYtB,wBAAwB,KAAG,GAAG,CAAC,OAqFjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -53,7 +53,7 @@ export const useQueryRange = (client, queryExpression, start, end, sumBy, skip =
|
|
|
53
53
|
}
|
|
54
54
|
}, [stepCountStr, defaultStepCount, setStepCount]);
|
|
55
55
|
const { data, isLoading, error } = useGrpcQuery({
|
|
56
|
-
key: ['query-range', queryExpression, start, end, sumBy.join(','), stepCount, metadata],
|
|
56
|
+
key: ['query-range', queryExpression, start, end, (sumBy ?? []).join(','), stepCount, metadata],
|
|
57
57
|
queryFn: async () => {
|
|
58
58
|
const stepDuration = getStepDuration(start, end, stepCount);
|
|
59
59
|
const { response } = await client.queryRange({
|
|
@@ -29,6 +29,6 @@ export interface IProfileTypesResult {
|
|
|
29
29
|
error?: RpcError;
|
|
30
30
|
}
|
|
31
31
|
export declare const useProfileTypes: (client: QueryServiceClient) => IProfileTypesResult;
|
|
32
|
-
declare const ProfileSelector: ({ queryClient, querySelection, selectProfile, selectQuery, closeProfile, enforcedProfileName, profileSelection, comparing, navigateTo,
|
|
32
|
+
declare const ProfileSelector: ({ queryClient, querySelection, selectProfile, selectQuery, closeProfile, enforcedProfileName, profileSelection, comparing, navigateTo, }: ProfileSelectorProps) => JSX.Element;
|
|
33
33
|
export default ProfileSelector;
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAQ,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAY9E,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAQ5D,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,oBAAoB;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;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,WAAY,kBAAkB,KAAG,mBAkB5D,CAAC;AAEF,QAAA,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAQ,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAY9E,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAQ5D,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,oBAAoB;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;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,WAAY,kBAAkB,KAAG,mBAkB5D,CAAC;AAEF,QAAA,MAAM,eAAe,6IAUlB,oBAAoB,KAAG,GAAG,CAAC,OAwT7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -21,7 +21,7 @@ import MatchersInput, { useLabelNames } from '../MatchersInput/index';
|
|
|
21
21
|
import { useMetricsGraphDimensions } from '../MetricsGraph/useMetricsGraphDimensions';
|
|
22
22
|
import ProfileMetricsGraph, { ProfileMetricsEmptyState } from '../ProfileMetricsGraph';
|
|
23
23
|
import ProfileTypeSelector from '../ProfileTypeSelector/index';
|
|
24
|
-
import {
|
|
24
|
+
import { useDefaultSumBy, useSumBySelection } from '../useSumBy';
|
|
25
25
|
import { useAutoQuerySelector } from './useAutoQuerySelector';
|
|
26
26
|
export const useProfileTypes = (client) => {
|
|
27
27
|
const [result, setResult] = useState(undefined);
|
|
@@ -40,7 +40,7 @@ export const useProfileTypes = (client) => {
|
|
|
40
40
|
}, [client, metadata, loading]);
|
|
41
41
|
return { loading, data: result, error };
|
|
42
42
|
};
|
|
43
|
-
const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQuery, closeProfile, enforcedProfileName, profileSelection, comparing, navigateTo,
|
|
43
|
+
const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQuery, closeProfile, enforcedProfileName, profileSelection, comparing, navigateTo, }) => {
|
|
44
44
|
const { loading: profileTypesLoading, data: profileTypesData, error, } = useProfileTypes(queryClient);
|
|
45
45
|
const { heightStyle } = useMetricsGraphDimensions(comparing);
|
|
46
46
|
const { viewComponent } = useParcaContext();
|
|
@@ -49,19 +49,23 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
|
|
|
49
49
|
const profileType = useMemo(() => {
|
|
50
50
|
return Query.parse(queryExpressionString).profileType();
|
|
51
51
|
}, [queryExpressionString]);
|
|
52
|
+
const selectedProfileType = useMemo(() => {
|
|
53
|
+
return Query.parse(querySelection.expression).profileType();
|
|
54
|
+
}, [querySelection.expression]);
|
|
52
55
|
const { loading: labelNamesLoading, result } = useLabelNames(queryClient, profileType.toString());
|
|
56
|
+
const { loading: selectedLabelNamesLoading, result: selectedLabelNamesResult } = useLabelNames(queryClient, selectedProfileType.toString());
|
|
53
57
|
const labels = useMemo(() => {
|
|
54
58
|
return result.response?.labelNames === undefined ? [] : result.response.labelNames;
|
|
55
59
|
}, [result]);
|
|
56
|
-
const
|
|
57
|
-
|
|
60
|
+
const selectedLabels = useMemo(() => {
|
|
61
|
+
return selectedLabelNamesResult.response?.labelNames === undefined
|
|
62
|
+
? []
|
|
63
|
+
: selectedLabelNamesResult.response.labelNames;
|
|
64
|
+
}, [selectedLabelNamesResult]);
|
|
65
|
+
const [sumBySelection, setUserSumBySelection, { isLoading: sumBySelectionLoading }] = useSumBySelection(profileType, labelNamesLoading, labels, {
|
|
66
|
+
defaultValue: querySelection.sumBy,
|
|
58
67
|
});
|
|
59
|
-
const
|
|
60
|
-
urlParamKey: 'sum_by_selection' + suffix,
|
|
61
|
-
withURLUpdate: false,
|
|
62
|
-
defaultValue: userSelectedSumBy,
|
|
63
|
-
});
|
|
64
|
-
const sumByLoading = labelNamesLoading;
|
|
68
|
+
const { defaultSumBy, isLoading: defaultSumByLoading } = useDefaultSumBy(selectedProfileType, selectedLabelNamesLoading, selectedLabels);
|
|
65
69
|
useEffect(() => {
|
|
66
70
|
if (enforcedProfileName !== '') {
|
|
67
71
|
const [q, changed] = Query.parse(querySelection.expression).setProfileName(enforcedProfileName);
|
|
@@ -80,9 +84,6 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
|
|
|
80
84
|
const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(queryExpressionString);
|
|
81
85
|
const selectedProfileName = query.profileName();
|
|
82
86
|
const setNewQueryExpression = (expr, updateTs = false) => {
|
|
83
|
-
if (!sumByLoading) {
|
|
84
|
-
setSumBy(sumBySelection);
|
|
85
|
-
}
|
|
86
87
|
const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(expr);
|
|
87
88
|
const delta = query.profileType().delta;
|
|
88
89
|
const from = timeRangeSelection.getFromMs(updateTs);
|
|
@@ -98,6 +99,7 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
|
|
|
98
99
|
from,
|
|
99
100
|
to,
|
|
100
101
|
timeSelection: timeRangeSelection.getRangeKey(),
|
|
102
|
+
sumBy: sumBySelection,
|
|
101
103
|
...mergeParams,
|
|
102
104
|
});
|
|
103
105
|
};
|
|
@@ -157,24 +159,25 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
|
|
|
157
159
|
profileTypesData,
|
|
158
160
|
setProfileName,
|
|
159
161
|
setQueryExpression,
|
|
160
|
-
querySelection: { ...querySelection, sumBy },
|
|
162
|
+
querySelection: { ...querySelection, sumBy: sumBySelection },
|
|
161
163
|
navigateTo,
|
|
164
|
+
loading: sumBySelectionLoading,
|
|
162
165
|
});
|
|
163
166
|
const searchDisabled = queryExpressionString === undefined ||
|
|
164
167
|
queryExpressionString === '' ||
|
|
165
168
|
queryExpressionString === '{}';
|
|
166
169
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2 flex gap-2", children: [_jsxs("div", { className: "flex w-full flex-wrap content-start items-center gap-2", children: [_jsxs("div", { className: "pb-6", children: [_jsx("label", { className: "text-xs", children: "Profile type" }), _jsx(ProfileTypeSelector, { profileTypesData: profileTypesData, loading: profileTypesLoading, selectedKey: selectedProfileName, onSelection: setProfileName, error: error, disabled: viewComponent?.disableProfileTypesDropdown })] }), _jsxs("div", { className: "w-full flex-1 pb-6", children: [_jsxs("div", { className: "mb-0.5 mt-1.5 flex items-center justify-between", children: [_jsx("label", { className: "text-xs", children: "Query" }), (query.matchers.length > 0 || query.inputMatcherString.length > 0) &&
|
|
167
|
-
viewComponent !== undefined && _jsx("div", { children: viewComponent?.createViewComponent })] }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName })] }), _jsxs("div", { className: "pb-6", children: [_jsx("div", { className: "mb-0.5 mt-1.5 flex items-center justify-between", children: _jsx("label", { className: "text-xs", children: "Sum by" }) }), _jsx(Select, { defaultValue: [], isMulti: true, name: "colors", options: labels.map(label => ({ label, value: label })), className: "parca-select-container text-sm w-80", classNamePrefix: "parca-select", value: sumBySelection.map(sumBy => ({ label: sumBy, value: sumBy })), onChange: selectedOptions => {
|
|
168
|
-
|
|
170
|
+
viewComponent !== undefined && _jsx("div", { children: viewComponent?.createViewComponent })] }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName })] }), _jsxs("div", { className: "pb-6", children: [_jsx("div", { className: "mb-0.5 mt-1.5 flex items-center justify-between", children: _jsx("label", { className: "text-xs", children: "Sum by" }) }), _jsx(Select, { defaultValue: [], isMulti: true, name: "colors", options: labels.map(label => ({ label, value: label })), className: "parca-select-container text-sm w-80", classNamePrefix: "parca-select", value: (sumBySelection ?? []).map(sumBy => ({ label: sumBy, value: sumBy })), onChange: selectedOptions => {
|
|
171
|
+
setUserSumBySelection(selectedOptions.map(option => option.value));
|
|
169
172
|
}, placeholder: "Labels...", styles: {
|
|
170
173
|
indicatorSeparator: () => ({ display: 'none' }),
|
|
171
|
-
} })] }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection }), _jsx(ButtonGroup, { children: _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
|
|
174
|
+
}, isDisabled: !profileType.delta })] }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection }), _jsx(ButtonGroup, { children: _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
|
|
172
175
|
e.preventDefault();
|
|
173
176
|
setQueryExpression(true);
|
|
174
177
|
}, id: "h-matcher-search-button", children: "Search" }) })] }), _jsx("div", { children: comparing && _jsx(IconButton, { onClick: () => closeProfile(), icon: _jsx(CloseIcon, {}) }) })] }), _jsx("div", { className: "rounded bg-white shadow dark:border-gray-500 dark:bg-gray-700", children: _jsx("div", { style: { height: heightStyle }, children: querySelection.expression !== undefined &&
|
|
175
178
|
querySelection.expression.length > 0 &&
|
|
176
179
|
querySelection.from !== undefined &&
|
|
177
|
-
querySelection.to !== undefined ? (_jsx("div", { className: "p-2", children: _jsx(ProfileMetricsGraph, { queryClient: queryClient, queryExpression: querySelection.expression,
|
|
180
|
+
querySelection.to !== undefined ? (_jsx("div", { className: "p-2", children: _jsx(ProfileMetricsGraph, { queryClient: queryClient, queryExpression: querySelection.expression, from: querySelection.from, to: querySelection.to, profile: profileSelection, comparing: comparing, sumBy: querySelection.sumBy ?? defaultSumBy ?? [], sumByLoading: defaultSumByLoading, setTimeRange: (range) => {
|
|
178
181
|
const from = range.getFromMs();
|
|
179
182
|
const to = range.getToMs();
|
|
180
183
|
let mergedProfileParams = {};
|
|
@@ -8,7 +8,8 @@ interface Props {
|
|
|
8
8
|
setQueryExpression: () => void;
|
|
9
9
|
querySelection: QuerySelection;
|
|
10
10
|
navigateTo: NavigateFunction;
|
|
11
|
+
loading: boolean;
|
|
11
12
|
}
|
|
12
|
-
export declare const useAutoQuerySelector: ({ selectedProfileName, profileTypesData, setProfileName, setQueryExpression, querySelection, navigateTo, }: Props) => void;
|
|
13
|
+
export declare const useAutoQuerySelector: ({ selectedProfileName, profileTypesData, setProfileName, setQueryExpression, querySelection, navigateTo, loading, }: Props) => void;
|
|
13
14
|
export {};
|
|
14
15
|
//# sourceMappingURL=useAutoQuerySelector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutoQuerySelector.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/useAutoQuerySelector.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,oBAAoB,EAAC,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAGlD,UAAU,KAAK;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useAutoQuerySelector.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/useAutoQuerySelector.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,oBAAoB,EAAC,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAGlD,UAAU,KAAK;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,oBAAoB,wHAQ9B,KAAK,KAAG,IAuIV,CAAC"}
|
|
@@ -14,13 +14,16 @@ import { useEffect } from 'react';
|
|
|
14
14
|
import { selectAutoQuery, setAutoQuery, useAppDispatch, useAppSelector } from '@parca/store';
|
|
15
15
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
16
16
|
import { constructProfileName } from '../ProfileTypeSelector';
|
|
17
|
-
export const useAutoQuerySelector = ({ selectedProfileName, profileTypesData, setProfileName, setQueryExpression, querySelection, navigateTo, }) => {
|
|
17
|
+
export const useAutoQuerySelector = ({ selectedProfileName, profileTypesData, setProfileName, setQueryExpression, querySelection, navigateTo, loading, }) => {
|
|
18
18
|
const autoQuery = useAppSelector(selectAutoQuery);
|
|
19
19
|
const dispatch = useAppDispatch();
|
|
20
20
|
const queryParams = new URLSearchParams(location.search);
|
|
21
21
|
const comparing = queryParams.get('comparing') === 'true';
|
|
22
22
|
const expressionA = queryParams.get('expression_a');
|
|
23
23
|
useEffect(() => {
|
|
24
|
+
if (loading) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
24
27
|
if (comparing && expressionA !== null && expressionA !== undefined) {
|
|
25
28
|
if (querySelection.expression === undefined) {
|
|
26
29
|
return;
|
|
@@ -62,7 +65,7 @@ export const useAutoQuerySelector = ({ selectedProfileName, profileTypesData, se
|
|
|
62
65
|
dashboard_items: ['icicle'],
|
|
63
66
|
});
|
|
64
67
|
}
|
|
65
|
-
}, [comparing, querySelection, navigateTo, expressionA, dispatch]);
|
|
68
|
+
}, [comparing, querySelection, navigateTo, expressionA, dispatch, loading]);
|
|
66
69
|
// Effect to load some initial data on load when is no selection
|
|
67
70
|
useEffect(() => {
|
|
68
71
|
void (async () => {
|
|
@@ -105,7 +108,8 @@ export const useAutoQuerySelector = ({ selectedProfileName, profileTypesData, se
|
|
|
105
108
|
if (autoQuery !== 'true' ||
|
|
106
109
|
profileTypesData?.types == null ||
|
|
107
110
|
profileTypesData.types.length < 1 ||
|
|
108
|
-
selectedProfileName.length === 0
|
|
111
|
+
selectedProfileName.length === 0 ||
|
|
112
|
+
loading) {
|
|
109
113
|
return;
|
|
110
114
|
}
|
|
111
115
|
setQueryExpression();
|
|
@@ -118,5 +122,6 @@ export const useAutoQuerySelector = ({ selectedProfileName, profileTypesData, se
|
|
|
118
122
|
setProfileName,
|
|
119
123
|
dispatch,
|
|
120
124
|
selectedProfileName,
|
|
125
|
+
loading,
|
|
121
126
|
]);
|
|
122
127
|
};
|
|
@@ -6,8 +6,9 @@ interface Props<IRes> {
|
|
|
6
6
|
enabled?: boolean | undefined;
|
|
7
7
|
staleTime?: number | undefined;
|
|
8
8
|
retry?: number | boolean;
|
|
9
|
+
keepPreviousData?: boolean | undefined;
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
|
-
declare const useGrpcQuery: <IRes>({ key, queryFn, options: { enabled, staleTime, retry }, }: Props<IRes>) => UseQueryResult<IRes>;
|
|
12
|
+
declare const useGrpcQuery: <IRes>({ key, queryFn, options: { enabled, staleTime, retry, keepPreviousData }, }: Props<IRes>) => UseQueryResult<IRes>;
|
|
12
13
|
export default useGrpcQuery;
|
|
13
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/useGrpcQuery/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAEpE,UAAU,KAAK,CAAC,IAAI;IAClB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/useGrpcQuery/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAEpE,UAAU,KAAK,CAAC,IAAI;IAClB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACzB,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACxC,CAAC;CACH;AAED,QAAA,MAAM,YAAY,GAAI,IAAI,+EAIvB,KAAK,CAAC,IAAI,CAAC,KAAG,cAAc,CAAC,IAAI,CAanC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useQuery } from '@tanstack/react-query';
|
|
14
|
-
const useGrpcQuery = ({ key, queryFn, options: { enabled = true, staleTime, retry } = {}, }) => {
|
|
14
|
+
const useGrpcQuery = ({ key, queryFn, options: { enabled = true, staleTime, retry, keepPreviousData } = {}, }) => {
|
|
15
15
|
return useQuery(key, async () => {
|
|
16
16
|
return await queryFn();
|
|
17
17
|
}, {
|
|
18
18
|
enabled,
|
|
19
19
|
staleTime,
|
|
20
20
|
retry,
|
|
21
|
+
keepPreviousData,
|
|
21
22
|
});
|
|
22
23
|
};
|
|
23
24
|
export default useGrpcQuery;
|
package/dist/useSumBy.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { ProfileType } from '@parca/parser';
|
|
2
2
|
export declare const DEFAULT_EMPTY_SUM_BY: string[];
|
|
3
|
-
export declare const
|
|
4
|
-
urlParamKey?: string;
|
|
5
|
-
withURLUpdate?: boolean;
|
|
3
|
+
export declare const useSumBySelection: (profileType: ProfileType | undefined, labelNamesLoading: boolean, labels: string[] | undefined, { defaultValue, }?: {
|
|
6
4
|
defaultValue?: string[];
|
|
7
|
-
}) => [string[], (labels: string[]) => void,
|
|
5
|
+
}) => [string[] | undefined, (labels: string[]) => void, {
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
}];
|
|
8
|
+
export declare const useDefaultSumBy: (profileType: ProfileType | undefined, labelNamesLoading: boolean, labels: string[] | undefined) => {
|
|
9
|
+
defaultSumBy: string[] | undefined;
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const useSumByFromParams: (param: string | string[] | undefined) => string[] | undefined;
|
|
13
|
+
export declare const sumByToParam: (sumBy: string[] | undefined) => string | string[] | undefined;
|
|
8
14
|
//# sourceMappingURL=useSumBy.d.ts.map
|
package/dist/useSumBy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSumBy.d.ts","sourceRoot":"","sources":["../src/useSumBy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useSumBy.d.ts","sourceRoot":"","sources":["../src/useSumBy.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAAO,CAAC;AA6BjD,eAAO,MAAM,iBAAiB,gBACf,WAAW,GAAG,SAAS,qBACjB,OAAO,UAClB,MAAM,EAAE,GAAG,SAAS,sBAGzB;IACD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,KACA,CACD,MAAM,EAAE,GAAG,SAAS,EACpB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,EAC1B;IACE,SAAS,EAAE,OAAO,CAAC;CACpB,CAsCF,CAAC;AAEF,eAAO,MAAM,eAAe,gBACb,WAAW,GAAG,SAAS,qBACjB,OAAO,UAClB,MAAM,EAAE,GAAG,SAAS,KAC3B;IAAC,YAAY,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAMzD,CAAC;AAkBF,eAAO,MAAM,kBAAkB,UAAW,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM,EAAE,GAAG,SAMpF,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAU9E,CAAC"}
|
package/dist/useSumBy.js
CHANGED
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import { useCallback,
|
|
14
|
-
import { useParcaContext, useURLState } from '@parca/components';
|
|
13
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
15
14
|
export const DEFAULT_EMPTY_SUM_BY = [];
|
|
16
15
|
const getDefaultSumBy = (profile, labels) => {
|
|
17
16
|
if (profile === undefined || labels === undefined) {
|
|
18
17
|
return undefined;
|
|
19
18
|
}
|
|
19
|
+
if (!profile.delta) {
|
|
20
|
+
return DEFAULT_EMPTY_SUM_BY;
|
|
21
|
+
}
|
|
20
22
|
if (labels.includes('comm')) {
|
|
21
23
|
return ['comm'];
|
|
22
24
|
}
|
|
@@ -28,51 +30,62 @@ const getDefaultSumBy = (profile, labels) => {
|
|
|
28
30
|
}
|
|
29
31
|
return undefined;
|
|
30
32
|
};
|
|
31
|
-
export const
|
|
32
|
-
const {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return defaultValue;
|
|
47
|
-
}
|
|
48
|
-
if (typeof userSelectedSumByParam === 'string') {
|
|
49
|
-
return [userSelectedSumByParam];
|
|
50
|
-
}
|
|
51
|
-
return userSelectedSumByParam;
|
|
52
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
-
}, [userSelectedSumByParam]);
|
|
54
|
-
const setUserSelectedSumBy = useCallback((sumBy) => {
|
|
55
|
-
if (sumBy.length === 0) {
|
|
56
|
-
setUserSelectedSumByParam('__none__');
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (sumBy.length === 1) {
|
|
60
|
-
// Handle this separately to take care of the empty string scenario
|
|
61
|
-
setUserSelectedSumByParam(sumBy[0]);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
setUserSelectedSumByParam(sumBy);
|
|
65
|
-
}, [setUserSelectedSumByParam]);
|
|
66
|
-
const [defaultSumBy, setDefaultSumBy] = useState(getDefaultSumBy(profileType, labels));
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
if (labelNamesLoading) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
setDefaultSumBy(getDefaultSumBy(profileType, labels));
|
|
72
|
-
}, [profileType, labels, labelNamesLoading]);
|
|
73
|
-
let sumBy = userSelectedSumBy ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY;
|
|
33
|
+
export const useSumBySelection = (profileType, labelNamesLoading, labels, { defaultValue, } = {}) => {
|
|
34
|
+
const [userSelectedSumBy, setUserSelectedSumBy] = useState(profileType != null ? { [profileType.toString()]: defaultValue } : {});
|
|
35
|
+
const setSumBy = useCallback((sumBy) => {
|
|
36
|
+
setUserSelectedSumBy(prev => {
|
|
37
|
+
if (profileType == null) {
|
|
38
|
+
return prev;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...prev,
|
|
42
|
+
[profileType.toString()]: sumBy,
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
}, [setUserSelectedSumBy, profileType]);
|
|
46
|
+
const { defaultSumBy } = useDefaultSumBy(profileType, labelNamesLoading, labels);
|
|
47
|
+
let sumBy = userSelectedSumBy[profileType?.toString() ?? ''] ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY;
|
|
74
48
|
if (profileType?.delta !== true) {
|
|
75
|
-
sumBy =
|
|
49
|
+
sumBy = DEFAULT_EMPTY_SUM_BY;
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
labelNamesLoading ? undefined : sumBy,
|
|
53
|
+
setSumBy,
|
|
54
|
+
{
|
|
55
|
+
isLoading: labelNamesLoading,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
};
|
|
59
|
+
export const useDefaultSumBy = (profileType, labelNamesLoading, labels) => {
|
|
60
|
+
const defaultSumBy = useMemo(() => {
|
|
61
|
+
return getDefaultSumBy(profileType, labels);
|
|
62
|
+
}, [profileType, labels]);
|
|
63
|
+
return { defaultSumBy, isLoading: labelNamesLoading };
|
|
64
|
+
};
|
|
65
|
+
const getSumByFromParam = (param) => {
|
|
66
|
+
if (param?.length === 0) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (param === '__none__') {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (typeof param === 'string') {
|
|
73
|
+
return [param];
|
|
74
|
+
}
|
|
75
|
+
return param;
|
|
76
|
+
};
|
|
77
|
+
export const useSumByFromParams = (param) => {
|
|
78
|
+
const sumBy = useMemo(() => {
|
|
79
|
+
return getSumByFromParam(param);
|
|
80
|
+
}, [param]);
|
|
81
|
+
return sumBy;
|
|
82
|
+
};
|
|
83
|
+
export const sumByToParam = (sumBy) => {
|
|
84
|
+
if (sumBy === undefined) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
if (sumBy.length === 0) {
|
|
88
|
+
return '__none__';
|
|
76
89
|
}
|
|
77
|
-
return
|
|
90
|
+
return sumBy;
|
|
78
91
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.415",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@headlessui/react": "^1.7.19",
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"access": "public",
|
|
74
74
|
"registry": "https://registry.npmjs.org/"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "4e0b35d45ffe7a449f875b54a8921dc05f2070e7"
|
|
77
77
|
}
|
|
@@ -21,6 +21,7 @@ import {useGrpcMetadata} from '@parca/components';
|
|
|
21
21
|
import {Query} from '@parca/parser';
|
|
22
22
|
import {millisToProtoTimestamp, sanitizeLabelValue} from '@parca/utilities';
|
|
23
23
|
|
|
24
|
+
import useGrpcQuery from '../useGrpcQuery';
|
|
24
25
|
import SuggestionsList, {Suggestion, Suggestions} from './SuggestionsList';
|
|
25
26
|
|
|
26
27
|
interface MatchersInputProps {
|
|
@@ -47,33 +48,30 @@ export const useLabelNames = (
|
|
|
47
48
|
start?: number,
|
|
48
49
|
end?: number
|
|
49
50
|
): UseLabelNames => {
|
|
50
|
-
const [loading, setLoading] = useState(true);
|
|
51
|
-
const [result, setResult] = useState<ILabelNamesResult>({});
|
|
52
51
|
const metadata = useGrpcMetadata();
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return {result, loading};
|
|
53
|
+
const {data, isLoading, error} = useGrpcQuery<LabelsResponse>({
|
|
54
|
+
key: ['labelNames', profileType],
|
|
55
|
+
queryFn: async () => {
|
|
56
|
+
const request: LabelsRequest = {match: []};
|
|
57
|
+
if (start !== undefined && end !== undefined) {
|
|
58
|
+
request.start = millisToProtoTimestamp(start);
|
|
59
|
+
request.end = millisToProtoTimestamp(end);
|
|
60
|
+
}
|
|
61
|
+
if (profileType !== undefined) {
|
|
62
|
+
request.profileType = profileType;
|
|
63
|
+
}
|
|
64
|
+
const {response} = await client.labels(request, {meta: metadata});
|
|
65
|
+
return response;
|
|
66
|
+
},
|
|
67
|
+
options: {
|
|
68
|
+
enabled: profileType !== undefined && profileType !== '',
|
|
69
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
70
|
+
keepPreviousData: false,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return {result: {response: data, error: error as Error}, loading: isLoading};
|
|
77
75
|
};
|
|
78
76
|
|
|
79
77
|
const MatchersInput = ({
|
|
@@ -22,6 +22,7 @@ import {capitalizeOnlyFirstLetter, type NavigateFunction} from '@parca/utilities
|
|
|
22
22
|
|
|
23
23
|
import {ProfileSelection, ProfileSelectionFromParams, SuffixParams} from '..';
|
|
24
24
|
import {QuerySelection, useProfileTypes} from '../ProfileSelector';
|
|
25
|
+
import {sumByToParam, useSumByFromParams} from '../useSumBy';
|
|
25
26
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
26
27
|
import ProfileExplorerSingle from './ProfileExplorerSingle';
|
|
27
28
|
|
|
@@ -64,6 +65,25 @@ const sanitizeDateRange = (
|
|
|
64
65
|
};
|
|
65
66
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
66
67
|
|
|
68
|
+
const filterEmptyParams = (o: Record<string, any>): Record<string, any> => {
|
|
69
|
+
return Object.fromEntries(
|
|
70
|
+
Object.entries(o)
|
|
71
|
+
.filter(
|
|
72
|
+
([_, value]) =>
|
|
73
|
+
value !== '' && value !== undefined && (Array.isArray(value) ? value.length > 0 : true)
|
|
74
|
+
)
|
|
75
|
+
.map(([key, value]) => {
|
|
76
|
+
if (typeof value === 'string') {
|
|
77
|
+
return [key, value];
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
return [key, value];
|
|
81
|
+
}
|
|
82
|
+
return [key, value];
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
67
87
|
const filterSuffix = (
|
|
68
88
|
o: {[key: string]: string | string[] | undefined},
|
|
69
89
|
suffix: string
|
|
@@ -148,6 +168,9 @@ const ProfileExplorerApp = ({
|
|
|
148
168
|
const [profileA, setProfileA] = useState<ProfileSelection | null>(null);
|
|
149
169
|
const [profileB, setProfileB] = useState<ProfileSelection | null>(null);
|
|
150
170
|
|
|
171
|
+
const sumByA = useSumByFromParams(sum_by_a);
|
|
172
|
+
const sumByB = useSumByFromParams(sum_by_b);
|
|
173
|
+
|
|
151
174
|
useEffect(() => {
|
|
152
175
|
const mergeFrom = merge_from_a ?? undefined;
|
|
153
176
|
const mergeTo = merge_to_a ?? undefined;
|
|
@@ -225,7 +248,7 @@ const ProfileExplorerApp = ({
|
|
|
225
248
|
from: parseInt(from_a as string),
|
|
226
249
|
to: parseInt(to_a as string),
|
|
227
250
|
timeSelection: time_selection_a as string,
|
|
228
|
-
sumBy:
|
|
251
|
+
sumBy: sumByA,
|
|
229
252
|
};
|
|
230
253
|
|
|
231
254
|
// Show the SingleProfileExplorer when not comparing
|
|
@@ -243,17 +266,18 @@ const ProfileExplorerApp = ({
|
|
|
243
266
|
'/',
|
|
244
267
|
// Filtering the _a suffix causes us to reset potential profile
|
|
245
268
|
// selection when running a new query.
|
|
246
|
-
{
|
|
269
|
+
filterEmptyParams({
|
|
247
270
|
...filterSuffix(queryParams, '_a'),
|
|
248
271
|
...{
|
|
249
272
|
expression_a: encodeURIComponent(q.expression),
|
|
250
273
|
from_a: q.from.toString(),
|
|
251
274
|
to_a: q.to.toString(),
|
|
252
275
|
time_selection_a: q.timeSelection,
|
|
276
|
+
sum_by_a: sumByToParam(q.sumBy),
|
|
253
277
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
254
278
|
...mergeParams,
|
|
255
279
|
},
|
|
256
|
-
}
|
|
280
|
+
})
|
|
257
281
|
);
|
|
258
282
|
};
|
|
259
283
|
|
|
@@ -283,7 +307,7 @@ const ProfileExplorerApp = ({
|
|
|
283
307
|
from: parseInt(from_b as string),
|
|
284
308
|
to: parseInt(to_b as string),
|
|
285
309
|
timeSelection: time_selection_b as string,
|
|
286
|
-
sumBy:
|
|
310
|
+
sumBy: sumByB,
|
|
287
311
|
};
|
|
288
312
|
|
|
289
313
|
const selectQueryA = (q: QuerySelection): void => {
|
|
@@ -299,7 +323,7 @@ const ProfileExplorerApp = ({
|
|
|
299
323
|
'/',
|
|
300
324
|
// Filtering the _a suffix causes us to reset potential profile
|
|
301
325
|
// selection when running a new query.
|
|
302
|
-
{
|
|
326
|
+
filterEmptyParams({
|
|
303
327
|
...filterSuffix(queryParams, '_a'),
|
|
304
328
|
...{
|
|
305
329
|
compare_a: 'true',
|
|
@@ -309,11 +333,12 @@ const ProfileExplorerApp = ({
|
|
|
309
333
|
from_a: q.from.toString(),
|
|
310
334
|
to_a: q.to.toString(),
|
|
311
335
|
time_selection_a: q.timeSelection,
|
|
336
|
+
sum_by_a: sumByToParam(q.sumBy),
|
|
312
337
|
filter_by_function: filter_by_function ?? '',
|
|
313
338
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
314
339
|
...mergeParams,
|
|
315
340
|
},
|
|
316
|
-
}
|
|
341
|
+
})
|
|
317
342
|
);
|
|
318
343
|
};
|
|
319
344
|
|
|
@@ -330,7 +355,7 @@ const ProfileExplorerApp = ({
|
|
|
330
355
|
'/',
|
|
331
356
|
// Filtering the _b suffix causes us to reset potential profile
|
|
332
357
|
// selection when running a new query.
|
|
333
|
-
{
|
|
358
|
+
filterEmptyParams({
|
|
334
359
|
...filterSuffix(queryParams, '_b'),
|
|
335
360
|
...{
|
|
336
361
|
compare_b: 'true',
|
|
@@ -340,11 +365,12 @@ const ProfileExplorerApp = ({
|
|
|
340
365
|
from_b: q.from.toString(),
|
|
341
366
|
to_b: q.to.toString(),
|
|
342
367
|
time_selection_b: q.timeSelection,
|
|
368
|
+
sum_by_b: sumByToParam(q.sumBy),
|
|
343
369
|
filter_by_function: filter_by_function ?? '',
|
|
344
370
|
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
345
371
|
...mergeParams,
|
|
346
372
|
},
|
|
347
|
-
}
|
|
373
|
+
})
|
|
348
374
|
);
|
|
349
375
|
};
|
|
350
376
|
|
|
@@ -58,7 +58,6 @@ export const ProfileMetricsEmptyState = ({message}: ProfileMetricsEmptyStateProp
|
|
|
58
58
|
interface ProfileMetricsGraphProps {
|
|
59
59
|
queryClient: QueryServiceClient;
|
|
60
60
|
queryExpression: string;
|
|
61
|
-
dirtyQueryExpression: string;
|
|
62
61
|
profile: ProfileSelection | null;
|
|
63
62
|
from: number;
|
|
64
63
|
to: number;
|
|
@@ -123,7 +122,7 @@ export const useQueryRange = (
|
|
|
123
122
|
}, [stepCountStr, defaultStepCount, setStepCount]);
|
|
124
123
|
|
|
125
124
|
const {data, isLoading, error} = useGrpcQuery<QueryRangeResponse | undefined>({
|
|
126
|
-
key: ['query-range', queryExpression, start, end, sumBy.join(','), stepCount, metadata],
|
|
125
|
+
key: ['query-range', queryExpression, start, end, (sumBy ?? []).join(','), stepCount, metadata],
|
|
127
126
|
queryFn: async () => {
|
|
128
127
|
const stepDuration = getStepDuration(start, end, stepCount);
|
|
129
128
|
const {response} = await client.queryRange(
|
|
@@ -35,7 +35,7 @@ import MatchersInput, {useLabelNames} from '../MatchersInput/index';
|
|
|
35
35
|
import {useMetricsGraphDimensions} from '../MetricsGraph/useMetricsGraphDimensions';
|
|
36
36
|
import ProfileMetricsGraph, {ProfileMetricsEmptyState} from '../ProfileMetricsGraph';
|
|
37
37
|
import ProfileTypeSelector from '../ProfileTypeSelector/index';
|
|
38
|
-
import {
|
|
38
|
+
import {useDefaultSumBy, useSumBySelection} from '../useSumBy';
|
|
39
39
|
import {useAutoQuerySelector} from './useAutoQuerySelector';
|
|
40
40
|
|
|
41
41
|
export interface QuerySelection {
|
|
@@ -97,7 +97,6 @@ const ProfileSelector = ({
|
|
|
97
97
|
profileSelection,
|
|
98
98
|
comparing,
|
|
99
99
|
navigateTo,
|
|
100
|
-
suffix = '',
|
|
101
100
|
}: ProfileSelectorProps): JSX.Element => {
|
|
102
101
|
const {
|
|
103
102
|
loading: profileTypesLoading,
|
|
@@ -117,33 +116,36 @@ const ProfileSelector = ({
|
|
|
117
116
|
return Query.parse(queryExpressionString).profileType();
|
|
118
117
|
}, [queryExpressionString]);
|
|
119
118
|
|
|
119
|
+
const selectedProfileType = useMemo(() => {
|
|
120
|
+
return Query.parse(querySelection.expression).profileType();
|
|
121
|
+
}, [querySelection.expression]);
|
|
122
|
+
|
|
120
123
|
const {loading: labelNamesLoading, result} = useLabelNames(queryClient, profileType.toString());
|
|
124
|
+
const {loading: selectedLabelNamesLoading, result: selectedLabelNamesResult} = useLabelNames(
|
|
125
|
+
queryClient,
|
|
126
|
+
selectedProfileType.toString()
|
|
127
|
+
);
|
|
121
128
|
|
|
122
129
|
const labels = useMemo(() => {
|
|
123
130
|
return result.response?.labelNames === undefined ? [] : result.response.labelNames;
|
|
124
131
|
}, [result]);
|
|
125
132
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
urlParamKey: 'sum_by' + suffix,
|
|
132
|
-
}
|
|
133
|
-
);
|
|
133
|
+
const selectedLabels = useMemo(() => {
|
|
134
|
+
return selectedLabelNamesResult.response?.labelNames === undefined
|
|
135
|
+
? []
|
|
136
|
+
: selectedLabelNamesResult.response.labelNames;
|
|
137
|
+
}, [selectedLabelNamesResult]);
|
|
134
138
|
|
|
135
|
-
const [sumBySelection,
|
|
136
|
-
profileType,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
urlParamKey: 'sum_by_selection' + suffix,
|
|
141
|
-
withURLUpdate: false,
|
|
142
|
-
defaultValue: userSelectedSumBy,
|
|
143
|
-
}
|
|
144
|
-
);
|
|
139
|
+
const [sumBySelection, setUserSumBySelection, {isLoading: sumBySelectionLoading}] =
|
|
140
|
+
useSumBySelection(profileType, labelNamesLoading, labels, {
|
|
141
|
+
defaultValue: querySelection.sumBy,
|
|
142
|
+
});
|
|
145
143
|
|
|
146
|
-
const
|
|
144
|
+
const {defaultSumBy, isLoading: defaultSumByLoading} = useDefaultSumBy(
|
|
145
|
+
selectedProfileType,
|
|
146
|
+
selectedLabelNamesLoading,
|
|
147
|
+
selectedLabels
|
|
148
|
+
);
|
|
147
149
|
|
|
148
150
|
useEffect(() => {
|
|
149
151
|
if (enforcedProfileName !== '') {
|
|
@@ -169,9 +171,6 @@ const ProfileSelector = ({
|
|
|
169
171
|
const selectedProfileName = query.profileName();
|
|
170
172
|
|
|
171
173
|
const setNewQueryExpression = (expr: string, updateTs = false): void => {
|
|
172
|
-
if (!sumByLoading) {
|
|
173
|
-
setSumBy(sumBySelection);
|
|
174
|
-
}
|
|
175
174
|
const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(expr);
|
|
176
175
|
const delta = query.profileType().delta;
|
|
177
176
|
const from = timeRangeSelection.getFromMs(updateTs);
|
|
@@ -188,6 +187,7 @@ const ProfileSelector = ({
|
|
|
188
187
|
from,
|
|
189
188
|
to,
|
|
190
189
|
timeSelection: timeRangeSelection.getRangeKey(),
|
|
190
|
+
sumBy: sumBySelection,
|
|
191
191
|
...mergeParams,
|
|
192
192
|
});
|
|
193
193
|
};
|
|
@@ -257,8 +257,9 @@ const ProfileSelector = ({
|
|
|
257
257
|
profileTypesData,
|
|
258
258
|
setProfileName,
|
|
259
259
|
setQueryExpression,
|
|
260
|
-
querySelection: {...querySelection, sumBy},
|
|
260
|
+
querySelection: {...querySelection, sumBy: sumBySelection},
|
|
261
261
|
navigateTo,
|
|
262
|
+
loading: sumBySelectionLoading,
|
|
262
263
|
});
|
|
263
264
|
|
|
264
265
|
const searchDisabled =
|
|
@@ -306,14 +307,15 @@ const ProfileSelector = ({
|
|
|
306
307
|
options={labels.map(label => ({label, value: label}))}
|
|
307
308
|
className="parca-select-container text-sm w-80"
|
|
308
309
|
classNamePrefix="parca-select"
|
|
309
|
-
value={sumBySelection.map(sumBy => ({label: sumBy, value: sumBy}))}
|
|
310
|
+
value={(sumBySelection ?? []).map(sumBy => ({label: sumBy, value: sumBy}))}
|
|
310
311
|
onChange={selectedOptions => {
|
|
311
|
-
|
|
312
|
+
setUserSumBySelection(selectedOptions.map(option => option.value));
|
|
312
313
|
}}
|
|
313
314
|
placeholder="Labels..."
|
|
314
315
|
styles={{
|
|
315
316
|
indicatorSeparator: () => ({display: 'none'}),
|
|
316
317
|
}}
|
|
318
|
+
isDisabled={!profileType.delta}
|
|
317
319
|
/>
|
|
318
320
|
</div>
|
|
319
321
|
<DateTimeRangePicker
|
|
@@ -345,13 +347,12 @@ const ProfileSelector = ({
|
|
|
345
347
|
<ProfileMetricsGraph
|
|
346
348
|
queryClient={queryClient}
|
|
347
349
|
queryExpression={querySelection.expression}
|
|
348
|
-
dirtyQueryExpression={queryExpressionString}
|
|
349
350
|
from={querySelection.from}
|
|
350
351
|
to={querySelection.to}
|
|
351
352
|
profile={profileSelection}
|
|
352
353
|
comparing={comparing}
|
|
353
|
-
sumBy={sumBy}
|
|
354
|
-
sumByLoading={
|
|
354
|
+
sumBy={querySelection.sumBy ?? defaultSumBy ?? []}
|
|
355
|
+
sumByLoading={defaultSumByLoading}
|
|
355
356
|
setTimeRange={(range: DateTimeRange) => {
|
|
356
357
|
const from = range.getFromMs();
|
|
357
358
|
const to = range.getToMs();
|
|
@@ -28,6 +28,7 @@ interface Props {
|
|
|
28
28
|
setQueryExpression: () => void;
|
|
29
29
|
querySelection: QuerySelection;
|
|
30
30
|
navigateTo: NavigateFunction;
|
|
31
|
+
loading: boolean;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export const useAutoQuerySelector = ({
|
|
@@ -37,6 +38,7 @@ export const useAutoQuerySelector = ({
|
|
|
37
38
|
setQueryExpression,
|
|
38
39
|
querySelection,
|
|
39
40
|
navigateTo,
|
|
41
|
+
loading,
|
|
40
42
|
}: Props): void => {
|
|
41
43
|
const autoQuery = useAppSelector(selectAutoQuery);
|
|
42
44
|
const dispatch = useAppDispatch();
|
|
@@ -46,6 +48,9 @@ export const useAutoQuerySelector = ({
|
|
|
46
48
|
const expressionA = queryParams.get('expression_a');
|
|
47
49
|
|
|
48
50
|
useEffect(() => {
|
|
51
|
+
if (loading) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
49
54
|
if (comparing && expressionA !== null && expressionA !== undefined) {
|
|
50
55
|
if (querySelection.expression === undefined) {
|
|
51
56
|
return;
|
|
@@ -98,7 +103,7 @@ export const useAutoQuerySelector = ({
|
|
|
98
103
|
dashboard_items: ['icicle'],
|
|
99
104
|
});
|
|
100
105
|
}
|
|
101
|
-
}, [comparing, querySelection, navigateTo, expressionA, dispatch]);
|
|
106
|
+
}, [comparing, querySelection, navigateTo, expressionA, dispatch, loading]);
|
|
102
107
|
|
|
103
108
|
// Effect to load some initial data on load when is no selection
|
|
104
109
|
useEffect(() => {
|
|
@@ -152,7 +157,8 @@ export const useAutoQuerySelector = ({
|
|
|
152
157
|
autoQuery !== 'true' ||
|
|
153
158
|
profileTypesData?.types == null ||
|
|
154
159
|
profileTypesData.types.length < 1 ||
|
|
155
|
-
selectedProfileName.length === 0
|
|
160
|
+
selectedProfileName.length === 0 ||
|
|
161
|
+
loading
|
|
156
162
|
) {
|
|
157
163
|
return;
|
|
158
164
|
}
|
|
@@ -166,5 +172,6 @@ export const useAutoQuerySelector = ({
|
|
|
166
172
|
setProfileName,
|
|
167
173
|
dispatch,
|
|
168
174
|
selectedProfileName,
|
|
175
|
+
loading,
|
|
169
176
|
]);
|
|
170
177
|
};
|
|
@@ -20,13 +20,14 @@ interface Props<IRes> {
|
|
|
20
20
|
enabled?: boolean | undefined;
|
|
21
21
|
staleTime?: number | undefined;
|
|
22
22
|
retry?: number | boolean;
|
|
23
|
+
keepPreviousData?: boolean | undefined;
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const useGrpcQuery = <IRes>({
|
|
27
28
|
key,
|
|
28
29
|
queryFn,
|
|
29
|
-
options: {enabled = true, staleTime, retry} = {},
|
|
30
|
+
options: {enabled = true, staleTime, retry, keepPreviousData} = {},
|
|
30
31
|
}: Props<IRes>): UseQueryResult<IRes> => {
|
|
31
32
|
return useQuery<IRes>(
|
|
32
33
|
key,
|
|
@@ -37,6 +38,7 @@ const useGrpcQuery = <IRes>({
|
|
|
37
38
|
enabled,
|
|
38
39
|
staleTime,
|
|
39
40
|
retry,
|
|
41
|
+
keepPreviousData,
|
|
40
42
|
}
|
|
41
43
|
);
|
|
42
44
|
};
|
package/src/useSumBy.ts
CHANGED
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
import {useCallback,
|
|
14
|
+
import {useCallback, useMemo, useState} from 'react';
|
|
15
15
|
|
|
16
|
-
import {useParcaContext, useURLState} from '@parca/components';
|
|
17
16
|
import {ProfileType} from '@parca/parser';
|
|
18
17
|
|
|
19
18
|
export const DEFAULT_EMPTY_SUM_BY: string[] = [];
|
|
@@ -26,6 +25,10 @@ const getDefaultSumBy = (
|
|
|
26
25
|
return undefined;
|
|
27
26
|
}
|
|
28
27
|
|
|
28
|
+
if (!profile.delta) {
|
|
29
|
+
return DEFAULT_EMPTY_SUM_BY;
|
|
30
|
+
}
|
|
31
|
+
|
|
29
32
|
if (labels.includes('comm')) {
|
|
30
33
|
return ['comm'];
|
|
31
34
|
}
|
|
@@ -41,83 +44,104 @@ const getDefaultSumBy = (
|
|
|
41
44
|
return undefined;
|
|
42
45
|
};
|
|
43
46
|
|
|
44
|
-
export const
|
|
47
|
+
export const useSumBySelection = (
|
|
45
48
|
profileType: ProfileType | undefined,
|
|
46
49
|
labelNamesLoading: boolean,
|
|
47
50
|
labels: string[] | undefined,
|
|
48
51
|
{
|
|
49
|
-
urlParamKey = 'sum_by',
|
|
50
|
-
withURLUpdate = true,
|
|
51
52
|
defaultValue,
|
|
52
53
|
}: {
|
|
53
|
-
urlParamKey?: string;
|
|
54
|
-
withURLUpdate?: boolean;
|
|
55
54
|
defaultValue?: string[];
|
|
56
55
|
} = {}
|
|
57
|
-
): [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
): [
|
|
57
|
+
string[] | undefined,
|
|
58
|
+
(labels: string[]) => void,
|
|
59
|
+
{
|
|
60
|
+
isLoading: boolean;
|
|
61
|
+
}
|
|
62
|
+
] => {
|
|
63
|
+
const [userSelectedSumBy, setUserSelectedSumBy] = useState<Record<string, string[] | undefined>>(
|
|
64
|
+
profileType != null ? {[profileType.toString()]: defaultValue} : {}
|
|
65
|
+
);
|
|
64
66
|
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const setSumBy = useCallback(
|
|
68
|
+
(sumBy: string[]) => {
|
|
69
|
+
setUserSelectedSumBy(prev => {
|
|
70
|
+
if (profileType == null) {
|
|
71
|
+
return prev;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...prev,
|
|
76
|
+
[profileType.toString()]: sumBy,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
[setUserSelectedSumBy, profileType]
|
|
81
|
+
);
|
|
69
82
|
|
|
70
|
-
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
83
|
+
const {defaultSumBy} = useDefaultSumBy(profileType, labelNamesLoading, labels);
|
|
73
84
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
85
|
+
let sumBy =
|
|
86
|
+
userSelectedSumBy[profileType?.toString() ?? ''] ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY;
|
|
77
87
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
if (profileType?.delta !== true) {
|
|
89
|
+
sumBy = DEFAULT_EMPTY_SUM_BY;
|
|
90
|
+
}
|
|
81
91
|
|
|
82
|
-
|
|
92
|
+
return [
|
|
93
|
+
labelNamesLoading ? undefined : sumBy,
|
|
94
|
+
setSumBy,
|
|
95
|
+
{
|
|
96
|
+
isLoading: labelNamesLoading,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
};
|
|
83
100
|
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
export const useDefaultSumBy = (
|
|
102
|
+
profileType: ProfileType | undefined,
|
|
103
|
+
labelNamesLoading: boolean,
|
|
104
|
+
labels: string[] | undefined
|
|
105
|
+
): {defaultSumBy: string[] | undefined; isLoading: boolean} => {
|
|
106
|
+
const defaultSumBy = useMemo(() => {
|
|
107
|
+
return getDefaultSumBy(profileType, labels);
|
|
108
|
+
}, [profileType, labels]);
|
|
86
109
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (sumBy.length === 0) {
|
|
90
|
-
setUserSelectedSumByParam('__none__');
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (sumBy.length === 1) {
|
|
95
|
-
// Handle this separately to take care of the empty string scenario
|
|
96
|
-
setUserSelectedSumByParam(sumBy[0]);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
setUserSelectedSumByParam(sumBy);
|
|
101
|
-
},
|
|
102
|
-
[setUserSelectedSumByParam]
|
|
103
|
-
);
|
|
110
|
+
return {defaultSumBy, isLoading: labelNamesLoading};
|
|
111
|
+
};
|
|
104
112
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
const getSumByFromParam = (param: string | string[] | undefined): string[] | undefined => {
|
|
114
|
+
if (param?.length === 0) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
108
117
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
setDefaultSumBy(getDefaultSumBy(profileType, labels));
|
|
114
|
-
}, [profileType, labels, labelNamesLoading]);
|
|
118
|
+
if (param === '__none__') {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
115
121
|
|
|
116
|
-
|
|
122
|
+
if (typeof param === 'string') {
|
|
123
|
+
return [param];
|
|
124
|
+
}
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
return param;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const useSumByFromParams = (param: string | string[] | undefined): string[] | undefined => {
|
|
130
|
+
const sumBy = useMemo(() => {
|
|
131
|
+
return getSumByFromParam(param);
|
|
132
|
+
}, [param]);
|
|
133
|
+
|
|
134
|
+
return sumBy;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const sumByToParam = (sumBy: string[] | undefined): string | string[] | undefined => {
|
|
138
|
+
if (sumBy === undefined) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (sumBy.length === 0) {
|
|
143
|
+
return '__none__';
|
|
120
144
|
}
|
|
121
145
|
|
|
122
|
-
return
|
|
146
|
+
return sumBy;
|
|
123
147
|
};
|