Skip to content

Commit 24c23a0

Browse files
authored
Merge pull request #246 from codebdy/add-zoomable-editor
Add zoomable editor
2 parents 25be74c + 2c06cfb commit 24c23a0

File tree

62 files changed

+395
-294
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+395
-294
lines changed

examples/app-designer-example/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@rxdrag/react-fieldy": "workspace:*",
4444
"@rxdrag/react-antd-shell": "workspace:*",
4545
"@rxdrag/react-locales": "workspace:*",
46+
"@rxdrag/core": "workspace:*",
4647
"@rxdrag/react-core": "workspace:*",
4748
"@rxdrag/react-antd-materials": "workspace:*",
4849
"@rxdrag/locales": "workspace:*",
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Tree } from "antd";
2+
import { DataNode } from "antd/es/tree";
3+
import { memo, useCallback, useMemo } from "react"
4+
import { TreeContainer } from "../common/TreeContainer";
5+
import { useModule } from "../../hooks/useModule";
6+
import { useDesignerEngine, useGetNode } from "@rxdrag/react-core";
7+
import { ITreeNode } from "@rxdrag/core"
8+
import { IControllerMeta } from "@rxdrag/minions-runtime-react";
9+
10+
const { DirectoryTree } = Tree;
11+
12+
export type ReactionableNode = {
13+
node: ITreeNode<unknown, IControllerMeta>,
14+
children?: ReactionableNode[]
15+
}
16+
17+
export const ComponentTree = memo(() => {
18+
const module = useModule()
19+
const engine = useDesignerEngine()
20+
const docs = engine?.getAllDocuments()
21+
const getNode = useGetNode()
22+
console.log("===>ComponentTree", module, docs)
23+
24+
const getReactionableSchemas = useCallback((node: ITreeNode<unknown, IControllerMeta>) => {
25+
const nodes: ReactionableNode[] = []
26+
let activeNodes = nodes
27+
if (node.meta["x-controller"]?.id) {
28+
const rNode: ReactionableNode = {
29+
node: node,
30+
children: []
31+
}
32+
nodes.push(rNode)
33+
activeNodes = rNode.children || []
34+
}
35+
36+
for (const childId of node.children) {
37+
const child = getNode(childId)
38+
if (child) {
39+
const children = getReactionableSchemas(child as ITreeNode<unknown, IControllerMeta>)
40+
activeNodes.push(...children)
41+
}
42+
}
43+
return nodes
44+
}, [getNode])
45+
46+
const getSchemaTreeOfView = useCallback((id: string) => {
47+
const doc = docs?.find(doc => doc.id === id)
48+
const rootNode = doc?.getRootNode()
49+
if (rootNode) {
50+
return getReactionableSchemas(rootNode as ITreeNode<unknown, IControllerMeta>)
51+
}
52+
53+
}, [docs, getReactionableSchemas])
54+
55+
const getOneNode = useCallback((rNode: ReactionableNode): DataNode => {
56+
return {
57+
key: rNode.node.id,
58+
title: rNode.node.meta?.["x-controller"]?.name || rNode.node.title,
59+
children: rNode.children?.map(child => getOneNode(child))
60+
}
61+
}, [])
62+
63+
const treeData: DataNode[] = useMemo(() => {
64+
return module?.views?.map(view => ({
65+
key: view.id,
66+
title: view.title,
67+
children: getSchemaTreeOfView(view.id)?.map(schema => getOneNode(schema)),
68+
})) || []
69+
}, [getOneNode, getSchemaTreeOfView, module?.views])
70+
71+
return (
72+
<TreeContainer>
73+
<DirectoryTree
74+
selectable={false}
75+
treeData={treeData}
76+
/>
77+
</TreeContainer>
78+
)
79+
})

examples/app-designer-example/src/FrontendDesigner/BottomConsole/FlowDesigner/index.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ReactNode, memo, useCallback, useMemo, useState } from "react"
22
import styled from "styled-components"
33
import { Button, Space, Tooltip, theme } from "antd"
4-
import { FunctionOutlined, ControlOutlined, CloseOutlined, AppstoreOutlined } from "@ant-design/icons"
4+
import { FunctionOutlined, ControlOutlined, CloseOutlined, PartitionOutlined, NodeIndexOutlined } from "@ant-design/icons"
55
import { FXes } from "./FXes"
66
import { Flows } from "./Flows"
77
import { LeftNav } from "../common/LeftNav"
@@ -13,6 +13,7 @@ import { activityMaterialCategories, activityMaterialLocales } from "../minion-m
1313
import { IActivityMaterial } from "@rxdrag/minions-schema"
1414
import { Toolbar } from "./Toolbar"
1515
import { useThemeMode } from "@rxdrag/react-core"
16+
import { ComponentTree } from "./ComponentTree"
1617

1718
const Content = styled.div`
1819
flex: 1;
@@ -24,6 +25,7 @@ const SaveButton = styled(Button)`
2425
`
2526

2627
enum NavType {
28+
componentTree = "componentTree",
2729
toolbox = "toolbox",
2830
flows = "flows",
2931
fxes = "fxes",
@@ -43,6 +45,10 @@ export const FlowDesigner = memo(() => {
4345
return materials.concat(...activityMaterialCategories.map(category => category.materials))
4446
}, [])
4547

48+
const handleToggleComponents = useCallback(() => {
49+
setNavType(type => type === NavType.componentTree ? null : NavType.componentTree)
50+
}, [])
51+
4652
const handleToggleToolbox = useCallback(() => {
4753
setNavType(type => type === NavType.toolbox ? null : NavType.toolbox)
4854
}, [])
@@ -73,17 +79,25 @@ export const FlowDesigner = memo(() => {
7379
<Tooltip title="元件箱" placement="right">
7480
<Button
7581
type={navType === NavType.toolbox ? "link" : "text"}
76-
icon={<AppstoreOutlined />}
82+
icon={<NodeIndexOutlined />}
7783
onClick={handleToggleToolbox}
7884
/>
7985
</Tooltip>
86+
<Tooltip title="组件树" placement="right">
87+
<Button
88+
type={navType === NavType.componentTree ? "link" : "text"}
89+
icon={<PartitionOutlined />}
90+
onClick={handleToggleComponents}
91+
/>
92+
</Tooltip>
8093
<Tooltip title="编排" placement="right">
8194
<Button
8295
type={navType === NavType.flows ? "link" : "text"}
8396
icon={<ControlOutlined />}
8497
onClick={handleToggleFlows}
8598
/>
8699
</Tooltip>
100+
87101
<Tooltip title="子编排" placement="right">
88102
<Button
89103
type={navType === NavType.fxes ? "link" : "text"}
@@ -100,10 +114,16 @@ export const FlowDesigner = memo(() => {
100114
minWidth={160}
101115
>
102116
<Title>
117+
{
118+
NavType.componentTree === navType &&
119+
<span>
120+
组件树
121+
</span>
122+
}
103123
{
104124
NavType.toolbox === navType &&
105125
<span>
106-
元件
126+
元件箱
107127
</span>
108128
}
109129
{
@@ -125,6 +145,10 @@ export const FlowDesigner = memo(() => {
125145
onClick={handleCloseLeft}
126146
/>
127147
</Title>
148+
{
149+
navType === NavType.componentTree &&
150+
<ComponentTree />
151+
}
128152
{
129153
navType === NavType.toolbox &&
130154
<Toolbox materialCategories={activityMaterialCategories} />

examples/app-designer-example/src/FrontendDesigner/ModuleUiDesigner/ModuleUiDesignerInner.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TabsProps } from "antd"
88
import styled from "styled-components"
99
import { FlowDesigner } from "../BottomConsole/FlowDesigner"
1010
import { ScriptDesigner } from "../BottomConsole/ScriptDesigner"
11+
import { ModuleContext } from "../contexts"
1112

1213
const Label = styled.div`
1314
display: flex;
@@ -52,16 +53,20 @@ export const ModuleUiDesignerInner = memo(() => {
5253
}, [])
5354

5455
return (
55-
module
56-
? <ZoomableEditor
57-
toolbox={
58-
Toolbox && <Toolbox />
59-
}
60-
schemas={module?.views}
61-
bottomConsole={{
62-
items
63-
}}
64-
/>
65-
: <></>
56+
<ModuleContext.Provider value={module}>
57+
{
58+
module
59+
? <ZoomableEditor
60+
toolbox={
61+
Toolbox && <Toolbox />
62+
}
63+
schemas={module?.views}
64+
bottomConsole={{
65+
items
66+
}}
67+
/>
68+
: <></>
69+
}
70+
</ModuleContext.Provider>
6671
)
6772
})
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { createContext } from "react";
2+
import { IModule } from "../interfaces/module";
3+
4+
export const ModuleContext = createContext<IModule | undefined>(undefined)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useContext } from "react";
2+
import { ModuleContext } from "../contexts";
3+
4+
export function useModule() {
5+
return useContext(ModuleContext)
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export class Mock {
2+
3+
}
4+
5+
export const globalMock = new Mock()

examples/app-designer-example/src/data/mudules.ts

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,93 @@ const rootNodeSchema: INodeSchema = {
66
componentName: "Page"
77
}
88

9+
const userList = {
10+
"componentName": "Page",
11+
"slots": {},
12+
"children": [
13+
{
14+
"componentName": "Form",
15+
"props": {
16+
"colon": false
17+
},
18+
"x-controller": {
19+
"id": "LlRDj22u",
20+
"name": "查询表单"
21+
},
22+
"slots": {},
23+
"children": [
24+
{
25+
"componentName": "Input",
26+
"x-controller": {
27+
"id": "Ddl53loc",
28+
"name": "字段1"
29+
},
30+
"slots": {},
31+
"children": []
32+
},
33+
{
34+
"componentName": "Input",
35+
"x-controller": {
36+
"id": "ndwJ5LwA",
37+
"name": "字段2"
38+
},
39+
"slots": {},
40+
"children": []
41+
}
42+
]
43+
},
44+
{
45+
"componentName": "Table",
46+
"selfRender": true,
47+
"x-controller": {
48+
"id": "JClydKG7",
49+
"name": "用户列表",
50+
"isArray": true,
51+
},
52+
"slots": {},
53+
"children": [
54+
{
55+
"componentName": "TableColumn",
56+
"props": {
57+
"title": "Column1"
58+
},
59+
"slots": {},
60+
"children": []
61+
},
62+
{
63+
"componentName": "TableColumn",
64+
"props": {
65+
"title": "Column2"
66+
},
67+
"slots": {},
68+
"children": []
69+
},
70+
{
71+
"componentName": "TableColumn",
72+
"props": {
73+
"title": "Column3"
74+
},
75+
"slots": {},
76+
"children": []
77+
}
78+
]
79+
}
80+
]
81+
}
82+
983
export const defaultModules: { [device: string]: IModule[] | undefined } = {
1084
[DeviceType.admin]: [
1185
{
1286
id: "users",
1387
title: "用户管理",
1488
views: [
1589
{
90+
id: "user-index",
1691
title: "入口页",
17-
schema: rootNodeSchema,
92+
schema: userList,
1893
},
1994
{
95+
id: "user-edit",
2096
title: "编辑对话框",
2197
schema: rootNodeSchema,
2298
}
@@ -37,10 +113,12 @@ export const defaultModules: { [device: string]: IModule[] | undefined } = {
37113
title: "用户管理(h5)",
38114
views: [
39115
{
116+
id: "h5-user-index",
40117
title: "入口页(h5)",
41118
schema: rootNodeSchema,
42119
},
43120
{
121+
id: "h5-user-eidit",
44122
title: "编辑对话框",
45123
schema: rootNodeSchema,
46124
}
@@ -61,10 +139,12 @@ export const defaultModules: { [device: string]: IModule[] | undefined } = {
61139
title: "用户管理(门户)",
62140
views: [
63141
{
142+
id: "website-user-index",
64143
title: "入口页(门户)",
65144
schema: rootNodeSchema,
66145
},
67146
{
147+
id: "weibsite-user-edit",
68148
title: "编辑对话框",
69149
schema: rootNodeSchema,
70150
}
@@ -85,10 +165,12 @@ export const defaultModules: { [device: string]: IModule[] | undefined } = {
85165
title: "用户管理(大屏)",
86166
views: [
87167
{
168+
id: "lg-user-index",
88169
title: "入口页(大屏)",
89170
schema: rootNodeSchema,
90171
},
91172
{
173+
id: "lg-user-edit",
92174
title: "编辑对话框",
93175
schema: rootNodeSchema,
94176
}

examples/example-common/src/controller/shortcuts/IShortcutControllerMeta.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IControllerMeta } from "@rxdrag/minions-runtime-react";
1+
import { IOldControllerMeta } from "@rxdrag/minions-runtime-react";
22

33
export enum ActionType {
44
list = "list",
@@ -7,7 +7,7 @@ export enum ActionType {
77
search = "search"
88
}
99

10-
export interface IShortcutControllerMeta extends IControllerMeta {
10+
export interface IShortcutControllerMeta extends IOldControllerMeta {
1111
actionType?: ActionType,
1212
url?: string,
1313
entityName?: string,

0 commit comments

Comments
 (0)