Skip to content

Commit 4e09640

Browse files
authored
Extract model output dropdown to its own component (#2839)
1 parent f99177a commit 4e09640

File tree

2 files changed

+73
-46
lines changed

2 files changed

+73
-46
lines changed

extensions/ql-vscode/src/view/model-editor/MethodRow.tsx

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
VSCodeProgressRing,
66
} from "@vscode/webview-ui-toolkit/react";
77
import * as React from "react";
8-
import { ChangeEvent, useCallback, useMemo } from "react";
8+
import { useCallback } from "react";
99
import { styled } from "styled-components";
1010
import { vscode } from "../vscode-api";
1111

@@ -14,7 +14,6 @@ import { ModeledMethod } from "../../model-editor/modeled-method";
1414
import { KindInput } from "./KindInput";
1515
import { extensiblePredicateDefinitions } from "../../model-editor/predicates";
1616
import { Mode } from "../../model-editor/shared/mode";
17-
import { Dropdown } from "../common/Dropdown";
1817
import { MethodClassifications } from "./MethodClassifications";
1918
import {
2019
ModelingStatus,
@@ -24,6 +23,7 @@ import { InProgressDropdown } from "./InProgressDropdown";
2423
import { MethodName } from "./MethodName";
2524
import { ModelTypeDropdown } from "./ModelTypeDropdown";
2625
import { ModelInputDropdown } from "./ModelInputDropdown";
26+
import { ModelOutputDropdown } from "./ModelOutputDropdown";
2727

2828
const ApiOrMethodCell = styled(VSCodeDataGridCell)`
2929
display: flex;
@@ -73,30 +73,6 @@ export const MethodRow = (props: MethodRowProps) => {
7373
function ModelableMethodRow(props: MethodRowProps) {
7474
const { method, modeledMethod, methodIsUnsaved, mode, onChange } = props;
7575

76-
const argumentsList = useMemo(() => {
77-
if (method.methodParameters === "()") {
78-
return [];
79-
}
80-
return method.methodParameters
81-
.substring(1, method.methodParameters.length - 1)
82-
.split(",");
83-
}, [method.methodParameters]);
84-
85-
const handleOutputInput = useCallback(
86-
(e: ChangeEvent<HTMLSelectElement>) => {
87-
if (!modeledMethod) {
88-
return;
89-
}
90-
91-
const target = e.target as HTMLSelectElement;
92-
93-
onChange(method, {
94-
...modeledMethod,
95-
output: target.value,
96-
});
97-
},
98-
[onChange, method, modeledMethod],
99-
);
10076
const handleKindChange = useCallback(
10177
(kind: string) => {
10278
if (!modeledMethod) {
@@ -116,20 +92,6 @@ function ModelableMethodRow(props: MethodRowProps) {
11692
[method],
11793
);
11894

119-
const outputOptions = useMemo(
120-
() => [
121-
{ value: "ReturnValue", label: "ReturnValue" },
122-
{ value: "Argument[this]", label: "Argument[this]" },
123-
...argumentsList.map((argument, index) => ({
124-
value: `Argument[${index}]`,
125-
label: `Argument[${index}]: ${argument}`,
126-
})),
127-
],
128-
[argumentsList],
129-
);
130-
131-
const showOutputCell =
132-
modeledMethod?.type && ["source", "summary"].includes(modeledMethod?.type);
13395
const predicate =
13496
modeledMethod?.type && modeledMethod.type !== "none"
13597
? extensiblePredicateDefinitions[modeledMethod.type]
@@ -185,12 +147,10 @@ function ModelableMethodRow(props: MethodRowProps) {
185147
/>
186148
</VSCodeDataGridCell>
187149
<VSCodeDataGridCell gridColumn={4}>
188-
<Dropdown
189-
value={modeledMethod?.output}
190-
options={outputOptions}
191-
disabled={!showOutputCell}
192-
onChange={handleOutputInput}
193-
aria-label="Output"
150+
<ModelOutputDropdown
151+
method={method}
152+
modeledMethod={modeledMethod}
153+
onChange={onChange}
194154
/>
195155
</VSCodeDataGridCell>
196156
<VSCodeDataGridCell gridColumn={5}>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import * as React from "react";
2+
import { ChangeEvent, useCallback, useMemo } from "react";
3+
import { Dropdown } from "../common/Dropdown";
4+
import { ModeledMethod } from "../../model-editor/modeled-method";
5+
import { Method, getArgumentsList } from "../../model-editor/method";
6+
7+
type Props = {
8+
method: Method;
9+
modeledMethod: ModeledMethod | undefined;
10+
onChange: (method: Method, modeledMethod: ModeledMethod) => void;
11+
};
12+
13+
export const ModelOutputDropdown = ({
14+
method,
15+
modeledMethod,
16+
onChange,
17+
}: Props): JSX.Element => {
18+
const argumentsList = useMemo(
19+
() => getArgumentsList(method.methodParameters),
20+
[method.methodParameters],
21+
);
22+
23+
const options = useMemo(
24+
() => [
25+
{ value: "ReturnValue", label: "ReturnValue" },
26+
{ value: "Argument[this]", label: "Argument[this]" },
27+
...argumentsList.map((argument, index) => ({
28+
value: `Argument[${index}]`,
29+
label: `Argument[${index}]: ${argument}`,
30+
})),
31+
],
32+
[argumentsList],
33+
);
34+
35+
const enabled = useMemo(
36+
() =>
37+
modeledMethod?.type &&
38+
["source", "summary"].includes(modeledMethod?.type),
39+
[modeledMethod?.type],
40+
);
41+
42+
const handleChange = useCallback(
43+
(e: ChangeEvent<HTMLSelectElement>) => {
44+
if (!modeledMethod) {
45+
return;
46+
}
47+
48+
const target = e.target as HTMLSelectElement;
49+
50+
onChange(method, {
51+
...modeledMethod,
52+
output: target.value,
53+
});
54+
},
55+
[onChange, method, modeledMethod],
56+
);
57+
58+
return (
59+
<Dropdown
60+
value={modeledMethod?.output}
61+
options={options}
62+
disabled={!enabled}
63+
onChange={handleChange}
64+
aria-label="Output"
65+
/>
66+
);
67+
};

0 commit comments

Comments
 (0)