complete router redirect

This commit is contained in:
kangwei 2020-08-13 15:05:23 +08:00
parent dc8542a8fa
commit 006aa31b18
11 changed files with 675 additions and 484 deletions

7
index.ts Normal file
View File

@ -0,0 +1,7 @@
import renderer from './packages/react-simulator-renderer/src/renderer';
if (typeof window !== 'undefined') {
(window as any).SimulatorRenderer = renderer;
}
export default renderer;

View File

@ -6,13 +6,13 @@
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title>LowCodeEngine Editor DEMO</title> <title>LowCodeEngine Editor DEMO</title>
<link rel="shortcut icon" href="./favicon.png" /> <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/16.13.1/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/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js"></script> <script src="https://g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js"></script>
<script> <script>
React.PropTypes = PropTypes; React.PropTypes = PropTypes;
</script> </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/platform/c/??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> <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> <script src="https://unpkg.alibaba-inc.com/@alifd/next@1.18.17/dist/next.min.js"></script>

View File

@ -1,3 +1,5 @@
{
"componentsTree": [
{ {
"componentName": "Page", "componentName": "Page",
"id": "node_dockcviv8fo1", "id": "node_dockcviv8fo1",
@ -8,10 +10,9 @@
"padding": "0 5px 0 5px" "padding": "0 5px 0 5px"
} }
}, },
"fileName":"test", "fileName": "a",
"dataSource": { "dataSource": {
"list":[ "list": []
]
}, },
"state": { "state": {
"text": "outter", "text": "outter",
@ -73,8 +74,7 @@
"id": "node_dockcy8n9xeg", "id": "node_dockcy8n9xeg",
"props": { "props": {
"prefix": "next-", "prefix": "next-",
"children":[ "children": ["首页"]
"首页"]
} }
}, },
{ {
@ -82,8 +82,7 @@
"id": "node_dockcy8n9xei", "id": "node_dockcy8n9xei",
"props": { "props": {
"prefix": "next-", "prefix": "next-",
"children":[ "children": ["品质中台"]
"品质中台"]
} }
}, },
{ {
@ -91,8 +90,7 @@
"id": "node_dockcy8n9xek", "id": "node_dockcy8n9xek",
"props": { "props": {
"prefix": "next-", "prefix": "next-",
"children":[ "children": ["商家品质页面管理"]
"商家品质页面管理"]
} }
}, },
{ {
@ -100,11 +98,12 @@
"id": "node_dockcy8n9xem", "id": "node_dockcy8n9xem",
"props": { "props": {
"prefix": "next-", "prefix": "next-",
"children":[ "children": ["质检知识条配置"]
"质检知识条配置"]
} }
}] }
}] ]
}
]
}, },
{ {
"componentName": "Box", "componentName": "Box",
@ -126,8 +125,7 @@
"marginRight": "12px", "marginRight": "12px",
"marginLeft": "12px" "marginLeft": "12px"
}, },
"__events":[ "__events": []
]
}, },
"children": [ "children": [
{ {
@ -151,7 +149,8 @@
"width": "150px" "width": "150px"
} }
} }
}] }
]
}, },
{ {
"componentName": "Form.Item", "componentName": "Form.Item",
@ -174,7 +173,8 @@
"width": "200px" "width": "200px"
} }
} }
}] }
]
}, },
{ {
"componentName": "Form.Item", "componentName": "Form.Item",
@ -197,13 +197,13 @@
"width": "200px" "width": "200px"
} }
} }
}] }
]
}, },
{ {
"componentName": "Button.Group", "componentName": "Button.Group",
"id": "node_dockcy8n9xew", "id": "node_dockcy8n9xew",
"props":{ "props": {},
},
"children": [ "children": [
{ {
"componentName": "Button", "componentName": "Button",
@ -222,7 +222,8 @@
"type": "success" "type": "success"
} }
}, },
"搜索"] "搜索"
]
} }
}, },
{ {
@ -234,12 +235,14 @@
"margin": "0 5px 0 5px" "margin": "0 5px 0 5px"
}, },
"htmlType": "reset", "htmlType": "reset",
"children":[ "children": ["清空"]
"清空"]
} }
}] }
}] ]
}] }
]
}
]
}, },
{ {
"componentName": "Box", "componentName": "Box",
@ -283,13 +286,15 @@
"type": "componentEvent", "type": "componentEvent",
"name": "onClick", "name": "onClick",
"relatedEventName": "onClick" "relatedEventName": "onClick"
}], }
],
"onClick": { "onClick": {
"type": "JSFunction", "type": "JSFunction",
"value": "function(){ this.onClick() }" "value": "function(){ this.onClick() }"
} }
} }
}] }
]
}, },
{ {
"componentName": "Box", "componentName": "Box",
@ -324,7 +329,8 @@
"title": "其他类目->新品预览项目Id知识库", "title": "其他类目->新品预览项目Id知识库",
"url": "其他", "url": "其他",
"operation": "编辑" "operation": "编辑"
}], }
],
"size": "medium", "size": "medium",
"prefix": "next-", "prefix": "next-",
"hasBorder": true, "hasBorder": true,
@ -403,8 +409,10 @@
"title": "操作", "title": "操作",
"dataIndex": "operation" "dataIndex": "operation"
} }
}] }
}] ]
}
]
}, },
{ {
"componentName": "Box", "componentName": "Box",
@ -435,8 +443,10 @@
"justifyContent": "flex-end" "justifyContent": "flex-end"
} }
} }
}] }
}] ]
}
]
}, },
{ {
"componentName": "Dialog", "componentName": "Dialog",
@ -444,9 +454,7 @@
"props": { "props": {
"prefix": "next-", "prefix": "next-",
"footerAlign": "right", "footerAlign": "right",
"footerActions":[ "footerActions": ["ok", "cancel"],
"ok",
"cancel"],
"closeable": "esc,close", "closeable": "esc,close",
"hasMask": true, "hasMask": true,
"align": "cc cc", "align": "cc cc",
@ -458,8 +466,77 @@
"title": "标题", "title": "标题",
"events":[ "events": []
}
}
]
},
{
"componentName": "Page",
"props": {
"ref": "outterView",
"autoLoading": true,
"style": {
"padding": "0 5px 0 5px"
}
},
"fileName": "b",
"dataSource": {
"list": []
},
"state": {
"text": "outter",
"isShowDialog": false
},
"css": "body {font-size: 12px;} .botton{width:100px;color:#ff00ff}",
"lifeCycles": {
"componentDidMount": {
"type": "JSFunction",
"value": "function() {\n console.log('did mount');\n }"
},
"componentWillUnmount": {
"type": "JSFunction",
"value": "function() {\n console.log('will umount');\n }"
}
},
"methods": {
"testFunc": {
"type": "JSFunction",
"value": "function() {\n console.log('test func');\n }"
},
"onClick": {
"type": "JSFunction",
"value": "function(){\n this.setState({\n isShowDialog:true\n })\n\t}"
}
},
"children": [
{
"componentName": "Button",
"id": "node_dockcy8n9xe13",
"props": {
"prefix": "next-",
"type": "primary",
"size": "medium",
"htmlType": "button",
"component": "button",
"style": {
"width": "100px"
},
"children": ["新建配置"],
"__events": [
{
"type": "componentEvent",
"name": "onClick",
"relatedEventName": "onClick"
}
],
"onClick": {
"type": "JSFunction",
"value": "function(){ this.utils.router.push('/a') }"
}
}
}
] ]
} }
}] ]
} }

View File

@ -58,6 +58,7 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
@computed get current() { @computed get current() {
const host = this.props.host; const host = this.props.host;
const doc = host.currentDocument; const doc = host.currentDocument;
console.info(doc);
if (!doc) { if (!doc) {
return null; return null;
} }

View File

@ -376,6 +376,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
return; return;
} }
const nodeInst = this.getNodeInstanceFromElement(e.target as Element); const nodeInst = this.getNodeInstanceFromElement(e.target as Element);
console.info(nodeInst);
detecting.capture(nodeInst?.node || null); detecting.capture(nodeInst?.node || null);
e.stopPropagation(); e.stopPropagation();
}; };

View File

@ -60,6 +60,7 @@ export class Project {
if (autoOpen === true) { if (autoOpen === true) {
// auto open first document or open a blank page // auto open first document or open a blank page
this.open(this.data.componentsTree[0]); this.open(this.data.componentsTree[0]);
// this.data.componentsTree.map((data) => this.createDocument(data))[0].open();
} else { } else {
// auto open should be string of fileName // auto open should be string of fileName
this.open(autoOpen); this.open(autoOpen);

View File

@ -53,7 +53,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
editor.set(Designer, designer); editor.set(Designer, designer);
editor.emit('designer.ready', designer); editor.emit('designer.ready', designer);
editor.onGot('schema', (schema) => { editor.onGot('schema', (schema) => {
designer.project.open(schema); designer.project.load(schema, true);
}); });
}; };

View File

@ -41,21 +41,32 @@ export default class SimulatorRendererView extends Component<{ rendererContainer
return ( return (
<Router history={rendererContainer.history}> <Router history={rendererContainer.history}>
<Layout rendererContainer={rendererContainer}> <Layout rendererContainer={rendererContainer}>
<Switch> <Routes rendererContainer={rendererContainer} />
{rendererContainer.documentInstances.map((instance) => (
<Route
path={instance.path}
key={instance.id}
render={(routeProps) => <Renderer documentInstance={instance} {...routeProps} />}
/>
))}
</Switch>
</Layout> </Layout>
</Router> </Router>
); );
} }
} }
@observer
export class Routes extends Component<{ rendererContainer: SimulatorRendererContainer }> {
render() {
const { rendererContainer } = this.props;
return (
<Switch>
{rendererContainer.documentInstances.map((instance) => {
return (
<Route
path={instance.path}
key={instance.id}
render={(routeProps) => <Renderer documentInstance={instance} {...routeProps} />}
/>
);
})}
</Switch>
);
}
}
function ucfirst(s: string) { function ucfirst(s: string) {
return s.charAt(0).toUpperCase() + s.substring(1); return s.charAt(0).toUpperCase() + s.substring(1);
} }

