@parca/profile 0.19.10 → 0.19.12
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/ProfileSelector/QueryControls.d.ts.map +1 -1
- package/dist/ProfileSelector/QueryControls.js +1 -1
- package/dist/ProfileView/components/ActionButtons/GroupByDropdown.d.ts +0 -1
- package/dist/ProfileView/components/ActionButtons/GroupByDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/ActionButtons/GroupByDropdown.js +4 -141
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts +8 -0
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.d.ts.map +1 -0
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +57 -0
- package/dist/ProfileView/components/InvertCallStack/index.d.ts +3 -0
- package/dist/ProfileView/components/InvertCallStack/index.d.ts.map +1 -0
- package/dist/ProfileView/components/InvertCallStack/index.js +21 -0
- package/dist/ProfileView/components/ShareButton/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ShareButton/index.js +1 -1
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts +3 -0
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +78 -20
- package/dist/ProfileView/components/Toolbars/SwitchMenuItem.d.ts +9 -0
- package/dist/ProfileView/components/Toolbars/SwitchMenuItem.d.ts.map +1 -0
- package/dist/ProfileView/components/Toolbars/SwitchMenuItem.js +22 -0
- package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/index.js +4 -1
- package/dist/ProfileView/components/ViewSelector/Dropdown.js +1 -1
- package/dist/ProfileView/components/ViewSelector/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ViewSelector/index.js +9 -12
- package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useVisualizationState.js +16 -6
- package/dist/styles.css +1 -1
- package/package.json +2 -2
- package/src/ProfileSelector/QueryControls.tsx +1 -0
- package/src/ProfileView/components/ActionButtons/GroupByDropdown.tsx +7 -323
- package/src/ProfileView/components/GroupByLabelsDropdown/index.tsx +92 -0
- package/src/ProfileView/components/InvertCallStack/index.tsx +34 -0
- package/src/ProfileView/components/ShareButton/index.tsx +8 -4
- package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +134 -22
- package/src/ProfileView/components/Toolbars/SwitchMenuItem.tsx +50 -0
- package/src/ProfileView/components/Toolbars/index.tsx +25 -9
- package/src/ProfileView/components/ViewSelector/Dropdown.tsx +1 -1
- package/src/ProfileView/components/ViewSelector/index.tsx +15 -19
- package/src/ProfileView/hooks/useVisualizationState.ts +25 -6
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.12 (2025-07-02)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.19.11](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.10...@parca/profile@0.19.11) (2025-06-26)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.19.10](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.9...@parca/profile@0.19.10) (2025-06-25)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/QueryControls.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAClD,OAAe,EAAC,KAAK,cAAc,EAAC,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAC,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACvE,OAAO,EAAS,aAAa,EAAsB,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAC,WAAW,EAAE,KAAK,EAAC,MAAM,eAAe,CAAC;AAYjD,UAAU,kBAAkB;IAC1B,uBAAuB,EAAE,OAAO,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACnD,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,aAAa,CAAC,EAAE;QACd,2BAA2B,CAAC,EAAE,OAAO,CAAC;QACtC,0BAA0B,CAAC,EAAE,OAAO,CAAC;QACrC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;KACvC,CAAC;IACF,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,2BAA2B,EAAE,OAAO,CAAC;IACrC,8BAA8B,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,KAAK,EAAE,KAAK,CAAC;IACb,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACjD,kBAAkB,EAAE,aAAa,CAAC;IAClC,qBAAqB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC1C,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,2BAA2B,EAC3B,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,MAAM,EACN,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,iBAAiB,GAClB,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/QueryControls.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAClD,OAAe,EAAC,KAAK,cAAc,EAAC,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAC,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACvE,OAAO,EAAS,aAAa,EAAsB,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAC,WAAW,EAAE,KAAK,EAAC,MAAM,eAAe,CAAC;AAYjD,UAAU,kBAAkB;IAC1B,uBAAuB,EAAE,OAAO,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACnD,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,aAAa,CAAC,EAAE;QACd,2BAA2B,CAAC,EAAE,OAAO,CAAC;QACtC,0BAA0B,CAAC,EAAE,OAAO,CAAC;QACrC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;KACvC,CAAC;IACF,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,2BAA2B,EAAE,OAAO,CAAC;IACrC,8BAA8B,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,KAAK,EAAE,KAAK,CAAC;IACb,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACjD,kBAAkB,EAAE,aAAa,CAAC;IAClC,qBAAqB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC1C,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,2BAA2B,EAC3B,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,MAAM,EACN,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,iBAAiB,GAClB,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,CAmJlC"}
|
|
@@ -24,7 +24,7 @@ export function QueryControls({ showProfileTypeSelector, profileTypesData, profi
|
|
|
24
24
|
setQueryBrowserMode(advancedModeForQueryBrowser ? 'simple' : 'advanced');
|
|
25
25
|
}, className: `${advancedModeForQueryBrowser ? 'bg-indigo-600' : 'bg-gray-400 dark:bg-gray-800'} relative inline-flex h-[20px] w-[44px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75`, children: [_jsx("span", { className: "sr-only", children: "Use setting" }), _jsx("span", { "aria-hidden": "true", className: `${advancedModeForQueryBrowser ? 'translate-x-6' : 'translate-x-0'} pointer-events-none inline-block h-[16px] w-[16px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out` })] }), _jsx("label", { className: "text-xs", children: "Advanced Mode" })] }))] }), viewComponent?.createViewComponent] }), viewComponent?.disableExplorativeQuerying === true &&
|
|
26
26
|
viewComponent?.labelnames !== undefined &&
|
|
27
|
-
viewComponent?.labelnames.length >= 1 ? (_jsx(ViewMatchers, { labelNames: viewComponent.labelnames, setMatchersString: setMatchersString, profileType: selectedProfileName, runQuery: setQueryExpression, currentQuery: query, queryClient: queryClient })) : advancedModeForQueryBrowser ? (_jsx(MatchersInput, { setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName, queryClient: queryClient })) : (_jsx(SimpleMatchers, { setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName, queryBrowserRef: queryBrowserRef, queryClient: queryClient }, query.toString()))] }), showSumBySelector && (_jsxs("div", { children: [_jsx("div", { className: "mb-0.5 mt-1.5 flex items-center justify-between", children: _jsx("label", { className: "text-xs", children: "Sum by" }) }), _jsx(Select, { id: "h-sum-by-selector", defaultValue: [], isMulti: true, name: "colors", options: labels.map(label => ({ label, value: label })), className: "parca-select-container text-sm w-full max-w-80", classNamePrefix: "parca-select", value: (sumBySelection ?? []).map(sumBy => ({ label: sumBy, value: sumBy })), onChange: newValue => {
|
|
27
|
+
viewComponent?.labelnames.length >= 1 ? (_jsx(ViewMatchers, { labelNames: viewComponent.labelnames, setMatchersString: setMatchersString, profileType: selectedProfileName, runQuery: setQueryExpression, currentQuery: query, queryClient: queryClient })) : advancedModeForQueryBrowser ? (_jsx(MatchersInput, { setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName, queryClient: queryClient })) : (_jsx(SimpleMatchers, { setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query, profileType: selectedProfileName, queryBrowserRef: queryBrowserRef, queryClient: queryClient }, query.toString()))] }), showSumBySelector && (_jsxs("div", { children: [_jsx("div", { className: "mb-0.5 mt-1.5 flex items-center justify-between", children: _jsx("label", { className: "text-xs", children: "Sum by" }) }), _jsx(Select, { id: "h-sum-by-selector", defaultValue: [], isMulti: true, isClearable: false, name: "colors", options: labels.map(label => ({ label, value: label })), className: "parca-select-container text-sm w-full max-w-80", classNamePrefix: "parca-select", value: (sumBySelection ?? []).map(sumBy => ({ label: sumBy, value: sumBy })), onChange: newValue => {
|
|
28
28
|
setUserSumBySelection(newValue.map(option => option.value));
|
|
29
29
|
}, placeholder: "Labels...", styles: {
|
|
30
30
|
indicatorSeparator: () => ({ display: 'none' }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupByDropdown.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ActionButtons/GroupByDropdown.tsx"],"names":[],"mappings":"AAaA,OAAO,
|
|
1
|
+
{"version":3,"file":"GroupByDropdown.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ActionButtons/GroupByDropdown.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC9C;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAYnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,143 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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 { useEffect, useRef, useState } from 'react';
|
|
15
|
-
import { Transition } from '@headlessui/react';
|
|
16
|
-
import { Icon } from '@iconify/react';
|
|
17
|
-
import Select from 'react-select';
|
|
18
|
-
import { Button } from '@parca/components';
|
|
19
|
-
import { FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_LABELS, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from '../../../ProfileIcicleGraph/IcicleGraphArrow';
|
|
20
|
-
const groupByOptions = [
|
|
21
|
-
{
|
|
22
|
-
value: FIELD_FUNCTION_NAME,
|
|
23
|
-
label: 'Function Name',
|
|
24
|
-
description: 'Stacktraces are grouped by function names.',
|
|
25
|
-
disabled: true,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
value: FIELD_FUNCTION_FILE_NAME,
|
|
29
|
-
label: 'Filename',
|
|
30
|
-
description: 'Stacktraces are grouped by filenames.',
|
|
31
|
-
disabled: false,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: FIELD_LOCATION_ADDRESS,
|
|
35
|
-
label: 'Address',
|
|
36
|
-
description: 'Stacktraces are grouped by addresses.',
|
|
37
|
-
disabled: false,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
value: FIELD_MAPPING_FILE,
|
|
41
|
-
label: 'Binary',
|
|
42
|
-
description: 'Stacktraces are grouped by binaries.',
|
|
43
|
-
disabled: false,
|
|
44
|
-
},
|
|
45
|
-
];
|
|
46
|
-
const LabelSelector = ({ labels, groupBy, setGroupByLabels, isOpen, labelsButtonRef, setIsLabelSelectorOpen, }) => {
|
|
47
|
-
const [position, setPosition] = useState({ top: 0, left: 0 });
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (isOpen && labelsButtonRef.current !== null) {
|
|
50
|
-
const rect = labelsButtonRef.current.getBoundingClientRect();
|
|
51
|
-
const parentRect = labelsButtonRef.current.offsetParent?.getBoundingClientRect() ?? {
|
|
52
|
-
top: 0,
|
|
53
|
-
left: 0,
|
|
54
|
-
};
|
|
55
|
-
setPosition({
|
|
56
|
-
top: rect.bottom - parentRect.top,
|
|
57
|
-
left: rect.right - parentRect.left + 4,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}, [isOpen, labelsButtonRef]);
|
|
61
|
-
if (!isOpen)
|
|
62
|
-
return null;
|
|
63
|
-
return (_jsx("div", { className: "absolute w-64 ml-4 z-20", style: {
|
|
64
|
-
top: `${position.top}px`,
|
|
65
|
-
left: `${position.left}px`,
|
|
66
|
-
}, children: _jsx(Select, { isMulti: true, name: "labels", options: labels.map(label => ({ label, value: `${FIELD_LABELS}.${label}` })), className: "parca-select-container text-sm w-full border-gray-300 border rounded-md", classNamePrefix: "parca-select", value: groupBy
|
|
67
|
-
.filter(l => l.startsWith(FIELD_LABELS))
|
|
68
|
-
.map(l => ({ value: l, label: l.slice(FIELD_LABELS.length + 1) })), onChange: newValue => {
|
|
69
|
-
setGroupByLabels(newValue.map(option => option.value));
|
|
70
|
-
setIsLabelSelectorOpen(false);
|
|
71
|
-
}, placeholder: "Select labels...", styles: {
|
|
72
|
-
menu: provided => ({
|
|
73
|
-
...provided,
|
|
74
|
-
position: 'relative',
|
|
75
|
-
marginBottom: 0,
|
|
76
|
-
boxShadow: 'none',
|
|
77
|
-
marginTop: 0,
|
|
78
|
-
}),
|
|
79
|
-
control: provided => ({
|
|
80
|
-
...provided,
|
|
81
|
-
boxShadow: 'none',
|
|
82
|
-
borderBottom: '1px solid #e2e8f0',
|
|
83
|
-
borderRight: 0,
|
|
84
|
-
borderLeft: 0,
|
|
85
|
-
borderTop: 0,
|
|
86
|
-
borderBottomLeftRadius: 0,
|
|
87
|
-
borderBottomRightRadius: 0,
|
|
88
|
-
':hover': {
|
|
89
|
-
borderColor: '#e2e8f0',
|
|
90
|
-
borderBottomLeftRadius: 0,
|
|
91
|
-
borderBottomRightRadius: 0,
|
|
92
|
-
},
|
|
93
|
-
}),
|
|
94
|
-
}, menuIsOpen: true }) }));
|
|
95
|
-
};
|
|
96
|
-
const GroupByDropdown = ({ groupBy, toggleGroupBy, onLabelClick, labelsButtonRef, }) => {
|
|
97
|
-
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
98
|
-
const dropdownRef = useRef(null);
|
|
99
|
-
useEffect(() => {
|
|
100
|
-
const handleClickOutside = (event) => {
|
|
101
|
-
if (isDropdownOpen &&
|
|
102
|
-
dropdownRef.current != null &&
|
|
103
|
-
!dropdownRef.current.contains(event.target)) {
|
|
104
|
-
setIsDropdownOpen(false);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
108
|
-
return () => {
|
|
109
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
110
|
-
};
|
|
111
|
-
}, [isDropdownOpen]);
|
|
112
|
-
const label = groupBy.length === 0
|
|
113
|
-
? 'Nothing'
|
|
114
|
-
: groupBy.length === 1
|
|
115
|
-
? groupByOptions.find(option => option.value === groupBy[0])?.label
|
|
116
|
-
: 'Multiple';
|
|
117
|
-
const selectedLabels = groupBy
|
|
118
|
-
.filter(l => l.startsWith(FIELD_LABELS))
|
|
119
|
-
.map(l => l.slice(FIELD_LABELS.length + 1));
|
|
120
|
-
return (_jsxs("div", { className: "relative", ref: dropdownRef, children: [_jsx("label", { className: "text-sm", children: "Group by" }), _jsxs("div", { className: "relative text-left", id: "h-group-by-filter", children: [_jsxs(Button, { variant: "neutral", onClick: () => setIsDropdownOpen(!isDropdownOpen), className: "relative w-max cursor-default rounded-md border bg-white py-2 pl-3 pr-[1.7rem] text-left text-sm shadow-sm dark:border-gray-600 dark:bg-gray-900 sm:text-sm", children: [_jsx("span", { className: "block overflow-x-hidden text-ellipsis", children: label }), _jsx("span", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 text-gray-400", children: _jsx(Icon, { icon: "heroicons:chevron-down-20-solid", "aria-hidden": "true" }) })] }), _jsx(Transition, { as: "div", leave: "transition ease-in duration-100", leaveFrom: "opacity-100", leaveTo: "opacity-0", show: isDropdownOpen, children: _jsx("div", { className: "absolute left-0 z-10 mt-1 min-w-[400px] overflow-auto rounded-md bg-gray-50 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-gray-600 dark:bg-gray-900 dark:ring-white dark:ring-opacity-20 sm:text-sm", children: _jsx("div", { className: "p-4", children: _jsx("fieldset", { children: _jsxs("div", { className: "space-y-5", children: [groupByOptions.map(({ value, label, description, disabled }) => (_jsxs("div", { className: "relative flex items-start", children: [_jsx("div", { className: "flex h-6 items-center", children: _jsx("input", { id: value, name: value, type: "checkbox", disabled: disabled, className: "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600", checked: groupBy.includes(value), onChange: () => toggleGroupBy(value) }) }), _jsxs("div", { className: "ml-3 text-sm leading-6", children: [_jsx("label", { htmlFor: value, className: "font-medium text-gray-900 dark:text-gray-200", children: label }), _jsx("p", { className: "text-gray-500 dark:text-gray-400", children: description })] })] }, value))), _jsxs("div", { className: "ml-7 flex flex-col items-start text-sm leading-6 cursor-pointer", onClick: onLabelClick, ref: labelsButtonRef, children: [_jsxs("div", { className: "flex justify-between w-full items-center", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900 dark:text-gray-200", children: "Labels" }), _jsx("p", { className: "text-gray-500 dark:text-gray-400", children: "Stacktraces are grouped by labels." })] }), _jsx(Icon, { icon: "flowbite:caret-right-solid", className: "h-[14px] w-[14px]" })] }), selectedLabels.length > 0 && (_jsxs("div", { className: "flex gap-2 flex-wrap", children: [_jsx("span", { className: "text-gray-500 dark:text-gray-200", children: "Selected labels:" }), _jsx("div", { className: "flex flex-wrap gap-3", children: selectedLabels.map(label => (_jsx("span", { className: "mr-2 px-3 py-1 text-xs text-gray-700 dark:text-gray-200 bg-gray-200 rounded-md dark:bg-gray-800", children: label }, label))) })] }))] })] }) }) }) }) })] })] }));
|
|
121
|
-
};
|
|
122
|
-
const GroupByControls = ({ groupBy, labels, toggleGroupBy, setGroupByLabels, }) => {
|
|
123
|
-
const [isLabelSelectorOpen, setIsLabelSelectorOpen] = useState(false);
|
|
124
|
-
const labelsButton = useRef(null);
|
|
125
|
-
const labelSelectorRef = useRef(null);
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
const handleClickOutside = (event) => {
|
|
128
|
-
if (isLabelSelectorOpen &&
|
|
129
|
-
labelSelectorRef.current !== null &&
|
|
130
|
-
!labelSelectorRef.current.contains(event.target) &&
|
|
131
|
-
labelsButton.current !== null &&
|
|
132
|
-
!labelsButton.current.contains(event.target)) {
|
|
133
|
-
setIsLabelSelectorOpen(false);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
137
|
-
return () => {
|
|
138
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
139
|
-
};
|
|
140
|
-
}, [isLabelSelectorOpen]);
|
|
141
|
-
return (_jsx("div", { className: "inline-flex items-start", children: _jsxs("div", { className: "relative flex items-start", children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, onLabelClick: () => setIsLabelSelectorOpen(!isLabelSelectorOpen), labelsButtonRef: labelsButton }), _jsx("div", { ref: labelSelectorRef, children: _jsx(LabelSelector, { labels: labels, groupBy: groupBy, setGroupByLabels: setGroupByLabels, isOpen: isLabelSelectorOpen, labelsButtonRef: labelsButton, setIsLabelSelectorOpen: setIsLabelSelectorOpen }) })] }) }));
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import GroupByLabelsDropdown from '../GroupByLabelsDropdown';
|
|
3
|
+
const GroupByControls = ({ groupBy, labels, setGroupByLabels }) => {
|
|
4
|
+
return (_jsx("div", { className: "inline-flex items-start", children: _jsx("div", { className: "relative flex gap-3 items-start", children: _jsx(GroupByLabelsDropdown, { labels: labels, groupBy: groupBy, setGroupByLabels: setGroupByLabels }) }) }));
|
|
142
5
|
};
|
|
143
6
|
export default GroupByControls;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
labels: string[];
|
|
3
|
+
groupBy: string[];
|
|
4
|
+
setGroupByLabels: (labels: string[]) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const GroupByLabelsDropdown: ({ labels, groupBy, setGroupByLabels }: Props) => JSX.Element;
|
|
7
|
+
export default GroupByLabelsDropdown;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/GroupByLabelsDropdown/index.tsx"],"names":[],"mappings":"AAsBA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC9C;AAED,QAAA,MAAM,qBAAqB,0CAAyC,KAAK,KAAG,GAAG,CAAC,OA6D/E,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
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 Select from 'react-select';
|
|
15
|
+
import { FIELD_LABELS } from '../../../ProfileIcicleGraph/IcicleGraphArrow';
|
|
16
|
+
const GroupByLabelsDropdown = ({ labels, groupBy, setGroupByLabels }) => {
|
|
17
|
+
return (_jsxs("div", { children: [_jsx("div", { className: "flex items-center justify-between", children: _jsx("label", { className: "text-sm", children: "Group by" }) }), _jsx(Select, { id: "h-group-by-labels-selector", isMulti: true, defaultMenuIsOpen: false, defaultValue: undefined, name: "labels", options: labels.map(label => ({ label, value: `${FIELD_LABELS}.${label}` })), className: "parca-select-container text-sm w-full rounded-md bg-white", classNamePrefix: "parca-select", value: groupBy
|
|
18
|
+
.filter(l => l.startsWith(FIELD_LABELS))
|
|
19
|
+
.map(l => ({ value: l, label: l.slice(FIELD_LABELS.length + 1) })), onChange: newValue => {
|
|
20
|
+
setGroupByLabels(newValue.map(option => option.value));
|
|
21
|
+
}, placeholder: "Select labels...", styles: {
|
|
22
|
+
menu: provided => ({
|
|
23
|
+
...provided,
|
|
24
|
+
marginBottom: 0,
|
|
25
|
+
boxShadow: 'none',
|
|
26
|
+
marginTop: 0,
|
|
27
|
+
zIndex: 1000,
|
|
28
|
+
minWidth: '320px',
|
|
29
|
+
}),
|
|
30
|
+
control: provided => ({
|
|
31
|
+
...provided,
|
|
32
|
+
position: 'relative',
|
|
33
|
+
boxShadow: 'none',
|
|
34
|
+
borderBottom: '1px solid #e2e8f0',
|
|
35
|
+
borderRight: '1px solid #e2e8f0',
|
|
36
|
+
borderLeft: '1px solid #e2e8f0',
|
|
37
|
+
borderTop: '1px solid #e2e8f0',
|
|
38
|
+
':hover': {
|
|
39
|
+
borderColor: '#e2e8f0',
|
|
40
|
+
borderBottomLeftRadius: 0,
|
|
41
|
+
borderBottomRightRadius: 0,
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
option: provided => ({
|
|
45
|
+
...provided,
|
|
46
|
+
':hover': {
|
|
47
|
+
backgroundColor: '#4f46e5',
|
|
48
|
+
color: '#ffffff',
|
|
49
|
+
},
|
|
50
|
+
':focus': {
|
|
51
|
+
backgroundColor: '#4f46e5',
|
|
52
|
+
color: '#ffffff',
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
} })] }));
|
|
56
|
+
};
|
|
57
|
+
export default GroupByLabelsDropdown;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/InvertCallStack/index.tsx"],"names":[],"mappings":"AAiBA,QAAA,MAAM,eAAe,QAAO,GAAG,CAAC,OAc/B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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 { Button, useURLState } from '@parca/components';
|
|
16
|
+
const InvertCallStack = () => {
|
|
17
|
+
const [invertStack = '', setInvertStack] = useURLState('invert_call_stack');
|
|
18
|
+
const isInvert = invertStack === 'true';
|
|
19
|
+
return (_jsxs(Button, { variant: "neutral", className: "flex items-center gap-2", onClick: () => setInvertStack(isInvert ? '' : 'true'), children: [_jsx(Icon, { icon: isInvert ? 'ph:sort-ascending' : 'ph:sort-descending', className: "h-4 w-4" }), isInvert ? 'Original' : 'Invert', " Call Stack"] }));
|
|
20
|
+
};
|
|
21
|
+
export default InvertCallStack;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ShareButton/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,KAAK,CAAC,SAAS,CAAC;CAChD;AAmGD,QAAA,MAAM,WAAW,oHAOd,KAAK,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ShareButton/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,KAAK,CAAC,SAAS,CAAC;CAChD;AAmGD,QAAA,MAAM,WAAW,oHAOd,KAAK,KAAG,GAAG,CAAC,OAgFd,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -77,7 +77,7 @@ const ShareButton = ({ queryRequest, queryClient, profileSource, onDownloadPProf
|
|
|
77
77
|
return (_jsx(_Fragment, { children: profileViewExternalSubActions != null ? (_jsx(_Fragment, { children: _jsxs(Button, { className: "gap-2", variant: "neutral", onClick: e => {
|
|
78
78
|
e.preventDefault();
|
|
79
79
|
onDownloadPProf();
|
|
80
|
-
}, disabled: pprofdownloading, id: "h-download-pprof", children: [pprofdownloading != null && pprofdownloading ? 'Downloading...' : 'Download pprof', _jsx(Icon, { icon: "material-symbols:download", width: 20 })] }) })) : (_jsxs(_Fragment, { children: [_jsxs(Dropdown, { dropdownWidth: "w-48", element: _jsxs(Button, { variant: "neutral",
|
|
80
|
+
}, disabled: pprofdownloading, id: "h-download-pprof", children: [pprofdownloading != null && pprofdownloading ? 'Downloading...' : 'Download pprof', _jsx(Icon, { icon: "material-symbols:download", width: 20 })] }) })) : (_jsxs(_Fragment, { children: [_jsxs(Dropdown, { dropdownWidth: "w-48", element: _jsxs(Button, { variant: "neutral", className: "flex items-center gap-2", id: "h-share-dropdown-button", children: [_jsx(Icon, { icon: "material-symbols:share", className: "h-4 w-4" }), "Share"] }), children: [_jsx("span", { className: "text-xs text-gray-400 capitalize px-2", children: "actions" }), actions.map(item => (_jsx(Dropdown.Item, { onSelect: item.onSelect, children: _jsxs("div", { id: item.id, className: "flex items-center gap-2", children: [_jsx(Icon, { icon: item.icon, className: "h-4 w-4" }), _jsx("span", { children: item.label })] }) }, item.key)))] }), profileSource !== undefined &&
|
|
81
81
|
queryClient !== undefined &&
|
|
82
82
|
queryRequest !== undefined && (_jsx(ProfileShareModal, { isOpen: showProfileShareModal, closeModal: () => setShowProfileShareModal(false), queryRequest: queryRequest, queryClient: queryClient }))] })) }));
|
|
83
83
|
};
|
|
@@ -3,6 +3,9 @@ import { ProfileType } from '@parca/parser';
|
|
|
3
3
|
interface MultiLevelDropdownProps {
|
|
4
4
|
onSelect: (path: string[]) => void;
|
|
5
5
|
profileType?: ProfileType;
|
|
6
|
+
groupBy: string[];
|
|
7
|
+
toggleGroupBy: (key: string) => void;
|
|
8
|
+
isTableVizOnly: boolean;
|
|
6
9
|
}
|
|
7
10
|
declare const MultiLevelDropdown: React.FC<MultiLevelDropdownProps>;
|
|
8
11
|
export default MultiLevelDropdown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiLevelDropdown.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx"],"names":[],"mappings":"AAaA,OAAO,
|
|
1
|
+
{"version":3,"file":"MultiLevelDropdown.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAQtE,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAkK1C,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAyOzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -11,14 +11,29 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
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 { useCallback } from 'react';
|
|
14
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
15
15
|
import { Menu } from '@headlessui/react';
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
17
|
+
import cx from 'classnames';
|
|
17
18
|
import { useURLState } from '@parca/components';
|
|
18
19
|
import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
|
|
19
|
-
import { FIELD_FUNCTION_NAME } from '../../../ProfileIcicleGraph/IcicleGraphArrow';
|
|
20
|
+
import { FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from '../../../ProfileIcicleGraph/IcicleGraphArrow';
|
|
20
21
|
import { useProfileViewContext } from '../../context/ProfileViewContext';
|
|
21
|
-
|
|
22
|
+
import SwitchMenuItem from './SwitchMenuItem';
|
|
23
|
+
const MenuItem = ({ label, items, onclick, onSelect, path = [], id, closeDropdown, isNested = false, activeValueForSortBy, activeValueForColorBy, activeValuesForLevel, value, disabled = false, icon, customSubmenu, renderAsDiv = false, }) => {
|
|
24
|
+
const menuRef = useRef(null);
|
|
25
|
+
const [shouldOpenLeft, setShouldOpenLeft] = useState(false);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (items !== undefined && menuRef.current !== null) {
|
|
28
|
+
const rect = menuRef.current.getBoundingClientRect();
|
|
29
|
+
const viewportWidth = window.innerWidth;
|
|
30
|
+
const menuWidth = 224; // w-56 = 14rem = 224px
|
|
31
|
+
const spaceOnRight = viewportWidth - rect.right;
|
|
32
|
+
const spaceOnLeft = rect.left;
|
|
33
|
+
// Open to the left if there's not enough space on the right but enough on the left
|
|
34
|
+
setShouldOpenLeft(spaceOnRight < menuWidth && spaceOnLeft >= menuWidth);
|
|
35
|
+
}
|
|
36
|
+
}, [items]);
|
|
22
37
|
let isActive = false;
|
|
23
38
|
if (isNested) {
|
|
24
39
|
if (activeValueForSortBy !== undefined && value === activeValueForSortBy) {
|
|
@@ -27,6 +42,9 @@ const MenuItem = ({ label, items, onclick, onSelect, path = [], id, closeDropdow
|
|
|
27
42
|
if (activeValueForColorBy !== undefined && value === activeValueForColorBy) {
|
|
28
43
|
isActive = true;
|
|
29
44
|
}
|
|
45
|
+
if (activeValuesForLevel?.includes(value ?? '') ?? false) {
|
|
46
|
+
isActive = true;
|
|
47
|
+
}
|
|
30
48
|
}
|
|
31
49
|
const handleSelect = () => {
|
|
32
50
|
if (items === undefined) {
|
|
@@ -40,17 +58,19 @@ const MenuItem = ({ label, items, onclick, onSelect, path = [], id, closeDropdow
|
|
|
40
58
|
}
|
|
41
59
|
}
|
|
42
60
|
};
|
|
43
|
-
return (_jsx("div", { className: "relative", children: _jsx(Menu, { children: ({ close }) => (_jsxs(_Fragment, { children: [_jsxs(Menu.Button, { className: `w-full text-left px-4 py-2 text-sm ${disabled
|
|
61
|
+
return (_jsx("div", { className: "relative", ref: menuRef, children: _jsx(Menu, { children: ({ close }) => (_jsxs(_Fragment, { children: [_jsxs(Menu.Button, { as: renderAsDiv ? 'div' : 'button', className: `w-full text-left px-4 py-2 text-sm ${disabled
|
|
44
62
|
? 'text-gray-400'
|
|
45
63
|
: isActive
|
|
46
64
|
? 'text-white bg-indigo-400 hover:text-white'
|
|
47
|
-
: 'text-white-600 hover:bg-indigo-600 hover:text-white'} flex justify-between items-center`, onClick: handleSelect, id: id, disabled: disabled, children: [customSubmenu !== undefined ? (customSubmenu) : (_jsxs("span", { className: "flex items-center", children: [_jsxs("div", { className: "flex items-center", children: [
|
|
65
|
+
: 'text-white-600 hover:bg-indigo-600 hover:text-white'} flex justify-between items-center`, onClick: handleSelect, id: id, disabled: disabled, children: [customSubmenu !== undefined ? (customSubmenu) : (_jsxs("span", { className: "flex items-center", children: [_jsxs("div", { className: "flex items-center gap-2", children: [icon !== undefined && _jsx(Icon, { icon: icon, className: "h-4 w-4" }), _jsx("span", { children: label })] }), isActive && _jsx(Icon, { icon: "heroicons-solid:check", className: "ml-2 h-4 w-4" })] })), items !== undefined && (_jsx(Icon, { icon: "flowbite:caret-right-solid", className: "h-[14px] w-[14px]" }))] }), items !== undefined && (_jsx(Menu.Items, { className: `absolute top-0 w-56 mt-0 bg-white border border-gray-200 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-gray-900 dark:border-gray-600 ${shouldOpenLeft
|
|
66
|
+
? 'right-full mr-1 origin-top-left'
|
|
67
|
+
: 'left-full ml-1 origin-top-right'}`, children: items?.map((item, index) => (_jsx(MenuItem, { ...item, onSelect: selectedPath => {
|
|
48
68
|
onSelect([...path, ...selectedPath]);
|
|
49
69
|
close();
|
|
50
70
|
closeDropdown();
|
|
51
|
-
}, path: [...path, label], closeDropdown: closeDropdown, isNested: true, activeValueForSortBy: activeValueForSortBy, activeValueForColorBy: activeValueForColorBy }, index))) }))] })) }) }));
|
|
71
|
+
}, path: [...path, label], closeDropdown: closeDropdown, isNested: true, activeValueForSortBy: activeValueForSortBy, activeValueForColorBy: activeValueForColorBy, activeValuesForLevel: activeValuesForLevel }, index))) }))] })) }) }));
|
|
52
72
|
};
|
|
53
|
-
const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
73
|
+
const MultiLevelDropdown = ({ onSelect, profileType, groupBy, toggleGroupBy, isTableVizOnly, }) => {
|
|
54
74
|
const [storeSortBy] = useURLState('sort_by', {
|
|
55
75
|
defaultValue: FIELD_FUNCTION_NAME,
|
|
56
76
|
});
|
|
@@ -63,8 +83,6 @@ const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
|
63
83
|
});
|
|
64
84
|
const { compareMode } = useProfileViewContext();
|
|
65
85
|
const [colorProfileName] = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key);
|
|
66
|
-
const [invertStack = '', setInvertStack] = useURLState('invert_call_stack');
|
|
67
|
-
const isInvert = invertStack === 'true';
|
|
68
86
|
const isColorStackLegendEnabled = colorStackLegend === 'true';
|
|
69
87
|
const [alignFunctionName, setAlignFunctionName] = useURLState('align_function_name');
|
|
70
88
|
const isLeftAligned = alignFunctionName === 'left' || alignFunctionName === undefined;
|
|
@@ -85,9 +103,37 @@ const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
|
85
103
|
setBinaryFrameFilter([]);
|
|
86
104
|
};
|
|
87
105
|
const menuItems = [
|
|
106
|
+
{
|
|
107
|
+
label: 'Levels',
|
|
108
|
+
id: 'h-levels-filter',
|
|
109
|
+
items: [
|
|
110
|
+
{
|
|
111
|
+
label: 'Function',
|
|
112
|
+
onclick: () => toggleGroupBy(FIELD_FUNCTION_NAME),
|
|
113
|
+
value: FIELD_FUNCTION_NAME,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
label: 'Binary',
|
|
117
|
+
onclick: () => toggleGroupBy(FIELD_MAPPING_FILE),
|
|
118
|
+
value: FIELD_MAPPING_FILE,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: 'Code',
|
|
122
|
+
onclick: () => toggleGroupBy(FIELD_FUNCTION_FILE_NAME),
|
|
123
|
+
value: FIELD_FUNCTION_FILE_NAME,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
label: 'Address',
|
|
127
|
+
onclick: () => toggleGroupBy(FIELD_LOCATION_ADDRESS),
|
|
128
|
+
value: FIELD_LOCATION_ADDRESS,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
hide: !!isTableVizOnly,
|
|
132
|
+
icon: 'heroicons-solid:bars-3',
|
|
133
|
+
},
|
|
88
134
|
{
|
|
89
135
|
label: 'Color by',
|
|
90
|
-
id: 'h-
|
|
136
|
+
id: 'h-color-by-filter',
|
|
91
137
|
items: [
|
|
92
138
|
{
|
|
93
139
|
label: 'Binary',
|
|
@@ -110,17 +156,11 @@ const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
|
110
156
|
id: 'h-show-legend-button',
|
|
111
157
|
icon: isColorStackLegendEnabled ? 'ph:eye-closed' : 'ph:eye',
|
|
112
158
|
},
|
|
113
|
-
{
|
|
114
|
-
label: isInvert ? 'Original Call Stack' : 'Invert Call Stack',
|
|
115
|
-
onclick: () => setInvertStack(isInvert ? '' : 'true'),
|
|
116
|
-
hide: false,
|
|
117
|
-
icon: isInvert ? 'ph:sort-ascending' : 'ph:sort-descending',
|
|
118
|
-
},
|
|
119
159
|
{
|
|
120
160
|
label: isLeftAligned ? 'Right-align function names' : 'Left-align function names',
|
|
121
161
|
onclick: () => setAlignFunctionName(isLeftAligned ? 'right' : 'left'),
|
|
122
162
|
id: 'h-align-function-names',
|
|
123
|
-
hide:
|
|
163
|
+
hide: !!isTableVizOnly,
|
|
124
164
|
icon: isLeftAligned
|
|
125
165
|
? 'ic:outline-align-horizontal-right'
|
|
126
166
|
: 'ic:outline-align-horizontal-left',
|
|
@@ -131,6 +171,24 @@ const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
|
131
171
|
hide: !compareMode,
|
|
132
172
|
icon: isCompareAbsolute ? 'fluent-mdl2:compare' : 'fluent-mdl2:compare-uneven',
|
|
133
173
|
},
|
|
174
|
+
{
|
|
175
|
+
label: 'Highlight matching nodes after filtering',
|
|
176
|
+
hide: !!isTableVizOnly,
|
|
177
|
+
customSubmenu: (_jsx(SwitchMenuItem, { label: "Highlight matching nodes after filtering", id: "h-highlight-after-filtering", userPreferenceDetails: USER_PREFERENCES.HIGHTLIGHT_AFTER_FILTERING })),
|
|
178
|
+
renderAsDiv: true,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
label: 'Dock Graph MetaInfo',
|
|
182
|
+
hide: !!isTableVizOnly,
|
|
183
|
+
customSubmenu: (_jsx(SwitchMenuItem, { label: "Dock graph tooltip", id: "h-dock-graph-meta-info", userPreferenceDetails: USER_PREFERENCES.GRAPH_METAINFO_DOCKED })),
|
|
184
|
+
renderAsDiv: true,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
label: 'Highlight similar stacks when hovering over a node',
|
|
188
|
+
hide: !!isTableVizOnly,
|
|
189
|
+
customSubmenu: (_jsx(SwitchMenuItem, { label: "Highlight similar stacks when hovering over a node", id: "h-highlight-similar-stacks", userPreferenceDetails: USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS })),
|
|
190
|
+
renderAsDiv: true,
|
|
191
|
+
},
|
|
134
192
|
{
|
|
135
193
|
label: 'Reset Legend',
|
|
136
194
|
hide: binaryFrameFilter === undefined || binaryFrameFilter.length === 0,
|
|
@@ -149,8 +207,8 @@ const MultiLevelDropdown = ({ onSelect, profileType }) => {
|
|
|
149
207
|
icon: 'ph:eye-closed',
|
|
150
208
|
},
|
|
151
209
|
];
|
|
152
|
-
return (_jsx("div", { className: "relative inline-block text-left", id: "h-visualisation-toolbar-actions", children: _jsx(Menu, { children: ({ open, close }) => (_jsxs(_Fragment, { children: [_jsxs(Menu.Button, { className: "
|
|
153
|
-
|
|
154
|
-
|
|
210
|
+
return (_jsx("div", { className: "relative inline-block text-left", id: "h-visualisation-toolbar-actions", children: _jsx(Menu, { children: ({ open, close }) => (_jsxs(_Fragment, { children: [_jsxs(Menu.Button, { className: "flex dark:bg-gray-900 dark:border-gray-600 justify-center w-full px-4 py-2 text-sm font-normal text-gray-600 dark:text-gray-200 bg-white rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 border border-gray-200 pr-[1.7rem]", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Icon, { icon: "pajamas:preferences", className: "w-4 h-4" }), _jsx("span", { children: "Preferences" })] }), _jsx("span", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 text-gray-400", children: _jsx(Icon, { icon: "heroicons:chevron-down-20-solid", "aria-hidden": "true" }) })] }), open && (_jsx(Menu.Items, { className: cx(isTableVizOnly ? 'w-64' : 'w-80', 'absolute z-30 left-0 mt-2 py-2 origin-top-right bg-white rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none border dark:bg-gray-900 dark:border-gray-600'), children: menuItems
|
|
211
|
+
.filter(item => item.hide !== undefined && !item.hide)
|
|
212
|
+
.map((item, index) => (_jsx(MenuItem, { ...item, onSelect: onSelect, closeDropdown: close, activeValueForSortBy: storeSortBy, activeValueForColorBy: colorBy === undefined || colorBy === '' ? 'binary' : colorBy, activeValuesForLevel: groupBy, renderAsDiv: item.renderAsDiv }, index))) }))] })) }) }));
|
|
155
213
|
};
|
|
156
214
|
export default MultiLevelDropdown;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type UserPreferenceDetails } from '@parca/hooks';
|
|
2
|
+
interface SwitchMenuItemProps {
|
|
3
|
+
label: string;
|
|
4
|
+
id: string;
|
|
5
|
+
userPreferenceDetails: UserPreferenceDetails;
|
|
6
|
+
}
|
|
7
|
+
declare function SwitchMenuItem<T>({ label, id, userPreferenceDetails }: SwitchMenuItemProps): JSX.Element;
|
|
8
|
+
export default SwitchMenuItem;
|
|
9
|
+
//# sourceMappingURL=SwitchMenuItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwitchMenuItem.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/SwitchMenuItem.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAoB,KAAK,qBAAqB,EAAC,MAAM,cAAc,CAAC;AAE3E,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB,EAAE,qBAAqB,CAAC;CAC9C;AAED,iBAAS,cAAc,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,EAAE,EAAE,qBAAqB,EAAC,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAwB/F;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 { Switch } from '@headlessui/react';
|
|
15
|
+
import { useUserPreference } from '@parca/hooks';
|
|
16
|
+
function SwitchMenuItem({ label, id, userPreferenceDetails }) {
|
|
17
|
+
const [enabledPreference, setEnabledPreference] = useUserPreference(userPreferenceDetails.key);
|
|
18
|
+
return (_jsxs("div", { className: "flex items-center justify-between w-full", children: [_jsx("span", { children: label }), _jsxs(Switch, { id: id, checked: enabledPreference, onChange: (checked) => setEnabledPreference(checked), className: `${enabledPreference ? 'bg-indigo-600' : 'bg-gray-400 dark:bg-gray-800'}
|
|
19
|
+
relative inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75`, children: [_jsx("span", { className: "sr-only", children: "Use setting" }), _jsx("span", { "aria-hidden": "true", className: `${enabledPreference ? 'translate-x-5' : 'translate-x-0'}
|
|
20
|
+
pointer-events-none inline-block h-[20px] w-[20px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out` })] })] }));
|
|
21
|
+
}
|
|
22
|
+
export default SwitchMenuItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAUrD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5E,yBAAyB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,+BAA+B;IAC9C,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAwB9C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAiB1D,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,+BAA+B,CAmB1E,CAAC;AAMF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CA6G9D,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { Button, UserPreferencesModal } from '@parca/components';
|
|
|
4
4
|
import { useDashboard } from '../../context/DashboardContext';
|
|
5
5
|
import GroupByDropdown from '../ActionButtons/GroupByDropdown';
|
|
6
6
|
import FilterByFunctionButton from '../FilterByFunctionButton';
|
|
7
|
+
import InvertCallStack from '../InvertCallStack';
|
|
7
8
|
import ShareButton from '../ShareButton';
|
|
8
9
|
import ViewSelector from '../ViewSelector';
|
|
9
10
|
import MultiLevelDropdown from './MultiLevelDropdown';
|
|
@@ -21,13 +22,15 @@ const Divider = () => (_jsx("div", { className: "border-t mt-4 border-gray-200 d
|
|
|
21
22
|
export const VisualisationToolbar = ({ groupBy, toggleGroupBy, groupByLabels, setGroupByLabels, profileType, preferencesModal, profileSource, queryClient, onDownloadPProf, pprofdownloading, profileViewExternalSubActions, curPath, setNewCurPath, total, filtered, currentSearchString, clearSelection, showVisualizationSelector = true, resetSandwichFunctionName, sandwichFunctionName, }) => {
|
|
22
23
|
const { dashboardItems } = useDashboard();
|
|
23
24
|
const isTableViz = dashboardItems?.includes('table');
|
|
25
|
+
const isTableVizOnly = dashboardItems?.length === 1 && isTableViz;
|
|
24
26
|
const isGraphViz = dashboardItems?.includes('icicle');
|
|
25
27
|
const isSandwichIcicleGraphViz = dashboardItems?.includes('sandwich');
|
|
28
|
+
const isTableView = isTableVizOnly || isSandwichIcicleGraphViz;
|
|
26
29
|
const req = profileSource?.QueryRequest();
|
|
27
30
|
if (req !== null && req !== undefined) {
|
|
28
31
|
req.groupBy = {
|
|
29
32
|
fields: groupBy ?? [],
|
|
30
33
|
};
|
|
31
34
|
}
|
|
32
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-end", children: [_jsxs("div", { className: "flex gap-3 items-end", children: [_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy,
|
|
35
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-end", children: [_jsxs("div", { className: "flex gap-3 items-end", children: [!isTableView && (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, labels: groupByLabels, setGroupByLabels: setGroupByLabels }), _jsx(InvertCallStack, {})] })), _jsx(FilterByFunctionButton, {}), profileViewExternalSubActions != null ? profileViewExternalSubActions : null] }), _jsxs("div", { className: "flex gap-3", children: [preferencesModal === true && _jsx(UserPreferencesModal, {}), _jsx(MultiLevelDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, profileType: profileType, onSelect: () => { }, isTableVizOnly: isTableView }), _jsx(ShareButton, { profileSource: profileSource, queryClient: queryClient, queryRequest: req, onDownloadPProf: onDownloadPProf, pprofdownloading: pprofdownloading ?? false, profileViewExternalSubActions: profileViewExternalSubActions }), showVisualizationSelector ? _jsx(ViewSelector, { profileSource: profileSource }) : null] })] }), isGraphViz && !isTableViz && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(IcicleGraphToolbar, { curPath: curPath, setNewCurPath: setNewCurPath })] })), isTableViz && !isGraphViz && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(TableToolbar, { profileType: profileType, total: total, filtered: filtered, clearSelection: clearSelection, currentSearchString: currentSearchString })] })), isSandwichIcicleGraphViz && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(SandwichIcicleGraphToolbar, { resetSandwichFunctionName: resetSandwichFunctionName, sandwichFunctionName: sandwichFunctionName })] }))] }));
|
|
33
36
|
};
|