mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-02-28 04:40:32 +00:00
Merge branch 'v/0.8.0' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into preset-general/0.9.0
This commit is contained in:
commit
55a707bbf5
@ -1,130 +1,17 @@
|
|||||||
// mixin
|
.expression-setter-item-inner {
|
||||||
.lowcode-setter-mixin > * {
|
.next-menu-item-text {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
display: flex;
|
||||||
.lowcode-setter-mixin {
|
justify-content: space-between;
|
||||||
width: 86%;
|
|
||||||
}
|
|
||||||
.lowcode-setter-mixin .next-input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.lowcode-setter-mixin .next-select-trigger {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
// json-setter
|
|
||||||
// :global {
|
|
||||||
.nrs-monaco-form {
|
|
||||||
.next-form-item:last-child {
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.monaco-editor-wrap {
|
.next-menu-item {
|
||||||
.luna-monaco-button .next-icon-first {
|
padding: 0 10px;
|
||||||
height: 26px;
|
|
||||||
}
|
|
||||||
.monaco_fullscreen_icon {
|
|
||||||
position: absolute;
|
|
||||||
line-height: 1;
|
|
||||||
z-index: 7;
|
|
||||||
color: #ddd;
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.btns-eare {
|
|
||||||
text-align: left;
|
|
||||||
line-height: initial;
|
|
||||||
margin-top: 5px;
|
|
||||||
// button{
|
|
||||||
// margin-right: 10px;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
&.monaco-nofullscreen {
|
|
||||||
position: relative !important;
|
|
||||||
.monaco_fullscreen_icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
right: 5px;
|
|
||||||
line-height: 1;
|
|
||||||
z-index: 7;
|
|
||||||
i:before {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.monaco-fullscreen {
|
|
||||||
position: fixed !important;
|
|
||||||
height: 100% !important;
|
|
||||||
width: 100% !important;
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1001;
|
|
||||||
overflow: hidden;
|
|
||||||
.monaco_fullscreen_icon {
|
|
||||||
top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
i:before {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.luna-monaco-button button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.luna-monaco-button-dialog {
|
|
||||||
.next-dialog-body {
|
|
||||||
padding: 0;
|
|
||||||
.next-form-item {
|
|
||||||
height: 100%;
|
|
||||||
margin-bottom: 0;
|
|
||||||
.next-form-item-control,
|
|
||||||
.next-form-item-control > div {
|
|
||||||
height: 100% !important;
|
|
||||||
}
|
|
||||||
.next-form-item-help {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
// color-setter
|
|
||||||
.lowcode-color-box {
|
|
||||||
margin-right: -5px;
|
|
||||||
padding: 3px 0 3px 3px;
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
display: inline-block;
|
|
||||||
div {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.next-balloon-normal.lowcode-color-content {
|
.code-input-value {
|
||||||
padding: 0;
|
float: left;
|
||||||
background: #ffffff;
|
}
|
||||||
border-radius: 0;
|
.code-input-help {
|
||||||
border: 1px solid #e5e5e5;
|
float: right;
|
||||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
|
color: #6897f2;
|
||||||
&:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.sketch-picker {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
.flexbox-fix {
|
|
||||||
input {
|
|
||||||
width: 100% !important;
|
|
||||||
min-width: 30px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,24 +1,26 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Select, Balloon } from '@alife/next';
|
import { Select, Balloon, Icon } from '@alife/next';
|
||||||
import * as acorn from 'acorn';
|
import * as acorn from 'acorn';
|
||||||
|
|
||||||
import { isJSExpression, generateI18n } from './locale/utils';
|
import { isJSExpression, generateI18n } from './locale/utils';
|
||||||
import zhCN from './locale/zh-CN';
|
import zhCN from './locale/zh-CN';
|
||||||
|
|
||||||
|
import './index.scss';
|
||||||
|
|
||||||
const { Option, AutoComplete } = Select;
|
const { Option, AutoComplete } = Select;
|
||||||
const { Tooltip } = Balloon;
|
const { Tooltip } = Balloon;
|
||||||
const helpMap = {
|
const helpMap = {
|
||||||
this: '容器上下文对象',
|
this: '容器上下文对象',
|
||||||
'this.state': '容器的state',
|
'state': '容器的state',
|
||||||
'this.props': '容器的props',
|
'props': '容器的props',
|
||||||
'this.context': '容器的context',
|
'context': '容器的context',
|
||||||
'this.page': '页面上下文对象',
|
'schema': '页面上下文对象',
|
||||||
'this.component': '组件上下文对象',
|
'component': '组件上下文对象',
|
||||||
'this.constants': '应用常量对象',
|
'constants': '应用常量对象',
|
||||||
'this.utils': '应用工具对象',
|
'utils': '应用工具对象',
|
||||||
'this.dataSourceMap': '容器数据源Map',
|
'dataSourceMap': '容器数据源Map',
|
||||||
'this.field': '表单Field对象'
|
'field': '表单Field对象'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ExpressionView extends PureComponent {
|
export default class ExpressionView extends PureComponent {
|
||||||
@ -45,7 +47,7 @@ export default class ExpressionView extends PureComponent {
|
|||||||
i18n: any;
|
i18n: any;
|
||||||
t: void;
|
t: void;
|
||||||
$input: any;
|
$input: any;
|
||||||
listenerFun: (event: any) => void;
|
listenerFun: ((event: any) => void) | undefined;
|
||||||
|
|
||||||
static getInitValue(val: { value: any; match: (arg0: RegExp) => any; }) {
|
static getInitValue(val: { value: any; match: (arg0: RegExp) => any; }) {
|
||||||
if (isJSExpression(val)) {
|
if (isJSExpression(val)) {
|
||||||
@ -81,51 +83,12 @@ export default class ExpressionView extends PureComponent {
|
|||||||
onChange(value: string, actionType: string) {
|
onChange(value: string, actionType: string) {
|
||||||
let realInputValue = value;
|
let realInputValue = value;
|
||||||
let realDataSource = null;
|
let realDataSource = null;
|
||||||
const cursorIndex = this.getInputCursorPosition();
|
|
||||||
let nextCursorIndex: number;
|
let nextCursorIndex: number;
|
||||||
//更新值
|
//更新值
|
||||||
if (actionType === 'itemClick' || actionType === 'enter') {
|
if (actionType === 'itemClick' || actionType === 'enter') {
|
||||||
let curValue = this.state.value;
|
let curValue = this.state.value;
|
||||||
if (curValue) {
|
if (curValue) {
|
||||||
//如果是非.结束,则替换当前这个变量;
|
realInputValue = curValue + realInputValue;
|
||||||
let preStr = curValue.substr(0, cursorIndex);
|
|
||||||
let nextStr = curValue.substr(cursorIndex);
|
|
||||||
let preArr = preStr.split('.');
|
|
||||||
let preArrLen = preArr.length;
|
|
||||||
let tarPreStr = '';
|
|
||||||
if (!preArr[preArrLen - 1]) {
|
|
||||||
//如果是.结束,则增加到.后面
|
|
||||||
if (preArr[preArrLen - 2] === 'this') {
|
|
||||||
preArr = preArr.slice(0, preArrLen - 2);
|
|
||||||
preArr.push(value);
|
|
||||||
tarPreStr = preArr.join('.');
|
|
||||||
} else {
|
|
||||||
tarPreStr = preStr + value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (preArr[preArrLen - 2] === 'this') {
|
|
||||||
preArr = preArr.slice(0, preArrLen - 2);
|
|
||||||
} else {
|
|
||||||
preArr = preArr.slice(0, preArrLen - 1);
|
|
||||||
}
|
|
||||||
preArr.push(value);
|
|
||||||
tarPreStr = preArr.join('.');
|
|
||||||
}
|
|
||||||
realInputValue = tarPreStr + nextStr;
|
|
||||||
realDataSource = this.getDataSource(tarPreStr + '.') || [];
|
|
||||||
nextCursorIndex = tarPreStr.length;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let tarPreStr = value.substr(0, cursorIndex);
|
|
||||||
if (tarPreStr) {
|
|
||||||
let lastChar = tarPreStr.charAt(tarPreStr.length - 1);
|
|
||||||
if (lastChar === '.') {
|
|
||||||
realDataSource = this.getDataSource(tarPreStr) || [];
|
|
||||||
} else {
|
|
||||||
realDataSource = this.getDataSource(tarPreStr + '.');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
realDataSource = this.getDataSource('this.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//更新数据源
|
//更新数据源
|
||||||
@ -154,21 +117,16 @@ export default class ExpressionView extends PureComponent {
|
|||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
getDataSource(tempStr: string): Array<any> {
|
getDataSource(tempStr: string): Array<any> {
|
||||||
if (tempStr === '' || /[^\w\.]$/.test(tempStr)) {
|
if (/[^\w\.]$/.test(tempStr)) {
|
||||||
return this.getDataSource('this.') || [];
|
return [];
|
||||||
|
} else if (tempStr === null || tempStr === '') {
|
||||||
|
return this.getContextKeys([]);
|
||||||
} else if (/\w\.$/.test(tempStr)) {
|
} else if (/\w\.$/.test(tempStr)) {
|
||||||
let currentField = this.getCurrentFiled(tempStr);
|
let currentField = this.getCurrentFiled(tempStr);
|
||||||
if (!currentField) return null;
|
if (!currentField) return null;
|
||||||
let tempKeys = this.getObjectKeys(currentField.str);
|
let tempKeys = this.getObjectKeys(currentField.str);
|
||||||
tempKeys = this.getContextKeys(tempKeys);
|
tempKeys = this.getContextKeys(tempKeys);
|
||||||
if (!tempKeys) return null;
|
if (!tempKeys) return null;
|
||||||
//给默认情况增加this
|
|
||||||
if (tempStr === 'this.') {
|
|
||||||
tempKeys = tempKeys.map((item: string) => {
|
|
||||||
return 'this.' + item;
|
|
||||||
});
|
|
||||||
tempKeys.unshift('this');
|
|
||||||
}
|
|
||||||
return tempKeys;
|
return tempKeys;
|
||||||
} else if (/\.$/.test(tempStr)) {
|
} else if (/\.$/.test(tempStr)) {
|
||||||
return [];
|
return [];
|
||||||
@ -202,34 +160,31 @@ export default class ExpressionView extends PureComponent {
|
|||||||
* @param {Array}
|
* @param {Array}
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
getContextKeys(keys: any) {
|
getContextKeys(keys: []) {
|
||||||
// let context = {};
|
const editor = this.props.field.editor;
|
||||||
// const { appHelper } = this.context;
|
console.log(editor);
|
||||||
// const activeKey = appHelper && appHelper.activeKey;
|
const limitKeys = ['schema', 'utils', 'constants'];
|
||||||
// if (!activeKey) return;
|
if (keys.length === 0) return limitKeys;
|
||||||
// const activeCtx = appHelper.schemaHelper.compCtxMap && appHelper.schemaHelper.compCtxMap[activeKey];
|
if (!limitKeys.includes(keys[0])) return [];
|
||||||
// if (!activeCtx) return null;
|
let result = [];
|
||||||
// let __self = activeCtx;
|
let keyValue = editor;
|
||||||
// if (keys && keys.length > 1) {
|
let assert = false;
|
||||||
// keys.shift(0);
|
keys.forEach(item => {
|
||||||
// let path = '/' + keys.join('/');
|
if (!keyValue[item] || typeof keyValue[item] !== 'object') {
|
||||||
// path = path.replace(/[\[\]]/g, '/');
|
assert = true;
|
||||||
// context = jsonuri.get(__self, path);
|
}
|
||||||
// if (context && typeof context === 'object') {
|
if (keyValue[item]) {
|
||||||
// return this.filterKey(context);
|
keyValue = keyValue[item];
|
||||||
// }
|
}
|
||||||
// } else if (keys && keys[0] === 'this') {
|
})
|
||||||
// return this.filterKey(__self);
|
if (assert) return [];
|
||||||
// }
|
result = Object.keys(keyValue);
|
||||||
// return null;
|
return result;
|
||||||
return [
|
// return utilsKeys.concat(constantsKeys).concat(schemaKeys);
|
||||||
"page",
|
|
||||||
"component"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*过滤key */
|
/*过滤key */
|
||||||
filterKey(obj: any) {
|
filterKey(obj: any, name: string) {
|
||||||
let filterKeys = [
|
let filterKeys = [
|
||||||
'reloadDataSource',
|
'reloadDataSource',
|
||||||
'REACT_HOT_LOADER_RENDERED_GENERATION',
|
'REACT_HOT_LOADER_RENDERED_GENERATION',
|
||||||
@ -244,7 +199,7 @@ export default class ExpressionView extends PureComponent {
|
|||||||
let result = [];
|
let result = [];
|
||||||
for (let key in obj) {
|
for (let key in obj) {
|
||||||
if (key.indexOf('_') !== 0 && filterKeys.indexOf(key) === -1) {
|
if (key.indexOf('_') !== 0 && filterKeys.indexOf(key) === -1) {
|
||||||
result.push(key);
|
result.push(`${name}.${key}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -259,12 +214,16 @@ export default class ExpressionView extends PureComponent {
|
|||||||
filterOption(inputValue: string, item: { value: string | any[]; }) {
|
filterOption(inputValue: string, item: { value: string | any[]; }) {
|
||||||
const cursorIndex = this.getInputCursorPosition();
|
const cursorIndex = this.getInputCursorPosition();
|
||||||
let preStr = inputValue.substr(0, cursorIndex);
|
let preStr = inputValue.substr(0, cursorIndex);
|
||||||
let lastKey = preStr.split('.').slice(-1);
|
let lastKey: string[] = preStr.split('.').slice(-1);
|
||||||
if (!lastKey) return true;
|
if (!lastKey) return true;
|
||||||
if (item.value.indexOf(lastKey) > -1) return true;
|
if (item.value.indexOf(lastKey) > -1) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleClick = () => {
|
||||||
|
// this.props.field.editor.emit('variableBindDialog.open');
|
||||||
|
// }
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { value, dataSource } = this.state;
|
const { value, dataSource } = this.state;
|
||||||
const { placeholder } = this.props;
|
const { placeholder } = this.props;
|
||||||
@ -293,26 +252,30 @@ export default class ExpressionView extends PureComponent {
|
|||||||
isValObject ? (
|
isValObject ? (
|
||||||
value
|
value
|
||||||
) : (
|
) : (
|
||||||
<AutoComplete
|
<div>
|
||||||
{...this.props}
|
<AutoComplete
|
||||||
style={{ width: '100%' }}
|
{...this.props}
|
||||||
dataSource={dataSource}
|
style={{ width: '100%' }}
|
||||||
placeholder={placeholder || this.i18n('jsExpression')}
|
dataSource={dataSource}
|
||||||
value={value}
|
placeholder={placeholder || this.i18n('jsExpression')}
|
||||||
disabled={isValObject}
|
value={value}
|
||||||
innerBefore={<span style={{ color: '#999', marginLeft: 4 }}>{'{{'}</span>}
|
disabled={isValObject}
|
||||||
innerAfter={<span style={{ color: '#999', marginRight: 4 }}>{'}}'}</span>}
|
innerBefore={<span style={{ color: '#999', marginLeft: 4 }}>{'{{'}</span>}
|
||||||
itemRender={({ value }) => {
|
innerAfter={<span style={{ color: '#999', marginRight: 4 }}>{'}}'}</span>}
|
||||||
return (
|
popupClassName="expression-setter-item-inner"
|
||||||
<Option key={value} text={value} value={value}>
|
itemRender={({ value }) => {
|
||||||
<div className="code-input-value">{value}</div>
|
console.log(value);
|
||||||
<div className="code-input-help">{helpMap[value]}</div>
|
return (
|
||||||
</Option>
|
<Option key={value} text={value} value={value}>
|
||||||
);
|
<div className="code-input-value">{value}</div>
|
||||||
}}
|
<div className="code-input-help">{helpMap[value]}</div>
|
||||||
onChange={this.onChange.bind(this)}
|
</Option>
|
||||||
filter={this.filterOption.bind(this)}
|
);
|
||||||
/>
|
}}
|
||||||
|
onChange={this.onChange.bind(this)}
|
||||||
|
filter={this.filterOption.bind(this)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -363,7 +326,7 @@ export default class ExpressionView extends PureComponent {
|
|||||||
* 字符串取得对象keys
|
* 字符串取得对象keys
|
||||||
*/
|
*/
|
||||||
getObjectKeys(str: string) {
|
getObjectKeys(str: string) {
|
||||||
let keys = [];
|
let keys: string | any[] = [];
|
||||||
if (str) keys = str.split('.');
|
if (str) keys = str.split('.');
|
||||||
return keys.slice(0, keys.length - 1);
|
return keys.slice(0, keys.length - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
4
packages/rax-provider/CHANGELOG.md
Normal file
4
packages/rax-provider/CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
1
packages/rax-provider/README.md
Normal file
1
packages/rax-provider/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# 低代码引擎运行时框架
|
||||||
11
packages/rax-provider/build.json
Normal file
11
packages/rax-provider/build.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"build-plugin-rax-component",
|
||||||
|
{
|
||||||
|
"type": "rax",
|
||||||
|
"targets": ["web"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
30
packages/rax-provider/package.json
Normal file
30
packages/rax-provider/package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "@ali/lowcode-rax-provider",
|
||||||
|
"version": "0.8.14-beta.0",
|
||||||
|
"description": "Rax Provider for Runtime",
|
||||||
|
"files": [
|
||||||
|
"es",
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"module": "es/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "build-scripts start",
|
||||||
|
"build": "build-scripts build"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ali/lowcode-runtime": "^0.8.14-beta.0",
|
||||||
|
"rax": "1.1.2",
|
||||||
|
"driver-universal": "^3.1.3",
|
||||||
|
"rax-use-router": "^3.0.0",
|
||||||
|
"history": "^4.10.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@alib/build-scripts": "^0.1.18",
|
||||||
|
"build-plugin-rax-component": "^0.2.0"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://registry.npm.alibaba-inc.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
packages/rax-provider/src/index.js
Normal file
5
packages/rax-provider/src/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import RaxProvider from './provider';
|
||||||
|
import getRouter from './router';
|
||||||
|
|
||||||
|
export { getRouter };
|
||||||
|
export default RaxProvider;
|
||||||
28
packages/rax-provider/src/lazy-component.js
Normal file
28
packages/rax-provider/src/lazy-component.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { createElement, useState, useEffect } from 'rax';
|
||||||
|
import { app } from '@ali/lowcode-runtime';
|
||||||
|
|
||||||
|
export default function LazyComponent(props) {
|
||||||
|
const [schema, setSchema] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const { getPageData } = props || {};
|
||||||
|
if (getPageData && !schema) {
|
||||||
|
const data = await getPageData();
|
||||||
|
setSchema(data);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
|
||||||
|
const { getPageData, ...restProps } = props || {};
|
||||||
|
const Renderer = app.getRenderer();
|
||||||
|
const Loading = app.getLoading();
|
||||||
|
if (!Renderer || !schema) {
|
||||||
|
if (!Loading) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// loading扩展点
|
||||||
|
return createElement(Loading);
|
||||||
|
}
|
||||||
|
return createElement(Renderer, { schema, loading: Loading ? createElement(Loading) : null, ...restProps });
|
||||||
|
}
|
||||||
103
packages/rax-provider/src/provider.js
Normal file
103
packages/rax-provider/src/provider.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { createElement, render } from 'rax';
|
||||||
|
import UniversalDriver from 'driver-universal';
|
||||||
|
import { app, Provider } from '@ali/lowcode-runtime';
|
||||||
|
import LazyComponent from './lazy-component';
|
||||||
|
import getRouter from './router';
|
||||||
|
|
||||||
|
export default class RaxProvider extends Provider {
|
||||||
|
// 定制构造根组件的逻辑,如切换路由机制
|
||||||
|
createApp() {
|
||||||
|
const RouterView = this.getRouterView();
|
||||||
|
let App;
|
||||||
|
const layoutConfig = this.getLayoutConfig();
|
||||||
|
if (!layoutConfig || !layoutConfig.componentName) {
|
||||||
|
App = (props) => (RouterView ? createElement(RouterView, { ...props }) : null);
|
||||||
|
return App;
|
||||||
|
}
|
||||||
|
const { componentName: layoutName, props: layoutProps } = layoutConfig;
|
||||||
|
const { content: Layout, props: extraLayoutProps } = app.getLayout(layoutName) || {};
|
||||||
|
const sectionalRender = this.isSectionalRender();
|
||||||
|
if (!sectionalRender && Layout) {
|
||||||
|
App = (props) =>
|
||||||
|
createElement(
|
||||||
|
Layout,
|
||||||
|
{ ...layoutProps, ...extraLayoutProps },
|
||||||
|
RouterView ? createElement(RouterView, props) : null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
App = (props) => (RouterView ? createElement(RouterView, props) : null);
|
||||||
|
}
|
||||||
|
return App;
|
||||||
|
}
|
||||||
|
|
||||||
|
runApp(App, config) {
|
||||||
|
render(createElement(App), document.getElementById(config?.containerId || 'App'), { driver: UniversalDriver });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内置实现 for 动态化渲染
|
||||||
|
getRouterView() {
|
||||||
|
const routerConfig = this.getRouterConfig();
|
||||||
|
if (!routerConfig) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const routes = [];
|
||||||
|
let homePageId = this.getHomePage();
|
||||||
|
Object.keys(routerConfig).forEach((pageId, idx) => {
|
||||||
|
if (!pageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const path = routerConfig[pageId];
|
||||||
|
routes.push({
|
||||||
|
path,
|
||||||
|
component: (props: any) =>
|
||||||
|
this.getLazyComponent(pageId, {
|
||||||
|
components: this.getComponents(),
|
||||||
|
utils: this.getUtils(),
|
||||||
|
componentsMap: this.getComponentsMapObj(),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (homePageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (idx === 0 || path === '/') {
|
||||||
|
homePageId = pageId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (homePageId) {
|
||||||
|
routes.push({
|
||||||
|
path: '**',
|
||||||
|
component: (props) =>
|
||||||
|
this.getLazyComponent(homePageId, {
|
||||||
|
components: this.getComponents(),
|
||||||
|
utils: this.getUtils(),
|
||||||
|
componentsMap: this.getComponentsMapObj(),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const Router = getRouter({
|
||||||
|
history: this.getHistory(),
|
||||||
|
routes,
|
||||||
|
});
|
||||||
|
const RouterView = (props) => createElement(Router, props);
|
||||||
|
return RouterView;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLazyComponent(pageId, props) {
|
||||||
|
if (!pageId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.getlazyElement(pageId)) {
|
||||||
|
return this.getlazyElement(pageId);
|
||||||
|
}
|
||||||
|
const lazyElement = createElement(LazyComponent, {
|
||||||
|
// eslint-disable-next-line no-return-await
|
||||||
|
getPageData: async () => await this.getPageData(pageId),
|
||||||
|
key: pageId,
|
||||||
|
...props,
|
||||||
|
});
|
||||||
|
this.setlazyElement(pageId, lazyElement);
|
||||||
|
return lazyElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/rax-provider/src/router.js
Normal file
26
packages/rax-provider/src/router.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { useRouter } from 'rax-use-router';
|
||||||
|
import { createHashHistory, createBrowserHistory } from 'history';
|
||||||
|
|
||||||
|
const getConfig = (config) => {
|
||||||
|
let { history } = config;
|
||||||
|
const { routes } = config;
|
||||||
|
if (typeof history === 'string') {
|
||||||
|
if (history === 'hash') {
|
||||||
|
history = createHashHistory();
|
||||||
|
} else if (history === 'browser') {
|
||||||
|
history = createBrowserHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return () => ({
|
||||||
|
history,
|
||||||
|
routes,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function getRouter(config) {
|
||||||
|
return function Router() {
|
||||||
|
const configWrapper = getConfig(config);
|
||||||
|
const { component } = useRouter(configWrapper);
|
||||||
|
return component;
|
||||||
|
};
|
||||||
|
}
|
||||||
4
packages/react-provider/CHANGELOG.md
Normal file
4
packages/react-provider/CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
1
packages/react-provider/README.md
Normal file
1
packages/react-provider/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# 低代码引擎运行时框架
|
||||||
5
packages/react-provider/build.json
Normal file
5
packages/react-provider/build.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"build-plugin-component"
|
||||||
|
]
|
||||||
|
}
|
||||||
43
packages/react-provider/package.json
Normal file
43
packages/react-provider/package.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "@ali/lowcode-react-provider",
|
||||||
|
"version": "0.8.14",
|
||||||
|
"description": "React Provider for Runtime",
|
||||||
|
"files": [
|
||||||
|
"es",
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"module": "es/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "build-scripts build --skip-demo",
|
||||||
|
"test": "ava",
|
||||||
|
"test:snapshot": "ava --update-snapshots"
|
||||||
|
},
|
||||||
|
"ava": {
|
||||||
|
"compileEnhancements": false,
|
||||||
|
"snapshotDir": "test/fixtures/__snapshots__",
|
||||||
|
"extensions": [
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
|
"require": [
|
||||||
|
"ts-node/register"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ali/lowcode-runtime": "^0.8.13",
|
||||||
|
"react": "^16",
|
||||||
|
"react-dom": "^16",
|
||||||
|
"@recore/router": "^1.0.11"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@alib/build-scripts": "^0.1.18",
|
||||||
|
"build-plugin-component": "^0.2.16",
|
||||||
|
"@types/node": "^13.7.1",
|
||||||
|
"@types/react": "^16",
|
||||||
|
"@types/react-dom": "^16"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://registry.npm.alibaba-inc.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
packages/react-provider/src/index.ts
Normal file
5
packages/react-provider/src/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import ReactProvider from './provider';
|
||||||
|
import { Router } from '@recore/router';
|
||||||
|
|
||||||
|
export { Router };
|
||||||
|
export default ReactProvider;
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { Component, createElement } from 'react';
|
import { Component, createElement } from 'react';
|
||||||
import app from '../../index';
|
import { app } from '@ali/lowcode-runtime';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
getPageData: () => any;
|
getPageData: () => any;
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { createElement, ReactType, ReactElement } from 'react';
|
import { createElement, ReactType, ReactElement } from 'react';
|
||||||
import { Router } from '@ali/recore';
|
import ReactDOM from 'react-dom';
|
||||||
import app from '../../index';
|
import { Router } from '@recore/router';
|
||||||
import Provider from '..';
|
import { app, Provider } from '@ali/lowcode-runtime';
|
||||||
import LazyComponent from './lazy-component';
|
import LazyComponent from './lazy-component';
|
||||||
|
|
||||||
export default class ReactProvider extends Provider {
|
export default class ReactProvider extends Provider {
|
||||||
@ -30,6 +30,10 @@ export default class ReactProvider extends Provider {
|
|||||||
return App;
|
return App;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runApp(App: any, config: any) {
|
||||||
|
ReactDOM.render(<App />, document.getElementById(config?.containerId || 'App'));
|
||||||
|
}
|
||||||
|
|
||||||
// 内置实现 for 动态化渲染
|
// 内置实现 for 动态化渲染
|
||||||
getRouterView(): ReactType | null {
|
getRouterView(): ReactType | null {
|
||||||
const routerConfig = this.getRouterConfig();
|
const routerConfig = this.getRouterConfig();
|
||||||
9
packages/react-provider/tsconfig.json
Normal file
9
packages/react-provider/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "lib"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./src/"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,9 +1,5 @@
|
|||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"build-plugin-component",
|
"build-plugin-component"
|
||||||
"build-plugin-fusion",
|
|
||||||
["build-plugin-moment-locales", {
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}]
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
3
packages/runtime/index.d.ts
vendored
3
packages/runtime/index.d.ts
vendored
@ -1,8 +1,7 @@
|
|||||||
import { ReactType } from 'react';
|
|
||||||
type HistoryMode = 'browser' | 'hash';
|
type HistoryMode = 'browser' | 'hash';
|
||||||
|
|
||||||
interface ComponentsMap {
|
interface ComponentsMap {
|
||||||
[key: string]: ReactType;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UtilsMap {
|
interface UtilsMap {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ali/lowcode-runtime",
|
"name": "@ali/lowcode-runtime",
|
||||||
"version": "0.8.13",
|
"version": "0.8.14",
|
||||||
"description": "Runtime for Ali lowCode engine",
|
"description": "Runtime for Ali lowCode engine",
|
||||||
"files": [
|
"files": [
|
||||||
"es",
|
"es",
|
||||||
@ -26,14 +26,12 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ali/offline-events": "^1.0.0",
|
"@ali/offline-events": "^1.0.0",
|
||||||
"@ali/recore": "^1.6.9"
|
"history": "^4.10.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.18",
|
||||||
"@types/node": "^13.7.1",
|
"@types/node": "^13.7.1",
|
||||||
"@types/react": "^16",
|
"build-plugin-component": "^0.2.16"
|
||||||
"@types/react-dom": "^16",
|
|
||||||
"build-plugin-component": "^0.2.11"
|
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://registry.npm.alibaba-inc.com"
|
"registry": "https://registry.npm.alibaba-inc.com"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { ReactType } from 'react';
|
|
||||||
import Provider from './provider';
|
import Provider from './provider';
|
||||||
|
|
||||||
export interface ILayoutOptions {
|
export interface ILayoutOptions {
|
||||||
@ -7,16 +6,16 @@ export interface ILayoutOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class Container {
|
export default class Container {
|
||||||
private renderer: ReactType | null = null;
|
private renderer: any = null;
|
||||||
private layouts: { [key: string]: { content: ReactType; props: any } } = {};
|
private layouts: { [key: string]: { content: any; props: any } } = {};
|
||||||
private loading: ReactType | null = null;
|
private loading: any = null;
|
||||||
private provider: any;
|
private provider: any;
|
||||||
|
|
||||||
registerRenderer(renderer: ReactType): any {
|
registerRenderer(renderer: any): any {
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLayout(Layout: ReactType, options: ILayoutOptions): any {
|
registerLayout(Layout: any, options: ILayoutOptions): any {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -27,7 +26,7 @@ export default class Container {
|
|||||||
this.layouts[componentName] = { content: Layout, props };
|
this.layouts[componentName] = { content: Layout, props };
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLoading(component: ReactType) {
|
registerLoading(component: any) {
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -50,11 +49,11 @@ export default class Container {
|
|||||||
return this.layouts[componentName];
|
return this.layouts[componentName];
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderer(): ReactType | null {
|
getRenderer(): any {
|
||||||
return this.renderer;
|
return this.renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoading(): ReactType | null {
|
getLoading(): any {
|
||||||
return this.loading;
|
return this.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { ReactType } from 'react';
|
|
||||||
import Container, { ILayoutOptions } from './container';
|
import Container, { ILayoutOptions } from './container';
|
||||||
import { IProvider } from './provider';
|
import { IProvider } from './provider';
|
||||||
import run from './run';
|
import runApp from './runApp';
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
private container: Container;
|
private container: Container;
|
||||||
@ -11,18 +10,18 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
run();
|
runApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
registerRenderer(renderer: ReactType): any {
|
registerRenderer(renderer: any): any {
|
||||||
this.container.registerRenderer(renderer);
|
this.container.registerRenderer(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLayout(Layout: ReactType, options: ILayoutOptions): any {
|
registerLayout(Layout: any, options: ILayoutOptions): any {
|
||||||
this.container.registerLayout(Layout, options);
|
this.container.registerLayout(Layout, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLoading(component: ReactType) {
|
registerLoading(component: any) {
|
||||||
this.container.registerLoading(component);
|
this.container.registerLoading(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +33,11 @@ class App {
|
|||||||
return this.container.getLayout(componentName);
|
return this.container.getLayout(componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderer(): ReactType | null {
|
getRenderer(): any | null {
|
||||||
return this.container.getRenderer();
|
return this.container.getRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoading(): ReactType | null {
|
getLoading(): any | null {
|
||||||
return this.container.getLoading();
|
return this.container.getLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { IAppConfig, IUtils, IComponents, HistoryMode } from '../run';
|
import { IAppConfig, IUtils, IComponents, HistoryMode } from './runApp';
|
||||||
import EventEmitter from '@ali/offline-events';
|
import EventEmitter from '@ali/offline-events';
|
||||||
|
|
||||||
interface IConstants {
|
interface IConstants {
|
||||||
@ -110,6 +110,7 @@ export interface IProvider {
|
|||||||
getPageData(pageId: string): Promise<ComponentModel | undefined>;
|
getPageData(pageId: string): Promise<ComponentModel | undefined>;
|
||||||
getLazyComponent(pageId: string, props: any): any;
|
getLazyComponent(pageId: string, props: any): any;
|
||||||
createApp(): void;
|
createApp(): void;
|
||||||
|
runApp(App: any, config: IAppConfig): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Provider implements IProvider {
|
export default class Provider implements IProvider {
|
||||||
@ -197,6 +198,10 @@ export default class Provider implements IProvider {
|
|||||||
throw new Error('Method called "createApp" not implemented.');
|
throw new Error('Method called "createApp" not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runApp(App: any, config: IAppConfig) {
|
||||||
|
throw new Error('Method called "runApp" not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
registerComponents(components: IComponents | undefined) {
|
registerComponents(components: IComponents | undefined) {
|
||||||
if (!components) {
|
if (!components) {
|
||||||
return;
|
return;
|
||||||
@ -1,6 +1,4 @@
|
|||||||
import { ReactType } from 'react';
|
import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from 'history';
|
||||||
import { runApp } from '@ali/recore';
|
|
||||||
import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from '@recore/history';
|
|
||||||
import app from './index';
|
import app from './index';
|
||||||
|
|
||||||
export type HistoryOptions = {
|
export type HistoryOptions = {
|
||||||
@ -8,7 +6,7 @@ export type HistoryOptions = {
|
|||||||
} & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions);
|
} & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions);
|
||||||
|
|
||||||
export interface IComponents {
|
export interface IComponents {
|
||||||
[key: string]: ReactType;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUtils {
|
export interface IUtils {
|
||||||
@ -22,34 +20,35 @@ export interface IAppConfig {
|
|||||||
components?: IComponents;
|
components?: IComponents;
|
||||||
utils?: IUtils;
|
utils?: IUtils;
|
||||||
containerId?: string;
|
containerId?: string;
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRecoreAppConfig {
|
// export interface IRecoreAppConfig {
|
||||||
history?: HistoryMode;
|
// history?: HistoryMode;
|
||||||
globalComponents?: IComponents;
|
// globalComponents?: IComponents;
|
||||||
globalUtils?: IUtils;
|
// globalUtils?: IUtils;
|
||||||
containerId?: string;
|
// containerId?: string;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig {
|
// function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig {
|
||||||
if (!config) {
|
// if (!config) {
|
||||||
return {};
|
// return {};
|
||||||
}
|
// }
|
||||||
if (typeof config === 'function') {
|
// if (typeof config === 'function') {
|
||||||
config = config();
|
// config = config();
|
||||||
}
|
// }
|
||||||
return {
|
// return {
|
||||||
history: config.history,
|
// history: config.history,
|
||||||
globalComponents: config.components,
|
// globalComponents: config.components,
|
||||||
globalUtils: config.utils,
|
// globalUtils: config.utils,
|
||||||
containerId: config.containerId,
|
// containerId: config.containerId,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default function run() {
|
export default function runApp() {
|
||||||
const provider = app.getProvider();
|
const provider = app.getProvider();
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
throw new Error('');
|
throw new Error('Please register class Provider');
|
||||||
}
|
}
|
||||||
provider.onReady(() => {
|
provider.onReady(() => {
|
||||||
const promise = provider.async();
|
const promise = provider.async();
|
||||||
@ -58,8 +57,7 @@ export default function run() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const App = provider.createApp();
|
const App = provider.createApp();
|
||||||
config = transformConfig(config);
|
provider.runApp(App, config);
|
||||||
runApp(App, config);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
import { navigator, Router } from '@ali/recore';
|
|
||||||
import Provider from './core/provider';
|
import Provider from './core/provider';
|
||||||
import ReactProvider from './core/provider/react';
|
|
||||||
import app from './core';
|
import app from './core';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
|
|
||||||
export { app, Router, Provider, ReactProvider, navigator, Utils };
|
export { app, Provider, Utils };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user