Extract model output dropdown to its own component (#2839)
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
VSCodeProgressRing,
|
||||
} from "@vscode/webview-ui-toolkit/react";
|
||||
import * as React from "react";
|
||||
import { ChangeEvent, useCallback, useMemo } from "react";
|
||||
import { useCallback } from "react";
|
||||
import { styled } from "styled-components";
|
||||
import { vscode } from "../vscode-api";
|
||||
|
||||
@@ -14,7 +14,6 @@ import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||
import { KindInput } from "./KindInput";
|
||||
import { extensiblePredicateDefinitions } from "../../model-editor/predicates";
|
||||
import { Mode } from "../../model-editor/shared/mode";
|
||||
import { Dropdown } from "../common/Dropdown";
|
||||
import { MethodClassifications } from "./MethodClassifications";
|
||||
import {
|
||||
ModelingStatus,
|
||||
@@ -24,6 +23,7 @@ import { InProgressDropdown } from "./InProgressDropdown";
|
||||
import { MethodName } from "./MethodName";
|
||||
import { ModelTypeDropdown } from "./ModelTypeDropdown";
|
||||
import { ModelInputDropdown } from "./ModelInputDropdown";
|
||||
import { ModelOutputDropdown } from "./ModelOutputDropdown";
|
||||
|
||||
const ApiOrMethodCell = styled(VSCodeDataGridCell)`
|
||||
display: flex;
|
||||
@@ -73,30 +73,6 @@ export const MethodRow = (props: MethodRowProps) => {
|
||||
function ModelableMethodRow(props: MethodRowProps) {
|
||||
const { method, modeledMethod, methodIsUnsaved, mode, onChange } = props;
|
||||
|
||||
const argumentsList = useMemo(() => {
|
||||
if (method.methodParameters === "()") {
|
||||
return [];
|
||||
}
|
||||
return method.methodParameters
|
||||
.substring(1, method.methodParameters.length - 1)
|
||||
.split(",");
|
||||
}, [method.methodParameters]);
|
||||
|
||||
const handleOutputInput = useCallback(
|
||||
(e: ChangeEvent<HTMLSelectElement>) => {
|
||||
if (!modeledMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = e.target as HTMLSelectElement;
|
||||
|
||||
onChange(method, {
|
||||
...modeledMethod,
|
||||
output: target.value,
|
||||
});
|
||||
},
|
||||
[onChange, method, modeledMethod],
|
||||
);
|
||||
const handleKindChange = useCallback(
|
||||
(kind: string) => {
|
||||
if (!modeledMethod) {
|
||||
@@ -116,20 +92,6 @@ function ModelableMethodRow(props: MethodRowProps) {
|
||||
[method],
|
||||
);
|
||||
|
||||
const outputOptions = useMemo(
|
||||
() => [
|
||||
{ value: "ReturnValue", label: "ReturnValue" },
|
||||
{ value: "Argument[this]", label: "Argument[this]" },
|
||||
...argumentsList.map((argument, index) => ({
|
||||
value: `Argument[${index}]`,
|
||||
label: `Argument[${index}]: ${argument}`,
|
||||
})),
|
||||
],
|
||||
[argumentsList],
|
||||
);
|
||||
|
||||
const showOutputCell =
|
||||
modeledMethod?.type && ["source", "summary"].includes(modeledMethod?.type);
|
||||
const predicate =
|
||||
modeledMethod?.type && modeledMethod.type !== "none"
|
||||
? extensiblePredicateDefinitions[modeledMethod.type]
|
||||
@@ -185,12 +147,10 @@ function ModelableMethodRow(props: MethodRowProps) {
|
||||
/>
|
||||
</VSCodeDataGridCell>
|
||||
<VSCodeDataGridCell gridColumn={4}>
|
||||
<Dropdown
|
||||
value={modeledMethod?.output}
|
||||
options={outputOptions}
|
||||
disabled={!showOutputCell}
|
||||
onChange={handleOutputInput}
|
||||
aria-label="Output"
|
||||
<ModelOutputDropdown
|
||||
method={method}
|
||||
modeledMethod={modeledMethod}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</VSCodeDataGridCell>
|
||||
<VSCodeDataGridCell gridColumn={5}>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import * as React from "react";
|
||||
import { ChangeEvent, useCallback, useMemo } from "react";
|
||||
import { Dropdown } from "../common/Dropdown";
|
||||
import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||
import { Method, getArgumentsList } from "../../model-editor/method";
|
||||
|
||||
type Props = {
|
||||
method: Method;
|
||||
modeledMethod: ModeledMethod | undefined;
|
||||
onChange: (method: Method, modeledMethod: ModeledMethod) => void;
|
||||
};
|
||||
|
||||
export const ModelOutputDropdown = ({
|
||||
method,
|
||||
modeledMethod,
|
||||
onChange,
|
||||
}: Props): JSX.Element => {
|
||||
const argumentsList = useMemo(
|
||||
() => getArgumentsList(method.methodParameters),
|
||||
[method.methodParameters],
|
||||
);
|
||||
|
||||
const options = useMemo(
|
||||
() => [
|
||||
{ value: "ReturnValue", label: "ReturnValue" },
|
||||
{ value: "Argument[this]", label: "Argument[this]" },
|
||||
...argumentsList.map((argument, index) => ({
|
||||
value: `Argument[${index}]`,
|
||||
label: `Argument[${index}]: ${argument}`,
|
||||
})),
|
||||
],
|
||||
[argumentsList],
|
||||
);
|
||||
|
||||
const enabled = useMemo(
|
||||
() =>
|
||||
modeledMethod?.type &&
|
||||
["source", "summary"].includes(modeledMethod?.type),
|
||||
[modeledMethod?.type],
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(e: ChangeEvent<HTMLSelectElement>) => {
|
||||
if (!modeledMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = e.target as HTMLSelectElement;
|
||||
|
||||
onChange(method, {
|
||||
...modeledMethod,
|
||||
output: target.value,
|
||||
});
|
||||
},
|
||||
[onChange, method, modeledMethod],
|
||||
);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
value={modeledMethod?.output}
|
||||
options={options}
|
||||
disabled={!enabled}
|
||||
onChange={handleChange}
|
||||
aria-label="Output"
|
||||
/>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user