@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.
- package/CHANGELOG.md +8 -0
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +1 -3
- package/dist/ProfileExplorer/index.d.ts.map +1 -1
- package/dist/ProfileExplorer/index.js +5 -8
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +0 -2
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts +0 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +2 -11
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +6 -14
- package/dist/ProfileSelector/useAutoQuerySelector.d.ts.map +1 -1
- package/dist/ProfileSelector/useAutoQuerySelector.js +1 -1
- package/dist/ProfileSource.d.ts +4 -11
- package/dist/ProfileSource.d.ts.map +1 -1
- package/dist/ProfileSource.js +6 -14
- package/dist/ProfileView/components/ColorStackLegend.d.ts.map +1 -1
- package/dist/ProfileView/components/ColorStackLegend.js +14 -10
- package/dist/ProfileView/components/DashboardItems/index.d.ts +1 -3
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/DashboardItems/index.js +2 -2
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts.map +1 -1
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +14 -1
- package/dist/ProfileView/components/InvertCallStack/index.js +1 -1
- package/dist/ProfileView/components/ProfileFilters/index.d.ts +5 -0
- package/dist/ProfileView/components/ProfileFilters/index.d.ts.map +1 -0
- package/dist/ProfileView/components/ProfileFilters/index.js +173 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.d.ts +17 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.d.ts.map +1 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +209 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts +8 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts.map +1 -0
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.js +87 -0
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +3 -10
- package/dist/ProfileView/components/Toolbars/index.d.ts +0 -5
- package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/index.js +6 -6
- package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.js +3 -12
- package/dist/ProfileView/hooks/useVisualizationState.d.ts +0 -3
- package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useVisualizationState.js +0 -7
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +3 -5
- package/dist/ProfileViewWithData.d.ts.map +1 -1
- package/dist/ProfileViewWithData.js +8 -7
- package/dist/Sandwich/index.d.ts.map +1 -1
- package/dist/Sandwich/index.js +4 -2
- package/dist/SimpleMatchers/index.js +8 -8
- package/dist/Table/index.d.ts +0 -2
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +5 -32
- package/dist/styles.css +1 -1
- package/dist/useQuery.d.ts +1 -1
- package/dist/useQuery.d.ts.map +1 -1
- package/dist/useQuery.js +7 -40
- package/package.json +7 -7
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +0 -4
- package/src/ProfileExplorer/index.tsx +4 -13
- package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx +0 -2
- package/src/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.tsx +1 -14
- package/src/ProfileFlameGraph/FlameGraphArrow/index.tsx +4 -16
- package/src/ProfileSelector/useAutoQuerySelector.ts +1 -2
- package/src/ProfileSource.tsx +6 -49
- package/src/ProfileView/components/ColorStackLegend.tsx +16 -12
- package/src/ProfileView/components/DashboardItems/index.tsx +0 -6
- package/src/ProfileView/components/GroupByLabelsDropdown/index.tsx +15 -2
- package/src/ProfileView/components/InvertCallStack/index.tsx +1 -1
- package/src/ProfileView/components/ProfileFilters/index.tsx +294 -0
- package/src/ProfileView/components/ProfileFilters/useProfileFilters.ts +284 -0
- package/src/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.ts +103 -0
- package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +3 -16
- package/src/ProfileView/components/Toolbars/index.tsx +5 -35
- package/src/ProfileView/hooks/useResetStateOnProfileTypeChange.ts +5 -12
- package/src/ProfileView/hooks/useVisualizationState.ts +0 -11
- package/src/ProfileView/index.tsx +1 -15
- package/src/ProfileViewWithData.tsx +9 -9
- package/src/Sandwich/index.tsx +5 -2
- package/src/SimpleMatchers/index.tsx +8 -8
- package/src/Table/index.tsx +3 -44
- package/src/useQuery.tsx +11 -43
- package/dist/ProfileView/components/FilterByFunctionButton.d.ts +0 -3
- package/dist/ProfileView/components/FilterByFunctionButton.d.ts.map +0 -1
- package/dist/ProfileView/components/FilterByFunctionButton.js +0 -89
- 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('
|
|
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
|
-
|
|
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:
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(() => {
|
package/src/Sandwich/index.tsx
CHANGED
|
@@ -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
|
|
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>
|
|
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>
|
|
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>
|
|
108
|
+
<span>Not Regex</span>
|
|
109
109
|
</>
|
|
110
110
|
),
|
|
111
111
|
},
|
package/src/Table/index.tsx
CHANGED
|
@@ -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
|
|
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
|
-
[
|
|
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
|
-
|
|
80
|
-
|
|
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 +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"}
|