@parca/profile 0.19.12 → 0.19.13

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 (79) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/GraphTooltipArrow/Content.js +1 -1
  3. package/dist/GraphTooltipArrow/index.js +2 -2
  4. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts.map +1 -1
  5. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +12 -3
  6. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts +1 -1
  7. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts.map +1 -1
  8. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.js +9 -1
  9. package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +1 -0
  10. package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts.map +1 -1
  11. package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +7 -3
  12. package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.d.ts.map +1 -1
  13. package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.js +17 -2
  14. package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -0
  15. package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
  16. package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +23 -8
  17. package/dist/ProfileIcicleGraph/index.d.ts +3 -1
  18. package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
  19. package/dist/ProfileIcicleGraph/index.js +6 -4
  20. package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
  21. package/dist/ProfileView/components/DashboardItems/index.js +1 -1
  22. package/dist/ProfileView/components/ShareButton/index.d.ts.map +1 -1
  23. package/dist/ProfileView/components/ShareButton/index.js +1 -1
  24. package/dist/ProfileView/components/Toolbars/index.d.ts +0 -2
  25. package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
  26. package/dist/ProfileView/components/Toolbars/index.js +4 -5
  27. package/dist/ProfileView/components/ViewSelector/index.d.ts.map +1 -1
  28. package/dist/ProfileView/components/ViewSelector/index.js +18 -11
  29. package/dist/ProfileView/context/DashboardContext.d.ts.map +1 -1
  30. package/dist/ProfileView/context/DashboardContext.js +5 -0
  31. package/dist/ProfileView/index.d.ts.map +1 -1
  32. package/dist/ProfileView/index.js +4 -3
  33. package/dist/Sandwich/components/CalleesSection.d.ts +1 -2
  34. package/dist/Sandwich/components/CalleesSection.d.ts.map +1 -1
  35. package/dist/Sandwich/components/CalleesSection.js +2 -6
  36. package/dist/Sandwich/components/CallersSection.d.ts +4 -2
  37. package/dist/Sandwich/components/CallersSection.d.ts.map +1 -1
  38. package/dist/Sandwich/components/CallersSection.js +45 -9
  39. package/dist/Sandwich/components/TableSection.js +1 -1
  40. package/dist/Sandwich/index.d.ts +0 -1
  41. package/dist/Sandwich/index.d.ts.map +1 -1
  42. package/dist/Sandwich/index.js +27 -79
  43. package/dist/Table/MoreDropdown.d.ts.map +1 -1
  44. package/dist/Table/MoreDropdown.js +1 -2
  45. package/dist/Table/TableContextMenu.d.ts +9 -0
  46. package/dist/Table/TableContextMenu.d.ts.map +1 -0
  47. package/dist/Table/TableContextMenu.js +38 -0
  48. package/dist/Table/TableContextMenuWrapper.d.ts +10 -0
  49. package/dist/Table/TableContextMenuWrapper.d.ts.map +1 -0
  50. package/dist/Table/TableContextMenuWrapper.js +30 -0
  51. package/dist/Table/hooks/useTableConfiguration.d.ts.map +1 -1
  52. package/dist/Table/hooks/useTableConfiguration.js +2 -20
  53. package/dist/Table/index.d.ts.map +1 -1
  54. package/dist/Table/index.js +65 -5
  55. package/dist/styles.css +1 -1
  56. package/package.json +3 -3
  57. package/src/GraphTooltipArrow/Content.tsx +3 -3
  58. package/src/GraphTooltipArrow/index.tsx +2 -2
  59. package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +19 -3
  60. package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.tsx +10 -2
  61. package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +19 -2
  62. package/src/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.tsx +20 -2
  63. package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +40 -6
  64. package/src/ProfileIcicleGraph/index.tsx +20 -2
  65. package/src/ProfileView/components/DashboardItems/index.tsx +0 -1
  66. package/src/ProfileView/components/ShareButton/index.tsx +9 -3
  67. package/src/ProfileView/components/Toolbars/index.tsx +7 -23
  68. package/src/ProfileView/components/ViewSelector/index.tsx +20 -11
  69. package/src/ProfileView/context/DashboardContext.tsx +6 -0
  70. package/src/ProfileView/index.tsx +12 -4
  71. package/src/Sandwich/components/CalleesSection.tsx +1 -7
  72. package/src/Sandwich/components/CallersSection.tsx +92 -35
  73. package/src/Sandwich/components/TableSection.tsx +2 -2
  74. package/src/Sandwich/index.tsx +20 -107
  75. package/src/Table/MoreDropdown.tsx +1 -2
  76. package/src/Table/TableContextMenu.tsx +70 -0
  77. package/src/Table/TableContextMenuWrapper.tsx +48 -0
  78. package/src/Table/hooks/useTableConfiguration.tsx +2 -25
  79. package/src/Table/index.tsx +84 -5
