@parca/profile 0.19.83 → 0.19.85

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/MatchersInput/index.d.ts +2 -34
  3. package/dist/MatchersInput/index.d.ts.map +1 -1
  4. package/dist/MatchersInput/index.js +14 -91
  5. package/dist/MetricsGraph/index.d.ts.map +1 -1
  6. package/dist/MetricsGraph/index.js +13 -1
  7. package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
  8. package/dist/ProfileMetricsGraph/index.js +6 -29
  9. package/dist/ProfileSelector/MetricsGraphSection.d.ts +8 -10
  10. package/dist/ProfileSelector/MetricsGraphSection.d.ts.map +1 -1
  11. package/dist/ProfileSelector/MetricsGraphSection.js +8 -41
  12. package/dist/ProfileSelector/index.d.ts +1 -29
  13. package/dist/ProfileSelector/index.d.ts.map +1 -1
  14. package/dist/ProfileSelector/index.js +14 -10
  15. package/dist/QueryControls/index.d.ts +46 -0
  16. package/dist/QueryControls/index.d.ts.map +1 -0
  17. package/dist/{ProfileSelector/QueryControls.js → QueryControls/index.js} +16 -13
  18. package/dist/SimpleMatchers/Select.js +1 -1
  19. package/dist/SimpleMatchers/index.d.ts +6 -10
  20. package/dist/SimpleMatchers/index.d.ts.map +1 -1
  21. package/dist/SimpleMatchers/index.js +30 -45
  22. package/dist/ViewMatchers/index.d.ts +0 -9
  23. package/dist/ViewMatchers/index.d.ts.map +1 -1
  24. package/dist/ViewMatchers/index.js +20 -12
  25. package/dist/contexts/LabelsQueryProvider.d.ts +35 -0
  26. package/dist/contexts/LabelsQueryProvider.d.ts.map +1 -0
  27. package/dist/contexts/LabelsQueryProvider.js +70 -0
  28. package/dist/contexts/UnifiedLabelsContext.d.ts +37 -0
  29. package/dist/contexts/UnifiedLabelsContext.d.ts.map +1 -0
  30. package/dist/contexts/UnifiedLabelsContext.js +88 -0
  31. package/dist/contexts/utils.d.ts +10 -0
  32. package/dist/contexts/utils.d.ts.map +1 -0
  33. package/dist/contexts/utils.js +31 -0
  34. package/dist/hooks/useLabels.d.ts +23 -0
  35. package/dist/hooks/useLabels.d.ts.map +1 -0
  36. package/dist/hooks/useLabels.js +75 -0
  37. package/dist/hooks/useQueryState.d.ts +3 -1
  38. package/dist/hooks/useQueryState.d.ts.map +1 -1
  39. package/dist/hooks/useQueryState.js +19 -12
  40. package/dist/index.d.ts +9 -3
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +9 -3
  43. package/dist/styles.css +1 -1
  44. package/dist/useSumBy.js +1 -1
  45. package/package.json +2 -2
  46. package/src/MatchersInput/index.tsx +17 -163
  47. package/src/MetricsGraph/index.tsx +17 -1
  48. package/src/ProfileMetricsGraph/index.tsx +17 -98
  49. package/src/ProfileSelector/MetricsGraphSection.tsx +25 -119
  50. package/src/ProfileSelector/index.tsx +115 -109
  51. package/src/{ProfileSelector/QueryControls.tsx → QueryControls/index.tsx} +76 -84
  52. package/src/SimpleMatchers/Select.tsx +1 -1
  53. package/src/SimpleMatchers/index.tsx +46 -84
  54. package/src/ViewMatchers/index.tsx +22 -30
  55. package/src/contexts/LabelsQueryProvider.tsx +142 -0
  56. package/src/contexts/UnifiedLabelsContext.tsx +155 -0
  57. package/src/contexts/utils.ts +43 -0
  58. package/src/hooks/useLabels.ts +121 -0
  59. package/src/hooks/useQueryState.ts +27 -16
  60. package/src/index.tsx +29 -3
  61. package/src/useSumBy.ts +1 -1
  62. package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts +0 -29
  63. package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts.map +0 -1
  64. package/dist/MetricsGraph/UtilizationMetrics/Throughput.js +0 -175
  65. package/dist/MetricsGraph/UtilizationMetrics/index.d.ts +0 -28
  66. package/dist/MetricsGraph/UtilizationMetrics/index.d.ts.map +0 -1
  67. package/dist/MetricsGraph/UtilizationMetrics/index.js +0 -186
  68. package/dist/ProfileSelector/QueryControls.d.ts +0 -43
  69. package/dist/ProfileSelector/QueryControls.d.ts.map +0 -1
  70. package/dist/contexts/MatchersInputLabelsContext.d.ts +0 -29
  71. package/dist/contexts/MatchersInputLabelsContext.d.ts.map +0 -1
  72. package/dist/contexts/MatchersInputLabelsContext.js +0 -79
  73. package/dist/contexts/SimpleMatchersLabelContext.d.ts +0 -25
  74. package/dist/contexts/SimpleMatchersLabelContext.d.ts.map +0 -1
  75. package/dist/contexts/SimpleMatchersLabelContext.js +0 -115
  76. package/dist/contexts/UtilizationLabelsContext.d.ts +0 -15
  77. package/dist/contexts/UtilizationLabelsContext.d.ts.map +0 -1
  78. package/dist/contexts/UtilizationLabelsContext.js +0 -25
  79. package/src/MetricsGraph/UtilizationMetrics/Throughput.tsx +0 -405
  80. package/src/MetricsGraph/UtilizationMetrics/index.tsx +0 -426
  81. package/src/contexts/MatchersInputLabelsContext.tsx +0 -141
  82. package/src/contexts/SimpleMatchersLabelContext.tsx +0 -189
  83. 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 {UtilizationLabelsProvider} from '../contexts/UtilizationLabelsContext';
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, utilizationMetrics != null);
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, refetch} = useLabelNames(queryClient, profileType.toString(), from, to);
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,112 @@ const ProfileSelector = ({
298
269
  const sumByRef = useRef(null);
299
270
 
300
271
  return (
301
- <UtilizationLabelsProvider value={{...utilizationLabels}}>
302
- <>
303
- <div className="mb-2 flex">
304
- <QueryControls
305
- showProfileTypeSelector={showProfileTypeSelector}
306
- showSumBySelector={showSumBySelector}
307
- disableExplorativeQuerying={disableExplorativeQuerying}
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
- queryExpressionString={queryExpressionString}
359
- setTimeRangeSelection={handleTimeRangeChange}
360
- selectQuery={commitDraft}
361
- setProfileSelection={setProfileSelection}
362
- query={query}
363
- setQueryExpression={setQueryExpression}
364
- setNewQueryExpression={setDraftExpression}
365
- utilizationMetrics={utilizationMetrics}
366
- utilizationMetricsLoading={utilizationMetricsLoading}
367
- onUtilizationSeriesSelect={onUtilizationSeriesSelect}
368
- />
369
- </>
370
- </UtilizationLabelsProvider>
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
+ commitDraft={commitDraft}
345
+ />
346
+ </>
371
347
  );
372
348
  };
373
349
 
374
350
  export default ProfileSelector;
351
+
352
+ const LabelsSource = ({children}: {children: React.ReactNode}): JSX.Element => {
353
+ const {
354
+ labelNames,
355
+ labelValues,
356
+ isLabelNamesLoading,
357
+ isLabelValuesLoading,
358
+ refetchLabelValues,
359
+ refetchLabelNames,
360
+ currentLabelName,
361
+ setCurrentLabelName,
362
+ suffix,
363
+ } = useLabelsQueryProvider();
364
+
365
+ return (
366
+ <UnifiedLabelsProvider
367
+ labelNames={labelNames}
368
+ labelValues={labelValues}
369
+ isLabelNamesLoading={isLabelNamesLoading}
370
+ isLabelValuesLoading={isLabelValuesLoading}
371
+ refetchLabelValues={refetchLabelValues}
372
+ refetchLabelNames={refetchLabelNames}
373
+ currentLabelName={currentLabelName}
374
+ setCurrentLabelName={setCurrentLabelName}
375
+ suffix={suffix}
376
+ >
377
+ {children}
378
+ </UnifiedLabelsProvider>
379
+ );
380
+ };
@@ -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
- showProfileTypeSelector: boolean;
38
- showSumBySelector: boolean;
39
- disableExplorativeQuerying: boolean;
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: boolean;
42
- selectedProfileName: string;
43
- setProfileName: (name: string | undefined) => void;
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
- queryBrowserMode: string;
52
- setQueryBrowserMode: (mode: string) => void;
53
- advancedModeForQueryBrowser: boolean;
54
- setAdvancedModeForQueryBrowser: (mode: boolean) => void;
55
- setMatchersString: (matchers: string) => void;
56
- setQueryExpression: (updateTs?: boolean) => void;
57
- query: Query;
58
- queryBrowserRef: React.RefObject<HTMLDivElement>;
59
- timeRangeSelection: DateTimeRange;
60
- setTimeRangeSelection: (range: DateTimeRange) => void;
61
- searchDisabled: boolean;
62
- queryClient: QueryServiceClient;
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
- showProfileTypeSelector,
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
- timeRangeSelection,
87
- setTimeRangeSelection,
88
- searchDisabled,
89
- queryClient,
90
- labels,
91
- sumBySelection,
92
- sumBySelectionLoading,
95
+ labels = [],
96
+ sumBySelection = [],
97
+ sumBySelectionLoading = false,
93
98
  setUserSumBySelection,
94
99
  sumByRef,
95
- profileType,
96
- showSumBySelector,
97
- profileTypesError,
98
- refreshLabelNames,
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={queryBrowserRef}
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
- labelNames={viewComponent.labelnames}
169
- setMatchersString={setMatchersString}
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
- setMatchersString={setMatchersString}
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={(sumBySelection ?? []).map(sumBy => ({label: sumBy, value: sumBy}))}
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.delta}
230
+ isDisabled={!(profileType as ProfileType)?.delta}
239
231
  // @ts-expect-error
240
232
  ref={sumByRef}
241
233
  onKeyDown={e => {
242
- const currentRef = sumByRef.current as unknown as SelectInstance | null;
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={refreshLabelNames}
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 label values"
380
+ title="Refresh results"
381
381
  testId={TEST_IDS.LABEL_VALUE_REFRESH_BUTTON}
382
382
  sticky={true}
383
383
  loading={isRefetching}