support oneof for array type

This commit is contained in:
codetypes committed 2025-04-13 20:19:47 +08:00
1 parent 826b69a587
commit de9c9a48c9
6 files changed
+76 -18

No files matched your search

+1 -1
View File
@@ -121,7 +121,7 @@
"node.name": "Node name", "node.name": "Node name",
"node.noNodeSelected": "No node selected", "node.noNodeSelected": "No node selected",
"node.notFound": "Node '{{name}}' not found", "node.notFound": "Node '{{name}}' not found",
"node.oneof.error": "Only one is allowed between input '{{input}}' and argument '{{arg}}({{desc}})'", "node.oneof.error": "Only one is allowed between input '{{input}}' and argument '{{desc}}({{arg}})'",
"node.oneof.inputNotfound": "Input '{{input}}' not found", "node.oneof.inputNotfound": "Input '{{input}}' not found",
"node.outputVariable": "Output variables", "node.outputVariable": "Output variables",
"node.pasteDataError": "Paste data error", "node.pasteDataError": "Paste data error",
+1 -1
View File
@@ -121,7 +121,7 @@
"node.name": "节点名称", "node.name": "节点名称",
"node.noNodeSelected": "未选择任务节点", "node.noNodeSelected": "未选择任务节点",
"node.notFound": "节点 “{{name}}” 不存在", "node.notFound": "节点 “{{name}}” 不存在",
"node.oneof.error": "输入项 “{{input}}” 和参数 “{{arg}}({{desc}})” 之中,只能选择设置其中之一", "node.oneof.error": "输入项 “{{input}}” 和参数 “{{desc}}({{arg}})” 之中,只能选择设置其中之一",
"node.oneof.inputNotfound": "输入项“{{input}}”不存在", "node.oneof.inputNotfound": "输入项“{{input}}”不存在",
"node.outputVariable": "输出变量", "node.outputVariable": "输出变量",
"node.pasteDataError": "粘贴数据出错", "node.pasteDataError": "粘贴数据出错",
+14
View File
@@ -416,5 +416,19 @@
} }
], ],
"desc": "等待" "desc": "等待"
},
{
"name": "TestOneof",
"desc": "测试oneof",
"type": "Action",
"input": ["选项?"],
"args": [
{
"name": "option",
"desc": "选项",
"type": "int[]?",
"oneof": "选项"
}
]
} }
] ]
+9
View File
@@ -104,6 +104,15 @@
"args": { "args": {
"builtin": "afterRunFailure" "builtin": "afterRunFailure"
} }
},
{
"id": "13",
"name": "TestOneof",
"input": [
"context"
],
"output": [],
"args": {}
} }
] ]
} }
+44 -14
View File
@@ -760,7 +760,7 @@ const NodeInspector: FC = () => {
} }
}); });
} }
data.args[arg.name] = arr; data.args[arg.name] = !isNodeArgOptional(arg) ? arr : arr.length ? arr : undefined;
} else if (isJsonType(type)) { } else if (isJsonType(type)) {
try { try {
data.args[arg.name] = value === "null" ? null : JSON.parse(value); data.args[arg.name] = value === "null" ? null : JSON.parse(value);
@@ -1070,7 +1070,7 @@ const NodeInspector: FC = () => {
setFieldValue(`input.${i}`, value); setFieldValue(`input.${i}`, value);
validateFields([argName]); validateFields([argName]);
} }
if (!checkOneof(getFieldValue(argName) ?? "", value)) { if (!checkOneof(arg, getFieldValue(argName), value)) {
return Promise.reject( return Promise.reject(
new Error( new Error(
t("node.oneof.error", { t("node.oneof.error", {
@@ -1116,8 +1116,45 @@ const NodeInspector: FC = () => {
const type = getNodeArgRawType(arg); const type = getNodeArgRawType(arg);
if (isNodeArgArray(arg)) { if (isNodeArgArray(arg)) {
return ( return (
<Form.Item key={`args.${arg.name}`}> <Form.List
<Form.List name={`args.${arg.name}`}> key={`args.${arg.name}`}
name={`args.${arg.name}`}
rules={[
{
validator(_, value: unknown[]) {
if (!arg.oneof) {
return Promise.resolve();
}
const idx = def.input?.findIndex(
(input) => input.replace("?", "") === arg.oneof
);
if (idx === undefined || idx < 0) {
return Promise.reject(
new Error(t("node.oneof.inputNotfound", { input: arg.oneof }))
);
}
const inputName = `input.${idx}`;
if (!form.isFieldValidating(inputName)) {
form.setFieldValue(`args.${arg.name}`, value);
form.validateFields([inputName]);
}
if (!checkOneof(arg, value, form.getFieldValue(inputName))) {
return Promise.reject(
new Error(
t("node.oneof.error", {
input: def.input![idx],
arg: arg.name,
desc: arg.desc ?? "",
})
)
);
} else {
return Promise.resolve();
}
},
},
]}
>
{(items, { add, remove }, { errors }) => ( {(items, { add, remove }, { errors }) => (
<div style={{ display: "flex", rowGap: 0, flexDirection: "column" }}> <div style={{ display: "flex", rowGap: 0, flexDirection: "column" }}>
{items.map((item, idx) => ( {items.map((item, idx) => (
@@ -1127,9 +1164,7 @@ const NodeInspector: FC = () => {
label={idx === 0 ? `${arg.desc}[${idx}]` : `[${idx}]`} label={idx === 0 ? `${arg.desc}[${idx}]` : `[${idx}]`}
validateTrigger={["onChange", "onBlur"]} validateTrigger={["onChange", "onBlur"]}
style={{ width: "100%", marginBottom: 5 }} style={{ width: "100%", marginBottom: 5 }}
initialValue={ initialValue={isBoolType(type) ? arg.default ?? false : arg.default}
isBoolType(type) ? arg.default ?? false : arg.default
}
valuePropName={isBoolType(type) ? "checked" : undefined} valuePropName={isBoolType(type) ? "checked" : undefined}
rules={[ rules={[
{ {
@@ -1155,11 +1190,7 @@ const NodeInspector: FC = () => {
<TextArea autoSize disabled={disabled} onBlur={submit} /> <TextArea autoSize disabled={disabled} onBlur={submit} />
)} )}
{!hasArgOptions(arg) && isIntType(type) && ( {!hasArgOptions(arg) && isIntType(type) && (
<InputNumber <InputNumber disabled={disabled} onBlur={submit} precision={0} />
disabled={disabled}
onBlur={submit}
precision={0}
/>
)} )}
{!hasArgOptions(arg) && isFloatType(type) && ( {!hasArgOptions(arg) && isFloatType(type) && (
<InputNumber disabled={disabled} onBlur={submit} /> <InputNumber disabled={disabled} onBlur={submit} />
@@ -1227,7 +1258,6 @@ const NodeInspector: FC = () => {
</div> </div>
)} )}
</Form.List> </Form.List>
</Form.Item>
); );
} else { } else {
return ( return (
@@ -1264,7 +1294,7 @@ const NodeInspector: FC = () => {
setFieldValue(`args.${arg.name}`, value); setFieldValue(`args.${arg.name}`, value);
validateFields([inputName]); validateFields([inputName]);
} }
if (!checkOneof(getFieldValue(inputName) ?? "", value)) { if (!checkOneof(arg, value, form.getFieldValue(inputName))) {
return Promise.reject( return Promise.reject(
new Error( new Error(
t("node.oneof.error", { t("node.oneof.error", {
+7 -2
View File
@@ -307,7 +307,7 @@ export const checkNodeArg = (data: NodeData, conf: NodeDef, i: number, verbose?:
} }
if (arg.oneof !== undefined) { if (arg.oneof !== undefined) {
const idx = conf.input?.findIndex((v) => v.startsWith(arg.oneof!)) ?? -1; const idx = conf.input?.findIndex((v) => v.startsWith(arg.oneof!)) ?? -1;
if (!checkOneof(data.args?.[arg.name], data.input?.[idx])) { if (!checkOneof(arg, data.args?.[arg.name], data.input?.[idx])) {
if (verbose) { if (verbose) {
error( error(
data, data,
@@ -321,7 +321,12 @@ export const checkNodeArg = (data: NodeData, conf: NodeDef, i: number, verbose?:
return !hasError; return !hasError;
}; };
export const checkOneof = (argValue: unknown, inputValue: unknown) => { export const checkOneof = (arg: NodeArg, argValue: unknown, inputValue: unknown) => {
if (isNodeArgArray(arg)) {
if (argValue instanceof Array && argValue.length === 0) {
argValue = undefined;
}
}
argValue = argValue === undefined ? "" : argValue; argValue = argValue === undefined ? "" : argValue;
inputValue = inputValue ?? ""; inputValue = inputValue ?? "";
return (argValue !== "" && inputValue === "") || (argValue === "" && inputValue !== ""); return (argValue !== "" && inputValue === "") || (argValue === "" && inputValue !== "");