Skip to content

Commit 302ee4b

Browse files
committed
feat: add plugin and action for block management
1 parent 1c17193 commit 302ee4b

File tree

17 files changed

+790
-0
lines changed

17 files changed

+790
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@
2525
- plugin-schema
2626
- plugin-undo-redo
2727
- plugin-zh-cn
28+
- plugin-block
29+
- action-block

packages/action-block/.gitignore

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# project custom
2+
build
3+
dist
4+
lib
5+
es
6+
package-lock.json
7+
yarn.lock
8+
deploy-space/packages
9+
deploy-space/.env
10+
11+
12+
# IDE
13+
.vscode
14+
.idea
15+
16+
# Logs
17+
logs
18+
*.log
19+
npm-debug.log*
20+
yarn-debug.log*
21+
yarn-error.log*
22+
lerna-debug.log*
23+
24+
# Runtime data
25+
pids
26+
*.pid
27+
*.seed
28+
*.pid.lock
29+
30+
31+
# Directory for instrumented libs generated by jscoverage/JSCover
32+
lib-cov
33+
34+
# Coverage directory used by tools like istanbul
35+
coverage
36+
37+
# nyc test coverage
38+
.nyc_output
39+
40+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
41+
.grunt
42+
43+
# Bower dependency directory (https://bower.io/)
44+
bower_components
45+
46+
# node-waf configuration
47+
.lock-wscript
48+
49+
# Compiled binary addons (https://nodejs.org/api/addons.html)
50+
build/Release
51+
lib
52+
53+
# Dependency directories
54+
node_modules/
55+
jspm_packages/
56+
57+
# TypeScript v1 declaration files
58+
typings/
59+
60+
# Optional npm cache directory
61+
.npm
62+
63+
# Optional eslint cache
64+
.eslintcache
65+
66+
# Optional REPL history
67+
.node_repl_history
68+
69+
# Output of 'npm pack'
70+
*.tgz
71+
72+
# Yarn Integrity file
73+
.yarn-integrity
74+
75+
# dotenv environment variables file
76+
.env
77+
.env.test
78+
79+
# parcel-bundler cache (https://parceljs.org/)
80+
.cache
81+
82+
# next.js build output
83+
.next
84+
85+
# nuxt.js build output
86+
.nuxt
87+
88+
# vuepress build output
89+
.vuepress/dist
90+
91+
# Serverless directories
92+
.serverless/
93+
94+
# FuseBox cache
95+
.fusebox/
96+
97+
# DynamoDB Local files
98+
.dynamodb/
99+
100+
# mac config files
101+
.DS_Store
102+
103+
# codealike
104+
codealike.json

packages/action-block/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# 区块管理 - 保存为区块
2+
3+
## 区块实体
4+
5+
```
6+
7+
interface Block {
8+
name: string;
9+
title: string;
10+
schema: string;
11+
screenshot: string;
12+
created_at?: string;
13+
updated_at?: string;
14+
}
15+
16+
```
17+
18+
## 注意
19+
20+
使用区块管理需要提前将对应的 API 注册到 engine config 里:
21+
22+
```
23+
24+
interface BlockAPI {
25+
listBlocks: () => Block[];
26+
createBlock: (Block) => any;
27+
}
28+
29+
function setupConfig() {
30+
config.set('apiList', {
31+
block: {
32+
listBlocks,
33+
createBlock
34+
},
35+
})
36+
}
37+
```
38+
39+
# 使用方式
40+
41+
```
42+
import { material } from '@alilc/lowcode-engine';
43+
import { default as saveAsBlock } from '@alilc/action-block';
44+
45+
material.addBuiltinComponentAction(saveAsBlock);
46+
```

packages/action-block/build.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"externals": {
3+
"react": "var window.React",
4+
"@alifd/next": "var window.Next",
5+
"@alilc/lowcode-engine": "var window.AliLowCodeEngine"
6+
},
7+
"plugins": [
8+
"build-plugin-component",
9+
"build-plugin-fusion",
10+
[
11+
"build-plugin-moment-locales",
12+
{
13+
"locales": ["zh-cn"]
14+
}
15+
]
16+
]
17+
}