View File

@ -13,6 +13,7 @@ import { BuiltinSimulatorRenderer, NodeInstance, Component, DocumentModel, Node
import { createMemoryHistory, MemoryHistory } from 'history'; import { createMemoryHistory, MemoryHistory } from 'history';
import Slot from './builtin-components/slot'; import Slot from './builtin-components/slot';
import Leaf from './builtin-components/leaf'; import Leaf from './builtin-components/leaf';
import { withQueryParams, parseQuery } from './utils/url';
export class DocumentInstance { export class DocumentInstance {
private instancesMap = new Map<string, ReactInstance[]>(); private instancesMap = new Map<string, ReactInstance[]>();
@ -154,7 +155,8 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
this._device = host.device; this._device = host.device;
}); });
const documentInstanceMap = new Map<string, DocumentInstance>(); const documentInstanceMap = new Map<string, DocumentInstance>();
host.autorun(() => { let initialEntry = '/';
host.autorun(({ firstRun }) => {
this._documentInstances = host.project.documents.map((doc) => { this._documentInstances = host.project.documents.map((doc) => {
let inst = documentInstanceMap.get(doc.id); let inst = documentInstanceMap.get(doc.id);
if (!inst) { if (!inst) {
@ -163,16 +165,23 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
} }
return inst; return inst;
}); });
console.info('instances', this._documentInstances); const path = host.project.currentDocument
});
const initialEntry = host.project.currentDocument
? documentInstanceMap.get(host.project.currentDocument.id)!.path ? documentInstanceMap.get(host.project.currentDocument.id)!.path
: '/'; : '/';
this.history = createMemoryHistory({ if (firstRun) {
initialEntry = path;
} else {
if (this.history.location.pathname !== path) {
this.history.replace(path);
}
}
});
const history = createMemoryHistory({
initialEntries: [initialEntry], initialEntries: [initialEntry],
}); });
this.history.listen((location, action) => { this.history = history;
console.info(location); history.listen((location, action) => {
host.project.open(location.pathname.substr(1));
}); });
host.componentsConsumer.consume(async (componentsAsset) => { host.componentsConsumer.consume(async (componentsAsset) => {
if (componentsAsset) { if (componentsAsset) {
@ -180,17 +189,27 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
this.buildComponents(); this.buildComponents();
} }
}); });
host.injectionConsumer.consume((data) => {
// sync utils, i18n, contants,... config
this._appContext = { this._appContext = {
utils: { utils: {
router: { router: {
push() {}, push(path: string, params?: object) {
replace() {}, history.push(withQueryParams(path, params));
}, },
replace(path: string, params?: object) {
history.replace(withQueryParams(path, params));
},
},
legaoBuiltins: {
getUrlParams() {
const search = history.location.search;
return parseQuery(search);
}
}
}, },
constants: {}, constants: {},
}; };
host.injectionConsumer.consume((data) => {
// sync utils, i18n, contants,... config
}); });
} }

View File

@ -0,0 +1,74 @@
/**
* Parse queryString
* @param {String} str '?q=query&b=test'
* @return {Object}
*/
export function parseQuery(str: string): object {
const ret: any = {};
if (typeof str !== 'string') {
return ret;
}
const s = str.trim().replace(/^(\?|#|&)/, '');
if (!s) {
return ret;
}
s.split('&').forEach((param) => {
const parts = param.replace(/\+/g, ' ').split('=');
let key = parts.shift()!;
let val: any = parts.length > 0 ? parts.join('=') : undefined;
key = decodeURIComponent(key);
val = val === undefined ? null : decodeURIComponent(val);
if (ret[key] === undefined) {
ret[key] = val;
} else if (Array.isArray(ret[key])) {
ret[key].push(val);
} else {
ret[key] = [ret[key], val];
}
});
return ret;
}
/**
* Stringify object to query parammeters
* @param {Object} obj
* @return {String}
*/
export function stringifyQuery(obj: any): string {
const param: string[] = [];
Object.keys(obj).forEach((key) => {
let value = obj[key];
if (value && typeof value === 'object') {
value = JSON.stringify(value);
}
param.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
});
return param.join('&');
}
export function uriEncode(uri: string) {
return encodeURIComponent(uri);
}
export function uriDecode(uri: string) {
return decodeURIComponent(uri);
}
export function withQueryParams(url: string, params?: object) {
const queryStr = params ? stringifyQuery(params) : '';
if (queryStr === '') {
return url;
}
const urlSplit = url.split('#');
const hash = urlSplit[1] ? `#${urlSplit[1]}` : '';
const urlWithoutHash = urlSplit[0];
return `${urlWithoutHash}${~urlWithoutHash.indexOf('?') ? '&' : '?'}${queryStr}${hash}`;
}

View File

@ -4,6 +4,6 @@
"outDir": "lib" "outDir": "lib"
}, },
"include": [ "include": [
"./src/" "./src/", "../../index.ts"
] ]
} }