mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 01:21:58 +00:00
add source-editor pannel
This commit is contained in:
parent
2cf8573b78
commit
d03844c706
@ -1,4 +1,6 @@
|
||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||
|
||||
|
||||
module.exports = ({ onGetWebpackConfig }) => {
|
||||
onGetWebpackConfig((config) => {
|
||||
@ -7,6 +9,16 @@ module.exports = ({ onGetWebpackConfig }) => {
|
||||
.use(TsconfigPathsPlugin, [{
|
||||
configFile: "./tsconfig.json"
|
||||
}]);
|
||||
|
||||
|
||||
config
|
||||
// 定义插件名称
|
||||
.plugin('MonacoWebpackPlugin')
|
||||
// 第一项为具体插件,第二项为插件参数
|
||||
.use(new MonacoWebpackPlugin({
|
||||
languages:["javascript","css","json"]
|
||||
}), []);
|
||||
|
||||
config.plugins.delete('hot');
|
||||
config.devServer.hot(false);
|
||||
});
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
"@ali/lowcode-plugin-event-bind-dialog": "^0.8.0",
|
||||
"@ali/lowcode-plugin-outline-pane": "^0.8.7",
|
||||
"@ali/lowcode-plugin-sample-logo": "^0.8.0",
|
||||
"@ali/lowcode-plugin-source-editor":"^0.8.2",
|
||||
"@ali/lowcode-plugin-sample-preview": "^0.8.6",
|
||||
"@ali/lowcode-plugin-settings-pane": "^0.8.8",
|
||||
"@ali/lowcode-plugin-undo-redo": "^0.8.0",
|
||||
@ -41,6 +42,7 @@
|
||||
"build-plugin-fusion": "^0.1.0",
|
||||
"build-plugin-moment-locales": "^0.1.0",
|
||||
"build-plugin-react-app": "^1.1.2",
|
||||
"monaco-editor-webpack-plugin":"^1.9.0",
|
||||
"tsconfig-paths-webpack-plugin": "^3.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,17 +83,18 @@ module.exports = {
|
||||
pluginProps: {
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
pluginKey: 'outlinePane',
|
||||
pluginKey: 'soueceEditor',
|
||||
type: 'PanelIcon',
|
||||
props: {
|
||||
align: 'top',
|
||||
icon: 'shuxingkongjian',
|
||||
title: '大纲树'
|
||||
title: '源码面板'
|
||||
},
|
||||
config: {
|
||||
package: '@ali/lowcode-plugin-outline-pane',
|
||||
version: '^0.8.0'
|
||||
package: '@ali/lowcode-plugin-source-editor',
|
||||
version: '^0.8.2'
|
||||
},
|
||||
pluginProps: {}
|
||||
},
|
||||
@ -137,6 +138,7 @@ module.exports = {
|
||||
version: '^0.8.0'
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
hooks: [],
|
||||
|
||||
@ -8,6 +8,7 @@ import zhEn from '@ali/lowcode-plugin-zh-en';
|
||||
import settingsPane from '@ali/lowcode-plugin-settings-pane';
|
||||
import designer from '@ali/lowcode-plugin-designer';
|
||||
import eventBindDialog from '@ali/lowcode-plugin-event-bind-dialog';
|
||||
import sourceEditor from '@ali/lowcode-plugin-source-editor'
|
||||
export default {
|
||||
LowcodeSkeleton,
|
||||
logo,
|
||||
@ -18,5 +19,6 @@ export default {
|
||||
zhEn,
|
||||
settingsPane,
|
||||
designer,
|
||||
eventBindDialog
|
||||
};
|
||||
eventBindDialog,
|
||||
sourceEditor
|
||||
};
|
||||
|
||||
@ -90,7 +90,30 @@ export default {
|
||||
"version": "^0.8.0"
|
||||
},
|
||||
"pluginProps": {}
|
||||
}, {
|
||||
},
|
||||
|
||||
{
|
||||
"pluginKey": "sourceEditor",
|
||||
"type": "PanelIcon",
|
||||
"props": {
|
||||
"align": "top",
|
||||
"icon": "zujianku",
|
||||
"title": "组件库",
|
||||
"panelProps":{
|
||||
"floatable": true,
|
||||
"defaultWidth":500
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
"config": {
|
||||
"package": "@ali/lowcode-plugin-source-editor",
|
||||
"version": "^0.8.0"
|
||||
},
|
||||
"pluginProps": {}
|
||||
},
|
||||
|
||||
{
|
||||
"pluginKey": "zhEn",
|
||||
"type": "Custom",
|
||||
"props": {
|
||||
@ -124,7 +147,8 @@ export default {
|
||||
"package": "@ali/lowcode-plugin-event-bind-dialog",
|
||||
"version": "^0.8.0"
|
||||
}
|
||||
}]
|
||||
},
|
||||
]
|
||||
},
|
||||
"hooks": [],
|
||||
"shortCuts": [],
|
||||
|
||||
20
packages/plugin-source-editor/CHANGELOG.md
Normal file
20
packages/plugin-source-editor/CHANGELOG.md
Normal file
@ -0,0 +1,20 @@
|
||||
# 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.8.2"></a>
|
||||
## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.1...@ali/lowcode-plugin-variable-bind-dialog@0.8.2) (2020-03-30)
|
||||
|
||||
|
||||
|
||||
|
||||
**Note:** Version bump only for package @ali/lowcode-plugin-source-editor
|
||||
|
||||
<a name="0.8.1"></a>
|
||||
## 0.8.1 (2020-03-30)
|
||||
|
||||
|
||||
|
||||
|
||||
**Note:** Version bump only for package @ali/lowcode-plugin-source-editor
|
||||
1
packages/plugin-source-editor/README.md
Normal file
1
packages/plugin-source-editor/README.md
Normal file
@ -0,0 +1 @@
|
||||
## todo
|
||||
9
packages/plugin-source-editor/build.json
Normal file
9
packages/plugin-source-editor/build.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"build-plugin-fusion",
|
||||
["build-plugin-moment-locales", {
|
||||
"locales": ["zh-cn"]
|
||||
}]
|
||||
]
|
||||
}
|
||||
41
packages/plugin-source-editor/package.json
Normal file
41
packages/plugin-source-editor/package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@ali/lowcode-plugin-source-editor",
|
||||
"version": "0.8.2",
|
||||
"description": "alibaba lowcode editor source-editor plugin",
|
||||
"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"
|
||||
},
|
||||
"keywords": [
|
||||
"lowcode",
|
||||
"editor"
|
||||
],
|
||||
"author": "zude.hzd",
|
||||
"dependencies": {
|
||||
"@ali/lowcode-editor-core": "^0.8.0",
|
||||
"@alifd/next": "^1.19.16",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1",
|
||||
"prettier":"^1.18.2",
|
||||
"js-beautify": "^1.10.1",
|
||||
"react-monaco-editor": "^0.36.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alib/build-scripts": "^0.1.3",
|
||||
"@types/react": "^16.9.13",
|
||||
"@types/react-dom": "^16.9.4",
|
||||
"build-plugin-component": "^0.2.7-1",
|
||||
"build-plugin-fusion": "^0.1.0",
|
||||
"build-plugin-moment-locales": "^0.1.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npm.alibaba-inc.com"
|
||||
}
|
||||
}
|
||||
23
packages/plugin-source-editor/src/index.scss
Normal file
23
packages/plugin-source-editor/src/index.scss
Normal file
@ -0,0 +1,23 @@
|
||||
.source-editor-container{
|
||||
height: 100%;
|
||||
|
||||
|
||||
.next-tabs {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.next-tabs-content{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.next-tabs-tabpane.active {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
246
packages/plugin-source-editor/src/index.tsx
Normal file
246
packages/plugin-source-editor/src/index.tsx
Normal file
@ -0,0 +1,246 @@
|
||||
import { Component, isValidElement, ReactElement, ReactNode } from 'react';
|
||||
import { Tab, Search, Input, Button } from '@alifd/next';
|
||||
import Editor from '@ali/lowcode-editor-core';
|
||||
import { js_beautify, css_beautify } from 'js-beautify';
|
||||
import MonacoEditor from 'react-monaco-editor';
|
||||
|
||||
// import lolizer from './sorceEditorPlugin',
|
||||
|
||||
import { Designer } from '@ali/lowcode-designer';
|
||||
const TAB_KEY = {
|
||||
JS_TAB: 'js_tab',
|
||||
CSS_TAB: 'css_tab',
|
||||
};
|
||||
|
||||
import './index.scss';
|
||||
import transfrom from './transform';
|
||||
|
||||
const defaultEditorOption = {
|
||||
width: '100%',
|
||||
height: '96%',
|
||||
options: {
|
||||
readOnly: false,
|
||||
automaticLayout: true,
|
||||
folding: true, //默认开启折叠代码功能
|
||||
lineNumbers: 'on',
|
||||
wordWrap: 'off',
|
||||
formatOnPaste: true,
|
||||
fontSize: 12,
|
||||
tabSize: 2,
|
||||
scrollBeyondLastLine: false,
|
||||
fixedOverflowWidgets: false,
|
||||
snippetSuggestions: 'top',
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
scrollbar: {
|
||||
vertical: 'auto',
|
||||
horizontal: 'auto',
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default class SourceEditor extends Component<{
|
||||
editor: Editor;
|
||||
}> {
|
||||
private monocoEditer:Object;
|
||||
private editorCmd:Object;
|
||||
|
||||
state = {
|
||||
isShow: false,
|
||||
tabKey: TAB_KEY.JS_TAB
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { editor } = this.props;
|
||||
editor.on('leftPanel.show', (key: String) => {
|
||||
if (key === 'sourceEditor' && !this.monocoEditer) {
|
||||
this.setState({
|
||||
isShow: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 添加函数
|
||||
editor.on('sourceEditor.addFunction',(params:Object)=>{
|
||||
this.callEditorEvent('sourceEditor.addFunction',params);
|
||||
})
|
||||
|
||||
editor.once('designer.mount', (designer: Designer) => {
|
||||
// let schema = designer.project.getSchema();
|
||||
// mock data
|
||||
let schema = {
|
||||
componentTree: [
|
||||
{
|
||||
state: {
|
||||
// 初始state: 选填 对象类型/变量表达式
|
||||
btnText: 'submit', // 默认数据值: 选填 变量表达式
|
||||
},
|
||||
css: 'body {font-size: 12px;} .botton{widht:100px;color:#ff00ff}', //css样式描述: 选填
|
||||
lifeCycles: {
|
||||
//生命周期: 选填 对象类型
|
||||
didMount: {
|
||||
type: 'JSExpression',
|
||||
value: "function() {\n \t\tconsole.log('did mount');\n\t}",
|
||||
},
|
||||
willUnmount: {
|
||||
type: 'JSExpression',
|
||||
value: "function() {\n \t\tconsole.log('will umount');\n\t}",
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
//自定义方法对象: 选填 对象类型
|
||||
testFunc: {
|
||||
//自定义方法: 选填 函数类型
|
||||
type: 'JSExpression',
|
||||
value: "function() {\n \t\tconsole.log('testFunc');\n \t}",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
this.initCode(schema);
|
||||
});
|
||||
|
||||
|
||||
setTimeout (()=>{
|
||||
editor.emit('sourceEditor.addFunction',{
|
||||
functionName:'testgaga'
|
||||
})
|
||||
},3000)
|
||||
|
||||
}
|
||||
|
||||
callEditorEvent = (eventName,params) => {
|
||||
if (!this.monocoEditer){
|
||||
this.editorCmd = {
|
||||
eventName,
|
||||
params
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventName === 'sourceEditor.addFunction'){
|
||||
this.addFunction(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
initCode = (schema) => {
|
||||
let jsCode = js_beautify(transfrom.schema2Code(schema),{ indent_size: 2, indent_empty_lines: true });
|
||||
let css;
|
||||
|
||||
if (schema.componentTree[0].css) {
|
||||
css = css_beautify(schema.componentTree[0].css,{ indent_size: 2 });
|
||||
}
|
||||
|
||||
this.setState({
|
||||
jsCode,
|
||||
css,
|
||||
selectTab: TAB_KEY.JS_TAB,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
addFunction (params){
|
||||
const count = this.monocoEditer.getModel().getLineCount() || 0;
|
||||
const range = new monaco.Range(count, 1, count, 1);
|
||||
const functionCode = transfrom.getNewFunctionCode(params.functionName);
|
||||
this.monocoEditer.executeEdits('log-source', [{ identifier: 'event_id', range:range , text: functionCode, forceMoveMarkers:true }]);
|
||||
|
||||
this.updateCode(this.monocoEditer.getModel().getValue())
|
||||
}
|
||||
|
||||
editorDidMount = (editor, monaco) => {
|
||||
console.log('editorDidMount', editor);
|
||||
this.monocoEditer = editor;
|
||||
|
||||
if (this.editorCmd){
|
||||
this.callEditorEvent(this.editorCmd.eventName,this.editorCmd.params);
|
||||
}
|
||||
|
||||
// var commandId = editor.addCommand(
|
||||
// 0,
|
||||
// function() {
|
||||
// // services available in `ctx`
|
||||
// alert('my command is executing!');
|
||||
// },
|
||||
// '',
|
||||
// );
|
||||
|
||||
// monaco.languages.registerCodeLensProvider('javascript', {
|
||||
// provideCodeLenses: function(model, token) {
|
||||
// return {
|
||||
// lenses: [
|
||||
// {
|
||||
// range: {
|
||||
// startLineNumber: 1,
|
||||
// startColumn: 1,
|
||||
// endLineNumber: 1,
|
||||
// endColumn: 1,
|
||||
// },
|
||||
// id: 'First Line',
|
||||
// command: {
|
||||
// id: commandId,
|
||||
// title: 'First Line',
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
// },
|
||||
// resolveCodeLens: function(model, codeLens, token) {
|
||||
// return codeLens;
|
||||
// },
|
||||
// });
|
||||
};
|
||||
|
||||
onTabChange = (key) => {
|
||||
this.setState({
|
||||
selectTab: key,
|
||||
});
|
||||
};
|
||||
|
||||
updateCode = (newCode) => {
|
||||
const { selectTab } = this.state;
|
||||
if (selectTab === TAB_KEY.JS_TAB) {
|
||||
this.setState({
|
||||
jsCode: newCode,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
css: newCode,
|
||||
});
|
||||
}
|
||||
|
||||
transfrom.code2Schema(newCode);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isShow, selectTab, jsCode, css } = this.state;
|
||||
const tabs = [
|
||||
{ tab: 'index.js', key: TAB_KEY.JS_TAB },
|
||||
{ tab: 'style.css', key: TAB_KEY.CSS_TAB },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="source-editor-container">
|
||||
<Tab size="small" shape="wrapped" onChange={this.onTabChange}>
|
||||
{tabs.map((item) => (
|
||||
<Tab.Item key={item.key} title={item.tab}>
|
||||
{isShow && (
|
||||
<MonacoEditor
|
||||
value={selectTab == TAB_KEY.JS_TAB ? jsCode : css}
|
||||
{...defaultEditorOption}
|
||||
{...{ language: selectTab == TAB_KEY.JS_TAB ? 'javascript' : 'css' }}
|
||||
onChange={(newCode) => this.updateCode(newCode)}
|
||||
editorDidMount={this.editorDidMount}
|
||||
/>
|
||||
)}
|
||||
</Tab.Item>
|
||||
))}
|
||||
</Tab>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
98
packages/plugin-source-editor/src/transform.ts
Normal file
98
packages/plugin-source-editor/src/transform.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import walkSourcePlugin from './sorceEditorPlugin';
|
||||
|
||||
const transfrom = {
|
||||
schema2Code(schema: Object) {
|
||||
let componentSchema = schema.componentTree[0];
|
||||
let code =
|
||||
`export default class {
|
||||
${initStateCode(componentSchema)}
|
||||
${initLifeCycleCode(componentSchema)}
|
||||
${initMethodsCode(componentSchema)}
|
||||
}`;
|
||||
console.log(code);
|
||||
return code;
|
||||
},
|
||||
|
||||
code2Schema(code: String) {
|
||||
|
||||
let newCode = code.replace(/export default class/,'class A');
|
||||
|
||||
let A,a;
|
||||
try {
|
||||
A = eval('('+newCode + ')');
|
||||
a = new A();
|
||||
}catch(e){
|
||||
return ''
|
||||
}
|
||||
|
||||
|
||||
let functionNameList = Object.getOwnPropertyNames(a.__proto__);
|
||||
|
||||
let functionMap = {};
|
||||
|
||||
functionNameList.map((functionName)=>{
|
||||
if (functionName != 'constructor'){
|
||||
let functionCode = a[functionName].toString().replace(new RegExp(functionName),'function');
|
||||
functionMap[functionName] = functionCode;
|
||||
}
|
||||
})
|
||||
|
||||
console.log(JSON.stringify(a.state));
|
||||
|
||||
console.log(functionMap);
|
||||
|
||||
},
|
||||
|
||||
getNewFunctionCode(functionName:String){
|
||||
return `\n\t${functionName}(){\n\t}\n`
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function initStateCode(componentSchema:Object) {
|
||||
if (componentSchema.state){
|
||||
return `state = ${JSON.stringify(componentSchema.state)}`
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function initLifeCycleCode(componentSchema: Object) {
|
||||
if (componentSchema.lifeCycles) {
|
||||
let lifeCycles = componentSchema.lifeCycles;
|
||||
let codeList = [];
|
||||
|
||||
for (let key in lifeCycles) {
|
||||
codeList.push(createFunctionCode(key, lifeCycles[key]));
|
||||
}
|
||||
|
||||
return codeList.join('');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function initMethodsCode(componentSchema: Object) {
|
||||
if (componentSchema.methods) {
|
||||
let methods = componentSchema.methods;
|
||||
let codeList = [];
|
||||
|
||||
for (let key in methods) {
|
||||
codeList.push(createFunctionCode(key, methods[key]));
|
||||
}
|
||||
|
||||
return codeList.join('');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function createFunctionCode(functionName: String, functionNode: Object) {
|
||||
if (functionNode.type === 'JSExpression') {
|
||||
let functionCode = functionNode.value;
|
||||
functionCode = functionCode.replace(/function/, functionName);
|
||||
return functionCode;
|
||||
}
|
||||
}
|
||||
|
||||
export default transfrom;
|
||||
9
packages/plugin-source-editor/tsconfig.json
Normal file
9
packages/plugin-source-editor/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": [
|
||||
"./src/"
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user