@parca/profile 0.16.122 → 0.16.124

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.
@@ -13,7 +13,6 @@
13
13
 
14
14
  import {Profiler, ProfilerProps, useEffect, useMemo, useState} from 'react';
15
15
 
16
- import {Icon} from '@iconify/react';
17
16
  import cx from 'classnames';
18
17
  import {scaleLinear} from 'd3';
19
18
  import {
@@ -35,7 +34,6 @@ import {
35
34
  } from '@parca/components';
36
35
  import {useContainerDimensions} from '@parca/dynamicsize';
37
36
  import {getNewSpanColor} from '@parca/functions';
38
- import {CloseIcon} from '@parca/icons';
39
37
  import {selectDarkMode, useAppSelector} from '@parca/store';
40
38
 
41
39
  import {Callgraph} from '../';
@@ -46,6 +44,7 @@ import ProfileShareButton from '../components/ProfileShareButton';
46
44
  import useDelayedLoader from '../useDelayedLoader';
47
45
  import FilterByFunctionButton from './FilterByFunctionButton';
48
46
  import ViewSelector from './ViewSelector';
47
+ import {VisualizationPanel} from './VisualizationPanel';
49
48
 
50
49
  type NavigateFunction = (path: string, queryParams: any, options?: {replace?: boolean}) => void;
51
50
 
@@ -106,6 +105,7 @@ export const ProfileView = ({
106
105
  param: 'dashboard_items',
107
106
  navigateTo,
108
107
  });
108
+ const [currentSearchString] = useURLState({param: 'search_string'});
109
109
  const dashboardItems = rawDashboardItems as string[];
110
110
  const isDarkMode = useAppSelector(selectDarkMode);
111
111
  const isMultiPanelView = dashboardItems.length > 1;
@@ -154,9 +154,11 @@ export const ProfileView = ({
154
154
  const getDashboardItemByType = ({
155
155
  type,
156
156
  isHalfScreen,
157
+ setActionButtons,
157
158
  }: {
158
159
  type: string;
159
160
  isHalfScreen: boolean;
161
+ setActionButtons: (actionButtons: JSX.Element) => void;
160
162
  }): JSX.Element => {
161
163
  switch (type) {
162
164
  case 'icicle': {
@@ -177,6 +179,7 @@ export const ProfileView = ({
177
179
  onContainerResize={onFlamegraphContainerResize}
178
180
  navigateTo={navigateTo}
179
181
  loading={flamegraphData.loading}
182
+ setActionButtons={setActionButtons}
180
183
  />
181
184
  </ConditionalWrapper>
182
185
  ) : (
@@ -202,6 +205,8 @@ export const ProfileView = ({
202
205
  data={topTableData.data}
203
206
  sampleUnit={sampleUnit}
204
207
  navigateTo={navigateTo}
208
+ setActionButtons={setActionButtons}
209
+ currentSearchString={currentSearchString as string}
205
210
  />
206
211
  ) : (
207
212
  <></>
@@ -305,41 +310,15 @@ export const ProfileView = ({
305
310
  snapshot.isDragging ? 'bg-gray-200' : 'bg-white'
306
311
  )}
307
312
  >
308
- <div className="w-full flex justify-end pb-2">
309
- <div className="w-full flex justify-between">
310
- <div
311
- className={cx(
312
- isMultiPanelView ? 'visible' : 'invisible',
313
- 'flex items-center'
314
- )}
315
- {...provided.dragHandleProps}
316
- >
317
- <Icon
318
- className="text-xl"
319
- icon="material-symbols:drag-indicator"
320
- />
321
- </div>
322
- <ViewSelector
323
- defaultValue={dashboardItem}
324
- navigateTo={navigateTo}
325
- position={index}
326
- />
327
- </div>
328
-
329
- {isMultiPanelView && (
330
- <button
331
- type="button"
332
- onClick={() => handleClosePanel(dashboardItem)}
333
- className="pl-2"
334
- >
335
- <CloseIcon />
336
- </button>
337
- )}
338
- </div>
339
- {getDashboardItemByType({
340
- type: dashboardItem,
341
- isHalfScreen: isMultiPanelView,
342
- })}
313
+ <VisualizationPanel
314
+ handleClosePanel={handleClosePanel}
315
+ isMultiPanelView={isMultiPanelView}
316
+ dashboardItem={dashboardItem}
317
+ getDashboardItemByType={getDashboardItemByType}
318
+ dragHandleProps={provided.dragHandleProps}
319
+ navigateTo={navigateTo}
320
+ index={index}
321
+ />
343
322
  </div>
344
323
  )}
345
324
  </Draggable>
@@ -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 {useCallback, useMemo} from 'react';
14
+ import React, {useCallback, useEffect, useMemo} from 'react';
15
15
 
16
16
  import {createColumnHelper, type ColumnDef} from '@tanstack/react-table';
17
17
 
@@ -32,6 +32,8 @@ interface TopTableProps {
32
32
  data?: Top;
33
33
  sampleUnit: string;
34
34
  navigateTo?: NavigateFunction;
35
+ currentSearchString?: string;
36
+ setActionButtons?: (buttons: JSX.Element) => void;
35
37
  }
36
38
 
37
39
  export const RowLabel = (meta: TopNodeMeta | undefined): string => {
@@ -60,15 +62,16 @@ const addPlusSign = (num: string): string => {
60
62
  return `+${num}`;
61
63
  };
62
64
 
63
- export const TopTable = ({
65
+ export const TopTable = React.memo(function TopTable({
64
66
  data: top,
65
67
  sampleUnit: unit,
66
68
  navigateTo,
67
69
  loading,
68
- }: TopTableProps): JSX.Element => {
70
+ currentSearchString,
71
+ setActionButtons,
72
+ }: TopTableProps): JSX.Element {
69
73
  const router = parseParams(window.location.search);
70
74
  const [rawDashboardItems] = useURLState({param: 'dashboard_items'});
71
- const [currentSearchString] = useURLState({param: 'search_string'});
72
75
  const [rawcompareMode] = useURLState({param: 'compare_a'});
73
76
 
74
77
  const compareMode: boolean = rawcompareMode === undefined ? false : rawcompareMode === 'true';
@@ -185,6 +188,27 @@ export const TopTable = ({
185
188
  }
186
189
  }, [navigateTo, router]);
187
190
 
191
+ useEffect(() => {
192
+ if (setActionButtons === undefined) {
193
+ return;
194
+ }
195
+ setActionButtons(
196
+ dashboardItems.length > 1 ? (
197
+ <Button
198
+ color="neutral"
199
+ onClick={clearSelection}
200
+ className="w-auto"
201
+ variant="neutral"
202
+ disabled={currentSearchString === undefined || currentSearchString.length === 0}
203
+ >
204
+ Clear selection
205
+ </Button>
206
+ ) : (
207
+ <></>
208
+ )
209
+ );
210
+ }, [dashboardItems, clearSelection, currentSearchString, setActionButtons]);
211
+
188
212
  const initialSorting = useMemo(() => {
189
213
  return [{id: compareMode ? 'diff' : 'cumulative', desc: true}];
190
214
  }, [compareMode]);
@@ -195,21 +219,6 @@ export const TopTable = ({
195
219
 
196
220
  return (
197
221
  <div className="relative">
198
- {/* Clearing the selection is only useful when two visualizations types are selected. So we'll only show it in that case */}
199
- {dashboardItems.length > 1 && (
200
- <div className="left-[25px] top-[-45px] absolute">
201
- <Button
202
- color="neutral"
203
- onClick={clearSelection}
204
- className="w-auto"
205
- variant="neutral"
206
- disabled={currentSearchString === undefined || currentSearchString.length === 0}
207
- >
208
- Clear selection
209
- </Button>
210
- </div>
211
- )}
212
-
213
222
  <div className="w-full font-robotoMono h-[80vh] overflow-scroll">
214
223
  <Table
215
224
  data={top?.list ?? []}
@@ -223,6 +232,6 @@ export const TopTable = ({
223
232
  </div>
224
233
  </div>
225
234
  );
226
- };
235
+ });
227
236
 
228
237
  export default TopTable;