packages/action-block/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@alilc/action-block",
3+
"version": "1.0.0-beta.0",
4+
"description": "",
5+
"main": "lib/index.js",
6+
"scripts": {
7+
"start": "build-scripts start",
8+
"build": "build-scripts build",
9+
"prepublishOnly": "npm run build"
10+
},
11+
"author": "mark.ck",
12+
"license": "MIT",
13+
"dependencies": {
14+
"@alifd/next": "^1.25.31",
15+
"@alilc/lowcode-engine": "^1.0.5",
16+
"html2canvas": "^1.4.1",
17+
"react": "^16.8.1"
18+
},
19+
"devDependencies": {
20+
"@alib/build-scripts": "^0.1.32",
21+
"build-plugin-component": "^1.10.0",
22+
"build-plugin-fusion": "^0.1.22",
23+
"build-plugin-moment-locales": "^0.1.3"
24+
},
25+
"homepage": "https://unpkg.com/@alilc/action-block@1.0.0-beta.0/build/index.html"
26+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.block-screenshot {
2+
background: gainsboro;
3+
display: flex;
4+
justify-content: center;
5+
align-items: center;
6+
padding: 10px 0;
7+
8+
img {
9+
max-width: 80%;
10+
}
11+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import * as React from 'react';
2+
import { default as html2canvas } from 'html2canvas';
3+
import { Node, config, event } from '@alilc/lowcode-engine';
4+
import { Dialog, Form, Input } from '@alifd/next';
5+
import './index.scss';
6+
7+
const FormItem = Form.Item;
8+
9+
interface SaveAsBlockProps {
10+
node: Node;
11+
}
12+
13+
function checkBlockAPI () {
14+
const apiList = config.get('apiList') || {};
15+
const { block: blockAPI } = apiList;
16+
17+
if (!blockAPI?.createBlock) {
18+
throw new Error('[BlockPane] block api required in engine config.');
19+
}
20+
21+
return blockAPI;
22+
}
23+
24+
let dialog: any;
25+
26+
const SaveAsBlock = (props: SaveAsBlockProps) => {
27+
const { createBlock } = checkBlockAPI();
28+
const { node } = props;
29+
const [ src, setSrc ] = React.useState();
30+
React.useEffect(() => {
31+
const generateImage = async () => {
32+
let dom2 = node.getDOMNode();
33+
console.log('html2canvas: ', html2canvas);
34+
const canvas = await html2canvas?.(dom2, { scale: 0.5 });
35+
const dataUrl = canvas.toDataURL();
36+
setSrc(dataUrl);
37+
};
38+
39+
generateImage();
40+
}, []);
41+
42+
const save = async (values) => {
43+
const { name, title } = values;
44+
const { schema } = node;
45+
46+
await createBlock({
47+
name,
48+
title,
49+
schema: JSON.stringify(schema),
50+
screenshot: src,
51+
});
52+
dialog?.hide();
53+
event.emit('BlockChanged');
54+
}
55+
56+
return <div>
57+
<Form colon>
58+
<FormItem
59+
name="name"
60+
label="英文名"
61+
required
62+
requiredMessage="Please input name!"
63+
>
64+
<Input />
65+
</FormItem>
66+
<FormItem
67+
name="title"
68+
label="中文名"
69+
required
70+
requiredMessage="Please input title!"
71+
>
72+
<Input />
73+
</FormItem>
74+
<FormItem
75+
name="screenshot"
76+
label="缩略图"
77+
>
78+
<div className='block-screenshot'>
79+
80+
<img src={src} />
81+
</div>
82+
<Input value={src} style={{display: 'none'}}/>
83+
</FormItem>
84+
<FormItem label=" " colon={false}>
85+
<Form.Submit
86+
type="primary"
87+
validate
88+
onClick={save}
89+
style={{ marginRight: 8 }}
90+
>
91+
保存
92+
</Form.Submit>
93+
<Form.Reset>重置</Form.Reset>
94+
</FormItem>
95+
</Form>
96+
</div>
97+
}
98+
99+
100+
export default {
101+
name: 'add',
102+
content: {
103+
icon: {
104+
type: 'add',
105+
size: 'xs'
106+
},
107+
title: '新增',
108+
action(node: Node) {
109+
console.log('node: ', node);
110+
dialog = Dialog.show({
111+
v2: true,
112+
title: "保存为区块",
113+
content: <SaveAsBlock node={node} />,
114+
footer: false
115+
});
116+
},
117+
},
118+
important: true,
119+
};

0 commit comments

Comments
 (0)