@parca/profile 0.19.82 → 0.19.83
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 +6 -0
- package/dist/MatchersInput/index.d.ts +34 -2
- package/dist/MatchersInput/index.d.ts.map +1 -1
- package/dist/MatchersInput/index.js +91 -14
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts +29 -0
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.d.ts.map +1 -0
- package/dist/MetricsGraph/UtilizationMetrics/Throughput.js +175 -0
- package/dist/MetricsGraph/UtilizationMetrics/index.d.ts +28 -0
- package/dist/MetricsGraph/UtilizationMetrics/index.d.ts.map +1 -0
- package/dist/MetricsGraph/UtilizationMetrics/index.js +186 -0
- package/dist/MetricsGraph/index.d.ts.map +1 -1
- package/dist/MetricsGraph/index.js +1 -13
- package/dist/ProfileMetricsGraph/index.d.ts.map +1 -1
- package/dist/ProfileMetricsGraph/index.js +29 -6
- package/dist/ProfileSelector/MetricsGraphSection.d.ts +9 -2
- package/dist/ProfileSelector/MetricsGraphSection.d.ts.map +1 -1
- package/dist/ProfileSelector/MetricsGraphSection.js +38 -3
- package/dist/ProfileSelector/QueryControls.d.ts +43 -0
- package/dist/ProfileSelector/QueryControls.d.ts.map +1 -0
- package/dist/{QueryControls/index.js → ProfileSelector/QueryControls.js} +13 -16
- package/dist/ProfileSelector/index.d.ts +29 -1
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +9 -12
- package/dist/SimpleMatchers/Select.js +1 -1
- package/dist/SimpleMatchers/index.d.ts +11 -2
- package/dist/SimpleMatchers/index.d.ts.map +1 -1
- package/dist/SimpleMatchers/index.js +45 -34
- package/dist/ViewMatchers/index.d.ts +9 -0
- package/dist/ViewMatchers/index.d.ts.map +1 -1
- package/dist/ViewMatchers/index.js +12 -20
- package/dist/contexts/MatchersInputLabelsContext.d.ts +29 -0
- package/dist/contexts/MatchersInputLabelsContext.d.ts.map +1 -0
- package/dist/contexts/MatchersInputLabelsContext.js +79 -0
- package/dist/contexts/SimpleMatchersLabelContext.d.ts +25 -0
- package/dist/contexts/SimpleMatchersLabelContext.d.ts.map +1 -0
- package/dist/contexts/SimpleMatchersLabelContext.js +115 -0
- package/dist/contexts/UtilizationLabelsContext.d.ts +15 -0
- package/dist/contexts/UtilizationLabelsContext.d.ts.map +1 -0
- package/dist/contexts/UtilizationLabelsContext.js +25 -0
- package/dist/hooks/useQueryState.d.ts +0 -2
- package/dist/hooks/useQueryState.d.ts.map +1 -1
- package/dist/hooks/useQueryState.js +0 -18
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -9
- package/dist/styles.css +1 -1
- package/dist/useSumBy.js +1 -1
- package/package.json +2 -2
- package/src/MatchersInput/index.tsx +163 -17
- package/src/MetricsGraph/UtilizationMetrics/Throughput.tsx +405 -0
- package/src/MetricsGraph/UtilizationMetrics/index.tsx +426 -0
- package/src/MetricsGraph/index.tsx +1 -17
- package/src/ProfileMetricsGraph/index.tsx +98 -17
- package/src/ProfileSelector/MetricsGraphSection.tsx +115 -14
- package/src/{QueryControls/index.tsx → ProfileSelector/QueryControls.tsx} +84 -66
- package/src/ProfileSelector/index.tsx +109 -106
- package/src/SimpleMatchers/Select.tsx +1 -1
- package/src/SimpleMatchers/index.tsx +85 -46
- package/src/ViewMatchers/index.tsx +30 -22
- package/src/contexts/MatchersInputLabelsContext.tsx +141 -0
- package/src/contexts/SimpleMatchersLabelContext.tsx +189 -0
- package/src/contexts/UtilizationLabelsContext.tsx +45 -0
- package/src/hooks/useQueryState.ts +0 -25
- package/src/index.tsx +3 -29
- package/src/useSumBy.ts +1 -1
- package/dist/QueryControls/index.d.ts +0 -42
- package/dist/QueryControls/index.d.ts.map +0 -1
- package/dist/contexts/LabelsQueryProvider.d.ts +0 -35
- package/dist/contexts/LabelsQueryProvider.d.ts.map +0 -1
- package/dist/contexts/LabelsQueryProvider.js +0 -70
- package/dist/contexts/UnifiedLabelsContext.d.ts +0 -37
- package/dist/contexts/UnifiedLabelsContext.d.ts.map +0 -1
- package/dist/contexts/UnifiedLabelsContext.js +0 -88
- package/dist/contexts/utils.d.ts +0 -10
- package/dist/contexts/utils.d.ts.map +0 -1
- package/dist/contexts/utils.js +0 -31
- package/dist/hooks/useLabels.d.ts +0 -23
- package/dist/hooks/useLabels.d.ts.map +0 -1
- package/dist/hooks/useLabels.js +0 -75
- package/src/contexts/LabelsQueryProvider.tsx +0 -142
- package/src/contexts/UnifiedLabelsContext.tsx +0 -155
- package/src/contexts/utils.ts +0 -43
- package/src/hooks/useLabels.ts +0 -121
|
@@ -11,23 +11,31 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } 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, useEffect, useState } from 'react';
|
|
14
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
15
15
|
import { Icon } from '@iconify/react';
|
|
16
16
|
import { useQueryClient } from '@tanstack/react-query';
|
|
17
17
|
import cx from 'classnames';
|
|
18
|
-
import { useGrpcMetadata
|
|
18
|
+
import { useGrpcMetadata } from '@parca/components';
|
|
19
19
|
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
20
20
|
import { millisToProtoTimestamp, sanitizeLabelValue } from '@parca/utilities';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { useQueryState } from '../hooks/useQueryState';
|
|
21
|
+
import { LabelProvider, useLabels } from '../contexts/SimpleMatchersLabelContext';
|
|
22
|
+
import { useUtilizationLabels } from '../contexts/UtilizationLabelsContext';
|
|
24
23
|
import Select from './Select';
|
|
24
|
+
const trimOtelPrefix = (labelName) => {
|
|
25
|
+
if (labelName.startsWith('attributes_resource.')) {
|
|
26
|
+
return labelName.replace('attributes_resource.', '');
|
|
27
|
+
}
|
|
28
|
+
if (labelName.startsWith('attributes.')) {
|
|
29
|
+
return labelName.replace('attributes.', '');
|
|
30
|
+
}
|
|
31
|
+
return labelName;
|
|
32
|
+
};
|
|
25
33
|
export const transformLabelsForSelect = (labelNames) => {
|
|
26
34
|
return labelNames.map(labelName => ({
|
|
27
35
|
key: labelName,
|
|
28
36
|
element: {
|
|
29
|
-
active: _jsx(_Fragment, { children:
|
|
30
|
-
expanded: _jsx(_Fragment, { children:
|
|
37
|
+
active: _jsx(_Fragment, { children: trimOtelPrefix(labelName) }),
|
|
38
|
+
expanded: _jsx(_Fragment, { children: trimOtelPrefix(labelName) }),
|
|
31
39
|
},
|
|
32
40
|
}));
|
|
33
41
|
};
|
|
@@ -61,19 +69,15 @@ const operatorOptions = [
|
|
|
61
69
|
},
|
|
62
70
|
},
|
|
63
71
|
];
|
|
64
|
-
const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
72
|
+
const SimpleMatchers = ({ queryClient, setMatchersString, currentQuery, profileType, queryBrowserRef, start, end, searchExecutedTimestamp, }) => {
|
|
73
|
+
const utilizationLabels = useUtilizationLabels();
|
|
65
74
|
const [queryRows, setQueryRows] = useState([
|
|
66
75
|
{ labelName: '', operator: '=', labelValue: '', labelValues: [], isLoading: false },
|
|
67
76
|
]);
|
|
68
77
|
const reactQueryClient = useQueryClient();
|
|
69
78
|
const metadata = useGrpcMetadata();
|
|
70
|
-
const { queryServiceClient: parcaQueryClient } = useParcaContext();
|
|
71
79
|
const [showAll, setShowAll] = useState(false);
|
|
72
80
|
const [isActivelyEditing, setIsActivelyEditing] = useState(false);
|
|
73
|
-
const { labelNameMappingsForSimpleMatchers: labelNameOptions, isLabelNamesLoading: labelNamesLoading, refetchLabelNames, suffix, } = useUnifiedLabels();
|
|
74
|
-
const { draftSelection, setDraftMatchers, draftParsedQuery } = useQueryState({
|
|
75
|
-
suffix,
|
|
76
|
-
});
|
|
77
81
|
// Reset editing mode when search is executed
|
|
78
82
|
useEffect(() => {
|
|
79
83
|
if (searchExecutedTimestamp !== undefined && searchExecutedTimestamp > 0) {
|
|
@@ -84,20 +88,14 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
84
88
|
const visibleRows = showAll || isActivelyEditing ? queryRows : queryRows.slice(0, 3);
|
|
85
89
|
const hiddenRowsCount = queryRows.length - 3;
|
|
86
90
|
const maxWidthInPixels = `max-w-[${queryBrowserRef.current?.offsetWidth.toString()}px]`;
|
|
87
|
-
const currentMatchers =
|
|
88
|
-
const profileType = draftParsedQuery?.profileType().toString();
|
|
89
|
-
const start = draftSelection.from;
|
|
90
|
-
const end = draftSelection.to;
|
|
91
|
+
const currentMatchers = currentQuery.matchersString();
|
|
91
92
|
const fetchLabelValues = useCallback(async (labelName) => {
|
|
92
|
-
if (labelName == null || labelName === '') {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
if (profileType == null || profileType === '') {
|
|
93
|
+
if (labelName == null || labelName === '' || profileType == null || profileType === '') {
|
|
96
94
|
return [];
|
|
97
95
|
}
|
|
98
96
|
try {
|
|
99
97
|
const values = await reactQueryClient.fetchQuery([labelName, profileType, start, end], async () => {
|
|
100
|
-
const response = await
|
|
98
|
+
const response = await queryClient.values({
|
|
101
99
|
labelName,
|
|
102
100
|
match: [],
|
|
103
101
|
profileType,
|
|
@@ -118,14 +116,18 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
118
116
|
console.error('Error fetching label values:', error);
|
|
119
117
|
return [];
|
|
120
118
|
}
|
|
121
|
-
}, [
|
|
119
|
+
}, [queryClient, metadata, profileType, reactQueryClient, start, end]);
|
|
120
|
+
const fetchLabelValuesUtilization = useCallback(async (labelName) => {
|
|
121
|
+
return (await utilizationLabels?.utilizationFetchLabelValues?.(labelName)) ?? [];
|
|
122
|
+
}, [utilizationLabels]);
|
|
122
123
|
const updateMatchersString = useCallback((rows) => {
|
|
123
124
|
const matcherString = rows
|
|
124
125
|
.filter(row => row.labelName.length > 0 && row.labelValue)
|
|
125
126
|
.map(row => `${row.labelName}${row.operator}"${row.labelValue}"`)
|
|
126
127
|
.join(',');
|
|
127
|
-
|
|
128
|
-
}, [
|
|
128
|
+
setMatchersString(matcherString);
|
|
129
|
+
}, [setMatchersString]);
|
|
130
|
+
const { labelNameOptions, isLoading: labelNamesLoading, refetchLabelValues, refetchLabelNames, } = useLabels();
|
|
129
131
|
// Helper to ensure selected label name is in the options (for page load before API returns)
|
|
130
132
|
const getLabelNameOptionsWithSelected = useCallback((selectedLabelName) => {
|
|
131
133
|
if (selectedLabelName === '')
|
|
@@ -182,10 +184,14 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
182
184
|
}
|
|
183
185
|
}, [labelNameOptions]);
|
|
184
186
|
const fetchLabelValuesUnified = useCallback(async (labelName) => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
const labelType = labelNameOptions.find(option => option.values.some(e => e.key === labelName))?.type;
|
|
188
|
+
const labelValues = labelType === 'gpu'
|
|
189
|
+
? await fetchLabelValuesUtilization(labelName)
|
|
190
|
+
: await fetchLabelValues(labelName);
|
|
191
|
+
return labelValues;
|
|
192
|
+
}, [fetchLabelValues, fetchLabelValuesUtilization, labelNameOptions]);
|
|
187
193
|
useEffect(() => {
|
|
188
|
-
if (currentMatchers === ''
|
|
194
|
+
if (currentMatchers === '') {
|
|
189
195
|
const defaultRow = {
|
|
190
196
|
labelName: '',
|
|
191
197
|
operator: '=',
|
|
@@ -199,7 +205,7 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
199
205
|
let isCancelled = false;
|
|
200
206
|
const fetchAndSetQueryRows = async () => {
|
|
201
207
|
const newRows = await Promise.all(currentMatchers.split(',').map(async (matcher) => {
|
|
202
|
-
const match = matcher.match(
|
|
208
|
+
const match = matcher.match(/([^=!~]+)([=!~]{1,2})(.+)/);
|
|
203
209
|
if (match === null)
|
|
204
210
|
return null;
|
|
205
211
|
const [, labelName, operator, labelValue] = match;
|
|
@@ -308,14 +314,11 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
308
314
|
};
|
|
309
315
|
}, [queryRows, fetchLabelValuesUnified]);
|
|
310
316
|
const isRowRegex = (row) => row.operator === '=~' || row.operator === '!~';
|
|
311
|
-
const handleRefetchForLabelValues = useCallback(async (labelName) => {
|
|
312
|
-
await fetchLabelValuesUnified(labelName);
|
|
313
|
-
}, [fetchLabelValuesUnified]);
|
|
314
317
|
return (_jsxs("div", { className: `flex items-center gap-3 ${maxWidthInPixels} w-full flex-wrap`, id: "simple-matchers", ...testId(TEST_IDS.SIMPLE_MATCHERS_CONTAINER), children: [visibleRows.map((row, index) => (_jsxs("div", { className: "flex items-center", ...testId(TEST_IDS.SIMPLE_MATCHER_ROW), children: [_jsx(Select, { items: getLabelNameOptionsWithSelected(row.labelName), onSelection: value => handleUpdateRow(index, 'labelName', value), placeholder: "Select label name", selectedKey: row.labelName, className: "rounded-tr-none rounded-br-none ring-0 focus:ring-0 outline-none", loading: labelNamesLoading, searchable: true, ...testId(TEST_IDS.LABEL_NAME_SELECT), refetchValues: refetchLabelNames }), _jsx(Select, { items: operatorOptions, onSelection: value => handleUpdateRow(index, 'operator', value), selectedKey: row.operator, className: "rounded-none ring-0 focus:ring-0 outline-none", ...testId(TEST_IDS.OPERATOR_SELECT) }), _jsx(Select, { items: transformLabelsForSelect(row.labelValue !== '' && !row.labelValues.includes(row.labelValue)
|
|
315
318
|
? [...row.labelValues, row.labelValue]
|
|
316
319
|
: row.labelValues), onSelection: value => handleUpdateRow(index, 'labelValue', value), placeholder: "Select label value", selectedKey: row.labelValue, className: "rounded-none ring-0 focus:ring-0 outline-none max-w-48", optionsClassname: cx('max-w-[600px]', {
|
|
317
320
|
'w-[300px]': isRowRegex(row),
|
|
318
|
-
}), searchable: true, disabled: row.labelName === '', loading: row.isLoading, onButtonClick: () => handleLabelValueClick(index), editable: isRowRegex(row), ...testId(TEST_IDS.LABEL_VALUE_SELECT), refetchValues: async () => await
|
|
321
|
+
}), searchable: true, disabled: row.labelName === '', loading: row.isLoading, onButtonClick: () => handleLabelValueClick(index), editable: isRowRegex(row), ...testId(TEST_IDS.LABEL_VALUE_SELECT), refetchValues: async () => await refetchLabelValues(row.labelName), showLoadingInButton: true }), _jsx("button", { onClick: () => removeRow(index), className: cx('p-2 border-gray-200 border rounded rounded-tl-none rounded-bl-none focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:border-gray-600 dark:bg-gray-900'), ...testId(TEST_IDS.REMOVE_MATCHER_BUTTON), children: _jsx(Icon, { icon: "carbon:close", className: "h-5 w-5 text-gray-400", "aria-hidden": "true" }) })] }, index))), queryRows.length > 3 && !isActivelyEditing && (_jsx("button", { onClick: () => {
|
|
319
322
|
if (showAll) {
|
|
320
323
|
// Clicking "Show less" - collapse and stop editing mode
|
|
321
324
|
setShowAll(false);
|
|
@@ -327,4 +330,12 @@ const SimpleMatchers = ({ queryBrowserRef, searchExecutedTimestamp, }) => {
|
|
|
327
330
|
}
|
|
328
331
|
}, className: "mr-2 px-3 py-1 text-sm font-medium text-gray-700 dark:text-gray-200 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:bg-gray-900", ...testId(showAll ? TEST_IDS.SHOW_LESS_BUTTON : TEST_IDS.SHOW_MORE_BUTTON), children: showAll ? 'Show less' : `Show ${hiddenRowsCount} more` })), _jsx("button", { onClick: addNewRow, className: "p-2 border-gray-200 dark:bg-gray-900 dark:border-gray-600 border rounded focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500", ...testId(TEST_IDS.ADD_MATCHER_BUTTON), children: _jsx(Icon, { icon: "material-symbols:add", className: "h-5 w-5 text-gray-400", "aria-hidden": "true" }) })] }));
|
|
329
332
|
};
|
|
330
|
-
export default
|
|
333
|
+
export default function SimpleMathersWithProvider(props) {
|
|
334
|
+
const labelNameFromMatchers = useMemo(() => {
|
|
335
|
+
if (props.currentQuery === undefined)
|
|
336
|
+
return [];
|
|
337
|
+
const matchers = props.currentQuery.matchers;
|
|
338
|
+
return matchers.map(matcher => matcher.key);
|
|
339
|
+
}, [props.currentQuery]);
|
|
340
|
+
return (_jsx(LabelProvider, { queryClient: props.queryClient, profileType: props.profileType, labelNameFromMatchers: labelNameFromMatchers, start: props.start, end: props.end, children: _jsx(SimpleMatchers, { ...props }) }));
|
|
341
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { QueryServiceClient } from '@parca/client';
|
|
3
|
+
import { Query } from '@parca/parser';
|
|
2
4
|
interface Props {
|
|
3
5
|
labelNames: string[];
|
|
6
|
+
profileType: string;
|
|
7
|
+
runQuery: () => void;
|
|
8
|
+
currentQuery: Query;
|
|
9
|
+
queryClient: QueryServiceClient;
|
|
10
|
+
setMatchersString: (arg: string) => void;
|
|
11
|
+
start?: number;
|
|
12
|
+
end?: number;
|
|
4
13
|
}
|
|
5
14
|
declare const ViewMatchers: React.FC<Props>;
|
|
6
15
|
export default ViewMatchers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ViewMatchers/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ViewMatchers/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAKtE,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAMpC,UAAU,KAAK;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC;IACpB,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAyKjC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -14,23 +14,15 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
14
14
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
15
15
|
import { Icon } from '@iconify/react';
|
|
16
16
|
import cx from 'classnames';
|
|
17
|
-
import { useGrpcMetadata
|
|
17
|
+
import { useGrpcMetadata } from '@parca/components';
|
|
18
18
|
import { TEST_IDS, testId } from '@parca/test-utils';
|
|
19
19
|
import { millisToProtoTimestamp, sanitizeLabelValue } from '@parca/utilities';
|
|
20
20
|
import CustomSelect from '../SimpleMatchers/Select';
|
|
21
|
-
|
|
22
|
-
import { useQueryState } from '../hooks/useQueryState';
|
|
23
|
-
const ViewMatchers = ({ labelNames }) => {
|
|
21
|
+
const ViewMatchers = ({ labelNames, profileType, queryClient, runQuery, setMatchersString, start, end, currentQuery, }) => {
|
|
24
22
|
const [labelValuesMap, setLabelValuesMap] = useState({});
|
|
25
23
|
const [isLoading, setIsLoading] = useState({});
|
|
26
24
|
const metadata = useGrpcMetadata();
|
|
27
|
-
const
|
|
28
|
-
const { suffix } = useUnifiedLabels();
|
|
29
|
-
const { draftSelection, setDraftMatchers, commitDraft, draftParsedQuery } = useQueryState({ suffix });
|
|
30
|
-
const currentMatchers = draftParsedQuery?.matchersString();
|
|
31
|
-
const profileType = draftParsedQuery?.profileType().toString();
|
|
32
|
-
const start = draftSelection.from;
|
|
33
|
-
const end = draftSelection.to;
|
|
25
|
+
const currentMatchers = currentQuery.matchersString();
|
|
34
26
|
const parseCurrentMatchers = useCallback((matchersString) => {
|
|
35
27
|
const matches = matchersString.match(/(\w+)="([^"]+)"/g);
|
|
36
28
|
if (matches === null)
|
|
@@ -45,19 +37,19 @@ const ViewMatchers = ({ labelNames }) => {
|
|
|
45
37
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
46
38
|
{});
|
|
47
39
|
}, []);
|
|
48
|
-
const initialSelections = parseCurrentMatchers(currentMatchers
|
|
40
|
+
const initialSelections = parseCurrentMatchers(currentMatchers);
|
|
49
41
|
const selectionsRef = useRef(initialSelections);
|
|
50
|
-
const
|
|
42
|
+
const runQueryRef = useRef(runQuery);
|
|
51
43
|
const timeoutRef = useRef(null);
|
|
52
44
|
useEffect(() => {
|
|
53
|
-
|
|
54
|
-
}, [
|
|
45
|
+
runQueryRef.current = runQuery;
|
|
46
|
+
}, [runQuery]);
|
|
55
47
|
useEffect(() => {
|
|
56
48
|
selectionsRef.current = initialSelections;
|
|
57
49
|
}, [initialSelections]);
|
|
58
50
|
const fetchLabelValues = useCallback(async (labelName) => {
|
|
59
51
|
try {
|
|
60
|
-
const response = await
|
|
52
|
+
const response = await queryClient.values({
|
|
61
53
|
labelName,
|
|
62
54
|
match: [],
|
|
63
55
|
profileType,
|
|
@@ -74,7 +66,7 @@ const ViewMatchers = ({ labelNames }) => {
|
|
|
74
66
|
console.error('Error fetching label values:', error);
|
|
75
67
|
return [];
|
|
76
68
|
}
|
|
77
|
-
}, [
|
|
69
|
+
}, [queryClient, metadata, profileType, start, end]);
|
|
78
70
|
const fetchAllLabelValues = useCallback(async () => {
|
|
79
71
|
const newLabelValuesMap = {};
|
|
80
72
|
const newIsLoading = {};
|
|
@@ -96,14 +88,14 @@ const ViewMatchers = ({ labelNames }) => {
|
|
|
96
88
|
.filter(([_, v]) => v !== null && v !== '')
|
|
97
89
|
.map(([ln, v]) => `${ln}="${v}"`);
|
|
98
90
|
const matcherString = matcherParts.join(',');
|
|
99
|
-
|
|
91
|
+
setMatchersString(matcherString);
|
|
100
92
|
if (timeoutRef.current !== null) {
|
|
101
93
|
clearTimeout(timeoutRef.current);
|
|
102
94
|
}
|
|
103
95
|
timeoutRef.current = setTimeout(() => {
|
|
104
|
-
|
|
96
|
+
runQueryRef.current();
|
|
105
97
|
}, 300);
|
|
106
|
-
}, [
|
|
98
|
+
}, [setMatchersString]);
|
|
107
99
|
const handleSelection = useCallback((labelName, value) => {
|
|
108
100
|
selectionsRef.current = {
|
|
109
101
|
...selectionsRef.current,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { QueryServiceClient } from '@parca/client';
|
|
3
|
+
interface LabelNameMapping {
|
|
4
|
+
displayName: string;
|
|
5
|
+
fullName: string;
|
|
6
|
+
}
|
|
7
|
+
interface LabelsContextType {
|
|
8
|
+
labelNames: string[];
|
|
9
|
+
labelValues: string[];
|
|
10
|
+
labelNameMappings: LabelNameMapping[];
|
|
11
|
+
isLabelNamesLoading: boolean;
|
|
12
|
+
isLabelValuesLoading: boolean;
|
|
13
|
+
currentLabelName: string | null;
|
|
14
|
+
setCurrentLabelName: (name: string | null) => void;
|
|
15
|
+
shouldHandlePrefixes: boolean;
|
|
16
|
+
refetchLabelValues: () => Promise<void>;
|
|
17
|
+
refetchLabelNames: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
interface LabelsProviderProps {
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
queryClient: QueryServiceClient;
|
|
22
|
+
profileType: string;
|
|
23
|
+
start?: number;
|
|
24
|
+
end?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function LabelsProvider({ children, queryClient, profileType, start, end, }: LabelsProviderProps): JSX.Element;
|
|
27
|
+
export declare function useLabels(): LabelsContextType;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=MatchersInputLabelsContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatchersInputLabelsContext.d.ts","sourceRoot":"","sources":["../../src/contexts/MatchersInputLabelsContext.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAKjD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAID,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,WAAW,EACX,WAAW,EACX,KAAK,EACL,GAAG,GACJ,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA4EnC;AAED,wBAAgB,SAAS,IAAI,iBAAiB,CAM7C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2022 The Parca Authors
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
15
|
+
import { useFetchUtilizationLabelValues, useLabelNames, useLabelValues } from '../MatchersInput';
|
|
16
|
+
import { useUtilizationLabels } from './UtilizationLabelsContext';
|
|
17
|
+
const LabelsContext = createContext(null);
|
|
18
|
+
// With there being the possibility of having utilization labels, we need to be able to determine whether the labels to be used are utilization labels or profiling data labels.
|
|
19
|
+
// This context is used to determine this.
|
|
20
|
+
export function LabelsProvider({ children, queryClient, profileType, start, end, }) {
|
|
21
|
+
const [currentLabelName, setCurrentLabelName] = React.useState(null);
|
|
22
|
+
const utilizationLabels = useUtilizationLabels();
|
|
23
|
+
const { result: labelNamesResponse, loading: isLabelNamesLoading, refetch: refetchLabelNames, } = useLabelNames(queryClient, profileType, start, end);
|
|
24
|
+
const labelNamesFromAPI = useMemo(() => {
|
|
25
|
+
return (labelNamesResponse.error === undefined || labelNamesResponse.error == null) &&
|
|
26
|
+
labelNamesResponse !== undefined &&
|
|
27
|
+
labelNamesResponse != null
|
|
28
|
+
? labelNamesResponse.response?.labelNames.filter(e => e !== '__name__') ?? []
|
|
29
|
+
: [];
|
|
30
|
+
}, [labelNamesResponse]);
|
|
31
|
+
const { result: labelValuesOriginal, loading: isLabelValuesLoading, refetch: refetchLabelValues, } = useLabelValues(queryClient, currentLabelName ?? '', profileType, start, end);
|
|
32
|
+
const utilizationLabelValues = useFetchUtilizationLabelValues(currentLabelName ?? '', utilizationLabels);
|
|
33
|
+
const shouldHandlePrefixes = utilizationLabels?.utilizationLabelNames !== undefined;
|
|
34
|
+
const labelNameMappings = useMemo(() => {
|
|
35
|
+
const names = utilizationLabels?.utilizationLabelNames ?? labelNamesFromAPI;
|
|
36
|
+
return names.map(name => ({
|
|
37
|
+
displayName: name.replace(/^(attributes\.|attributes_resource\.)/, ''),
|
|
38
|
+
fullName: name,
|
|
39
|
+
}));
|
|
40
|
+
}, [labelNamesFromAPI, utilizationLabels?.utilizationLabelNames]);
|
|
41
|
+
const labelNames = useMemo(() => {
|
|
42
|
+
return shouldHandlePrefixes ? labelNameMappings.map(m => m.displayName) : labelNamesFromAPI;
|
|
43
|
+
}, [labelNameMappings, labelNamesFromAPI, shouldHandlePrefixes]);
|
|
44
|
+
const labelValues = useMemo(() => {
|
|
45
|
+
return utilizationLabels?.utilizationFetchLabelValues !== undefined
|
|
46
|
+
? utilizationLabelValues
|
|
47
|
+
: labelValuesOriginal.response;
|
|
48
|
+
}, [labelValuesOriginal, utilizationLabelValues, utilizationLabels]);
|
|
49
|
+
const value = useMemo(() => ({
|
|
50
|
+
labelNames,
|
|
51
|
+
labelValues,
|
|
52
|
+
labelNameMappings,
|
|
53
|
+
isLabelNamesLoading,
|
|
54
|
+
isLabelValuesLoading,
|
|
55
|
+
currentLabelName,
|
|
56
|
+
setCurrentLabelName,
|
|
57
|
+
shouldHandlePrefixes,
|
|
58
|
+
refetchLabelValues,
|
|
59
|
+
refetchLabelNames,
|
|
60
|
+
}), [
|
|
61
|
+
labelNames,
|
|
62
|
+
labelValues,
|
|
63
|
+
labelNameMappings,
|
|
64
|
+
isLabelNamesLoading,
|
|
65
|
+
isLabelValuesLoading,
|
|
66
|
+
currentLabelName,
|
|
67
|
+
shouldHandlePrefixes,
|
|
68
|
+
refetchLabelValues,
|
|
69
|
+
refetchLabelNames,
|
|
70
|
+
]);
|
|
71
|
+
return _jsx(LabelsContext.Provider, { value: value, children: children });
|
|
72
|
+
}
|
|
73
|
+
export function useLabels() {
|
|
74
|
+
const context = useContext(LabelsContext);
|
|
75
|
+
if (context === null) {
|
|
76
|
+
throw new Error('useLabels must be used within a LabelsProvider');
|
|
77
|
+
}
|
|
78
|
+
return context;
|
|
79
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { QueryServiceClient } from '@parca/client';
|
|
2
|
+
import type { SelectItem } from '../SimpleMatchers/Select';
|
|
3
|
+
interface LabelNameSection {
|
|
4
|
+
type: string;
|
|
5
|
+
values: SelectItem[];
|
|
6
|
+
}
|
|
7
|
+
interface LabelContextValue {
|
|
8
|
+
labelNameOptions: LabelNameSection[];
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
refetchLabelValues: (labelName?: string) => Promise<void>;
|
|
12
|
+
refetchLabelNames: () => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
interface LabelProviderProps {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
queryClient: QueryServiceClient;
|
|
17
|
+
profileType: string;
|
|
18
|
+
labelNameFromMatchers: string[];
|
|
19
|
+
start?: number;
|
|
20
|
+
end?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function LabelProvider({ children, queryClient, profileType, labelNameFromMatchers, start, end, }: LabelProviderProps): JSX.Element;
|
|
23
|
+
export declare function useLabels(): LabelContextValue;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=SimpleMatchersLabelContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimpleMatchersLabelContext.d.ts","sourceRoot":"","sources":["../../src/contexts/SimpleMatchersLabelContext.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAGzD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,UAAU,iBAAiB;IACzB,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,kBAAkB,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAID,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,KAAK,EACL,GAAG,GACJ,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,CA0HlC;AAED,wBAAgB,SAAS,IAAI,iBAAiB,CAM7C"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2022 The Parca Authors
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { createContext, useCallback, useContext, useMemo } from 'react';
|
|
15
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
16
|
+
import { useLabelNames } from '../MatchersInput';
|
|
17
|
+
import { transformLabelsForSelect } from '../SimpleMatchers';
|
|
18
|
+
import { useUtilizationLabels } from './UtilizationLabelsContext';
|
|
19
|
+
const LabelContext = createContext(null);
|
|
20
|
+
// With there being the possibility of having utilization labels, we need to be able to determine whether the labels to be used are utilization labels or profiling data labels.
|
|
21
|
+
// This context is used to determine this.
|
|
22
|
+
export function LabelProvider({ children, queryClient, profileType, labelNameFromMatchers, start, end, }) {
|
|
23
|
+
const reactQueryClient = useQueryClient();
|
|
24
|
+
const utilizationLabelResponse = useUtilizationLabels();
|
|
25
|
+
const { loading, result, refetch: refetchLabelNamesQuery, } = useLabelNames(queryClient, profileType, start, end);
|
|
26
|
+
const profileValues = useMemo(() => {
|
|
27
|
+
const profileLabelNames = result.error != null ? [] : result.response?.labelNames.filter(e => e !== '__name__') ?? [];
|
|
28
|
+
const uniqueProfileLabelNames = Array.from(new Set(profileLabelNames));
|
|
29
|
+
return {
|
|
30
|
+
labelNameOptions: uniqueProfileLabelNames,
|
|
31
|
+
isLoading: loading,
|
|
32
|
+
error: result.error ?? null,
|
|
33
|
+
};
|
|
34
|
+
}, [result, loading]);
|
|
35
|
+
const utilizationValues = useMemo(() => {
|
|
36
|
+
if (utilizationLabelResponse?.utilizationLabelNamesLoading === true) {
|
|
37
|
+
return { labelNameOptions: [], isLoading: true };
|
|
38
|
+
}
|
|
39
|
+
if (utilizationLabelResponse == null ||
|
|
40
|
+
utilizationLabelResponse.utilizationLabelNames == null) {
|
|
41
|
+
return { labelNameOptions: [], isLoading: false };
|
|
42
|
+
}
|
|
43
|
+
const uniqueUtilizationLabelNames = Array.from(new Set(utilizationLabelResponse.utilizationLabelNames));
|
|
44
|
+
return {
|
|
45
|
+
labelNameOptions: uniqueUtilizationLabelNames,
|
|
46
|
+
isLoading: utilizationLabelResponse.utilizationLabelNamesLoading,
|
|
47
|
+
};
|
|
48
|
+
}, [utilizationLabelResponse]);
|
|
49
|
+
const value = useMemo(() => {
|
|
50
|
+
if (profileValues.error != null ||
|
|
51
|
+
profileValues.isLoading ||
|
|
52
|
+
utilizationValues.isLoading === true) {
|
|
53
|
+
return {
|
|
54
|
+
labelNameOptions: [],
|
|
55
|
+
isLoading: (profileValues.isLoading || utilizationValues.isLoading) ?? false,
|
|
56
|
+
error: profileValues.error,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
let nonMatchingLabels = labelNameFromMatchers.filter(label => !utilizationValues.labelNameOptions.includes(label));
|
|
60
|
+
nonMatchingLabels = nonMatchingLabels.filter(label => !profileValues.labelNameOptions.includes(label));
|
|
61
|
+
const nonMatchingLabelsSet = Array.from(new Set(nonMatchingLabels));
|
|
62
|
+
const options = [
|
|
63
|
+
{
|
|
64
|
+
type: 'cpu',
|
|
65
|
+
values: transformLabelsForSelect(profileValues.labelNameOptions),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'gpu',
|
|
69
|
+
values: transformLabelsForSelect(utilizationValues.labelNameOptions),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
type: '',
|
|
73
|
+
values: transformLabelsForSelect(nonMatchingLabelsSet),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
return {
|
|
77
|
+
labelNameOptions: options.filter(e => e.values.length > 0),
|
|
78
|
+
isLoading: false,
|
|
79
|
+
error: null,
|
|
80
|
+
};
|
|
81
|
+
}, [profileValues, utilizationValues, labelNameFromMatchers]);
|
|
82
|
+
const refetchLabelValues = useCallback(async (labelName) => {
|
|
83
|
+
await reactQueryClient.refetchQueries({
|
|
84
|
+
predicate: query => {
|
|
85
|
+
const key = query.queryKey;
|
|
86
|
+
const matchesStructure = Array.isArray(key) &&
|
|
87
|
+
key.length === 4 &&
|
|
88
|
+
typeof key[0] === 'string' &&
|
|
89
|
+
key[1] === profileType;
|
|
90
|
+
if (!matchesStructure)
|
|
91
|
+
return false;
|
|
92
|
+
if (labelName !== undefined && labelName !== '') {
|
|
93
|
+
return key[0] === labelName;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}, [reactQueryClient, profileType]);
|
|
99
|
+
const refetchLabelNames = useCallback(async () => {
|
|
100
|
+
await refetchLabelNamesQuery();
|
|
101
|
+
}, [refetchLabelNamesQuery]);
|
|
102
|
+
const contextValue = useMemo(() => ({
|
|
103
|
+
...value,
|
|
104
|
+
refetchLabelValues,
|
|
105
|
+
refetchLabelNames,
|
|
106
|
+
}), [value, refetchLabelValues, refetchLabelNames]);
|
|
107
|
+
return _jsx(LabelContext.Provider, { value: contextValue, children: children });
|
|
108
|
+
}
|
|
109
|
+
export function useLabels() {
|
|
110
|
+
const context = useContext(LabelContext);
|
|
111
|
+
if (context === null) {
|
|
112
|
+
throw new Error('useLabels must be used within a LabelProvider');
|
|
113
|
+
}
|
|
114
|
+
return context;
|
|
115
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface UtilizationLabels {
|
|
3
|
+
utilizationLabelNames?: string[];
|
|
4
|
+
utilizationFetchLabelValues?: (key: string) => Promise<string[]>;
|
|
5
|
+
utilizationLabelValues?: string[];
|
|
6
|
+
utilizationLabelNamesLoading?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface UtilizationLabelsProviderProps {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
value: UtilizationLabels | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function UtilizationLabelsProvider({ children, value, }: UtilizationLabelsProviderProps): JSX.Element;
|
|
13
|
+
export declare function useUtilizationLabels(): UtilizationLabels | undefined;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=UtilizationLabelsContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UtilizationLabelsContext.d.ts","sourceRoot":"","sources":["../../src/contexts/UtilizationLabelsContext.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,SAAS,EAA4B,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,2BAA2B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,UAAU,8BAA8B;IACtC,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACtC;AAOD,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,KAAK,GACN,EAAE,8BAA8B,GAAG,GAAG,CAAC,OAAO,CAI9C;AAED,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,SAAS,CAGpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2022 The Parca Authors
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { createContext, useContext } from 'react';
|
|
15
|
+
// The UtilizationLabelsContext is used to store the utilization label names and values. It also
|
|
16
|
+
// contains the function utilizationFetchLabelValues to fetch the utilization label values.
|
|
17
|
+
// This context was created so as to avoid props drilling.
|
|
18
|
+
const UtilizationLabelsContext = createContext(undefined);
|
|
19
|
+
export function UtilizationLabelsProvider({ children, value, }) {
|
|
20
|
+
return (_jsx(UtilizationLabelsContext.Provider, { value: value, children: children }));
|
|
21
|
+
}
|
|
22
|
+
export function useUtilizationLabels() {
|
|
23
|
+
const context = useContext(UtilizationLabelsContext);
|
|
24
|
+
return context;
|
|
25
|
+
}
|
|
@@ -26,8 +26,6 @@ interface UseQueryStateReturn {
|
|
|
26
26
|
profileSource: ProfileSource | null;
|
|
27
27
|
setProfileSelection: (mergeFrom: bigint, mergeTo: bigint, query: Query) => void;
|
|
28
28
|
sumByLoading: boolean;
|
|
29
|
-
draftParsedQuery: Query | null;
|
|
30
|
-
parsedQuery: Query | null;
|
|
31
29
|
}
|
|
32
30
|
export declare const useQueryState: (options?: UseQueryStateOptions) => UseQueryStateReturn;
|
|
33
31
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryState.d.ts","sourceRoot":"","sources":["../../src/hooks/useQueryState.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAC,gBAAgB,EAA8B,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAI7F,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,mBAAmB;IAE3B,cAAc,EAAE,cAAc,CAAC;IAG/B,cAAc,EAAE,cAAc,CAAC;IAG/B,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnE,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAG7C,WAAW,EAAE,CAAC,kBAAkB,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CAAC;IAG9F,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAG1C,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAGpC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAGhF,YAAY,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useQueryState.d.ts","sourceRoot":"","sources":["../../src/hooks/useQueryState.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAC,gBAAgB,EAA8B,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAI7F,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,mBAAmB;IAE3B,cAAc,EAAE,cAAc,CAAC;IAG/B,cAAc,EAAE,cAAc,CAAC;IAG/B,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnE,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAG7C,WAAW,EAAE,CAAC,kBAAkB,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CAAC;IAG9F,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAG1C,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAGpC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAGhF,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,GAAI,UAAS,oBAAyB,KAAG,mBAmWlE,CAAC"}
|
|
@@ -267,22 +267,6 @@ export const useQueryState = (options = {}) => {
|
|
|
267
267
|
setMergeToState(mergeTo.toString());
|
|
268
268
|
});
|
|
269
269
|
}, [batchUpdates, setSelectionParam, setMergeFromState, setMergeToState]);
|
|
270
|
-
const draftParsedQuery = useMemo(() => {
|
|
271
|
-
try {
|
|
272
|
-
return Query.parse(draftSelection.expression ?? '');
|
|
273
|
-
}
|
|
274
|
-
catch {
|
|
275
|
-
return Query.parse('');
|
|
276
|
-
}
|
|
277
|
-
}, [draftSelection.expression]);
|
|
278
|
-
const parsedQuery = useMemo(() => {
|
|
279
|
-
try {
|
|
280
|
-
return Query.parse(querySelection.expression ?? '');
|
|
281
|
-
}
|
|
282
|
-
catch {
|
|
283
|
-
return Query.parse('');
|
|
284
|
-
}
|
|
285
|
-
}, [querySelection.expression]);
|
|
286
270
|
return {
|
|
287
271
|
// Current committed state
|
|
288
272
|
querySelection,
|
|
@@ -302,7 +286,5 @@ export const useQueryState = (options = {}) => {
|
|
|
302
286
|
setProfileSelection,
|
|
303
287
|
// Loading state
|
|
304
288
|
sumByLoading: sumBySelectionLoading,
|
|
305
|
-
draftParsedQuery,
|
|
306
|
-
parsedQuery,
|
|
307
289
|
};
|
|
308
290
|
};
|