@parca/profile 0.19.106 → 0.19.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +2 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.js +1 -1
- package/dist/ProfileFlameGraph/index.js +1 -1
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/DashboardItems/index.js +1 -1
- package/dist/ProfileView/types/visualization.d.ts +4 -3
- package/dist/ProfileView/types/visualization.d.ts.map +1 -1
- package/dist/Sandwich/components/CalleesSection.d.ts.map +1 -1
- package/dist/Sandwich/components/CalleesSection.js +2 -1
- package/dist/Sandwich/components/CallersSection.d.ts.map +1 -1
- package/dist/Sandwich/components/CallersSection.js +2 -1
- package/dist/Sandwich/index.d.ts.map +1 -1
- package/dist/Sandwich/index.js +2 -1
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +4 -1
- package/dist/useSumBy.js +1 -1
- package/package.json +4 -4
- package/src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx +2 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.ts +1 -1
- package/src/ProfileFlameGraph/index.tsx +1 -1
- package/src/ProfileView/components/DashboardItems/index.tsx +1 -0
- package/src/ProfileView/types/visualization.ts +5 -3
- package/src/Sandwich/components/CalleesSection.tsx +7 -1
- package/src/Sandwich/components/CallersSection.tsx +6 -1
- package/src/Sandwich/index.tsx +6 -2
- package/src/Table/index.tsx +6 -0
- package/src/useSumBy.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.19.108](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.107...@parca/profile@0.19.108) (2026-01-05)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.19.107](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.106...@parca/profile@0.19.107) (2025-12-22)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.19.106](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.105...@parca/profile@0.19.106) (2025-12-18)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAOnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAOnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,kIAalB,gBAAgB,KAAG,GAAG,CAAC,OAyOzB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -17,6 +17,7 @@ import { Item, Menu, Separator, Submenu } from 'react-contexify';
|
|
|
17
17
|
import { Tooltip } from 'react-tooltip';
|
|
18
18
|
import { useParcaContext, useURLState } from '@parca/components';
|
|
19
19
|
import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
|
|
20
|
+
import { TEST_IDS } from '@parca/test-utils';
|
|
20
21
|
import { getLastItem } from '@parca/utilities';
|
|
21
22
|
import { useGraphTooltip } from '../../GraphTooltipArrow/useGraphTooltip';
|
|
22
23
|
import { useGraphTooltipMetaInfo } from '../../GraphTooltipArrow/useGraphTooltipMetaInfo';
|
|
@@ -92,7 +93,7 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, compareAbsolu
|
|
|
92
93
|
else {
|
|
93
94
|
setDashboardItems([...dashboardItems, 'table']);
|
|
94
95
|
}
|
|
95
|
-
}, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), enableSandwichView === true && (_jsx(Item, { id: "show-in-sandwich", onClick: () => {
|
|
96
|
+
}, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), enableSandwichView === true && (_jsx(Item, { id: "show-in-sandwich", "data-testid": TEST_IDS.CONTEXT_MENU_SHOW_IN_SANDWICH, onClick: () => {
|
|
96
97
|
if (functionName === '' || functionName == null) {
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
@@ -87,7 +87,7 @@ export const useVisibleNodes = ({ table, viewport, total, width, selectedRow, ef
|
|
|
87
87
|
renderedRangeRef.current = {
|
|
88
88
|
minDepth: Infinity,
|
|
89
89
|
maxDepth: -Infinity,
|
|
90
|
-
table
|
|
90
|
+
table,
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
// Expand the rendered range (never shrink when scrolling up/down)
|
|
@@ -106,7 +106,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
|
|
|
106
106
|
: { isValid: true, isNonDelta: false, isDurationTooLong: false };
|
|
107
107
|
const isInvalidFlameChartQuery = isFlameChart && !isFlameChartValid;
|
|
108
108
|
if (isLoading && !isInvalidFlameChartQuery) {
|
|
109
|
-
return (_jsx("div", { className: "h-auto overflow-clip", children: isRenderedAsFlamegraph ? (_jsx(SandwichFlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(FlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
|
|
109
|
+
return (_jsx("div", { className: "h-auto overflow-clip", "data-testid": TEST_IDS.FLAMEGRAPH_SKELETON, children: isRenderedAsFlamegraph ? (_jsx(SandwichFlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(FlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
|
|
110
110
|
}
|
|
111
111
|
// Do necessary checks to ensure that flame chart can be rendered for this query.
|
|
112
112
|
if (isInvalidFlameChartQuery) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GAAI,qLAe9B,qBAAqB,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GAAI,qLAe9B,qBAAqB,KAAG,GAAG,CAAC,OAgG9B,CAAC"}
|
|
@@ -35,7 +35,7 @@ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphDat
|
|
|
35
35
|
: dimensions.width - 16
|
|
36
36
|
: 0, metadataMappingFiles: flamechartData.metadataMappingFiles, metadataLoading: flamechartData.metadataLoading, profileSource: profileSource, isFlameChart: true }));
|
|
37
37
|
case 'table':
|
|
38
|
-
return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles })) : (_jsx(_Fragment, {}));
|
|
38
|
+
return topTableData != null ? (_jsx(Table, { error: topTableData.error, total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles })) : (_jsx(_Fragment, {}));
|
|
39
39
|
case 'sandwich':
|
|
40
40
|
return topTableData != null ? (_jsx(Sandwich, { profileSource: profileSource, sandwichData: sandwichData })) : (_jsx(_Fragment, {}));
|
|
41
41
|
case 'source':
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RpcError } from '@protobuf-ts/runtime-rpc';
|
|
1
2
|
import { FlamegraphArrow, QueryServiceClient, Source, TableArrow } from '@parca/client';
|
|
2
3
|
import { ProfileSource } from '../../ProfileSource';
|
|
3
4
|
export interface FlamegraphData {
|
|
@@ -5,7 +6,7 @@ export interface FlamegraphData {
|
|
|
5
6
|
arrow?: FlamegraphArrow;
|
|
6
7
|
total?: bigint;
|
|
7
8
|
filtered?: bigint;
|
|
8
|
-
error
|
|
9
|
+
error: RpcError | null;
|
|
9
10
|
metadataMappingFiles?: string[];
|
|
10
11
|
metadataLoading: boolean;
|
|
11
12
|
metadataLabels?: string[];
|
|
@@ -16,13 +17,13 @@ export interface TopTableData {
|
|
|
16
17
|
arrow?: TableArrow;
|
|
17
18
|
total?: bigint;
|
|
18
19
|
filtered?: bigint;
|
|
19
|
-
error
|
|
20
|
+
error: RpcError | null;
|
|
20
21
|
unit?: string;
|
|
21
22
|
}
|
|
22
23
|
export interface SourceData {
|
|
23
24
|
loading: boolean;
|
|
24
25
|
data?: Source;
|
|
25
|
-
error
|
|
26
|
+
error: RpcError | null;
|
|
26
27
|
}
|
|
27
28
|
export interface SandwichData {
|
|
28
29
|
callees: FlamegraphData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAEtF,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,
|
|
1
|
+
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAEtF,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,WAAW,GACX,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAErE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,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,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA+BnC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
2
3
|
import ProfileFlameGraph from '../../ProfileFlameGraph';
|
|
3
4
|
export function CalleesSection({ calleesRef, calleesFlamegraphData, profileSource, curPathArrow, setCurPathArrow, }) {
|
|
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(ProfileFlameGraph, { arrow: calleesFlamegraphData?.arrow, total: calleesFlamegraphData.total ?? BigInt(0), filtered: calleesFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: calleesFlamegraphData.loading, error: calleesFlamegraphData.error, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: calleesFlamegraphData.metadataMappingFiles, metadataLoading: calleesFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
|
|
5
|
+
return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, ...testId(TEST_IDS.SANDWICH_CALLEES_SECTION), children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileFlameGraph, { arrow: calleesFlamegraphData?.arrow, total: calleesFlamegraphData.total ?? BigInt(0), filtered: calleesFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: calleesFlamegraphData.loading, error: calleesFlamegraphData.error, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: calleesFlamegraphData.metadataMappingFiles, metadataLoading: calleesFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
|
|
5
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AASrC,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAerE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,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,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAqEnC"}
|
|
@@ -15,6 +15,7 @@ import { useMemo } from 'react';
|
|
|
15
15
|
import { tableFromIPC } from 'apache-arrow';
|
|
16
16
|
import { Tooltip } from 'react-tooltip';
|
|
17
17
|
import { Button } from '@parca/components';
|
|
18
|
+
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
18
19
|
import ProfileFlameGraph from '../../ProfileFlameGraph';
|
|
19
20
|
const FIELD_DEPTH = 'depth';
|
|
20
21
|
function getMaxDepth(depthColumn) {
|
|
@@ -40,5 +41,5 @@ export function CallersSection({ callersRef, callersFlamegraphData, profileSourc
|
|
|
40
41
|
const shouldShowButton = maxDepth > defaultMaxFrames;
|
|
41
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
|
|
42
43
|
? `This profile has ${maxDepth} frames, showing only the top ${defaultMaxFrames} frames. Click to show more frames.`
|
|
43
|
-
: `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(ProfileFlameGraph, { arrow: callersFlamegraphData?.arrow, total: callersFlamegraphData.total ?? BigInt(0), filtered: callersFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: callersFlamegraphData.loading, error: callersFlamegraphData.error, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: callersFlamegraphData.metadataMappingFiles, metadataLoading: callersFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
|
|
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, ...testId(TEST_IDS.SANDWICH_CALLERS_SECTION), 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(ProfileFlameGraph, { arrow: callersFlamegraphData?.arrow, total: callersFlamegraphData.total ?? BigInt(0), filtered: callersFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: callersFlamegraphData.loading, error: callersFlamegraphData.error, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: callersFlamegraphData.metadataMappingFiles, metadataLoading: callersFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
|
|
44
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAO9C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAIhE,UAAU,KAAK;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,mCAuEZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
|
package/dist/Sandwich/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
14
14
|
import React, { useRef, useState } from 'react';
|
|
15
15
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
16
16
|
import { useURLState } from '@parca/components';
|
|
17
|
+
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
17
18
|
import { useDashboard } from '../ProfileView/context/DashboardContext';
|
|
18
19
|
import { useVisualizationState } from '../ProfileView/hooks/useVisualizationState';
|
|
19
20
|
import { CalleesSection } from './components/CalleesSection';
|
|
@@ -27,6 +28,6 @@ const Sandwich = React.memo(function Sandwich({ sandwichData, profileSource, })
|
|
|
27
28
|
const defaultMaxFrames = 10;
|
|
28
29
|
const callersCalleesContainerRef = useRef(null);
|
|
29
30
|
const { curPathArrow, setCurPathArrow } = useVisualizationState();
|
|
30
|
-
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, callersFlamegraphData: sandwichData.callers, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphData: sandwichData.callees, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
|
|
31
|
+
return (_jsx("section", { className: "flex flex-row h-full w-full", ...testId(TEST_IDS.SANDWICH_CONTAINER), 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, callersFlamegraphData: sandwichData.callers, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphData: sandwichData.callees, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", ...testId(TEST_IDS.SANDWICH_NO_FUNCTION_SELECTED), children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
|
|
31
32
|
});
|
|
32
33
|
export default Sandwich;
|
package/dist/Table/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { RpcError } from '@protobuf-ts/runtime-rpc';
|
|
2
3
|
import { ProfileType } from '@parca/parser';
|
|
3
4
|
import { DataRow } from './utils/functions';
|
|
4
5
|
export declare const FIELD_MAPPING_FILE = "mapping_file";
|
|
@@ -23,6 +24,7 @@ export interface TableProps {
|
|
|
23
24
|
isHalfScreen: boolean;
|
|
24
25
|
unit?: string;
|
|
25
26
|
metadataMappingFiles?: string[];
|
|
27
|
+
error: RpcError | null;
|
|
26
28
|
}
|
|
27
29
|
export declare const Table: React.NamedExoticComponent<TableProps>;
|
|
28
30
|
export default Table;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAYlD,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,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;IAChC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,KAAK,wCA0MhB,CAAC;AAEH,eAAe,KAAK,CAAC"}
|
package/dist/Table/index.js
CHANGED
|
@@ -34,7 +34,7 @@ export const FIELD_CUMULATIVE = 'cumulative';
|
|
|
34
34
|
export const FIELD_CUMULATIVE_DIFF = 'cumulative_diff';
|
|
35
35
|
export const FIELD_CALLERS = 'callers';
|
|
36
36
|
export const FIELD_CALLEES = 'callees';
|
|
37
|
-
export const Table = React.memo(function Table({ data, total, filtered, profileType, loading, isHalfScreen, unit, metadataMappingFiles, }) {
|
|
37
|
+
export const Table = React.memo(function Table({ data, total, filtered, profileType, loading, isHalfScreen, unit, metadataMappingFiles, error, }) {
|
|
38
38
|
const currentColorProfile = useCurrentColorProfile();
|
|
39
39
|
const [dashboardItems] = useURLState('dashboard_items', {
|
|
40
40
|
alwaysReturnArray: true,
|
|
@@ -142,6 +142,9 @@ export const Table = React.memo(function Table({ data, total, filtered, profileT
|
|
|
142
142
|
if (loading) {
|
|
143
143
|
return (_jsx("div", { className: "overflow-clip h-[700px] min-h-[700px]", children: _jsx(TableSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode }) }));
|
|
144
144
|
}
|
|
145
|
+
if (error != null) {
|
|
146
|
+
return _jsxs("div", { className: "mx-auto text-center", children: ["Error: ", error.message] });
|
|
147
|
+
}
|
|
145
148
|
if (rows.length === 0) {
|
|
146
149
|
return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
|
|
147
150
|
}
|
package/dist/useSumBy.js
CHANGED
|
@@ -149,7 +149,7 @@ export const useDraftSumBy = (queryClient, profileType, timeRange, defaultValue)
|
|
|
149
149
|
const { defaultSumBy, isLoading } = useDefaultSumBy(profileType, labelNamesLoading, labels);
|
|
150
150
|
return {
|
|
151
151
|
draftSumBy: draftSumBy ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY,
|
|
152
|
-
setDraftSumBy
|
|
152
|
+
setDraftSumBy,
|
|
153
153
|
isDraftSumByLoading: isLoading,
|
|
154
154
|
};
|
|
155
155
|
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.108",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@floating-ui/react": "^0.27.12",
|
|
7
7
|
"@headlessui/react": "^1.7.19",
|
|
8
8
|
"@iconify/react": "^4.0.0",
|
|
9
9
|
"@parca/client": "0.17.16",
|
|
10
|
-
"@parca/components": "0.16.
|
|
10
|
+
"@parca/components": "0.16.395",
|
|
11
11
|
"@parca/dynamicsize": "0.16.72",
|
|
12
12
|
"@parca/hooks": "0.0.116",
|
|
13
13
|
"@parca/icons": "0.16.79",
|
|
14
14
|
"@parca/parser": "0.16.86",
|
|
15
15
|
"@parca/store": "0.16.199",
|
|
16
|
-
"@parca/test-utils": "0.0.
|
|
16
|
+
"@parca/test-utils": "0.0.20",
|
|
17
17
|
"@parca/utilities": "0.0.122",
|
|
18
18
|
"@popperjs/core": "^2.11.8",
|
|
19
19
|
"@protobuf-ts/runtime-rpc": "^2.5.0",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"access": "public",
|
|
85
85
|
"registry": "https://registry.npmjs.org/"
|
|
86
86
|
},
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "062ac8ece420950b51220c40eaa2056e7e6e6493"
|
|
88
88
|
}
|
|
@@ -20,6 +20,7 @@ import {Tooltip} from 'react-tooltip';
|
|
|
20
20
|
import {useParcaContext, useURLState} from '@parca/components';
|
|
21
21
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
22
22
|
import {ProfileType} from '@parca/parser';
|
|
23
|
+
import {TEST_IDS} from '@parca/test-utils';
|
|
23
24
|
import {getLastItem} from '@parca/utilities';
|
|
24
25
|
|
|
25
26
|
import {useGraphTooltip} from '../../GraphTooltipArrow/useGraphTooltip';
|
|
@@ -187,6 +188,7 @@ const ContextMenu = ({
|
|
|
187
188
|
{enableSandwichView === true && (
|
|
188
189
|
<Item
|
|
189
190
|
id="show-in-sandwich"
|
|
191
|
+
data-testid={TEST_IDS.CONTEXT_MENU_SHOW_IN_SANDWICH}
|
|
190
192
|
onClick={() => {
|
|
191
193
|
if (functionName === '' || functionName == null) {
|
|
192
194
|
return;
|
|
@@ -205,7 +205,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
205
205
|
|
|
206
206
|
if (isLoading && !isInvalidFlameChartQuery) {
|
|
207
207
|
return (
|
|
208
|
-
<div className="h-auto overflow-clip">
|
|
208
|
+
<div className="h-auto overflow-clip" data-testid={TEST_IDS.FLAMEGRAPH_SKELETON}>
|
|
209
209
|
{isRenderedAsFlamegraph ? (
|
|
210
210
|
<SandwichFlameGraphSkeleton isHalfScreen={isHalfScreen} isDarkMode={isDarkMode} />
|
|
211
211
|
) : (
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
+
import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
15
|
+
|
|
14
16
|
import {FlamegraphArrow, QueryServiceClient, Source, TableArrow} from '@parca/client';
|
|
15
17
|
|
|
16
18
|
import {ProfileSource} from '../../ProfileSource';
|
|
@@ -20,7 +22,7 @@ export interface FlamegraphData {
|
|
|
20
22
|
arrow?: FlamegraphArrow;
|
|
21
23
|
total?: bigint;
|
|
22
24
|
filtered?: bigint;
|
|
23
|
-
error
|
|
25
|
+
error: RpcError | null;
|
|
24
26
|
metadataMappingFiles?: string[];
|
|
25
27
|
metadataLoading: boolean;
|
|
26
28
|
metadataLabels?: string[];
|
|
@@ -32,14 +34,14 @@ export interface TopTableData {
|
|
|
32
34
|
arrow?: TableArrow;
|
|
33
35
|
total?: bigint;
|
|
34
36
|
filtered?: bigint;
|
|
35
|
-
error
|
|
37
|
+
error: RpcError | null;
|
|
36
38
|
unit?: string;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export interface SourceData {
|
|
40
42
|
loading: boolean;
|
|
41
43
|
data?: Source;
|
|
42
|
-
error
|
|
44
|
+
error: RpcError | null;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
export interface SandwichData {
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
import React from 'react';
|
|
15
15
|
|
|
16
|
+
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
17
|
+
|
|
16
18
|
import ProfileFlameGraph from '../../ProfileFlameGraph';
|
|
17
19
|
import {type CurrentPathFrame} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
|
|
18
20
|
import {type ProfileSource} from '../../ProfileSource';
|
|
@@ -35,7 +37,11 @@ export function CalleesSection({
|
|
|
35
37
|
setCurPathArrow,
|
|
36
38
|
}: CalleesSectionProps): JSX.Element {
|
|
37
39
|
return (
|
|
38
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
className="flex relative items-start flex-row"
|
|
42
|
+
ref={calleesRef}
|
|
43
|
+
{...testId(TEST_IDS.SANDWICH_CALLEES_SECTION)}
|
|
44
|
+
>
|
|
39
45
|
<div className="[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left">
|
|
40
46
|
{'<-'} Callees
|
|
41
47
|
</div>
|
|
@@ -17,6 +17,7 @@ import {Vector, tableFromIPC} from 'apache-arrow';
|
|
|
17
17
|
import {Tooltip} from 'react-tooltip';
|
|
18
18
|
|
|
19
19
|
import {Button} from '@parca/components';
|
|
20
|
+
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
20
21
|
|
|
21
22
|
import ProfileFlameGraph from '../../ProfileFlameGraph';
|
|
22
23
|
import {type CurrentPathFrame} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
|
|
@@ -90,7 +91,11 @@ export function CallersSection({
|
|
|
90
91
|
<Tooltip id="show-more-frames" />
|
|
91
92
|
</Button>
|
|
92
93
|
)}
|
|
93
|
-
<div
|
|
94
|
+
<div
|
|
95
|
+
className="flex relative flex-row overflow-hidden"
|
|
96
|
+
ref={callersRef}
|
|
97
|
+
{...testId(TEST_IDS.SANDWICH_CALLERS_SECTION)}
|
|
98
|
+
>
|
|
94
99
|
<div className="[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0">
|
|
95
100
|
Callers {'->'}
|
|
96
101
|
</div>
|
package/src/Sandwich/index.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import React, {useRef, useState} from 'react';
|
|
|
16
16
|
import {AnimatePresence, motion} from 'framer-motion';
|
|
17
17
|
|
|
18
18
|
import {useURLState} from '@parca/components';
|
|
19
|
+
import {TEST_IDS, testId} from '@parca/test-utils';
|
|
19
20
|
|
|
20
21
|
import {ProfileSource} from '../ProfileSource';
|
|
21
22
|
import {useDashboard} from '../ProfileView/context/DashboardContext';
|
|
@@ -46,7 +47,7 @@ const Sandwich = React.memo(function Sandwich({
|
|
|
46
47
|
const {curPathArrow, setCurPathArrow} = useVisualizationState();
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
|
-
<section className="flex flex-row h-full w-full">
|
|
50
|
+
<section className="flex flex-row h-full w-full" {...testId(TEST_IDS.SANDWICH_CONTAINER)}>
|
|
50
51
|
<AnimatePresence>
|
|
51
52
|
<motion.div
|
|
52
53
|
className="h-full w-full"
|
|
@@ -78,7 +79,10 @@ const Sandwich = React.memo(function Sandwich({
|
|
|
78
79
|
/>
|
|
79
80
|
</div>
|
|
80
81
|
) : (
|
|
81
|
-
<div
|
|
82
|
+
<div
|
|
83
|
+
className="items-center justify-center flex h-full w-full"
|
|
84
|
+
{...testId(TEST_IDS.SANDWICH_NO_FUNCTION_SELECTED)}
|
|
85
|
+
>
|
|
82
86
|
<p className="text-sm">
|
|
83
87
|
{dashboardItems.includes('table') ? (
|
|
84
88
|
'Please select a function to view its callers and callees.'
|
package/src/Table/index.tsx
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import React, {useCallback, useEffect, useMemo, useRef} from 'react';
|
|
15
15
|
|
|
16
|
+
import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
16
17
|
import {tableFromIPC} from 'apache-arrow';
|
|
17
18
|
import {AnimatePresence, motion} from 'framer-motion';
|
|
18
19
|
import {useContextMenu} from 'react-contexify';
|
|
@@ -59,6 +60,7 @@ export interface TableProps {
|
|
|
59
60
|
isHalfScreen: boolean;
|
|
60
61
|
unit?: string;
|
|
61
62
|
metadataMappingFiles?: string[];
|
|
63
|
+
error: RpcError | null;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
export const Table = React.memo(function Table({
|
|
@@ -70,6 +72,7 @@ export const Table = React.memo(function Table({
|
|
|
70
72
|
isHalfScreen,
|
|
71
73
|
unit,
|
|
72
74
|
metadataMappingFiles,
|
|
75
|
+
error,
|
|
73
76
|
}: TableProps): React.JSX.Element {
|
|
74
77
|
const currentColorProfile = useCurrentColorProfile();
|
|
75
78
|
const [dashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
@@ -220,6 +223,9 @@ export const Table = React.memo(function Table({
|
|
|
220
223
|
</div>
|
|
221
224
|
);
|
|
222
225
|
}
|
|
226
|
+
if (error != null) {
|
|
227
|
+
return <div className="mx-auto text-center">Error: {error.message}</div>;
|
|
228
|
+
}
|
|
223
229
|
|
|
224
230
|
if (rows.length === 0) {
|
|
225
231
|
return <div className="mx-auto text-center">Profile has no samples</div>;
|