@parca/profile 0.16.183 → 0.16.185
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/Callgraph/constants.js +2 -2
- package/dist/Callgraph/index.js +35 -45
- package/dist/Callgraph/mockData/index.js +28 -11
- package/dist/Callgraph/utils.js +51 -58
- package/dist/GraphTooltip/ExpandOnHoverValue.js +2 -14
- package/dist/GraphTooltip/index.d.ts +5 -5
- package/dist/GraphTooltip/index.js +96 -122
- package/dist/MatchersInput/SuggestionItem.js +5 -17
- package/dist/MatchersInput/SuggestionsList.js +29 -53
- package/dist/MatchersInput/index.js +58 -74
- package/dist/MetricsCircle/index.js +2 -16
- package/dist/MetricsGraph/MetricsTooltip/index.js +27 -53
- package/dist/MetricsGraph/index.js +79 -98
- package/dist/MetricsSeries/index.js +4 -19
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +4 -16
- package/dist/ProfileExplorer/ProfileExplorerSingle.js +2 -14
- package/dist/ProfileExplorer/index.js +129 -88
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.js +15 -31
- package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.d.ts +4 -4
- package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.js +38 -54
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +15 -31
- package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.js +22 -26
- package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.js +8 -9
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.js +18 -20
- package/dist/ProfileIcicleGraph/index.d.ts +2 -2
- package/dist/ProfileIcicleGraph/index.js +18 -30
- package/dist/ProfileMetricsGraph/index.js +36 -88
- package/dist/ProfileSelector/CompareButton.js +8 -20
- package/dist/ProfileSelector/index.js +69 -69
- package/dist/ProfileSource.js +56 -65
- package/dist/ProfileTypeSelector/index.js +14 -28
- package/dist/ProfileView/FilterByFunctionButton.js +6 -7
- package/dist/ProfileView/ViewSelector.js +18 -31
- package/dist/ProfileView/VisualizationPanel.js +4 -16
- package/dist/ProfileView/index.d.ts +2 -1
- package/dist/ProfileView/index.js +73 -151
- package/dist/ProfileViewWithData.js +50 -97
- package/dist/TopTable/index.js +55 -63
- package/dist/components/DiffLegend.js +16 -28
- package/dist/components/ProfileShareButton/ResultBox.js +7 -21
- package/dist/components/ProfileShareButton/index.js +31 -90
- package/dist/useDelayedLoader.js +7 -8
- package/dist/useGrpcQuery/index.js +6 -48
- package/dist/useQuery.js +14 -58
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +16 -68
- package/package.json +6 -6
- package/src/Callgraph/index.tsx +3 -3
- package/src/Callgraph/utils.ts +1 -1
- package/src/GraphTooltip/index.tsx +17 -17
- package/src/MetricsGraph/index.tsx +3 -3
- package/src/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.tsx +9 -10
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +4 -8
- package/src/ProfileIcicleGraph/IcicleGraph/useNodeColor.ts +2 -2
- package/src/ProfileIcicleGraph/index.tsx +8 -8
- package/src/ProfileView/index.tsx +8 -3
- package/src/ProfileViewWithData.tsx +5 -0
- package/src/TopTable/index.tsx +3 -3
- package/src/utils.ts +2 -2
package/dist/TopTable/index.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
2
|
// Copyright 2022 The Parca Authors
|
|
14
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -27,57 +16,54 @@ import { createColumnHelper } from '@tanstack/react-table';
|
|
|
27
16
|
import { Button, Table, useURLState } from '@parca/components';
|
|
28
17
|
import { getLastItem, isSearchMatch, parseParams, valueFormatter, } from '@parca/utilities';
|
|
29
18
|
import { hexifyAddress } from '../utils';
|
|
30
|
-
export
|
|
31
|
-
var _a, _b, _c, _d, _e, _f;
|
|
19
|
+
export const RowLabel = (meta) => {
|
|
32
20
|
if (meta === undefined)
|
|
33
21
|
return '<unknown>';
|
|
34
|
-
|
|
35
|
-
?
|
|
36
|
-
: ''
|
|
37
|
-
if (
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
22
|
+
const mapping = `${meta?.mapping?.file !== undefined && meta?.mapping?.file !== ''
|
|
23
|
+
? `[${getLastItem(meta.mapping.file) ?? ''}]`
|
|
24
|
+
: ''}`;
|
|
25
|
+
if (meta.function?.name !== undefined && meta.function?.name !== '')
|
|
26
|
+
return `${mapping} ${meta.function.name}`;
|
|
27
|
+
const address = hexifyAddress(meta.location?.address);
|
|
28
|
+
const fallback = `${mapping} ${address}`;
|
|
41
29
|
return fallback === '' ? '<unknown>' : fallback;
|
|
42
30
|
};
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
const columnHelper = createColumnHelper();
|
|
32
|
+
const addPlusSign = (num) => {
|
|
45
33
|
if (num.charAt(0) === '0' || num.charAt(0) === '-') {
|
|
46
34
|
return num;
|
|
47
35
|
}
|
|
48
|
-
return
|
|
36
|
+
return `+${num}`;
|
|
49
37
|
};
|
|
50
|
-
export
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
var compareMode = rawcompareMode === undefined ? false : rawcompareMode === 'true';
|
|
57
|
-
var dashboardItems = useMemo(function () {
|
|
38
|
+
export const TopTable = React.memo(function TopTable({ data: top, sampleUnit: unit, navigateTo, loading, currentSearchString, setActionButtons, }) {
|
|
39
|
+
const router = parseParams(window?.location.search);
|
|
40
|
+
const [rawDashboardItems] = useURLState({ param: 'dashboard_items' });
|
|
41
|
+
const [rawcompareMode] = useURLState({ param: 'compare_a' });
|
|
42
|
+
const compareMode = rawcompareMode === undefined ? false : rawcompareMode === 'true';
|
|
43
|
+
const dashboardItems = useMemo(() => {
|
|
58
44
|
if (rawDashboardItems !== undefined) {
|
|
59
45
|
return rawDashboardItems;
|
|
60
46
|
}
|
|
61
47
|
return ['icicle'];
|
|
62
48
|
}, [rawDashboardItems]);
|
|
63
|
-
|
|
64
|
-
|
|
49
|
+
const columns = useMemo(() => {
|
|
50
|
+
const cols = [
|
|
65
51
|
columnHelper.accessor('meta', {
|
|
66
|
-
header:
|
|
67
|
-
cell:
|
|
68
|
-
|
|
69
|
-
|
|
52
|
+
header: () => _jsx("span", { className: "text-left", children: "Name" }),
|
|
53
|
+
cell: info => {
|
|
54
|
+
const meta = info.row.original.meta;
|
|
55
|
+
const name = RowLabel(meta);
|
|
70
56
|
return name;
|
|
71
57
|
},
|
|
72
|
-
sortingFn:
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
sortingFn: (a, b) => {
|
|
59
|
+
const aName = RowLabel(a.original.meta);
|
|
60
|
+
const bName = RowLabel(b.original.meta);
|
|
75
61
|
return aName.localeCompare(bName);
|
|
76
62
|
},
|
|
77
63
|
}),
|
|
78
64
|
columnHelper.accessor('flat', {
|
|
79
|
-
header:
|
|
80
|
-
cell:
|
|
65
|
+
header: () => 'Flat',
|
|
66
|
+
cell: info => valueFormatter(info.getValue(), unit, 2),
|
|
81
67
|
size: 150,
|
|
82
68
|
meta: {
|
|
83
69
|
align: 'right',
|
|
@@ -85,8 +71,8 @@ export var TopTable = React.memo(function TopTable(_a) {
|
|
|
85
71
|
sortDescFirst: true,
|
|
86
72
|
}),
|
|
87
73
|
columnHelper.accessor('cumulative', {
|
|
88
|
-
header:
|
|
89
|
-
cell:
|
|
74
|
+
header: () => 'Cumulative',
|
|
75
|
+
cell: info => valueFormatter(info.getValue(), unit, 2),
|
|
90
76
|
size: 150,
|
|
91
77
|
meta: {
|
|
92
78
|
align: 'right',
|
|
@@ -96,8 +82,8 @@ export var TopTable = React.memo(function TopTable(_a) {
|
|
|
96
82
|
];
|
|
97
83
|
if (compareMode) {
|
|
98
84
|
cols.push(columnHelper.accessor('diff', {
|
|
99
|
-
header:
|
|
100
|
-
cell:
|
|
85
|
+
header: () => 'Diff',
|
|
86
|
+
cell: info => addPlusSign(valueFormatter(info.getValue(), unit, 2)),
|
|
101
87
|
size: 150,
|
|
102
88
|
meta: {
|
|
103
89
|
align: 'right',
|
|
@@ -107,50 +93,56 @@ export var TopTable = React.memo(function TopTable(_a) {
|
|
|
107
93
|
}
|
|
108
94
|
return cols;
|
|
109
95
|
}, [unit, compareMode]);
|
|
110
|
-
|
|
96
|
+
const selectSpan = useCallback((span) => {
|
|
111
97
|
if (navigateTo != null) {
|
|
112
|
-
navigateTo('/',
|
|
98
|
+
navigateTo('/', {
|
|
99
|
+
...router,
|
|
100
|
+
...{ search_string: span.trim() },
|
|
101
|
+
}, { replace: true });
|
|
113
102
|
}
|
|
114
103
|
}, [navigateTo, router]);
|
|
115
|
-
|
|
104
|
+
const onRowClick = useCallback((row) => {
|
|
116
105
|
// If there is only one dashboard item, we don't want to select a span
|
|
117
106
|
if (dashboardItems.length <= 1) {
|
|
118
107
|
return;
|
|
119
108
|
}
|
|
120
|
-
|
|
109
|
+
const meta = row.meta;
|
|
121
110
|
if (meta === undefined) {
|
|
122
111
|
return;
|
|
123
112
|
}
|
|
124
|
-
|
|
113
|
+
const name = RowLabel(meta);
|
|
125
114
|
selectSpan(name);
|
|
126
115
|
}, [selectSpan, dashboardItems.length]);
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
const shouldHighlightRow = useCallback((row) => {
|
|
117
|
+
const meta = row.meta;
|
|
129
118
|
if (meta === undefined)
|
|
130
119
|
return false;
|
|
131
|
-
|
|
120
|
+
const name = RowLabel(meta);
|
|
132
121
|
return isSearchMatch(currentSearchString, name);
|
|
133
122
|
}, [currentSearchString]);
|
|
134
|
-
|
|
135
|
-
return currentSearchString != null &&
|
|
123
|
+
const enableHighlighting = useMemo(() => {
|
|
124
|
+
return currentSearchString != null && currentSearchString?.length > 0;
|
|
136
125
|
}, [currentSearchString]);
|
|
137
|
-
|
|
126
|
+
const clearSelection = useCallback(() => {
|
|
138
127
|
if (navigateTo != null) {
|
|
139
|
-
navigateTo('/',
|
|
128
|
+
navigateTo('/', {
|
|
129
|
+
...router,
|
|
130
|
+
...{ search_string: '' },
|
|
131
|
+
}, { replace: true });
|
|
140
132
|
}
|
|
141
133
|
}, [navigateTo, router]);
|
|
142
|
-
useEffect(
|
|
134
|
+
useEffect(() => {
|
|
143
135
|
if (setActionButtons === undefined) {
|
|
144
136
|
return;
|
|
145
137
|
}
|
|
146
|
-
setActionButtons(dashboardItems.length > 1 ? (_jsx(Button,
|
|
138
|
+
setActionButtons(dashboardItems.length > 1 ? (_jsx(Button, { color: "neutral", onClick: clearSelection, className: "w-auto", variant: "neutral", disabled: currentSearchString === undefined || currentSearchString.length === 0, children: "Clear selection" })) : (_jsx(_Fragment, {})));
|
|
147
139
|
}, [dashboardItems, clearSelection, currentSearchString, setActionButtons]);
|
|
148
|
-
|
|
140
|
+
const initialSorting = useMemo(() => {
|
|
149
141
|
return [{ id: compareMode ? 'diff' : 'cumulative', desc: true }];
|
|
150
142
|
}, [compareMode]);
|
|
151
|
-
|
|
143
|
+
const total = top != null ? top.list.length : 0;
|
|
152
144
|
if (total === 0 && !loading)
|
|
153
145
|
return _jsx(_Fragment, { children: "Profile has no samples" });
|
|
154
|
-
return (_jsx("div",
|
|
146
|
+
return (_jsx("div", { className: "relative", children: _jsx("div", { className: "font-robotoMono h-[80vh] w-full overflow-scroll", children: _jsx(Table, { data: top?.list ?? [], columns: columns, initialSorting: initialSorting, onRowClick: onRowClick, enableHighlighting: enableHighlighting, shouldHighlightRow: shouldHighlightRow, usePointerCursor: dashboardItems.length > 1 }) }) }));
|
|
155
147
|
});
|
|
156
148
|
export default TopTable;
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
2
|
// Copyright 2022 The Parca Authors
|
|
14
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -27,13 +16,12 @@ import { Popover, Transition } from '@headlessui/react';
|
|
|
27
16
|
import { usePopper } from 'react-popper';
|
|
28
17
|
import { selectDarkMode, useAppSelector } from '@parca/store';
|
|
29
18
|
import { getIncreasedSpanColor, getNewSpanColor, getReducedSpanColor } from '@parca/utilities';
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
var absoluteValue = Math.abs(valueAsPercentage);
|
|
19
|
+
const transparencyValues = [-100, -80, -60, -40, -20, 0, 20, 40, 60, 80, 100];
|
|
20
|
+
const DiffLegendBar = ({ onMouseEnter, onMouseLeave, }) => {
|
|
21
|
+
const isDarkMode = useAppSelector(selectDarkMode);
|
|
22
|
+
return (_jsx("div", { className: "m-2 flex items-center", children: transparencyValues.map(value => {
|
|
23
|
+
const valueAsPercentage = value / 100;
|
|
24
|
+
const absoluteValue = Math.abs(valueAsPercentage);
|
|
37
25
|
return (_jsx("div", { onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: "h-4 w-8", style: {
|
|
38
26
|
backgroundColor: absoluteValue === 0
|
|
39
27
|
? getNewSpanColor(isDarkMode)
|
|
@@ -41,22 +29,22 @@ var DiffLegendBar = function (_a) {
|
|
|
41
29
|
? getIncreasedSpanColor(absoluteValue, isDarkMode)
|
|
42
30
|
: getReducedSpanColor(absoluteValue, isDarkMode),
|
|
43
31
|
} }, valueAsPercentage));
|
|
44
|
-
}) }))
|
|
32
|
+
}) }));
|
|
45
33
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
34
|
+
const DiffLegend = () => {
|
|
35
|
+
const [showLegendTooltip, setShowLegendTooltip] = useState(false);
|
|
36
|
+
const [popperElement, setPopperElement] = useState(null);
|
|
37
|
+
const [referenceElement, setReferenceElement] = useState(null);
|
|
38
|
+
const { styles, attributes } = usePopper(referenceElement, popperElement, {
|
|
51
39
|
placement: 'auto-start',
|
|
52
40
|
strategy: 'absolute',
|
|
53
|
-
})
|
|
54
|
-
|
|
41
|
+
});
|
|
42
|
+
const handleMouseEnter = () => {
|
|
55
43
|
setShowLegendTooltip(true);
|
|
56
44
|
};
|
|
57
|
-
|
|
45
|
+
const handleMouseLeave = () => {
|
|
58
46
|
setShowLegendTooltip(false);
|
|
59
47
|
};
|
|
60
|
-
return (_jsxs("div",
|
|
48
|
+
return (_jsxs("div", { className: "mt-1 mb-2", children: [_jsxs("div", { ref: setReferenceElement, className: "flex items-center justify-center", children: [_jsx("span", { children: "Better" }), _jsx(DiffLegendBar, { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }), _jsx("span", { children: "Worse" })] }), _jsx(Popover, { className: "relative", children: () => (_jsx(Transition, { show: showLegendTooltip, as: Fragment, enter: "transition ease-out duration-200", enterFrom: "opacity-0 translate-y-1", enterTo: "opacity-100 translate-y-0", leave: "transition ease-in duration-150", leaveFrom: "opacity-100 translate-y-0", leaveTo: "opacity-0 translate-y-1", children: _jsx(Popover.Panel, { ref: setPopperElement, style: styles.popper, ...attributes.popper, children: _jsx("div", { className: "overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5", children: _jsxs("div", { className: "bg-gray-50 p-4 dark:bg-gray-800", children: [_jsx("div", { className: "flex items-center justify-center" }), _jsx("span", { className: "block text-sm text-gray-500 dark:text-gray-50", children: "This is a differential icicle graph, where a purple-colored node means unchanged, and the darker the red, the worse the node got, and the darker the green, the better the node got." })] }) }) }) })) })] }));
|
|
61
49
|
};
|
|
62
50
|
export default DiffLegend;
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
2
|
// Copyright 2022 The Parca Authors
|
|
14
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -27,23 +16,20 @@ import { Icon } from '@iconify/react';
|
|
|
27
16
|
import cx from 'classnames';
|
|
28
17
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|
29
18
|
import { Button } from '@parca/components';
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var _d = useState(false), isCopied = _d[0], setIsCopied = _d[1];
|
|
35
|
-
var onCopy = function () {
|
|
36
|
-
var _a, _b;
|
|
19
|
+
let timeoutHandle = null;
|
|
20
|
+
const ResultBox = ({ value, className = '' }) => {
|
|
21
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
22
|
+
const onCopy = () => {
|
|
37
23
|
if (typeof window === 'undefined') {
|
|
38
24
|
return;
|
|
39
25
|
}
|
|
40
26
|
setIsCopied(true);
|
|
41
|
-
|
|
27
|
+
window.document?.activeElement?.blur();
|
|
42
28
|
if (timeoutHandle != null) {
|
|
43
29
|
clearTimeout(timeoutHandle);
|
|
44
30
|
}
|
|
45
|
-
timeoutHandle = setTimeout(
|
|
31
|
+
timeoutHandle = setTimeout(() => setIsCopied(false), 3000);
|
|
46
32
|
};
|
|
47
|
-
return (_jsxs("div",
|
|
33
|
+
return (_jsxs("div", { className: cx('flex w-full flex-row', { [className]: className?.length > 0 }), children: [_jsx("span", { className: "flex w-16 items-center justify-center rounded-l border border-r-0", children: _jsx(Icon, { icon: "ant-design:link-outlined" }) }), _jsx("input", { type: "text", className: "w-full flex-grow border bg-inherit px-1 py-2 text-sm", value: value, readOnly: true }), _jsx(CopyToClipboard, { text: value, onCopy: onCopy, children: _jsx(Button, { variant: "link", className: "w-fit items-center whitespace-nowrap rounded-none rounded-r border border-l-0 p-4 !text-indigo-600 dark:!text-indigo-400", children: isCopied ? 'Copied!' : 'Copy Link' }) })] }));
|
|
48
34
|
};
|
|
49
35
|
export default ResultBox;
|
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
49
2
|
// Copyright 2022 The Parca Authors
|
|
50
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -62,58 +15,46 @@ import { useState } from 'react';
|
|
|
62
15
|
import { Icon } from '@iconify/react';
|
|
63
16
|
import { Button, Modal, useGrpcMetadata } from '@parca/components';
|
|
64
17
|
import ResultBox from './ResultBox';
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
case 2:
|
|
89
|
-
err_1 = _a.sent();
|
|
90
|
-
if (err_1 instanceof Error) {
|
|
91
|
-
console.error(err_1);
|
|
92
|
-
setLoading(false);
|
|
93
|
-
// https://github.com/microsoft/TypeScript/issues/38347
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
95
|
-
setError(err_1.toString());
|
|
96
|
-
}
|
|
97
|
-
return [3 /*break*/, 3];
|
|
98
|
-
case 3: return [2 /*return*/];
|
|
18
|
+
const ProfileShareModal = ({ isOpen, closeModal, queryRequest, queryClient, }) => {
|
|
19
|
+
const [isShared, setIsShared] = useState(false);
|
|
20
|
+
const [loading, setLoading] = useState(false);
|
|
21
|
+
const [error, setError] = useState('');
|
|
22
|
+
const [description, setDescription] = useState('');
|
|
23
|
+
const [sharedLink, setSharedLink] = useState('');
|
|
24
|
+
const metadata = useGrpcMetadata();
|
|
25
|
+
const isFormDataValid = () => true;
|
|
26
|
+
const handleSubmit = async () => {
|
|
27
|
+
try {
|
|
28
|
+
setLoading(true);
|
|
29
|
+
const { response } = await queryClient.shareProfile({ queryRequest, description }, { meta: metadata });
|
|
30
|
+
setSharedLink(response.link);
|
|
31
|
+
setLoading(false);
|
|
32
|
+
setIsShared(true);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err instanceof Error) {
|
|
36
|
+
console.error(err);
|
|
37
|
+
setLoading(false);
|
|
38
|
+
// https://github.com/microsoft/TypeScript/issues/38347
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
40
|
+
setError(err.toString());
|
|
99
41
|
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const onClose = () => {
|
|
103
45
|
setLoading(false);
|
|
104
46
|
setError('');
|
|
105
47
|
setDescription('');
|
|
106
48
|
setIsShared(false);
|
|
107
49
|
closeModal();
|
|
108
50
|
};
|
|
109
|
-
return (_jsx(Modal,
|
|
51
|
+
return (_jsx(Modal, { isOpen: isOpen, closeModal: onClose, title: "Share Profile", className: "w-[420px]", children: _jsxs("form", { className: "py-2", children: [_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-300", children: "Note: Shared profiles can be accessed by anyone with the link, even from people outside your organisation." }), !isShared || error?.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mt-3 mb-2 text-sm text-gray-500 dark:text-gray-300", children: "Enter a description (optional)" }), _jsx("textarea", { className: "w-full border bg-inherit px-2 py-2 text-sm text-gray-500 dark:text-gray-300", value: description, onChange: e => setDescription(e.target.value) }), _jsx(Button, { className: "mt-4", onClick: e => {
|
|
110
52
|
e.preventDefault();
|
|
111
53
|
void handleSubmit();
|
|
112
|
-
}, disabled: loading || !isFormDataValid(), type: "submit"
|
|
54
|
+
}, disabled: loading || !isFormDataValid(), type: "submit", children: loading ? 'Sharing' : 'Share' }), error !== '' ? _jsx("p", { children: "Something went wrong please try again" }) : null] })) : (_jsxs(_Fragment, { children: [_jsx(ResultBox, { value: sharedLink, className: "mt-4" }), _jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Button, { variant: "neutral", className: "w-fit", onClick: onClose, children: "Close" }) })] }))] }) }));
|
|
113
55
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, __assign({ color: "neutral", onClick: function () { return setIsOpen(true); }, disabled: disabled }, { children: _jsx(Icon, { icon: "ei:share-apple", width: 20 }) })), _jsx(ProfileShareModal, { isOpen: isOpen, closeModal: function () { return setIsOpen(false); }, queryRequest: queryRequest, queryClient: queryClient })] }));
|
|
56
|
+
const ProfileShareButton = ({ queryRequest, queryClient, disabled = false }) => {
|
|
57
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
58
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { color: "neutral", onClick: () => setIsOpen(true), disabled: disabled, children: _jsx(Icon, { icon: "ei:share-apple", width: 20 }) }), _jsx(ProfileShareModal, { isOpen: isOpen, closeModal: () => setIsOpen(false), queryRequest: queryRequest, queryClient: queryClient })] }));
|
|
118
59
|
};
|
|
119
60
|
export default ProfileShareButton;
|
package/dist/useDelayedLoader.js
CHANGED
|
@@ -11,22 +11,21 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useEffect, useState } from 'react';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
var showLoaderTimeout;
|
|
14
|
+
const useDelayedLoader = (isLoading = false, options) => {
|
|
15
|
+
const { delay = 500 } = options ?? {};
|
|
16
|
+
const [isLoaderVisible, setIsLoaderVisible] = useState(false);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
let showLoaderTimeout;
|
|
20
19
|
if (isLoading && !isLoaderVisible) {
|
|
21
20
|
// if the request takes longer than half a second, show the loading icon
|
|
22
|
-
showLoaderTimeout = setTimeout(
|
|
21
|
+
showLoaderTimeout = setTimeout(() => {
|
|
23
22
|
setIsLoaderVisible(true);
|
|
24
23
|
}, delay);
|
|
25
24
|
}
|
|
26
25
|
else if (!isLoading && isLoaderVisible) {
|
|
27
26
|
setIsLoaderVisible(false);
|
|
28
27
|
}
|
|
29
|
-
return
|
|
28
|
+
return () => clearTimeout(showLoaderTimeout);
|
|
30
29
|
}, [isLoading, isLoaderVisible, delay]);
|
|
31
30
|
return isLoaderVisible;
|
|
32
31
|
};
|
|
@@ -10,55 +10,13 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
13
|
import { useQuery } from '@tanstack/react-query';
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
case 1: return [2 /*return*/, _a.sent()];
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}); }, {
|
|
60
|
-
enabled: enabled,
|
|
61
|
-
staleTime: staleTime,
|
|
14
|
+
const useGrpcQuery = ({ key, queryFn, options: { enabled = true, staleTime } = {}, }) => {
|
|
15
|
+
return useQuery(key, async () => {
|
|
16
|
+
return await queryFn();
|
|
17
|
+
}, {
|
|
18
|
+
enabled,
|
|
19
|
+
staleTime,
|
|
62
20
|
});
|
|
63
21
|
};
|
|
64
22
|
export default useGrpcQuery;
|