@@ -18,9 +18,14 @@ export const DashboardProvider = ({ children }) => {
18
18
  const [dashboardItems, setDashboardItems] = useURLState('dashboard_items', {
19
19
  alwaysReturnArray: true,
20
20
  });
21
+ const [, setSandwichFunctionName] = useURLState('sandwich_function_name');
21
22
  const handleClosePanel = (visualizationType) => {
22
23
  const newDashboardItems = dashboardItems.filter(item => item !== visualizationType);
23
24
  setDashboardItems(newDashboardItems);
25
+ // Reset sandwich function name when closing sandwich panel
26
+ if (visualizationType === 'sandwich') {
27
+ setSandwichFunctionName(undefined);
28
+ }
24
29
  };
25
30
  const isMultiPanelView = dashboardItems.length > 1;
26
31
  return (_jsx(DashboardContext.Provider, { value: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,sLAarB,gBAAgB,KAAG,GAAG,CAAC,OAyIzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,sLAarB,gBAAgB,KAAG,GAAG,CAAC,OA4IzB,CAAC"}
@@ -18,7 +18,7 @@ import ColorStackLegend from './components/ColorStackLegend';
18
18
  import { getDashboardItem } from './components/DashboardItems';
19
19
  import { DashboardLayout } from './components/DashboardLayout';
20
20
  import { ProfileHeader } from './components/ProfileHeader';
21
- import { IcicleGraphToolbar, TableToolbar, VisualisationToolbar } from './components/Toolbars';
21
+ import { IcicleGraphToolbar, SandwichIcicleGraphToolbar, TableToolbar, VisualisationToolbar, } from './components/Toolbars';
22
22
  import { DashboardProvider } from './context/DashboardContext';
23
23
  import { ProfileViewContextProvider } from './context/ProfileViewContext';
24
24
  import { useProfileMetadata } from './hooks/useProfileMetadata';
@@ -26,7 +26,7 @@ import { useVisualizationState } from './hooks/useVisualizationState';
26
26
  export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, }) => {
27
27
  const { timezone, perf, profileViewExternalMainActions, preferencesModal, profileViewExternalSubActions, } = useParcaContext();
28
28
  const { ref, dimensions } = useContainerDimensions();
29
- const { curPath, setCurPath, curPathArrow, setCurPathArrow, currentSearchString, setSearchString, colorStackLegend, colorBy, groupBy, toggleGroupBy, clearSelection, setGroupByLabels, sandwichFunctionName, setSandwichFunctionName, resetSandwichFunctionName, } = useVisualizationState();
29
+ const { curPath, setCurPath, curPathArrow, setCurPathArrow, currentSearchString, setSearchString, colorStackLegend, colorBy, groupBy, toggleGroupBy, clearSelection, setGroupByLabels, sandwichFunctionName, resetSandwichFunctionName, } = useVisualizationState();
30
30
  const { colorMappings } = useProfileMetadata({
31
31
  flamegraphArrow: flamegraphData.arrow,
32
32
  metadataMappingFiles: flamegraphData.metadataMappingFiles,
@@ -61,7 +61,8 @@ export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, t
61
61
  const actionButtons = {
62
62
  icicle: _jsx(IcicleGraphToolbar, { curPath: curPathArrow, setNewCurPath: setCurPathArrow }),
63
63
  table: (_jsx(TableToolbar, { profileType: profileSource?.ProfileType(), total: total, filtered: filtered, clearSelection: clearSelection, currentSearchString: currentSearchString })),
64
+ sandwich: (_jsx(SandwichIcicleGraphToolbar, { resetSandwichFunctionName: resetSandwichFunctionName, sandwichFunctionName: sandwichFunctionName })),
64
65
  };
65
66
  const hasProfileSource = profileSource !== undefined && profileSource.toString(timezone) !== '';
66
- return (_jsx(KeyDownProvider, { children: _jsx(ProfileViewContextProvider, { value: { profileSource, compareMode }, children: _jsxs(DashboardProvider, { children: [_jsx(ProfileHeader, { profileSourceString: profileSource?.toString(timezone), hasProfileSource: hasProfileSource, externalMainActions: profileViewExternalMainActions }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, curPath: curPathArrow, setNewCurPath: setCurPathArrow, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [], preferencesModal: preferencesModal, profileViewExternalSubActions: profileViewExternalSubActions, clearSelection: clearSelection, setGroupByLabels: setGroupByLabels, showVisualizationSelector: showVisualizationSelector, sandwichFunctionName: sandwichFunctionName, setSandwichFunctionName: setSandwichFunctionName, resetSandwichFunctionName: resetSandwichFunctionName }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorMappings, loading: flamegraphData.metadataLoading })), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DashboardLayout, { getDashboardItemByType: getDashboardItemByType, actionButtons: actionButtons }) })] }) }) }));
67
+ return (_jsx(KeyDownProvider, { children: _jsx(ProfileViewContextProvider, { value: { profileSource, compareMode }, children: _jsxs(DashboardProvider, { children: [_jsx(ProfileHeader, { profileSourceString: profileSource?.toString(timezone), hasProfileSource: hasProfileSource, externalMainActions: profileViewExternalMainActions }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, curPath: curPathArrow, setNewCurPath: setCurPathArrow, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [], preferencesModal: preferencesModal, profileViewExternalSubActions: profileViewExternalSubActions, clearSelection: clearSelection, setGroupByLabels: setGroupByLabels, showVisualizationSelector: showVisualizationSelector, sandwichFunctionName: sandwichFunctionName }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorMappings, loading: flamegraphData.metadataLoading })), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DashboardLayout, { getDashboardItemByType: getDashboardItemByType, actionButtons: actionButtons }) })] }) }) }));
67
68
  };
