support group by type for node def
This commit is contained in:
1 parent
be509bed9e
commit
543c5b09c3
7 files changed
+110
-88
No files matched your search
@@ -1,14 +1,11 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[json]": {
|
||||
"editor.formatOnSave": false
|
||||
}
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@
|
||||
},
|
||||
{
|
||||
"name": "MoveToPos",
|
||||
"type": "Action",
|
||||
"type": "Action (Client)",
|
||||
"args": [
|
||||
{
|
||||
"name": "x",
|
||||
@@ -141,7 +141,7 @@
|
||||
},
|
||||
{
|
||||
"name": "MoveToTarget",
|
||||
"type": "Action",
|
||||
"type": "Action (Server)",
|
||||
"input": [
|
||||
"{目标}"
|
||||
],
|
||||
|
||||
+64
-35
@@ -1,4 +1,5 @@
|
||||
import { FileTreeType, useWorkspace } from "@/contexts/workspace-context";
|
||||
import { NodeDef, getNodeType } from "@/misc/b3type";
|
||||
import * as b3util from "@/misc/b3util";
|
||||
import { modal } from "@/misc/hooks";
|
||||
import { Hotkey, isHotkeyPressed, isMacos, useHotkeys } from "@/misc/keys";
|
||||
@@ -31,6 +32,15 @@ type MenuEvent =
|
||||
| "move"
|
||||
| "duplicate";
|
||||
|
||||
export type NodeTreeType = {
|
||||
title: string;
|
||||
def?: NodeDef;
|
||||
icon?: React.ReactNode;
|
||||
isLeaf?: boolean;
|
||||
children?: NodeTreeType[];
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
const findFile = (path: string | undefined, node: FileTreeType): FileTreeType | undefined => {
|
||||
if (!path) {
|
||||
return;
|
||||
@@ -112,7 +122,6 @@ export const Explorer: FC = () => {
|
||||
editors: useWorkspace((state) => state.editors),
|
||||
fileTree: useWorkspace((state) => state.fileTree),
|
||||
nodeDefs: useWorkspace((state) => state.nodeDefs),
|
||||
nodeTree: useWorkspace((state) => state.nodeTree),
|
||||
workdir: useWorkspace((state) => state.workdir),
|
||||
onEditingNodeDef: useWorkspace((state) => state.onEditingNodeDef),
|
||||
open: useWorkspace((state) => state.open),
|
||||
@@ -134,49 +143,69 @@ export const Explorer: FC = () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (workspace.nodeTree) {
|
||||
workspace.nodeTree.title = t("nodeDefinition");
|
||||
workspace.nodeTree.icon = (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<PiTreeStructureFill size={19} />
|
||||
</Flex>
|
||||
);
|
||||
workspace.nodeTree.children?.forEach((catalog) => {
|
||||
catalog.icon = (
|
||||
const nodeTree = useMemo(() => {
|
||||
const data: NodeTreeType = {
|
||||
title: t("nodeDefinition"),
|
||||
icon: (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<img
|
||||
className="b3-node-icon"
|
||||
style={{ width: "13px", height: "13px", color: "white" }}
|
||||
src={`./icons/${catalog.title}.svg`}
|
||||
/>
|
||||
<PiTreeStructureFill size={19} />
|
||||
</Flex>
|
||||
);
|
||||
catalog.children?.forEach((node) => {
|
||||
if (node.def?.icon) {
|
||||
node.icon = (
|
||||
),
|
||||
children: [],
|
||||
style: {
|
||||
fontWeight: "bold",
|
||||
fontSize: "13px",
|
||||
},
|
||||
};
|
||||
workspace.nodeDefs.forEach((nodeDef) => {
|
||||
let catalog = data.children?.find((nt) => nt.title === nodeDef.type);
|
||||
if (!catalog) {
|
||||
const type = getNodeType(nodeDef);
|
||||
catalog = {
|
||||
title: nodeDef.type,
|
||||
children: [],
|
||||
icon: (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<img
|
||||
className="b3-node-icon"
|
||||
key={catalog.title}
|
||||
style={{ width: "13px", height: "13px", color: "white" }}
|
||||
src={
|
||||
process.env.VITE_DEV_SERVER_URL && isMacos
|
||||
? `${Path.basename(workspace.workdir)}/${node.def?.icon}`
|
||||
: `${workspace.workdir}/${node.def?.icon}`
|
||||
}
|
||||
src={`./icons/${type}.svg`}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
} else {
|
||||
node.icon = (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<BsBoxFill style={{ width: "12px", height: "12px", color: "white" }} />{" "}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
),
|
||||
};
|
||||
data.children?.push(catalog);
|
||||
}
|
||||
catalog.children?.push({
|
||||
title: `${nodeDef.name}(${nodeDef.desc})`,
|
||||
isLeaf: true,
|
||||
def: nodeDef,
|
||||
icon: nodeDef.icon ? (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<img
|
||||
className="b3-node-icon"
|
||||
key={catalog.title}
|
||||
style={{ width: "13px", height: "13px", color: "white" }}
|
||||
src={
|
||||
process.env.VITE_DEV_SERVER_URL && isMacos
|
||||
? `${Path.basename(workspace.workdir)}/${nodeDef.icon}`
|
||||
: `${workspace.workdir}/${nodeDef.icon}`
|
||||
}
|
||||
/>
|
||||
</Flex>
|
||||
) : (
|
||||
<Flex justify="center" align="center" style={{ height: "100%" }}>
|
||||
<BsBoxFill style={{ width: "12px", height: "12px", color: "white" }} />{" "}
|
||||
</Flex>
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
data.children?.sort((a, b) => a.title.localeCompare(b.title));
|
||||
data.children?.forEach((child) =>
|
||||
child.children?.sort((a, b) => a.title.localeCompare(b.title))
|
||||
);
|
||||
return data;
|
||||
}, [t, workspace.nodeDefs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (workspace.editing) {
|
||||
@@ -795,7 +824,7 @@ export const Explorer: FC = () => {
|
||||
<DirectoryTree
|
||||
tabIndex={-1}
|
||||
fieldNames={{ key: "title" }}
|
||||
treeData={workspace.nodeTree ? [workspace.nodeTree] : []}
|
||||
treeData={nodeTree ? [nodeTree] : []}
|
||||
draggable={{ icon: false, nodeDraggable: (node) => !!node.isLeaf }}
|
||||
onSelect={(_, info) => {
|
||||
const node = info.node;
|
||||
|
||||
@@ -80,6 +80,7 @@ const NodeInspector: FC = () => {
|
||||
form.resetFields();
|
||||
form.setFieldValue("id", data.id);
|
||||
form.setFieldValue("name", data.name);
|
||||
form.setFieldValue("type", def.type);
|
||||
form.setFieldValue("desc", data.desc);
|
||||
form.setFieldValue("debug", data.debug);
|
||||
form.setFieldValue("path", data.path);
|
||||
@@ -227,6 +228,14 @@ const NodeInspector: FC = () => {
|
||||
>
|
||||
<Input disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="type"
|
||||
label={
|
||||
<div style={{ minWidth: "80px", justifyContent: "flex-end" }}>{t("node.type")}</div>
|
||||
}
|
||||
>
|
||||
<Input disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("node.name")} name="name">
|
||||
<AutoComplete
|
||||
disabled={disabled}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useWorkspace } from "@/contexts/workspace-context";
|
||||
import { TreeGraphData } from "@/misc/b3type";
|
||||
import { TreeGraphData, getNodeType } from "@/misc/b3type";
|
||||
import { checkTreeData, toBreakWord } from "@/misc/b3util";
|
||||
import i18n from "@/misc/i18n";
|
||||
import { isMacos } from "@/misc/keys";
|
||||
import Path from "@/misc/path";
|
||||
import G6 from "@antv/g6";
|
||||
|
||||
const NODE_COLORS: any = {
|
||||
@@ -73,7 +75,7 @@ G6.registerNode(
|
||||
draw(cfg, group) {
|
||||
const workspace = useWorkspace.getState();
|
||||
const nodeDef = workspace.getNodeDef(cfg.name as string);
|
||||
let classify = nodeDef.type || "Other";
|
||||
let classify = getNodeType(nodeDef);
|
||||
let color = nodeDef.color || NODE_COLORS[classify] || NODE_COLORS["Other"];
|
||||
if (
|
||||
!workspace.hasNodeDef(cfg.name as string) ||
|
||||
@@ -176,7 +178,11 @@ G6.registerNode(
|
||||
});
|
||||
|
||||
// icon
|
||||
const img = nodeDef.icon ? workspace.workdir + "/" + nodeDef.icon : `./icons/${classify}.svg`;
|
||||
const img = nodeDef.icon
|
||||
? process.env.VITE_DEV_SERVER_URL && isMacos
|
||||
? `${Path.basename(workspace.workdir)}/${nodeDef.icon}`
|
||||
: `${workspace.workdir}/${nodeDef.icon}`
|
||||
: `./icons/${classify}.svg`;
|
||||
addShape("image", {
|
||||
attrs: {
|
||||
x: 5,
|
||||
|
||||
@@ -79,15 +79,6 @@ export type FileTreeType = {
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export type NodeTreeType = {
|
||||
title: string;
|
||||
def?: NodeDef;
|
||||
icon?: React.ReactNode;
|
||||
isLeaf?: boolean;
|
||||
children?: NodeTreeType[];
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export type EditNode = {
|
||||
data: NodeModel;
|
||||
editable: boolean;
|
||||
@@ -112,7 +103,6 @@ export type WorkspaceStore = {
|
||||
path: string;
|
||||
|
||||
allFiles: string[];
|
||||
nodeTree?: NodeTreeType;
|
||||
fileTree?: FileTreeType;
|
||||
editors: EditorStore[];
|
||||
editing?: EditorStore;
|
||||
@@ -452,36 +442,11 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
||||
loadNodeDefs: () => {
|
||||
const workspace = get();
|
||||
const nodeDefData = readJson(`${workspace.workdir}/node-config.b3-setting`) as NodeDef[];
|
||||
const nodeTree: NodeTreeType = {
|
||||
title: i18n.t("nodeDefinition"),
|
||||
children: [],
|
||||
style: {
|
||||
fontWeight: "bold",
|
||||
fontSize: "13px",
|
||||
},
|
||||
};
|
||||
const nodeDefs: Map<string, NodeDef> = new Map();
|
||||
for (const v of nodeDefData) {
|
||||
nodeDefs.set(v.name, v);
|
||||
let catalog = nodeTree.children?.find((nt) => nt.title === v.type);
|
||||
if (!catalog) {
|
||||
catalog = {
|
||||
title: v.type,
|
||||
children: [],
|
||||
};
|
||||
nodeTree.children?.push(catalog);
|
||||
}
|
||||
catalog.children?.push({
|
||||
title: `${v.name}(${v.desc})`,
|
||||
isLeaf: true,
|
||||
def: v,
|
||||
});
|
||||
}
|
||||
nodeTree.children?.sort((a, b) => a.title.localeCompare(b.title));
|
||||
nodeTree.children?.forEach((child) =>
|
||||
child.children?.sort((a, b) => a.title.localeCompare(b.title))
|
||||
);
|
||||
set({ nodeDefs, nodeTree });
|
||||
set({ nodeDefs });
|
||||
workspace.editing?.dispatch?.("reload");
|
||||
},
|
||||
|
||||
|
||||
+17
-1
@@ -1,6 +1,7 @@
|
||||
import { TreeGraphData as G6TreeGraphData } from "@antv/g6";
|
||||
|
||||
export type NodeArgType = "string" | "int" | "float" | "boolean" | "enum" | "code";
|
||||
export type NodeType = "Action" | "Composite" | "Decorator" | "Condition" | "Other" | "Error";
|
||||
|
||||
export interface NodeArgOption {
|
||||
name: string;
|
||||
@@ -16,7 +17,7 @@ export interface NodeArg {
|
||||
}
|
||||
export interface NodeDef {
|
||||
name: string;
|
||||
type: string;
|
||||
type: NodeType;
|
||||
desc?: string;
|
||||
args?: NodeArg[];
|
||||
input?: string[];
|
||||
@@ -67,3 +68,18 @@ export const unknownNodeDef: NodeDef = {
|
||||
desc: "新建节点",
|
||||
type: "Action",
|
||||
};
|
||||
|
||||
export const getNodeType = (def: NodeDef): NodeType => {
|
||||
const type = def.type.toLocaleLowerCase().toString();
|
||||
if (type.startsWith("action")) {
|
||||
return "Action";
|
||||
} else if (type.startsWith("composite")) {
|
||||
return "Composite";
|
||||
} else if (type.startsWith("decorator")) {
|
||||
return "Decorator";
|
||||
} else if (type.startsWith("condition")) {
|
||||
return "Condition";
|
||||
} else {
|
||||
return "Other";
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user