Skip to content

Commit 4dcbafb

Browse files
authored
Revert "Refactor ProfileSelector and MetricsGraphSection components (#6025)" (#6072)
This reverts commit 7e22b1c.
1 parent c75b87f commit 4dcbafb

File tree

21 files changed

+1896
-822
lines changed

21 files changed

+1896
-822
lines changed

ui/packages/shared/profile/src/MatchersInput/index.tsx

Lines changed: 163 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,179 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
import React, {useMemo, useRef, useState} from 'react';
14+
import React, {useEffect, useMemo, useRef, useState} from 'react';
1515

16+
import {useQuery} from '@tanstack/react-query';
1617
import cx from 'classnames';
1718
import TextareaAutosize from 'react-textarea-autosize';
1819

20+
import {LabelsRequest, LabelsResponse, QueryServiceClient, ValuesRequest} from '@parca/client';
21+
import {useGrpcMetadata} from '@parca/components';
1922
import {Query} from '@parca/parser';
2023
import {TEST_IDS, testId} from '@parca/test-utils';
24+
import {millisToProtoTimestamp, sanitizeLabelValue} from '@parca/utilities';
2125

22-
import {useUnifiedLabels} from '../contexts/UnifiedLabelsContext';
23-
import {useQueryState} from '../hooks/useQueryState';
26+
import {UtilizationLabels} from '../ProfileSelector';
27+
import {LabelsProvider, useLabels} from '../contexts/MatchersInputLabelsContext';
28+
import useGrpcQuery from '../useGrpcQuery';
2429
import SuggestionsList, {Suggestion, Suggestions} from './SuggestionsList';
2530

26-
const MatchersInput = (): JSX.Element => {
31+
interface MatchersInputProps {
32+
queryClient: QueryServiceClient;
33+
setMatchersString: (arg: string) => void;
34+
runQuery: () => void;
35+
currentQuery: Query;
36+
profileType: string;
37+
start?: number;
38+
end?: number;
39+
}
40+
41+
export interface ILabelNamesResult {
42+
response?: LabelsResponse;
43+
error?: Error;
44+
}
45+
46+
interface UseLabelNames {
47+
result: ILabelNamesResult;
48+
loading: boolean;
49+
refetch: () => Promise<void>;
50+
}
51+
52+
export const useLabelNames = (
53+
client: QueryServiceClient,
54+
profileType: string,
55+
start?: number,
56+
end?: number,
57+
match?: string[]
58+
): UseLabelNames => {
59+
const metadata = useGrpcMetadata();
60+
61+
const {data, isLoading, error, refetch} = useGrpcQuery<LabelsResponse>({
62+
key: ['labelNames', profileType, match?.join(','), start, end],
63+
queryFn: async signal => {
64+
const request: LabelsRequest = {match: match !== undefined ? match : []};
65+
if (start !== undefined && end !== undefined) {
66+
request.start = millisToProtoTimestamp(start);
67+
request.end = millisToProtoTimestamp(end);
68+
}
69+
if (profileType !== undefined) {
70+
request.profileType = profileType;
71+
}
72+
const {response} = await client.labels(request, {meta: metadata, abort: signal});
73+
return response;
74+
},
75+
options: {
76+
enabled: profileType !== undefined && profileType !== '',
77+
keepPreviousData: false,
78+
},
79+
});
80+
81+
useEffect(() => {
82+
console.log('Label names query result:', {data, error, isLoading});
83+
}, [data, error, isLoading]);
84+
85+
return {
86+
result: {response: data, error: error as Error},
87+
loading: isLoading,
88+
refetch: async () => {
89+
await refetch();
90+
},
91+
};
92+
};
93+
94+
interface UseLabelValues {
95+
result: {
96+
response: string[];
97+
error?: Error;
98+
};
99+
loading: boolean;
100+
refetch: () => Promise<void>;
101+
}
102+
103+
export const useLabelValues = (
104+
client: QueryServiceClient,
105+
labelName: string,
106+
profileType: string,
107+
start?: number,
108+
end?: number
109+
): UseLabelValues => {
110+
const metadata = useGrpcMetadata();
111+
112+
const {data, isLoading, error, refetch} = useGrpcQuery<string[]>({
113+
key: ['labelValues', labelName, profileType, start, end],
114+
queryFn: async signal => {
115+
const request: ValuesRequest = {labelName, match: [], profileType};
116+
if (start !== undefined && end !== undefined) {
117+
request.start = millisToProtoTimestamp(start);
118+
request.end = millisToProtoTimestamp(end);
119+
}
120+
const {response} = await client.values(request, {meta: metadata, abort: signal});
121+
return sanitizeLabelValue(response.labelValues);
122+
},
123+
options: {
124+
enabled:
125+
profileType !== undefined &&
126+
profileType !== '' &&
127+
labelName !== undefined &&
128+
labelName !== '',
129+
keepPreviousData: false,
130+
},
131+
});
132+
133+
console.log('Label values query result:', {data, error, isLoading, labelName});
134+
135+
return {
136+
result: {response: data ?? [], error: error as Error},
137+
loading: isLoading,
138+
refetch: async () => {
139+
await refetch();
140+
},
141+
};
142+
};
143+
144+
export const useFetchUtilizationLabelValues = (
145+
labelName: string,
146+
utilizationLabels?: UtilizationLabels
147+
): string[] => {
148+
const {data} = useQuery({
149+
queryKey: ['utilizationLabelValues', labelName],
150+
queryFn: async () => {
151+
const result = await utilizationLabels?.utilizationFetchLabelValues?.(labelName);
152+
return result ?? [];
153+
},
154+
enabled: utilizationLabels?.utilizationFetchLabelValues != null && labelName !== '',
155+
});
156+
157+
return data ?? [];
158+
};
159+
160+
const MatchersInput = ({
161+
setMatchersString,
162+
runQuery,
163+
currentQuery,
164+
}: MatchersInputProps): JSX.Element => {
27165
const inputRef = useRef<HTMLTextAreaElement | null>(null);
28166
const [focusedInput, setFocusedInput] = useState(false);
29167
const [lastCompleted, setLastCompleted] = useState<Suggestion>(new Suggestion('', '', ''));
30168

31169
const {
32170
labelNames,
33171
labelValues,
34-
labelNameMappingsForMatchersInput: labelNameMappings,
172+
labelNameMappings,
35173
isLabelNamesLoading,
36174
isLabelValuesLoading,
37175
currentLabelName,
38176
setCurrentLabelName,
39177
shouldHandlePrefixes,
40178
refetchLabelValues,
41179
refetchLabelNames,
42-
suffix,
43-
} = useUnifiedLabels();
44-
45-
const {setDraftMatchers, commitDraft, draftParsedQuery} = useQueryState({suffix});
180+
} = useLabels();
46181

47-
const value = draftParsedQuery != null ? draftParsedQuery.matchersString() : '';
182+
const value = currentQuery.matchersString();
48183

49184
const suggestionSections = useMemo(() => {
50185
const suggestionSections = new Suggestions();
51-
Query.suggest(`${draftParsedQuery?.profileName() as string}{${value}`).forEach(function (s) {
186+
Query.suggest(`${currentQuery.profileName()}{${value}`).forEach(function (s) {
52187
// Skip suggestions that we just completed. This really only works,
53188
// because we know the language is not repetitive. For a language that
54189
// has a repeating word, this would not work.
@@ -121,7 +256,7 @@ const MatchersInput = (): JSX.Element => {
121256
});
122257
return suggestionSections;
123258
}, [
124-
draftParsedQuery,
259+
currentQuery,
125260
lastCompleted,
126261
labelNames,
127262
labelValues,
@@ -136,7 +271,7 @@ const MatchersInput = (): JSX.Element => {
136271

137272
const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {
138273
const newValue = e.target.value;
139-
setDraftMatchers(newValue);
274+
setMatchersString(newValue);
140275
resetLastCompleted();
141276
};
142277

@@ -159,7 +294,7 @@ const MatchersInput = (): JSX.Element => {
159294
const applySuggestion = (suggestion: Suggestion): void => {
160295
const newValue = complete(suggestion);
161296
setLastCompleted(suggestion);
162-
setDraftMatchers(newValue);
297+
setMatchersString(newValue);
163298
if (inputRef.current !== null) {
164299
inputRef.current.value = newValue;
165300
inputRef.current.focus();
@@ -174,7 +309,7 @@ const MatchersInput = (): JSX.Element => {
174309
setFocusedInput(false);
175310
};
176311

177-
const profileSelected = draftParsedQuery?.profileName() === '';
312+
const profileSelected = currentQuery.profileName() === '';
178313

179314
return (
180315
<div
@@ -210,7 +345,7 @@ const MatchersInput = (): JSX.Element => {
210345
suggestions={suggestionSections}
211346
applySuggestion={applySuggestion}
212347
inputRef={inputRef.current}
213-
runQuery={commitDraft}
348+
runQuery={runQuery}
214349
focusedInput={focusedInput}
215350
isLabelValuesLoading={
216351
isLabelValuesLoading && lastCompleted.type === 'literal' && lastCompleted.value !== ','
@@ -223,4 +358,15 @@ const MatchersInput = (): JSX.Element => {
223358
);
224359
};
225360

226-
export default MatchersInput;
361+
export default function MatchersInputWithProvider(props: MatchersInputProps): JSX.Element {
362+
return (
363+
<LabelsProvider
364+
queryClient={props.queryClient}
365+
profileType={props.profileType}
366+
start={props.start}
367+
end={props.end}
368+
>
369+
<MatchersInput {...props} />
370+
</LabelsProvider>
371+
);
372+
}

0 commit comments

Comments
 (0)