Merge remote-tracking branch 'origin/preset-vision/0.9.0' into release/0.9.0

# Conflicts:
#	packages/designer/src/designer/setting/utils.js
This commit is contained in:
wuji.xwt 2020-06-19 11:12:50 +08:00
commit 631bb1e1cf
129 changed files with 4725 additions and 538 deletions

View File

@ -15,9 +15,7 @@
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alifd/next/1.11.6/next.min.css" />
<script src="https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.js"></script>
<!-- lowcode engine globals -->
<link rel="stylesheet" href="./core.css" />
<!-- lowcode engine globals -->
<link rel="stylesheet" href="./vision-preset.css" />
<link rel="stylesheet" href="./editor-preset-vision.css" />
<!-- lowcode engine app -->
<link rel="stylesheet" href="./lowcode-editor.css" />
<script>
@ -72,9 +70,7 @@
<body>
<div id="lce-container"></div>
<!-- lowcode engine globals -->
<script src="./core.js"></script>
<!-- lowcode engine globals -->
<script src="./vision-preset.js"></script>
<script src="./editor-preset-vision.js"></script>
<script src="https://dev.g.alicdn.com/vision/visualengine-utils/5.0.0/engine-utils.js"></script>
<link rel="stylesheet" type="text/css" href="//g.alicdn.com/??platform/common/s/1.1/global/global.css,uxcore/uxcore-kuma/2.2.1/orange.min.css">
<!-- lowcode engine app -->

View File

@ -4,20 +4,80 @@
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<title>LowCodeEngine Preview DEMO</title>
<title>LowCodeEngine Editor DEMO</title>
<link rel="shortcut icon" href="./favicon.png" />
<script src="https://g.alicdn.com/code/lib/react/16.9.0/umd/react.development.js"></script>
<script src="https://g.alicdn.com/code/lib/react-dom/16.9.0/umd/react-dom.development.js"></script>
<script src="https://g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js"></script>
<script> React.PropTypes = PropTypes; </script>
<script src="https://g.alicdn.com/platform/c/??react15-polyfill/0.0.1/dist/index.js,lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js,natty-storage/2.0.2/dist/natty-storage.min.js,natty-fetch/2.6.0/dist/natty-fetch.pc.min.js,tinymce/4.2.5/tinymce-full.js"></script>
<script src="https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"></script>
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alifd/next/1.11.6/next.min.css">
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alifd/next/1.11.6/next.min.css" />
<script src="https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.js"></script>
<link rel="stylesheet" href="./lowcode-preview.css" />
<!-- lowcode engine globals -->
<link rel="stylesheet" href="./core.css" />
<!-- lowcode engine globals -->
<link rel="stylesheet" href="./vision-preset.css" />
<!-- lowcode engine app -->
<link rel="stylesheet" href="./lowcode-editor.css" />
<script>
window.pageConfig = {
env: 'release',
locale: 'zh_CN',
pageType: 'single',
deviceType: 'web',
appName: '基础包管理后台',
appType: '',
templateType: '',
pageId: 'FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V',
slug: 'test',
appMode: 'back',
isAppAdmin: 'y',
isSuperAdmin: 'n',
isBetaDeveloper: 'n',
formType: 'display',
title: { en_US: '测试', type: 'i18n', zh_CN: '测试' },
urlPrefix: 'https://go.alibaba-inc.com',
APIUrlPrefix: 'https://mocks.alibaba-inc.com/mock/lowCodeEngine',
devVersion: '0.1.0', // 这个是子应用的变更 id
subAppType: '0.1.0',
appKey: '',
RE_VERSION: '7.1.1',
appSource: '',
isDomainDefault: 'n',
useReleaseBundle: 'n',
isDomainPkg: 'n',
medusaAppName: '',
domainCode: 'kS6SyH',
aecp: {
mdcDomain: '',
projectId: '',
appCode: '',
},
designerConfigs: {},
navConfig:
'{"appName":{"en_US":"基础包管理后台","key":"","type":"i18n","zh_CN":"基础包管理后台"},"bgColor":"white","data":[{"children":[],"hidden":false,"icon":"","inner":true,"navUuid":"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V","relateUuid":"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V","slug":"test","targetNew":false,"title":{"en_US":"测试","type":"i18n","zh_CN":"测试"}}],"isFixed":"y","isFold":"y","isFoldHorizontal":"n","languageChangeUrl":{"en_US":"/common/account/changeAccountLanguage.json","type":"i18n","zh_CN":"/common/account/changeAccountLanguage.json"},"layout":"auto","navStyle":"orange","navTheme":"light","openSubMode":false,"showAppTitle":true,"showCrumb":true,"showIcon":false,"showLanguageChange":true,"showNav":true,"showSearch":"n","singletons":{"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V":{"isFixed":"n","isFold":"n","isFoldHorizontal":"n","showAppTitle":false,"showCrumb":false,"showLanguageChange":false,"showNav":false,"showSearch":"n","singleton":false},"test":{"$ref":"$.singletons.FORM\\-3KYJN7RV\\-DIOD8LLK1WGQ89S7NHA92\\-QJVH497K\\-V"}},"type":"top_fold"}',
historyType: 'HASH',
isSinglePage: 'n',
rhino: 'n',
isMiniApp: '',
taskId: '',
appSchema: 'V5',
openSubMode: 'n',
};
window.g_config = {};
</script>
</head>
<body>
<script src="./lowcode-preview.js"></script>
<div id="lce-container"></div>
<!-- lowcode engine globals -->
<script src="./core.js"></script>
<!-- lowcode engine globals -->
<script src="./vision-preset.js"></script>
<script src="https://dev.g.alicdn.com/vision/visualengine-utils/5.0.0/engine-utils.js"></script>
<link rel="stylesheet" type="text/css" href="//g.alicdn.com/??platform/common/s/1.1/global/global.css,uxcore/uxcore-kuma/2.2.1/orange.min.css">
<!-- lowcode engine app -->
<script src="./lowcode-editor.js"></script>
</body>
</html>

View File

@ -10,7 +10,7 @@
]
},
"scripts": {
"build": "lerna run build --stream",
"build": "./scripts/build.sh",
"clean": "rm -rf ./packages/*/lib ./packages/*/es ./packages/*/dist ./packages/*/build",
"commit": "git-cz",
"pub": "lerna publish --cd-version patch",
@ -48,5 +48,9 @@
},
"engines": {
"node": ">=10.0.0"
},
"tnpm": {
"mode": "yarn",
"lockfile": "enable"
}
}

View File