@@ -4,7 +4,6 @@ import { type CurrentPathFrame } from '../../ProfileIcicleGraph/IcicleGraphArrow
4
4
  import { type ProfileSource } from '../../ProfileSource';
5
5
  interface CalleesSectionProps {
6
6
  calleesRef: React.RefObject<HTMLDivElement>;
7
- isHalfScreen: boolean;
8
7
  calleesFlamegraphResponse?: {
9
8
  report: {
10
9
  oneofKind: string;
@@ -20,6 +19,6 @@ interface CalleesSectionProps {
20
19
  setCurPathArrow: (path: CurrentPathFrame[]) => void;
21
20
  metadataMappingFiles?: string[];
22
21
  }
23
- export declare function CalleesSection({ calleesRef, isHalfScreen, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }: CalleesSectionProps): JSX.Element;
22
+ export declare function CalleesSection({ calleesRef, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }: CalleesSectionProps): JSX.Element;
24
23
  export {};
25
24
  //# sourceMappingURL=CalleesSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,YAAY,EAAE,OAAO,CAAC;IACtB,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,YAAY,EACZ,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAmCnC"}
1
+ {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA+BnC"}
@@ -1,11 +1,7 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import ProfileIcicleGraph from '../../ProfileIcicleGraph';
3
- export function CalleesSection({ calleesRef, isHalfScreen, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }) {
3
+ export function CalleesSection({ calleesRef, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }) {
4
4
  return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileIcicleGraph, { arrow: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
5
5
  ? calleesFlamegraphResponse?.report?.flamegraphArrow
6
- : undefined, total: BigInt(calleesFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: calleesFlamegraphLoading, error: calleesFlamegraphError, isHalfScreen: true, width: calleesRef.current != null
7
- ? isHalfScreen
8
- ? (calleesRef.current.getBoundingClientRect().width - 54) / 2
9
- : calleesRef.current.getBoundingClientRect().width - 16
10
- : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isSandwichIcicleGraph: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
6
+ : undefined, total: BigInt(calleesFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: calleesFlamegraphLoading, error: calleesFlamegraphError, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isSandwichIcicleGraph: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
11
7
  }
@@ -4,7 +4,6 @@ import { type CurrentPathFrame } from '../../ProfileIcicleGraph/IcicleGraphArrow
4
4
  import { type ProfileSource } from '../../ProfileSource';
5
5
  interface CallersSectionProps {
6
6
  callersRef: React.RefObject<HTMLDivElement>;
7
- isHalfScreen: boolean;
8
7
  callersFlamegraphResponse?: {
9
8
  report: {
10
9
  oneofKind: string;
@@ -19,7 +18,10 @@ interface CallersSectionProps {
19
18
  curPathArrow: CurrentPathFrame[];
20
19
  setCurPathArrow: (path: CurrentPathFrame[]) => void;
21
20
  metadataMappingFiles?: string[];
21
+ isExpanded: boolean;
22
+ setIsExpanded: (isExpanded: boolean) => void;
23
+ defaultMaxFrames: number;
22
24
  }
23
- export declare function CallersSection({ callersRef, isHalfScreen, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }: CallersSectionProps): JSX.Element;
25
+ export declare function CallersSection({ callersRef, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, isExpanded, setIsExpanded, defaultMaxFrames, }: CallersSectionProps): JSX.Element;
24
26
  export {};
25
27
  //# sourceMappingURL=CallersSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,YAAY,EAAE,OAAO,CAAC;IACtB,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,YAAY,EACZ,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAoCnC"}
1
+ {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAInD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAevD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAwEnC"}
@@ -1,11 +1,47 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // Copyright 2022 The Parca Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { useMemo } from 'react';
15
+ import { tableFromIPC } from 'apache-arrow';
16
+ import { Tooltip } from 'react-tooltip';
17
+ import { Button } from '@parca/components';
2
18
  import ProfileIcicleGraph from '../../ProfileIcicleGraph';
3
- export function CallersSection({ callersRef, isHalfScreen, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }) {
4
- return (_jsxs("div", { className: "flex relative flex-row", ref: callersRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ["Callers ", '->'] }), _jsx(ProfileIcicleGraph, { arrow: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
5
- ? callersFlamegraphResponse?.report?.flamegraphArrow
6
- : undefined, total: BigInt(callersFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: callersFlamegraphLoading, error: callersFlamegraphError, isHalfScreen: true, width: callersRef.current != null
7
- ? isHalfScreen
8
- ? (callersRef.current.getBoundingClientRect().width - 54) / 2
9
- : callersRef.current.getBoundingClientRect().width - 16
10
- : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isSandwichIcicleGraph: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isFlamegraph: true, profileSource: profileSource, tooltipId: "callers" })] }));
19
+ const FIELD_DEPTH = 'depth';
20
+ function getMaxDepth(depthColumn) {
21
+ if (depthColumn === null)
22
+ return 0;
23
+ let max = 0;
24
+ for (const val of depthColumn) {
25
+ const numVal = Number(val);
26
+ if (numVal > max)
27
+ max = numVal;
28
+ }
29
+ return max;
30
+ }
31
+ export function CallersSection({ callersRef, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, isExpanded, setIsExpanded, defaultMaxFrames, }) {
32
+ const maxDepth = useMemo(() => {
33
+ if (callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow' &&
34
+ callersFlamegraphResponse?.report?.flamegraphArrow != null) {
35
+ const table = tableFromIPC(callersFlamegraphResponse.report.flamegraphArrow.record);
36
+ const depthColumn = table.getChild(FIELD_DEPTH);
37
+ return getMaxDepth(depthColumn);
38
+ }
39
+ return 0;
40
+ }, [callersFlamegraphResponse]);
41
+ const shouldShowButton = maxDepth > defaultMaxFrames;
42
+ return (_jsxs(_Fragment, { children: [shouldShowButton && (_jsxs(Button, { variant: "neutral", onClick: () => setIsExpanded(!isExpanded), className: "absolute right-8 top-[-46px] z-10", type: "button", children: [_jsx("span", { "data-tooltip-content": !isExpanded
43
+ ? `This profile has ${maxDepth} frames, showing only the top ${defaultMaxFrames} frames. Click to show more frames.`
44
+ : `This profile has ${maxDepth} frames, showing all frames. Click to hide frames.`, "data-tooltip-id": "show-more-frames", children: isExpanded ? 'Hide frames' : 'Show more frames' }), _jsx(Tooltip, { id: "show-more-frames" })] })), _jsxs("div", { className: "flex relative flex-row overflow-hidden", ref: callersRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0", children: ["Callers ", '->'] }), _jsx("div", { className: "flex-1 overflow-hidden relative", children: _jsx(ProfileIcicleGraph, { arrow: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
45
+ ? callersFlamegraphResponse?.report?.flamegraphArrow
46
+ : undefined, total: BigInt(callersFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: callersFlamegraphLoading, error: callersFlamegraphError, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isSandwichIcicleGraph: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
11
47
  }
@@ -2,5 +2,5 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Table as TableComponent } from '@parca/components';
3
3
  import { ROW_HEIGHT } from '../../Table/utils/functions';
4
4
  export function TableSection({ rows, columns, initialSorting, selectedRow, onRowClick, shouldHighlightRow, enableHighlighting, columnVisibility, height, sandwichFunctionName, }) {
5
- return (_jsx("div", { style: { height: height !== undefined ? `${height}px` : '80vh' }, className: `font-robotoMono w-full cursor-pointer ${selectedRow != null && sandwichFunctionName !== undefined ? 'w-[50%]' : ''}`, children: _jsx(TableComponent, { data: rows, columns: columns, initialSorting: initialSorting, usePointerCursor: true, onRowClick: onRowClick, shouldHighlightRow: shouldHighlightRow, enableHighlighting: enableHighlighting, estimatedRowHeight: ROW_HEIGHT, columnVisibility: columnVisibility }) }));
5
+ return (_jsx("div", { style: { height: height !== undefined ? `${height}px` : '80vh' }, className: `font-robotoMono cursor-pointer ${selectedRow != null && sandwichFunctionName !== undefined ? 'w-[50%]' : 'w-full'}`, children: _jsx(TableComponent, { data: rows, columns: columns, initialSorting: initialSorting, usePointerCursor: true, onRowClick: onRowClick, shouldHighlightRow: shouldHighlightRow, enableHighlighting: enableHighlighting, estimatedRowHeight: ROW_HEIGHT, columnVisibility: columnVisibility }) }));
6
6
  }
@@ -8,7 +8,6 @@ interface Props {
8
8
  filtered: bigint;
9
9
  profileType?: ProfileType;
10
10
  loading: boolean;
11
- isHalfScreen: boolean;
12
11
  unit?: string;
13
12
  metadataMappingFiles?: string[];
14
13
  queryClient?: QueryServiceClient;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAM/E,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAM1C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAa/C,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,QAAA,MAAM,QAAQ,mCA6RZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAMlE,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAK1C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAU/C,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,QAAA,MAAM,QAAQ,mCA2MZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -11,34 +11,32 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
14
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
15
15
  import { tableFromIPC } from 'apache-arrow';
16
16
  import { AnimatePresence, motion } from 'framer-motion';
17
17
  import { QueryRequest_ReportType } from '@parca/client';
18
- import { TableSkeleton, useParcaContext, useURLState } from '@parca/components';
18
+ import { useParcaContext, useURLState } from '@parca/components';
19
19
  import { useCurrentColorProfile } from '@parca/hooks';
20
- import { isSearchMatch } from '@parca/utilities';
21
20
  import useMappingList, { useFilenamesList, } from '../ProfileIcicleGraph/IcicleGraphArrow/useMappingList';
22
- import { useProfileViewContext } from '../ProfileView/context/ProfileViewContext';
21
+ import { useDashboard } from '../ProfileView/context/DashboardContext';
23
22
  import { useVisualizationState } from '../ProfileView/hooks/useVisualizationState';
24
23
  import { FIELD_FUNCTION_NAME } from '../Table';
25
24
  import { useColorManagement } from '../Table/hooks/useColorManagement';
26
- import { useTableConfiguration } from '../Table/hooks/useTableConfiguration';
27
25
  import { useQuery } from '../useQuery';
28
26
  import { CalleesSection } from './components/CalleesSection';
29
27
  import { CallersSection } from './components/CallersSection';
30
- import { TableSection } from './components/TableSection';
31
28
  import { processRowData } from './utils/processRowData';
32
- const Sandwich = React.memo(function Sandwich({ data, total, filtered, profileType, loading, isHalfScreen, unit, metadataMappingFiles, queryClient, profileSource, }) {
29
+ const Sandwich = React.memo(function Sandwich({ data, filtered, profileType, loading, unit, metadataMappingFiles, queryClient, profileSource, }) {
33
30
  const currentColorProfile = useCurrentColorProfile();
34
- const [sandwichFunctionName, setSandwichFunctionName] = useURLState('sandwich_function_name');
31
+ const { dashboardItems } = useDashboard();
32
+ const [sandwichFunctionName] = useURLState('sandwich_function_name');
35
33
  const { isDarkMode } = useParcaContext();
36
34
  const [selectedRow, setSelectedRow] = useState(null);
37
35
  const callersRef = React.useRef(null);
38
36
  const calleesRef = React.useRef(null);
37
+ const [isExpanded, setIsExpanded] = useState(false);
38
+ const defaultMaxFrames = 10;
39
39
  const callersCalleesContainerRef = useRef(null);
40
- const [tableHeight, setTableHeight] = useState(undefined);
41
- const { compareMode } = useProfileViewContext();
42
40
  const { colorBy, setColorBy, curPathArrow, setCurPathArrow } = useVisualizationState();
43
41
  const nodeTrimThreshold = useMemo(() => {
44
42
  let width =
@@ -88,13 +86,6 @@ const Sandwich = React.memo(function Sandwich({ data, total, filtered, profileTy
88
86
  colorBy,
89
87
  });
90
88
  unit = useMemo(() => unit ?? profileType?.sampleUnit ?? '', [unit, profileType?.sampleUnit]);
91
- const tableConfig = useTableConfiguration({
92
- unit,
93
- total,
94
- filtered,
95
- compareMode,
96
- });
97
- const { columns, initialSorting, columnVisibility } = tableConfig;
98
89
  const rows = useMemo(() => {
99
90
  if (table == null || table.numRows === 0) {
100
91
  return [];
@@ -116,67 +107,24 @@ const Sandwich = React.memo(function Sandwich({ data, total, filtered, profileTy
116
107
  }
117
108
  }
118
109
  }, [sandwichFunctionName, rows, selectedRow]);
119
- // Update table height based on callers/callees container height
120
- useEffect(() => {
121
- const updateTableHeight = () => {
122
- if (callersCalleesContainerRef.current != null) {
123
- const containerHeight = callersCalleesContainerRef.current.getBoundingClientRect().height;
124
- setTableHeight(containerHeight);
125
- }
126
- };
127
- // Initial measurement
128
- updateTableHeight();
129
- // Update on window resize
130
- window.addEventListener('resize', updateTableHeight);
131
- // Use ResizeObserver if available for more accurate updates
132
- let resizeObserver = null;
133
- if (callersCalleesContainerRef.current != null && 'ResizeObserver' in window) {
134
- resizeObserver = new ResizeObserver(updateTableHeight);
135
- resizeObserver.observe(callersCalleesContainerRef.current);
136
- }
137
- return () => {
138
- window.removeEventListener('resize', updateTableHeight);
139
- if (resizeObserver != null) {
140
- resizeObserver.disconnect();
141
- }
142
- };
143
- }, [sandwichFunctionName, callersFlamegraphResponse, calleesFlamegraphResponse]);
144
- const onRowClick = useCallback((row) => {
145
- setSelectedRow(row);
146
- setSandwichFunctionName(row.name.trim());
147
- }, [setSandwichFunctionName]);
148
- const enableHighlighting = useMemo(() => {
149
- return sandwichFunctionName != null && sandwichFunctionName?.length > 0;
150
- }, [sandwichFunctionName]);
151
- const shouldHighlightRow = useCallback((row) => {
152
- if (!('name' in row)) {
153
- return false;
154
- }
155
- const name = row.name;
156
- return isSearchMatch(sandwichFunctionName, name);
157
- }, [sandwichFunctionName]);
158
- if (loading) {
159
- return (_jsx("div", { className: "overflow-clip h-[700px] min-h-[700px]", children: _jsx(TableSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode }) }));
160
- }
161
- if (rows.length === 0) {
162
- return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
163
- }
164
- return (_jsx("section", { className: "flex flex-row h-full w-full", children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsxs("div", { className: "relative flex flex-row", children: [_jsx(TableSection, { rows: rows, columns: columns, initialSorting: initialSorting, columnVisibility: columnVisibility, selectedRow: selectedRow, onRowClick: onRowClick, shouldHighlightRow: shouldHighlightRow, enableHighlighting: enableHighlighting, height: tableHeight, sandwichFunctionName: sandwichFunctionName }), sandwichFunctionName !== undefined && (_jsxs("div", { className: "w-[50%] flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, isHalfScreen: isHalfScreen, callersFlamegraphResponse: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
165
- ? {
166
- report: {
167
- oneofKind: 'flamegraphArrow',
168
- flamegraphArrow: callersFlamegraphResponse.report.flamegraphArrow,
169
- },
170
- total: callersFlamegraphResponse.total?.toString() ?? '0',
171
- }
172
- : undefined, callersFlamegraphLoading: callersFlamegraphLoading, callersFlamegraphError: callersFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, isHalfScreen: isHalfScreen, calleesFlamegraphResponse: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
173
- ? {
174
- report: {
175
- oneofKind: 'flamegraphArrow',
176
- flamegraphArrow: calleesFlamegraphResponse.report.flamegraphArrow,
177
- },
178
- total: calleesFlamegraphResponse.total?.toString() ?? '0',
179
- }
180
- : undefined, calleesFlamegraphLoading: calleesFlamegraphLoading, calleesFlamegraphError: calleesFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles })] }))] }) }, "sandwich-loaded") }) }));
110
+ return (_jsx("section", { className: "flex flex-row h-full w-full", children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsx("div", { className: "relative flex flex-row", children: sandwichFunctionName !== undefined ? (_jsxs("div", { className: "w-full flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, callersFlamegraphResponse: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
111
+ ? {
112
+ report: {
113
+ oneofKind: 'flamegraphArrow',
114
+ flamegraphArrow: callersFlamegraphResponse.report.flamegraphArrow,
115
+ },
116
+ total: callersFlamegraphResponse.total?.toString() ?? '0',
117
+ }
118
+ : undefined, callersFlamegraphLoading: callersFlamegraphLoading, callersFlamegraphError: callersFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphResponse: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
119
+ ? {
120
+ report: {
121
+ oneofKind: 'flamegraphArrow',
122
+ flamegraphArrow: calleesFlamegraphResponse.report.flamegraphArrow,
123
+ },
124
+ total: calleesFlamegraphResponse.total?.toString() ?? '0',
125
+ }
126
+ : undefined, calleesFlamegraphLoading: calleesFlamegraphLoading, calleesFlamegraphError: calleesFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table')
127
+ ? 'Please select a function to view its callers and callees.'
128
+ : 'Use the right-click menu on the flame graph to choose a function to view its callers and callees.' }) })) }) }, "sandwich-loaded") }) }));
181
129
  });
182
130
  export default Sandwich;
@@ -1 +1 @@
1
- {"version":3,"file":"MoreDropdown.d.ts","sourceRoot":"","sources":["../../src/Table/MoreDropdown.tsx"],"names":[],"mappings":"AAkBA,QAAA,MAAM,YAAY,qBAAoB;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,KAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IA6DlF,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"MoreDropdown.d.ts","sourceRoot":"","sources":["../../src/Table/MoreDropdown.tsx"],"names":[],"mappings":"AAkBA,QAAA,MAAM,YAAY,qBAAoB;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,KAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IA4DlF,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -16,14 +16,13 @@ import { Icon } from '@iconify/react';
16
16
  import { useParcaContext, useURLState } from '@parca/components';
17
17
  const MoreDropdown = ({ functionName }) => {
18
18
  const [_, setSandwichFunctionName] = useURLState('sandwich_function_name');
19
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
19
  const [dashboardItems, setDashboardItems] = useURLState('dashboard_items', {
21
20
  alwaysReturnArray: true,
22
21
  });
23
22
  const { enableSandwichView } = useParcaContext();
24
23
  const onSandwichViewSelect = () => {
25
24
  setSandwichFunctionName(functionName.trim());
26
- setDashboardItems(['sandwich']);
25
+ setDashboardItems([...dashboardItems, 'sandwich']);
27
26
  };
28
27
  const menuItems = [];
29
28
  if (enableSandwichView === true) {
@@ -0,0 +1,9 @@
1
+ import 'react-contexify/dist/ReactContexify.css';
2
+ import { type Row } from '.';
3
+ interface TableContextMenuProps {
4
+ menuId: string;
5
+ row: Row | null;
6
+ }
7
+ declare const TableContextMenu: ({ menuId, row }: TableContextMenuProps) => React.JSX.Element;
8
+ export default TableContextMenu;
9
+ //# sourceMappingURL=TableContextMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableContextMenu.d.ts","sourceRoot":"","sources":["../../src/Table/TableContextMenu.tsx"],"names":[],"mappings":"AAiBA,OAAO,yCAAyC,CAAC;AAIjD,OAAO,EAAC,KAAK,GAAG,EAAC,MAAM,GAAG,CAAC;AAE3B,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;CACjB;AAED,QAAA,MAAM,gBAAgB,oBAAmB,qBAAqB,KAAG,KAAK,CAAC,GAAG,CAAC,OAuC1E,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright 2022 The Parca Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { Icon } from '@iconify/react';
15
+ import cx from 'classnames';
16
+ import { Item, Menu } from 'react-contexify';
17
+ import 'react-contexify/dist/ReactContexify.css';
18
+ import { useParcaContext, useURLState } from '@parca/components';
19
+ const TableContextMenu = ({ menuId, row }) => {
20
+ const [_, setSandwichFunctionName] = useURLState('sandwich_function_name');
21
+ const [dashboardItems, setDashboardItems] = useURLState('dashboard_items', {
22
+ alwaysReturnArray: true,
23
+ });
24
+ const { enableSandwichView, isDarkMode } = useParcaContext();
25
+ const onSandwichViewSelect = () => {
26
+ if (row?.name != null && row.name.length > 0) {
27
+ setSandwichFunctionName(row.name.trim());
28
+ if (!dashboardItems.includes('sandwich')) {
29
+ setDashboardItems([...dashboardItems, 'sandwich']);
30
+ }
31
+ }
32
+ };
33
+ const isMenuDisabled = row === null || enableSandwichView !== true;
34
+ return (_jsx(Menu, { id: menuId, theme: isDarkMode ? 'dark' : '', className: cx(dashboardItems.includes('sandwich') ? 'min-w-[350px] w-[350px]' : 'min-w-[260px] w-[260px]'), children: _jsx(Item, { id: "sandwich-view", onClick: onSandwichViewSelect, disabled: isMenuDisabled, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "tdesign:sandwich-filled" }), _jsxs("div", { className: "relative", children: [dashboardItems.includes('sandwich')
35
+ ? 'Focus sandwich on this frame.'
36
+ : 'Show in sandwich', _jsx("span", { className: "absolute top-[-2px] text-xs lowercase text-red-500", children: "\u00A0alpha" })] })] }) }) }));
37
+ };
38
+ export default TableContextMenu;
@@ -0,0 +1,10 @@
1
+ import { type Row } from '.';
2
+ interface TableContextMenuWrapperProps {
3
+ menuId: string;
4
+ }
5
+ export interface TableContextMenuWrapperRef {
6
+ setRow: (row: Row | null, callback?: () => void) => void;
7
+ }
8
+ declare const TableContextMenuWrapper: import("react").ForwardRefExoticComponent<TableContextMenuWrapperProps & import("react").RefAttributes<TableContextMenuWrapperRef>>;
9
+ export default TableContextMenuWrapper;
10
+ //# sourceMappingURL=TableContextMenuWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableContextMenuWrapper.d.ts","sourceRoot":"","sources":["../../src/Table/TableContextMenuWrapper.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,KAAK,GAAG,EAAC,MAAM,GAAG,CAAC;AAG3B,UAAU,4BAA4B;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC1D;AAED,QAAA,MAAM,uBAAuB,qIAiB3B,CAAC;AAIH,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // Copyright 2022 The Parca Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { forwardRef, useImperativeHandle, useState } from 'react';
15
+ import TableContextMenu from './TableContextMenu';
16
+ const TableContextMenuWrapper = forwardRef(({ menuId }, ref) => {
17
+ const [row, setRow] = useState(null);
18
+ useImperativeHandle(ref, () => ({
19
+ setRow: (newRow, callback) => {
20
+ setRow(newRow);
21
+ // Execute callback after state update using requestAnimationFrame
22
+ if (callback != null) {
23
+ requestAnimationFrame(callback);
24
+ }
25
+ },
26
+ }));
27
+ return _jsx(TableContextMenu, { menuId: menuId, row: row });
28
+ });
29
+ TableContextMenuWrapper.displayName = 'TableContextMenuWrapper';
30
+ export default TableContextMenuWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"useTableConfiguration.d.ts","sourceRoot":"","sources":["../../../src/Table/hooks/useTableConfiguration.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,sBAAsB,CAAC;AAKxE,OAAO,EAAC,KAAK,GAAG,EAAC,MAAM,IAAI,CAAC;AAG5B,OAAO,EAA2B,KAAK,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAE7E,UAAU,0BAA0B;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,cAAc,EAAE,KAAK,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,CAAC,CAAC;IACnD,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;CAC/C;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAS,EACT,KAAK,EACL,QAAQ,EACR,WAAW,GACZ,EAAE,0BAA0B,GAAG,kBAAkB,CAqMjD"}
1
+ {"version":3,"file":"useTableConfiguration.d.ts","sourceRoot":"","sources":["../../../src/Table/hooks/useTableConfiguration.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,sBAAsB,CAAC;AAKxE,OAAO,EAAC,KAAK,GAAG,EAAC,MAAM,IAAI,CAAC;AAE5B,OAAO,EAA2B,KAAK,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAE7E,UAAU,0BAA0B;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,cAAc,EAAE,KAAK,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,CAAC,CAAC;IACnD,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;CAC/C;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAS,EACT,KAAK,EACL,QAAQ,EACR,WAAW,GACZ,EAAE,0BAA0B,GAAG,kBAAkB,CA+KjD"}
@@ -13,20 +13,15 @@ import { jsx as _jsx } from "react/jsx-runtime";
13
13
  // limitations under the License.
14
14
  import { useEffect, useMemo, useState } from 'react';
15
15
  import { createColumnHelper } from '@tanstack/table-core';
16
- import { useParcaContext, useURLState } from '@parca/components';
16
+ import { useURLState } from '@parca/components';
17
17
  import { valueFormatter } from '@parca/utilities';
18
18
  import { ColorCell } from '../ColorCell';
19
- import MoreDropdown from '../MoreDropdown';
20
19
  import { addPlusSign, ratioString } from '../utils/functions';
21
20
  export function useTableConfiguration({ unit = '', total, filtered, compareMode, }) {
22
21
  const columnHelper = createColumnHelper();
23
22
  const [tableColumns] = useURLState('table_columns', {
24
23
  alwaysReturnArray: true,
25
24
  });
26
- const [dashboardItems] = useURLState('dashboard_items', {
27
- alwaysReturnArray: true,
28
- });
29
- const { enableSandwichView } = useParcaContext();
30
25
  const [columnVisibility, setColumnVisibility] = useState(() => {
31
26
  return {
32
27
  color: true,
@@ -176,21 +171,8 @@ export function useTableConfiguration({ unit = '', total, filtered, compareMode,
176
171
  cell: info => info.getValue(),
177
172
  }),
178
173
  ];
179
- if (dashboardItems.length === 1 &&
180
- dashboardItems[0] === 'table' &&
181
- enableSandwichView === true) {
182
- baseColumns.unshift(columnHelper.accessor('moreActions', {
183
- id: 'moreActions',
184
- header: '',
185
- cell: info => {
186
- return _jsx(MoreDropdown, { functionName: info.row.original.name });
187
- },
188
- size: 10,
189
- enableSorting: false,
190
- }));
191
- }
192
174
  return baseColumns;
193
- }, [unit, total, filtered, columnHelper, dashboardItems, enableSandwichView]);
175
+ }, [unit, total, filtered, columnHelper]);
194
176
  const initialSorting = useMemo(() => {
195
177
  return [
196
178
  {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAYvE,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAS1C,OAAO,EAAC,OAAO,EAAmC,MAAM,mBAAmB,CAAC;AAE5E,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AACvD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,MAAM,MAAM,GAAG,GAAG,OAAO,CAAC;AAE1B,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,eAAO,MAAM,KAAK,wCA6MhB,CAAC;AAEH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAa/E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAU1C,OAAO,EAAC,OAAO,EAAmC,MAAM,mBAAmB,CAAC;AAE5E,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AACvD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,MAAM,MAAM,GAAG,GAAG,OAAO,CAAC;AAE1B,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,eAAO,MAAM,KAAK,wCA0RhB,CAAC;AAEH,eAAe,KAAK,CAAC"}