Commit c0c6b795 authored by 张晨辰's avatar 张晨辰

Merge branch 'dev' into feature/20190923-feature

parents 45b15e27 f3422756
/**
* Created by rockyl on 2019-09-19.
*/
export let API_HOST;
if (process.env.NODE_ENV === 'development') {
//API_HOST = 'http://10.10.95.74:7777';
//API_HOST = 'http://10.10.94.134:7777';
//API_HOST = 'http://localhost:3002';
API_HOST = window.__data.apiHost;
<<<<<<< HEAD
=======
//API_HOST = '';
>>>>>>> 4be75099e23b6946a0ba4a754861b69a32bad830
} else {
API_HOST = window.__data.apiHost;
}
if (API_HOST[API_HOST.length - 1] === '/') {
API_HOST = API_HOST.substr(0, API_HOST.length - 1);
}
export const SSO_VERIFY_PAGE_URL = '/sso/logout';
export const DOCK_POINT_OFFSET = 4;
//文件类型图标 t表示展示缩略图
export const fileTypeIcon = {
'': 'file-empty',
'.txt': 'file-text',
'.json': 'file-text',
'.zip': 'file-zip',
'.fnt': 'file-font',
'.jpg': 't',
'.jpeg': 't',
'.png': 't',
'.gif': 't',
'.svg': 't',
};
/**
* Created by rockyl on 2019-09-19.
*/
export let API_HOST;
if (process.env.NODE_ENV === 'development') {
//API_HOST = 'http://10.10.95.74:7777';
//API_HOST = 'http://10.10.94.134:7777';
//API_HOST = 'http://localhost:3002';
API_HOST = window.__data.apiHost;
//API_HOST = '';
} else {
API_HOST = window.__data.apiHost;
}
if (API_HOST[API_HOST.length - 1] === '/') {
API_HOST = API_HOST.substr(0, API_HOST.length - 1);
}
export const SSO_VERIFY_PAGE_URL = '/sso/logout';
export const DOCK_POINT_OFFSET = 4;
//文件类型图标 t表示展示缩略图
export const fileTypeIcon = {
'': 'file-empty',
'.txt': 'file-text',
'.json': 'file-text',
'.zip': 'file-zip',
'.fnt': 'file-font',
'.jpg': 't',
'.jpeg': 't',
'.png': 't',
'.gif': 't',
'.svg': 't',
};
......@@ -14,7 +14,7 @@
</noscript>
<script>
window.__data = {
token : "<%= process.env.NODE_ENV === 'development' ? 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MjQ1LCJuYW1lIjoi5byg5pmo6L6wIiwiYWNjb3VudCI6InpjYyIsImVtYWlsIjoiemNjQGR1aWJhLmNvbS5jbiIsIm1vYmlsZSI6IjE4NzU3MTU1NzUxIiwiZGluZ1VzZXJJZCI6IjAyMDcxMTUyNjgyNDI1MTc1MiIsIm1vZGVsQXV0aG9yaXplIjpmYWxzZSwibG9naW5UaW1lb3V0Ijo4NjMxMCwiZ210Q3JlYXRlIjoxNTM0NDEyMDA4MDAwLCJnbXRNb2RpZmllZCI6MTU3NDA0OTAwODAwMCwic3lzdGVtSWRTZXQiOlswLDEsMzQsMzYsMzcsMjMxLDIwMywxOSwyMSwyNDYsMjMsMjQ5LDI1LDI3LDMwXSwiaWF0IjoxNTc0ODU5OTA5fQ.OIOZDSSdJRPHeDI_YPY6lBFWvNoRZZ2O4uByG6rDOxk' : '$TOKEN$' %>",
token : "<%= process.env.NODE_ENV === 'development' ? 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MjA4NSwibmFtZSI6IuWKs-eQquWzsCIsImFjY291bnQiOiJsYW9xaWZlbmciLCJlbWFpbCI6Imxhb3FpZmVuZ0BkdWliYS5jb20uY24iLCJtb2JpbGUiOiIxMzQ1Njc3NDE1MyIsImRpbmdVc2VySWQiOiI1MDY5MDYyOTIxMjkxMDAxIiwibW9kZWxBdXRob3JpemUiOmZhbHNlLCJsb2dpblRpbWVvdXQiOjE0ODA5LCJnbXRDcmVhdGUiOjE1MzQ0MTIwMTUwMDAsImdtdE1vZGlmaWVkIjoxNTczODgyMDk2MDAwLCJzeXN0ZW1JZFNldCI6WzAsMSwzNCwyMjcsMzYsMzcsMjMxLDIwMywxOSwyMSwyNDYsMjMsMjUsMjQ5LDI3LDMwXSwiaWF0IjoxNTc1MzQwMzg2fQ.2JEYMRx6wbJsMIMh3quyM14OsoMz_iJRq4Az_xz-WTc' : '$TOKEN$' %>",
apiHost : "<%= process.env.NODE_ENV === 'development' ? 'http://beacon.duibadev.com.cn' : '$API_HOST$' %>"
}
</script>
......
......@@ -52,9 +52,9 @@ export async function saveOne(project) {
})
}
export async function pack(id) {
export async function pack(id, debug) {
return await fetchApi('/api/project/pack', {
params: {id},
params: {id, debug},
method: 'post',
errMessage: 'Failed to pack project',
})
......
......@@ -5,7 +5,8 @@
export let API_HOST;
if (process.env.NODE_ENV === 'development') {
//API_HOST = 'http://10.10.95.74:7777';
//API_HOST = 'http://10.10.94.134:7777';
//API_HOST = 'http://192.168.1.16:7777';
//API_HOST = 'http://10.10.92.33:7777';
//API_HOST = 'http://localhost:3002';
API_HOST = window.__data.apiHost;
//API_HOST = '';
......
......@@ -5,6 +5,7 @@
"Close": "Close",
"Still Close": "Still Close",
"Save": "Save",
"Save And Preview": "Save And Preview",
"Reset": "Reset",
"Copy": "Copy",
"Exit": "Exit",
......@@ -78,6 +79,7 @@
"Env constant": "Env constant",
"Custom module": "Custom module",
"Copy template to clipboard": "Copy template to clipboard",
"Copied process to clipboard": "Copied process to clipboard",
"Link to parent": "Link to parent",
"Input project name": "Input project name",
"Invalid project name": "Invalid project name",
......
......@@ -5,6 +5,7 @@
"Close": "关闭",
"Still Close": "仍然关闭",
"Save": "保存",
"Save And Preview": "保存并预览",
"Reset": "重置",
"Copy": "复制",
"Exit": "退出",
......@@ -78,6 +79,7 @@
"Env constant": "自定义常量",
"Custom module": "自定义模块",
"Copy template to clipboard": "复制模板到粘贴板",
"Copied process to clipboard": "复制过程到粘贴板",
"Link to parent": "连接到父节点",
"Input project name": "输入项目名",
"Invalid project name": "无效的项目名",
......
......@@ -73,9 +73,7 @@ export const behaviorStore = {
state.originBehaviors[0] = state.currentBehavior;
},
updateProcesses(state, {targetMetaID, replaceMetaID}) {
for (let process of state.data.processes) {
updateProcesses(process, targetMetaID, replaceMetaID);
}
updateProcesses(state.data.processes, targetMetaID, replaceMetaID);
},
deleteProcessMeta(state, {meta, process}) {
let container;
......
......@@ -598,8 +598,8 @@ export const projectStore = {
}*/
return failedList;
},
async packProject({state}) {
const result = await projectApi.pack(state.id);
async packProject({state}, debug) {
const result = await projectApi.pack(state.id, debug);
console.log(result);
return result;
}
......
......@@ -34,10 +34,13 @@ content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, u
<body>
<div id="$CONTAINER_ID$" style="line-height:0;font-size:0"></div>
<script src="http://10.10.94.134:4002/dist/index.js"></script>
<script src="${process.env.NODE_ENV === 'development' ? 'http://10.10.94.134:4002/dist/index.js' : 'http://yun.duiba.com.cn/editor/zeroing/libs/engine.a913456caee2ee40c20108a1c4571f61479e54a1.js'}"></script>
<script src="$PROCESSES_URL$"></script>
<script src="$SCRIPTS_URL$"></script>
<script src="$CUSTOMS_URL$"></script>
<script>
engine.launch('//yun.duiba.com.cn/aurora/$VERSION$-data.json');
</script>
</script>
</body>
</html>
`;
......@@ -9,6 +9,7 @@ $dock-pin-width: 9px;
.el-dialog__body {
flex: 1;
height: 0;
padding: 5px;
}
......@@ -320,8 +321,9 @@ $dock-pin-width: 9px;
}
.meta-editor-wrapper {
height: 40vh;
//height: 40vh;
display: flex;
height: 100%;
padding: 5px;
flex-direction: column;
......@@ -332,6 +334,15 @@ $dock-pin-width: 9px;
.script-editor {
flex: 1;
}
.vue-codemirror{
flex: 1;
height: 0;
}
.CodeMirror {
height: 100%;
}
}
.props-editor-dialog {
......
......@@ -14,7 +14,7 @@ export function messageError(e) {
})
}
export function playWaiting(promise, text) {
export function playWaiting(promise, text, closeLoading = true) {
const loading = Loading.service({
lock: true,
text: text || i18n.t('In processing'),
......@@ -24,7 +24,9 @@ export function playWaiting(promise, text) {
messageError(e);
throw e;
}).finally(() => {
if(closeLoading){
loading.close();
}
})
}
......@@ -69,13 +71,18 @@ export function getInputDefaultValue(property) {
return property ? property.hasOwnProperty('default') ? property.default + '' : 'unset' : 'unset';
}
export function updateProcesses(process, targetMetaID, replaceMetaID) {
export function updateProcesses(processes, targetMetaID, replaceMetaID) {
for (let process of processes) {
for (let key in process.sub) {
let subProcess = process.sub[key];
if (subProcess.meta === targetMetaID) {
subProcess.meta = replaceMetaID;
}
}
if(process.metas){
updateProcesses(process.metas, targetMetaID, replaceMetaID)
}
}
}
export function metaInUse(process, targetMetaID) {
......@@ -123,3 +130,15 @@ export function selectFile(callback, {accept, multiple} = {}) {
}
input.click();
}
export function openPreview(packResult){
setTimeout(() => {
let url;
if(location.host.startsWith('localhost')){
url = packResult.tplUrl;
}else{
url = '/preview?url=http:' + packResult.tplUrl;
}
window.open(url, 'blank');
}, 500);
}
......@@ -134,6 +134,11 @@ export default {
type: 'textArea',
value: ''
},
htmlText: {
title: 'HTML内容',
type: 'input',
value: ''
},
fillColor: {
title: '颜色',
type: 'colorPicker',
......@@ -150,10 +155,11 @@ export default {
},
size: {
title: '字体大小',
type: 'swSelect',
type: 'inputNumber',
/*type: 'swSelect',
props: {
optionType: 'fontSize'
},
},*/
value: 12
},
lineHeight: {
......@@ -273,5 +279,12 @@ export default {
type: 'inputNumber',
value: 20,
},
}
},
/*htmlView: {
groupName: 'HTML视图',
htmlElement: {
title: 'HTML内容',
type: 'input',
},
}*/
}
......@@ -25,9 +25,10 @@
import Playground from "./Editor/Playground";
import Assets from "./Editor/Assets";
import DetailsDialog from "./Editor/dialogs/DetailsDialog";
import {playWaiting} from "../utils";
import {openPreview, playWaiting} from "../utils";
import i18n from "../i18n";
import PackResultDialog from "./Editor/dialogs/PackResultDialog";
import events from "@/global-events.js"
export default {
name: 'Editor',
......@@ -50,7 +51,7 @@
},
watch: {
$route: {
handler: function(val, oldVal){
handler: function (val, oldVal) {
console.log('router changed');
this.loadProject();
},
......@@ -63,29 +64,34 @@
async mounted() {
document.addEventListener('keydown', this.onKeyPress);
await playWaiting(this.prepare(), this.$t('Preparing')).catch(e => {});
await playWaiting(this.prepare(), this.$t('Preparing')).catch(e => {
});
this.loadProject();
},
destroyed(){
destroyed() {
document.removeEventListener('keydown', this.onKeyPress)
},
created(){
events.$on('saveAndPreview',()=>{
this.clickMenu("preview");
});
},
methods: {
prepare(){
prepare() {
return Promise.all([
this.updateEnv(),
])
},
onKeyPress(e){
if(e.key === 's' && (e.ctrlKey||e.metaKey)){
onKeyPress(e) {
if (e.key === 's' && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.saveProject();
this.clickMenu("preview");
return false;
}
},
async loadProject(){
async loadProject() {
const {projectID} = this.$route.params;
if (await this.localVersionExist(projectID)) {
this.$confirm(this.$t('Unsaved version found locally'), this.$t('Alert'), {
......@@ -111,7 +117,7 @@
loadLocalVersion(projectID) {
this.ready = false;
this.loadFromLocal(projectID);
this.$nextTick(()=>{
this.$nextTick(() => {
this.ready = true;
});
},
......@@ -121,7 +127,7 @@
await playWaiting(this.loadFromRemote(projectID), this.$t('Preparing')).catch(e => {
this.$alert(this.$t('Project does not exist'), this.$t('Alert'), {
confirmButtonText: this.$t('Confirm'),
callback: action=>{
callback: action => {
this.$router.replace({name: 'home'});
}
});
......@@ -139,8 +145,8 @@
this.panesConfig[id] = configs[0].width / 100;
localStorage.panesConfig = JSON.stringify(this.panesConfig);
},
async saveProject() {
await playWaiting(this.saveToRemote(), this.$t('Saving'));
async saveProject(closeLoading) {
await playWaiting(this.saveToRemote(), this.$t('Saving'), closeLoading);
this.$message({
message: i18n.t('Save project successfully'), //因为message是异步出现,但是当路由回退的时候,this.i18n的实例已经置空,所以要用全局的i18n实例
type: 'success'
......@@ -157,6 +163,9 @@
case 'details':
this.$refs.dialogsDialog.show();
break;
case 'preview':
await this.pack(true);
break;
case 'pack':
await this.pack();
break;
......@@ -188,20 +197,24 @@
break;
}
},
async pack(){
async pack(debug = false) {
const loading = this.$loading({
lock: true,
text: this.$t('Packing'),
});
try{
await this.saveProject();
const packResult = await this.packProject();
try {
await this.saveProject(false);
const packResult = await this.packProject(debug);
this.$message({
message: this.$t('Pack project successfully'),
type: 'success',
duration: 1000,
duration: 500,
});
if (debug) {
openPreview(packResult);
} else {
this.$refs.packResultDialog.show(packResult);
}
/*this.$confirm(this.$t('Pack project successfully'), this.$t('Alert'), {
confirmButtonText: this.$t('Open in new tab'),
cancelButtonText: this.$t('Close'),
......@@ -213,7 +226,7 @@
}).catch(() => {
});*/
}catch (e) {
} catch (e) {
this.$message({
message: this.$t('Pack project failed'),
type: 'error',
......
......@@ -19,7 +19,7 @@
</div>
</el-form>
</el-scrollbar>
<behavior-editor-dialog :behaviors="behaviors" @change="v => handleBehaviorsChange(v)" ref="behaviorEditorDialog"></behavior-editor-dialog>
<behavior-editor-dialog :behaviors="behaviors" @change="isPreview => handleBehaviorsChange(isPreview)" ref="behaviorEditorDialog"></behavior-editor-dialog>
</div>
</template>
......@@ -27,6 +27,8 @@
import { mapGetters } from 'vuex';
import _ from 'lodash';
import BehaviorEditorDialog from '../dialogs/BehaviorEditorDialog';
import events from "@/global-events.js"
export default {
name: 'BehaviorTab',
......@@ -93,7 +95,7 @@ export default {
/**
* 行为发生变化,同步数据
*/
handleBehaviorsChange(v) {
handleBehaviorsChange(isPreview) {
if (this.currentEvent /* && v && v.length*/) {
let event = {};
let currentEvent = this.eventsObj[this.currentEvent];
......@@ -104,6 +106,10 @@ export default {
});
this.updateEventsObj();
}
if(isPreview){
events.$emit('saveAndPreview')
}
},
/**
* 删除行为
......
......@@ -42,6 +42,11 @@
return menu;
}
},
async mounted() {
//监听键盘事件
document.addEventListener('keydown', this.onKeyPress);
},
methods: {
clickMenu(menuItem) {
this.$emit('click-menu', menuItem);
......@@ -60,6 +65,25 @@
}).catch(() => {
});
},
onKeyPress(e) {
if (e.key === 'z' && (e.ctrlKey || e.metaKey) && (!e.shiftKey)) {
//快捷键ctrl+z执行撤销
e.preventDefault();
//是否可执行撤销
if(!(!this.project.operateStack.length || this.project.operateStack.length === this.project.stackIndex + 1)){
this.clickMenu("undo");
}
return false;
}else if (e.key === 'z' && (e.ctrlKey || e.metaKey) && (e.shiftKey)) {
//快捷键ctrl+shift+z执行重做
e.preventDefault();
//是否可以执行重做
if(!(this.project.stackIndex === 0)){
this.clickMenu("redo");
}
return false;
}
},
...mapMutations([
'modifyProject'
]),
......
......@@ -37,6 +37,8 @@
import EditPath from "./Board/EditPath";
import Process from "./Board/Process";
import MetaEditorDialog from "./MetaEditorDialog";
import events from "@/global-events.js"
export default {
name: "BehaviorEditor",
......@@ -118,7 +120,7 @@
});
}
},
onSaveMeta(meta) {
onSaveMeta(meta,isPreview) {
let oldMetaID = this.metaInEditing.id;
for (let key in meta) {
this.metaInEditing[key] = meta[key];
......@@ -131,6 +133,10 @@
});
}
this.$refs.board.updateProcessNode(meta.id);
//是否预览
if(isPreview){
events.$emit('behaviorSave',isPreview)
}
},
...mapMutations([
'updateProcesses',
......
<template>
<div class="board" @dragover="onDragOver" @drop="onDrop" v-resize="onResize">
<div class="board" @dragover="onDragOver" @drop="onDrop" @paste="onPaste" v-resize="onResize">
<div style="height: 1px;"></div>
<!--<el-scrollbar class="full-size">-->
<svg ref="board" class="svg-board full-size" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" @mousedown="onBoardMouseDown">
......@@ -14,8 +15,9 @@
@click="onClickProcessNode(process, key)"
@hover-pin="onPinHover"
@leave-pin="onPinLeave"
@down-pin="onPintDown"
@down-pin="onPinDown"
@delete="onProcessNodeDelete"
@copy="onProcessNodeCopy"
@edit-meta="onEditMeta"
@dblclick="editSubProcess(process)"
@meta-modified="onProcessMetaModified"
......@@ -25,7 +27,6 @@
</svg>
<!--</el-scrollbar>-->
<tool-tip ref="toolTip"/>
<inline-choose-dialog ref="inlineChooseDialog"/>
</div>
</template>
......@@ -39,13 +40,14 @@
import {DOCK_POINT_OFFSET} from "../../../config";
import events from "../../../global-events";
import generateUUID from "uuid/v4";
import InlineChooseDialog from "./InlineChooseDialog";
import copy from 'copy-to-clipboard'
import {clonePureObj} from "../../../utils";
const customs = ['custom', 'divider'];
export default {
name: "Board",
components: {InlineChooseDialog, ToolTip, LinkLine, ProcessNode,},
components: {ToolTip, LinkLine, ProcessNode,},
props: [],
data() {
return {
......@@ -115,28 +117,31 @@
const process = new Process(this.process, data, this.resolveProcess);
this.$set(this.subProcessMap, uuid, process);
},
showInlineChoose() {
return this.$confirm(this.$t('As inline'));
},
async addSubProcessData(processId, pos) {
let meta, isInline;
if (customs.includes(processId)) {
try {
const result = await this.$refs.inlineChooseDialog.show();
isInline = result.isInline;
await this.showInlineChoose();
isInline = true;
} catch (e) {
return;
}
meta = await this.addCustomProcessMeta({masterProcess: this.process, isInline, processId});
}else{
} else {
meta = this.process.resolveMeta(processId);
}
if(meta.isPrefab){
if (meta.isPrefab) {
try {
const result = await this.$refs.inlineChooseDialog.show();
isInline = result.isInline;
await this.showInlineChoose();
isInline = true;
} catch (e) {
return;
}
meta = await this.addProcessFromPrefab({masterProcess: this.process, isInline, meta})
}
......@@ -170,7 +175,7 @@
const data = await this.addSubProcessData(processId, {
x: e.offsetX - this.boardOffset.x - 9,
y: e.offsetY - this.boardOffset.y,
y: e.offsetY - this.boardOffset.y - 20,
});
if (!data) {
return;
......@@ -181,6 +186,30 @@
events.$emit('update-dock-pin-pos');
});
},
onPaste(e) {
let dataStr = e.clipboardData.getData("process-data");
if (dataStr) {
this.addProcessFromCopy(dataStr);
}
},
addProcessFromCopy(avatar){
if(typeof avatar === 'string'){
avatar = JSON.parse(avatar);
}
avatar.uuid = generateUUID();
avatar.design.x += 20;
avatar.design.y += 20;
avatar.output = {};
delete avatar.design['output'];
delete avatar.design['input'];
this.$set(this.process.meta.sub, avatar.uuid, avatar);
this.addSubProcess(avatar.uuid, avatar);
this.$nextTick(() => {
events.$emit('update-dock-pin-pos');
});
},
onResize() {
const {x, y} = this.$el.getBoundingClientRect();
this.drawState.boardOffset.x = x + this.boardOffset.x;
......@@ -228,7 +257,7 @@
onPinLeave(x, y, pin) {
this.$refs.toolTip.hide();
},
onPintDown(e, process, pin) {
onPinDown(e, process, pin) {
document.addEventListener("mousemove", this.onMouseMove);
document.addEventListener("mouseup", this.onMouseUp);
......@@ -286,6 +315,20 @@
});
}
},
onProcessNodeCopy(data, meta) {
if(meta.isInline){ //内联直接复制
let avatar = clonePureObj(data);
this.addProcessFromCopy(avatar);
}else{
copy(JSON.stringify(data), {format: 'process-data'});
this.$message({
message: this.$t('Copied process to clipboard'),
type: 'success',
duration: 700,
});
}
},
onEditMeta(data, meta) {
this.$emit('edit-meta', meta);
},
......
......@@ -5,6 +5,7 @@
<div class="top-bar" v-if="meta.id !== 'entry' && editable">
<el-link icon="el-icon-delete" :underline="false" @mousedown.stop.prevent @click.stop="onClickDelete"/>
<el-link icon="el-icon-edit" :underline="false" v-if="meta.type !== 'builtin' && !meta.isDivider" @mousedown.stop.prevent @click.stop="onClickEdit"/>
<el-link icon="el-icon-document-copy" :underline="false" @mousedown.stop.prevent @click.stop="onClickCopy"/>
</div>
<div class="header">
<i v-if="meta.isInline">i</i>
......@@ -231,6 +232,9 @@
onClickEdit() {
this.$emit('edit-meta', this.data, this.meta);
},
onClickCopy() {
this.$emit('copy', this.data, this.meta);
},
outputPointModify(action) {
let output = this.meta.output;
let count = output.length;
......
<template>
<el-dialog
:title="$t('Alert')"
:visible.sync="dialogVisible"
append-to-body
@close="onClose"
>
<el-checkbox v-model="asInline">{{$t('As inline')}}</el-checkbox>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="dialogVisible = false">{{$t('Cancel')}}</el-button>
<el-button size="mini" type="primary" @click="onConfirm">{{$t('Confirm')}}</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: "InlineChooseDialog",
data() {
return {
dialogVisible: false,
asInline: false,
}
},
methods: {
show() {
this.dialogVisible = true;
return new Promise((resolve, reject) => {
this.p = {resolve, reject};
});
},
onClose() {
if (this.p) {
this.p.reject();
this.p = null;
}
this.dialogVisible = false;
},
onConfirm() {
if (this.p) {
this.p.resolve({
isInline: this.asInline,
});
this.p = null;
}
this.dialogVisible = false;
},
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<el-dialog :title="$t('Meta Editor')" width="80%" :visible.sync="visible"
:close-on-click-modal="false"
:append-to-body="true">
:close-on-press-escape="false"
:show-close="false"
fullscreen
:append-to-body="true"
custom-class="behavior-editor-dialog"
>
<div class="meta-editor-wrapper">
<el-form ref="form" v-if="meta" :model="meta" :rules="rules" :show-message="false" class="info-editor" size="mini" label-position="right" label-width="70px" @submit.native.prevent>
<template>
......@@ -37,10 +42,17 @@
</template>
</el-form>
<div style="margin-top: 5px;">
<el-tag v-for="item in exposeVariables" size="mini">{{item}}</el-tag>
<el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{item}}</el-tag>
</div>
<el-input v-if="meta" class="script-editor" :readonly=" !editable" type="textarea" :placeholder="$t('Code')"
v-model="meta.script"></el-input>
<!--<el-input v-if="meta" class="script-editor" :readonly=" !editable" type="textarea" :placeholder="$t('Code')"
v-model="meta.script"></el-input>-->
<codemirror ref="codeEditor" v-if="meta"
v-model="meta.script"
:options="cmOptions"
@cursorActivity="onCodeChange"
>
</codemirror>
</div>
<div slot="footer" class="dialog-footer">
<div class="button-bar">
......@@ -52,7 +64,8 @@
</el-popover>
</el-button-group>
<el-button size="mini" plain @click="cancel">{{$t('Cancel')}}</el-button>
<el-button size="mini" plain @click="save">{{$t('Save')}}</el-button>
<el-button size="mini" plain @click="save(true)">{{$t('Save And Preview')}}</el-button>
<el-button size="mini" plain @click="save(false)">{{$t('Save')}}</el-button>
</div>
</div>
<props-editor-dialog ref="propsEditorDialog"/>
......@@ -62,14 +75,24 @@
<script>
import ElFormItem from "./inputs/form-item";
import PropsEditorDialog from "./PropsEditorDialog";
import {codemirror} from "vue-codemirror";
import copy from 'copy-to-clipboard'
import {clonePureObj} from "../../../utils";
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/monokai.css'
import 'codemirror/addon/edit/closebrackets.js'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/javascript-hint.js'
import events from "@/global-events.js"
const exposeVariables = ['args', 'props', 'target', 'global', 'vm', 'engine'];
export default {
name: "MetaEditorDialog",
components: {PropsEditorDialog, ElFormItem},
components: {PropsEditorDialog, ElFormItem, codemirror},
data() {
return {
visible: false,
......@@ -85,7 +108,20 @@
{ required: true, trigger: 'blur' }
],
},
cmOptions: {
tabSize: 2,
mode: 'text/javascript',
styleActiveLine: true,
theme: 'default',
lineNumbers: true,
line: true,
matchBrackets: true,
autoCloseBrackets: true,
}
}
},
mounted(){
},
computed: {
editable() {
......@@ -104,7 +140,7 @@
onClickEditProps() {
this.$refs.propsEditorDialog.edit(this.meta.props);
},
save() {
save(isPreview) {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.oldMetaID !== this.meta.id && this.$store.getters.metaIDExists(this.meta.id)) {
......@@ -112,8 +148,8 @@
.catch((e) => {
});
} else {
this.$emit('input', this.meta);
this.visible = false;
this.$emit('input',this.meta,isPreview);
this.visible=false;
}
} else {
return false;
......@@ -143,6 +179,10 @@
focusPasteBoard(){
this.$refs.pasteBoard.focus();
},
onCodeChange(codemirror){
//codemirror.showHint();
//console.log(code);
}
}
}
</script>
......
......@@ -19,7 +19,7 @@
<dynamic-selector style="flex: 1;" v-model="item.value"
:editable="editable"/>
<el-button class="delete-button" icon="el-icon-minus" size="mini" plain circle type="danger"
@click="addMapItem"/>
@click="deleteMapItem(index)"/>
</div>
</div>
<div class="bottom-bar">
......@@ -85,6 +85,9 @@
addMapItem() {
this.editValue.push({});
},
deleteMapItem(index) {
this.editValue.splice(index, 1);
},
save() {
let v = {type: 'map', value: {}};
for (let item of this.editValue) {
......
......@@ -4,7 +4,8 @@
:append-to-body="true" custom-class="behavior-editor-dialog">
<behavior-editor v-if="editorReady" ref="behaviorEditor" class="full-size"></behavior-editor>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="onSave">{{$t('Save')}}</el-button>
<el-button size="mini" type="primary" @click="onSave(false)">{{$t('Save')}}</el-button>
<el-button size="mini" type="primary" @click="onSave(true)">{{$t('Save And Preview')}}</el-button>
</div>
</el-dialog>
</template>
......@@ -12,6 +13,8 @@
<script>
import {mapState, mapMutations} from 'vuex'
import BehaviorEditor from "../behavior-editor/BehaviorEditor";
import events from "@/global-events.js"
export default {
name: "BehaviorEditorDialog",
......@@ -28,6 +31,11 @@
}),
},
created(){
events.$on('behaviorSave',(isPreview)=>{
this.onSave(isPreview)
});
},
methods: {
show(behaviors, event) {
this.behavior_startEdit({
......@@ -38,10 +46,9 @@
this.editorReady = false;
this.visible = true;
},
onSave() {
onSave(isPreview) {
this.behavior_save();
this.visible = false;
this.$emit('change');
this.$emit('change',isPreview);
},
beforeClose(done) {
this.$confirm(this.$t('Save this behavior before'), this.$t('Alert'), {
......
......@@ -18,6 +18,7 @@
<script>
import copy from 'copy-to-clipboard'
import {openPreview} from "../../../utils";
export default {
name: "PackResultDialog",
......@@ -40,9 +41,7 @@
openInNewTab() {
this.visible = false;
setTimeout(()=>{
window.open(this.packResult.tplUrl, 'blank');
}, 500);
openPreview(this.packResult);
},
copy() {
this.visible = false;
......
......@@ -10,7 +10,7 @@ module.exports = {
enableInSFC: true
}
},
devServer: {
/*devServer: {
host: '0.0.0.0',
port: '8080',
proxy: {
......@@ -21,7 +21,7 @@ module.exports = {
target: serverHost,
},
}
},
},*/
configureWebpack: {
}
......
......@@ -2365,6 +2365,11 @@ code-point-at@^1.0.0:
resolved "https://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.41.0:
version "5.49.2"
resolved "https://registry.npm.taobao.org/codemirror/download/codemirror-5.49.2.tgz#c84fdaf11b19803f828b0c67060c7bc6d154ccad"
integrity sha1-yE/a8RsZgD+CiwxnBgx7xtFUzK0=
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/collection-visit/download/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
......@@ -3117,6 +3122,11 @@ detect-node@^2.0.4:
resolved "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=
diff-match-patch@^1.0.0:
version "1.0.4"
resolved "https://registry.npm.taobao.org/diff-match-patch/download/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1"
integrity sha1-asS1UjdGN2HE2vDcYD64aRJHRLE=
diff@^4.0.1:
version "4.0.1"
resolved "https://registry.npm.taobao.org/diff/download/diff-4.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff"
......@@ -9430,6 +9440,14 @@ vue-cli-plugin-i18n@^0.6.0:
vue-i18n "^8.0.0"
vue-i18n-extract "^0.4.13"
vue-codemirror@^4.0.6:
version "4.0.6"
resolved "https://registry.npm.taobao.org/vue-codemirror/download/vue-codemirror-4.0.6.tgz#b786bb80d8d762a93aab8e46f79a81006f0437c4"
integrity sha1-t4a7gNjXYqk6q45G95qBAG8EN8Q=
dependencies:
codemirror "^5.41.0"
diff-match-patch "^1.0.0"
vue-draggable-resizable@^2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/vue-draggable-resizable/download/vue-draggable-resizable-2.0.1.tgz#fb98d0997b1cfa8e3ba90f723cf8b605012cd96d"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment