@parca/profile 0.19.20 → 0.19.22

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 (87) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
  3. package/dist/ProfileExplorer/ProfileExplorerCompare.js +1 -3
  4. package/dist/ProfileExplorer/index.d.ts.map +1 -1
  5. package/dist/ProfileExplorer/index.js +5 -8
  6. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts.map +1 -1
  7. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +0 -2
  8. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts +0 -1
  9. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts.map +1 -1
  10. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +2 -11
  11. package/dist/ProfileFlameGraph/FlameGraphArrow/index.d.ts.map +1 -1
  12. package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +6 -14
  13. package/dist/ProfileSelector/useAutoQuerySelector.d.ts.map +1 -1
  14. package/dist/ProfileSelector/useAutoQuerySelector.js +1 -1
  15. package/dist/ProfileSource.d.ts +4 -11
  16. package/dist/ProfileSource.d.ts.map +1 -1
  17. package/dist/ProfileSource.js +6 -14
  18. package/dist/ProfileView/components/ColorStackLegend.d.ts.map +1 -1
  19. package/dist/ProfileView/components/ColorStackLegend.js +14 -10
  20. package/dist/ProfileView/components/DashboardItems/index.d.ts +1 -3
  21. package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
  22. package/dist/ProfileView/components/DashboardItems/index.js +2 -2
  23. package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts.map +1 -1
  24. package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +14 -1
  25. package/dist/ProfileView/components/InvertCallStack/index.js +1 -1
  26. package/dist/ProfileView/components/ProfileFilters/index.d.ts +5 -0
  27. package/dist/ProfileView/components/ProfileFilters/index.d.ts.map +1 -0
  28. package/dist/ProfileView/components/ProfileFilters/index.js +173 -0
  29. package/dist/ProfileView/components/ProfileFilters/useProfileFilters.d.ts +17 -0
  30. package/dist/ProfileView/components/ProfileFilters/useProfileFilters.d.ts.map +1 -0
  31. package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +209 -0
  32. package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts +8 -0
  33. package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts.map +1 -0
  34. package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.js +87 -0
  35. package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
  36. package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +3 -10
  37. package/dist/ProfileView/components/Toolbars/index.d.ts +0 -5
  38. package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
  39. package/dist/ProfileView/components/Toolbars/index.js +6 -6
  40. package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.d.ts.map +1 -1
  41. package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.js +3 -12
  42. package/dist/ProfileView/hooks/useVisualizationState.d.ts +0 -3
  43. package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
  44. package/dist/ProfileView/hooks/useVisualizationState.js +0 -7
  45. package/dist/ProfileView/index.d.ts.map +1 -1
  46. package/dist/ProfileView/index.js +3 -5
  47. package/dist/ProfileViewWithData.d.ts.map +1 -1
  48. package/dist/ProfileViewWithData.js +8 -7
  49. package/dist/Sandwich/index.d.ts.map +1 -1
  50. package/dist/Sandwich/index.js +4 -2
  51. package/dist/SimpleMatchers/index.js +8 -8
  52. package/dist/Table/index.d.ts +0 -2
  53. package/dist/Table/index.d.ts.map +1 -1
  54. package/dist/Table/index.js +5 -32
  55. package/dist/styles.css +1 -1
  56. package/dist/useQuery.d.ts +1 -1
  57. package/dist/useQuery.d.ts.map +1 -1
  58. package/dist/useQuery.js +7 -40
  59. package/package.json +7 -7
  60. package/src/ProfileExplorer/ProfileExplorerCompare.tsx +0 -4
  61. package/src/ProfileExplorer/index.tsx +4 -13
  62. package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx +0 -2
  63. package/src/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.tsx +1 -14
  64. package/src/ProfileFlameGraph/FlameGraphArrow/index.tsx +4 -16
  65. package/src/ProfileSelector/useAutoQuerySelector.ts +1 -2
  66. package/src/ProfileSource.tsx +6 -49
  67. package/src/ProfileView/components/ColorStackLegend.tsx +16 -12
  68. package/src/ProfileView/components/DashboardItems/index.tsx +0 -6
  69. package/src/ProfileView/components/GroupByLabelsDropdown/index.tsx +15 -2
  70. package/src/ProfileView/components/InvertCallStack/index.tsx +1 -1
  71. package/src/ProfileView/components/ProfileFilters/index.tsx +294 -0
  72. package/src/ProfileView/components/ProfileFilters/useProfileFilters.ts +284 -0
  73. package/src/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.ts +103 -0
  74. package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +3 -16
  75. package/src/ProfileView/components/Toolbars/index.tsx +5 -35
  76. package/src/ProfileView/hooks/useResetStateOnProfileTypeChange.ts +5 -12
  77. package/src/ProfileView/hooks/useVisualizationState.ts +0 -11
  78. package/src/ProfileView/index.tsx +1 -15
  79. package/src/ProfileViewWithData.tsx +9 -9
  80. package/src/Sandwich/index.tsx +5 -2
  81. package/src/SimpleMatchers/index.tsx +8 -8
  82. package/src/Table/index.tsx +3 -44
  83. package/src/useQuery.tsx +11 -43
  84. package/dist/ProfileView/components/FilterByFunctionButton.d.ts +0 -3
  85. package/dist/ProfileView/components/FilterByFunctionButton.d.ts.map +0 -1
  86. package/dist/ProfileView/components/FilterByFunctionButton.js +0 -89
  87. package/src/ProfileView/components/FilterByFunctionButton.tsx +0 -128
