@parca/profile 0.19.140 → 0.19.142
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 +5 -1
- package/dist/GraphTooltipArrow/Content.js +224 -30
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +192 -33
- package/dist/GraphTooltipArrow/ExpandOnHoverValue.js +53 -3
- package/dist/GraphTooltipArrow/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/index.js +86 -56
- package/dist/GraphTooltipArrow/useGraphTooltip/index.js +37 -37
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.js +104 -72
- package/dist/MatchersInput/SuggestionItem.js +91 -12
- package/dist/MatchersInput/SuggestionsList.d.ts +2 -1
- package/dist/MatchersInput/SuggestionsList.d.ts.map +1 -1
- package/dist/MatchersInput/SuggestionsList.js +371 -157
- package/dist/MatchersInput/SuggestionsList.test.d.ts +2 -0
- package/dist/MatchersInput/SuggestionsList.test.d.ts.map +1 -0
- package/dist/MatchersInput/index.js +308 -115
- package/dist/MetricsCircle/index.js +39 -3
- package/dist/MetricsGraph/MetricsContextMenu/index.js +119 -19
- package/dist/MetricsGraph/MetricsInfoPanel/index.js +81 -20
- package/dist/MetricsGraph/MetricsTooltip/index.d.ts.map +1 -1
- package/dist/MetricsGraph/MetricsTooltip/index.js +107 -74
- package/dist/MetricsGraph/index.js +552 -203
- package/dist/MetricsGraph/useMetricsGraphDimensions.js +46 -25
- package/dist/MetricsGraph/utils/colorMapping.js +24 -17
- package/dist/MetricsSeries/index.js +70 -7
- package/dist/PreSelectedMatchers/index.d.ts.map +1 -1
- package/dist/PreSelectedMatchers/index.js +249 -102
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +241 -45
- package/dist/ProfileExplorer/ProfileExplorerSingle.js +98 -11
- package/dist/ProfileExplorer/index.js +183 -32
- package/dist/ProfileFlameChart/SamplesStrips/SamplesGraph/index.js +333 -148
- package/dist/ProfileFlameChart/SamplesStrips/SamplesStrips.stories.js +69 -35
- package/dist/ProfileFlameChart/SamplesStrips/index.d.ts +2 -2
- package/dist/ProfileFlameChart/SamplesStrips/index.d.ts.map +1 -1
- package/dist/ProfileFlameChart/SamplesStrips/index.js +645 -134
- package/dist/ProfileFlameChart/SamplesStrips/labelSetUtils.js +114 -55
- package/dist/ProfileFlameChart/index.d.ts.map +1 -1
- package/dist/ProfileFlameChart/index.js +267 -129
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +288 -89
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.js +56 -20
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +211 -140
- package/dist/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.js +133 -38
- package/dist/ProfileFlameGraph/FlameGraphArrow/MiniMap.js +261 -216
- package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.js +72 -47
- package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.js +58 -28
- package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.js +59 -8
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +396 -179
- package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.js +68 -50
- package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.js +62 -38
- package/dist/ProfileFlameGraph/FlameGraphArrow/useNodeColor.js +14 -6
- package/dist/ProfileFlameGraph/FlameGraphArrow/useScrollViewport.js +124 -82
- package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.js +160 -98
- package/dist/ProfileFlameGraph/FlameGraphArrow/useZoom.js +232 -112
- package/dist/ProfileFlameGraph/FlameGraphArrow/utils.js +137 -114
- package/dist/ProfileFlameGraph/benchmarks/benchdata/populateData.js +85 -0
- package/dist/ProfileFlameGraph/index.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/index.js +324 -150
- package/dist/ProfileMetricsGraph/hooks/useQueryRange.js +140 -32
- package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
- package/dist/ProfileMetricsGraph/index.js +519 -258
- package/dist/ProfileSelector/CompareButton.js +132 -12
- package/dist/ProfileSelector/MetricsGraphSection.d.ts.map +1 -1
- package/dist/ProfileSelector/MetricsGraphSection.js +236 -64
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +727 -141
- package/dist/ProfileSelector/useAutoQuerySelector.js +249 -130
- package/dist/ProfileSource.js +230 -163
- package/dist/ProfileTypeSelector/index.js +214 -125
- package/dist/ProfileView/components/ActionButtons/GroupByDropdown.js +50 -4
- package/dist/ProfileView/components/ActionButtons/SortByDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/ActionButtons/SortByDropdown.js +141 -35
- package/dist/ProfileView/components/ColorStackLegend.d.ts.map +1 -1
- package/dist/ProfileView/components/ColorStackLegend.js +185 -55
- package/dist/ProfileView/components/DashboardItems/index.js +87 -28
- package/dist/ProfileView/components/DashboardLayout/index.js +108 -16
- package/dist/ProfileView/components/DiffLegend.js +172 -29
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +199 -55
- package/dist/ProfileView/components/InvertCallStack/index.d.ts.map +1 -1
- package/dist/ProfileView/components/InvertCallStack/index.js +100 -12
- package/dist/ProfileView/components/ProfileFilters/filterPresets.js +260 -315
- package/dist/ProfileView/components/ProfileFilters/index.js +518 -215
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +370 -306
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts +2 -1
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.d.ts.map +1 -1
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.js +188 -118
- package/dist/ProfileView/components/ProfileHeader/index.js +105 -11
- package/dist/ProfileView/components/ShareButton/ResultBox.js +119 -16
- package/dist/ProfileView/components/ShareButton/index.js +352 -62
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +678 -194
- package/dist/ProfileView/components/Toolbars/SwitchMenuItem.js +94 -7
- package/dist/ProfileView/components/Toolbars/TableColumnsDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/TableColumnsDropdown.js +199 -157
- package/dist/ProfileView/components/Toolbars/index.d.ts +2 -2
- package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/index.js +441 -21
- package/dist/ProfileView/components/ViewSelector/Dropdown.js +233 -22
- package/dist/ProfileView/components/ViewSelector/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ViewSelector/index.js +212 -86
- package/dist/ProfileView/components/VisualizationContainer/index.d.ts.map +1 -1
- package/dist/ProfileView/components/VisualizationContainer/index.js +52 -7
- package/dist/ProfileView/components/VisualizationPanel.js +185 -8
- package/dist/ProfileView/context/DashboardContext.d.ts.map +1 -1
- package/dist/ProfileView/context/DashboardContext.js +85 -29
- package/dist/ProfileView/context/ProfileViewContext.js +56 -15
- package/dist/ProfileView/hooks/useAutoSelectDimension.js +71 -41
- package/dist/ProfileView/hooks/useProfileMetadata.js +50 -18
- package/dist/ProfileView/hooks/useResetFlameGraphState.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useResetFlameGraphState.js +32 -12
- package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.js +71 -27
- package/dist/ProfileView/hooks/useResetStateOnSeriesChange.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useResetStateOnSeriesChange.js +40 -19
- package/dist/ProfileView/hooks/useVisualizationState.d.ts +3 -3
- package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useVisualizationState.js +258 -67
- package/dist/ProfileView/index.js +383 -45
- package/dist/ProfileView/types/visualization.js +1 -13
- package/dist/ProfileView/utils/colorUtils.js +8 -7
- package/dist/ProfileViewWithData.d.ts.map +1 -1
- package/dist/ProfileViewWithData.js +332 -228
- package/dist/QueryControls/index.js +418 -47
- package/dist/Sandwich/components/CalleesSection.js +54 -4
- package/dist/Sandwich/components/CallersSection.js +97 -27
- package/dist/Sandwich/components/TableSection.js +77 -4
- package/dist/Sandwich/index.d.ts.map +1 -1
- package/dist/Sandwich/index.js +126 -14
- package/dist/Sandwich/utils/processRowData.js +48 -39
- package/dist/SelectWithRefresh/index.js +102 -28
- package/dist/SimpleMatchers/Select.js +520 -187
- package/dist/SimpleMatchers/index.js +590 -288
- package/dist/SourceView/Highlighter.js +230 -70
- package/dist/SourceView/LineNo.js +72 -17
- package/dist/SourceView/index.d.ts.map +1 -1
- package/dist/SourceView/index.js +178 -104
- package/dist/SourceView/lang-detector/ext-to-lang.json +798 -798
- package/dist/SourceView/lang-detector/index.js +28 -14
- package/dist/SourceView/useSelectedLineRange.d.ts.map +1 -1
- package/dist/SourceView/useSelectedLineRange.js +99 -23
- package/dist/Table/ColorCell.js +42 -1
- package/dist/Table/ColumnsVisibility.js +114 -6
- package/dist/Table/MoreDropdown.d.ts.map +1 -1
- package/dist/Table/MoreDropdown.js +122 -25
- package/dist/Table/TableContextMenu.d.ts.map +1 -1
- package/dist/Table/TableContextMenu.js +151 -137
- package/dist/Table/TableContextMenuWrapper.js +59 -14
- package/dist/Table/hooks/useColorManagement.js +58 -16
- package/dist/Table/hooks/useTableConfiguration.d.ts.map +1 -1
- package/dist/Table/hooks/useTableConfiguration.js +333 -169
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +222 -128
- package/dist/Table/utils/functions.js +169 -144
- package/dist/Table/utils/topAndBottomExpandedRowModel.js +69 -52
- package/dist/TimelineGuide/index.js +209 -16
- package/dist/TopTable/benchmarks/benchdata/populateData.js +91 -0
- package/dist/TopTable/index.d.ts.map +1 -1
- package/dist/TopTable/index.js +342 -123
- package/dist/contexts/LabelsQueryProvider.js +94 -32
- package/dist/contexts/UnifiedLabelsContext.js +114 -49
- package/dist/contexts/utils.js +37 -15
- package/dist/hooks/useCompareModeMeta.d.ts.map +1 -1
- package/dist/hooks/useCompareModeMeta.js +158 -64
- package/dist/hooks/useLabels.js +295 -52
- package/dist/hooks/useQueryState.d.ts +3 -3
- package/dist/hooks/useQueryState.d.ts.map +1 -1
- package/dist/hooks/useQueryState.js +373 -332
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -8
- package/dist/testdata/fg-diff.json +3750 -0
- package/dist/testdata/fg-simple.json +1879 -0
- package/dist/testdata/link_data.json +56 -0
- package/dist/testdata/tabular.json +30 -0
- package/dist/testdata/test_flamegraph.json +26846 -0
- package/dist/testdata/test_graph.json +53 -0
- package/dist/useDelayedLoader.js +32 -18
- package/dist/useGrpcQuery/index.js +71 -11
- package/dist/useHasProfileData.js +90 -12
- package/dist/useQuery.js +205 -64
- package/dist/useSumBy.d.ts +1 -1
- package/dist/useSumBy.d.ts.map +1 -1
- package/dist/useSumBy.js +294 -138
- package/dist/utils.js +62 -30
- package/package.json +9 -10
- package/src/GraphTooltipArrow/index.tsx +3 -0
- package/src/GraphTooltipArrow/useGraphTooltipMetaInfo/index.ts +13 -11
- package/src/MatchersInput/SuggestionsList.test.tsx +70 -0
- package/src/MatchersInput/SuggestionsList.tsx +11 -10
- package/src/MatchersInput/index.tsx +1 -1
- package/src/MetricsGraph/MetricsTooltip/index.tsx +22 -34
- package/src/PreSelectedMatchers/index.tsx +3 -0
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +9 -4
- package/src/ProfileFlameChart/SamplesStrips/index.tsx +2 -2
- package/src/ProfileFlameChart/index.tsx +28 -21
- package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx +9 -10
- package/src/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.tsx +6 -5
- package/src/ProfileFlameGraph/FlameGraphArrow/TooltipContext.tsx +3 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/ZoomControls.tsx +3 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.ts +3 -0
- package/src/ProfileFlameGraph/index.tsx +9 -6
- package/src/ProfileMetricsGraph/index.tsx +8 -6
- package/src/ProfileSelector/MetricsGraphSection.tsx +10 -5
- package/src/ProfileSelector/index.tsx +61 -39
- package/src/ProfileView/components/ActionButtons/SortByDropdown.tsx +6 -10
- package/src/ProfileView/components/ColorStackLegend.tsx +4 -2
- package/src/ProfileView/components/InvertCallStack/index.tsx +4 -5
- package/src/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.test.tsx +192 -94
- package/src/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.ts +21 -21
- package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +28 -24
- package/src/ProfileView/components/Toolbars/TableColumnsDropdown.tsx +5 -4
- package/src/ProfileView/components/Toolbars/index.tsx +3 -3
- package/src/ProfileView/components/ViewSelector/index.tsx +16 -9
- package/src/ProfileView/components/VisualizationContainer/index.tsx +3 -0
- package/src/ProfileView/context/DashboardContext.tsx +6 -6
- package/src/ProfileView/hooks/useResetFlameGraphState.ts +4 -6
- package/src/ProfileView/hooks/useResetStateOnProfileTypeChange.ts +26 -24
- package/src/ProfileView/hooks/useResetStateOnSeriesChange.ts +8 -16
- package/src/ProfileView/hooks/useVisualizationState.ts +69 -61
- package/src/ProfileViewWithData.tsx +35 -29
- package/src/Sandwich/index.tsx +3 -4
- package/src/SourceView/index.tsx +2 -4
- package/src/SourceView/useSelectedLineRange.ts +19 -34
- package/src/Table/MoreDropdown.tsx +11 -9
- package/src/Table/TableContextMenu.tsx +13 -10
- package/src/Table/hooks/useTableConfiguration.tsx +11 -16
- package/src/Table/index.tsx +21 -12
- package/src/TopTable/index.tsx +4 -3
- package/src/hooks/useCompareModeMeta.ts +91 -61
- package/src/hooks/useQueryState.test.tsx +345 -275
- package/src/hooks/useQueryState.ts +118 -136
- package/src/index.tsx +15 -16
- package/src/useDelayedLoader.ts +10 -10
- package/src/useSumBy.ts +15 -21
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.test.js +0 -455
- package/dist/hooks/urlParsers.d.ts +0 -18
- package/dist/hooks/urlParsers.d.ts.map +0 -1
- package/dist/hooks/urlParsers.js +0 -32
- package/dist/hooks/useColorBy.d.ts +0 -5
- package/dist/hooks/useColorBy.d.ts.map +0 -1
- package/dist/hooks/useColorBy.js +0 -26
- package/dist/hooks/useDashboardItems.d.ts +0 -5
- package/dist/hooks/useDashboardItems.d.ts.map +0 -1
- package/dist/hooks/useDashboardItems.js +0 -27
- package/dist/hooks/useQueryState.test.js +0 -868
- package/src/hooks/urlParsers.ts +0 -38
- package/src/hooks/useColorBy.ts +0 -42
- package/src/hooks/useDashboardItems.ts +0 -46
|
@@ -12,10 +12,9 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
14
|
import {Table} from '@uwdata/flechette';
|
|
15
|
-
import {useQueryState} from 'nuqs';
|
|
16
15
|
|
|
17
16
|
import {QueryRequest_ReportType} from '@parca/client';
|
|
18
|
-
import {useParcaContext} from '@parca/components';
|
|
17
|
+
import {useParcaContext, useURLState} from '@parca/components';
|
|
19
18
|
|
|
20
19
|
import {
|
|
21
20
|
FIELD_FUNCTION_FILE_NAME,
|
|
@@ -31,8 +30,6 @@ import {
|
|
|
31
30
|
import {arrowToString} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
|
|
32
31
|
import {ProfileSource} from '../../ProfileSource';
|
|
33
32
|
import {useProfileViewContext} from '../../ProfileView/context/ProfileViewContext';
|
|
34
|
-
import {stringParam} from '../../hooks/urlParsers';
|
|
35
|
-
import {useDashboardItems} from '../../hooks/useDashboardItems';
|
|
36
33
|
import {useQuery} from '../../useQuery';
|
|
37
34
|
|
|
38
35
|
interface Props {
|
|
@@ -110,23 +107,28 @@ export const useGraphTooltipMetaInfo = ({table, row}: Props): GraphTooltipMetaIn
|
|
|
110
107
|
])
|
|
111
108
|
.filter(value => value[1] !== '') as Array<[string, string]>;
|
|
112
109
|
|
|
113
|
-
const
|
|
110
|
+
const [dashboardItems, setDashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
111
|
+
alwaysReturnArray: true,
|
|
112
|
+
});
|
|
114
113
|
|
|
115
|
-
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
+
const [unusedBuildId, setSourceBuildId] = useURLState('source_buildid');
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
118
|
+
const [unusedFilename, setSourceFilename] = useURLState('source_filename');
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
121
|
+
const [unusedLine, setSourceLine] = useURLState('source_line');
|
|
120
122
|
|
|
121
123
|
const openFile = (): void => {
|
|
122
124
|
setDashboardItems([dashboardItems[0], 'source']);
|
|
123
125
|
if (mappingBuildID != null) {
|
|
124
|
-
|
|
126
|
+
setSourceBuildId(mappingBuildID);
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
setSourceFilename(functionFilename);
|
|
128
130
|
if (lineNumber !== undefined) {
|
|
129
|
-
|
|
131
|
+
setSourceLine(lineNumber.toString());
|
|
130
132
|
}
|
|
131
133
|
};
|
|
132
134
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright 2022 The Parca Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
|
|
14
|
+
import {useRef} from 'react';
|
|
15
|
+
|
|
16
|
+
import {act, fireEvent, render} from '@testing-library/react';
|
|
17
|
+
import {beforeAll, describe, expect, it, vi} from 'vitest';
|
|
18
|
+
|
|
19
|
+
import SuggestionsList, {Suggestion, Suggestions} from './SuggestionsList';
|
|
20
|
+
|
|
21
|
+
vi.mock('@parca/components', () => ({
|
|
22
|
+
RefreshButton: ({title}: {title: string}) => <button type="button">{title}</button>,
|
|
23
|
+
useParcaContext: () => ({
|
|
24
|
+
loader: <div>loading</div>,
|
|
25
|
+
}),
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
beforeAll(() => {
|
|
29
|
+
Element.prototype.scrollIntoView = vi.fn();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const TestHarness = ({inputKey = 'initial'}: {inputKey?: string}): JSX.Element => {
|
|
33
|
+
const inputRef = useRef<HTMLTextAreaElement | null>(null);
|
|
34
|
+
const suggestions = new Suggestions();
|
|
35
|
+
suggestions.labelNames.push(new Suggestion('labelName', 'na', 'namespace'));
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div>
|
|
39
|
+
<textarea key={inputKey} ref={inputRef} />
|
|
40
|
+
<SuggestionsList
|
|
41
|
+
suggestions={suggestions}
|
|
42
|
+
applySuggestion={vi.fn()}
|
|
43
|
+
inputRef={inputRef}
|
|
44
|
+
runQuery={vi.fn()}
|
|
45
|
+
focusedInput
|
|
46
|
+
isLabelNamesLoading={false}
|
|
47
|
+
isLabelValuesLoading={false}
|
|
48
|
+
shouldTrimPrefix={false}
|
|
49
|
+
refetchLabelValues={vi.fn(async () => {})}
|
|
50
|
+
refetchLabelNames={vi.fn(async () => {})}
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
describe('SuggestionsList', () => {
|
|
57
|
+
it('rebinds keyboard listeners when the textarea ref points to a remounted node', () => {
|
|
58
|
+
const {rerender, getByRole, getByText} = render(<TestHarness inputKey="first" />);
|
|
59
|
+
|
|
60
|
+
rerender(<TestHarness inputKey="second" />);
|
|
61
|
+
|
|
62
|
+
const textarea = getByRole('textbox');
|
|
63
|
+
act(() => {
|
|
64
|
+
fireEvent.keyDown(textarea, {key: 'ArrowDown'});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line jest-dom/prefer-to-have-class
|
|
68
|
+
expect(getByText('namespace').className).toContain('bg-indigo-600');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -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 {Fragment, useCallback, useEffect, useState} from 'react';
|
|
14
|
+
import React, {Fragment, useCallback, useEffect, useState} from 'react';
|
|
15
15
|
|
|
16
16
|
import {Transition} from '@headlessui/react';
|
|
17
17
|
import {usePopper} from 'react-popper';
|
|
@@ -48,7 +48,7 @@ export class Suggestions {
|
|
|
48
48
|
interface Props {
|
|
49
49
|
suggestions: Suggestions;
|
|
50
50
|
applySuggestion: (suggestion: Suggestion) => void;
|
|
51
|
-
inputRef: HTMLTextAreaElement | null
|
|
51
|
+
inputRef: React.RefObject<HTMLTextAreaElement | null>;
|
|
52
52
|
runQuery: () => void;
|
|
53
53
|
focusedInput: boolean;
|
|
54
54
|
isLabelNamesLoading: boolean;
|
|
@@ -82,7 +82,7 @@ const SuggestionsList = ({
|
|
|
82
82
|
refetchLabelNames,
|
|
83
83
|
}: Props): JSX.Element => {
|
|
84
84
|
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
|
85
|
-
const {styles, attributes} = usePopper(inputRef, popperElement, {
|
|
85
|
+
const {styles, attributes} = usePopper(inputRef.current, popperElement, {
|
|
86
86
|
placement: 'bottom-start',
|
|
87
87
|
});
|
|
88
88
|
const [highlightedSuggestionIndex, setHighlightedSuggestionIndex] = useState<number>(-1);
|
|
@@ -227,18 +227,19 @@ const SuggestionsList = ({
|
|
|
227
227
|
);
|
|
228
228
|
|
|
229
229
|
useEffect(() => {
|
|
230
|
-
|
|
230
|
+
const el = inputRef.current;
|
|
231
|
+
if (el == null) {
|
|
231
232
|
return;
|
|
232
233
|
}
|
|
233
234
|
|
|
234
|
-
|
|
235
|
-
|
|
235
|
+
el.addEventListener('keydown', handleKeyDown);
|
|
236
|
+
el.addEventListener('keypress', handleKeyPress as any);
|
|
236
237
|
|
|
237
238
|
return () => {
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
el.removeEventListener('keydown', handleKeyDown);
|
|
240
|
+
el.removeEventListener('keypress', handleKeyPress as any);
|
|
240
241
|
};
|
|
241
|
-
}
|
|
242
|
+
});
|
|
242
243
|
|
|
243
244
|
useEffect(() => {
|
|
244
245
|
if (suggestionsLength > 0 && focusedInput) {
|
|
@@ -263,7 +264,7 @@ const SuggestionsList = ({
|
|
|
263
264
|
leaveTo="opacity-0"
|
|
264
265
|
>
|
|
265
266
|
<div
|
|
266
|
-
style={{width: inputRef?.offsetWidth}}
|
|
267
|
+
style={{width: inputRef.current?.offsetWidth}}
|
|
267
268
|
className="absolute z-10 mt-1 max-h-[400px] rounded-md bg-gray-50 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-gray-900 sm:text-sm flex flex-col"
|
|
268
269
|
>
|
|
269
270
|
<div className="flex-1 overflow-auto min-h-0">
|
|
@@ -211,7 +211,7 @@ const MatchersInput = ({setDraftMatchers, draftParsedQuery, commitDraft}: Props)
|
|
|
211
211
|
isLabelNamesLoading={isLabelNamesLoading}
|
|
212
212
|
suggestions={suggestionSections}
|
|
213
213
|
applySuggestion={applySuggestion}
|
|
214
|
-
inputRef={inputRef
|
|
214
|
+
inputRef={inputRef}
|
|
215
215
|
runQuery={commitDraft}
|
|
216
216
|
focusedInput={focusedInput}
|
|
217
217
|
isLabelValuesLoading={
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/* eslint-disable react-hooks/refs */
|
|
15
|
+
|
|
16
|
+
import {useLayoutEffect, useRef, useState} from 'react';
|
|
15
17
|
|
|
16
18
|
import {usePopper} from 'react-popper';
|
|
17
19
|
|
|
@@ -28,21 +30,16 @@ interface Props {
|
|
|
28
30
|
content: React.ReactNode;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
y: 0,
|
|
42
|
-
toJSON: () => ({}),
|
|
43
|
-
};
|
|
44
|
-
return emptyRect;
|
|
45
|
-
},
|
|
33
|
+
const emptyRect: DOMRect = {
|
|
34
|
+
width: 0,
|
|
35
|
+
height: 0,
|
|
36
|
+
top: 0,
|
|
37
|
+
right: 0,
|
|
38
|
+
bottom: 0,
|
|
39
|
+
left: 0,
|
|
40
|
+
x: 0,
|
|
41
|
+
y: 0,
|
|
42
|
+
toJSON: () => ({}),
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
const createDomRect = (x: number, y: number): DOMRect => {
|
|
@@ -61,9 +58,13 @@ const createDomRect = (x: number, y: number): DOMRect => {
|
|
|
61
58
|
};
|
|
62
59
|
|
|
63
60
|
const MetricsTooltip = ({x, y, contextElement, content}: Props): JSX.Element => {
|
|
61
|
+
'use no memo';
|
|
64
62
|
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
|
63
|
+
const virtualElementRef = useRef<VirtualElement>({
|
|
64
|
+
getBoundingClientRect: () => emptyRect,
|
|
65
|
+
});
|
|
65
66
|
|
|
66
|
-
const {styles, attributes, update} = usePopper(
|
|
67
|
+
const {styles, attributes, update} = usePopper(virtualElementRef.current, popperElement, {
|
|
67
68
|
placement: 'auto-start',
|
|
68
69
|
strategy: 'absolute',
|
|
69
70
|
modifiers: [
|
|
@@ -82,26 +83,13 @@ const MetricsTooltip = ({x, y, contextElement, content}: Props): JSX.Element =>
|
|
|
82
83
|
],
|
|
83
84
|
});
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const domRect: DOMRect = (contextElement as Element)?.getBoundingClientRect() ??
|
|
88
|
-
width: 0,
|
|
89
|
-
height: 0,
|
|
90
|
-
top: 0,
|
|
91
|
-
right: 0,
|
|
92
|
-
bottom: 0,
|
|
93
|
-
left: 0,
|
|
94
|
-
x: 0,
|
|
95
|
-
y: 0,
|
|
96
|
-
toJSON: () => ({}),
|
|
97
|
-
};
|
|
86
|
+
useLayoutEffect(() => {
|
|
87
|
+
virtualElementRef.current.getBoundingClientRect = (): DOMRect => {
|
|
88
|
+
const domRect: DOMRect = (contextElement as Element)?.getBoundingClientRect() ?? emptyRect;
|
|
98
89
|
return createDomRect(domRect.x + x, domRect.y + y);
|
|
99
90
|
};
|
|
100
|
-
}, [x, y, contextElement]);
|
|
101
|
-
|
|
102
|
-
useEffect(() => {
|
|
103
91
|
void update?.();
|
|
104
|
-
}, [x, y, update]);
|
|
92
|
+
}, [x, y, contextElement, update]);
|
|
105
93
|
|
|
106
94
|
// Don't render anything if content is null or undefined
|
|
107
95
|
if (content == null) {
|
|
@@ -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
|
+
/* eslint-disable react-hooks/refs */
|
|
15
|
+
|
|
14
16
|
import React, {useCallback, useEffect, useRef, useState} from 'react';
|
|
15
17
|
|
|
16
18
|
import {Icon} from '@iconify/react';
|
|
@@ -29,6 +31,7 @@ interface Props {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
const PreSelectedMatchers: React.FC<Props> = ({labelNames}) => {
|
|
34
|
+
'use no memo';
|
|
32
35
|
const [labelValuesMap, setLabelValuesMap] = useState<Record<string, string[]>>({});
|
|
33
36
|
const [isLoading, setIsLoading] = useState<Record<string, boolean>>({});
|
|
34
37
|
const metadata = useGrpcMetadata();
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import {useCallback, useEffect, useMemo, useState} from 'react';
|
|
15
15
|
|
|
16
16
|
import {QueryServiceClient} from '@parca/client';
|
|
17
|
+
import {useURLStateBatch} from '@parca/components';
|
|
17
18
|
import {Query} from '@parca/parser';
|
|
18
19
|
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
19
20
|
import type {NavigateFunction} from '@parca/utilities';
|
|
@@ -33,6 +34,7 @@ const ProfileExplorerCompare = ({
|
|
|
33
34
|
navigateTo,
|
|
34
35
|
}: ProfileExplorerCompareProps): JSX.Element => {
|
|
35
36
|
const [showMetricsGraph, setShowMetricsGraph] = useState(true);
|
|
37
|
+
const batchUpdates = useURLStateBatch();
|
|
36
38
|
const {closeCompareMode, isCompareMode, isCompareAbsolute} = useCompareModeMeta();
|
|
37
39
|
|
|
38
40
|
// Read ProfileSource states from URL for both sides
|
|
@@ -63,10 +65,12 @@ const ProfileExplorerCompare = ({
|
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
if (querySelectionB.expression === '' && querySelectionA.expression !== '') {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
batchUpdates(() => {
|
|
69
|
+
setDraftExpressionB(querySelectionA.expression);
|
|
70
|
+
setDraftTimeRangeB(querySelectionA.from, querySelectionA.to, querySelectionA.timeSelection);
|
|
71
|
+
// Commit to update the URL and trigger metrics graph load
|
|
72
|
+
commitDraftB();
|
|
73
|
+
});
|
|
70
74
|
}
|
|
71
75
|
}, [
|
|
72
76
|
isCompareMode,
|
|
@@ -78,6 +82,7 @@ const ProfileExplorerCompare = ({
|
|
|
78
82
|
setDraftExpressionB,
|
|
79
83
|
setDraftTimeRangeB,
|
|
80
84
|
commitDraftB,
|
|
85
|
+
batchUpdates,
|
|
81
86
|
]);
|
|
82
87
|
|
|
83
88
|
const closeProfileA = useCallback((): void => {
|
|
@@ -39,10 +39,10 @@ interface Props {
|
|
|
39
39
|
loading?: boolean;
|
|
40
40
|
cpus: LabelSet[];
|
|
41
41
|
data: DataPoint[][];
|
|
42
|
-
selectedTimeframe
|
|
42
|
+
selectedTimeframe?: {
|
|
43
43
|
labels: LabelSet;
|
|
44
44
|
bounds: NumberDuo;
|
|
45
|
-
}
|
|
45
|
+
};
|
|
46
46
|
onSelectedTimeframe: (labels: LabelSet, bounds: NumberDuo | undefined) => void;
|
|
47
47
|
width?: number;
|
|
48
48
|
bounds: NumberDuo;
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
import {useEffect, useMemo, useRef} from 'react';
|
|
15
15
|
|
|
16
|
-
import {createParser, useQueryState} from 'nuqs';
|
|
17
|
-
|
|
18
16
|
import {LabelSet, QueryRequest_ReportType, QueryServiceClient} from '@parca/client';
|
|
19
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Button,
|
|
19
|
+
useParcaContext,
|
|
20
|
+
useURLState,
|
|
21
|
+
useURLStateCustom,
|
|
22
|
+
type OptionsCustom,
|
|
23
|
+
} from '@parca/components';
|
|
20
24
|
import {Matcher, MatcherTypes, ProfileType, Query} from '@parca/parser';
|
|
21
25
|
import {TimeUnits, formatDate, formatDuration} from '@parca/utilities';
|
|
22
26
|
|
|
@@ -25,7 +29,6 @@ import {boundsFromProfileSource} from '../ProfileFlameGraph/FlameGraphArrow/util
|
|
|
25
29
|
import {MergedProfileSource, ProfileSource, timeFormat} from '../ProfileSource';
|
|
26
30
|
import {useProfileFilters} from '../ProfileView/components/ProfileFilters/useProfileFilters';
|
|
27
31
|
import type {SamplesData} from '../ProfileView/types/visualization';
|
|
28
|
-
import {flamechartDimensionParser} from '../hooks/urlParsers';
|
|
29
32
|
import {useQuery} from '../useQuery';
|
|
30
33
|
import {NumberDuo} from '../utils';
|
|
31
34
|
import {SamplesStrip} from './SamplesStrips';
|
|
@@ -35,8 +38,11 @@ interface SelectedTimeframe {
|
|
|
35
38
|
bounds: NumberDuo;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
const
|
|
39
|
-
parse: (value: string) => {
|
|
41
|
+
const TimeframeStateSerializer: OptionsCustom<SelectedTimeframe | undefined> = {
|
|
42
|
+
parse: (value: string | string[] | undefined) => {
|
|
43
|
+
if (value == null || value === '' || value === 'undefined' || Array.isArray(value)) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
40
46
|
try {
|
|
41
47
|
const [labelPart, boundsPart] = value.split('|');
|
|
42
48
|
if (labelPart != null && boundsPart != null) {
|
|
@@ -55,13 +61,16 @@ const timeframeParser = createParser<SelectedTimeframe>({
|
|
|
55
61
|
} catch {
|
|
56
62
|
// Ignore parsing errors
|
|
57
63
|
}
|
|
58
|
-
return
|
|
64
|
+
return undefined;
|
|
59
65
|
},
|
|
60
|
-
|
|
66
|
+
stringify: (value: SelectedTimeframe | undefined) => {
|
|
67
|
+
if (value == null) {
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
61
70
|
const labelsStr = value.labels.labels.map(l => `${l.name}:${l.value}`).join(',');
|
|
62
71
|
return `${labelsStr}|${value.bounds[0]},${value.bounds[1]}`;
|
|
63
72
|
},
|
|
64
|
-
}
|
|
73
|
+
};
|
|
65
74
|
|
|
66
75
|
interface ProfileFlameChartProps {
|
|
67
76
|
samplesData?: SamplesData;
|
|
@@ -123,16 +132,14 @@ export const ProfileFlameChart = ({
|
|
|
123
132
|
const {protoFilters} = useProfileFilters();
|
|
124
133
|
const zoomControlsRef = useRef<HTMLDivElement>(null);
|
|
125
134
|
|
|
126
|
-
const [selectedTimeframe, setSelectedTimeframe] =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
135
|
+
const [selectedTimeframe, setSelectedTimeframe] = useURLStateCustom<
|
|
136
|
+
SelectedTimeframe | undefined
|
|
137
|
+
>('flamechart_timeframe', TimeframeStateSerializer);
|
|
130
138
|
|
|
131
139
|
// Read flamechart dimension from URL state to detect changes
|
|
132
|
-
const [flamechartDimension] =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
);
|
|
140
|
+
const [flamechartDimension] = useURLState<string[]>('flamechart_dimension', {
|
|
141
|
+
alwaysReturnArray: true,
|
|
142
|
+
});
|
|
136
143
|
|
|
137
144
|
// Reset selection when the parent time range (profileSource) changes
|
|
138
145
|
const timeBoundsKey = boundsFromProfileSource(profileSource).join(',');
|
|
@@ -140,7 +147,7 @@ export const ProfileFlameChart = ({
|
|
|
140
147
|
useEffect(() => {
|
|
141
148
|
if (prevTimeBoundsKey.current !== timeBoundsKey) {
|
|
142
149
|
prevTimeBoundsKey.current = timeBoundsKey;
|
|
143
|
-
|
|
150
|
+
setSelectedTimeframe(undefined);
|
|
144
151
|
}
|
|
145
152
|
}, [timeBoundsKey, setSelectedTimeframe]);
|
|
146
153
|
|
|
@@ -150,16 +157,16 @@ export const ProfileFlameChart = ({
|
|
|
150
157
|
useEffect(() => {
|
|
151
158
|
if (prevDimensionKey.current !== dimensionKey) {
|
|
152
159
|
prevDimensionKey.current = dimensionKey;
|
|
153
|
-
|
|
160
|
+
setSelectedTimeframe(undefined);
|
|
154
161
|
}
|
|
155
162
|
}, [dimensionKey, setSelectedTimeframe]);
|
|
156
163
|
|
|
157
164
|
// Handle timeframe selection from strips
|
|
158
165
|
const handleSelectedTimeframe = (labels: LabelSet, bounds: NumberDuo | undefined): void => {
|
|
159
166
|
if (bounds === undefined) {
|
|
160
|
-
|
|
167
|
+
setSelectedTimeframe(undefined);
|
|
161
168
|
} else {
|
|
162
|
-
|
|
169
|
+
setSelectedTimeframe({labels, bounds});
|
|
163
170
|
}
|
|
164
171
|
};
|
|
165
172
|
|
|
@@ -14,11 +14,10 @@
|
|
|
14
14
|
import {Icon} from '@iconify/react';
|
|
15
15
|
import {Table} from '@uwdata/flechette';
|
|
16
16
|
import cx from 'classnames';
|
|
17
|
-
import {useQueryState} from 'nuqs';
|
|
18
17
|
import {Item, Menu, Separator, Submenu} from 'react-contexify';
|
|
19
18
|
import {Tooltip} from 'react-tooltip';
|
|
20
19
|
|
|
21
|
-
import {useParcaContext} from '@parca/components';
|
|
20
|
+
import {useParcaContext, useURLState} from '@parca/components';
|
|
22
21
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
23
22
|
import {ProfileType} from '@parca/parser';
|
|
24
23
|
import {TEST_IDS} from '@parca/test-utils';
|
|
@@ -26,8 +25,6 @@ import {getLastItem} from '@parca/utilities';
|
|
|
26
25
|
|
|
27
26
|
import {useGraphTooltip} from '../../GraphTooltipArrow/useGraphTooltip';
|
|
28
27
|
import {useGraphTooltipMetaInfo} from '../../GraphTooltipArrow/useGraphTooltipMetaInfo';
|
|
29
|
-
import {stringParam} from '../../hooks/urlParsers';
|
|
30
|
-
import {useDashboardItems} from '../../hooks/useDashboardItems';
|
|
31
28
|
import {hexifyAddress, truncateString} from '../../utils';
|
|
32
29
|
|
|
33
30
|
interface ContextMenuProps {
|
|
@@ -86,10 +83,12 @@ const ContextMenu = ({
|
|
|
86
83
|
inlined,
|
|
87
84
|
} = useGraphTooltipMetaInfo({table, row});
|
|
88
85
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
const [dashboardItems, setDashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
87
|
+
alwaysReturnArray: true,
|
|
88
|
+
});
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
90
|
+
const [sandwichFunctionName, setSandwichFunctionName] = useURLState<string | undefined>(
|
|
91
|
+
'sandwich_function_name'
|
|
93
92
|
);
|
|
94
93
|
|
|
95
94
|
if (contextMenuData === null) {
|
|
@@ -196,12 +195,12 @@ const ContextMenu = ({
|
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
if (dashboardItems.includes('sandwich')) {
|
|
199
|
-
|
|
198
|
+
setSandwichFunctionName(functionName);
|
|
200
199
|
hideMenu();
|
|
201
200
|
return;
|
|
202
201
|
}
|
|
203
202
|
|
|
204
|
-
|
|
203
|
+
setSandwichFunctionName(functionName);
|
|
205
204
|
setDashboardItems([...dashboardItems, 'sandwich']);
|
|
206
205
|
hideMenu();
|
|
207
206
|
}}
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/* eslint-disable react-hooks/set-state-in-effect */
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import {useEffect, useRef, useState} from 'react';
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import {useURLState} from '@parca/components';
|
|
19
19
|
|
|
20
20
|
interface Props {
|
|
21
21
|
text: string;
|
|
@@ -66,11 +66,12 @@ function calculateTruncatedText(
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function TextWithEllipsis({text, x, y, width}: Props): JSX.Element {
|
|
69
|
+
'use no memo';
|
|
69
70
|
const textRef = useRef<SVGTextElement>(null);
|
|
70
71
|
const [displayText, setDisplayText] = useState(text);
|
|
71
|
-
const [alignFunctionName] =
|
|
72
|
+
const [alignFunctionName] = useURLState('align_function_name');
|
|
72
73
|
|
|
73
|
-
const showFunctionNameFromLeft = alignFunctionName === 'left';
|
|
74
|
+
const showFunctionNameFromLeft = alignFunctionName === 'left' || alignFunctionName === undefined;
|
|
74
75
|
|
|
75
76
|
useEffect(() => {
|
|
76
77
|
const textElement = textRef.current;
|
|
@@ -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
|
+
/* eslint-disable react-hooks/refs */
|
|
15
|
+
|
|
14
16
|
import React, {createContext, useCallback, useContext, useMemo, useRef} from 'react';
|
|
15
17
|
|
|
16
18
|
import {Table} from '@uwdata/flechette';
|
|
@@ -68,6 +70,7 @@ export const TooltipProvider: React.FC<TooltipProviderProps> = ({
|
|
|
68
70
|
onTooltipUpdate,
|
|
69
71
|
tooltipId = 'default',
|
|
70
72
|
}) => {
|
|
73
|
+
'use no memo';
|
|
71
74
|
const tooltipStateRef = useRef<TooltipState>({row: null, x: 0, y: 0});
|
|
72
75
|
|
|
73
76
|
const updateTooltip = useCallback(
|
|
@@ -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
|
+
/* eslint-disable react-hooks/refs */
|
|
15
|
+
|
|
14
16
|
import React from 'react';
|
|
15
17
|
|
|
16
18
|
import {Icon} from '@iconify/react';
|
|
@@ -33,6 +35,7 @@ export const ZoomControls = ({
|
|
|
33
35
|
resetZoom,
|
|
34
36
|
portalRef,
|
|
35
37
|
}: ZoomControlsProps): React.JSX.Element => {
|
|
38
|
+
'use no memo';
|
|
36
39
|
const controls = (
|
|
37
40
|
<div className="flex items-center gap-1 rounded-md border border-gray-200 bg-white/90 px-1 py-0.5 shadow-sm backdrop-blur-sm dark:border-gray-600 dark:bg-gray-800/90">
|
|
38
41
|
<button
|
|
@@ -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
|
+
/* eslint-disable react-hooks/set-state-in-effect */
|
|
15
|
+
|
|
14
16
|
import {useEffect, useRef, useState} from 'react';
|
|
15
17
|
|
|
16
18
|
interface UseBatchedRenderingOptions {
|
|
@@ -29,6 +31,7 @@ export const useBatchedRendering = <T>(
|
|
|
29
31
|
items: T[],
|
|
30
32
|
options: UseBatchedRenderingOptions = {}
|
|
31
33
|
): UseBatchedRenderingResult<T> => {
|
|
34
|
+
'use no memo';
|
|
32
35
|
const {batchSize = 500, batchDelay = 0} = options;
|
|
33
36
|
|
|
34
37
|
const [renderedCount, setRenderedCount] = useState(0);
|
|
@@ -15,11 +15,15 @@ import React, {LegacyRef, ReactNode, useCallback, useEffect, useMemo, useState}
|
|
|
15
15
|
|
|
16
16
|
import cx from 'classnames';
|
|
17
17
|
import {AnimatePresence, motion} from 'framer-motion';
|
|
18
|
-
import {useQueryState} from 'nuqs';
|
|
19
18
|
import {useMeasure} from 'react-use';
|
|
20
19
|
|
|
21
20
|
import {FlamegraphArrow} from '@parca/client';
|
|
22
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
FlameGraphSkeleton,
|
|
23
|
+
SandwichFlameGraphSkeleton,
|
|
24
|
+
useParcaContext,
|
|
25
|
+
useURLState,
|
|
26
|
+
} from '@parca/components';
|
|
23
27
|
import {ProfileType} from '@parca/parser';
|
|
24
28
|
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
25
29
|
import {capitalizeOnlyFirstLetter, divide} from '@parca/utilities';
|
|
@@ -29,7 +33,6 @@ import DiffLegend from '../ProfileView/components/DiffLegend';
|
|
|
29
33
|
import {useProfileViewContext} from '../ProfileView/context/ProfileViewContext';
|
|
30
34
|
import {useProfileMetadata} from '../ProfileView/hooks/useProfileMetadata';
|
|
31
35
|
import {useVisualizationState} from '../ProfileView/hooks/useVisualizationState';
|
|
32
|
-
import {boolParam} from '../hooks/urlParsers';
|
|
33
36
|
import {FlameGraphArrow} from './FlameGraphArrow';
|
|
34
37
|
import {CurrentPathFrame} from './FlameGraphArrow/utils';
|
|
35
38
|
|
|
@@ -134,8 +137,8 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
134
137
|
// For non-delta profiles, like goroutines or memory, we want the profiles to be compared absolutely.
|
|
135
138
|
const compareAbsoluteDefault = profileType?.delta === false ? 'true' : 'false';
|
|
136
139
|
|
|
137
|
-
const [compareAbsolute] =
|
|
138
|
-
const isCompareAbsolute = compareAbsolute
|
|
140
|
+
const [compareAbsolute = compareAbsoluteDefault] = useURLState('compare_absolute');
|
|
141
|
+
const isCompareAbsolute = compareAbsolute === 'true';
|
|
139
142
|
|
|
140
143
|
const mappingsListCount = useMemo(
|
|
141
144
|
() => mappingsList.filter(m => m !== '').length,
|
|
@@ -177,7 +180,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
177
180
|
// If there is only one mapping file, we want to color by filename by default.
|
|
178
181
|
useEffect(() => {
|
|
179
182
|
if (mappingsListCount === 1 && colorBy !== 'filename') {
|
|
180
|
-
|
|
183
|
+
setColorBy('filename');
|
|
181
184
|
}
|
|
182
185
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
183
186
|
}, [mappingsListCount]);
|