show variable using count

This commit is contained in:
codetypes committed 2025-03-20 00:45:25 +08:00
1 parent 097e66ea8d
commit da96ad865b
8 files changed
+375 -280

No files matched your search

+1
View File
@@ -110,6 +110,7 @@
"node.invalidVariableName": "Invalid variable name, should start with a letter or underscore", "node.invalidVariableName": "Invalid variable name, should start with a letter or underscore",
"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.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 '{{arg}}({{desc}})'",
"node.oneof.inputNotfound": "Input '{{input}}' not found", "node.oneof.inputNotfound": "Input '{{input}}' not found",
"node.outputVariable": "Output variables", "node.outputVariable": "Output variables",
+1
View File
@@ -110,6 +110,7 @@
"node.invalidVariableName": "变量名必须以字母或下划线开头", "node.invalidVariableName": "变量名必须以字母或下划线开头",
"node.name": "节点名称", "node.name": "节点名称",
"node.noNodeSelected": "未选择任务节点", "node.noNodeSelected": "未选择任务节点",
"node.notFound": "节点 “{{name}}” 不存在",
"node.oneof.error": "输入项 “{{input}}” 和参数 “{{arg}}({{desc}})” 之中,只能选择设置其中之一", "node.oneof.error": "输入项 “{{input}}” 和参数 “{{arg}}({{desc}})” 之中,只能选择设置其中之一",
"node.oneof.inputNotfound": "输入项“{{input}}”不存在", "node.oneof.inputNotfound": "输入项“{{input}}”不存在",
"node.outputVariable": "输出变量", "node.outputVariable": "输出变量",
+9 -8
View File
@@ -63,16 +63,10 @@
"name": "Clear", "name": "Clear",
"output": [ "output": [
"test" "test"
],
"children": [
{
"id": 9,
"name": "Idle"
}
] ]
}, },
{ {
"id": 10, "id": 9,
"name": "TestB3", "name": "TestB3",
"args": { "args": {
"time": 1, "time": 1,
@@ -83,7 +77,7 @@
} }
}, },
{ {
"id": 11, "id": 10,
"name": "TestB3", "name": "TestB3",
"args": { "args": {
"time": 1, "time": 1,
@@ -92,6 +86,13 @@
"name": "1", "name": "1",
"status": "RUNNING" "status": "RUNNING"
} }
},
{
"id": 11,
"name": "Clear",
"output": [
"context"
]
} }
] ]
}, },
+50 -46
View File
@@ -70,34 +70,34 @@ const refreshTreeData = (data: TreeGraphData) => {
const isTreeUpdated = (editor: EditorStore, editTree: EditTree) => { const isTreeUpdated = (editor: EditorStore, editTree: EditTree) => {
if ( if (
editor.data.firstid !== editTree.data.firstid || editor.data.firstid !== editTree.firstid ||
editor.data.export !== editTree.data.export || editor.data.export !== editTree.export ||
editor.data.name !== editTree.data.name || editor.data.name !== editTree.name ||
editor.data.desc !== editTree.data.desc editor.data.desc !== editTree.desc
) { ) {
return true; return true;
} }
let max = Math.max(editor.declare.declvar.length, editTree.data.declvar.length); let max = Math.max(editor.declare.declvar.length, editTree.declvar.length);
for (let i = 0; i < max; i++) { for (let i = 0; i < max; i++) {
const v1: VarDef | undefined = editor.declare.declvar[i]; const v1: VarDef | undefined = editor.declare.declvar[i];
const v2: VarDef | undefined = editTree.data.declvar[i]; const v2: VarDef | undefined = editTree.declvar[i];
if (v1?.name !== v2?.name || v1?.desc !== v2?.desc) { if (v1?.name !== v2?.name || v1?.desc !== v2?.desc) {
return true; return true;
} }
} }
max = Math.max(editor.data.group.length, editTree.data.group.length); max = Math.max(editor.data.group.length, editTree.group.length);
for (let i = 0; i < max; i++) { for (let i = 0; i < max; i++) {
if (editor.data.group[i] !== editTree.data.group[i]) { if (editor.data.group[i] !== editTree.group[i]) {
return true; return true;
} }
} }
max = Math.max(editor.declare.import.length, editTree.data.import.length); max = Math.max(editor.declare.import.length, editTree.import.length);
for (let i = 0; i < max; i++) { for (let i = 0; i < max; i++) {
const v1: ImportDef | undefined = editor.declare.import[i]; const v1: ImportDef | undefined = editor.declare.import[i];
const v2: ImportDef | undefined = editTree.data.import[i]; const v2: ImportDef | undefined = editTree.import[i];
if (v1?.path !== v2?.path) { if (v1?.path !== v2?.path) {
return true; return true;
} }
@@ -551,12 +551,12 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
const updateTree = (editTree: EditTree) => { const updateTree = (editTree: EditTree) => {
if (isTreeUpdated(editor, editTree)) { if (isTreeUpdated(editor, editTree)) {
editor.data.desc = editTree.data.desc || ""; editor.data.desc = editTree.desc || "";
editor.data.export = editTree.data.export !== false; editor.data.export = editTree.export !== false;
editor.data.group = editTree.data.group; editor.data.group = editTree.group;
editor.data.firstid = editTree.data.firstid ?? 1; editor.data.firstid = editTree.firstid ?? 1;
editor.declare.declvar = editTree.data.declvar || []; editor.declare.declvar = editTree.declvar || [];
editor.declare.import = editTree.data.import || []; editor.declare.import = editTree.import || [];
editor.data.import = editor.declare.import.map((v) => v.path).sort(); editor.data.import = editor.declare.import.map((v) => v.path).sort();
editor.data.declvar = editor.declare.declvar editor.data.declvar = editor.declare.declvar
.map((v) => ({ ...v })) .map((v) => ({ ...v }))
@@ -568,6 +568,32 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
} }
}; };
const clickVar = (...names: string[]) => {
const changed = findHightlight(editor.root, names);
if (changed.length > 0) {
const refreshHighlight = (node: TreeGraphData) => {
const item = editor.graph.findById(node.id);
if (names.length > 0) {
node.highlightGray = !(node.highlightInput || node.highlightOutput || node.highlightArgs);
} else {
node.highlightGray = false;
}
item.draw();
if (node.children) {
node.children.forEach(refreshHighlight);
}
};
refreshHighlight(editor.root);
}
if (names.length === 0 && editor.searchingText) {
onSearchChange({
...filterOption,
filterType: "content",
filterStr: editor.searchingText,
});
}
};
const selectNode = (id: string | null) => { const selectNode = (id: string | null) => {
if (editor.selectedId) { if (editor.selectedId) {
setItemState(editor.selectedId, "selected", false); setItemState(editor.selectedId, "selected", false);
@@ -953,41 +979,15 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
}); });
editor.graph.on("node:click", (e: G6GraphEvent) => { editor.graph.on("node:click", (e: G6GraphEvent) => {
const highlight: string[] = []; const names: string[] = [];
if (e.shape.cfg.name === "input-text") { if (e.shape.cfg.name === "input-text") {
const data = findDataById(e.item.getID()); const data = findDataById(e.item.getID());
data.input?.forEach((v) => v && highlight.push(v)); data.input?.forEach((v) => v && names.push(v));
} else if (e.shape.cfg.name === "output-text") { } else if (e.shape.cfg.name === "output-text") {
const data = findDataById(e.item.getID()); const data = findDataById(e.item.getID());
data.output?.forEach((v) => v && highlight.push(v)); data.output?.forEach((v) => v && names.push(v));
}
const changed = findHightlight(editor.root, highlight);
if (changed.length > 0) {
const refreshHighlight = (node: TreeGraphData) => {
const item = editor.graph.findById(node.id);
if (highlight.length > 0) {
node.highlightGray = !(
node.highlightInput ||
node.highlightOutput ||
node.highlightArgs
);
} else {
node.highlightGray = false;
}
item.draw();
if (node.children) {
node.children.forEach(refreshHighlight);
}
};
refreshHighlight(editor.root);
}
if (highlight.length === 0 && editor.searchingText) {
onSearchChange({
...filterOption,
filterType: "content",
filterStr: editor.searchingText,
});
} }
clickVar(...names);
}); });
editor.graph.on("node:contextmenu", (e: G6GraphEvent) => { editor.graph.on("node:contextmenu", (e: G6GraphEvent) => {
@@ -1253,6 +1253,10 @@ export const Editor: FC<EditorProps> = ({ onUpdate: updateState, data: editor, .
saveAsSubtree(); saveAsSubtree();
break; break;
} }
case "clickVar": {
clickVar(data as string);
break;
}
} }
}; };
+291 -202
View File
@@ -57,12 +57,13 @@ interface OptionType extends DefaultOptionType {
const TreeInspector: FC = () => { const TreeInspector: FC = () => {
const workspace = useWorkspace( const workspace = useWorkspace(
useShallow((state) => ({ useShallow((state) => ({
allFiles: state.allFiles,
editing: state.editing, editing: state.editing,
editingTree: state.editingTree!, editingTree: state.editingTree!,
allFiles: state.allFiles,
relative: state.relative,
fileTree: state.fileTree, fileTree: state.fileTree,
groupDefs: state.groupDefs, groupDefs: state.groupDefs,
nodeDefs: state.nodeDefs,
relative: state.relative,
})) }))
); );
const { t } = useTranslation(); const { t } = useTranslation();
@@ -72,10 +73,50 @@ const TreeInspector: FC = () => {
const groupDefs: GroupDef[] = useMemo(() => { const groupDefs: GroupDef[] = useMemo(() => {
return workspace.groupDefs.map((v) => ({ return workspace.groupDefs.map((v) => ({
name: v, name: v,
value: workspace.editingTree.data.group.includes(v), value: workspace.editingTree.group.includes(v),
})); }));
}, [workspace.groupDefs, workspace.editingTree]); }, [workspace.groupDefs, workspace.editingTree]);
// using count
const usingCount: Record<string, number> = useMemo(() => {
const count: Record<string, number> = {};
const collect = (node: TreeGraphData) => {
const def = workspace.nodeDefs.get(node.name);
if (def.input) {
node.input?.forEach((v) => {
count[v] = (count[v] ?? 0) + 1;
});
}
if (def.output) {
node.output?.forEach((v) => {
count[v] = (count[v] ?? 0) + 1;
});
}
if (def.args) {
def.args.forEach((arg) => {
const expr = node.args?.[arg.name] as string | string[] | undefined;
if (!isExprType(arg.type) || !expr) {
return;
}
if (Array.isArray(expr)) {
expr.forEach((str) => {
parseExpr(str).forEach((v) => {
count[v] = (count[v] ?? 0) + 1;
});
});
} else {
parseExpr(expr).forEach((v) => {
count[v] = (count[v] ?? 0) + 1;
});
}
});
}
node.children?.forEach(collect);
};
collect(workspace.editingTree.root);
return count;
}, [workspace.editingTree, workspace.nodeDefs]);
// auto complete for subtree // auto complete for subtree
const subtreeOptions = useMemo(() => { const subtreeOptions = useMemo(() => {
const options: OptionType[] = []; const options: OptionType[] = [];
@@ -93,42 +134,39 @@ const TreeInspector: FC = () => {
// set form values // set form values
useEffect(() => { useEffect(() => {
const data = workspace.editingTree.data; loadVarDef(workspace.editingTree.import);
loadVarDef(data.import);
form.resetFields(); form.resetFields();
form.setFieldValue("name", data.name); form.setFieldValue("name", workspace.editingTree.name);
form.setFieldValue("desc", data.desc); form.setFieldValue("desc", workspace.editingTree.desc);
form.setFieldValue("export", data.export !== false); form.setFieldValue("export", workspace.editingTree.export !== false);
form.setFieldValue("firstid", data.firstid); form.setFieldValue("firstid", workspace.editingTree.firstid);
form.setFieldValue("group", groupDefs); form.setFieldValue("group", groupDefs);
form.setFieldValue("declvar", data.declvar); form.setFieldValue("declvar", workspace.editingTree.declvar);
form.setFieldValue("import", data.import); form.setFieldValue("import", workspace.editingTree.import);
form.setFieldValue("subtree", data.subtree); form.setFieldValue("subtree", workspace.editingTree.subtree);
}, [workspace.editingTree, groupDefs]); }, [workspace.editingTree, groupDefs]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const finish = (values: any) => { const finish = (values: any) => {
workspace.editing?.dispatch("updateTree", { workspace.editing?.dispatch("updateTree", {
data: { name: values.name,
name: values.name, desc: values.desc,
desc: values.desc, export: values.export,
export: values.export, firstid: Number(values.firstid),
firstid: Number(values.firstid), group: (values.group as GroupDef[])
group: (values.group as GroupDef[]) .map((v) => (v.value ? v.name : ""))
.map((v) => (v.value ? v.name : "")) .filter((v) => v)
.filter((v) => v) .sort((a, b) => a.localeCompare(b)),
.sort((a, b) => a.localeCompare(b)), declvar: (values.declvar as VarDef[])
declvar: (values.declvar as VarDef[]) .filter((v) => v && v.name)
.filter((v) => v && v.name) .sort((a, b) => a.name.localeCompare(b.name)),
.sort((a, b) => a.name.localeCompare(b.name)), import: (values.import as ImportDef[])
import: (values.import as ImportDef[]) .filter((v) => v && v.path)
.filter((v) => v && v.path) .sort((a, b) => a.path.localeCompare(b.path))
.sort((a, b) => a.path.localeCompare(b.path)) .map((v) => ({
.map((v) => ({ path: v.path,
path: v.path, vars: v.vars ?? [],
vars: v.vars ?? [], })),
})),
},
} as EditTree); } as EditTree);
}; };
@@ -200,70 +238,85 @@ const TreeInspector: FC = () => {
<h4>{t("tree.vars")}</h4> <h4>{t("tree.vars")}</h4>
</Divider> </Divider>
<Form.List name="declvar"> <Form.List name="declvar">
{(items, { add, remove }, { errors }) => ( {(fields, { add, remove }, { errors }) => (
<div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}> <div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}>
{items.map((item) => ( {fields.map((item) => {
<Flex key={item.key} gap={4}> const vardef = workspace.editingTree.declvar[item.name];
<Space.Compact return (
className="b3-inspector-vars-item" <Flex key={item.key} gap={4}>
style={{ width: "100%", marginBottom: 2 }} <Space.Compact
> className="b3-inspector-vars-item"
<Form.Item style={{ width: "100%", marginBottom: 2 }}
noStyle >
name={[item.name, "name"]} <Form.Item
validateTrigger={["onChange", "onBlur"]} noStyle
rules={[ name={[item.name, "name"]}
{ validateTrigger={["onChange", "onBlur"]}
validator(_, value) { rules={[
if (value && /^[_\w]+\w*$/.test(value)) { {
return Promise.resolve(); validator(_, value) {
} if (value && /^[_\w]+\w*$/.test(value)) {
return Promise.reject(new Error(t("tree.vars.invalidName"))); return Promise.resolve();
}
return Promise.reject(new Error(t("tree.vars.invalidName")));
},
}, },
}, ]}
]} >
> <Input
<Input addonBefore={
addonBefore={ <div
<div style={{ display: "flex", alignItems: "center", width: "45px" }}> style={{
<AimOutlined /> display: "flex",
<span style={{ marginLeft: 4 }}>0</span> cursor: "pointer",
</div> alignItems: "center",
} width: "45px",
placeholder={t("tree.vars.name")} }}
onBlur={form.submit} onClick={() =>
/> workspace.editing?.dispatch("clickVar", vardef.name)
</Form.Item> }
<Form.Item >
noStyle <AimOutlined />
name={[item.name, "desc"]} <span style={{ marginLeft: 4 }}>
validateTrigger={["onChange", "onBlur"]} {usingCount[vardef.name] ?? 0}
rules={[ </span>
{ </div>
required: true, }
message: t("fieldRequired", { field: t("tree.vars.desc") }), placeholder={t("tree.vars.name")}
}, onBlur={form.submit}
]} />
> </Form.Item>
<Input <Form.Item
style={{ width: "60%" }} noStyle
placeholder={t("tree.vars.desc")} name={[item.name, "desc"]}
onBlur={form.submit} validateTrigger={["onChange", "onBlur"]}
/> rules={[
</Form.Item> {
</Space.Compact> required: true,
<MinusCircleOutlined message: t("fieldRequired", { field: t("tree.vars.desc") }),
style={{ marginBottom: "6px" }} },
onClick={() => { ]}
remove(item.name); >
form.submit(); <Input
}} style={{ width: "60%" }}
/> placeholder={t("tree.vars.desc")}
</Flex> onBlur={form.submit}
))} />
</Form.Item>
</Space.Compact>
<MinusCircleOutlined
style={{ marginBottom: "6px" }}
onClick={() => {
remove(item.name);
form.submit();
}}
/>
</Flex>
);
})}
<Form.Item <Form.Item
style={{ style={{
marginRight: items.length === 0 ? undefined : "18px", marginRight: fields.length === 0 ? undefined : "18px",
marginTop: 4, marginTop: 4,
alignItems: "end", alignItems: "end",
}} }}
@@ -284,66 +337,76 @@ const TreeInspector: FC = () => {
)} )}
</Form.List> </Form.List>
</> </>
{workspace.editingTree.data.subtree.length > 0 && ( {workspace.editingTree.subtree.length > 0 && (
<> <>
<Divider orientation="left"> <Divider orientation="left">
<h4>{t("tree.vars.subtree")}</h4> <h4>{t("tree.vars.subtree")}</h4>
</Divider> </Divider>
<Form.List name="subtree"> <Form.List name="subtree">
{(vars) => ( {(fields) => (
<div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}> <div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}>
{vars.map((v, idx, arr) => ( {fields.map((item, idx) => {
<Flex key={v.key} gap={4}> const vardef = workspace.editingTree.subtree[item.name];
<Space.Compact return (
className="b3-inspector-vars-item" <Flex key={item.key} gap={4}>
style={{ width: "100%", marginBottom: 0, paddingRight: 18 }} <Space.Compact
> className="b3-inspector-vars-item"
<Form.Item noStyle name={[v.name, "id"]}> style={{ width: "100%", marginBottom: 0, paddingRight: 18 }}
<div >
style={{ <Form.Item noStyle name={[item.name, "id"]}>
display: "flex", <div
alignItems: "center", style={{
paddingLeft: "8px", display: "flex",
paddingRight: "8px", alignItems: "center",
maxWidth: "60px", paddingLeft: "8px",
minWidth: "60px", paddingRight: "8px",
borderTopLeftRadius: idx === 0 ? "4px" : 0, maxWidth: "60px",
borderBottomLeftRadius: idx === arr.length - 1 ? "4px" : 0, minWidth: "60px",
borderLeft: "1px solid #3d506c", borderTopLeftRadius: idx === 0 ? "4px" : 0,
borderTop: "1px solid #3d506c", borderBottomLeftRadius: idx === fields.length - 1 ? "4px" : 0,
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none", borderLeft: "1px solid #3d506c",
}} borderTop: "1px solid #3d506c",
> cursor: "pointer",
<AimOutlined /> borderBottom:
<span style={{ marginLeft: 4 }}>0</span> idx === fields.length - 1 ? "1px solid #3d506c" : "none",
</div> }}
</Form.Item> onClick={() => workspace.editing?.dispatch("clickVar", vardef.name)}
<Form.Item noStyle name={[v.name, "name"]}> >
<Input <AimOutlined />
disabled={true} <span style={{ marginLeft: 4 }}>
placeholder={t("tree.vars.name")} {usingCount[vardef.name] ?? 0}
style={{ </span>
borderRadius: "0", </div>
borderTop: "1px solid #3d506c", </Form.Item>
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none", <Form.Item noStyle name={[item.name, "name"]}>
}} <Input
/> disabled={true}
</Form.Item> placeholder={t("tree.vars.name")}
<Form.Item noStyle name={[v.name, "desc"]}> style={{
<Input borderRadius: "0",
disabled={true} borderTop: "1px solid #3d506c",
placeholder={t("tree.vars.desc")} borderBottom:
style={{ idx === fields.length - 1 ? "1px solid #3d506c" : "none",
borderTopRightRadius: idx === 0 ? "4px" : 0, }}
borderBottomRightRadius: idx === arr.length - 1 ? "4px" : 0, />
borderTop: "1px solid #3d506c", </Form.Item>
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none", <Form.Item noStyle name={[item.name, "desc"]}>
}} <Input
/> disabled={true}
</Form.Item> placeholder={t("tree.vars.desc")}
</Space.Compact> style={{
</Flex> borderTopRightRadius: idx === 0 ? "4px" : 0,
))} borderBottomRightRadius: idx === fields.length - 1 ? "4px" : 0,
borderTop: "1px solid #3d506c",
borderBottom:
idx === fields.length - 1 ? "1px solid #3d506c" : "none",
}}
/>
</Form.Item>
</Space.Compact>
</Flex>
);
})}
</div> </div>
)} )}
</Form.List> </Form.List>
@@ -390,61 +453,72 @@ const TreeInspector: FC = () => {
<Form.List name={[item.name, "vars"]}> <Form.List name={[item.name, "vars"]}>
{(vars) => ( {(vars) => (
<div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}> <div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}>
{vars.map((v, idx, arr) => ( {vars.map((v, idx) => {
<Flex key={v.key} gap={4}> const vardef = workspace.editingTree.import[item.name].vars[v.name];
<Space.Compact return (
className="b3-inspector-vars-item" <Flex key={v.key} gap={4}>
style={{ width: "100%", marginBottom: 0, paddingRight: 18 }} <Space.Compact
> className="b3-inspector-vars-item"
<Form.Item noStyle name={[v.name, "id"]}> style={{ width: "100%", marginBottom: 0, paddingRight: 18 }}
<div >
style={{ <Form.Item noStyle name={[v.name, "id"]}>
display: "flex", <div
alignItems: "center", style={{
paddingLeft: "8px", display: "flex",
paddingRight: "8px", alignItems: "center",
maxWidth: "60px", paddingLeft: "8px",
minWidth: "60px", paddingRight: "8px",
borderTopLeftRadius: idx === 0 ? "4px" : 0, maxWidth: "60px",
borderBottomLeftRadius: idx === arr.length - 1 ? "4px" : 0, minWidth: "60px",
borderLeft: "1px solid #3d506c", borderTopLeftRadius: idx === 0 ? "4px" : 0,
borderTop: "1px solid #3d506c", borderBottomLeftRadius:
borderBottom: idx === vars.length - 1 ? "4px" : 0,
idx === arr.length - 1 ? "1px solid #3d506c" : "none", borderLeft: "1px solid #3d506c",
}} borderTop: "1px solid #3d506c",
> borderBottom:
<AimOutlined /> idx === vars.length - 1 ? "1px solid #3d506c" : "none",
<span style={{ marginLeft: 4 }}>0</span> cursor: "pointer",
</div> }}
</Form.Item> onClick={() =>
<Form.Item noStyle name={[v.name, "name"]}> workspace.editing?.dispatch("clickVar", vardef.name)
<Input }
disabled={true} >
placeholder={t("tree.vars.name")} <AimOutlined />
style={{ <span style={{ marginLeft: 4 }}>
borderRadius: "0", {usingCount[vardef.name] ?? 0}
borderTop: "1px solid #3d506c", </span>
borderBottom: </div>
idx === arr.length - 1 ? "1px solid #3d506c" : "none", </Form.Item>
}} <Form.Item noStyle name={[v.name, "name"]}>
/> <Input
</Form.Item> disabled={true}
<Form.Item noStyle name={[v.name, "desc"]}> placeholder={t("tree.vars.name")}
<Input style={{
disabled={true} borderRadius: "0",
placeholder={t("tree.vars.desc")} borderTop: "1px solid #3d506c",
style={{ borderBottom:
borderTopRightRadius: idx === 0 ? "4px" : 0, idx === vars.length - 1 ? "1px solid #3d506c" : "none",
borderBottomRightRadius: idx === arr.length - 1 ? "4px" : 0, }}
borderTop: "1px solid #3d506c", />
borderBottom: </Form.Item>
idx === arr.length - 1 ? "1px solid #3d506c" : "none", <Form.Item noStyle name={[v.name, "desc"]}>
}} <Input
/> disabled={true}
</Form.Item> placeholder={t("tree.vars.desc")}
</Space.Compact> style={{
</Flex> borderTopRightRadius: idx === 0 ? "4px" : 0,
))} borderBottomRightRadius:
idx === vars.length - 1 ? "4px" : 0,
borderTop: "1px solid #3d506c",
borderBottom:
idx === vars.length - 1 ? "1px solid #3d506c" : "none",
}}
/>
</Form.Item>
</Space.Compact>
</Flex>
);
})}
</div> </div>
)} )}
</Form.List> </Form.List>
@@ -793,7 +867,22 @@ const NodeInspector: FC = () => {
> >
<Input disabled={true} /> <Input disabled={true} />
</Form.Item> </Form.Item>
<Form.Item label={t("node.name")} name="name"> <Form.Item
label={t("node.name")}
name="name"
rules={[
{
validator() {
if (!workspace.nodeDefs.has(editingNode.data.name)) {
return Promise.reject(
new Error(t("node.notFound", { name: editingNode.data.name }))
);
}
return Promise.resolve();
},
},
]}
>
<AutoComplete <AutoComplete
disabled={disabled} disabled={disabled}
options={nodeOptions} options={nodeOptions}
+4 -4
View File
@@ -370,7 +370,7 @@ G6.registerNode(
let y = 32; let y = 32;
// desc text // desc text
let desc = (data.desc || nodeDef.desc) as string; let desc = (data.desc || nodeDef.desc) as string;
if (desc) { if (desc || desc === "") {
desc = i18n.t("regnode.mark") + desc; desc = i18n.t("regnode.mark") + desc;
desc = cutWordTo(desc, w - 15); desc = cutWordTo(desc, w - 15);
addShape("text", { addShape("text", {
@@ -388,7 +388,7 @@ G6.registerNode(
} }
const args = data.args; const args = data.args;
if (nodeDef.args && args && Object.keys(args).length > 0) { if (args && Object.keys(args).length > 0) {
const { str, line } = toBreakWord(`${i18n.t("regnode.args")}${JSON.stringify(args)}`, 200); const { str, line } = toBreakWord(`${i18n.t("regnode.args")}${JSON.stringify(args)}`, 200);
if (data.highlightArgs) { if (data.highlightArgs) {
addShape("rect", { addShape("rect", {
@@ -420,7 +420,7 @@ G6.registerNode(
} }
const input = data.input ?? []; const input = data.input ?? [];
if (nodeDef.input && input.length > 0) { if (input.length > 0) {
const { str, line } = toBreakWord( const { str, line } = toBreakWord(
`${i18n.t("regnode.input")}${JSON.stringify(input)}`, `${i18n.t("regnode.input")}${JSON.stringify(input)}`,
200 200
@@ -458,7 +458,7 @@ G6.registerNode(
} }
const output = data.output ?? []; const output = data.output ?? [];
if (nodeDef.output && output.length > 0) { if (output.length > 0) {
const { str, line } = toBreakWord( const { str, line } = toBreakWord(
`${i18n.t("regnode.output")}${JSON.stringify(output)}`, `${i18n.t("regnode.output")}${JSON.stringify(output)}`,
200 200
+18 -19
View File
@@ -46,7 +46,8 @@ export type EditEvent =
| "updateNode" | "updateNode"
| "searchNode" | "searchNode"
| "editSubtree" | "editSubtree"
| "saveAsSubtree"; | "saveAsSubtree"
| "clickVar";
export class EditorStore { export class EditorStore {
path: string; path: string;
@@ -123,16 +124,15 @@ export type EditNodeDef = {
}; };
export type EditTree = { export type EditTree = {
data: { name: string;
name: string; desc?: string;
desc?: string; export?: boolean;
export?: boolean; firstid?: number;
firstid?: number; group: string[];
group: string[]; import: ImportDef[];
import: ImportDef[]; declvar: VarDef[];
declvar: VarDef[]; subtree: VarDef[];
subtree: VarDef[]; root: TreeGraphData;
};
}; };
export type FileMeta = { export type FileMeta = {
@@ -692,14 +692,13 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
workspace.refresh(editor.path); workspace.refresh(editor.path);
set({ set({
editingTree: { editingTree: {
data: { ...editor.data,
...editor.data, root: editor.root,
import: editor.declare.import, import: editor.declare.import,
declvar: editor.declare.declvar, declvar: editor.declare.declvar,
subtree: editor.declare.subtree subtree: editor.declare.subtree
.map((def) => def.vars) .map((def) => def.vars)
.reduce((acc, v) => [...acc, ...v], []), .reduce((acc, v) => [...acc, ...v], []),
},
}, },
editingNodeDef: null, editingNodeDef: null,
editingNode: null, editingNode: null,