@@ -202,9 +202,8 @@ const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
202
202
  defaultValue: FIELD_FUNCTION_NAME,
203
203
  });
204
204
  const [colorStackLegend, setStoreColorStackLegend] = useURLState('color_stack_legend');
205
- const [binaryFrameFilter, setBinaryFrameFilter] = useURLState('binary_frame_filter');
206
205
  const [colorBy, setColorBy] = useURLState('color_by');
207
- const [hiddenBinaries, setHiddenBinaries] = useURLState('binary_frame_filter', {
206
+ const [hiddenBinaries, setHiddenBinaries] = useURLState('hidden_binaries', {
208
207
  defaultValue: [],
209
208
  alwaysReturnArray: true,
210
209
  });
@@ -257,7 +256,7 @@ const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
257
256
  );
258
257
 
259
258
  const resetLegend = (): void => {
260
- setBinaryFrameFilter([]);
259
+ setHiddenBinaries([]);
261
260
  };
262
261
 
263
262
  const menuItems: MenuItemType[] = [
@@ -329,18 +328,6 @@ const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
329
328
  hide: !compareMode,
330
329
  icon: isCompareAbsolute ? 'fluent-mdl2:compare' : 'fluent-mdl2:compare-uneven',
331
330
  },
332
- {
333
- label: 'Highlight matching nodes after filtering',
334
- hide: !!isTableVizOnly,
335
- customSubmenu: (
336
- <SwitchMenuItem
337
- label="Highlight matching nodes after filtering"
338
- id="h-highlight-after-filtering"
339
- userPreferenceDetails={USER_PREFERENCES.HIGHTLIGHT_AFTER_FILTERING}
340
- />
341
- ),
342
- renderAsDiv: true,
343
- },
344
331
  {
345
332
  label: 'Dock Graph MetaInfo',
346
333
  hide: !!isTableVizOnly,
@@ -367,7 +354,7 @@ const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
367
354
  },
368
355
  {
369
356
  label: 'Reset Legend',
370
- hide: binaryFrameFilter === undefined || binaryFrameFilter.length === 0,
357
+ hide: hiddenBinaries === undefined || hiddenBinaries.length === 0,
371
358
  onclick: () => resetLegend(),
372
359
  id: 'h-reset-legend-button',
373
360
  icon: 'system-uicons:reset',
@@ -23,8 +23,8 @@ import {CurrentPathFrame} from '../../../ProfileFlameGraph/FlameGraphArrow/utils
23
23
  import {ProfileSource} from '../../../ProfileSource';
24
24
  import {useDashboard} from '../../context/DashboardContext';
25
25
  import GroupByDropdown from '../ActionButtons/GroupByDropdown';
26
- import FilterByFunctionButton from '../FilterByFunctionButton';
27
26
  import InvertCallStack from '../InvertCallStack';
27
+ import ProfileFilters from '../ProfileFilters';
28
28
  import ShareButton from '../ShareButton';
29
29
  import ViewSelector from '../ViewSelector';
30
30
  import MultiLevelDropdown from './MultiLevelDropdown';
@@ -43,12 +43,9 @@ export interface VisualisationToolbarProps {
43
43
  profileType?: ProfileType;
44
44
  total: bigint;
45
45
  filtered: bigint;
46
- currentSearchString?: string;
47
- setSearchString?: (value: string) => void;
48
46
  groupByLabels: string[];
49
47
  preferencesModal?: boolean;
50
48
  profileViewExternalSubActions?: React.ReactNode;
51
- clearSelection: () => void;
52
49
  setGroupByLabels: (labels: string[]) => void;
53
50
  showVisualizationSelector?: boolean;
54
51
  sandwichFunctionName?: string;
@@ -58,8 +55,6 @@ export interface TableToolbarProps {
58
55
  profileType?: ProfileType;
59
56
  total: bigint;
60
57
  filtered: bigint;
61
- clearSelection: () => void;
62
- currentSearchString?: string;
63
58
  }
64
59
 
65
60
  export interface FlameGraphToolbarProps {
@@ -72,27 +67,11 @@ export interface SandwichFlameGraphToolbarProps {
72
67
  sandwichFunctionName?: string;
73
68
  }
74
69
 
75
- export const TableToolbar: FC<TableToolbarProps> = ({
76
- profileType,
77
- total,
78
- filtered,
79
- clearSelection,
80
- currentSearchString,
81
- }) => {
70
+ export const TableToolbar: FC<TableToolbarProps> = ({profileType, total, filtered}) => {
82
71
  return (
83
72
  <>
84
73
  <div className="flex w-full gap-2 items-end">
85
74
  <TableColumnsDropdown profileType={profileType} total={total} filtered={filtered} />
86
-
87
- <Button
88
- color="neutral"
89
- onClick={clearSelection}
90
- className="w-auto"
91
- variant="neutral"
92
- disabled={currentSearchString === undefined || currentSearchString.length === 0}
93
- >
94
- Clear selection
95
- </Button>
96
75
  </div>
97
76
  </>
98
77
  );
@@ -157,8 +136,6 @@ export const VisualisationToolbar: FC<VisualisationToolbarProps> = ({
157
136
  setNewCurPath,
158
137
  total,
159
138
  filtered,
160
- currentSearchString,
161
- clearSelection,
162
139
  showVisualizationSelector = true,
163
140
  }) => {
164
141
  const {dashboardItems} = useDashboard();
@@ -190,12 +167,11 @@ export const VisualisationToolbar: FC<VisualisationToolbarProps> = ({
190
167
  <InvertCallStack />
191
168
  </>
192
169
  )}
193
-
194
- <FilterByFunctionButton />
170
+ <ProfileFilters />
195
171
 
196
172
  {profileViewExternalSubActions != null ? profileViewExternalSubActions : null}
197
173
  </div>
198
- <div className="flex gap-3">
174
+ <div className="flex gap-2">
199
175
  <MultiLevelDropdown
200
176
  groupBy={groupBy}
201
177
  toggleGroupBy={toggleGroupBy}
@@ -226,13 +202,7 @@ export const VisualisationToolbar: FC<VisualisationToolbarProps> = ({
226
202
  {isTableVizOnly && (
227
203
  <>
228
204
  <Divider />
229
- <TableToolbar
230
- profileType={profileType}
231
- total={total}
232
- filtered={filtered}
233
- clearSelection={clearSelection}
234
- currentSearchString={currentSearchString}
235
- />
205
+ <TableToolbar profileType={profileType} total={total} filtered={filtered} />
236
206
  </>
237
207
  )}
238
208
  </>
@@ -13,12 +13,12 @@
13
13
 
14
14
  import {useURLState} from '@parca/components';
15
15
 
16
+ import {useProfileFilters} from '../components/ProfileFilters/useProfileFilters';
17
+
16
18
  export const useResetStateOnProfileTypeChange = (): (() => void) => {
17
19
  const [groupBy, setGroupBy] = useURLState('group_by');
18
- const [filterByFunction, setFilterByFunction] = useURLState('filter_by_function');
19
- const [excludeFunction, setExcludeFunction] = useURLState('exclude_function');
20
- const [searchString, setSearchString] = useURLState('search_string');
21
20
  const [curPath, setCurPath] = useURLState('cur_path');
21
+ const {resetFilters} = useProfileFilters();
22
22
  const [sandwichFunctionName, setSandwichFunctionName] = useURLState('sandwich_function_name');
23
23
 
24
24
  return () => {
@@ -26,21 +26,14 @@ export const useResetStateOnProfileTypeChange = (): (() => void) => {
26
26
  if (groupBy !== undefined) {
27
27
  setGroupBy(undefined);
28
28
  }
29
- if (filterByFunction !== undefined) {
30
- setFilterByFunction(undefined);
31
- }
32
- if (excludeFunction !== undefined) {
33
- setExcludeFunction(undefined);
34
- }
35
- if (searchString !== undefined) {
36
- setSearchString(undefined);
37
- }
38
29
  if (curPath !== undefined) {
39
30
  setCurPath(undefined);
40
31
  }
41
32
  if (sandwichFunctionName !== undefined) {
42
33
  setSandwichFunctionName(undefined);
43
34
  }
35
+
36
+ resetFilters();
44
37
  });
45
38
  };
46
39
  };
@@ -29,15 +29,12 @@ export const useVisualizationState = (): {
29
29
  setCurPath: (path: string[]) => void;
30
30
  curPathArrow: CurrentPathFrame[];
31
31
  setCurPathArrow: (path: CurrentPathFrame[]) => void;
32
- currentSearchString: string | undefined;
33
- setSearchString: (searchString: string | undefined) => void;
34
32
  colorStackLegend: string | undefined;
35
33
  colorBy: string;
36
34
  setColorBy: (colorBy: string) => void;
37
35
  groupBy: string[];
38
36
  setGroupBy: (keys: string[]) => void;
39
37
  toggleGroupBy: (key: string) => void;
40
- clearSelection: () => void;
41
38
  setGroupByLabels: (labels: string[]) => void;
42
39
  sandwichFunctionName: string | undefined;
43
40
  setSandwichFunctionName: (sandwichFunctionName: string | undefined) => void;
@@ -49,7 +46,6 @@ export const useVisualizationState = (): {
49
46
  stringify: JSONSerializer,
50
47
  defaultValue: '[]',
51
48
  });
52
- const [currentSearchString, setSearchString] = useURLState<string | undefined>('search_string');
53
49
  const [colorStackLegend] = useURLState<string | undefined>('color_stack_legend');
54
50
  const [colorBy, setColorBy] = useURLState('color_by');
55
51
  const [groupBy, setStoreGroupBy] = useURLState<string[]>('group_by', {
@@ -96,10 +92,6 @@ export const useVisualizationState = (): {
96
92
  [groupBy, setGroupBy]
97
93
  );
98
94
 
99
- const clearSelection = useCallback((): void => {
100
- setSearchString?.('');
101
- }, [setSearchString]);
102
-
103
95
  const resetSandwichFunctionName = useCallback((): void => {
104
96
  setSandwichFunctionName(undefined);
105
97
  }, [setSandwichFunctionName]);
@@ -109,8 +101,6 @@ export const useVisualizationState = (): {
109
101
  setCurPath,
110
102
  curPathArrow,
111
103
  setCurPathArrow,
112
- currentSearchString,
113
- setSearchString,
114
104
  colorStackLegend,
115
105
  colorBy: (colorBy as string) ?? '',
116
106
  setColorBy,
@@ -118,7 +108,6 @@ export const useVisualizationState = (): {
118
108
  setGroupBy,
119
109
  toggleGroupBy,
120
110
  setGroupByLabels,
121
- clearSelection,
122
111
  sandwichFunctionName,
123
112
  setSandwichFunctionName,
124
113
  resetSandwichFunctionName,
@@ -59,13 +59,10 @@ export const ProfileView = ({
59
59
  setCurPath,
60
60
  curPathArrow,
61
61
  setCurPathArrow,
62
- currentSearchString,
63
- setSearchString,
64
62
  colorStackLegend,
65
63
  colorBy,
66
64
  groupBy,
67
65
  toggleGroupBy,
68
- clearSelection,
69
66
  setGroupByLabels,
70
67
  sandwichFunctionName,
71
68
  resetSandwichFunctionName,
@@ -105,8 +102,6 @@ export const ProfileView = ({
105
102
  setNewCurPath: setCurPath,
106
103
  curPathArrow,
107
104
  setNewCurPathArrow: setCurPathArrow,
108
- currentSearchString,
109
- setSearchString,
110
105
  perf,
111
106
  queryClient,
112
107
  });
@@ -115,13 +110,7 @@ export const ProfileView = ({
115
110
  const actionButtons = {
116
111
  flame: <FlameGraphToolbar curPath={curPathArrow} setNewCurPath={setCurPathArrow} />,
117
112
  table: (
118
- <TableToolbar
119
- profileType={profileSource?.ProfileType()}
120
- total={total}
121
- filtered={filtered}
122
- clearSelection={clearSelection}
123
- currentSearchString={currentSearchString}
124
- />
113
+ <TableToolbar profileType={profileSource?.ProfileType()} total={total} filtered={filtered} />
125
114
  ),
126
115
  sandwich: (
127
116
  <SandwichFlameGraphToolbar
@@ -155,12 +144,9 @@ export const ProfileView = ({
155
144
  profileType={profileSource?.ProfileType()}
156
145
  total={total}
157
146
  filtered={filtered}
158
- currentSearchString={currentSearchString}
159
- setSearchString={setSearchString}
160
147
  groupByLabels={flamegraphData.metadataLabels ?? []}
161
148
  preferencesModal={preferencesModal}
162
149
  profileViewExternalSubActions={profileViewExternalSubActions}
163
- clearSelection={clearSelection}
164
150
  setGroupByLabels={setGroupByLabels}
165
151
  showVisualizationSelector={showVisualizationSelector}
166
152
  sandwichFunctionName={sandwichFunctionName}
@@ -21,6 +21,7 @@ import {validateFlameChartQuery} from './ProfileFlameGraph';
21
21
  import {FIELD_FUNCTION_NAME} from './ProfileFlameGraph/FlameGraphArrow';
22
22
  import {MergedProfileSource, ProfileSource} from './ProfileSource';
23
23
  import {ProfileView} from './ProfileView';
24
+ import {useProfileFilters} from './ProfileView/components/ProfileFilters/useProfileFilters';
24
25
  import {useQuery} from './useQuery';
25
26
  import {downloadPprof} from './utils';
26
27
 
@@ -49,15 +50,11 @@ export const ProfileViewWithData = ({
49
50
 
50
51
  const [invertStack] = useURLState('invert_call_stack');
51
52
  const invertCallStack = invertStack === 'true';
52
- const [binaryFrameFilterStr] = useURLState<string[] | string>('binary_frame_filter');
53
-
54
- const binaryFrameFilter: string[] =
55
- typeof binaryFrameFilterStr === 'string'
56
- ? binaryFrameFilterStr.split(',')
57
- : binaryFrameFilterStr;
58
53
 
59
54
  const [pprofDownloading, setPprofDownloading] = useState<boolean>(false);
60
55
 
56
+ const {protoFilters} = useProfileFilters();
57
+
61
58
  useEffect(() => {
62
59
  // If profile type is not delta, remove flamechart from the dashboard items
63
60
  // and set it to flame if no other items are selected.
@@ -95,7 +92,7 @@ export const ProfileViewWithData = ({
95
92
  nodeTrimThreshold,
96
93
  groupBy,
97
94
  invertCallStack,
98
- binaryFrameFilter,
95
+ protoFilters,
99
96
  });
100
97
 
101
98
  const {
@@ -110,7 +107,7 @@ export const ProfileViewWithData = ({
110
107
  nodeTrimThreshold,
111
108
  groupBy,
112
109
  invertCallStack,
113
- binaryFrameFilter,
110
+ protoFilters,
114
111
  });
115
112
 
116
113
  const {
@@ -120,6 +117,7 @@ export const ProfileViewWithData = ({
120
117
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.PROFILE_METADATA, {
121
118
  nodeTrimThreshold,
122
119
  groupBy,
120
+ protoFilters,
123
121
  });
124
122
 
125
123
  const {perf} = useParcaContext();
@@ -130,7 +128,7 @@ export const ProfileViewWithData = ({
130
128
  error: tableError,
131
129
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.TABLE_ARROW, {
132
130
  skip: !dashboardItems.includes('table') && !dashboardItems.includes('sandwich'),
133
- binaryFrameFilter,
131
+ protoFilters,
134
132
  });
135
133
 
136
134
  const {
@@ -139,6 +137,7 @@ export const ProfileViewWithData = ({
139
137
  error: callgraphError,
140
138
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
141
139
  skip: !dashboardItems.includes('callgraph'),
140
+ protoFilters,
142
141
  });
143
142
 
144
143
  const {
@@ -149,6 +148,7 @@ export const ProfileViewWithData = ({
149
148
  skip: !dashboardItems.includes('source'),
150
149
  sourceBuildID,
151
150
  sourceFilename,
151
+ protoFilters,
152
152
  });
153
153
 
154
154
  useEffect(() => {
@@ -26,6 +26,7 @@ import useMappingList, {
26
26
  useFilenamesList,
27
27
  } from '../ProfileFlameGraph/FlameGraphArrow/useMappingList';
28
28
  import {ProfileSource} from '../ProfileSource';
29
+ import {useProfileFilters} from '../ProfileView/components/ProfileFilters/useProfileFilters';
29
30
  import {useDashboard} from '../ProfileView/context/DashboardContext';
30
31
  import {useVisualizationState} from '../ProfileView/hooks/useVisualizationState';
31
32
  import {FIELD_FUNCTION_NAME, Row} from '../Table';
@@ -81,6 +82,8 @@ const Sandwich = React.memo(function Sandwich({
81
82
  return (1 / width) * 100;
82
83
  }, []);
83
84
 
85
+ const {protoFilters} = useProfileFilters();
86
+
84
87
  const {
85
88
  isLoading: callersFlamegraphLoading,
86
89
  response: callersFlamegraphResponse,
@@ -93,9 +96,9 @@ const Sandwich = React.memo(function Sandwich({
93
96
  nodeTrimThreshold,
94
97
  groupBy: [FIELD_FUNCTION_NAME],
95
98
  invertCallStack: true,
96
- binaryFrameFilter: [],
97
99
  sandwichByFunction: sandwichFunctionName,
98
100
  skip: sandwichFunctionName === undefined,
101
+ protoFilters,
99
102
  }
100
103
  );
101
104
 
@@ -111,9 +114,9 @@ const Sandwich = React.memo(function Sandwich({
111
114
  nodeTrimThreshold,
112
115
  groupBy: [FIELD_FUNCTION_NAME],
113
116
  invertCallStack: false,
114
- binaryFrameFilter: [],
115
117
  sandwichByFunction: sandwichFunctionName,
116
118
  skip: sandwichFunctionName === undefined,
119
+ protoFilters,
117
120
  }
118
121
  );
119
122
 
@@ -69,10 +69,10 @@ const operatorOptions = [
69
69
  {
70
70
  key: '=',
71
71
  element: {
72
- active: <>=</>,
72
+ active: <>Equals</>,
73
73
  expanded: (
74
74
  <>
75
- <span>=</span>
75
+ <span>Equals</span>
76
76
  </>
77
77
  ),
78
78
  },
@@ -80,10 +80,10 @@ const operatorOptions = [
80
80
  {
81
81
  key: '!=',
82
82
  element: {
83
- active: <>{'!='}</>,
83
+ active: <>Not Equals</>,
84
84
  expanded: (
85
85
  <>
86
- <span>{'!='}</span>
86
+ <span>Not Equals</span>
87
87
  </>
88
88
  ),
89
89
  },
@@ -91,10 +91,10 @@ const operatorOptions = [
91
91
  {
92
92
  key: '=~',
93
93
  element: {
94
- active: <>{'=~'}</>,
94
+ active: <>Regex</>,
95
95
  expanded: (
96
96
  <>
97
- <span>{'=~'}</span>
97
+ <span>Regex</span>
98
98
  </>
99
99
  ),
100
100
  },
@@ -102,10 +102,10 @@ const operatorOptions = [
102
102
  {
103
103
  key: '!~',
104
104
  element: {
105
- active: <>{'!~'}</>,
105
+ active: <>Not Regex</>,
106
106
  expanded: (
107
107
  <>
108
- <span>{'!~'}</span>
108
+ <span>Not Regex</span>
109
109
  </>
110
110
  ),
111
111
  },
@@ -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 React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
14
+ import React, {useCallback, useEffect, useMemo, useRef} from 'react';
15
15
 
16
16
  import {tableFromIPC} from 'apache-arrow';
17
17
  import {AnimatePresence, motion} from 'framer-motion';
@@ -25,7 +25,6 @@ import {
25
25
  } from '@parca/components';
26
26
  import {useCurrentColorProfile} from '@parca/hooks';
27
27
  import {ProfileType} from '@parca/parser';
28
- import {isSearchMatch} from '@parca/utilities';
29
28
 
30
29
  import useMappingList, {
31
30
  useFilenamesList,
@@ -56,8 +55,6 @@ export interface TableProps {
56
55
  filtered: bigint;
57
56
  profileType?: ProfileType;
58
57
  loading: boolean;
59
- currentSearchString?: string;
60
- setSearchString?: (searchString: string) => void;
61
58
  setActionButtons?: (buttons: React.JSX.Element) => void;
62
59
  isHalfScreen: boolean;
63
60
  unit?: string;
@@ -70,8 +67,6 @@ export const Table = React.memo(function Table({
70
67
  filtered,
71
68
  profileType,
72
69
  loading,
73
- currentSearchString,
74
- setSearchString = () => {},
75
70
  isHalfScreen,
76
71
  unit,
77
72
  metadataMappingFiles,
@@ -83,8 +78,6 @@ export const Table = React.memo(function Table({
83
78
  const [_, setSandwichFunctionName] = useURLState<string | undefined>('sandwich_function_name');
84
79
  const [colorBy, setColorBy] = useURLState('color_by');
85
80
  const {isDarkMode} = useParcaContext();
86
- const [scrollToIndex, setScrollToIndex] = useState<number | undefined>(undefined);
87
-
88
81
  const {compareMode} = useProfileViewContext();
89
82
 
90
83
  const MENU_ID = 'table-context-menu';
@@ -138,13 +131,11 @@ export const Table = React.memo(function Table({
138
131
 
139
132
  const selectSpan = useCallback(
140
133
  (span: string): void => {
141
- if (dashboardItems.includes('flamegraph')) {
142
- setSearchString(span.trim());
143
- } else {
134
+ if (!dashboardItems.includes('flamegraph')) {
144
135
  setSandwichFunctionName(span.trim());
145
136
  }
146
137
  },
147
- [setSearchString, setSandwichFunctionName, dashboardItems]
138
+ [setSandwichFunctionName, dashboardItems]
148
139
  );
149
140
 
150
141
  const onRowClick = useCallback(
@@ -158,21 +149,6 @@ export const Table = React.memo(function Table({
158
149
  [selectSpan, dashboardItems.length]
159
150
  );
160
151
 
161
- const shouldHighlightRow = useCallback(
162
- (row: Row) => {
163
- if (!('name' in row)) {
164
- return false;
165
- }
166
- const name = row.name;
167
- return isSearchMatch(currentSearchString as string, name);
168
- },
169
- [currentSearchString]
170
- );
171
-
172
- const enableHighlighting = useMemo(() => {
173
- return currentSearchString != null && currentSearchString?.length > 0;
174
- }, [currentSearchString]);
175
-
176
152
  const rows: DataRow[] = useMemo(() => {
177
153
  if (table == null || table.numRows === 0) {
178
154
  return [];
@@ -291,20 +267,6 @@ export const Table = React.memo(function Table({
291
267
  [rows, show]
292
268
  );
293
269
 
294
- useEffect(() => {
295
- setTimeout(() => {
296
- if (currentSearchString == null || rows.length === 0) return;
297
-
298
- const firstHighlightedRowIndex = rows.findIndex(row => {
299
- return isSearchMatch(currentSearchString, row.name);
300
- });
301
-
302
- if (firstHighlightedRowIndex !== -1) {
303
- setScrollToIndex(firstHighlightedRowIndex);
304
- }
305
- }, 1000); // Adding a delay to allow the table to render seems to be the only way to get this to work i.e. scrolling down to the highlighted row
306
- }, [currentSearchString, rows]);
307
-
308
270
  if (loading) {
309
271
  return (
310
272
  <div className="overflow-clip h-[700px] min-h-[700px]">
@@ -335,10 +297,7 @@ export const Table = React.memo(function Table({
335
297
  initialSorting={initialSorting}
336
298
  columnVisibility={columnVisibility}
337
299
  onRowClick={onRowClick}
338
- enableHighlighting={enableHighlighting}
339
- shouldHighlightRow={shouldHighlightRow}
340
300
  usePointerCursor={dashboardItems.length > 1}
341
- scrollToIndex={scrollToIndex}
342
301
  estimatedRowHeight={ROW_HEIGHT}
343
302
  />
344
303
  </div>
package/src/useQuery.tsx CHANGED
@@ -11,6 +11,8 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
+ import {useMemo} from 'react';
15
+
14
16
  import {RpcError} from '@protobuf-ts/runtime-rpc';
15
17
 
16
18
  import {QueryRequest_ReportType, QueryResponse, QueryServiceClient} from '@parca/client';
@@ -33,8 +35,8 @@ interface UseQueryOptions {
33
35
  sourceFilename?: string;
34
36
  sourceOnly?: boolean;
35
37
  invertCallStack?: boolean;
36
- binaryFrameFilter?: string[];
37
38
  sandwichByFunction?: string;
39
+ protoFilters?: any[]; // Using any[] to match the Filter type from hook
38
40
  }
39
41
 
40
42
  export const useQuery = (
@@ -45,6 +47,11 @@ export const useQuery = (
45
47
  ): IQueryResult => {
46
48
  const {skip = false} = options ?? {};
47
49
  const metadata = useGrpcMetadata();
50
+
51
+ const protoFiltersKey = useMemo(() => {
52
+ return JSON.stringify(options?.protoFilters ?? []);
53
+ }, [options?.protoFilters]);
54
+
48
55
  const {data, isLoading, error} = useGrpcQuery<QueryResponse | undefined>({
49
56
  key: [
50
57
  'query',
@@ -56,9 +63,8 @@ export const useQuery = (
56
63
  options?.sourceOnly,
57
64
  options?.sourceOnly === true ? '' : options?.sourceFilename,
58
65
  options?.invertCallStack ?? false,
59
- options?.binaryFrameFilter ?? '',
60
- profileSource.excludeFunction ?? false,
61
66
  options?.sandwichByFunction ?? '',
67
+ protoFiltersKey,
62
68
  ],
63
69
  queryFn: async () => {
64
70
  const req = profileSource.QueryRequest();
@@ -76,52 +82,14 @@ export const useQuery = (
76
82
  }
77
83
  req.invertCallStack = options?.invertCallStack ?? false;
78
84
 
79
- // Handle filter from ProfileSource (filter by function toolbar)
80
- const functionToFilter = req.filterQuery;
81
- if (functionToFilter !== undefined && functionToFilter !== '') {
82
- req.filter = [
83
- ...req.filter,
84
- {
85
- filter: {
86
- oneofKind: 'stackFilter',
87
- stackFilter: {
88
- filter: {
89
- oneofKind: 'functionNameStackFilter',
90
- functionNameStackFilter: {
91
- functionToFilter,
92
- exclude: profileSource.excludeFunction ?? false,
93
- },
94
- },
95
- },
96
- },
97
- },
98
- ];
85
+ if (options?.protoFilters != null && options?.protoFilters?.length > 0) {
86
+ req.filter = options.protoFilters;
99
87
  }
100
-
101
88
  // Handle sandwich view filter separately
102
89
  if (options?.sandwichByFunction !== undefined) {
103
90
  req.sandwichByFunction = options.sandwichByFunction;
104
91
  }
105
92
 
106
- if (options?.binaryFrameFilter !== undefined && options?.binaryFrameFilter.length > 0) {
107
- req.filter = [
108
- ...req.filter,
109
- {
110
- filter: {
111
- oneofKind: 'frameFilter',
112
- frameFilter: {
113
- filter: {
114
- oneofKind: 'binaryFrameFilter',
115
- binaryFrameFilter: {
116
- includeBinaries: options?.binaryFrameFilter ?? [],
117
- },
118
- },
119
- },
120
- },
121
- },
122
- ];
123
- }
124
-
125
93
  try {
126
94
  const {response} = await client.query(req, {meta: metadata});
127
95
  return response;
@@ -1,3 +0,0 @@
1
- declare const FilterByFunctionButton: () => JSX.Element;
2
- export default FilterByFunctionButton;
3
- //# sourceMappingURL=FilterByFunctionButton.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FilterByFunctionButton.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/components/FilterByFunctionButton.tsx"],"names":[],"mappings":"AAoBA,QAAA,MAAM,sBAAsB,QAAO,GAAG,CAAC,OAyGtC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}