support check children limit

This commit is contained in:
codetypes committed 2024-07-19 00:06:29 +08:00
1 parent b4021e487c
commit e4f0686f2f
7 files changed
+84 -47

No files matched your search

+14
View File
@@ -403,6 +403,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
workspace.onEditingNode({
data: b3util.createNode(data, false),
editable: !isSubtreeNode(data),
limit_error: !b3util.checkChildrenLimit(data),
});
setItemState(editor.selectedId, "selected", true);
} else {
@@ -453,6 +454,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
selectNode(null);
curNodeData.children ||= [];
curNodeData.children.push(data);
refreshItem(curNodeData);
updateGrahp();
pushHistory();
onChange();
@@ -485,6 +487,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
const data = b3util.createTreeData(JSON.parse(str), editor.selectedId);
editor.autoId = b3util.refreshTreeDataId(data, editor.autoId);
parentData.children![idx] = data;
refreshItem(parentData);
updateGrahp();
} else {
editor.data = b3util.createTreeData(JSON.parse(str), editor.selectedId);
@@ -520,6 +523,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
};
curNodeData.children ||= [];
curNodeData.children.push(b3util.createTreeData(newNodeData, editor.selectedId));
refreshItem(curNodeData);
updateGrahp();
pushHistory();
onChange();
@@ -544,12 +548,17 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
const parentData = findParent(data)!;
parentData.children = parentData.children!.filter((e) => e.id != editor.selectedId);
refreshItem(parentData);
selectNode(null);
updateGrahp();
pushHistory();
onChange();
};
const refreshItem = (data: TreeGraphData) => {
editor.graph.findById(data.id)?.draw();
};
const useStackData = (data: NodeModel) => {
editor.data = b3util.createTreeData(data);
editor.autoId = b3util.refreshTreeDataId(editor.data);
@@ -844,6 +853,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
);
dstData.children ||= [];
dstData.children.push(newTreeData);
refreshItem(dstData);
srcNodeId = newTreeData.id;
} else if (exploreFile && exploreFile !== editor.path) {
const newTreeData: TreeGraphData = b3util.createTreeData(
@@ -856,6 +866,7 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
);
dstData.children ||= [];
dstData.children.push(newTreeData);
refreshItem(dstData);
srcNodeId = newTreeData.id;
editor.autoId = b3util.refreshTreeDataId(newTreeData, Number(srcNodeId));
}
@@ -916,6 +927,9 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
return;
}
refreshItem(srcParent);
refreshItem(dstData);
updateGrahp();
pushHistory();
onChange();
+40 -47
View File
@@ -1,7 +1,6 @@
import { EditNode, EditTree, useWorkspace } from "@/contexts/workspace-context";
import { NodeArgType, NodeModel, TreeGraphData, TreeModel } from "@/misc/b3type";
import { NodeArgType, NodeModel, TreeGraphData } from "@/misc/b3type";
import { Hotkey, isMacos } from "@/misc/keys";
import Path from "@/misc/path";
import { EditOutlined } from "@ant-design/icons";
import {
AutoComplete,
@@ -102,6 +101,11 @@ const NodeInspector: FC = () => {
form.setFieldValue("debug", data.debug);
form.setFieldValue("disabled", data.disabled);
form.setFieldValue("path", data.path);
if (def.children === undefined || def.children === -1) {
form.setFieldValue("children", t("node.children.unlimited"));
} else {
form.setFieldValue("children", def.children);
}
def.args?.forEach((v) => {
form.setFieldValue(`args.${v.name}`, data.args?.[v.name] ?? v.default);
});
@@ -241,22 +245,18 @@ const NodeInspector: FC = () => {
labelCol={{ span: "auto" }}
onFinish={finish}
>
<Form.Item
name="id"
label={
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.id")}</div>
}
>
<Form.Item name="id" label={t("node.id")}>
<Input disabled={true} />
</Form.Item>
<Form.Item
name="type"
label={
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.type")}</div>
}
>
<Form.Item name="type" label={t("node.type")}>
<Input disabled={true} />
</Form.Item>
<Form.Item name="children" label={t("node.children")}>
<Input
style={{ borderColor: editingNode.limit_error ? "red" : undefined }}
disabled={true}
/>
</Form.Item>
<Form.Item label={t("node.name")} name="name">
<AutoComplete
disabled={disabled}
@@ -418,22 +418,27 @@ const NodeDefInspector: FC = () => {
};
const { t } = useTranslation();
const [form] = Form.useForm();
const data = workspace.editingNodeDef.data;
const def = workspace.editingNodeDef.data;
// set form values
useEffect(() => {
form.resetFields();
form.setFieldValue("name", data.name);
form.setFieldValue("type", data.type);
form.setFieldValue("desc", data.desc);
form.setFieldValue("doc", data.doc);
data.input?.forEach((v, i) => {
form.setFieldValue("name", def.name);
form.setFieldValue("type", def.type);
form.setFieldValue("desc", def.desc);
form.setFieldValue("doc", def.doc);
if (def.children === undefined || def.children === -1) {
form.setFieldValue("children", t("node.children.unlimited"));
} else {
form.setFieldValue("children", def.children);
}
def.input?.forEach((v, i) => {
form.setFieldValue(`input.${i}.name`, v.replaceAll("?", ""));
});
data.output?.forEach((v, i) => {
def.output?.forEach((v, i) => {
form.setFieldValue(`output.${i}.name`, v.replaceAll("?", ""));
});
data.args?.forEach((v, i) => {
def.args?.forEach((v, i) => {
form.setFieldValue(`args.${i}.type`, v.type.replaceAll("?", ""));
});
}, [workspace.editingNodeDef]);
@@ -452,37 +457,25 @@ const NodeDefInspector: FC = () => {
labelCol={{ span: "auto" }}
// onFinish={finish}
>
<Form.Item
name="name"
label={
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.name")}</div>
}
>
<Form.Item name="name" label={t("node.name")}>
<Input disabled={true} />
</Form.Item>
<Form.Item
name="type"
label={
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.type")}</div>
}
>
<Form.Item name="type" label={t("node.type")}>
<Input disabled={true} />
</Form.Item>
<Form.Item
name="desc"
label={
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.desc")}</div>
}
>
<Form.Item name="children" label={t("node.children")}>
<Input disabled={true} />
</Form.Item>
<Form.Item name="desc" label={t("node.desc")}>
<TextArea autoSize disabled={true} />
</Form.Item>
<Markdown className="b3-markdown">{data.doc}</Markdown>
{data.input && data.input.length > 0 && (
<Markdown className="b3-markdown">{def.doc}</Markdown>
{def.input && def.input.length > 0 && (
<>
<Divider orientation="left">
<h4>{t("node.inputVariable")}</h4>
</Divider>
{data.input.map((v, i) => {
{def.input.map((v, i) => {
const required = v.indexOf("?") == -1;
return (
<Form.Item
@@ -497,12 +490,12 @@ const NodeDefInspector: FC = () => {
})}
</>
)}
{data.args && data.args.length > 0 && (
{def.args && def.args.length > 0 && (
<>
<Divider orientation="left">
<h4>{t("node.args")}</h4>
</Divider>
{data.args.map((v, i) => {
{def.args.map((v, i) => {
const required = v.type.indexOf("?") == -1;
return (
<Form.Item
@@ -525,12 +518,12 @@ const NodeDefInspector: FC = () => {
})}
</>
)}
{data.output && data.output.length > 0 && (
{def.output && def.output.length > 0 && (
<>
<Divider orientation="left">
<h4>{t("node.outputVariable")}</h4>
</Divider>
{data.output.map((v, i) => {
{def.output.map((v, i) => {
const required = v.indexOf("?") == -1;
return (
<Form.Item
+1
View File
@@ -90,6 +90,7 @@ export type FileTreeType = {
export type EditNode = {
data: NodeModel;
editable: boolean;
limit_error?: boolean;
};
export type EditNodeDef = {
+1
View File
@@ -32,6 +32,7 @@ export interface NodeDef {
`${Status}` | `!${Status}` | `|${Status}` | `&${Status}`,
"!running" | "&running"
>[];
children?: -1 | 0 | 1;
}
export interface NodeModel {
+24
View File
@@ -73,6 +73,15 @@ export const checkNodeData = (data: NodeModel | null | undefined) => {
}
let hasError = false;
const conf = useWorkspace.getState().getNodeDef(data.name);
if (conf.children !== undefined) {
if (conf.children == 0 && data.children?.length) {
hasError = true;
console.error(`check ${data.id}|${data.name}: no children is required`);
} else if (conf.children == 1 && data.children?.length !== 1) {
hasError = true;
console.error(`check ${data.id}|${data.name}: only one child is required`);
}
}
if (conf.input) {
for (let i = 0; i < conf.input.length; i++) {
if (!data.input) {
@@ -330,6 +339,18 @@ export const calcTreeDataSize = (data: TreeGraphData) => {
return [220, height];
};
export const checkChildrenLimit = (data: TreeGraphData) => {
const conf = data.def;
if (conf.children !== undefined) {
if (conf.children == 0 && data.children?.length) {
return false;
} else if (conf.children == 1 && data.children?.length !== 1) {
return false;
}
}
return true;
};
export const checkTreeData = (data: TreeGraphData) => {
const conf = data.def;
if (conf.input) {
@@ -346,6 +367,9 @@ export const checkTreeData = (data: TreeGraphData) => {
}
}
}
if (!checkChildrenLimit(data)) {
return false;
}
if (conf.args) {
for (let i = 0; i < conf.args.length; i++) {
const arg = conf.args[i];