@parca/profile 0.19.83 → 0.19.84
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/MatchersInput/index.d.ts +2 -34
- package/dist/MatchersInput/index.d.ts.map +1 -1
- package/dist/MatchersInput/index.js +14 -91
- package/dist/MetricsGraph/index.d.ts.map +1 -1
- package/dist/MetricsGraph/index.js +13 -1
- package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
- package/dist/ProfileMetricsGraph/index.js +6 -29
- package/dist/ProfileSelector/MetricsGraphSection.d.ts +2 -9
- package/dist/ProfileSelector/MetricsGraphSection.d.ts.map +1 -1
- package/dist/ProfileSelector/MetricsGraphSection.js +3 -38
- package/dist/ProfileSelector/index.d.ts +1 -29
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +14 -10
- package/dist/QueryControls/index.d.ts +46 -0
- package/dist/QueryControls/index.d.ts.map +1 -0
- package/dist/{ProfileSelector/QueryControls.js → QueryControls/index.js} +16 -13
- package/dist/SimpleMatchers/Select.js +1 -1
- package/dist/SimpleMatchers/index.d.ts +6 -10
- package/dist/SimpleMatchers/index.d.ts.map +1 -1
- package/dist/SimpleMatchers/index.js +30 -45
- package/dist/ViewMatchers/index.d.ts +0 -9
- package/dist/ViewMatchers/index.d.ts.map +1 -1
- package/dist/ViewMatchers/index.js +20 -12
- package/dist/contexts/LabelsQueryProvider.d.ts +35 -0
- package/dist/contexts/LabelsQueryProvider.d.ts.map +1 -0
- package/dist/contexts/LabelsQueryProvider.js +70 -0
- package/dist/contexts/UnifiedLabelsContext.d.ts +37 -0
- package/dist/contexts/UnifiedLabelsContext.d.ts.map +1 -0
- package/dist/contexts/UnifiedLabelsContext.js +88 -0
- package/dist/contexts/utils.d.ts +10 -0
- package/dist/contexts/utils.d.ts.map +1 -0
- package/dist/contexts/utils.js +31 -0
- package/dist/hooks/useLabels.d.ts +23 -0
- package/dist/hooks/useLabels.d.ts.map +1 -0
- package/dist/hooks/useLabels.js +75 -0
- package/dist/hooks/useQueryState.d.ts +2 -0
- package/dist/hooks/useQueryState.d.ts.map +1 -1
- package/dist/hooks/useQueryState.js +19 -12
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/styles.css +1 -1
- package/dist/useSumBy.js +1 -1
- package/package.json +2 -2
- package/src/MatchersInput/index.tsx +17 -163
- package/src/MetricsGraph/index.tsx +17 -1
- package/src/ProfileMetricsGraph/index.tsx +17 -98
- package/src/ProfileSelector/MetricsGraphSection.tsx +14 -115
- package/src/ProfileSelector/index.tsx +114 -109
- package/src/{ProfileSelector/QueryControls.tsx → QueryControls/index.tsx} +76 -84
- package/src/SimpleMatchers/Select.tsx +1 -1
- package/src/SimpleMatchers/index.tsx +46 -84
- package/src/ViewMatchers/index.tsx +22 -30
- package/src/contexts/LabelsQueryProvider.tsx +142 -0
- package/src/contexts/UnifiedLabelsContext.tsx +155 -0
- package/src/contexts/utils.ts +43 -0
- package/src/hooks/useLabels.ts +121 -0
- package/src/hooks/useQueryState.ts +26 -15
- package/src/index.tsx +29 -3
- package/src/useSumBy.ts +1 -1
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts +0 -29
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts.map +0 -1
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.js +0 -175
- package/dist/MetricsGraph/UtilizationMetrics/index.d.ts +0 -28
- package/dist/MetricsGraph/UtilizationMetrics/index.d.ts.map +0 -1
- package/dist/MetricsGraph/UtilizationMetrics/index.js +0 -186
- package/dist/ProfileSelector/QueryControls.d.ts +0 -43
- package/dist/ProfileSelector/QueryControls.d.ts.map +0 -1
- package/dist/contexts/MatchersInputLabelsContext.d.ts +0 -29
- package/dist/contexts/MatchersInputLabelsContext.d.ts.map +0 -1
- package/dist/contexts/MatchersInputLabelsContext.js +0 -79
- package/dist/contexts/SimpleMatchersLabelContext.d.ts +0 -25
- package/dist/contexts/SimpleMatchersLabelContext.d.ts.map +0 -1
- package/dist/contexts/SimpleMatchersLabelContext.js +0 -115
- package/dist/contexts/UtilizationLabelsContext.d.ts +0 -15
- package/dist/contexts/UtilizationLabelsContext.d.ts.map +0 -1
- package/dist/contexts/UtilizationLabelsContext.js +0 -25
- package/src/MetricsGraph/UtilizationMetrics/Throughput.tsx +0 -405
- package/src/MetricsGraph/UtilizationMetrics/index.tsx +0 -426
- package/src/contexts/MatchersInputLabelsContext.tsx +0 -141
- package/src/contexts/SimpleMatchersLabelContext.tsx +0 -189
- package/src/contexts/UtilizationLabelsContext.tsx +0 -45
|
@@ -29,13 +29,14 @@ import {Query} from '@parca/parser';
|
|
|
29
29
|
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
30
30
|
import {millisToProtoTimestamp, type NavigateFunction} from '@parca/utilities';
|
|
31
31
|
|
|
32
|
-
import {useLabelNames} from '../MatchersInput/index';
|
|
33
32
|
import {useMetricsGraphDimensions} from '../MetricsGraph/useMetricsGraphDimensions';
|
|
34
|
-
import {
|
|
33
|
+
import {QueryControls} from '../QueryControls';
|
|
34
|
+
import {LabelsQueryProvider, useLabelsQueryProvider} from '../contexts/LabelsQueryProvider';
|
|
35
|
+
import {UnifiedLabelsProvider} from '../contexts/UnifiedLabelsContext';
|
|
36
|
+
import {useLabelNames} from '../hooks/useLabels';
|
|
35
37
|
import {useQueryState} from '../hooks/useQueryState';
|
|
36
38
|
import useGrpcQuery from '../useGrpcQuery';
|
|
37
39
|
import {MetricsGraphSection} from './MetricsGraphSection';
|
|
38
|
-
import {QueryControls} from './QueryControls';
|
|
39
40
|
import {useAutoQuerySelector} from './useAutoQuerySelector';
|
|
40
41
|
|
|
41
42
|
export interface QuerySelection {
|
|
@@ -52,31 +53,9 @@ interface ProfileSelectorFeatures {
|
|
|
52
53
|
showMetricsGraph: boolean;
|
|
53
54
|
showSumBySelector?: boolean;
|
|
54
55
|
showProfileTypeSelector?: boolean;
|
|
55
|
-
disableExplorativeQuerying?: boolean;
|
|
56
56
|
disableProfileTypesDropdown?: boolean;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export interface UtilizationMetrics {
|
|
60
|
-
isSelected: boolean;
|
|
61
|
-
labelset: {
|
|
62
|
-
labels: Array<{
|
|
63
|
-
name: string;
|
|
64
|
-
value: string;
|
|
65
|
-
}>;
|
|
66
|
-
};
|
|
67
|
-
samples: Array<{
|
|
68
|
-
timestamp: number;
|
|
69
|
-
value: number;
|
|
70
|
-
}>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface UtilizationLabels {
|
|
74
|
-
utilizationLabelNames?: string[];
|
|
75
|
-
utilizationFetchLabelValues?: (key: string) => Promise<string[]>;
|
|
76
|
-
utilizationLabelValues?: string[];
|
|
77
|
-
utilizationLabelNamesLoading?: boolean;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
59
|
interface ProfileSelectorProps extends ProfileSelectorFeatures {
|
|
81
60
|
queryClient: QueryServiceClient;
|
|
82
61
|
closeProfile: () => void;
|
|
@@ -85,14 +64,6 @@ interface ProfileSelectorProps extends ProfileSelectorFeatures {
|
|
|
85
64
|
navigateTo: NavigateFunction;
|
|
86
65
|
setDisplayHideMetricsGraphButton?: Dispatch<SetStateAction<boolean>>;
|
|
87
66
|
suffix?: '_a' | '_b'; // For comparison mode
|
|
88
|
-
utilizationMetrics?: Array<{
|
|
89
|
-
name: string;
|
|
90
|
-
humanReadableName: string;
|
|
91
|
-
data: UtilizationMetrics[];
|
|
92
|
-
}>;
|
|
93
|
-
utilizationMetricsLoading?: boolean;
|
|
94
|
-
utilizationLabels?: UtilizationLabels;
|
|
95
|
-
onUtilizationSeriesSelect?: (name: string, seriesIndex: number) => void;
|
|
96
67
|
onSearchHook?: () => void;
|
|
97
68
|
}
|
|
98
69
|
|
|
@@ -139,16 +110,11 @@ const ProfileSelector = ({
|
|
|
139
110
|
showMetricsGraph = true,
|
|
140
111
|
showSumBySelector = true,
|
|
141
112
|
showProfileTypeSelector = true,
|
|
142
|
-
disableExplorativeQuerying = false,
|
|
143
113
|
setDisplayHideMetricsGraphButton,
|
|
144
114
|
suffix,
|
|
145
|
-
utilizationMetrics,
|
|
146
|
-
utilizationMetricsLoading,
|
|
147
|
-
utilizationLabels,
|
|
148
|
-
onUtilizationSeriesSelect,
|
|
149
115
|
onSearchHook,
|
|
150
116
|
}: ProfileSelectorProps): JSX.Element => {
|
|
151
|
-
const {heightStyle} = useMetricsGraphDimensions(comparing,
|
|
117
|
+
const {heightStyle} = useMetricsGraphDimensions(comparing, false);
|
|
152
118
|
const {viewComponent} = useParcaContext();
|
|
153
119
|
const [queryBrowserMode, setQueryBrowserMode] = useURLState('query_browser_mode');
|
|
154
120
|
const batchUpdates = useURLStateBatch();
|
|
@@ -166,6 +132,7 @@ const ProfileSelector = ({
|
|
|
166
132
|
profileSelection,
|
|
167
133
|
setProfileSelection,
|
|
168
134
|
sumByLoading,
|
|
135
|
+
draftParsedQuery,
|
|
169
136
|
} = useQueryState({suffix});
|
|
170
137
|
|
|
171
138
|
// Use draft state for local state instead of committed state
|
|
@@ -201,7 +168,7 @@ const ProfileSelector = ({
|
|
|
201
168
|
error,
|
|
202
169
|
} = useProfileTypes(queryClient, from, to);
|
|
203
170
|
|
|
204
|
-
const {result
|
|
171
|
+
const {result} = useLabelNames(queryClient, profileType.toString(), from, to);
|
|
205
172
|
|
|
206
173
|
const labels = useMemo(() => {
|
|
207
174
|
return result.response?.labelNames === undefined ? [] : result.response.labelNames;
|
|
@@ -242,6 +209,10 @@ const ProfileSelector = ({
|
|
|
242
209
|
const currentTo = timeRangeSelection.getToMs(true);
|
|
243
210
|
const currentRangeKey = timeRangeSelection.getRangeKey();
|
|
244
211
|
// Commit with refreshed time range
|
|
212
|
+
console.log(
|
|
213
|
+
'[draftExpression] setQueryExpression: committing with refreshed time range:',
|
|
214
|
+
draftSelection.expression
|
|
215
|
+
);
|
|
245
216
|
commitDraft({
|
|
246
217
|
from: currentFrom,
|
|
247
218
|
to: currentTo,
|
|
@@ -298,77 +269,111 @@ const ProfileSelector = ({
|
|
|
298
269
|
const sumByRef = useRef(null);
|
|
299
270
|
|
|
300
271
|
return (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
profileTypesData={profileTypesData}
|
|
309
|
-
profileTypesLoading={profileTypesLoading}
|
|
310
|
-
selectedProfileName={selectedProfileName}
|
|
311
|
-
setProfileName={setProfileName}
|
|
312
|
-
setMatchersString={setMatchersString}
|
|
313
|
-
setQueryExpression={setQueryExpression}
|
|
314
|
-
query={query}
|
|
315
|
-
queryBrowserRef={queryBrowserRef}
|
|
316
|
-
timeRangeSelection={timeRangeSelection}
|
|
317
|
-
setTimeRangeSelection={handleTimeRangeChange}
|
|
318
|
-
searchDisabled={searchDisabled}
|
|
319
|
-
queryBrowserMode={queryBrowserMode as string}
|
|
320
|
-
setQueryBrowserMode={setQueryBrowserMode}
|
|
321
|
-
advancedModeForQueryBrowser={advancedModeForQueryBrowser}
|
|
322
|
-
setAdvancedModeForQueryBrowser={setAdvancedModeForQueryBrowser}
|
|
323
|
-
queryClient={queryClient}
|
|
324
|
-
sumByRef={sumByRef}
|
|
325
|
-
labels={labels}
|
|
326
|
-
sumBySelection={draftSelection.sumBy ?? []}
|
|
327
|
-
sumBySelectionLoading={sumByLoading}
|
|
328
|
-
setUserSumBySelection={setDraftSumBy}
|
|
329
|
-
profileType={profileType}
|
|
330
|
-
profileTypesError={error}
|
|
331
|
-
viewComponent={viewComponent}
|
|
332
|
-
refreshLabelNames={refetch}
|
|
333
|
-
/>
|
|
334
|
-
{comparing && (
|
|
335
|
-
<div>
|
|
336
|
-
<IconButton
|
|
337
|
-
onClick={() => closeProfile()}
|
|
338
|
-
icon={<CloseIcon />}
|
|
339
|
-
{...testId(TEST_IDS.COMPARE_CLOSE_BUTTON)}
|
|
340
|
-
/>
|
|
341
|
-
</div>
|
|
342
|
-
)}
|
|
343
|
-
</div>
|
|
344
|
-
<MetricsGraphSection
|
|
345
|
-
showMetricsGraph={showMetricsGraph}
|
|
346
|
-
setDisplayHideMetricsGraphButton={setDisplayHideMetricsGraphButton}
|
|
347
|
-
heightStyle={
|
|
348
|
-
utilizationMetrics !== undefined && utilizationMetrics?.length > 0
|
|
349
|
-
? 'auto'
|
|
350
|
-
: heightStyle
|
|
351
|
-
}
|
|
352
|
-
querySelection={querySelection}
|
|
353
|
-
profileSelection={profileSelection}
|
|
354
|
-
comparing={comparing}
|
|
355
|
-
sumBy={querySelection.sumBy ?? []}
|
|
356
|
-
defaultSumByLoading={sumByLoading}
|
|
272
|
+
<>
|
|
273
|
+
<div className="mb-2 flex">
|
|
274
|
+
<LabelsQueryProvider
|
|
275
|
+
setMatchersString={setMatchersString}
|
|
276
|
+
runQuery={setQueryExpression}
|
|
277
|
+
currentQuery={query}
|
|
278
|
+
profileType={selectedProfileName ?? profileType.toString()}
|
|
357
279
|
queryClient={queryClient}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
280
|
+
start={timeRangeSelection.getFromMs()}
|
|
281
|
+
end={timeRangeSelection.getToMs()}
|
|
282
|
+
suffix={suffix}
|
|
283
|
+
>
|
|
284
|
+
<LabelsSource>
|
|
285
|
+
<QueryControls
|
|
286
|
+
showProfileTypeSelector={showProfileTypeSelector}
|
|
287
|
+
showSumBySelector={showSumBySelector}
|
|
288
|
+
profileTypesData={profileTypesData}
|
|
289
|
+
profileTypesLoading={profileTypesLoading}
|
|
290
|
+
selectedProfileName={selectedProfileName}
|
|
291
|
+
setProfileName={setProfileName}
|
|
292
|
+
setMatchersString={setMatchersString}
|
|
293
|
+
setQueryExpression={setQueryExpression}
|
|
294
|
+
query={query}
|
|
295
|
+
queryBrowserRef={queryBrowserRef}
|
|
296
|
+
timeRangeSelection={timeRangeSelection}
|
|
297
|
+
setTimeRangeSelection={handleTimeRangeChange}
|
|
298
|
+
searchDisabled={searchDisabled}
|
|
299
|
+
setQueryBrowserMode={setQueryBrowserMode}
|
|
300
|
+
advancedModeForQueryBrowser={advancedModeForQueryBrowser}
|
|
301
|
+
setAdvancedModeForQueryBrowser={setAdvancedModeForQueryBrowser}
|
|
302
|
+
queryClient={queryClient}
|
|
303
|
+
sumByRef={sumByRef}
|
|
304
|
+
labels={labels}
|
|
305
|
+
sumBySelection={draftSelection.sumBy ?? []}
|
|
306
|
+
sumBySelectionLoading={sumByLoading}
|
|
307
|
+
setUserSumBySelection={setDraftSumBy}
|
|
308
|
+
profileType={profileType}
|
|
309
|
+
profileTypesError={error}
|
|
310
|
+
viewComponent={viewComponent}
|
|
311
|
+
draftSelection={draftSelection}
|
|
312
|
+
setDraftMatchers={setDraftMatchers}
|
|
313
|
+
draftParsedQuery={draftParsedQuery}
|
|
314
|
+
/>
|
|
315
|
+
</LabelsSource>
|
|
316
|
+
</LabelsQueryProvider>
|
|
317
|
+
{comparing && (
|
|
318
|
+
<div>
|
|
319
|
+
<IconButton
|
|
320
|
+
onClick={() => closeProfile()}
|
|
321
|
+
icon={<CloseIcon />}
|
|
322
|
+
{...testId(TEST_IDS.COMPARE_CLOSE_BUTTON)}
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
)}
|
|
326
|
+
</div>
|
|
327
|
+
<MetricsGraphSection
|
|
328
|
+
showMetricsGraph={showMetricsGraph}
|
|
329
|
+
setDisplayHideMetricsGraphButton={setDisplayHideMetricsGraphButton}
|
|
330
|
+
heightStyle={heightStyle}
|
|
331
|
+
querySelection={querySelection}
|
|
332
|
+
profileSelection={profileSelection}
|
|
333
|
+
comparing={comparing}
|
|
334
|
+
sumBy={querySelection.sumBy ?? []}
|
|
335
|
+
defaultSumByLoading={sumByLoading}
|
|
336
|
+
queryClient={queryClient}
|
|
337
|
+
queryExpressionString={queryExpressionString}
|
|
338
|
+
setTimeRangeSelection={handleTimeRangeChange}
|
|
339
|
+
selectQuery={commitDraft}
|
|
340
|
+
setProfileSelection={setProfileSelection}
|
|
341
|
+
query={query}
|
|
342
|
+
setQueryExpression={setQueryExpression}
|
|
343
|
+
setNewQueryExpression={setDraftExpression}
|
|
344
|
+
/>
|
|
345
|
+
</>
|
|
371
346
|
);
|
|
372
347
|
};
|
|
373
348
|
|
|
374
349
|
export default ProfileSelector;
|
|
350
|
+
|
|
351
|
+
const LabelsSource = ({children}: {children: React.ReactNode}): JSX.Element => {
|
|
352
|
+
const {
|
|
353
|
+
labelNames,
|
|
354
|
+
labelValues,
|
|
355
|
+
isLabelNamesLoading,
|
|
356
|
+
isLabelValuesLoading,
|
|
357
|
+
refetchLabelValues,
|
|
358
|
+
refetchLabelNames,
|
|
359
|
+
currentLabelName,
|
|
360
|
+
setCurrentLabelName,
|
|
361
|
+
suffix,
|
|
362
|
+
} = useLabelsQueryProvider();
|
|
363
|
+
|
|
364
|
+
return (
|
|
365
|
+
<UnifiedLabelsProvider
|
|
366
|
+
labelNames={labelNames}
|
|
367
|
+
labelValues={labelValues}
|
|
368
|
+
isLabelNamesLoading={isLabelNamesLoading}
|
|
369
|
+
isLabelValuesLoading={isLabelValuesLoading}
|
|
370
|
+
refetchLabelValues={refetchLabelValues}
|
|
371
|
+
refetchLabelNames={refetchLabelNames}
|
|
372
|
+
currentLabelName={currentLabelName}
|
|
373
|
+
setCurrentLabelName={setCurrentLabelName}
|
|
374
|
+
suffix={suffix}
|
|
375
|
+
>
|
|
376
|
+
{children}
|
|
377
|
+
</UnifiedLabelsProvider>
|
|
378
|
+
);
|
|
379
|
+
};
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
import {useState} from 'react';
|
|
14
|
+
import {useRef, useState} from 'react';
|
|
15
15
|
|
|
16
16
|
import {Switch} from '@headlessui/react';
|
|
17
17
|
import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
@@ -23,10 +23,12 @@ import {ProfileType, Query} from '@parca/parser';
|
|
|
23
23
|
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
24
24
|
|
|
25
25
|
import MatchersInput from '../MatchersInput';
|
|
26
|
+
import {QuerySelection} from '../ProfileSelector';
|
|
26
27
|
import ProfileTypeSelector from '../ProfileTypeSelector';
|
|
27
|
-
import SelectWithRefresh from '../SelectWithRefresh';
|
|
28
|
-
import SimpleMatchers from '../SimpleMatchers';
|
|
28
|
+
import {SelectWithRefresh} from '../SelectWithRefresh';
|
|
29
|
+
import SimpleMatchers from '../SimpleMatchers/';
|
|
29
30
|
import ViewMatchers from '../ViewMatchers';
|
|
31
|
+
import {useLabelNames} from '../hooks/useLabels';
|
|
30
32
|
|
|
31
33
|
interface SelectOption {
|
|
32
34
|
label: string;
|
|
@@ -34,13 +36,22 @@ interface SelectOption {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
interface QueryControlsProps {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
queryClient: QueryServiceClient;
|
|
40
|
+
query: Query;
|
|
41
|
+
profileType: string | ProfileType;
|
|
42
|
+
timeRangeSelection: DateTimeRange;
|
|
43
|
+
setTimeRangeSelection: (range: DateTimeRange) => void;
|
|
44
|
+
setMatchersString: (matchers: string) => void;
|
|
45
|
+
setQueryExpression: (updateTs?: boolean) => void;
|
|
46
|
+
searchDisabled: boolean;
|
|
47
|
+
showProfileTypeSelector?: boolean;
|
|
48
|
+
showSumBySelector?: boolean;
|
|
49
|
+
showAdvancedMode?: boolean;
|
|
50
|
+
disableExplorativeQuerying?: boolean;
|
|
40
51
|
profileTypesData?: ProfileTypesResponse;
|
|
41
|
-
profileTypesLoading
|
|
42
|
-
selectedProfileName
|
|
43
|
-
setProfileName
|
|
52
|
+
profileTypesLoading?: boolean;
|
|
53
|
+
selectedProfileName?: string;
|
|
54
|
+
setProfileName?: (name: string | undefined) => void;
|
|
44
55
|
profileTypesError?: RpcError;
|
|
45
56
|
viewComponent?: {
|
|
46
57
|
disableProfileTypesDropdown?: boolean;
|
|
@@ -48,58 +59,61 @@ interface QueryControlsProps {
|
|
|
48
59
|
labelnames?: string[];
|
|
49
60
|
createViewComponent?: React.ReactNode;
|
|
50
61
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
labels: string[];
|
|
64
|
-
sumBySelection: string[];
|
|
65
|
-
sumBySelectionLoading: boolean;
|
|
66
|
-
setUserSumBySelection: (sumBy: string[]) => void;
|
|
67
|
-
sumByRef: React.RefObject<SelectInstance>;
|
|
68
|
-
profileType: ProfileType;
|
|
69
|
-
refreshLabelNames: () => Promise<void>;
|
|
62
|
+
setQueryBrowserMode?: (mode: string) => void;
|
|
63
|
+
advancedModeForQueryBrowser?: boolean;
|
|
64
|
+
setAdvancedModeForQueryBrowser?: (mode: boolean) => void;
|
|
65
|
+
queryBrowserRef?: React.RefObject<HTMLDivElement>;
|
|
66
|
+
labels?: string[];
|
|
67
|
+
sumBySelection?: string[];
|
|
68
|
+
sumBySelectionLoading?: boolean;
|
|
69
|
+
setUserSumBySelection?: (sumBy: string[]) => void;
|
|
70
|
+
sumByRef?: React.RefObject<SelectInstance>;
|
|
71
|
+
draftSelection: QuerySelection;
|
|
72
|
+
setDraftMatchers: (selection: string) => void;
|
|
73
|
+
draftParsedQuery?: Query | null;
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
export function QueryControls({
|
|
73
|
-
|
|
77
|
+
profileType,
|
|
78
|
+
timeRangeSelection,
|
|
79
|
+
setTimeRangeSelection,
|
|
80
|
+
setQueryExpression,
|
|
81
|
+
searchDisabled,
|
|
82
|
+
showProfileTypeSelector = false,
|
|
83
|
+
showSumBySelector = false,
|
|
84
|
+
showAdvancedMode = true,
|
|
74
85
|
profileTypesData,
|
|
75
|
-
profileTypesLoading,
|
|
86
|
+
profileTypesLoading = false,
|
|
76
87
|
selectedProfileName,
|
|
77
88
|
setProfileName,
|
|
89
|
+
profileTypesError,
|
|
78
90
|
viewComponent,
|
|
79
91
|
setQueryBrowserMode,
|
|
80
|
-
advancedModeForQueryBrowser,
|
|
92
|
+
advancedModeForQueryBrowser = false,
|
|
81
93
|
setAdvancedModeForQueryBrowser,
|
|
82
|
-
setMatchersString,
|
|
83
|
-
setQueryExpression,
|
|
84
|
-
query,
|
|
85
94
|
queryBrowserRef,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
queryClient,
|
|
90
|
-
labels,
|
|
91
|
-
sumBySelection,
|
|
92
|
-
sumBySelectionLoading,
|
|
95
|
+
labels = [],
|
|
96
|
+
sumBySelection = [],
|
|
97
|
+
sumBySelectionLoading = false,
|
|
93
98
|
setUserSumBySelection,
|
|
94
99
|
sumByRef,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
queryClient,
|
|
101
|
+
draftSelection,
|
|
102
|
+
setDraftMatchers,
|
|
103
|
+
draftParsedQuery,
|
|
99
104
|
}: QueryControlsProps): JSX.Element {
|
|
100
105
|
const {timezone} = useParcaContext();
|
|
106
|
+
const defaultQueryBrowserRef = useRef<HTMLDivElement>(null);
|
|
107
|
+
const actualQueryBrowserRef = queryBrowserRef ?? defaultQueryBrowserRef;
|
|
101
108
|
const [searchExecutedTimestamp, setSearchExecutedTimestamp] = useState<number>(0);
|
|
102
109
|
|
|
110
|
+
const {refetch: refetchLabelNames} = useLabelNames(
|
|
111
|
+
queryClient,
|
|
112
|
+
profileType as string,
|
|
113
|
+
timeRangeSelection.getFromMs(),
|
|
114
|
+
timeRangeSelection.getToMs()
|
|
115
|
+
);
|
|
116
|
+
|
|
103
117
|
return (
|
|
104
118
|
<div
|
|
105
119
|
className="flex w-full flex-wrap items-start gap-2"
|
|
@@ -114,7 +128,7 @@ export function QueryControls({
|
|
|
114
128
|
profileTypesData={profileTypesData}
|
|
115
129
|
loading={profileTypesLoading}
|
|
116
130
|
selectedKey={selectedProfileName}
|
|
117
|
-
onSelection={setProfileName}
|
|
131
|
+
onSelection={setProfileName ?? (() => {})}
|
|
118
132
|
error={profileTypesError}
|
|
119
133
|
disabled={viewComponent?.disableProfileTypesDropdown}
|
|
120
134
|
/>
|
|
@@ -123,7 +137,7 @@ export function QueryControls({
|
|
|
123
137
|
|
|
124
138
|
<div
|
|
125
139
|
className="w-full flex-1 flex flex-col gap-1 mt-auto"
|
|
126
|
-
ref={
|
|
140
|
+
ref={actualQueryBrowserRef}
|
|
127
141
|
{...testId(TEST_IDS.QUERY_BROWSER_CONTAINER)}
|
|
128
142
|
>
|
|
129
143
|
<div className="flex items-center justify-between">
|
|
@@ -131,13 +145,13 @@ export function QueryControls({
|
|
|
131
145
|
<label className="text-xs" {...testId(TEST_IDS.QUERY_LABEL)}>
|
|
132
146
|
Query
|
|
133
147
|
</label>
|
|
134
|
-
{viewComponent?.disableExplorativeQuerying !== true && (
|
|
148
|
+
{showAdvancedMode && viewComponent?.disableExplorativeQuerying !== true && (
|
|
135
149
|
<>
|
|
136
150
|
<Switch
|
|
137
151
|
checked={advancedModeForQueryBrowser}
|
|
138
152
|
onChange={() => {
|
|
139
|
-
setAdvancedModeForQueryBrowser(!advancedModeForQueryBrowser);
|
|
140
|
-
setQueryBrowserMode(advancedModeForQueryBrowser ? 'simple' : 'advanced');
|
|
153
|
+
setAdvancedModeForQueryBrowser?.(!advancedModeForQueryBrowser);
|
|
154
|
+
setQueryBrowserMode?.(advancedModeForQueryBrowser ? 'simple' : 'advanced');
|
|
141
155
|
}}
|
|
142
156
|
className={`${
|
|
143
157
|
advancedModeForQueryBrowser ? 'bg-indigo-600' : 'bg-gray-400 dark:bg-gray-800'
|
|
@@ -164,37 +178,16 @@ export function QueryControls({
|
|
|
164
178
|
{viewComponent?.disableExplorativeQuerying === true &&
|
|
165
179
|
viewComponent?.labelnames !== undefined &&
|
|
166
180
|
viewComponent?.labelnames.length >= 1 ? (
|
|
167
|
-
<ViewMatchers
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
profileType={selectedProfileName}
|
|
171
|
-
runQuery={setQueryExpression}
|
|
172
|
-
currentQuery={query}
|
|
173
|
-
queryClient={queryClient}
|
|
174
|
-
start={timeRangeSelection.getFromMs()}
|
|
175
|
-
end={timeRangeSelection.getToMs()}
|
|
176
|
-
/>
|
|
177
|
-
) : advancedModeForQueryBrowser ? (
|
|
178
|
-
<MatchersInput
|
|
179
|
-
setMatchersString={setMatchersString}
|
|
180
|
-
runQuery={setQueryExpression}
|
|
181
|
-
currentQuery={query}
|
|
182
|
-
profileType={selectedProfileName}
|
|
183
|
-
queryClient={queryClient}
|
|
184
|
-
start={timeRangeSelection.getFromMs()}
|
|
185
|
-
end={timeRangeSelection.getToMs()}
|
|
186
|
-
/>
|
|
181
|
+
<ViewMatchers labelNames={viewComponent.labelnames} />
|
|
182
|
+
) : showAdvancedMode && advancedModeForQueryBrowser ? (
|
|
183
|
+
<MatchersInput />
|
|
187
184
|
) : (
|
|
188
185
|
<SimpleMatchers
|
|
189
|
-
|
|
190
|
-
runQuery={setQueryExpression}
|
|
191
|
-
currentQuery={query}
|
|
192
|
-
profileType={selectedProfileName}
|
|
193
|
-
queryBrowserRef={queryBrowserRef}
|
|
194
|
-
queryClient={queryClient}
|
|
195
|
-
start={timeRangeSelection.getFromMs()}
|
|
196
|
-
end={timeRangeSelection.getToMs()}
|
|
186
|
+
queryBrowserRef={actualQueryBrowserRef}
|
|
197
187
|
searchExecutedTimestamp={searchExecutedTimestamp}
|
|
188
|
+
draftSelection={draftSelection}
|
|
189
|
+
setDraftMatchers={setDraftMatchers}
|
|
190
|
+
draftParsedQuery={draftParsedQuery}
|
|
198
191
|
/>
|
|
199
192
|
)}
|
|
200
193
|
</div>
|
|
@@ -216,9 +209,9 @@ export function QueryControls({
|
|
|
216
209
|
options={labels.map(label => ({label, value: label}))}
|
|
217
210
|
className="parca-select-container text-sm w-full max-w-80"
|
|
218
211
|
classNamePrefix="parca-select"
|
|
219
|
-
value={
|
|
212
|
+
value={sumBySelection.map(sumBy => ({label: sumBy, value: sumBy}))}
|
|
220
213
|
onChange={newValue => {
|
|
221
|
-
setUserSumBySelection(newValue.map(option => option.value));
|
|
214
|
+
setUserSumBySelection?.(newValue.map(option => option.value));
|
|
222
215
|
}}
|
|
223
216
|
placeholder="Labels..."
|
|
224
217
|
styles={{
|
|
@@ -232,14 +225,13 @@ export function QueryControls({
|
|
|
232
225
|
minWidth: '320px',
|
|
233
226
|
position: 'absolute',
|
|
234
227
|
}),
|
|
235
|
-
// menu: provided => ({...provided, width: 'max-content', zIndex: 50}), // Setting the same zIndex as drop down menus
|
|
236
228
|
}}
|
|
237
229
|
isLoading={sumBySelectionLoading}
|
|
238
|
-
isDisabled={!profileType
|
|
230
|
+
isDisabled={!(profileType as ProfileType)?.delta}
|
|
239
231
|
// @ts-expect-error
|
|
240
232
|
ref={sumByRef}
|
|
241
233
|
onKeyDown={e => {
|
|
242
|
-
const currentRef = sumByRef
|
|
234
|
+
const currentRef = sumByRef?.current as unknown as SelectInstance | null;
|
|
243
235
|
if (currentRef == null) {
|
|
244
236
|
return;
|
|
245
237
|
}
|
|
@@ -257,7 +249,7 @@ export function QueryControls({
|
|
|
257
249
|
currentRef.blur();
|
|
258
250
|
}
|
|
259
251
|
}}
|
|
260
|
-
onRefresh={
|
|
252
|
+
onRefresh={refetchLabelNames}
|
|
261
253
|
refreshTitle="Refresh label names"
|
|
262
254
|
refreshTestId="sum-by-refresh-button"
|
|
263
255
|
menuTestId={TEST_IDS.SUM_BY_SELECT_FLYOUT}
|
|
@@ -377,7 +377,7 @@ const CustomSelect: React.FC<CustomSelectProps & Record<string, any>> = ({
|
|
|
377
377
|
<RefreshButton
|
|
378
378
|
onClick={() => void handleRefetch()}
|
|
379
379
|
disabled={isRefetching}
|
|
380
|
-
title="Refresh
|
|
380
|
+
title="Refresh results"
|
|
381
381
|
testId={TEST_IDS.LABEL_VALUE_REFRESH_BUTTON}
|
|
382
382
|
sticky={true}
|
|
383
383
|
loading={isRefetching}
|