@ -58,7 +58,7 @@ const demoData: IProjectSchema = {
componentsTree: [
{
componentName: 'Page',
id: 'node$1',
id: 'node_1',
meta: {
title: '测试',
router: '/',
@ -74,7 +74,7 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'Form',
id: 'node$2',
id: 'node_2',
props: {
labelCol: 4,
style: {},
@ -83,7 +83,7 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'Form.Item',
id: 'node$3',
id: 'node_3',
props: {
label: '姓名:',
name: 'name',
@ -92,7 +92,7 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'Input',
id: 'node$4',
id: 'node_4',
props: {
placeholder: '请输入',
size: 'medium',
@ -105,7 +105,7 @@ const demoData: IProjectSchema = {
},
{
componentName: 'Form.Item',
id: 'node$5',
id: 'node_5',
props: {
label: '年龄:',
name: 'age',
@ -114,7 +114,7 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'NumberPicker',
id: 'node$6',
id: 'node_6',
props: {
size: 'medium',
type: 'normal',
@ -124,7 +124,7 @@ const demoData: IProjectSchema = {
},
{
componentName: 'Form.Item',
id: 'node$7',
id: 'node_7',
props: {
label: '职业:',
name: 'profession',
@ -132,7 +132,7 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'Select',
id: 'node$8',
id: 'node_8',
props: {
dataSource: [
{
@ -154,7 +154,7 @@ const demoData: IProjectSchema = {
},
{
componentName: 'Div',
id: 'node$9',
id: 'node_9',
props: {
style: {
textAlign: 'center',
@ -163,12 +163,12 @@ const demoData: IProjectSchema = {
children: [
{
componentName: 'Button.Group',
id: 'node$a',
id: 'node_a',
props: {},
children: [
{
componentName: 'Button',
id: 'node$b',
id: 'node_b',
props: {
type: 'primary',
style: {
@ -180,7 +180,7 @@ const demoData: IProjectSchema = {
},
{
componentName: 'Button',
id: 'node$d',
id: 'node_d',
props: {
type: 'normal',
style: {

View File

@ -3,6 +3,89 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.8.30"></a>
## [0.8.30](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.29...@ali/lowcode-demo@0.8.30) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.29"></a>
## [0.8.29](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.28...@ali/lowcode-demo@0.8.29) (2020-06-15)
### Bug Fixes
* style ([4694331](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4694331))
<a name="0.8.28"></a>
## [0.8.28](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.27...@ali/lowcode-demo@0.8.28) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.27"></a>
## [0.8.27](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.26...@ali/lowcode-demo@0.8.27) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.26"></a>
## [0.8.26](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.25...@ali/lowcode-demo@0.8.26) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.25"></a>
## [0.8.25](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.24...@ali/lowcode-demo@0.8.25) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.24"></a>
## [0.8.24](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.23...@ali/lowcode-demo@0.8.24) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.23"></a>
## [0.8.23](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.22...@ali/lowcode-demo@0.8.23) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.22"></a>
## [0.8.22](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.21...@ali/lowcode-demo@0.8.22) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.21"></a>
## [0.8.21](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.20...@ali/lowcode-demo@0.8.21) (2020-05-15)
**Note:** Version bump only for package @ali/lowcode-demo
<a name="0.8.20"></a>
## [0.8.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.19...@ali/lowcode-demo@0.8.20) (2020-05-15)

View File

@ -1,6 +1,7 @@
{
"entry": {
"index": "src/index.ts",
"index": "src/index",
"editor-preset-vision": "../editor-preset-vision/src/index.ts",
"react-simulator-renderer": "../react-simulator-renderer/src/index.ts"
},
"vendor": false,

View File

@ -7,9 +7,12 @@
"react": "window.React",
"react-dom": "window.ReactDOM",
"prop-types": "window.PropTypes",
"@ali/lowcode-editor-core": "window.LCECore",
"@ali/visualengine": "window.VisualEngine",
"@ali/visualengine-utils": "window.VisualEngineUtils"
"@ali/visualengine-utils": "window.VisualEngineUtils",
"@ali/lowcode-editor-preset-general": "window.LowcodeEditor",
"@ali/lowcode-editor-core": "window.LowcodeEditor",
"@ali/lowcode-editor-skeleton": "window.LowcodeEditor",
"@ali/lowcode-designer": "window.LowcodeEditor"
},
"minify": false,
"sourcemap": true,

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-demo",
"version": "0.8.20",
"version": "0.8.30",
"private": true,
"description": "低代码引擎 DEMO",
"scripts": {
@ -9,21 +9,32 @@
},
"config": {},
"dependencies": {
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-editor-skeleton": "^0.8.17",
"@ali/lowcode-plugin-components-pane": "^0.8.13",
"@ali/lowcode-plugin-designer": "^0.9.11",
"@ali/lowcode-plugin-event-bind-dialog": "^0.8.12",
"@ali/lowcode-plugin-outline-pane": "^0.8.17",
"@ali/lowcode-plugin-sample-logo": "^0.8.11",
"@ali/lowcode-plugin-sample-preview": "^0.8.16",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-editor-skeleton": "^0.8.26",
"@ali/lowcode-plugin-components-pane": "^0.8.23",
"@ali/lowcode-plugin-designer": "^0.9.20",
"@ali/lowcode-plugin-event-bind-dialog": "^0.8.16",
"@ali/lowcode-plugin-outline-pane": "^0.8.26",
"@ali/lowcode-plugin-sample-logo": "^0.8.15",
"@ali/lowcode-plugin-sample-preview": "^0.8.25",
"@ali/lowcode-plugin-settings-pane": "^0.8.8",
"@ali/lowcode-plugin-undo-redo": "^0.8.16",
"@ali/lowcode-plugin-variable-bind-dialog": "^0.8.10",
"@ali/lowcode-plugin-zh-en": "^0.8.14",
"@ali/lowcode-react-renderer": "^0.8.8",
"@ali/lowcode-plugin-undo-redo": "^0.8.25",
"@ali/lowcode-plugin-variable-bind-dialog": "^0.8.14",
"@ali/lowcode-plugin-zh-en": "^0.8.18",
"@ali/lowcode-react-renderer": "^0.8.0",
"@ali/lowcode-runtime": "^0.8.13",
"@ali/lowcode-utils": "^0.8.4",
"@ali/lowcode-utils": "^0.8.7",
"@ali/ve-action-pane": "^4.7.0-beta.0",
"@ali/ve-datapool-pane": "^6.4.3",
"@ali/ve-history-pane": "4.0.0",
"@ali/ve-i18n-manage-pane": "^4.3.0",
"@ali/ve-i18n-pane": "^4.0.0-beta.0",
"@ali/ve-page-history": "1.2.0",
"@ali/ve-page-history-pane": "^5.0.0-beta.0",
"@ali/ve-trunk-pane": "^5.1.0-beta.14",
"@ali/vs-variable-setter": "^3.1.0",
"@ali/vu-function-parser": "^2.5.0-beta.0",
"@ali/vu-legao-design-fetch-context": "^1.0.3",
"@alifd/next": "^1.19.12",
"@alife/theme-lowcode-light": "^0.1.0",
"compare-versions": "^3.0.1",

View File

@ -12,13 +12,63 @@
<script>
React.PropTypes = PropTypes;
</script>
<script src="https://g.alicdn.com/platform/c/??react15-polyfill/0.0.1/dist/index.js,lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js,natty-storage/2.0.2/dist/natty-storage.min.js,natty-fetch/2.6.0/dist/natty-fetch.pc.min.js,tinymce/4.2.5/tinymce-full.js"></script>
<script src="https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"></script>
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alifd/next/1.11.6/next.min.css" />
<script src="https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.js"></script>
<link rel="stylesheet" href="/css/editor-preset-vision.css" />
<script>
window.pageConfig = {
env: 'release',
locale: 'zh_CN',
pageType: 'single',
deviceType: 'web',
appName: '基础包管理后台',
appType: 'legao_base_packages',
templateType: '',
pageId: 'FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V',
slug: 'test',
appMode: 'back',
isAppAdmin: 'y',
isSuperAdmin: 'n',
isBetaDeveloper: 'n',
formType: 'display',
title: { en_US: '测试', type: 'i18n', zh_CN: '测试' },
urlPrefix: 'https://go.alibaba-inc.com',
APIUrlPrefix: 'https://go.alibaba-inc.com',
devVersion: '0.1.0', // 这个是子应用的变更 id
subAppType: '0.1.0',
appKey: 'legao_base_packages',
RE_VERSION: '7.1.1',
appSource: '',
isDomainDefault: 'n',
useReleaseBundle: 'n',
isDomainPkg: 'n',
medusaAppName: '',
domainCode: 'kS6SyH',
aecp: {
mdcDomain: '',
projectId: '',
appCode: '',
},
designerConfigs: {},
navConfig:
'{"appName":{"en_US":"基础包管理后台","key":"","type":"i18n","zh_CN":"基础包管理后台"},"bgColor":"white","data":[{"children":[],"hidden":false,"icon":"","inner":true,"navUuid":"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V","relateUuid":"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V","slug":"test","targetNew":false,"title":{"en_US":"测试","type":"i18n","zh_CN":"测试"}}],"isFixed":"y","isFold":"y","isFoldHorizontal":"n","languageChangeUrl":{"en_US":"/common/account/changeAccountLanguage.json","type":"i18n","zh_CN":"/common/account/changeAccountLanguage.json"},"layout":"auto","navStyle":"orange","navTheme":"light","openSubMode":false,"showAppTitle":true,"showCrumb":true,"showIcon":false,"showLanguageChange":true,"showNav":true,"showSearch":"n","singletons":{"FORM-3KYJN7RV-DIOD8LLK1WGQ89S7NHA92-QJVH497K-V":{"isFixed":"n","isFold":"n","isFoldHorizontal":"n","showAppTitle":false,"showCrumb":false,"showLanguageChange":false,"showNav":false,"showSearch":"n","singleton":false},"test":{"$ref":"$.singletons.FORM\\-3KYJN7RV\\-DIOD8LLK1WGQ89S7NHA92\\-QJVH497K\\-V"}},"type":"top_fold"}',
historyType: 'HASH',
isSinglePage: 'n',
rhino: 'n',
isMiniApp: '',
taskId: '',
appSchema: 'V5',
openSubMode: 'n',
};
window.g_config = {};
</script>
</head>
<body>
<!-- lowcode engine globals -->
<div id="lce-container"></div>
<script src="/js/editor-preset-vision.js"></script>
<script src="https://dev.g.alicdn.com/vision/visualengine-utils/5.0.0/engine-utils.js"></script>
</body>
</html>

View File

@ -97,22 +97,6 @@
"packageName": "@ali/vc-div",
"version": "1.0.1"
},
{
"prototypeConfigsUrl": [
"https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-page/1.0.5/proto.899e4b1.css",
"https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-page/1.0.5/proto.451d5fc.js"
],
"prototypeViewsUrl": null,
"alias": "",
"library": "AliVcPage",
"urls": [
"https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-page/1.0.5/view.3fdc557.css",
"https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-page/1.0.5/view.ae881b7.js"
],
"components": null,
"packageName": "@ali/vc-page",
"version": "1.0.5"
},
{
"prototypeConfigsUrl": [
"https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/vc-deep/2.1.12/proto.611ab53.css",

View File

@ -1,13 +1,6 @@
{
"componentName": "Page",
"fileName": "test",
"dataSource": {
"list": [],
"online": []
},
"state": {
"text": "outter"
},
"id": "node_1",
"props": {
"ref": "outterView",
"autoLoading": true,
@ -15,5 +8,884 @@
"padding": 20
}
},
"children": []
"fileName": "test",
"dataSource": {
"list": []
},
"state": {
"text": "outter",
"abc": [
1,
2,
3
]
},
"children": [
{
"componentName": "Steps",
"id": "node_1i",
"props": {
"dataSource": [
{
"title": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "报名"
},
"status": "",
"content": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "Open the refrigerator door"
},
"customSwitcher": false
},
{
"title": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "信息收集"
},
"status": "",
"content": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "Put the elephant in the refrigerator"
},
"customSwitcher": false
},
{
"title": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "审核"
},
"status": "",
"content": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": "Close the refrigerator door"
},
"customSwitcher": false
}
],
"current": 1,
"shape": "circle",
"direction": "horizontal",
"labelPlacement": "vertical",
"readOnly": false,
"animation": true,
"__style__": {},
"fieldId": "steps_kadcb0ov"
}
},
{
"componentName": "Title",
"id": "node_b",
"props": {
"text": "请填写以下人员信息表单",
"type": "primary",
"noDecoration": false,
"__style__": {},
"fieldId": "title_kadcb0nw"
}
},
{
"componentName": "Paragraph",
"id": "node_e",
"props": {
"content": "人最宝贵的是生命。它给予我们只有一次。人的一生应当这样度过:当他回首往事时不因虚度年华而悔恨,也不因碌碌无为而羞耻。这样在他临死的时侯就能够说:我已把我整个的生命和全部精力都献给最壮丽的事业——为人类的解放而斗争。",
"size": "medium",
"type": "long",
"__style__": {},
"fieldId": "paragraph_kadcb0nz"
}
},
{
"componentName": "ColumnsLayout",
"id": "node_r",
"props": {
"layout": "6:6",
"columnGap": "16px",
"rowGap": "16px",
"__style__": {
"marginTop": "24px"
},
"fieldId": "columnsLayout_kadcb0ob"
},
"children": [
{
"componentName": "Column",
"id": "node_s",
"props": {
"fieldId": "column_kadcb0o9",
"__style__": {}
},
"children": [
{
"componentName": "Card",
"id": "node_n",
"props": {
"title": "基本信息",
"subTitle": {
"type": "i18n",
"zh_CN": "",
"en_US": ""
},
"extra": {
"type": "JSSlot",
"params": null,
"value": [
{
"componentName": "Icon",
"id": "node_q",
"props": {
"type": {
"useType": true,
"baseType": "smile",
"otherType": "smile"
},
"size": "medium",
"__style__": {},
"fieldId": "icon_kadcb0o8"
}
}
]
},
"showTitleBullet": true,
"showHeadDivider": true,
"dividerNoInset": false,
"contentHeight": "",
"__style__": {},
"fieldId": "card_kadcb0o7"
},
"children": [
{
"componentName": "CardContent",
"id": "node_o",
"props": {},
"children": [
{
"componentName": "Form",
"id": "node_f",
"props": {
"labelAlign": "top",
"size": "medium",
"behavior": "NORMAL",
"autoValidate": true,
"scrollToFirstError": true,
"autoUnmount": true,
"fieldOptions": {},
"__style__": {
"marginTop": "24px"
},
"fieldId": "form_kadcb0o5"
},
"children": [
{
"componentName": "TextField",
"id": "node_g",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "姓名",
"value": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"placeholder": {
"type": "i18n",
"use": "zh_CN",
"en_US": "Please enter",
"zh_CN": "请输入"
},
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"htmlType": "input",
"state": "",
"rows": 4,
"autoHeight": false,
"hasClear": false,
"trim": false,
"autoFocus": false,
"addonBefore": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"addonAfter": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"validation": [],
"hasLimitHint": false,
"cutString": false,
"__style__": {},
"fieldId": "textField_kadcb0o0"
}
},
{
"componentName": "RadioField",
"id": "node_14",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "性别",
"value": "",
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"shape": "default",
"itemDirection": "hoz",
"dataSource": [
{
"text": {
"zh_CN": "选项一",
"en_US": "Option 1",
"type": "i18n",
"use": "zh_CN"
},
"value": "1",
"disable": false
},
{
"text": {
"zh_CN": "选项二",
"en_US": "Option 2",
"type": "i18n",
"use": "zh_CN"
},
"value": "2",
"disable": false
},
{
"text": {
"zh_CN": "选项三",
"en_US": "Option 3",
"type": "i18n",
"use": "zh_CN"
},
"value": "3",
"disable": true
}
],
"validation": [],
"__style__": {},
"fieldId": "radioField_kadcb0ok"
}
},
{
"componentName": "SelectField",
"id": "node_h",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "学校",
"value": "",
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"placeholder": {
"type": "i18n",
"use": "zh_CN",
"en_US": "please select",
"zh_CN": "请选择"
},
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"mode": "single",
"hasClear": false,
"hasSelectAll": false,
"showSearch": false,
"filterLocal": true,
"dataSource": [
{
"text": {
"zh_CN": "选项一",
"en_US": "Option 1",
"type": "i18n"
},
"value": "1"
},
{
"text": {
"zh_CN": "选项二",
"en_US": "Option 2",
"type": "i18n"
},
"value": "2"
},
{
"text": {
"zh_CN": "选项三",
"en_US": "Option 3",
"type": "i18n"
},
"value": "3"
}
],
"validation": [],
"notFoundContent": {
"type": "i18n",
"use": "zh_CN",
"en_US": null
},
"hasArrow": true,
"hasBorder": true,
"autoWidth": true,
"searchDelay": 300,
"__style__": {},
"fieldId": "select_kadcb0o1"
}
},
{
"componentName": "Div",
"id": "node_i",
"props": {
"behavior": "NORMAL",
"__style__": {},
"fieldId": "div_kadcb0o4"
},
"children": [
{
"componentName": "Button",
"id": "node_j",
"props": {
"content": {
"type": "i18n",
"en_US": "Ok",
"zh_CN": "提交"
},
"type": "primary",
"size": "medium",
"behavior": "NORMAL",
"baseIcon": "",
"otherIcon": "",
"loading": false,
"triggerEventsWhenLoading": false,
"__style__": ":root {\n margin-right: 15px;\n}",
"fieldId": "button_kadcb0o2",
"onClick": {
"type": "JSExpression",
"value": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}",
"extType": "function",
"events": [
{
"name": "onClick",
"params": {},
"func": {
"type": "js",
"source": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}",
"compiled": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}"
}
}
]
}
}
},
{
"componentName": "Button",
"id": "node_k",
"props": {
"content": {
"type": "i18n",
"en_US": "Reset",
"zh_CN": "重置"
},
"type": "secondary",
"size": "medium",
"behavior": "NORMAL",
"baseIcon": "",
"otherIcon": "",
"loading": false,
"triggerEventsWhenLoading": false,
"__style__": {},
"fieldId": "button_kadcb0o3",
"onClick": {
"type": "JSExpression",
"value": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}",
"extType": "function",
"events": [
{
"name": "onClick",
"params": {},
"func": {
"type": "js",
"source": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}",
"compiled": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}"
}
}
]
}
}
}
]
}
]
}
]
}
]
}
]
},
{
"componentName": "Column",
"id": "node_t",
"props": {
"fieldId": "column_kadcb0oa",
"__style__": {}
},
"children": [
{
"componentName": "Card",
"id": "node_u",
"props": {
"title": {
"type": "JSSlot",
"params": null,
"value": [
{
"componentName": "Icon",
"id": "node_18",
"props": {
"type": {
"useType": true,
"baseType": "smile",
"otherType": "smile"
},
"size": "medium",
"__style__": {},
"fieldId": "icon_kadcb0on"
}
},
{
"componentName": "Link",
"id": "node_19",
"props": {
"content": {
"type": "i18n",
"use": "zh_CN",
"en_US": "link text",
"zh_CN": "扩展信息"
},
"textOverflow": false,
"link": {
"type": "page",
"page": null,
"router": {
"type": "JSExpression",
"value": "this.utils.router"
}
},
"__style__": {},
"fieldId": "link_kadcb0oo"
}
}
]
},
"subTitle": {
"type": "i18n",
"zh_CN": "",
"en_US": ""
},
"extra": {
"type": "JSSlot",
"params": null,
"value": [
{
"componentName": "Icon",
"id": "node_1a",
"props": {
"type": {
"useType": true,
"baseType": "smile",
"otherType": "smile"
},
"size": "xl",
"__style__": {},
"fieldId": "icon_kadcb0op"
}
}
]
},
"showTitleBullet": true,
"showHeadDivider": true,
"dividerNoInset": false,
"contentHeight": "",
"__style__": {},
"fieldId": "card_kadcb0oc"
},
"children": [
{
"componentName": "CardContent",
"id": "node_v",
"props": {},
"children": [
{
"componentName": "Form",
"id": "node_x",
"props": {
"labelAlign": "top",
"size": "medium",
"behavior": "NORMAL",
"autoValidate": true,
"scrollToFirstError": true,
"autoUnmount": true,
"fieldOptions": {},
"__style__": {
"marginTop": "24px"
},
"fieldId": "form_kadcb0oi"
},
"children": [
{
"componentName": "TextField",
"id": "node_y",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "职位",
"value": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"placeholder": {
"type": "i18n",
"use": "zh_CN",
"en_US": "Please enter",
"zh_CN": "请输入"
},
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"htmlType": "input",
"state": "",
"rows": 4,
"autoHeight": false,
"hasClear": false,
"trim": false,
"autoFocus": false,
"addonBefore": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"addonAfter": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"validation": [],
"hasLimitHint": false,
"cutString": false,
"__style__": {},
"fieldId": "textField_kadcb0od"
}
},
{
"componentName": "DateField",
"id": "node_15",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "入职时间",
"value": "",
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"placeholder": {
"type": "i18n",
"use": "zh_CN",
"en_US": "please select",
"zh_CN": "请选择"
},
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"format": "YYYY-MM-DD",
"returnType": "timestamp",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"hasClear": true,
"resetTime": false,
"disabledDate": false,
"validation": [],
"__style__": {},
"fieldId": "dateField_kadcb0ol"
}
},
{
"componentName": "SelectField",
"id": "node_z",
"props": {
"__category__": "form",
"__useMediator": "value",
"label": "下拉选择",
"value": "",
"labelAlign": "top",
"labelColSpan": 4,
"labelColOffset": 0,
"wrapperColSpan": 0,
"wrapperColOffset": 0,
"labelTextAlign": "right",
"placeholder": {
"type": "i18n",
"use": "zh_CN",
"en_US": "please select",
"zh_CN": "请选择"
},
"tips": {
"zh_CN": "",
"en_US": "",
"type": "i18n"
},
"size": "medium",
"behavior": "NORMAL",
"labelTipsTypes": "none",
"labelTipsIcon": "",
"labelTipsText": {
"type": "i18n",
"use": "zh_CN",
"en_US": null,
"zh_CN": ""
},
"mode": "single",
"hasClear": false,
"hasSelectAll": false,
"showSearch": false,
"filterLocal": true,
"dataSource": [
{
"text": {
"zh_CN": "选项一",
"en_US": "Option 1",
"type": "i18n"
},
"value": "1"
},
{
"text": {
"zh_CN": "选项二",
"en_US": "Option 2",
"type": "i18n"
},
"value": "2"
},
{
"text": {
"zh_CN": "选项三",
"en_US": "Option 3",
"type": "i18n"
},
"value": "3"
}
],
"validation": [],
"notFoundContent": {
"type": "i18n",
"use": "zh_CN",
"en_US": null
},
"hasArrow": true,
"hasBorder": true,
"autoWidth": true,
"searchDelay": 300,
"__style__": {},
"fieldId": "select_kadcb0oe"
}
},
{
"componentName": "Div",
"id": "node_10",
"props": {
"behavior": "NORMAL",
"__style__": {},
"fieldId": "div_kadcb0oh"
},
"children": [
{
"componentName": "Button",
"id": "node_11",
"props": {
"content": {
"type": "i18n",
"en_US": "Ok",
"zh_CN": "提交"
},
"type": "primary",
"size": "medium",
"behavior": "NORMAL",
"baseIcon": "",
"otherIcon": "",
"loading": false,
"triggerEventsWhenLoading": false,
"__style__": ":root {\n margin-right: 15px;\n}",
"fieldId": "button_kadcb0of",
"onClick": {
"type": "JSExpression",
"value": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}",
"extType": "function",
"events": [
{
"name": "onClick",
"params": {},
"func": {
"type": "js",
"source": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}",
"compiled": "function onSubmit(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').submit(function(data, error) {\n if (data) {\n console.log(data);\n // 往后端提交数据,一般写法如下\n // this.dataSourceMap['xxx'].load(data).then(() => {\n // this.utils.toast({\n // type: 'success',\n // title: '提交成功'\n // });\n // });\n }\n });\n}"
}
}
]
}
}
},
{
"componentName": "Button",
"id": "node_12",
"props": {
"content": {
"type": "i18n",
"en_US": "Reset",
"zh_CN": "重置"
},
"type": "secondary",
"size": "medium",
"behavior": "NORMAL",
"baseIcon": "",
"otherIcon": "",
"loading": false,
"triggerEventsWhenLoading": false,
"__style__": {},
"fieldId": "button_kadcb0og",
"onClick": {
"type": "JSExpression",
"value": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}",
"extType": "function",
"events": [
{
"name": "onClick",
"params": {},
"func": {
"type": "js",
"source": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}",
"compiled": "function onReset(){\n // 请将 fieldId 替换为表单容器的 fieldId\n this.$('fieldId').reset();\n}"
}
}
]
}
}
}
]
}
]
}
]
}
]
}
]
}
]
}
]
}

View File

@ -1 +1 @@
import './editor';
import './vision';

View File

@ -0,0 +1,517 @@
/* eslint-disable */
import { createElement } from 'react';
import { Button } from '@alifd/next';
import Engine, { Panes, Prototype } from '@ali/visualengine';
import { ActionUtil as actionUtil } from '@ali/visualengine-utils';
import getTrunkPane from '@ali/ve-trunk-pane';
import DatapoolPane from '@ali/ve-datapool-pane';
import PageHistoryManager from '@ali/ve-page-history';
import HistoryPane from '@ali/ve-history-pane';
import PageHistoryPane from '@ali/ve-page-history-pane';
// import I18nPane from '@ali/ve-i18n-pane';
import I18nManagePane from '@ali/ve-i18n-manage-pane';
import ActionPane from '@ali/ve-action-pane';
import SourceEditor from '@ali/lowcode-plugin-source-editor';
import fetchContext from '@ali/vu-legao-design-fetch-context';
import EventBindDialog from '@ali/lowcode-plugin-event-bind-dialog';
import loadUrls from './loader';
import { upgradeAssetsBundle } from './upgrade-assets';
import { isCSSUrl } from '@ali/lowcode-utils';
import VariableSetter from '@ali/vs-variable-setter';
import _isArray from "lodash/isArray";
import _isObject from "lodash/isObject";
import _get from 'lodash/get';
import funcParser from '@ali/vu-function-parser';
import {
NumberSetter,
BoolSetter,
ChoiceSetter,
CodeSetter,
ColorSetter,
DateSetter,
I18nSetter,
JsonSetter,
ListSetter,
SelectSetter,
OptionsSetter,
TextSetter,
ValidationSetter,
ActionSetter,
} from '@ali/visualengine-utils';
const { editor, skeleton, context, HOOKS, Trunk } = Engine;
Trunk.registerSetter('Input', TextSetter);
Trunk.registerSetter('StringSetter', TextSetter);
Trunk.registerSetter('TextArea', TextSetter);
Trunk.registerSetter('Object', JsonSetter);
Trunk.registerSetter('Function', ActionSetter);
Trunk.registerSetter('Node', CodeSetter);
Trunk.registerSetter('Mixin', CodeSetter);
Trunk.registerSetter('Expression', CodeSetter);
Trunk.registerSetter('List', ListSetter);
Trunk.registerSetter('Switch', BoolSetter);
Trunk.registerSetter('Number', NumberSetter);
Trunk.registerSetter('Select', SelectSetter);
Trunk.registerSetter('ActionSetter', ActionSetter);
Trunk.registerSetter('BoolSetter', BoolSetter);
Trunk.registerSetter('ChoiceSetter', ChoiceSetter);
Trunk.registerSetter('CodeSetter', CodeSetter);
Trunk.registerSetter('ColorSetter', ColorSetter);
Trunk.registerSetter('DateSetter', DateSetter);
Trunk.registerSetter('JsonSetter', JsonSetter);
Trunk.registerSetter('ListSetter', ListSetter);
Trunk.registerSetter('SelectSetter', SelectSetter);
Trunk.registerSetter('OptionsSetter', OptionsSetter);
Trunk.registerSetter('TextSetter', TextSetter);
Trunk.registerSetter('NumberSetter', NumberSetter);
Trunk.registerSetter('ValidationSetter', ValidationSetter);
// 需要额外覆盖配置的 setters
function wrapSetter(component: any, title: any, initialValueWrapper: any) {
return {
component,
title,
recommend: true,
initialValue: initialValueWrapper ? (field: any) => {
let defaultValueFromSetter;
if (component.initial) {
defaultValueFromSetter = component.initial.call(field, field.getValue());
}
const defaultValue = initialValueWrapper(defaultValueFromSetter);
return defaultValue;
} : undefined,
}
}
Trunk.registerSetter('I18nSetter', wrapSetter(
I18nSetter,
{ type: 'i18n', 'zh-CN': '国际化输入', 'en-US': 'International Input' },
(defaultValue: any) => {
if (defaultValue[defaultValue.use] && typeof defaultValue[defaultValue.use] !== 'string') {
defaultValue[defaultValue.use] = null;
}
return defaultValue;
}
));
context.use(HOOKS.VE_SETTING_FIELD_VARIABLE_SETTER, VariableSetter);
const externals = ['react', 'react-dom', 'prop-types', 'react-router', 'react-router-dom', '@ali/recore'];
async function loadAssets() {
const legaoAssets = await editor.utils.get('./legao-assets.json');
const assets = upgradeAssetsBundle(legaoAssets);
if (assets.packages) {
assets.packages.forEach((item: any) => {
if (item.package && externals.indexOf(item.package) > -1) {
item.urls = null;
}
});
}
if (assets['x-prototypes']) {
const tasks: Array<Promise<any>> = [];
const prototypeStyles: string[] = [];
assets['x-prototypes'].forEach((pkg: any) => {
if (pkg?.urls) {
const urls = Array.isArray(pkg.urls) ? pkg.urls : [pkg.urls];
urls.forEach((url: string) => {
if (isCSSUrl(url)) {
prototypeStyles.push(url);
}
});
tasks.push(loadUrls(urls));
}
});
if (prototypeStyles.length > 0) {
assets.packages.push({
library: '_prototypesStyle',
package: '_prototypes-style',
urls: prototypeStyles,
});
}
await Promise.all(tasks);
// proccess snippets
}
editor.set('legao-assets', legaoAssets);
editor.set('assets', assets);
}
async function loadSchema() {
const schema = await editor.utils.get('./schema.json');
editor.set('schema', schema);
}
// demo
function initDemoPanes() {
skeleton.add({
name: 'eventBindDialog',
type: 'Widget',
content: EventBindDialog,
});
// skeleton.add({
// area: 'left',
// name: 'sourceEditor',
// type: "PanelDock",
// content: SourceEditor,
// props: {
// align: undefined,
// description: "动作面板",
// onDestroy: undefined,
// icon: 'set',
// onInit: undefined
// },
// panelProps:{
// height: 300,
// help: undefined,
// hideTitleBar: true,
// maxHeight: 800,
// maxWidth: 1200,
// title: "动作面板",
// width: 600
// }
// });
// skeleton.add({
// area: 'leftArea',
// name: 'icon1',
// type: 'PanelDock',
// props: {
// align: 'bottom',
// icon: 'set',
// description: '设置'
// },
// });
skeleton.add({
area: 'leftArea',
name: 'icon2',
type: 'Dock',
props: {
align: 'bottom',
icon: 'help',
description: '帮助'
},
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'publish',
props: {
align: 'right',
},
content: createElement(Button, {
size: 'small',
type: 'secondary',
children: '发布',
}),
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'save',
props: {
align: 'right',
},
content: createElement(Button, {
size: 'small',
type: 'primary',
children: '保存',
}),
});
// skeleton.add({
// area: 'topArea',
// type: 'Dock',
// name: 'preview4',
// props: {
// align: 'center',
// },
// content: createElement('img', {
// src: 'https://img.alicdn.com/tfs/TB1WW.VC.z1gK0jSZLeXXb9kVXa-486-64.png',
// style: {
// height: 32,
// },
// }),
// });
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'preview1',
props: {
align: 'left',
},
content: createElement('img', {
src: 'https://img.alicdn.com/tfs/TB1zqBfDlr0gK0jSZFnXXbRRXXa-440-64.png',
style: {
height: 32,
},
}),
});
}
async function initTrunkPane() {
const assets = await editor.onceGot('legao-assets');
const config = {
disableLowCodeComponent: true,
disableComponentStore: true,
app: {
getAssetsData() {
return assets;
// return data;
},
},
};
const TrunkPane = getTrunkPane(config);
Panes.add(TrunkPane);
}
// 数据源面板
function initDataPoolPane() {
const dpConfigs = {};
if (!dpConfigs) {
return;
}
fetchContext.create('DataPoolPaneAPI', {
saveGlobalConfig: {
url: 'query/appConfig/saveGlobalConfig.json',
method: 'POST',
},
saveOrUpdateAppDataPool: {
url: 'query/appDataPool/saveOrUpdateAppDataPool.json',
method: 'POST',
},
batchSaveOrUpdateAppDataPool: {
url: 'query/appDataPool/batchSaveOrUpdateAppDataPool.json',
method: 'POST'
},
listAppDataPool: {
url: 'query/appDataPool/listAppDataPool.json',
method: 'GET',
},
getAppDataPool: {
url: 'query/appDataPool/getAppDataPool.json',
method: 'POST',
},
getEpaasApiInApp: {
url: 'query/formdesign/getEpaasApiInApp.jsonp',
method: 'GET',
},
getFormListOrder: {
url: 'query/formdesign/getFormListOrder.json',
method: 'GET',
},
// 实时修改 effectForm
operateAppDpBind: {
url: 'query/appDataPool/operateAppDpBind.json',
method: 'POST',
},
// 校验全局数据源是否被其他页面修改
checkAppDataPoolModified: {
url: 'query/appDataPool/checkAppDataPoolModified.json',
method: 'POST',
},
});
const props = {
enableGateService: true,
enableGlobalFitConfig: true,
enableOneAPIService: true,
formUuid: 'xxx',
api: fetchContext.api.DataPoolPaneAPI,
};
Panes.add(DatapoolPane, {
props,
});
}
// 国际化面板
function initI18nPane() {
fetchContext.create('I18nManagePaneAPI', {
// 绑定美杜莎
bindMedusa: {
url: 'query/app/createMedusa.json',
},
// 解除绑定
unbindMedusa: {
url: 'query/app/removeMedusa.json',
},
// 同步美杜莎
syncMedusa: {
url: 'query/formi18n/syncI18n.json',
},
});
Panes.add(I18nManagePane, {
props: {
enableMedusa: true,
api: fetchContext.api.I18nManagePaneAPI,
},
});
}
// 动作面板
function initActionPane() {
actionUtil.setActions({
module: {
compiled: "'use strict';\n\nexports.__esModule = true;\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.submit = submit;\nexports.onLoadData = onLoadData;\nexports.add = add;\nexports.edit = edit;\nexports.del = del;\nexports.search = search;\nexports.reset = reset;\n/**\n* 点击弹框的“确认”\n*/\nfunction submit() {\n var _this = this;\n\n this.$('form').submit(function (data, error) {\n if (data) {\n _this.dataSourceMap['table_submit'].load(data).then(function (res) {\n _this.utils.toast({\n type: 'success',\n title: '提交成功'\n });\n _this.$('dialog').hide();\n _this.dataSourceMap['table_list'].load();\n }).catch(function () {\n _this.utils.toast({\n type: 'error',\n title: '提交失败'\n });\n });\n }\n });\n}\n\n/**\n* tablePc onLoadData\n* @param currentPage 当前页码\n* @param pageSize 每页显示条数\n* @param searchKey 搜索关键字\n* @param orderColumn 排序列\n* @param orderType 排序方式desc,asc\n* @param from 触发来源order,search,pagination\n*/\nfunction onLoadData(currentPage, pageSize, searchKey, orderColumn, orderType, from) {\n var tableParams = {\n currentPage: from === 'search' ? 1 : currentPage,\n pageSize: pageSize,\n searchKey: searchKey,\n orderColumn: orderColumn,\n orderType: orderType\n };\n this.setState({ tableParams: tableParams });\n}\n\n// 点击新增\nfunction add() {\n this.setState({\n formData: null\n });\n this.$('dialog').show();\n}\n\n// 点击编辑\nfunction edit(rowData) {\n this.setState({\n formData: rowData\n });\n this.$('dialog').show();\n}\n\n// 点击删除\nfunction del(rowData) {\n var _this2 = this;\n\n this.utils.dialog({\n method: 'confirm',\n title: '提示',\n content: '确认删除该条目吗?',\n onOk: function onOk() {\n _this2.dataSourceMap['table_delete'].load({ id: rowData.id }).then(function () {\n _this2.utils.toast({\n type: 'success',\n title: '删除成功'\n });\n _this2.dataSourceMap['table_list'].load();\n }).catch(function () {\n _this2.utils.toast({\n type: 'error',\n title: '删除失败'\n });\n });\n }\n });\n}\n\n/**\n* button onClick\n*/\nfunction search() {\n var filterData = this.$('filter').getValue();\n this.setState({\n filterData: filterData,\n tableParams: _extends({}, this.state.tableParams, {\n time: Date.now(),\n currentPage: 1\n })\n });\n}\n\n/**\n* button onClick\n*/\nfunction reset() {\n this.$('filter').reset();\n this.setState({\n filterData: {},\n tableParams: _extends({}, this.state.tableParams, {\n time: Date.now(),\n currentPage: 1\n })\n });\n}",
source: "/**\n* 点击弹框的“确认”\n*/\nexport function submit() {\n this.$('form').submit((data, error) => {\n if (data) {\n this.dataSourceMap['table_submit'].load(data).then((res) => {\n this.utils.toast({\n type: 'success',\n title: '提交成功'\n });\n this.$('dialog').hide();\n this.dataSourceMap['table_list'].load();\n }).catch(()=>{\n this.utils.toast({\n type: 'error',\n title: '提交失败'\n });\n })\n }\n })\n}\n\n/**\n* tablePc onLoadData\n* @param currentPage 当前页码\n* @param pageSize 每页显示条数\n* @param searchKey 搜索关键字\n* @param orderColumn 排序列\n* @param orderType 排序方式desc,asc\n* @param from 触发来源order,search,pagination\n*/\nexport function onLoadData(currentPage, pageSize, searchKey, orderColumn, orderType, from) {\n const tableParams = {\n currentPage: from === 'search' ? 1 : currentPage,\n pageSize,\n searchKey,\n orderColumn,\n orderType\n };\n this.setState({ tableParams });\n}\n\n// 点击新增\nexport function add() {\n this.setState({\n formData: null,\n });\n this.$('dialog').show();\n}\n\n\n// 点击编辑\nexport function edit(rowData) {\n this.setState({\n formData: rowData\n });\n this.$('dialog').show();\n}\n\n// 点击删除\nexport function del(rowData) {\n this.utils.dialog({\n method: 'confirm',\n title: '提示',\n content: '确认删除该条目吗?',\n onOk: () => {\n this.dataSourceMap['table_delete'].load({ id: rowData.id }).then(() => {\n this.utils.toast({\n type: 'success',\n title: '删除成功'\n });\n this.dataSourceMap['table_list'].load();\n }).catch(()=>{\n this.utils.toast({\n type: 'error',\n title: '删除失败'\n });\n })\n }\n })\n}\n\n/**\n* button onClick\n*/\nexport function search(){\n const filterData = this.$('filter').getValue();\n this.setState({\n filterData,\n tableParams: {\n ...this.state.tableParams,\n time: Date.now(),\n currentPage: 1\n }\n });\n}\n\n/**\n* button onClick\n*/\nexport function reset(){\n this.$('filter').reset();\n this.setState({\n filterData: {},\n tableParams: {\n ...this.state.tableParams,\n time: Date.now(),\n currentPage: 1\n }\n });\n}"
},
type: "FUNCTION",
list: [
{
"id": "submit",
"title": "submit"
},
{
"id": "onLoadData",
"title": "onLoadData"
},
{
"id": "add",
"title": "add"
},
{
"id": "edit",
"title": "edit"
},
{
"id": "del",
"title": "del"
},
{
"id": "search",
"title": "search"
},
{
"id": "reset",
"title": "reset"
}
]
});
const props = {
enableGlobalJS: false,
enableVsCodeEdit: false,
enableHeaderTip: true,
};
Panes.add(ActionPane, {
props,
});
}
function replaceFuncProp(props?: any){
const replaceProps: any = {};
for (const name in props) {
const prop = props[name];
if (!prop) {
continue;
}
if ((prop.compiled && prop.source) || prop.type === 'actionRef' || prop.type === 'js') {
replaceProps[name] = funcParser(prop);
} else if (_isObject(prop)) {
replaceFuncProp(prop);
} else if (_isArray(prop)) {
prop.map((propItem) => {
replaceFuncProp(propItem);
});
}
}
for (const name in replaceProps) {
props[name] = replaceProps[name];
}
return props;
};
// 操作历史与页面历史面板
function initHistoryPane() {
// let historyConfigs = {getDesignerModuleConfigs(
// this.designerConfigs,
// 'history',
// )};
let historyConfigs = {
enableRedoAndUndo: true,
enablePageHistory: true,
};;
const isDemoMode = false;
const isEnvSupportsHistoryPane = true;
const historyManager = PageHistoryManager.getManager();
console.log('PageHistoryManager', historyManager);
console.log('PageHistoryManager.onOpenPane', historyManager.onOpenPane);
// 历史撤销、重做以及唤起页面历史按钮
if (typeof HistoryPane === 'function') {
Panes.add(HistoryPane, {
props : {
showPageHistory:
isEnvSupportsHistoryPane
// && this.app.isForm()
&& !isDemoMode,
historyManager,
historyConfigs,
index: -940,
}
});
} else {
Panes.add(HistoryPane, {
index: -940,
});
}
// 页面历史 UI 面板
if (
PageHistoryPane
&& !isDemoMode
&& isEnvSupportsHistoryPane
) {
Panes.add(PageHistoryPane, {
props : {
historyManager: {
historyManager,
app: {
}
},
index: -940,
},
});
}
}
async function init() {
Engine.Env.setEnv('RE_VERSION', '7.2.0');
Engine.Env.setSupportFeatures({
subview: true,
i18nPane: true,
});
Prototype.addGlobalPropsReducer(replaceFuncProp);
await loadAssets();
await loadSchema();
await initTrunkPane();
// initDataPoolPane();
// initI18nPane();
// initActionPane();
initDemoPanes();
// initHistoryPane();
Engine.init();
}
init();

View File

@ -0,0 +1,172 @@
/* eslint-disable */
function getStylePoint(id, level) {
if (stylePointTable[id]) {
return stylePointTable[id];
}
const base = getBasePoint();
if (id === 'base') {
return base;
}
const point = new StylePoint(id, level || 2000);
if (level >= base.level) {
let prev = base;
let next = prev.next;
while (next && level >= next.level) {
prev = next;
next = prev.next;
}
prev.next = point;
point.prev = prev;
if (next) {
point.next = next;
next.prev = point;
}
} else {
let next = base;
let prev = next.prev;
while (prev && level < prev.level) {
next = prev;
prev = next.prev;
}
next.prev = point;
point.next = next;
if (prev) {
point.prev = prev;
prev.next = point;
}
}
point.insert();
stylePointTable[id] = point;
return point;
}
const stylePointTable = {};
function getBasePoint() {
if (!stylePointTable.base) {
stylePointTable.base = new StylePoint('base', 1000);
stylePointTable.base.insert();
}
return stylePointTable.base;
}
class StylePoint {
constructor(id, level, placeholder) {
this.lastContent = null;
this.lastUrl = null;
this.next = null;
this.prev = null;
this.id = id;
this.level = level;
if (placeholder) {
this.placeholder = placeholder;
} else {
this.placeholder = document.createTextNode('');
}
}
insert() {
if (this.next) {
document.head.insertBefore(this.placeholder, this.next.placeholder);
} else if (this.prev) {
document.head.insertBefore(this.placeholder, this.prev.placeholder.nextSibling);
} else {
document.head.appendChild(this.placeholder);
}
}
applyText(content) {
if (this.lastContent === content) {
return;
}
this.lastContent = content;
this.lastUrl = undefined;
const element = document.createElement('style');
element.setAttribute('type', 'text/css');
element.setAttribute('data-for', this.id);
element.appendChild(document.createTextNode(content));
document.head.insertBefore(element, this.placeholder);
document.head.removeChild(this.placeholder);
this.placeholder = element;
}
applyUrl(url) {
if (this.lastUrl === url) {
return;
}
this.lastContent = undefined;
this.lastUrl = url;
const element = document.createElement('link');
element.href = url;
element.rel = 'stylesheet';
element.setAttribute('data-for', this.id);
document.head.insertBefore(element, this.placeholder);
document.head.removeChild(this.placeholder);
this.placeholder = element;
}
}
function loadCSS(url) {
getStylePoint(url).applyUrl(url);
}
function isCSSUrl(url) {
return /\.css$/.test(url);
}
function loadScript(url) {
const node = document.createElement('script');
// node.setAttribute('crossorigin', 'anonymous');
node.onload = onload;
node.onerror = onload;
const i = {};
const promise = new Promise((resolve, reject) => {
i.resolve = resolve;
i.reject = reject;
});
function onload(e) {
node.onload = null;
node.onerror = null;
if (e.type === 'load') {
i.resolve();
} else {
i.reject();
}
// document.head.removeChild(node);
// node = null;
}
// node.async = true;
node.src = url;
document.head.appendChild(node);
return promise;
}
export default function loadUrls(urls) {
if (!urls || urls.length < 1) {
return Promise.resolve();
}
let promise = null;
urls.forEach((url) => {
if (isCSSUrl(url)) {
loadCSS(url);
} else if (!promise) {
promise = loadScript(url);
} else {
promise = promise.then(() => loadScript(url));
}
});
return promise || Promise.resolve();
}

13
packages/demo/src/vision/module.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
declare module '@ali/visualengine';
declare module '@ali/visualengine-utils';
declare module '@ali/ve-trunk-pane';
declare module '@ali/vs-variable-setter';
declare module '@ali/ve-datapool-pane';
declare module '@ali/ve-history-pane';
declare module '@ali/ve-page-history-pane';
declare module '@ali/ve-page-history';
declare module '@ali/ve-i18n-manage-pane';
declare module '@ali/ve-action-pane';
declare module '@ali/vu-legao-design-fetch-context';
declare module "@ali/vu-function-parser";
declare module "compare-versions";

View File

@ -0,0 +1,68 @@
/* eslint-disable */
export function upgradeAssetsBundle(assets) {
const components = [];
const xPrototypes = [];
const componentList = [];
const packages = assets.externals.map(({ urls, library, name, version }) => {
return {
package: name,
version,
urls,
library,
};
});
assets.componentDependencies.forEach((item) => {
const componentName = item.alias || item.library;
const metadata = {
componentName,
npm: {
package: item.packageName,
library: item.library,
version: item.version,
destructuring: false,
},
props: [],
};
if (item.prototypeConfigsUrl) {
xPrototypes.push({
package: item.packageName,
urls: item.prototypeConfigsUrl,
});
} else if (item.components) {
packages.push({
urls: item.urls,
library: item.library,
package: item.packageName,
version: item.version,
});
const meta = item.components[0];
metadata.componentName = meta.componentName;
metadata.configure = meta.configure;
metadata.title = meta.title;
components.push(metadata);
// TODO:
if (meta.snippets) {
componentList.push({
title: meta.category,
icon: '',
children: [
{
title: 'json格式化展示',
icon: '',
snippets: meta.snippets,
},
],
});
}
}
});
return {
"version": "1.0.0",
packages,
'x-prototypes': xPrototypes,
components,
componentList
};
}

View File

@ -3,6 +3,98 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.9.20"></a>
## [0.9.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.19...@ali/lowcode-designer@0.9.20) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.19"></a>
## [0.9.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.18...@ali/lowcode-designer@0.9.19) (2020-06-15)
### Bug Fixes
* force schema ([6d0a8ff](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/6d0a8ff))
* patch prototype ([f20bfaa](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/f20bfaa))
* try get settingfield ([56f242f](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/56f242f))
* 禁止组件拉到 Page 的直接子节点, 以及替换 tab 组件 ([d93a291](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/d93a291))
### Features
* complete live-editing expr & i18n ([3ac08ba](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/3ac08ba))
* get SettingField instead of SettingPropEntry for compatibility ([2787a12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/2787a12))
* support prop.autorun ([c0a5235](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c0a5235))
* ve事件埋点 ([700e5b0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/700e5b0))
<a name="0.9.18"></a>
## [0.9.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.17...@ali/lowcode-designer@0.9.18) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.17"></a>
## [0.9.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.16...@ali/lowcode-designer@0.9.17) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.16"></a>
## [0.9.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.15...@ali/lowcode-designer@0.9.16) (2020-05-18)
### Bug Fixes
* uniqueid ([8db52f0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/8db52f0))
<a name="0.9.15"></a>
## [0.9.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.14...@ali/lowcode-designer@0.9.15) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.14"></a>
## [0.9.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.13...@ali/lowcode-designer@0.9.14) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.13"></a>
## [0.9.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.12...@ali/lowcode-designer@0.9.13) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-designer
<a name="0.9.12"></a>
## [0.9.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.11...@ali/lowcode-designer@0.9.12) (2020-05-15)
### Features
* change reducer stage ([c2e83c7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c2e83c7))
<a name="0.9.11"></a>
## [0.9.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.10...@ali/lowcode-designer@0.9.11) (2020-05-15)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-designer",
"version": "0.9.11",
"version": "0.9.20",
"description": "Designer for Ali LowCode Engine",
"main": "lib/index.js",
"module": "es/index.js",
@ -15,9 +15,9 @@
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-types": "^0.8.3",
"@ali/lowcode-utils": "^0.8.4",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-types": "^0.8.6",
"@ali/lowcode-utils": "^0.8.7",
"classnames": "^2.2.6",
"event": "^1.0.0",
"react": "^16",

View File

@ -1,6 +1,6 @@
import { Component, Fragment } from 'react';
import DragResizeEngine from './drag-resize-engine';
import { observer, computed } from '@ali/lowcode-editor-core';
import { observer, computed, globalContext, Editor } from '@ali/lowcode-editor-core';
import classNames from 'classnames';
import { SimulatorContext } from '../context';
import { BuiltinSimulatorHost } from '../host';
@ -177,6 +177,17 @@ export class BoxResizingInstance extends Component<{
e.trigger = direction;
metaData.experimental.callbacks.onResizeStart(e, node);
}
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
editor?.emit('designer.border.resize', {
selected,
layout: node?.parent?.getPropValue('layout') || '',
});
};
this.dragEngine.onResize(resize);

View File

@ -9,7 +9,7 @@ import {
ComponentType,
} from 'react';
import classNames from 'classnames';
import { observer, computed, Tip } from '@ali/lowcode-editor-core';
import { observer, computed, Tip, globalContext, Editor } from '@ali/lowcode-editor-core';
import { createIcon, isReactComponent } from '@ali/lowcode-utils';
import { ActionContentObject, isActionContentObject } from '@ali/lowcode-types';
import { BuiltinSimulatorHost } from '../host';
@ -124,6 +124,16 @@ function createAction(content: ReactNode | ComponentType<any> | ActionContentObj
className="lc-borders-action"
onClick={() => {
action && action(node);
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const target =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
editor?.emit('designer.border.action', {
name: key,
target,
});
}}
>
{icon && createIcon(icon)}

View File

@ -1,6 +1,6 @@
import * as EventEmitter from 'events';
import { ISimulatorHost, isSimulatorHost } from '../../../../designer/src/simulator';
import { Designer } from '../../../../designer/src/designer/designer';
import { EventEmitter } from 'events';
import { ISimulatorHost, isSimulatorHost } from '../../simulator';
import { Designer, Point } from '../../designer';
import { setNativeSelection, cursor } from '@ali/lowcode-utils';
// import Cursor from './cursor';
// import Pages from './pages';
@ -66,21 +66,37 @@ export default class DragResizeEngine {
*/
from(shell: Element, direction: string, boost: (e: MouseEvent) => any) {
let node: any;
let startEvent: MouseEvent;
let startEvent: Point;
if (!shell) {
return () => {};
}
const move = (e: MouseEvent) => {
const moveX = e.clientX - startEvent.clientX;
const moveY = e.clientY - startEvent.clientY;
const x = createResizeEvent(e);
const moveX = x.clientX - startEvent.clientX;
const moveY = x.clientY - startEvent.clientY;
this.emitter.emit('resize', e, direction, node, moveX, moveY);
};
const masterSensors = this.getMasterSensors();
const createResizeEvent = (e: MouseEvent | DragEvent): Point => {
const evt: any = {};
const sourceDocument = e.view?.document;
if (!sourceDocument || sourceDocument === document) {
return e;
}
const srcSim = masterSensors.find((sim) => sim.contentDocument === sourceDocument);
if (srcSim) {
return srcSim.viewport.toGlobalPoint(e);
}
return e;
};
const over = (e: MouseEvent) => {
const handleEvents = makeEventsHandler(e, masterSensors);
handleEvents((doc) => {
@ -96,7 +112,7 @@ export default class DragResizeEngine {
const mousedown = (e: MouseEvent) => {
node = boost(e);
startEvent = e;
startEvent = createResizeEvent(e);
const handleEvents = makeEventsHandler(e, masterSensors);
handleEvents((doc) => {
doc.addEventListener('mousemove', move, true);

View File

@ -1,10 +1,10 @@
import { obx, autorun, computed, getPublicPath, hotkey, focusTracker } from '@ali/lowcode-editor-core';
import { obx, autorun, computed, getPublicPath, hotkey, focusTracker, globalContext, Editor } from '@ali/lowcode-editor-core';
import { ISimulatorHost, Component, NodeInstance, ComponentInstance } from '../simulator';
import Viewport from './viewport';
import { createSimulator } from './create-simulator';
import { Node, ParentalNode, DocumentModel, isNode, contains, isRootNode } from '../document';
import ResourceConsumer from './resource-consumer';
import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, isElement } from '@ali/lowcode-utils';
import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, isElement, isFormEvent } from '@ali/lowcode-utils';
import {
DragObjectType,
isShaken,
@ -22,7 +22,7 @@ import {
CanvasPoint,
} from '../designer';
import { parseMetadata } from './utils/parse-metadata';
import { ComponentMetadata } from '@ali/lowcode-types';
import { ComponentMetadata, ComponentSchema } from '@ali/lowcode-types';
import { BuiltinSimulatorRenderer } from './renderer';
import clipboard from '../designer/clipboard';
import { LiveEditing } from './live-editing/live-editing';
@ -227,6 +227,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this.setupDragAndClick();
this.setupDetecting();
this.setupLiveEditing();
this.setupContextMenu();
}
setupDragAndClick() {
@ -240,6 +241,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
doc.addEventListener(
'mousedown',
(downEvent: MouseEvent) => {
// fix for popups close logic
document.dispatchEvent(new Event('mousedown'));
if (this.liveEditing.editing) {
return;
}
@ -247,6 +250,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
downEvent.stopPropagation();
downEvent.preventDefault();
// FIXME: dirty fix remove label-for fro liveEditing
(downEvent.target as HTMLElement).removeAttribute('for');
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
const node = nodeInst?.node || this.document.rootNode;
const isMulti = downEvent.metaKey || downEvent.ctrlKey;
@ -260,6 +266,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
selection.remove(id);
} else {
selection.select(id);
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
editor?.emit('designer.builtinSimulator.select', {
selected,
});
}
}
};
@ -303,9 +318,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
doc.addEventListener(
'click',
(e) => {
// fix for popups close logic
document.dispatchEvent(new Event('click'));
const target = e.target as HTMLElement;
if (isFormEvent(e) || target?.closest('.next-input-group,.next-checkbox-group,.next-date-picker,.next-input,.next-month-picker,.next-number-picker,.next-radio-group,.next-range,.next-range-picker,.next-rating,.next-select,.next-switch,.next-time-picker,.next-upload,.next-year-picker,.next-breadcrumb-item,.next-calendar-header,.next-calendar-table')) {
e.preventDefault();
e.stopPropagation();
}
// stop response document click event
// e.preventDefault();
// e.stopPropagation();
// todo: catch link redirect
},
true,
@ -400,6 +420,30 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
}
}
setupContextMenu() {
const doc = this.contentDocument!;
doc.addEventListener('contextmenu', (e: MouseEvent) => {
const targetElement = e.target as HTMLElement;
const nodeInst = this.getNodeInstanceFromElement(targetElement);
if (!nodeInst) {
return;
}
const node = nodeInst.node || this.document.rootNode;
if (!node) {
return;
}
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
editor?.emit('desiger.builtinSimulator.contextmenu', {
selected,
});
});
}
/**
* @see ISimulator
*/
@ -437,6 +481,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
return this.renderer?.getComponent(componentName) || null;
}
createComponent(schema: ComponentSchema): Component | null {
return this.renderer?.createComponent(schema) || null;
}
@obx.val private instancesMap = new Map<string, ComponentInstance[]>();
setInstance(id: string, instances: ComponentInstance[] | null) {
if (instances == null) {
@ -739,7 +787,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this.sensing = true;
this.scroller.scrolling(e);
const dropContainer = this.getDropContainer(e);
if (!dropContainer) {
if (!dropContainer ||
(typeof dropContainer.container?.componentMeta?.prototype?.options?.canDropIn === 'function' &&
!dropContainer.container?.componentMeta?.prototype?.options?.canDropIn(e.dragObject.nodes[0]))) {
return null;
}

View File

@ -1,4 +1,4 @@
import { obx } from '@ali/lowcode-editor-core';
import { obx, globalContext, Editor } from '@ali/lowcode-editor-core';
import { LiveTextEditingConfig } from '@ali/lowcode-types';
import { Node, Prop } from '../../document';
@ -42,6 +42,14 @@ export class LiveEditing {
const targetElement = event.target as HTMLElement;
const liveTextEditing = node.componentMeta.liveTextEditing;
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || node?.componentMeta?.componentName || '';
editor?.emit('designer.builinSimulator.LiveEditing', {
selected,
});
let setterPropElement = getSetterPropElement(targetElement, rootElement);
let propTarget = setterPropElement?.dataset.setterProp;
let matched: (LiveTextEditingConfig & { propElement?: HTMLElement; }) | undefined | null;
@ -98,7 +106,6 @@ export class LiveEditing {
const onSaveContent = matched?.onSaveContent || saveHandlers.find(item => item.condition(prop))?.onSaveContent || defaultSaveContent;
setterPropElement.setAttribute('contenteditable', matched?.mode && matched.mode !== 'plaintext' ? 'true' : 'plaintext-only');
setterPropElement.removeAttribute('for');
setterPropElement.classList.add('engine-live-editing');
// be sure
setterPropElement.focus();
@ -110,6 +117,13 @@ export class LiveEditing {
const keydown = (e: KeyboardEvent) => {
console.info(e.code);
switch (e.code) {
case 'Enter':
// TODO: check is richtext?
case 'Escape':
case 'Tab':
setterPropElement?.blur();
}
// esc
// enter
// tab
@ -134,9 +148,7 @@ export class LiveEditing {
// TODO: upward testing for b/i/a html elements
// 非文本编辑
// 国际化数据,改变当前
// JSExpression, 改变 mock 或 弹出绑定变量
}
get editing() {

View File

@ -1,7 +1,7 @@
import { Overlay } from '@alifd/next';
import React from 'react';
import { Title, globalContext, Editor } from '@ali/lowcode-editor-core';
import './index.less';
import { Title } from '@ali/lowcode-editor-core';
import { Node, ParentalNode } from '@ali/lowcode-designer';
@ -46,6 +46,16 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
onSelect = (node: Node) => () => {
if (node && typeof node.select === 'function') {
node.select();
const editor = globalContext.get(Editor);
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
editor?.emit('designer.border.action', {
name: 'select',
selected,
});
}
};
onMouseOver = (node: Node) => (_: any, flag = true) => {

View File

@ -1,7 +1,9 @@
import { ComponentInstance, NodeInstance, Component } from '../simulator';
import { ComponentSchema } from '@ali/lowcode-types';
export interface BuiltinSimulatorRenderer {
readonly isSimulatorRenderer: true;
createComponent(schema: ComponentSchema): Component | null;
getComponent(componentName: string): Component;
getComponentInstances(id: string): ComponentInstance[] | null;
getClosestNodeInstance(from: ComponentInstance, nodeId?: string): NodeInstance<ComponentInstance> | null;

View File

@ -13,7 +13,7 @@ import {
FieldConfig,
} from '@ali/lowcode-types';
import { computed } from '@ali/lowcode-editor-core';
import { Node, ParentalNode } from './document';
import { Node, ParentalNode, TransformStage } from './document';
import { Designer } from './designer';
import { intlNode } from './locale';
import { IconContainer } from './icons/container';
@ -249,6 +249,9 @@ export class ComponentMeta {
}
return true;
}
// compatiable vision
prototype?: any;
}
export function isComponentMeta(obj: any): obj is ComponentMeta {
@ -379,8 +382,8 @@ const builtinComponentActions: ComponentAction[] = [
title: intlNode('copy'),
action(node: Node) {
// node.remove();
const { document: doc, parent, schema, index } = node;
parent && doc.insertNode(parent, schema, index);
const { document: doc, parent, index } = node;
parent && doc.insertNode(parent, node, index, true);
},
},
important: true,

View File

@ -106,7 +106,9 @@ hotkey.bind(['command+c', 'ctrl+c', 'command+x', 'ctrl+x'], (e, action) => {
if (!selected || selected.length < 1) return;
const componentsMap = {};
const componentsTree = selected.map((item) => item.export(TransformStage.Save));
const componentsTree = selected.map((item) => item.export(TransformStage.Clone));
// FIXME: clear node.id
const data = { type: 'nodeSchema', componentsMap, componentsTree };

View File

@ -67,10 +67,19 @@ export class Designer {
this.project = new Project(this, props.defaultSchema);
let startTime: any;
let src = '';
this.dragon.onDragstart((e) => {
startTime = Date.now() / 1000;
this.detecting.enable = false;
const { dragObject } = e;
if (isDragNodeObject(dragObject)) {
const node = dragObject.nodes[0]?.parent;
const npm = node?.componentMeta?.npm;
src =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
if (dragObject.nodes.length === 1) {
if (dragObject.nodes[0].parent) {
// ensure current selecting
@ -111,6 +120,32 @@ export class Designer {
if (nodes) {
loc.document.selection.selectAll(nodes.map((o) => o.id));
setTimeout(() => this.activeTracker.track(nodes![0]), 10);
const endTime: any = Date.now() / 1000;
const parent = nodes[0]?.parent;
const npm = parent?.componentMeta?.npm;
const dest =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
parent?.componentMeta?.componentName ||
'';
this.editor?.emit('designer.drag', {
time: (endTime - startTime).toFixed(2),
selected: nodes
?.map((n) => {
if (!n) {
return;
}
const npm = n?.componentMeta?.npm;
return (
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
n?.componentMeta?.componentName
);
})
.join('&'),
align: loc?.detail?.near?.align || '',
pos: loc?.detail?.near?.pos || '',
src,
dest,
});
}
}
}
@ -228,7 +263,7 @@ export class Designer {
touchOffsetObserver() {
this.clearOobxList(true);
this.oobxList.forEach(item => item.compute());
this.oobxList.forEach((item) => item.compute());
}
createSettingEntry(editor: IEditor, nodes: Node[]) {
@ -392,12 +427,17 @@ export class Designer {
@computed get componentsMap(): { [key: string]: NpmInfo | Component } {
const maps: any = {};
this._componentMetasMap.forEach((config, key) => {
const view = config.getMetadata().experimental?.view;
const metaData = config.getMetadata();
if (metaData.devMode === 'lowcode') {
maps[key] = this.currentDocument?.simulator?.createComponent(metaData.schema!);
} else {
const view = metaData.experimental?.view;
if (view) {
maps[key] = view;
} else if (config.npm) {
maps[key] = config.npm;
}
}
});
return maps;
}

View File

@ -159,20 +159,15 @@ function makeEventsHandler(
const topDoc = window.top.document;
const sourceDoc = boostEvent.view?.document || topDoc;
// TODO: optimize this logic, reduce listener
// const boostPrevented = boostEvent.defaultPrevented;
const docs = new Set<Document>();
// if (boostPrevented || isDragEvent(boostEvent)) {
docs.add(topDoc);
// }
docs.add(sourceDoc);
// if (sourceDoc !== topDoc || isDragEvent(boostEvent)) {
sensors.forEach((sim) => {
const sdoc = sim.contentDocument;
if (sdoc) {
docs.add(sdoc);
}
});
// }
return (handle: (sdoc: Document) => void) => {
docs.forEach((doc) => handle(doc));

View File

@ -37,7 +37,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
this._expanded = value;
}
constructor(readonly parent: SettingEntry, config: FieldConfig) {
constructor(readonly parent: SettingEntry, config: FieldConfig, settingFieldCollector?: (name: string | number, field: SettingField) => void) {
super(parent, config.name, config.type);
const { title, items, setter, extraProps, ...rest } = config;
@ -52,7 +52,9 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
// initial items
if (this.type === 'group' && items) {
this.initItems(items);
this.initItems(items, settingFieldCollector);
} else if (settingFieldCollector && config.name) {
settingFieldCollector(config.name, this);
}
// compatiable old config
@ -65,12 +67,12 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
return this._items;
}
private initItems(items: Array<FieldConfig | CustomView>) {
private initItems(items: Array<FieldConfig | CustomView>, settingFieldCollector?: { (name: string | number, field: SettingField): void; (name: string, field: SettingField): void; }) {
this._items = items.map((item) => {
if (isCustomView(item)) {
return item;
}
return new SettingField(this, item);
return new SettingField(this, item, settingFieldCollector);
});
}
@ -88,8 +90,21 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
this.disposeItems();
}
private hotValue: any;
// ======= compatibles for vision ======
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: any) {
if (isHotValue) {
this.setHotValue(val, extraOptions);
return;
}
super.setValue(val, false, false, extraOptions);
}
getHotValue(): any {
if (this.hotValue) {
return this.hotValue;
}
// avoid View modify
let v = cloneDeep(this.getMockOrValue());
if (v == null) {
@ -98,7 +113,8 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
return this.transducer.toHot(v);
}
setHotValue(data: any) {
setHotValue(data: any, options?: any) {
this.hotValue = data;
const v = this.transducer.toNative(data);
if (this.isUseVariable()) {
const ov = this.getValue();
@ -106,10 +122,16 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
type: 'JSExpression',
value: ov.value,
mock: v,
});
}, false, false, options);
} else {
this.setValue(v);
this.setValue(v, false, false, options);
}
// dirty fix list setter
if (Array.isArray(data) && data[0] && data[0].__sid__) {
return;
}
this.valueChange();
}

View File

@ -144,12 +144,15 @@ export class SettingPropEntry implements SettingEntry {
/**
*
*/
setValue(val: any) {
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: any) {
if (this.type === 'field') {
this.parent.setPropValue(this.name, val);
}
if (!extraOptions) {
extraOptions = {};
}
const { setValue } = this.extraProps;
if (setValue) {
if (setValue && !extraOptions.disableMutator) {
setValue(this, val);
}
}
@ -294,6 +297,9 @@ export class SettingPropEntry implements SettingEntry {
isUseVariable() {
return isJSExpression(this.getValue());
}
get useVariable() {
return this.isUseVariable();
}
getMockOrValue() {
const v = this.getValue();
if (isJSExpression(v)) {

View File

@ -2,7 +2,7 @@ import { EventEmitter } from 'events';
import { CustomView, isCustomView, IEditor } from '@ali/lowcode-types';
import { computed } from '@ali/lowcode-editor-core';
import { SettingEntry } from './setting-entry';
import { SettingField } from './setting-field';
import { SettingField, isSettingField } from './setting-field';
import { SettingPropEntry } from './setting-prop-entry';
import { Node } from '../../document';
import { ComponentMeta } from '../../component-meta';
@ -20,6 +20,7 @@ export class SettingTopEntry implements SettingEntry {
private _items: Array<SettingField | CustomView> = [];
private _componentMeta: ComponentMeta | null = null;
private _isSame: boolean = true;
private _settingFieldMap: { [prop: string]: SettingField } = {};
readonly path = [];
readonly top = this;
readonly parent = this;
@ -96,12 +97,17 @@ export class SettingTopEntry implements SettingEntry {
private setupItems() {
if (this.componentMeta) {
const settingFieldMap: { [prop: string]: SettingField } = {};
const settingFieldCollector = (name: string | number, field: SettingField) => {
settingFieldMap[name] = field;
}
this._items = this.componentMeta.configure.map((item) => {
if (isCustomView(item)) {
return item;
}
return new SettingField(this, item as any);
return new SettingField(this, item as any, settingFieldCollector);
});
this._settingFieldMap = settingFieldMap;
}
}
@ -124,7 +130,7 @@ export class SettingTopEntry implements SettingEntry {
*
*/
get(propName: string | number): SettingPropEntry {
return new SettingPropEntry(this, propName);
return this._settingFieldMap[propName] || (new SettingPropEntry(this, propName));
}
/**

View File

@ -39,7 +39,7 @@ export class Transducer {
} else if (isValidElement(setter) && setter.type.displayName === 'MixedSetter') {
setter = setter.props.setters[0];
} else if (typeof setter === 'object' && setter.componentName === 'MixedSetter') {
setter = setter.props.setters[0];
setter = setter.props.setters?.[0];
}
if (isSetterConfig(setter)) {
@ -47,9 +47,6 @@ export class Transducer {
}
if (typeof setter === 'string') {
setter = getSetter(setter)?.component;
if (!setter) {
// debugger;
}
}
this.setterTransducer = combineTransducer(

View File

@ -66,6 +66,7 @@ export class DocumentModel {
return this.modalNode || this.rootNode;
}
private inited = false;
constructor(readonly project: Project, schema?: RootSchema) {
/*
// TODO
@ -88,10 +89,11 @@ export class DocumentModel {
);
this.history = new History(
() => this.schema,
() => this.export(TransformStage.Serilize),
(schema) => this.import(schema as RootSchema, true),
);
this.setupListenActiveNodes();
this.inited = true;
}
@obx.val private willPurgeSpace: Node[] = [];
@ -161,6 +163,9 @@ export class DocumentModel {
}
let node: Node | null = null;
if (!this.inited) {
schema.id = null;
}
if (schema.id) {
node = this.getNode(schema.id);
if (node && node.componentName === schema.componentName) {
@ -483,7 +488,7 @@ export class DocumentModel {
// add toData
toData() {
const node = this.project?.currentDocument?.export(TransformStage.Serilize);
const node = this.project?.currentDocument?.export(TransformStage.Save);
return { componentsTree: [node] };
}

View File

@ -1,5 +1,5 @@
import { EventEmitter } from 'events';
import { autorun, Reaction, untracked } from '@ali/lowcode-editor-core';
import { autorun, Reaction, untracked, globalContext, Editor } from '@ali/lowcode-editor-core';
import { NodeSchema } from '@ali/lowcode-types';
// TODO: cache to localStorage
@ -114,6 +114,11 @@ export class History {
}
const cursor = this.session.cursor - 1;
this.go(cursor);
const editor = globalContext.get(Editor);
if (!editor) {
return;
}
editor.emit('history.back', cursor);
}
forward() {
@ -122,6 +127,11 @@ export class History {
}
const cursor = this.session.cursor + 1;
this.go(cursor);
const editor = globalContext.get(Editor);
if (!editor) {
return;
}
editor.emit('history.forward', cursor);
}
savePoint() {

View File

@ -158,6 +158,13 @@ export class NodeChildren {
return this.children.indexOf(node);
}
/**
*
*/
splice(start: number, deleteCount: number, node: Node): Node[] {
return this.children.splice(start, deleteCount, node);
}
/**
*
*/

View File

@ -1,4 +1,4 @@
import { obx, computed } from '@ali/lowcode-editor-core';
import { obx, computed, autorun } from '@ali/lowcode-editor-core';
import {
isDOMText,
isJSExpression,
@ -13,7 +13,7 @@ import {
ComponentSchema,
NodeStatus,
} from '@ali/lowcode-types';
import { Props, EXTRA_KEY_PREFIX } from './props/props';
import { Props, getConvertedExtraKey } from './props/props';
import { DocumentModel } from '../document-model';
import { NodeChildren } from './node-children';
import { Prop } from './props/prop';
@ -144,7 +144,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
constructor(readonly document: DocumentModel, nodeSchema: Schema) {
const { componentName, id, children, props, ...extras } = nodeSchema;
this.id = id || `node$${document.nextId()}`;
this.id = id || `node_${document.nextId()}`;
this.componentName = componentName;
if (this.componentName === 'Leaf') {
this.props = new Props(this, {
@ -155,17 +155,33 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
this._children = new NodeChildren(this as ParentalNode, this.initialChildren(children));
this._children.interalInitParent();
this.props.import(this.transformProps(props || {}), extras);
this.setupAutoruns();
}
if (this.componentMeta.isModal) {
this.getExtraProp('hidden', true)?.setValue(true);
}
}
private transformProps(props: any): any {
// FIXME! support PropsList
const x = this.document.designer.transformProps(props, this, TransformStage.Init);
return x;
return this.document.designer.transformProps(props, this, TransformStage.Init);
// TODO: run transducers in metadata.experimental
}
private autoruns?: Array<() => void>;
private setupAutoruns() {
const autoruns = this.componentMeta.getMetadata().experimental?.autoruns;
if (!autoruns || autoruns.length < 1) {
return;
}
this.autoruns = autoruns.map((item) => {
return autorun(() => {
item.autorun(this.props.get(item.name, true) as any);
}, true);
});
}
private initialChildren(children: any): NodeData[] {
// FIXME! this is dirty code
if (children == null) {
@ -368,9 +384,33 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
// todo
}
replaceWith(schema: Schema, migrate = true) {
replaceWith(schema: Schema, migrate = false) {
// reuse the same id? or replaceSelection
//
schema = Object.assign({}, migrate ? this.export() : {}, schema);
return this.parent?.replaceChild(this, schema);
}
/**
*
*
* @param {Node} node
* @param {object} data
*/
replaceChild(node: Node, data: any) {
if (this.children?.has(node)) {
const selected = this.document.selection.has(node.id);
delete data.id;
const newNode = this.document.createNode(data);
this.insertBefore(newNode, node);
node.remove();
if (selected) {
this.document.selection.select(newNode.id);
}
}
return node;
}
getProp(path: string, stash = true): Prop | null {
@ -378,7 +418,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
}
getExtraProp(key: string, stash = true): Prop | null {
return this.props.get(EXTRA_KEY_PREFIX + key, stash) || null;
return this.props.get(getConvertedExtraKey(key), stash) || null;
}
/**
@ -426,7 +466,6 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return this.parent.children.indexOf(this);
}
/**
*
*/
@ -481,13 +520,11 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
* schema
*/
export(stage: TransformStage = TransformStage.Save): Schema {
// run transducers
// run
const baseSchema: any = {
componentName: this.componentName,
};
if (stage !== TransformStage.Save) {
if (stage !== TransformStage.Clone) {
baseSchema.id = this.id;
}
@ -593,6 +630,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
if (this.isParental()) {
this.children.purge();
}
this.autoruns?.forEach((dispose) => dispose());
this.props.purge();
this.document.internalRemoveAndPurgeNode(this);
}
@ -610,7 +648,16 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
insertBefore(node: Node, ref?: Node) {
this.children?.insert(node, ref ? ref.index : null);
}
insertAfter(node: Node, ref?: Node) {
insertAfter(node: any, ref?: Node) {
if (!isNode(node)) {
if (node.getComponentName) {
node = this.document.createNode({
componentName: node.getComponentName(),
});
} else {
node = this.document.createNode(node);
}
}
this.children?.insert(node, ref ? ref.index + 1 : null);
}
getParent() {
@ -689,6 +736,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
* @deprecated
*/
getSuitablePlace(node: Node, ref: any): any {
// TODO:
if (this.isRoot()) {
return { container: this, ref };
}
@ -723,7 +771,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
}
getPrototype() {
return this;
return this.componentMeta.prototype;
}
getIcon() {
@ -827,7 +875,7 @@ export function comparePosition(node1: Node, node2: Node): PositionNO {
export function insertChild(container: ParentalNode, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
let node: Node;
if (isNode(thing) && (copy || thing.isSlot())) {
thing = thing.export(TransformStage.Save);
thing = thing.export(TransformStage.Clone);
}
if (isNode(thing)) {
node = thing;

View File

@ -1,6 +1,7 @@
import { obx, autorun, untracked, computed } from '@ali/lowcode-editor-core';
import { Prop, IPropParent, UNSET } from './prop';
import { Props } from './props';
import { Node } from '../node';
export type PendingItem = Prop[];
export class PropStash implements IPropParent {
@ -15,8 +16,10 @@ export class PropStash implements IPropParent {
return maps;
}
private willPurge: () => void;
readonly owner: Node;
constructor(readonly props: Props, write: (item: Prop) => void) {
this.owner = props.owner;
this.willPurge = autorun(() => {
if (this.space.size < 1) {
return;

View File

@ -4,7 +4,7 @@ import { uniqueId, isPlainObject, hasOwnProperty } from '@ali/lowcode-utils';
import { PropStash } from './prop-stash';
import { valueToSource } from './value-to-source';
import { Props } from './props';
import { SlotNode } from '../node';
import { SlotNode, Node } from '../node';
import { TransformStage } from '../transform-stage';
export const UNSET = Symbol.for('unset');
@ -13,12 +13,35 @@ export type UNSET = typeof UNSET;
export interface IPropParent {
delete(prop: Prop): void;
readonly props: Props;
readonly owner: Node;
}
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
export class Prop implements IPropParent {
readonly isProp = true;
readonly owner: Node;
/**
* @see SettingTarget
*/
getPropValue(propName: string | number): any {
return this.get(propName)!.getValue();
}
/**
* @see SettingTarget
*/
setPropValue(propName: string | number, value: any): void {
this.set(propName, value);
}
/**
* @see SettingTarget
*/
clearPropValue(propName: string | number): void {
this.get(propName, false)?.unset();
}
readonly id = uniqueId('prop$');
@ -74,7 +97,7 @@ export class Prop implements IPropParent {
this.items!.forEach((prop, key) => {
const v = prop.export(stage);
if (v !== UNSET) {
maps[key] = v;
maps[prop.key == null ? key : prop.key] = v;
}
});
return maps;
@ -329,6 +352,7 @@ export class Prop implements IPropParent {
key?: string | number,
spread = false,
) {
this.owner = parent.owner;
this.props = parent.props;
if (value !== UNSET) {
this.setValue(value);
@ -341,7 +365,7 @@ export class Prop implements IPropParent {
*
* @param stash
*/
get(path: string | number, stash = true): Prop | null {
get(path: string | number, stash: boolean = true): Prop | null {
const type = this._type;
if (type !== 'map' && type !== 'list' && type !== 'unset' && !stash) {
return null;
@ -588,6 +612,14 @@ export class Prop implements IPropParent {
return isMap ? fn(item, item.key) : fn(item, index);
});
}
getProps() {
return this.parent;
}
getNode() {
return this.owner;
}
}
export function isProp(obj: any): obj is Prop {

View File

@ -7,6 +7,19 @@ import { Node } from '../node';
import { TransformStage } from '../transform-stage';
export const EXTRA_KEY_PREFIX = '___';
export function getConvertedExtraKey(key: string): string {
if (!key) {
return '';
}
let _key = key;
if (key.indexOf('.') > 0) {
_key = key.split('.')[0];
}
return EXTRA_KEY_PREFIX + _key + EXTRA_KEY_PREFIX + key.substr(_key.length);
}
export function getOriginalExtraKey(key: string): string {
return key.replace(new RegExp(`${EXTRA_KEY_PREFIX}`, 'g'), '');
}
export class Props implements IPropParent {
readonly id = uniqueId('props');
@ -50,7 +63,7 @@ export class Props implements IPropParent {
}
if (extras) {
Object.keys(extras).forEach(key => {
this.items.push(new Prop(this, (extras as any)[key], EXTRA_KEY_PREFIX + key));
this.items.push(new Prop(this, (extras as any)[key], getConvertedExtraKey(key)));
});
}
}
@ -70,7 +83,7 @@ export class Props implements IPropParent {
}
if (extras) {
Object.keys(extras).forEach(key => {
this.items.push(new Prop(this, (extras as any)[key], EXTRA_KEY_PREFIX + key));
this.items.push(new Prop(this, (extras as any)[key], getConvertedExtraKey(key)));
});
}
originItems.forEach(item => item.purge());
@ -97,7 +110,7 @@ export class Props implements IPropParent {
}
let name = item.key as string;
if (name && typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) {
name = name.substr(EXTRA_KEY_PREFIX.length);
name = getOriginalExtraKey(name);
extras[name] = value;
} else {
props.push({
@ -119,7 +132,7 @@ export class Props implements IPropParent {
value = null;
}
if (typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) {
name = name.substr(EXTRA_KEY_PREFIX.length);
name = getOriginalExtraKey(name);
extras[name] = value;
} else {
props[name] = value;

View File

@ -2,5 +2,6 @@ export enum TransformStage {
Render = 1,
Serilize = 2,
Save = 3,
Init = 4,
Clone = 4,
Init = 5,
}

View File

@ -1,5 +1,5 @@
import { Component as ReactComponent, ComponentType } from 'react';
import { ComponentMetadata } from '@ali/lowcode-types';
import { ComponentMetadata, ComponentSchema } from '@ali/lowcode-types';
import { ISensor, Point, ScrollTarget, IScrollable } from './designer';
import { Node } from './document';
@ -126,6 +126,10 @@ export interface ISimulatorHost<P = object> extends ISensor {
*
*/
getComponentInstances(node: Node): ComponentInstance[] | null;
/**
* schema
*/
createComponent(schema: ComponentSchema): Component | null;
/**
*
*/

View File

@ -3,6 +3,43 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.8.16"></a>
## [0.8.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.15...@ali/lowcode-editor-core@0.8.16) (2020-06-15)
### Features
* add Monitor ([f915d19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/f915d19))
* add URL link for setter titles ([4678408](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4678408))
* ve事件埋点 ([700e5b0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/700e5b0))
<a name="0.8.15"></a>
## [0.8.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.14...@ali/lowcode-editor-core@0.8.15) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-editor-core
<a name="0.8.14"></a>
## [0.8.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.13...@ali/lowcode-editor-core@0.8.14) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-core
<a name="0.8.13"></a>
## [0.8.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.12...@ali/lowcode-editor-core@0.8.13) (2020-05-15)
**Note:** Version bump only for package @ali/lowcode-editor-core
<a name="0.8.12"></a>
## [0.8.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.11...@ali/lowcode-editor-core@0.8.12) (2020-05-13)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-editor-core",
"version": "0.8.12",
"version": "0.8.16",
"description": "Core Api for Ali lowCode engine",
"license": "MIT",
"main": "lib/index.js",
@ -15,8 +15,8 @@
"cloud-build": "build-scripts build --skip-demo"
},
"dependencies": {
"@ali/lowcode-types": "^0.8.3",
"@ali/lowcode-utils": "^0.8.4",
"@ali/lowcode-types": "^0.8.6",
"@ali/lowcode-utils": "^0.8.7",
"@alifd/next": "^1.19.16",
"@recore/obx": "^1.0.9",
"@recore/obx-react": "^1.0.8",

View File

@ -1,3 +1,6 @@
import { globalContext } from './di';
import { Editor } from './editor';
interface KeyMap {
[key: number]: string;
}
@ -329,6 +332,19 @@ function fireCallback(callback: HotkeyCallback, e: KeyboardEvent, combo?: string
e.preventDefault();
e.stopPropagation();
}
const editor = globalContext.get(Editor);
const designer = editor.get('designer');
const node = designer?.currentSelection?.getNodes()?.[0];
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || node?.componentMeta?.componentName || '';
editor?.emit('hotkey.callback.call', {
callback,
e,
combo,
sequence,
selected,
});
}
export class Hotkey {

View File

@ -1,11 +0,0 @@
/**
*
* @param {String} gmKey
* @param {Object} params
* @param {String} logKey
*/
export function goldlog(gmKey: string, params: object = {}, logKey: string = 'other'): void {
}

View File

@ -1,5 +1,5 @@
export * from './get-public-path';
export * from './goldlog';
export * from './monitor';
export * from './obx';
export * from './request';
export * from './focus-tracker';

View File

@ -0,0 +1,46 @@
class Monitor {
fn = (params: any) => {
const { AES } = window as any;
if (typeof AES.log === 'function') {
const { p1, p2, p3, p4 = 'OTHER', ...rest } = params || {};
AES.log('event', {
p1,
p2,
p3,
p4,
...rest,
});
}
};
constructor() {
(window as any).AES = (window as any).AES || {};
}
register(fn: () => any) {
if (typeof fn === 'function') {
this.fn = fn;
}
}
log(params: any) {
if (typeof this.fn === 'function') {
this.fn(params);
}
}
setConfig(key: string | object, value?: string): void {
const { AES } = window as any;
if (typeof AES?.setConfig !== 'function') {
return;
}
if (typeof key === 'string' && value) {
AES.setConfig(key, value);
} else if (typeof key === 'object') {
AES.setConfig(key);
}
}
}
const monitor = new Monitor();
export { monitor };

View File

@ -7,8 +7,26 @@ import { Tip } from '../tip';
import './title.less';
export class Title extends Component<{ title: TitleContent; className?: string; onClick?: () => void }> {
constructor(props: any) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e: React.MouseEvent) {
const { title, onClick } = this.props as any;
const url = title && (title.docUrl || title.url);
if (url) {
window.open(url);
// 防止触发行操作(如折叠面板)
e.stopPropagation();
}
// TODO: 操作交互冲突,目前 mixedSetter 仅有 2 个 setter 注册时用到了 onClick
onClick && onClick(e);
}
render() {
let { title, className, onClick } = this.props;
let { title, className } = this.props;
if (title == null) {
return null;
}
if (isValidElement(title)) {
return title;
}
@ -37,7 +55,7 @@ export class Title extends Component<{ title: TitleContent; className?: string;
'has-tip': !!tip,
'only-icon': !title.label
})}
onClick={onClick}
onClick={this.handleClick}
>
{icon ? <b className="lc-title-icon">{icon}</b> : null}
{title.label ? intl(title.label) : null}

View File

@ -0,0 +1,52 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.9.6"></a>
## [0.9.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-general@0.9.5...@ali/lowcode-editor-preset-general@0.9.6) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general
<a name="0.9.5"></a>
## [0.9.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-general@0.9.4...@ali/lowcode-editor-preset-general@0.9.5) (2020-06-15)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general
<a name="0.9.4"></a>
## [0.9.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-general@0.9.3...@ali/lowcode-editor-preset-general@0.9.4) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general
<a name="0.9.3"></a>
## [0.9.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-general@0.9.2...@ali/lowcode-editor-preset-general@0.9.3) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general
<a name="0.9.2"></a>
## [0.9.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-general@0.9.1...@ali/lowcode-editor-preset-general@0.9.2) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general
<a name="0.9.1"></a>
## 0.9.1 (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-preset-general

View File

@ -4,7 +4,7 @@
"build-plugin-component",
{
"filename": "editor-preset-general",
"library": "LowcodeEditorPresetGeneral",
"library": "LowcodeEditor",
"libraryTarget": "umd",
"externals": {
"react": "var window.React",

View File

@ -1,6 +1,7 @@
{
"name": "@ali/lowcode-editor-preset-general",
"version": "0.9.0",
"version": "0.9.6",
"private": true,
"description": "Ali General Editor Preset",
"main": "lib/index.js",
"files": [
@ -9,17 +10,17 @@
"lib"
],
"scripts": {
"build": "build-scripts build --skip-demo",
"cloud-build": "build-scripts build --skip-demo"
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-utils": "^0.8.0",
"@ali/lowcode-types": "^0.8.0",
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-editor-skeleton": "^0.8.17",
"@ali/lowcode-plugin-designer": "^0.9.11",
"@ali/lowcode-plugin-outline-pane": "^0.8.17",
"@ali/lowcode-editor-setters": "^0.9.0",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-editor-skeleton": "^0.8.26",
"@ali/lowcode-plugin-designer": "^0.9.20",
"@ali/lowcode-plugin-outline-pane": "^0.8.26",
"@ali/lowcode-types": "^0.8.6",
"@ali/lowcode-utils": "^0.8.7",
"@alifd/next": "^1.19.12",
"@alife/theme-lowcode-dark": "^0.1.0",
"@alife/theme-lowcode-light": "^0.1.0",
@ -27,6 +28,7 @@
"react-dom": "^16.8.1"
},
"devDependencies": {
"@ali/lowcode-editor-setters": "^0.9.3",
"@alib/build-scripts": "^0.1.18",
"@types/events": "^3.0.0",
"@types/react": "^16.8.3",
@ -35,5 +37,8 @@
"build-plugin-moment-locales": "^0.1.0",
"build-plugin-react-app": "^1.1.2",
"tsconfig-paths-webpack-plugin": "^3.2.0"
},
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
}
}

View File

@ -3,7 +3,7 @@ import { createElement } from 'react';
import { Workbench, Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton';
import { globalContext, Editor } from '@ali/lowcode-editor-core';
import { Designer } from '@ali/lowcode-designer';
import { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane';
import Outline, { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane';
import DesignerPlugin from '@ali/lowcode-plugin-designer';
import '@ali/lowcode-editor-setters';
@ -30,6 +30,15 @@ skeleton.add({
type: 'Widget',
content: DesignerPlugin,
});
skeleton.add({
area: 'leftArea',
name: 'outlinePane',
type: 'PanelDock',
content: Outline,
panelProps: {
area: 'leftFixedArea',
},
});
skeleton.add({
area: 'rightArea',
name: 'settingsPane',
@ -74,7 +83,7 @@ export function init(container?: Element) {
}
console.log(
`%cLowcodeEditorPresetGeneral %cv${version}`,
`%cLowcodeEngine %cv${version}`,
"color:#000;font-weight:bold;",
"color:green;font-weight:bold;"
);

View File

@ -3,6 +3,113 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.8.21"></a>
## [0.8.21](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.20...@ali/lowcode-editor-preset-vision@0.8.21) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.20"></a>
## [0.8.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.19...@ali/lowcode-editor-preset-vision@0.8.20) (2020-06-15)
### Bug Fixes
* compatiable old VE api ([45af1c5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/45af1c5))
* i18n parser & setting ([dbdd9e4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/dbdd9e4))
* patch prototype ([f20bfaa](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/f20bfaa))
* render children ([487f257](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/487f257))
* style ([4694331](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4694331))
* 调整保存成功弹出框位置 ([5198dae](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/5198dae))
### Features
* complete live-editing expr & i18n ([3ac08ba](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/3ac08ba))
* support prop.autorun ([c0a5235](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c0a5235))
* ve事件埋点 ([700e5b0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/700e5b0))
<a name="0.8.19"></a>
## [0.8.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.18...@ali/lowcode-editor-preset-vision@0.8.19) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.18"></a>
## [0.8.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.17...@ali/lowcode-editor-preset-vision@0.8.18) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.17"></a>
## [0.8.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.16...@ali/lowcode-editor-preset-vision@0.8.17) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.16"></a>
## [0.8.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-preset-vision@0.8.15...@ali/lowcode-editor-preset-vision@0.8.16) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.15"></a>
## 0.8.15 (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-preset-vision
<a name="0.8.14"></a>
## [0.8.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.13...@ali/lowcode-vision-preset@0.8.14) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-vision-preset
<a name="0.8.13"></a>
## [0.8.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.12...@ali/lowcode-vision-preset@0.8.13) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-vision-preset
<a name="0.8.12"></a>
## [0.8.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.11...@ali/lowcode-vision-preset@0.8.12) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-vision-preset
<a name="0.8.11"></a>
## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.10...@ali/lowcode-vision-preset@0.8.11) (2020-05-15)
### Features
* add filter reducer ([17c6ed3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/17c6ed3))
* change reducer stage ([c2e83c7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/c2e83c7))
<a name="0.8.10"></a>
## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.9...@ali/lowcode-vision-preset@0.8.10) (2020-05-15)

View File

@ -3,8 +3,8 @@
[
"build-plugin-component",
{
"filename": "vision-preset",
"library": "VisualEngine",
"filename": "editor-preset-vision",
"library": "LowcodeEditor",
"libraryTarget": "umd",
"externals": {
"react": "var window.React",

View File

@ -1,7 +1,7 @@
{
"name": "@ali/lowcode-editor-preset-vision",
"version": "0.8.21",
"private": true,
"version": "0.8.10",
"description": "Vision Polyfill for Ali lowCode engine",
"main": "lib/index.js",
"files": [
@ -10,15 +10,17 @@
"lib"
],
"scripts": {
"build": "build-scripts build --skip-demo",
"cloud-build": "build-scripts build --skip-demo"
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-editor-skeleton": "^0.8.17",
"@ali/lowcode-plugin-designer": "^0.9.11",
"@ali/lowcode-plugin-outline-pane": "^0.8.17",
"@ali/ve-i18n-util": "^2.0.2",
"@ali/lowcode-designer": "^0.9.20",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-editor-skeleton": "^0.8.26",
"@ali/lowcode-plugin-designer": "^0.9.20",
"@ali/lowcode-plugin-outline-pane": "^0.8.26",
"@ali/ve-i18n-util": "^2.0.0",
"@ali/ve-icons": "^4.1.9",
"@ali/ve-less-variables": "2.0.3",
"@ali/ve-popups": "^4.2.5",
@ -44,5 +46,8 @@
"build-plugin-moment-locales": "^0.1.0",
"build-plugin-react-app": "^1.1.2",
"tsconfig-paths-webpack-plugin": "^3.2.0"
},
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
}
}

View File

@ -1,5 +1,5 @@
import { ComponentType, ReactElement } from 'react';
import { ComponentMetadata, FieldConfig, InitialItem } from '@ali/lowcode-types';
import { ComponentMetadata, FieldConfig, InitialItem, FilterItem, AutorunItem } from '@ali/lowcode-types';
import {
ComponentMeta,
addBuiltinComponentAction,
@ -18,22 +18,42 @@ import {
import { designer } from '../editor';
import { uniqueId } from '@ali/lowcode-utils';
const GlobalPropsConfigure: Array<{ position: string; initials?: InitialItem[]; config: FieldConfig }> = [];
const GlobalPropsConfigure: Array<{
position: string;
initials?: InitialItem[];
filters?: FilterItem[];
autoruns?: AutorunItem[];
config: FieldConfig
}> = [];
const Overrides: {
[componentName: string]: {
initials?: InitialItem[];
filters?: FilterItem[];
autoruns?: AutorunItem[];
override: any;
};
} = {};
function addGlobalPropsConfigure(config: OldGlobalPropConfig) {
const initials: InitialItem[] = [];
const filters: FilterItem[] = [];
const autoruns: AutorunItem[] = [];
GlobalPropsConfigure.push({
position: config.position || 'bottom',
initials,
config: upgradePropConfig(config, (item) => {
filters,
autoruns,
config: upgradePropConfig(config, {
addInitial: (item) => {
initials.push(item);
}),
},
addFilter: (item) => {
filters.push(item);
},
addAutorun: (item) => {
autoruns.push(item);
},
})
});
}
function removeGlobalPropsConfigure(name: string) {
@ -46,20 +66,30 @@ function removeGlobalPropsConfigure(name: string) {
}
function overridePropsConfigure(componentName: string, config: { [name: string]: OldPropConfig } | OldPropConfig[]) {
const initials: InitialItem[] = [];
const filters: FilterItem[] = [];
const autoruns: AutorunItem[] = [];
const addInitial = (item: InitialItem) => {
initials.push(item);
};
const addFilter = (item: FilterItem) => {
filters.push(item);
};
const addAutorun = (item: AutorunItem) => {
autoruns.push(item);
};
let override: any;
if (Array.isArray(config)) {
override = upgradeConfigure(config, addInitial);
override = upgradeConfigure(config, { addInitial, addFilter, addAutorun });
} else {
override = {};
Object.keys(config).forEach(key => {
override[key] = upgradePropConfig(config[key], addInitial);
override[key] = upgradePropConfig(config[key], { addInitial, addFilter, addAutorun });
});
}
Overrides[componentName] = {
initials,
filters,
autoruns,
override,
};
}
@ -89,6 +119,7 @@ registerMetadataTransducer(
} else if (position === 'bottom') {
bottom.push(item.config);
}
// TODO: replace autoruns,initials,filters
});
const override = Overrides[componentName]?.override;
@ -109,6 +140,7 @@ registerMetadataTransducer(
}
}
}
// TODO: replace autoruns,initials,filters
}
return metadata;
@ -184,7 +216,7 @@ class Prototype {
return new Prototype(config);
}
private id: string;
readonly isPrototype = true;
private meta: ComponentMeta;
readonly options: OldPrototypeConfig | ComponentMetadata;
@ -197,11 +229,11 @@ class Prototype {
const metadata = isNewSpec(input) ? input : upgradeMetadata(input);
this.meta = designer.createComponentMeta(metadata);
}
this.id = uniqueId('prototype');
(this.meta as any).prototype = this;
}
getId() {
return this.id;
return this.getComponentName();
}
getConfig(configName?: keyof (OldPrototypeConfig | ComponentMetadata)) {
@ -298,4 +330,8 @@ class Prototype {
}
}
export function isPrototype(obj: any): obj is Prototype {
return obj && obj.isPrototype;
}
export default Prototype;

View File

@ -1,6 +1,6 @@
import { ReactElement, ComponentType } from 'react';
import { EventEmitter } from 'events';
import { registerSetter, RegisteredSetter } from '@ali/lowcode-editor-core';
import { registerSetter, RegisteredSetter, getSetter } from '@ali/lowcode-editor-core';
import Bundle from './bundle';
import { CustomView } from '@ali/lowcode-types';
@ -41,6 +41,38 @@ export class Trunk {
return this.metaBundle.getFromMeta(name);
}
getPrototypeById(id: string) {
return this.getPrototype(id);
}
listByCategory() {
const categories: any[] = [];
const categoryMap: any = {};
const categoryItems: any[] = [];
const defaultCategory = {
items: categoryItems,
name: '*',
};
categories.push(defaultCategory);
categoryMap['*'] = defaultCategory;
this.getList().forEach((prototype) => {
const cat = prototype.getCategory();
if (!cat) {
return;
}
if (!categoryMap.hasOwnProperty(cat)) {
const categoryMapItems: any[] = [];
categoryMap[cat] = {
items: categoryMapItems,
name: cat,
};
categories.push(categoryMap[cat]);
}
categoryMap[cat].items.push(prototype);
});
return categories;
}
getPrototypeView(componentName: string) {
return this.getPrototype(componentName)?.getView();
}
@ -72,6 +104,14 @@ export class Trunk {
setPackages() {
console.warn('Trunk.setPackages is deprecated');
}
getSetter(type: string): any{
const setter = getSetter(type);
if (setter?.component) {
return setter.component;
}
return setter;
}
}
export default new Trunk();

View File

@ -1,6 +1,8 @@
import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react';
import { isPlainObject } from '@ali/lowcode-utils';
import { isI18nData, SettingTarget, InitialItem, isJSSlot, isJSExpression } from '@ali/lowcode-types';
import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, ProjectSchema, AutorunItem } from '@ali/lowcode-types';
import { untracked } from '@ali/lowcode-editor-core';
import { editor, designer } from '../editor';
type Field = SettingTarget;
@ -166,6 +168,8 @@ export interface OldPrototypeConfig {
onResizeStart?: (e: MouseEvent, triggerDirection: string, dragment: Node) => void;
onResize?: (e: MouseEvent, triggerDirection: string, dragment: Node, moveX: number, moveY: number) => void;
onResizeEnd?: (e: MouseEvent, triggerDirection: string, dragment: Node) => void;
devMode?: string;
schema?: ProjectSchema;
}
export interface ISetterConfig {
@ -178,7 +182,7 @@ type SetterGetter = (this: Field, value: any) => ComponentClass;
type ReturnBooleanFunction = (this: Field, value: any) => boolean;
export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) {
export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollector) {
const {
type,
name,
@ -209,7 +213,9 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
liveTextEditing,
} = config;
const extraProps: any = {};
const extraProps: any = {
display: DISPLAY_TYPE.BLOCK,
};
const newConfig: any = {
type: type === 'group' ? 'group' : 'field',
name,
@ -261,22 +267,9 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
} else if (hidden != null || disabled != null) {
extraProps.condition = (field: Field) => !(isHidden(field) || isDisabled(field));
}
if (ignore != null || disabled != null) {
// FIXME! addFilter
extraProps.virtual = (field: Field) => {
if (isDisabled(field)) {
return true;
}
if (typeof ignore === 'function') {
return ignore.call(field, field.getValue()) === true;
}
return ignore === true;
};
}
if (type === 'group') {
newConfig.items = items ? upgradeConfigure(items, addInitial) : [];
newConfig.items = items ? upgradeConfigure(items, collector) : [];
return newConfig;
}
@ -303,18 +296,44 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
};
}
if (accessor && !slotName) {
if (!slotName) {
if (accessor) {
extraProps.getValue = (field: Field, fieldValue: any) => {
return accessor.call(field, fieldValue);
};
if (!initialFn) {
initialFn = accessor;
}
if (sync || accessor) {
collector.addAutorun({
name,
autorun: (field: Field) => {
let fieldValue = untracked(() => field.getValue());
if (accessor) {
fieldValue = accessor.call(field, fieldValue)
}
if (sync) {
fieldValue = sync.call(field, fieldValue);
if (fieldValue !== undefined) {
field.setValue(fieldValue);
}
} else {
field.setValue(fieldValue);
}
}
});
}
if (mutator) {
extraProps.setValue = (field: Field, value: any) => {
mutator.call(field, value, value);
};
}
}
const setterInitial = getInitialFromSetter(setter);
addInitial({
collector.addInitial({
// FIXME! name could be "xxx.xxx"
name: slotName || name,
initial: (field: Field, currentValue: any) => {
// FIXME! read from prototype.defaultProps
@ -334,18 +353,27 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
},
});
if (sync) {
extraProps.autorun = (field: Field) => {
const value = sync.call(field, field.getValue());
if (value !== undefined) {
field.setValue(value);
if (ignore != null || disabled != null) {
collector.addFilter({
// FIXME! name should be "xxx.xxx"
name: slotName || name,
filter: (field: Field, currentValue: any) => {
let disabledValue: boolean;
if (typeof disabled === 'function') {
disabledValue = disabled.call(field, currentValue) === true;
}
};
else {
disabledValue = disabled === true;
}
if (mutator && !slotName) {
extraProps.setValue = (field: Field, value: any) => {
mutator.call(field, value, value);
};
if (disabledValue) {
return false;
}
if (typeof ignore === 'function') {
return ignore.call(field, currentValue) !== true;
}
return ignore !== true;
}
});
}
if (slotName) {
@ -371,7 +399,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
},
},
];
if (allowTextInput !== false) {
if (allowTextInput) {
setters.unshift('I18nSetter');
}
if (supportVariable) {
@ -386,9 +414,25 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
if (type === 'composite') {
const initials: InitialItem[] = [];
const objItems = items
? upgradeConfigure(items, (item) => {
? upgradeConfigure(items,
{
addInitial: (item) => {
initials.push(item);
})
},
addFilter: (item) => {
collector.addFilter({
name: `${name}.${item.name}`,
filter: item.filter,
});
},
addAutorun: (item) => {
collector.addAutorun({
name: `${name}.${item.name}`,
autorun: item.autorun,
});
},
}
)
: [];
const initial = (target: SettingTarget, value?: any) => {
// TODO:
@ -400,7 +444,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
});
return data;
};
addInitial({
collector.addInitial({
name,
initial,
});
@ -460,7 +504,15 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
return newConfig;
}
type AddIntial = (initialItem: InitialItem) => void;
type AddInitial = (initialItem: InitialItem) => void;
type AddFilter = (filterItem: FilterItem) => void;
type AddAutorun = (autorunItem: AutorunItem) => void;
type ConfigCollector = {
addInitial: AddInitial;
addFilter: AddFilter;
addAutorun: AddAutorun;
}
function getInitialFromSetter(setter: any) {
return setter && (
@ -474,7 +526,7 @@ function defaultInitial(value: any, defaultValue: any) {
}
export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial) {
export function upgradeConfigure(items: OldPropConfig[], collector: ConfigCollector) {
const configure: any[] = [];
let ignoreSlotName: any = null;
items.forEach((config) => {
@ -487,7 +539,7 @@ export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial)
}
ignoreSlotName = null;
}
configure.push(upgradePropConfig(config, addInitial));
configure.push(upgradePropConfig(config, collector));
});
return configure;
}
@ -560,6 +612,8 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
onResizeStart, // onResizeStart
onResize, // onResize
onResizeEnd, // onResizeEnd
devMode,
schema,
} = oldConfig;
const meta: any = {
@ -567,7 +621,8 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
title,
icon,
docUrl,
devMode: 'procode',
devMode: devMode || 'procode',
schema: schema?.componentsTree[0],
};
if (category) {
@ -655,8 +710,9 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
if (initialChildren) {
experimental.initialChildren =
typeof initialChildren === 'function'
? (field: Field) => {
return initialChildren.call(field, (field as any).props);
? (node: any) => {
const props = designer.createSettingEntry(editor, [ node ]);
return initialChildren.call(node, props);
}
: initialChildren;
}
@ -724,10 +780,24 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
experimental.callbacks = callbacks;
const initials: InitialItem[] = [];
const props = upgradeConfigure(configure || [], (item) => {
const filters: FilterItem[] = [];
const autoruns: AutorunItem[] = [];
const props = upgradeConfigure(configure || [],
{
addInitial: (item) => {
initials.push(item);
});
},
addFilter: (item) => {
filters.push(item);
},
addAutorun: (item) => {
autoruns.push(item);
}
}
);
experimental.initials = initials;
experimental.filters = filters;
experimental.autoruns = autoruns;
const supports: any = {};
if (canUseCondition != null) {

View File

@ -1,5 +1,6 @@
import logger from '@ali/vu-logger';
import { EventEmitter } from 'events';
import { editor } from './editor';
/**
* Bus class as an EventEmitter
@ -19,7 +20,6 @@ export class Bus {
// alias to unsub
off(event: string, func: (...args: any[]) => any) {
this.unsub(event, func);
}
// alias to pub
@ -62,4 +62,18 @@ export class Bus {
}
}
export default new Bus();
const bus = new Bus();
editor.on('hotkey.callback.call', (data) => {
bus.emit('ve.hotkey.callback.call', data);
});
editor.on('history.back', (data) => {
bus.emit('ve.history.back', data);
});
editor.on('history.forward', (data) => {
bus.emit('ve.history.forward', data);
});
export default bus;

View File

@ -0,0 +1,41 @@
import Env from './env';
import { isJSSlot, isI18nData, isJSExpression } from '@ali/lowcode-types';
import { isPlainObject } from '@ali/lowcode-utils';
import i18nUtil from './i18n-util';
// FIXME: 表达式使用 mock 值未来live 模式直接使用原始值
export function deepValueParser(obj?: any): any {
if (isJSExpression(obj)) {
obj = obj.mock;
}
if (!obj) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => deepValueParser(item));
}
if (isPlainObject(obj)) {
if (isI18nData(obj)) {
// FIXME! use editor.get
let locale = Env.getLocale();
if (obj.key) {
// FIXME: 此处需要升级I18nUtil改成响应式
return i18nUtil.get(obj.key, locale);
}
if (locale !== 'zh_CN' && locale !== 'zh_TW' && !obj[locale]) {
locale = 'en_US';
}
return obj[obj.use || locale] || obj.zh_CN;
}
if (isJSSlot(obj)) {
return obj;
}
const out: any = {};
Object.keys(obj).forEach((key) => {
out[key] = deepValueParser(obj[key]);
});
return out;
}
return obj;
}

View File

@ -1,5 +1,6 @@
import { designer } from './editor';
import { DragObjectType, isNode, isDragNodeDataObject } from '@ali/lowcode-designer';
import { isPrototype } from './bundle/prototype';
const dragon = designer.dragon;
const DragEngine = {
@ -9,7 +10,14 @@ const DragEngine = {
if (!r) {
return null;
}
if (isNode(r)) {
if (isPrototype(r)) {
return {
type: DragObjectType.NodeData,
data: {
componentName: r.getComponentName(),
},
};
} else if (isNode(r)) {
return {
type: DragObjectType.Node,
nodes: [r],

View File

@ -1,16 +1,16 @@
import { isJSBlock, isJSExpression, isJSSlot } from '@ali/lowcode-types';
import { isPlainObject } from '@ali/lowcode-utils';
import { isJSBlock, isJSExpression, isJSSlot, isI18nData } from '@ali/lowcode-types';
import { isPlainObject, hasOwnProperty } from '@ali/lowcode-utils';
import { globalContext, Editor } from '@ali/lowcode-editor-core';
import { Designer, LiveEditing, TransformStage, addBuiltinComponentAction } from '@ali/lowcode-designer';
import { Designer, LiveEditing, TransformStage, Node } from '@ali/lowcode-designer';
import Outline, { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane';
import { toCss } from '@ali/vu-css-style';
import logger from '@ali/vu-logger';
import DesignerPlugin from '@ali/lowcode-plugin-designer';
import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton';
import { i18nReducer } from './i18n-reducer';
import { InstanceNodeSelector } from './components';
import { liveEditingRule } from './vc-live-editing';
import { deepValueParser } from './deep-value-parser';
import { liveEditingRule, liveEditingSaveHander } from './vc-live-editing';
export const editor = new Editor();
globalContext.register(editor, Editor);
@ -31,18 +31,48 @@ designer.addPropsReducer((props, node) => {
const newProps: any = {};
initials.forEach((item) => {
// FIXME! this implements SettingTarget
try {
// FIXME! item.name could be 'xxx.xxx'
const v = item.initial(node as any, props[item.name]);
if (v !== undefined) {
newProps[item.name] = v;
}
} catch (e) {
if (hasOwnProperty(props, item.name)) {
newProps[item.name] = props[item.name];
}
}
});
return newProps;
}
return props;
}, TransformStage.Init);
// 国际化渲染时处理
designer.addPropsReducer(i18nReducer, TransformStage.Render);
function filterReducer(props: any, node: Node): any {
const filters = node.componentMeta.getMetadata().experimental?.filters;
if (filters && filters.length) {
const newProps = { ...props };
filters.forEach((item) => {
// FIXME! item.name could be 'xxx.xxx'
if (!hasOwnProperty(newProps, item.name)) {
return;
}
try {
if (item.filter(node.getProp(item.name) as any, props[item.name]) === false) {
delete newProps[item.name];
}
} catch (e) {
console.warn(e);
logger.trace(e);
}
});
return newProps;
}
return props;
}
designer.addPropsReducer(filterReducer, TransformStage.Save);
designer.addPropsReducer(filterReducer, TransformStage.Render);
function upgradePropsReducer(props: any) {
if (!isPlainObject(props)) {
@ -72,6 +102,32 @@ function upgradePropsReducer(props: any) {
// 升级 Props
designer.addPropsReducer(upgradePropsReducer, TransformStage.Init);
function compatiableReducer(props: any) {
if (!isPlainObject(props)) {
return props;
}
const newProps: any = {};
Object.entries<any>(props).forEach(([key, val]) => {
if (isJSSlot(val)) {
val.value
val = {
type: 'JSBlock',
value: {
componentName: 'Slot',
children: val.value,
props: {
slotTitle: val.title,
},
},
}
}
newProps[key] = val;
});
return newProps;
}
// Dirty fix: will remove this reducer
designer.addPropsReducer(compatiableReducer, TransformStage.Save);
// 设计器组件样式处理
function stylePropsReducer(props: any, node: any) {
if (props && typeof props === 'object' && props.__style__) {
@ -119,30 +175,8 @@ function appendStyleNode(props: any, styleProp: any, cssClass: string, cssId: st
}
designer.addPropsReducer(stylePropsReducer, TransformStage.Render);
// FIXME: 表达式使用 mock 值未来live 模式直接使用原始值
function expressionReducer(obj?: any): any {
if (!obj) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => expressionReducer(item));
}
if (isPlainObject(obj)) {
if (isJSExpression(obj)) {
return obj.mock;
}
if (isJSSlot(obj)) {
return obj;
}
const out: any = {};
Object.keys(obj).forEach((key) => {
out[key] = expressionReducer(obj[key]);
});
return out;
}
return obj;
}
designer.addPropsReducer(expressionReducer, TransformStage.Render);
// 国际化 & Expression 渲染时处理
designer.addPropsReducer(deepValueParser, TransformStage.Render);
skeleton.add({
area: 'mainArea',
@ -178,11 +212,4 @@ skeleton.add({
});
LiveEditing.addLiveEditingSpecificRule(liveEditingRule);
// 实例节点选择器,线框高亮
// addBuiltinComponentAction({
// name: 'instance-node-selector',
// content: InstanceNodeSelector,
// important: true,
// condition: 'always'
// });
LiveEditing.addLiveEditingSaveHandler(liveEditingSaveHander);

View File

@ -1,38 +0,0 @@
import Env from './env';
const I18nUtil = require('@ali/ve-i18n-util');
interface I18nObject {
type?: string;
use?: string;
key?: string;
[lang: string]: string | undefined;
}
export function i18nReducer(obj?: any): any {
if (!obj) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => i18nReducer(item));
}
if (typeof obj === 'object') {
if (obj.type === 'i18n') {
// FIXME! use editor.get
let locale = Env.getLocale();
if (obj.key) {
// FIXME: 此处需要升级I18nUtil改成响应式
return I18nUtil.get(obj.key, locale);
}
if (locale !== 'zh_CN' && locale !== 'zh_TW' && !obj[locale]) {
locale = 'en_US';
}
return obj[obj.use || locale] || obj.zh_CN;
}
const out: I18nObject = {};
Object.keys(obj).forEach((key) => {
out[key] = i18nReducer(obj[key]);
});
return out;
}
return obj;
}

View File

@ -0,0 +1,79 @@
declare enum LANGUAGES {
zh_CN = 'zh_CN',
en_US = 'en_US'
}
export interface I18nRecord {
type?: 'i18n';
[key: string]: string;
/**
* i18n unique key
*/
key?: string;
}
export interface I18nRecordData {
gmtCreate: Date;
gmtModified: Date;
i18nKey: string;
i18nText: I18nRecord;
id: number;
}
export interface II18nUtilConfigs {
items?: {};
/**
*
*/
disableInstantLoad?: boolean;
/**
*
*/
disableFullLoad?: boolean;
loader?: (configs: ILoaderConfigs) => Promise<I18nRecordData[]>;
remover?: (key: string, dic: I18nRecord) => Promise<void>;
saver?: (key: string, dic: I18nRecord) => Promise<void>;
}
export interface ILoaderConfigs {
/**
* search keywords
*/
keyword?: string;
/**
* should load all i18n items
*/
isFull?: boolean;
/**
* search i18n item based on uniqueKey
*/
key?: string;
}
export interface II18nUtil {
init(config: II18nUtilConfigs): void;
isInitialized(): boolean;
isReady(): boolean;
attach(prop: object, value: I18nRecord, updator: () => any);
search(keyword: string, silent?: boolean);
load(configs: ILoaderConfigs): Promise<I18nRecord[]>;
/**
* Get local i18n Record
* @param key
* @param lang
*/
get(key: string, lang: string): string | I18nRecord;
getFromRemote(key: string): Promise<I18nRecord>;
getItem(key: string, forceData?: boolean): any;
getItems(): I18nRecord[];
update(key: string, doc: I18nRecord, lang: LANGUAGES);
create(doc: I18nRecord, lang: LANGUAGES): string;
remove(key: string): Promise<void>;
onReady(func: () => any);
onRowsChange(func: () => any);
onChange(func: (dic: I18nRecord) => any);
}
declare const i18nUtil: II18nUtil;
export default i18nUtil;

View File

@ -0,0 +1,310 @@
import { EventEmitter } from 'events';
import { obx } from '@ali/lowcode-editor-core';
let keybase = Date.now();
function keygen(maps) {
let key;
do {
key = `i18n-${(keybase).toString(36)}`;
keybase += 1;
} while (key in maps);
return key;
}
class DocItem {
constructor(parent, doc, unInitial) {
this.parent = parent;
const { use, ...strings } = doc;
this.doc = obx.val({
type: 'i18n',
...strings,
});
this.emitter = new EventEmitter;
this.inited = unInitial !== true;
}
getKey() {
return this.doc.key;
}
getDoc(lang) {
if (lang) {
return this.doc[lang];
}
return this.doc;
}
setDoc(doc, lang, initial) {
if (lang) {
this.doc[lang] = doc;
} else {
const { use, strings } = doc || {};
Object.assign(this.doc, strings);
}
this.emitter.emit('change', this.doc);
if (initial) {
this.inited = true;
} else if (this.inited) {
this.parent._saveChange(this.doc.key, this.doc);
}
}
remove() {
if (!this.inited) return Promise.reject('not initialized');
const { key, ...doc } = this.doc; // eslint-disable-line
this.emitter.emit('change', doc);
return this.parent.remove(this.getKey());
}
onChange(func) {
this.emitter.on('change', func);
return () => {
this.emitter.removeListener('change', func);
};
}
}
class I18nUtil {
constructor() {
this.emitter = new EventEmitter;
// original data source from remote
this.i18nData = {};
// current i18n records on the left pane
this.items = [];
this.maps = {};
// full list of i18n records for synchronized call
this.fullList = [];
this.fullMap = {};
this.config = {};
this.ready = false;
this.isInited = false;
}
_prepareItems(items, isFull = false, isSilent = false) {
this[isFull ? 'fullList' : 'items'] = items.map((dict) => {
let item = this[isFull ? 'fullMap' : 'maps'][dict.key];
if (item) {
item.setDoc(dict, null, true);
} else {
item = new DocItem(this, dict);
this[isFull ? 'fullMap' : 'maps'][dict.key] = item;
}
return item;
});
if (this.ready && !isSilent) {
this.emitter.emit('rowschange');
this.emitter.emit('change');
} else {
this.ready = true;
this.emitter.emit('ready');
}
}
_load(configs = {}, silent) {
if (!this.config.loader) {
console.error(new Error('Please load loader while init I18nUtil.'));
return Promise.reject();
}
return this.config.loader(configs).then((data) => {
if (configs.i18nKey) {
return Promise.resolve(data.i18nText);
}
this._prepareItems(data.data, configs.isFull, silent);
// set pagination data to i18nData
this.i18nData = data;
if (!silent) {
this.emitter.emit('rowschange');
this.emitter.emit('change');
}
return Promise.resolve(this.items.map(i => i.getDoc()));
});
}
_saveToItems(key, dict) {
let item = null;
item = this.items.find(doc => doc.getKey() === key);
if (!item) {
item = this.fullList.find(doc => doc.getKey() === key);
}
if (item) {
item.setDoc(dict);
} else {
item = new DocItem(this, {
key,
...dict,
});
this.items.unshift(item);
this.fullList.unshift(item);
this.maps[key] = item;
this.fullMap[key] = item;
this._saveChange(key, dict, true);
}
}
_saveChange(key, dict, rowschange) {
if (rowschange) {
this.emitter.emit('rowschange');
}
this.emitter.emit('change');
if (dict === null) {
delete this.maps[key];
delete this.fullMap[key];
}
return this._save(key, dict);
}
_save(key, dict) {
const saver = dict === null ? this.config.remover : this.config.saver;
if (!saver) return Promise.reject('Saver function is not set');
return saver(key, dict);
}
init(config) {
if (this.isInited) return;
this.config = config || {};
if (this.config.items) {
// inject to current page
this._prepareItems(this.config.items);
}
if (!this.config.disableInstantLoad) {
this._load({ isFull: !this.config.disableFullLoad });
}
this.isInited = true;
}
isInitialized() {
return this.isInited;
}
isReady() {
return this.ready;
}
// add events updater when i18n record change
// we should notify engine's view to change
attach(prop, value, updator) {
const isI18nValue = value && value.type === 'i18n' && value.key;
const key = isI18nValue ? value.key : null;
if (prop.i18nLink) {
if (isI18nValue && (key === prop.i18nLink.key)) {
return prop.i18nLink;
}
prop.i18nLink.detach();
}
if (isI18nValue) {
return {
key,
detach: this.getItem(key, value).onChange(updator),
};
}
return null;
}
/**
* 搜索 i18n 词条
*
* @param {any} keyword 搜索关键字
* @param {boolean} [silent=false] 是否刷新左侧的 i18n 数据
* @returns
*
* @memberof I18nUtil
*/
search(keyword, silent = false) {
return this._load({ keyword }, silent);
}
load(configs = {}) {
return this._load(configs);
}
get(key, lang) {
const item = this.getItem(key);
if (item) {
return item.getDoc(lang);
}
return null;
}
getFromRemote(key) {
return this._load({ i18nKey: key });
}
getItem(key, forceData) {
if (forceData && !this.maps[key] && !this.fullList[key]) {
const item = new DocItem(this, {
key,
...forceData,
}, true);
this.maps[key] = item;
this.fullMap[key] = item;
this.fullList.push(item);
this.items.push(item);
}
return this.maps[key] || this.fullMap[key];
}
getItems() {
return this.items;
}
update(key, doc, lang) {
let dict = this.get(key) || {};
if (!lang) {
dict = doc;
} else {
dict[lang] = doc;
}
this._saveToItems(key, dict);
}
create(doc, lang) {
const dict = lang ? { [lang]: doc } : doc;
const key = keygen(this.fullMap);
this._saveToItems(key, dict);
return key;
}
remove(key) {
const index = this.items.findIndex(item => item.getKey() === key);
const indexG = this.fullList.findIndex(item => item.getKey() === key);
if (index > -1) {
this.items.splice(index, 1);
}
if (indexG > -1) {
this.fullList.splice(index, 1);
}
return this._saveChange(key, null, true);
}
onReady(func) {
this.emitter.on('ready', func);
return () => {
this.emitter.removeListener('ready', func);
};
}
onRowsChange(func) {
this.emitter.on('rowschange', func);
return () => {
this.emitter.removeListener('rowschange', func);
};
}
onChange(func) {
this.emitter.on('change', func);
return () => {
this.emitter.removeListener('change', func);
};
}
}
export default new I18nUtil();

View File

@ -3,7 +3,7 @@ import Popup from '@ali/ve-popups';
import Icons from '@ali/ve-icons';
import logger from '@ali/vu-logger';
import { render } from 'react-dom';
import I18nUtil from '@ali/ve-i18n-util';
import I18nUtil from './i18n-util';
import { hotkey as Hotkey } from '@ali/lowcode-editor-core';
import { createElement } from 'react';
import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS, VERSION as Version } from './base/const';
@ -161,11 +161,10 @@ export {
Symbols,
};
const version = '6.0.0(LowcodeEngine 0.9.0-beta)';
/*
console.log(
`%cLowcodeEngine %cv${VERSION}`,
"color:#000;font-weight:bold;",
"color:green;font-weight:bold;"
`%c VisionEngine %c v${version} `,
"padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060;font-weight:bold;",
"padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: #42c02e;font-weight:bold;"
);
*/

View File

@ -4,33 +4,60 @@ import { DocumentModel } from '@ali/lowcode-designer';
const { project } = designer;
export interface OldPageData {
export interface PageDataV1 {
id: string;
componentsTree: RootSchema[];
layout: RootSchema;
[dataAddon: string]: any;
}
export interface PageDataV2 {
id: string;
componentsTree: RootSchema[];
[dataAddon: string]: any;
}
function isPageDataV1(obj: any): obj is PageDataV1 {
return obj && obj.layout;
}
function isPageDataV2(obj: any): obj is PageDataV2 {
return obj && obj.componentsTree && Array.isArray(obj.componentsTree);
}
type OldPageData = PageDataV1 | PageDataV2;
const pages = Object.assign(project, {
setPages(pages: OldPageData[]) {
if (!pages || !Array.isArray(pages) || pages.length === 0) {
throw new Error('pages schema 不合法');
}
if (pages[0].componentsTree[0]) {
pages[0].componentsTree[0].componentName = 'Page';
let componentsTree: any;
if (isPageDataV1(pages[0])) {
componentsTree = [pages[0].layout];
} else {
componentsTree = pages[0].componentsTree;
if (componentsTree[0]) {
componentsTree[0].componentName = 'Page';
// FIXME
pages[0].componentsTree[0].lifeCycles = {};
pages[0].componentsTree[0].methods = {};
componentsTree[0].lifeCycles = {};
componentsTree[0].methods = {};
}
}
project.load({
version: '1.0.0',
componentsMap: [],
componentsTree: pages[0].componentsTree,
componentsTree,
}, true);
},
addPage(data: OldPageData) {
return project.open(data.layout);
addPage(data: OldPageData | RootSchema) {
if (isPageDataV1(data)) {
data = data.layout;
} else if (isPageDataV2(data)) {
data = data.componentsTree[0];
}
return project.open(data);
},
getPage(fnOrIndex: ((page: DocumentModel) => boolean) | number) {
if (typeof fnOrIndex === 'number') {

View File

@ -2,6 +2,7 @@ import { skeleton, editor } from './editor';
import { ReactElement } from 'react';
import { IWidgetBaseConfig, Skeleton } from '@ali/lowcode-editor-skeleton';
import { uniqueId } from '@ali/lowcode-utils';
import bus from './bus';
export interface IContentItemConfig {
title: string;
@ -92,6 +93,7 @@ function upgradeConfig(config: OldPaneConfig): IWidgetBaseConfig & { area: strin
type: 'Panel',
name: typeof title === 'string' ? title : `${name}:${index}`,
content,
contentProps: props,
props: {
title,
help: tip,
@ -132,7 +134,18 @@ function add(config: (() => OldPaneConfig) | OldPaneConfig, extraConfig?: any) {
config = { ...config, ...extraConfig };
}
skeleton.add(upgradeConfig(config));
const upgraded = upgradeConfig(config);
if (upgraded.area === 'stages') {
if (upgraded.id) {
upgraded.name = upgraded.id;
} else if (!upgraded.name) {
upgraded.name = uniqueId('stage');
}
const stage = skeleton.add(upgraded);
return stage?.getName();
} else {
return skeleton.add(upgraded);
}
}
const actionPane = Object.assign(skeleton.topArea, {
@ -164,6 +177,7 @@ const dockPane = Object.assign(skeleton.leftArea, {
console.warn(`Could not find pane with name ${name}`);
}
pane?.active();
bus.emit('ve.dock_pane.active_doc', pane);
},
/**

View File

@ -1,4 +1,4 @@
class Project {
export class Project {
private schema: any;
constructor() {

View File

@ -1,7 +1,7 @@
import { EditingTarget, Node as DocNode } from '@ali/lowcode-designer';
import { EditingTarget, Node as DocNode, SaveHandler } from '@ali/lowcode-designer';
import Env from './env';
import { isJSExpression } from '@ali/lowcode-types';
const I18nUtil = require('@ali/ve-i18n-util');
import { isJSExpression, isI18nData } from '@ali/lowcode-types';
import i18nUtil from './i18n-util';
interface I18nObject {
type?: string;
@ -13,7 +13,7 @@ interface I18nObject {
function getI18nText(obj: I18nObject) {
let locale = Env.getLocale();
if (obj.key) {
return I18nUtil.get(obj.key, locale);
return i18nUtil.get(obj.key, locale);
}
if (locale !== 'zh_CN' && locale !== 'zh_TW' && !obj[locale]) {
locale = 'en_US';
@ -26,7 +26,10 @@ function getText(node: DocNode, prop: string) {
if (!p || p.isUnset()) {
return null;
}
const v = p.getValue();
let v = p.getValue();
if (isJSExpression(v)) {
v = v.mock;
}
if (v == null) {
return null;
}
@ -36,9 +39,7 @@ function getText(node: DocNode, prop: string) {
if ((v as any).type === 'i18n') {
return getI18nText(v as any);
}
if (isJSExpression(v)) {
return v.mock;
}
return Symbol.for('not-literal');
}
export function liveEditingRule(target: EditingTarget) {
@ -53,8 +54,7 @@ export function liveEditingRule(target: EditingTarget) {
const innerText = targetElement.innerText;
const propTarget = ['title', 'label', 'text', 'content'].find(prop => {
// TODO: enhance compare text logic
return getText(node, prop) === innerText;
return equalText(getText(node, prop), innerText);
});
if (propTarget) {
@ -66,7 +66,51 @@ export function liveEditingRule(target: EditingTarget) {
return null;
}
// TODO:
export function liveEditingSaveHander() {
function equalText(v: any, innerText: string) {
// TODO: enhance compare text logic
if (typeof v !== 'string') {
return false;
}
return v.trim() === innerText
}
export const liveEditingSaveHander: SaveHandler = {
condition: (prop) => {
const v = prop.getValue();
return prop.type === 'expression' || isI18nData(v);
},
onSaveContent: (content, prop) => {
const v = prop.getValue();
const locale = Env.getLocale();
let data = v;
if (isJSExpression(v)) {
data = v.mock;
}
if (isI18nData(data)) {
const i18n = data.key ? i18nUtil.getItem(data.key) : null;
if (i18n) {
i18n.setDoc(content, locale);
return;
}
data = {
...(data as any),
[locale]: content,
};
} else {
data = content;
}
if (isJSExpression(v)) {
prop.setValue({
type: 'JSExpression',
value: v.value,
mock: data,
});
} else {
prop.setValue(data);
}
}
}
// TODO:
// 非文本编辑
// 国际化数据,改变当前
// JSExpression, 改变 mock 或 弹出绑定变量

View File

@ -43,7 +43,7 @@ html {
}
html.engine-blur #engine {
-webkit-filter: blur(4px);
filter: blur(4px);
}
.engine-main {
@ -98,6 +98,11 @@ html.engine-blur #engine {
}
}
.vs-icon .vs-icon-del, .vs-icon .vs-icon-entry {
width: 16px!important;
height: 16px!important;
}
.lc-left-float-pane {
font-size: 14px;
}
@ -107,3 +112,13 @@ html.engine-preview-mode {
display: none !important;
}
}
.ve-popups .ve-message {
right: 290px;
.ve-message-content {
display: flex;
align-items: center;
line-height: 22px;
}
}

View File

@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.9.3"></a>
## [0.9.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-setters@0.9.2...@ali/lowcode-editor-setters@0.9.3) (2020-06-15)
**Note:** Version bump only for package @ali/lowcode-editor-setters
<a name="0.9.2"></a>
## [0.9.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-setters@0.9.1...@ali/lowcode-editor-setters@0.9.2) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-editor-setters
<a name="0.9.1"></a>
## 0.9.1 (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-setters
<a name="0.8.15"></a>
## [0.8.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.14...@ali/lowcode-setters@0.8.15) (2020-05-15)
**Note:** Version bump only for package @ali/lowcode-setters
<a name="0.8.14"></a>
## [0.8.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.13...@ali/lowcode-setters@0.8.14) (2020-05-13)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-editor-setters",
"version": "0.9.0",
"version": "0.9.3",
"description": "Builtin setters for Ali lowCode engine",
"files": [
"es",
@ -22,7 +22,7 @@
"@ali/iceluna-comp-react-node": "^1.0.5",
"@ali/iceluna-sdk": "^1.0.5-beta.24",
"@ali/lc-style-setter": "^0.0.1",
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-editor-core": "^0.8.16",
"@alifd/next": "^1.19.16",
"acorn": "^6.4.1",
"classnames": "^2.2.6",

View File

@ -3,6 +3,93 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.8.26"></a>
## [0.8.26](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.25...@ali/lowcode-editor-skeleton@0.8.26) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.25"></a>
## [0.8.25](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.24...@ali/lowcode-editor-skeleton@0.8.25) (2020-06-15)
### Bug Fixes
* 修复bool类型对应的setter ([2df6230](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/2df6230))
* 禁止组件拉到 Page 的直接子节点, 以及替换 tab 组件 ([d93a291](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/d93a291))
* 调整保存成功弹出框位置 ([5198dae](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/5198dae))
### Features
* add URL link for setter titles ([4678408](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/4678408))
* panel增加自动埋点 ([afc7758](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/afc7758))
* 自动埋点 ([fecf34d](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fecf34d))
<a name="0.8.24"></a>
## [0.8.24](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.23...@ali/lowcode-editor-skeleton@0.8.24) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.23"></a>
## [0.8.23](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.22...@ali/lowcode-editor-skeleton@0.8.23) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.22"></a>
## [0.8.22](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.21...@ali/lowcode-editor-skeleton@0.8.22) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.21"></a>
## [0.8.21](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.20...@ali/lowcode-editor-skeleton@0.8.21) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.20"></a>
## [0.8.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.19...@ali/lowcode-editor-skeleton@0.8.20) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.19"></a>
## [0.8.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.18...@ali/lowcode-editor-skeleton@0.8.19) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-editor-skeleton
<a name="0.8.18"></a>
## [0.8.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.17...@ali/lowcode-editor-skeleton@0.8.18) (2020-05-15)
### Bug Fixes
* 解决点击数据源,自动隐藏的问题 ([7dcd61c](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/7dcd61c))
<a name="0.8.17"></a>
## [0.8.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.16...@ali/lowcode-editor-skeleton@0.8.17) (2020-05-15)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-editor-skeleton",
"version": "0.8.17",
"version": "0.8.26",
"description": "alibaba lowcode editor skeleton",
"main": "lib/index.js",
"module": "es/index.js",
@ -19,11 +19,11 @@
"editor"
],
"dependencies": {
"@ali/lowcode-designer": "^0.9.11",
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-types": "^0.8.3",
"@ali/lowcode-utils": "^0.8.4",
"@alifd/next": "^1.x",
"@ali/lowcode-designer": "^0.9.20",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-types": "^0.8.6",
"@ali/lowcode-utils": "^0.8.7",
"@alifd/next": "^1.20.12",
"classnames": "^2.2.6",
"react": "^16.8.1",
"react-dom": "^16.8.1"

View File

@ -12,6 +12,7 @@ import InlineTip from './inlinetip';
export interface FieldProps {
className?: string;
meta?: { package: string; componentName: string } | string;
title?: TitleContent | null;
defaultDisplay?: 'accordion' | 'inline' | 'block';
collapsed?: boolean;
@ -28,6 +29,11 @@ export class Field extends Component<FieldProps> {
display: this.props.defaultDisplay || 'inline',
};
constructor(props: any) {
super(props);
this.handleClear = this.handleClear.bind(this);
}
private toggleExpand = () => {
const { onExpandChange } = this.props;
const collapsed = !this.state.collapsed;
@ -68,6 +74,10 @@ export class Field extends Component<FieldProps> {
});
this.dispose = () => observer.disconnect();
}
private handleClear(e: React.MouseEvent) {
e.stopPropagation();
this.props.onClear && this.props.onClear();
}
componentDidMount() {
const { defaultDisplay } = this.props;
if (!defaultDisplay || defaultDisplay === 'inline') {
@ -106,19 +116,27 @@ export class Field extends Component<FieldProps> {
}
render() {
const { className, children, title, valueState, onClear, name: propName, tip } = this.props;
const { className, children, meta, title, valueState, onClear, name: propName, tip } = this.props;
const { display, collapsed } = this.state;
const isAccordion = display === 'accordion';
let hostName = '';
if (typeof meta === 'object') {
hostName = `${meta?.package || ''}-${meta.componentName || ''}`;
} else if (typeof meta === 'string') {
hostName = meta;
}
const id = `${hostName}-${propName || (title as any)['en-US'] || (title as any)['zh-CN']}`;
const tipContent = this.getTipContent(propName!, tip);
return (
<div
className={classNames(`lc-field lc-${display}-field`, className, {
'lc-field-is-collapsed': isAccordion && collapsed,
})}
id={id}
>
<div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}>
<div className="lc-field-title">
{createValueState(valueState, onClear)}
{createValueState(valueState, this.handleClear)}
<Title title={title || ''} />
<InlineTip position="top">{tipContent}</InlineTip>
</div>
@ -143,7 +161,7 @@ export class Field extends Component<FieldProps> {
*
* TODO: turn number to enum
*/
function createValueState(valueState?: number, onClear?: () => void) {
function createValueState(valueState?: number, onClear?: (e: React.MouseEvent) => void) {
let tip: any = null;
let className = 'lc-valuestate';
let icon: any = null;

View File

@ -67,16 +67,16 @@
}
}
&.lc-plain-field {
// for top-level style
// padding: 8px 10px;
> .lc-field-body {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
}
}
// &.lc-plain-field {
// // for top-level style
// // padding: 8px 10px;
// > .lc-field-body {
// flex: 1;
// min-width: 0;
// display: flex;
// align-items: center;
// }
// }
&.lc-inline-field {
display: flex;
@ -211,14 +211,14 @@
}
// 3rd level field title width should short
.lc-field-body .lc-inline-field {
> .lc-field-head {
width: 50px;
.lc-title-label {
width: 50px;
}
}
}
// .lc-field-body .lc-inline-field {
// > .lc-field-head {
// width: 50px;
// .lc-title-label {
// width: 50px;
// }
// }
// }
>.lc-block-setter {
flex: 1;
}

View File

@ -59,8 +59,8 @@ export class PopupPipe {
}
}
export default class PopupService extends Component<{ actionKey?: string; safeId?: string }> {
private popupPipe = new PopupPipe();
export default class PopupService extends Component<{ popupPipe?: PopupPipe; actionKey?: string; safeId?: string }> {
private popupPipe = this.props.popupPipe || new PopupPipe();
componentWillUnmount() {
this.popupPipe.purge();
@ -121,6 +121,7 @@ export class PopupContent extends PureComponent<{ safeId?: string }> {
className="lc-ballon"
align="l"
id={this.props.safeId}
alignEdge
safeNode={id}
visible={visible}
style={{ width }}
@ -135,7 +136,7 @@ export class PopupContent extends PureComponent<{ safeId?: string }> {
trigger={<div className="lc-popup-placeholder" style={pos} />}
triggerType="click"
animation={false}
// needAdjust
needAdjust
shouldUpdatePosition
>
<div className="lc-ballon-title">{title}</div>

View File

@ -13,10 +13,16 @@
}
.lc-ballon-content {
margin-top: 10px;
// width: 300px;
// FIXME: popup position is bad
max-height: calc(60vh);
overflow-x: hidden;
overflow-y: auto;
}
&.next-balloon-closable {
padding: 10px !important;
}
.next-balloon-close {
top: 4px;
right: 4px;
top: 4px !important;
right: 4px !important;
}
}

View File

@ -1,11 +1,13 @@
import { Component } from 'react';
import { Component, MouseEvent } from 'react';
import { shallowIntl, createSetterContent, observer } from '@ali/lowcode-editor-core';
import { createContent } from '@ali/lowcode-utils';
import { Field, createField } from '../field';
import PopupService from '../popup';
import PopupService, { PopupPipe } from '../popup';
import { SkeletonContext } from '../../context';
import { SettingField, isSettingField, SettingTopEntry, SettingEntry } from '@ali/lowcode-designer';
import { isSetterConfig, CustomView } from '@ali/lowcode-types';
import { intl } from '../../locale';
import { Skeleton } from 'editor-skeleton/src/skeleton';
@observer
class SettingFieldView extends Component<{ field: SettingField }> {
@ -61,6 +63,7 @@ class SettingFieldView extends Component<{ field: SettingField }> {
return createField(
{
meta: field?.componentMeta?.npm || field?.componentMeta?.componentName || '',
title: field.title,
collapsed: !field.expanded,
valueState: field.isRequired ? 10 : field.valueState,
@ -119,6 +122,7 @@ class SettingGroupView extends Component<{ field: SettingField }> {
return (
<Field
defaultDisplay="accordion"
meta={field?.componentMeta?.npm || field?.componentMeta?.componentName || ''}
title={field.title}
collapsed={!field.expanded}
onExpandChange={(expandState) => {
@ -145,17 +149,54 @@ export function createSettingFieldView(item: SettingField | CustomView, field: S
@observer
export class SettingsPane extends Component<{ target: SettingTopEntry | SettingField }> {
static contextType = SkeletonContext;
shouldComponentUpdate() {
return false;
}
private popupPipe = new PopupPipe();
private pipe = this.popupPipe.create();
private handleClick = (e: MouseEvent) => {
// compatiable vision stageBox
// TODO: optimize these codes
const pane = e.currentTarget as HTMLDivElement;
let entry: any;
function getTarget(node: any): any {
if (!pane.contains(node) || (node.nodeName === 'A' && node.getAttribute('href'))) {
return null;
}
const target = node.dataset ? node.dataset.stageTarget : null;
if (target) {
entry = node;
return target;
}
return getTarget(node.parentNode);
}
const target = getTarget(e.target);
if (!target) {
return;
}
const skeleton = this.context as Skeleton;
if (!skeleton || !skeleton.stages) {
return;
}
const stage = skeleton.stages.container.get(target);
if (stage) {
this.pipe.send(stage.content, stage.title);
this.pipe.show(entry);
}
};
render() {
const { target } = this.props;
const items = target.items;
return (
<div className="lc-settings-pane">
<div className="lc-settings-pane" onClick={this.handleClick}>
{/* todo: add head for single use */}
<PopupService>
<PopupService popupPipe={this.popupPipe}>
<div className="lc-settings-content">
{items.map((item, index) => createSettingFieldView(item, target, index))}
</div>

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Tab, Breadcrumb } from '@alifd/next';
import { Title, observer, Editor } from '@ali/lowcode-editor-core';
import { Node, isSettingField, SettingField } from '@ali/lowcode-designer';
import { Title, observer, Editor, obx, globalContext } from '@ali/lowcode-editor-core';
import { Node, isSettingField, SettingField, Designer } from '@ali/lowcode-designer';
import { SettingsMain } from './main';
import { SettingsPane } from './settings-pane';
import { createIcon } from '@ali/lowcode-utils';
@ -10,6 +10,8 @@ import { createIcon } from '@ali/lowcode-utils';
export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
private main = new SettingsMain(this.props.editor);
@obx.ref private _activeKey?: any;
shouldComponentUpdate() {
return false;
}
@ -33,6 +35,9 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
);
}
const editor = globalContext.get(Editor);
const designer = editor.get(Designer);
const current = designer?.currentSelection?.getNodes()?.[0];
let node: Node | null = settings.first;
const items = [];
let l = 3;
@ -43,9 +48,27 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
: {
onMouseOver: hoverNode.bind(null, node, true),
onMouseOut: hoverNode.bind(null, node, false),
onClick: selectNode.bind(null, node),
onClick: () => {
selectNode.call(null, node);
const getName = (node) => {
const npm = node?.componentMeta?.npm;
return [npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
node?.componentMeta?.componentName ||
'';
};
items.unshift(<Breadcrumb.Item {...props} key={node.id}><Title title={node.title} /></Breadcrumb.Item>);
const selected = getName(current);
const target = getName(node);
editor?.emit('skeleton.settingsPane.Breadcrumb', {
selected,
target,
});
},
};
items.unshift(
<Breadcrumb.Item {...props} key={node.id}>
<Title title={node.title} />
</Breadcrumb.Item>,
);
node = node.parent;
}
@ -82,7 +105,7 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
}
const { items } = settings;
if (items.length > 5 || items.some(item => !isSettingField(item) || !item.isGroup)) {
if (items.length > 5 || items.some((item) => !isSettingField(item) || !item.isGroup)) {
return (
<div className="lc-settings-main">
{this.renderBreadcrumb()}
@ -93,21 +116,34 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
);
}
let matched = false;
const tabs = (items as SettingField[]).map((field) => {
if (this._activeKey === field.name) {
matched = true;
}
return (
<Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}>
<SettingsPane target={field} key={field.id} />
</Tab.Item>
);
});
const activeKey = matched ? this._activeKey : (items[0] as SettingField).name;
return (
<div className="lc-settings-main">
<Tab
key={settings.id}
activeKey={activeKey}
onChange={(tabKey) => {
this._activeKey = tabKey;
}}
navClassName="lc-settings-tabs"
animation={false}
excessMode="dropdown"
contentClassName="lc-settings-tabs-content"
disableKeyboard={true}
extra={this.renderBreadcrumb()}
>
{(items as SettingField[]).map(field => (
<Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}>
<SettingsPane target={field} key={field.id} />
</Tab.Item>
))}
{tabs}
</Tab>
</div>
);

View File

@ -1,7 +1,7 @@
import { Component, ReactElement } from 'react';
import { Icon } from '@alifd/next';
import classNames from 'classnames';
import { Title, observer, Tip } from '@ali/lowcode-editor-core';
import { Title, observer, Tip, globalContext, Editor } from '@ali/lowcode-editor-core';
import { DockProps } from '../types';
import PanelDock from '../widget/panel-dock';
import { composeTitle } from '../widget/utils';
@ -38,7 +38,7 @@ function HelpTip({ tip }: any) {
<Icon type="help" size="small" className="lc-help-tip" />
<Tip>{tip.content}</Tip>
</div>
)
);
}
@observer
@ -49,7 +49,7 @@ export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
componentDidUpdate() {
this.checkActived();
}
private lastActived: boolean = false;
private lastActived = false;
checkActived() {
const { dock } = this.props;
if (dock.actived !== this.lastActived) {
@ -77,12 +77,10 @@ export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
}
}
export class DialogDockView extends Component {
}
export class DialogDockView extends Component {}
@observer
export class TitledPanelView extends Component<{ panel: Panel }> {
export class TitledPanelView extends Component<{ panel: Panel; area?: string }> {
shouldComponentUpdate() {
return false;
}
@ -92,7 +90,7 @@ export class TitledPanelView extends Component<{ panel: Panel }> {
componentDidUpdate() {
this.checkVisible();
}
private lastVisible: boolean = false;
private lastVisible = false;
checkVisible() {
const { panel } = this.props;
const currentVisible = panel.inited && panel.visible;
@ -106,14 +104,23 @@ export class TitledPanelView extends Component<{ panel: Panel }> {
}
}
render() {
const { panel } = this.props;
const { panel, area } = this.props;
if (!panel.inited) {
return null;
}
const editor = globalContext.get(Editor);
const panelName = area ? `${area}-${panel.name}` : panel.name;
editor?.emit('skeleton.panel.toggle', {
name: panelName || '',
status: panel.visible ? 'show' : 'hide',
});
return (
<div className={classNames('lc-titled-panel', {
<div
className={classNames('lc-titled-panel', {
hidden: !panel.visible,
})}>
})}
id={panelName}
>
<PanelTitle panel={panel} />
<div className="lc-panel-body">{panel.body}</div>
</div>
@ -122,7 +129,7 @@ export class TitledPanelView extends Component<{ panel: Panel }> {
}
@observer
export class PanelView extends Component<{ panel: Panel }> {
export class PanelView extends Component<{ panel: Panel; area?: string }> {
shouldComponentUpdate() {
return false;
}
@ -132,7 +139,7 @@ export class PanelView extends Component<{ panel: Panel }> {
componentDidUpdate() {
this.checkVisible();
}
private lastVisible: boolean = false;
private lastVisible = false;
checkVisible() {
const { panel } = this.props;
const currentVisible = panel.inited && panel.visible;
@ -150,15 +157,22 @@ export class PanelView extends Component<{ panel: Panel }> {
}
}
render() {
const { panel } = this.props;
const { panel, area } = this.props;
if (!panel.inited) {
return null;
}
const editor = globalContext.get(Editor);
const panelName = area ? `${area}-${panel.name}` : panel.name;
editor?.emit('skeleton.panel.toggle', {
name: panelName || '',
status: panel.visible ? 'show' : 'hide',
});
return (
<div
className={classNames('lc-panel', {
hidden: !panel.visible,
})}
id={panelName}
>
{panel.body}
</div>
@ -233,7 +247,7 @@ export class WidgetView extends Component<{ widget: IWidget }> {
componentDidUpdate() {
this.checkVisible();
}
private lastVisible: boolean = false;
private lastVisible = false;
checkVisible() {
const { widget } = this.props;
const currentVisible = widget.visible;

View File

@ -0,0 +1,4 @@
import { createContext } from 'react';
import { Skeleton } from './skeleton';
export const SkeletonContext = createContext<Skeleton>({} as any);

View File

@ -3,5 +3,6 @@ export * from './skeleton';
export * from './types';
export * from './components/settings';
export * from './components/field';
export * from './context';
import './register-defaults';

View File

@ -24,11 +24,12 @@ class Contents extends Component<{ area: Area }> {
const { area } = this.props;
const top: any[] = [];
const bottom: any[] = [];
area.container.items.forEach(item => {
area.container.items.forEach((item) => {
const content = <div id={`left-area-${item.name}`}>{item.content}</div>;
if (item.align === 'bottom') {
bottom.push(item.content);
bottom.push(content);
} else {
top.push(item.content);
top.push(content);
}
});
return (

View File

@ -25,8 +25,7 @@ export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, P
'lc-area-visible': area.visible,
})}
>
{
!hideTitleBar && (
{!hideTitleBar && (
<Button
text
className="lc-pane-close"
@ -36,8 +35,7 @@ export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, P
>
<Icon type="close" />
</Button>
)
}
)}
<Contents area={area} />
</div>
);
@ -51,10 +49,6 @@ class Contents extends Component<{ area: Area<PanelConfig, Panel> }> {
}
render() {
const { area } = this.props;
return (
<Fragment>
{area.container.items.map((panel) => panel.content)}
</Fragment>
);
return <Fragment>{area.container.items.map((panel) => panel.content)}</Fragment>;
}
}

View File

@ -31,6 +31,15 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }>
if (this.shell?.contains(target)) {
return true;
}
// 点击了 iframe 内容,算失焦
if (document.querySelector('.lc-simulator-content-frame')
.contentWindow.document.documentElement.contains(target)) {
return false;
}
// 点击非编辑区域的 popup / dialog 等,不触发失焦
if (!document.querySelector('.lc-workbench')?.contains(target)) {
return true;
}
const docks = area.current?.getAssocDocks();
if (docks && docks?.length) {
return docks.some(dock => dock.getDOMNode()?.contains(target));
@ -41,6 +50,7 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }>
this.props.area.setVisible(false);
},
onBlur: () => {
// debugger
this.props.area.setVisible(false);
},
});

View File

@ -30,7 +30,7 @@ class Contents extends Component<{ area: Area, itemClassName?: string }> {
return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1);
}).forEach(item => {
const content = (
<div className={itemClassName || ''}>
<div className={itemClassName || ''} id={`top-area-${item.name}`}>
{item.content}
</div>
);

View File

@ -11,6 +11,7 @@ import MainArea from './main-area';
import BottomArea from './bottom-area';
import RightArea from './right-area';
import './workbench.less';
import { SkeletonContext } from '../context';
import { EditorConfig, PluginClassSet } from '@ali/lowcode-types';
@observer
@ -28,6 +29,7 @@ export class Workbench extends Component<{ skeleton: Skeleton; config?: EditorCo
const { skeleton, className, topAreaItemClassName } = this.props;
return (
<div className={classNames('lc-workbench', className)}>
<SkeletonContext.Provider value={this.props.skeleton}>
<TopArea area={skeleton.topArea} itemClassName={topAreaItemClassName} />
<div className="lc-workbench-body">
<LeftArea area={skeleton.leftArea} />
@ -41,6 +43,7 @@ export class Workbench extends Component<{ skeleton: Skeleton; config?: EditorCo
<RightArea area={skeleton.rightArea} />
</div>
<TipContainer />
</SkeletonContext.Provider>
</div>
);
}

View File

@ -294,7 +294,7 @@ export class Skeleton {
let { area } = parsedConfig;
if (!area) {
if (parsedConfig.type === 'Panel') {
area = 'leftFloatArea'
area = 'leftFloatArea';
} else if (parsedConfig.type === 'Widget') {
area = 'mainArea';
} else {

View File

@ -1,5 +1,6 @@
import { TransformedComponentMetadata, FieldConfig, SettingTarget } from '@ali/lowcode-types';
import { IconSlot } from '../icons/slot';
import { getConvertedExtraKey } from '@ali/lowcode-designer';
export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata {
const { componentName, configure = {} } = metadata;
@ -86,7 +87,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
if (componentName === 'Slot') {
basicInfo.icon = IconSlot;
propsGroup = [{
name: '___title',
name: getConvertedExtraKey('title'),
title: {
type: 'i18n',
'en-US': 'Slot Title',
@ -203,7 +204,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
if (!isRoot) {
if (supports.condition !== false) {
advanceGroup.push({
name: '___condition',
name: getConvertedExtraKey('condition'),
title: { type: 'i18n', 'zh-CN': '是否渲染', 'en-US': 'Condition' },
defaultValue: true,
setter: [{
@ -219,7 +220,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' },
items: [
{
name: '___loop',
name: getConvertedExtraKey('loop'),
title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' },
defaultValue: [],
setter: [{
@ -232,7 +233,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
}],
},
{
name: '___loopArgs.0',
name: getConvertedExtraKey('loopArgs.0'),
title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' },
setter: {
componentName: 'StringSetter',
@ -242,7 +243,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
},
},
{
name: '___loopArgs.1',
name: getConvertedExtraKey('loopArgs.1'),
title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' },
setter: {
componentName: 'StringSetter',

View File

@ -53,7 +53,7 @@ function propTypeToSetter(propType: PropType): SetterType {
};
case 'bool':
return {
componentName: 'NumberSetter',
componentName: 'BoolSetter',
isRequired,
initialValue: false,
};

View File

@ -18,6 +18,7 @@ export interface WidgetConfig extends IWidgetBaseConfig {
props?: {
align?: "left" | "right" | "bottom" | "center" | "top";
onInit?: (widget: IWidget) => void;
title?: TitleContent;
};
content?: string | ReactElement | ComponentType<any>; // children
}

View File

@ -53,13 +53,16 @@ export default class Panel implements IWidget {
}
get content(): ReactNode {
const area = this.config?.area || this.parent?.name;
console.log(area);
if (this.plain) {
return createElement(PanelView, {
panel: this,
key: this.id,
area,
});
}
return createElement(TitledPanelView, { panel: this, key: this.id });
return createElement(TitledPanelView, { panel: this, key: this.id, area });
}
readonly title: TitleContent;

View File

@ -4,6 +4,7 @@ import { createContent, uniqueId } from '@ali/lowcode-utils';
import { WidgetConfig, IWidgetBaseConfig } from '../types';
import { Skeleton } from '../skeleton';
import { WidgetView } from '../components/widget-views';
import { TitleContent } from '@ali/lowcode-types';
export interface IWidget {
readonly name: string;
@ -56,10 +57,13 @@ export default class Widget implements IWidget {
});
}
readonly title: TitleContent;
constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) {
const { props = {}, name } = config;
this.name = name;
this.align = props.align;
this.title = props.title || name;
if (props.onInit) {
props.onInit.call(this, this);
}

View File

@ -3,6 +3,89 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.8.23"></a>
## [0.8.23](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.22...@ali/lowcode-plugin-components-pane@0.8.23) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.22"></a>
## [0.8.22](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.21...@ali/lowcode-plugin-components-pane@0.8.22) (2020-06-15)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.21"></a>
## [0.8.21](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.20...@ali/lowcode-plugin-components-pane@0.8.21) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.20"></a>
## [0.8.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.19...@ali/lowcode-plugin-components-pane@0.8.20) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.19"></a>
## [0.8.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.18...@ali/lowcode-plugin-components-pane@0.8.19) (2020-05-18)
### Features
* use new ComponentPane ([56ae5ad](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/56ae5ad))
<a name="0.8.18"></a>
## [0.8.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.17...@ali/lowcode-plugin-components-pane@0.8.18) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.17"></a>
## [0.8.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.16...@ali/lowcode-plugin-components-pane@0.8.17) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.16"></a>
## [0.8.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.15...@ali/lowcode-plugin-components-pane@0.8.16) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.15"></a>
## [0.8.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.14...@ali/lowcode-plugin-components-pane@0.8.15) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.14"></a>
## [0.8.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.13...@ali/lowcode-plugin-components-pane@0.8.14) (2020-05-15)
**Note:** Version bump only for package @ali/lowcode-plugin-components-pane
<a name="0.8.13"></a>
## [0.8.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.12...@ali/lowcode-plugin-components-pane@0.8.13) (2020-05-15)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-plugin-components-pane",
"version": "0.8.13",
"version": "0.8.23",
"description": "alibaba lowcode editor component-list plugin",
"files": [
"es/",
@ -20,11 +20,11 @@
],
"author": "xiayang.xy",
"dependencies": {
"@ali/lowcode-designer": "^0.9.11",
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-types": "^0.8.3",
"@alifd/next": "^1.19.19",
"@ali/lowcode-designer": "^0.9.20",
"@ali/lowcode-editor-core": "^0.8.16",
"@ali/lowcode-types": "^0.8.6",
"@ali/ve-component-list": "^1.1.1",
"@alifd/next": "^1.19.19",
"react": "^16.8.1"
},
"devDependencies": {

View File

@ -3,6 +3,78 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="0.9.20"></a>
## [0.9.20](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.19...@ali/lowcode-plugin-designer@0.9.20) (2020-06-16)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.19"></a>
## [0.9.19](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.18...@ali/lowcode-plugin-designer@0.9.19) (2020-06-15)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.18"></a>
## [0.9.18](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.17...@ali/lowcode-plugin-designer@0.9.18) (2020-05-20)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.17"></a>
## [0.9.17](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.16...@ali/lowcode-plugin-designer@0.9.17) (2020-05-19)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.16"></a>
## [0.9.16](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.15...@ali/lowcode-plugin-designer@0.9.16) (2020-05-18)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.15"></a>
## [0.9.15](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.14...@ali/lowcode-plugin-designer@0.9.15) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.14"></a>
## [0.9.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.13...@ali/lowcode-plugin-designer@0.9.14) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.13"></a>
## [0.9.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.12...@ali/lowcode-plugin-designer@0.9.13) (2020-05-16)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.12"></a>
## [0.9.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.11...@ali/lowcode-plugin-designer@0.9.12) (2020-05-15)
**Note:** Version bump only for package @ali/lowcode-plugin-designer
<a name="0.9.11"></a>
## [0.9.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.10...@ali/lowcode-plugin-designer@0.9.11) (2020-05-15)

View File

@ -1,6 +1,6 @@
{
"name": "@ali/lowcode-plugin-designer",
"version": "0.9.11",
"version": "0.9.20",
"description": "alibaba lowcode editor designer plugin",
"files": [
"es",
@ -20,8 +20,8 @@
],
"author": "xiayang.xy",
"dependencies": {
"@ali/lowcode-designer": "^0.9.11",
"@ali/lowcode-editor-core": "^0.8.12",
"@ali/lowcode-designer": "^0.9.20",
"@ali/lowcode-editor-core": "^0.8.16",
"react": "^16.8.1",
"react-dom": "^16.8.1"
},

Some files were not shown because too many files have changed in this diff Show More