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

Merge branch 'dev' into feature/20190923-feature

parents 6cd8cf2b 8f3347d3
...@@ -9,4 +9,6 @@ ...@@ -9,4 +9,6 @@
4. 增加circle类型,属性同rect 4. 增加circle类型,属性同rect
5. 属性中增加alias为别名,用来呈现中文别名(`{alias: '文本', type: 'string', default: '你好'}`) 5. 属性中增加alias为别名,用来呈现中文别名(`{alias: '文本', type: 'string', default: '你好'}`)
6. 属性中枚举的类型,type改为enum,增加以enum为名字的字符串存放枚举项(`{alias: '类型', type: 'enum', enum: ['rotate', 'jump', 'breath'], default: 'rotate'}`) 6. 属性中枚举的类型,type改为enum,增加以enum为名字的字符串存放枚举项(`{alias: '类型', type: 'enum', enum: ['rotate', 'jump', 'breath'], default: 'rotate'}`)
7. 编辑区需要能设置尺寸,默认`750*1334`,增加缩放功能,缩放可由按钮或者滚轮控制 7. 编辑区需要能设置尺寸,默认`750*1334`,增加缩放功能,缩放可由按钮或者滚轮控制
\ No newline at end of file 8. 增加删除脚本功能
9. 增加删除行为功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function verification(callback) {
var container = document.createElement('div');
container.style.position = 'fixed';
container.style.zIndex = '99999';
document.body.append(container);
var input = document.createElement('input');
input.placeholder = 'password';
container.append(input);
var button = document.createElement('button');
button.innerText = 'OK';
container.append(button);
button.onclick = function () {
callback(input.value === 'password');
}
var aaa = document.createElement('div');
document.body.append(aaa);
}
verification(function(result){
console.log(result);
})
</script>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
...@@ -228,7 +228,7 @@ const data = { ...@@ -228,7 +228,7 @@ const data = {
alias: 'test', alias: 'test',
meta: 'test', meta: 'test',
props: { props: {
text: '$_linked_$',
}, },
output: { output: {
success: [], success: [],
......
module.exports = {
region: 'oss-cn-hangzhou',
id: 'LTAIqO2wblIxQvwc',
secret: '4brsaSRbRpjxw3oDIxJi6bNMcndIR6',
bucket: 'duiba',
output: '/editor/zeroing/v1'
};
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"upload": "cp dist/index.html ../duiba-aurora-node/src/public/index.html&&ali-oss-publish -c oss.config.js -e dist",
"build:upload": "npm run build&&npm run upload",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'" "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
}, },
"dependencies": { "dependencies": {
...@@ -27,6 +29,7 @@ ...@@ -27,6 +29,7 @@
"@kazupon/vue-i18n-loader": "^0.3.0", "@kazupon/vue-i18n-loader": "^0.3.0",
"@vue/cli-plugin-babel": "^3.11.0", "@vue/cli-plugin-babel": "^3.11.0",
"@vue/cli-service": "^3.11.0", "@vue/cli-service": "^3.11.0",
"ali-oss-publish": "^0.3.0",
"lodash": "^4.17.15", "lodash": "^4.17.15",
"node-sass": "^4.9.2", "node-sass": "^4.9.2",
"sass": "^1.22.9", "sass": "^1.22.9",
......
public/favicon.ico

4.19 KB | W: | H:

public/favicon.ico

4.19 KB | W: | H:

public/favicon.ico
public/favicon.ico
public/favicon.ico
public/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>zeroing-editor</title> <title>烽火台</title>
</head> </head>
<body> <body>
<noscript> <noscript>
<strong>We're sorry but zeroing-editor doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>We're sorry but zeroing-editor doesn't work properly without JavaScript enabled. Please enable it to
</noscript> continue.</strong>
<div id="app"></div> </noscript>
<!-- built files will be auto injected --> <script>
</body> window.__data = {
token : "<%= process.env.NODE_ENV === 'development' ? 'eyJhbGciOiJIUzI1NiJ9.5Yqz55Cq5bOw.wixVqBeqGS2FBY_VWF1cC_Vg5Zr0vYgRTfuncjGthYY' : '$TOKEN$' %>"
}
</script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html> </html>
<template> <template>
<div id="app" class="theme-light"> <div id="app" class="theme-light">
<router-view/> <div class="error-tips" v-if="ready && showErrorTips">
<div class="invalid-route" v-if="ready && invalidRoute"> <p>{{errorTipsStr}}</p>
<p>无效的页面 {{cd}}秒后跳转</p> <el-button @click="jump">direct link</el-button>
</div> </div>
<router-view v-else/>
</div> </div>
</template> </template>
<script> <script>
import i18n from "./i18n";
import {SSO_VERIFY_PAGE_URL} from "./config";
const errorTipsArr = [
'',
i18n.t('Access denied'),
i18n.t('Invalid router'),
];
export default { export default {
name: "App", name: "App",
...@@ -15,25 +24,38 @@ ...@@ -15,25 +24,38 @@
return { return {
cd: 5, cd: 5,
ready: false, ready: false,
errorType: 0,
errorTips: '',
} }
}, },
computed: { mounted() {
invalidRoute() { if (!window['zeroing_token']) {
return !this.$route.matched || this.$route.matched.length === 0; this.dealError(1);
} }
}, },
computed: {
showErrorTips() {
return !window['zeroing_token'] || !this.$route.matched || this.$route.matched.length === 0;
},
errorTipsStr() {
return this.errorTips + ' ' + this.$t('Jump after', {cd: this.cd});
},
},
watch: { watch: {
$route: { $route: {
handler: function(val, oldVal){ handler: function (val, oldVal) {
this.dealInvalidRoute(); this.dealError(2);
this.ready = true;
}, },
deep: true deep: true
} }
}, },
methods: { methods: {
dealInvalidRoute(){ dealError(type) {
if (this.invalidRoute) { this.errorType = type;
this.errorTips = errorTipsArr[type];
this.ready = true;
if (this.showErrorTips) {
this.cd = 5; this.cd = 5;
this.startCD(); this.startCD();
} }
...@@ -42,18 +64,28 @@ ...@@ -42,18 +64,28 @@
this.timer = setInterval(() => { this.timer = setInterval(() => {
if (this.cd <= 0) { if (this.cd <= 0) {
clearInterval(this.timer); clearInterval(this.timer);
this.$router.replace({name: 'home'}); this.jump();
return; return;
} }
this.cd--; this.cd--;
}, 1000) }, 1000)
} },
jump() {
switch (this.errorType) {
case 1:
location.href = SSO_VERIFY_PAGE_URL;
break;
case 2:
this.$router.replace({name: 'home'});
break;
}
},
}, },
} }
</script> </script>
<style> <style>
.invalid-route { .error-tips {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
......
...@@ -3,11 +3,8 @@ ...@@ -3,11 +3,8 @@
*/ */
import {API_HOST} from "../config"; import {API_HOST} from "../config";
import cookie from "cookie";
import {stringify} from "querystringify"; import {stringify} from "querystringify";
const user_cookie = cookie.parse(document.cookie).user_cookie;
class ApiError extends Error { class ApiError extends Error {
constructor(name, code, message) { constructor(name, code, message) {
super(); super();
...@@ -33,8 +30,9 @@ export async function fetchApi(uri, {params, method = 'get', contentType = 'json ...@@ -33,8 +30,9 @@ export async function fetchApi(uri, {params, method = 'get', contentType = 'json
const options = { const options = {
method, method,
headers: { headers: {
authorization: user_cookie, authorization: 'Bearer ' + window['zeroing_token'],
}, },
//credentials: 'include',
}; };
if (params) { if (params) {
if (method.toLowerCase() === 'post') { if (method.toLowerCase() === 'post') {
......
...@@ -2,13 +2,20 @@ ...@@ -2,13 +2,20 @@
* Created by rockyl on 2019-09-19. * Created by rockyl on 2019-09-19.
*/ */
export const API_HOST = 'http://beacon.duibadev.com.cn'; export let API_HOST;
//export const API_HOST = 'http://10.10.95.74:7777'; if(process.env.NODE_ENV === 'development'){
//export const API_HOST = 'http://localhost:3002'; //API_HOST = 'http://10.10.95.74:7777';
//API_HOST = 'http://localhost:3002';
API_HOST = 'http://beacon.duibadev.com.cn'
}else{
API_HOST = 'http://beacon.duibadev.com.cn'
}
export const UPLOAD_FILE_URL = API_HOST + '/api/uploadFile'; export const UPLOAD_FILE_URL = API_HOST + '/api/uploadFile';
export const PARSE_BUNDLE_URL = API_HOST + '/api/parsePSD'; export const PARSE_BUNDLE_URL = API_HOST + '/api/parsePSD';
export const SSO_VERIFY_PAGE_URL = '/sso/logout';
export const DOCK_POINT_OFFSET = 4; export const DOCK_POINT_OFFSET = 4;
//文件类型图标 t表示展示缩略图 //文件类型图标 t表示展示缩略图
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
"Edit": "Edit", "Edit": "Edit",
"ID": "ID", "ID": "ID",
"Name": "Name", "Name": "Name",
"Alias": "Alias",
"Output": "Output", "Output": "Output",
"Code": "Code", "Code": "Code",
"Desc": "Desc", "Desc": "Desc",
...@@ -41,6 +42,11 @@ ...@@ -41,6 +42,11 @@
"Custom": "Custom", "Custom": "Custom",
"Entry": "Entry", "Entry": "Entry",
"Packing": "Packing", "Packing": "Packing",
"Type": "Type",
"Group": "Group",
"Access denied": "Access denied",
"Invalid router": "Invalid router",
"Jump after": "Jump after {cd}s",
"Open in new tab": "Open in new tab", "Open in new tab": "Open in new tab",
"Pack project successfully": "Pack project successfully", "Pack project successfully": "Pack project successfully",
"Pack project failed": "Pack project failed", "Pack project failed": "Pack project failed",
...@@ -58,6 +64,7 @@ ...@@ -58,6 +64,7 @@
"Edit Behavior": "Edit Behavior", "Edit Behavior": "Edit Behavior",
"Trigger once": "Trigger once", "Trigger once": "Trigger once",
"Meta Editor": "Meta Editor", "Meta Editor": "Meta Editor",
"As inline": "As inline",
"Link to parent": "Link to parent", "Link to parent": "Link to parent",
"Input project name": "Input project name", "Input project name": "Input project name",
"Invalid project name": "Invalid project name", "Invalid project name": "Invalid project name",
...@@ -119,5 +126,10 @@ ...@@ -119,5 +126,10 @@
"Inspector": "Inspector", "Inspector": "Inspector",
"Playground": "Playground", "Playground": "Playground",
"Views": "Views" "Views": "Views"
},
"dataTypes": {
"static": "Static",
"arguments": "Arguments",
"data-center": "DataCenter"
} }
} }
\ No newline at end of file
...@@ -11,6 +11,8 @@ import './assets/style.css' ...@@ -11,6 +11,8 @@ import './assets/style.css'
import './plugins/element.js' import './plugins/element.js'
import './themes/light/index.scss' import './themes/light/index.scss'
import './token'
new Vue({ new Vue({
router, router,
store, store,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* 行为编辑 * 行为编辑
*/ */
import Vue from "vue";
import i18n from "../../i18n"; import i18n from "../../i18n";
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
import {metaInUse, updateProcesses} from "../../utils"; import {metaInUse, updateProcesses} from "../../utils";
...@@ -75,13 +76,21 @@ export const behaviorStore = { ...@@ -75,13 +76,21 @@ export const behaviorStore = {
updateProcesses(process, targetMetaID, replaceMetaID); updateProcesses(process, targetMetaID, replaceMetaID);
} }
}, },
deleteProcessMeta(state, metaID) { deleteProcessMeta(state, {meta, process}) {
for (let i = 0, li = state.data.processes.length; i < li; i++) { let container;
const process = state.data.processes[i]; if(meta.isInline){
container = process.meta.metas;
}else{
container = state.data.processes;
}
if(container){
for (let i = 0, li = container.length; i < li; i++) {
const process = container[i];
if (process.id === metaID) { if (process.id === meta.id) {
state.data.processes.splice(i, 1); container.splice(i, 1);
break; break;
}
} }
} }
}, },
...@@ -134,25 +143,32 @@ export const behaviorStore = { ...@@ -134,25 +143,32 @@ export const behaviorStore = {
} }
}, },
actions: { actions: {
addCustomProcessMeta({commit, state}) { addCustomProcessMeta({commit, state}, {process, isInline, processId}) {
let meta = { let meta = {
id: generateUUID(), id: generateUUID(),
name: i18n.t('Custom'),
script: '', script: '',
props: {}, props: {},
output: ['success', 'failed'], isInline,
};
commit('addProcessMeta', meta);
return meta;
},
addDividerProcessMeta({commit, state}) {
let meta = {
id: generateUUID(),
name: i18n.t('Divider'),
isDivider: true,
output: ['p0'],
}; };
commit('addProcessMeta', meta); switch (processId) {
case 'custom':
meta.name = i18n.t('Custom');
meta.output = ['success', 'failed'];
break;
case 'divider':
meta.name = i18n.t('Divider');
meta.output = ['p0'];
meta.isDivider = true;
break;
}
if (isInline) {
if (!process.meta.metas) {
Vue.set(process.meta, 'metas', []);
}
process.meta.metas.push(meta);
} else {
commit('addProcessMeta', meta);
}
return meta; return meta;
}, },
} }
......
...@@ -17,8 +17,11 @@ $dock-pin-width: 9px; ...@@ -17,8 +17,11 @@ $dock-pin-width: 9px;
} }
.process-tree { .process-tree {
display: flex;
flex-direction: column;
.scrollbar { .scrollbar {
height: 100%; flex: 1;
.process-tree-node { .process-tree-node {
flex: 1; flex: 1;
...@@ -72,8 +75,6 @@ $dock-pin-width: 9px; ...@@ -72,8 +75,6 @@ $dock-pin-width: 9px;
stroke: $--color-primary; stroke: $--color-primary;
stroke-dasharray: 5, 1; stroke-dasharray: 5, 1;
} }
} }
.node { .node {
...@@ -88,6 +89,11 @@ $dock-pin-width: 9px; ...@@ -88,6 +89,11 @@ $dock-pin-width: 9px;
user-select: none; user-select: none;
margin: 0 $dock-pin-width; margin: 0 $dock-pin-width;
&:hover {
& > .top-bar {
visibility: visible;
}
}
/*&:hover { /*&:hover {
border-color: $block-border-hover-background-color; border-color: $block-border-hover-background-color;
...@@ -104,6 +110,21 @@ $dock-pin-width: 9px; ...@@ -104,6 +110,21 @@ $dock-pin-width: 9px;
} }
}*/ }*/
.top-bar {
height: 19px;
padding: 0 3px;
margin: -20px 5px 0;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
background-color: rgba(0, 0, 0, 0.1);
align-self: flex-end;
visibility: hidden;
.el-link + .el-link {
margin-left: 5px;
}
}
.header { .header {
min-height: 12px; min-height: 12px;
background-color: $block-border-blur-background-color; background-color: $block-border-blur-background-color;
...@@ -114,17 +135,14 @@ $dock-pin-width: 9px; ...@@ -114,17 +135,14 @@ $dock-pin-width: 9px;
color: white; color: white;
display: flex; display: flex;
.title { i{
flex: 1; display: block;
//color: $--color-warning;
margin-right: 3px;
} }
.delete-button { .title {
padding: 2px; flex: 1;
color: $--border-color-lighter;
&:hover {
color: white;
}
} }
} }
...@@ -150,8 +168,18 @@ $dock-pin-width: 9px; ...@@ -150,8 +168,18 @@ $dock-pin-width: 9px;
} }
.linked-value {
display: flex;
align-items: center;
justify-content: flex-end;
}
.string-value { .string-value {
text-align: right; text-align: right;
.tag {
color: $--color-success;
}
} }
.color-value { .color-value {
...@@ -161,11 +189,6 @@ $dock-pin-width: 9px; ...@@ -161,11 +189,6 @@ $dock-pin-width: 9px;
float: right; float: right;
border: 1px solid $--border-color-base; border: 1px solid $--border-color-base;
} }
.linked-icon {
float: right;
color: $--color-success;
}
} }
} }
...@@ -221,6 +244,10 @@ $dock-pin-width: 9px; ...@@ -221,6 +244,10 @@ $dock-pin-width: 9px;
& > .header { & > .header {
background-color: $block-border-focus-background-color; background-color: $block-border-focus-background-color;
} }
/*& > .top-bar {
visibility: visible;
}*/
} }
} }
} }
...@@ -229,7 +256,7 @@ $dock-pin-width: 9px; ...@@ -229,7 +256,7 @@ $dock-pin-width: 9px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.linked{ .linked {
display: block; display: block;
height: 26px; height: 26px;
overflow: hidden; overflow: hidden;
...@@ -260,7 +287,7 @@ $dock-pin-width: 9px; ...@@ -260,7 +287,7 @@ $dock-pin-width: 9px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.name-input{ .name-input {
} }
...@@ -269,7 +296,7 @@ $dock-pin-width: 9px; ...@@ -269,7 +296,7 @@ $dock-pin-width: 9px;
padding-top: 5px; padding-top: 5px;
flex: 1; flex: 1;
.scrollbar-view{ .scrollbar-view {
padding-right: 10px; padding-right: 10px;
} }
...@@ -282,11 +309,11 @@ $dock-pin-width: 9px; ...@@ -282,11 +309,11 @@ $dock-pin-width: 9px;
} }
} }
.node-select-container{ .node-select-container {
flex: 1; flex: 1;
} }
.string-editor-container{ .string-input-container {
flex: 1; flex: 1;
height: 28px; height: 28px;
} }
...@@ -346,13 +373,13 @@ $dock-pin-width: 9px; ...@@ -346,13 +373,13 @@ $dock-pin-width: 9px;
} }
} }
.node-select-popover{ .node-select-popover {
.tree-scrollbar { .tree-scrollbar {
width: 100%; width: 100%;
height: 200px; height: 200px;
} }
.bottom-bar{ .bottom-bar {
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -360,3 +387,9 @@ $dock-pin-width: 9px; ...@@ -360,3 +387,9 @@ $dock-pin-width: 9px;
} }
} }
.linked-prop-popover {
div + div {
margin-top: 5px;
}
}
/**
* Created by rockyl on 2019-11-16.
*/
import cookie from "cookie";
let user_cookie;
user_cookie = cookie.parse(document.cookie).user_cookie;
if (!user_cookie) {
try {
user_cookie = window.__data.token;
} catch (e) {
}
}
if (!user_cookie) {
console.log('Access denied');
}
window['zeroing_token'] = user_cookie;
...@@ -20,8 +20,6 @@ export const RENDERER_TYPES= { ...@@ -20,8 +20,6 @@ export const RENDERER_TYPES= {
CANVAS: 'canvas', CANVAS: 'canvas',
}; };
export const linkedFlag = '$_linked_$';
export function messageError(e) { export function messageError(e) {
Message({ Message({
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
...@@ -81,7 +79,7 @@ export function saveAs(blob, fileName) { ...@@ -81,7 +79,7 @@ export function saveAs(blob, fileName) {
} }
} }
export function getEditorDefaultValue(property) { export function getInputDefaultValue(property) {
return property.hasOwnProperty('default') ? property.default + '' : 'unset'; return property.hasOwnProperty('default') ? property.default + '' : 'unset';
} }
......
...@@ -13,26 +13,26 @@ export default { ...@@ -13,26 +13,26 @@ export default {
type: 'inputNumber', type: 'inputNumber',
value: 0, value: 0,
}, },
// left: { left: {
// title: '左边距', title: '左边距',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// }, },
// right: { right: {
// title: '右边距', title: '右边距',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// }, },
// top: { top: {
// title: '上边距', title: '上边距',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// }, },
// bottom: { bottom: {
// title: '下边距', title: '下边距',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// }, },
width: { width: {
title: '宽度', title: '宽度',
type: 'inputNumber', type: 'inputNumber',
...@@ -43,18 +43,18 @@ export default { ...@@ -43,18 +43,18 @@ export default {
type: 'inputNumber', type: 'inputNumber',
value: 1 value: 1
}, },
// horizonCenter: { horizonCenter: {
// title: '水平偏移', title: '水平偏移',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// desc: '相对于父元素中心点的水平偏移,0为正中心' desc: '相对于父元素中心点的水平偏移,0为正中心'
// }, },
// verticalCenter: { verticalCenter: {
// title: '垂直偏移', title: '垂直偏移',
// type: 'inputNumber', type: 'inputNumber',
// value: undefined, value: undefined,
// desc: '相对于父元素中心点的垂直偏移,0为正中心' desc: '相对于父元素中心点的垂直偏移,0为正中心'
// }, },
rotation: { rotation: {
title: '旋转', title: '旋转',
type: 'inputNumber', type: 'inputNumber',
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<split-panes class="pane-container" @resized="onPanesReSized(0, $event)"> <split-panes class="pane-container" @resized="onPanesReSized(0, $event)">
<split-panes splitpanes-min="40" :splitpanes-size="getSize(0, 0)" horizontal @resized="onPanesReSized(1, $event)"> <split-panes splitpanes-min="40" :splitpanes-size="getSize(0, 0)" horizontal @resized="onPanesReSized(1, $event)">
<split-panes splitpanes-min="20" :splitpanes-size="getSize(1, 0)" @resized="onPanesReSized(2, $event)"> <split-panes splitpanes-min="20" :splitpanes-size="getSize(1, 0)" @resized="onPanesReSized(2, $event)">
<views splitpanes-min="30" :splitpanes-size="getSize(2, 0)"></views> <views splitpanes-min="20" :splitpanes-size="getSize(2, 0)"></views>
<playground splitpanes-min="20" :splitpanes-size="getSize(2, 1)"></playground> <playground splitpanes-min="20" :splitpanes-size="getSize(2, 1)"></playground>
</split-panes> </split-panes>
<assets splitpanes-min="20" :splitpanes-size="getSize(1, 1)"></assets> <assets splitpanes-min="20" :splitpanes-size="getSize(1, 1)"></assets>
...@@ -176,7 +176,9 @@ ...@@ -176,7 +176,9 @@
}).then(() => { }).then(() => {
}).catch(() => { }).catch(() => {
window.open(tplUrl, 'blank'); setTimeout(()=>{
window.open(tplUrl, 'blank');
}, 500);
}); });
}catch (e) { }catch (e) {
this.$message({ this.$message({
......
...@@ -54,7 +54,7 @@ export default { ...@@ -54,7 +54,7 @@ export default {
showBehaviorEditor(evn, key) { showBehaviorEditor(evn, key) {
this.currentEvent = key; this.currentEvent = key;
this.behaviors = evn.behaviors || []; this.behaviors = evn.behaviors || [];
this.$refs.behaviorEditorDialog.show(this.behaviors, key); this.$refs.behaviorEditorDialog.show(this.behaviors, this.activeComponent.name + '_' + key);
}, },
/** /**
* 当前选中组件发生变化时,更新eventsObj的数据 * 当前选中组件发生变化时,更新eventsObj的数据
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
class="menu-item import-file" class="menu-item import-file"
:action="importFileUrl" :action="importFileUrl"
name="file" name="file"
:headers="uploadHeaders"
:show-file-list="false" :show-file-list="false"
:on-success="uploadFileSuccess" :on-success="uploadFileSuccess"
:on-error="uploadFileError" :on-error="uploadFileError"
...@@ -66,7 +67,10 @@ export default { ...@@ -66,7 +67,10 @@ export default {
defaultProps: { defaultProps: {
children: 'children', children: 'children',
label: 'name' label: 'name'
} },
uploadHeaders: {
authorization: 'Bearer ' + window['zeroing_token'],
},
}; };
}, },
computed: { computed: {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</split-panes> </split-panes>
<div class="center full-size background" splitpanes-min="20" :splitpanes-size="70"> <div class="center full-size background" splitpanes-min="20" :splitpanes-size="70">
<edit-path :processStack="processStack" @pop="onPop"/> <edit-path :processStack="processStack" @pop="onPop"/>
<board ref="board" @select-process-node="onSelectProcessNode" @edit-process="editProcess"/> <board ref="board" @select-process-node="onSelectProcessNode" @edit-process="editProcess" @edit-meta="onEditMeta"/>
</div> </div>
<div class="properties background full-size" splitpanes-min="20" :splitpanes-size="20"> <div class="properties background full-size" splitpanes-min="20" :splitpanes-size="20">
<properties-editor ref="properties"/> <properties-editor ref="properties"/>
......
...@@ -13,12 +13,14 @@ ...@@ -13,12 +13,14 @@
@leave-pin="onPinLeave" @leave-pin="onPinLeave"
@down-pin="onPintDown" @down-pin="onPintDown"
@delete="onProcessNodeDelete" @delete="onProcessNodeDelete"
@edit-meta="onEditMeta"
@dblclick="editSubProcess(process)" @dblclick="editSubProcess(process)"
@meta-modified="onProcessMetaModified" @meta-modified="onProcessMetaModified"
/> />
</g> </g>
</svg> </svg>
<tool-tip ref="toolTip"/> <tool-tip ref="toolTip"/>
<inline-choose-dialog ref="inlineChooseDialog"/>
</div> </div>
</template> </template>
...@@ -31,10 +33,13 @@ ...@@ -31,10 +33,13 @@
import {DOCK_POINT_OFFSET} from "../../../config"; import {DOCK_POINT_OFFSET} from "../../../config";
import events from "../../../global-events"; import events from "../../../global-events";
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
//todo 缩放功能 import InlineChooseDialog from "./InlineChooseDialog";
const customs = ['custom', 'divider'];
//todo 缩放功能
export default { export default {
name: "Board", name: "Board",
components: {ToolTip, LinkLine, ProcessNode,}, components: {InlineChooseDialog, ToolTip, LinkLine, ProcessNode,},
props: [], props: [],
data() { data() {
return { return {
...@@ -46,7 +51,7 @@ ...@@ -46,7 +51,7 @@
visible: false, visible: false,
path: '', path: '',
process: null, process: null,
} },
} }
}, },
mounted() { mounted() {
...@@ -54,7 +59,8 @@ ...@@ -54,7 +59,8 @@
}, },
computed: { computed: {
...mapState({ ...mapState({
drawState: state=>state.behavior.drawState drawState: state => state.behavior.drawState,
editable: state => state.behavior.editable,
}) })
}, },
methods: { methods: {
...@@ -90,20 +96,21 @@ ...@@ -90,20 +96,21 @@
this.$set(this.subProcessMap, uuid, process); this.$set(this.subProcessMap, uuid, process);
}, },
async addSubProcessData(processId, pos) { async addSubProcessData(processId, pos) {
let process, processMeta; let process, processMeta, isInline;
switch(processId){ if (customs.includes(processId)) {
case 'custom': try {
processMeta = await this.addCustomProcessMeta(); const result = await this.$refs.inlineChooseDialog.show();
processId = processMeta.id; isInline = result.isInline;
break; } catch (e) {
case 'divider': return;
processMeta = await this.addDividerProcessMeta(); }
processId = processMeta.id;
break; processMeta = await this.addCustomProcessMeta({process: this.process, isInline, processId});
processId = processMeta.id;
} }
process = this.resolveProcess(processId); process = this.process.resolveMeta(processId);
let data = { let data = {
uuid: generateUUID(), uuid: generateUUID(),
...@@ -136,13 +143,16 @@ ...@@ -136,13 +143,16 @@
x: e.offsetX - 9, x: e.offsetX - 9,
y: e.offsetY, y: e.offsetY,
}); });
if(!data){
return;
}
this.addSubProcess(data.uuid, data); this.addSubProcess(data.uuid, data);
this.$nextTick(() => { this.$nextTick(() => {
events.$emit('update-dock-pin-pos'); events.$emit('update-dock-pin-pos');
}); });
}, },
onResize(){ onResize() {
const {x, y} = this.$el.getBoundingClientRect(); const {x, y} = this.$el.getBoundingClientRect();
this.drawState.boardOffset.x = x; this.drawState.boardOffset.x = x;
this.drawState.boardOffset.y = y; this.drawState.boardOffset.y = y;
...@@ -239,16 +249,22 @@ ...@@ -239,16 +249,22 @@
} }
} }
if(meta.isDivider){ //如果是分流器还要删除对应的meta if (meta.isDivider || meta.isInline) { //如果是分流节点或者内联节点还要删除对应的meta
this.deleteProcessMeta(meta.id); this.deleteProcessMeta({
meta,
process: this.process,
});
} }
}, },
onEditMeta(data, meta){
this.$emit('edit-meta', meta);
},
editSubProcess(process) { editSubProcess(process) {
if (!process.meta.isDivider && (process.meta.type !== 'builtin' || process.meta.sub && Object.keys(process.meta.sub).length > 0)) { if (!process.meta.isDivider && (this.editable || process.meta.sub && Object.keys(process.meta.sub).length > 0)) {
this.$emit('edit-process', process); this.$emit('edit-process', process);
} }
}, },
onProcessMetaModified(process, meta){ onProcessMetaModified(process, meta) {
let ids = Object.keys(this.lines); let ids = Object.keys(this.lines);
for (let id of ids) { for (let id of ids) {
const line = this.lines[id]; const line = this.lines[id];
...@@ -256,7 +272,7 @@ ...@@ -256,7 +272,7 @@
if (prev === process) { if (prev === process) {
const {outputType} = line; const {outputType} = line;
if(meta.output.indexOf(outputType) < 0){ if (meta.output.indexOf(outputType) < 0) {
this.onDeleteLine(line); this.onDeleteLine(line);
} }
} }
...@@ -279,7 +295,7 @@ ...@@ -279,7 +295,7 @@
} }
}, },
updateProcessNode(metaID) { updateProcessNode(metaID) {
this.$nextTick(()=>{ this.$nextTick(() => {
for (let key in this.$refs) { for (let key in this.$refs) {
if (key.startsWith('pn_')) { if (key.startsWith('pn_')) {
......
...@@ -15,7 +15,7 @@ export default class Process { ...@@ -15,7 +15,7 @@ export default class Process {
} }
resolveMeta(id) { resolveMeta(id) {
let meta = this.meta && this.meta.metas ? this.meta.metas[id] : null; let meta = this.meta && this.meta.metas ? this.meta.metas.find(meta=>meta.id === id) : null;
if (!meta && this._parent) { if (!meta && this._parent) {
meta = this._parent.resolveMeta(id); meta = this._parent.resolveMeta(id);
} }
......
<template> <template>
<foreignObject :x="data.design.x" :y="data.design.y" :width="width" :height="height"> <foreignObject :x="data.design.x" :y="data.design.y" :width="width" :height="height">
<div ref="node" :class="{active: active}" class="node" @mousedown="onMouseDown" @mouseenter="onMouseEnter" <div ref="node" :class="{active: active}" class="node" style="margin-top: 20px;" @mousedown="onMouseDown" @mouseenter="onMouseEnter"
@mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick"> @mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick">
<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'" @mousedown.stop.prevent @click.stop="onClickEdit"/>
</div>
<div class="header"> <div class="header">
<i v-if="meta.isInline">i</i>
<span class="title">{{data.alias || meta.name}}</span> <span class="title">{{data.alias || meta.name}}</span>
<i v-if="meta.id !== 'entry'" class="delete-button el-icon-delete" @click.stop="onClickDelete"
@mousedown.stop.prevent></i>
</div> </div>
<div class="body"> <div class="body">
<div v-if="meta.isDivider"> <div v-if="meta.isDivider">
...@@ -14,8 +17,17 @@ ...@@ -14,8 +17,17 @@
</div> </div>
<div v-else class="field-item" v-for="(param, key, index) in meta.props" :key="index"> <div v-else class="field-item" v-for="(param, key, index) in meta.props" :key="index">
<span class="key">{{param.alias || key}}</span>: <span class="key">{{param.alias || key}}</span>:
<span class="" v-if="data.props[key] === linkedFlag"> <span class="linked-value" v-if="typeof data.props[key] === 'object'">
<i class="el-icon-link linked-icon"></i> <span class="string-value">
<template v-if="data.props[key].type === 'link'">
{{data.props[key].alias || ''}}
<i class="el-icon-link tag"></i>
</template>
<template v-else>
{{data.props[key].value || ''}}
<i class="tag">{{data.props[key].type[0].toUpperCase()}}</i>
</template>
</span>
</span> </span>
<template v-else> <template v-else>
<div v-if="param.type === 'color'"> <div v-if="param.type === 'color'">
...@@ -30,9 +42,9 @@ ...@@ -30,9 +42,9 @@
</div> </div>
<div ref="outputDock" class="dock output"> <div ref="outputDock" class="dock output">
<dock-pin v-for="(pin, key, index) in meta.output" :key="index" :data="pin" <dock-pin v-for="(pin, key, index) in meta.output" :key="index" :data="pin"
@mouseenter="onPinHover" @mouseenter="onPinHover"
@mouseleave="onPinLeave" @mouseleave="onPinLeave"
@mousedown="onPinDown" @mousedown="onPinDown"
></dock-pin> ></dock-pin>
</div> </div>
</div> </div>
...@@ -43,7 +55,6 @@ ...@@ -43,7 +55,6 @@
import {mapState} from "vuex"; import {mapState} from "vuex";
import DockPin from "./DockPin"; import DockPin from "./DockPin";
import events from "../../../../global-events"; import events from "../../../../global-events";
import {linkedFlag} from "../../../../utils";
export default { export default {
name: "ProcessNode", name: "ProcessNode",
...@@ -57,7 +68,6 @@ ...@@ -57,7 +68,6 @@
height: 100, height: 100,
inputMeta, inputMeta,
active: false, active: false,
linkedFlag,
} }
}, },
mounted() { mounted() {
...@@ -76,7 +86,8 @@ ...@@ -76,7 +86,8 @@
return this.process.data; return this.process.data;
}, },
...mapState({ ...mapState({
drawState: state=>state.behavior.drawState drawState: state => state.behavior.drawState,
editable: state => state.behavior.editable,
}), }),
}, },
watch: { watch: {
...@@ -169,7 +180,7 @@ ...@@ -169,7 +180,7 @@
this.$nextTick(() => { this.$nextTick(() => {
let bounds = this.$refs.node.getBoundingClientRect(); let bounds = this.$refs.node.getBoundingClientRect();
this.width = bounds.width + 18; this.width = bounds.width + 18;
this.height = bounds.height; this.height = bounds.height + 20;
}); });
}, },
updateDockPointPos() { updateDockPointPos() {
...@@ -214,6 +225,9 @@ ...@@ -214,6 +225,9 @@
onClickDelete() { onClickDelete() {
this.$emit('delete', this.data, this.meta); this.$emit('delete', this.data, this.meta);
}, },
onClickEdit() {
this.$emit('edit-meta', this.data, this.meta);
},
outputPointModify(action) { outputPointModify(action) {
let output = this.meta.output; let output = this.meta.output;
let count = output.length; let count = output.length;
...@@ -234,7 +248,7 @@ ...@@ -234,7 +248,7 @@
} }
this.$emit('meta-modified', this.data, this.meta); this.$emit('meta-modified', this.data, this.meta);
this.$nextTick(()=>{ this.$nextTick(() => {
this.updateDockPointPos(); this.updateDockPointPos();
}); });
} }
......
<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
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<el-form-item prop="desc" label="Desc"> <el-form-item prop="desc" label="Desc">
<el-input v-model="meta.desc" :placeholder="$t('Description')" :readonly="!editable"/> <el-input v-model="meta.desc" :placeholder="$t('Description')" :readonly="!editable"/>
</el-form-item> </el-form-item>
<!--<el-form-item prop="type" label="Type">
<el-input v-model="meta.type" :placeholder="$t('Type')" :readonly="!editable"/>
</el-form-item>
<el-form-item prop="group" label="Group">
<el-input v-model="meta.group" :placeholder="$t('Group')" :readonly="!editable"/>
</el-form-item>-->
<el-form-item label="Props"> <el-form-item label="Props">
<el-link :underline="false" @click="onClickEditProps" :disabled="!editable"> <el-link :underline="false" @click="onClickEditProps" :disabled="!editable">
<template v-if="Object.keys(meta.props).length"> <template v-if="Object.keys(meta.props).length">
...@@ -35,7 +41,13 @@ ...@@ -35,7 +41,13 @@
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<div class="button-bar"> <div class="button-bar">
<el-button size="mini" plain @click="printMeta">PrintMeta</el-button> <el-button-group style="margin-right: 20px;">
<el-button size="mini" plain @click="copyMeta">CopyMeta</el-button>
<el-popover>
<div ref="pasteBoard" @paste="onPaste">Click and Ctrl+V</div>
<el-button size="mini" slot="reference" plain @click="pasteMeta">PasteMeta</el-button>
</el-popover>
</el-button-group>
<el-button size="mini" plain @click="cancel">Cancel</el-button> <el-button size="mini" plain @click="cancel">Cancel</el-button>
<el-button size="mini" plain @click="save">Save</el-button> <el-button size="mini" plain @click="save">Save</el-button>
</div> </div>
...@@ -45,8 +57,9 @@ ...@@ -45,8 +57,9 @@
</template> </template>
<script> <script>
import ElFormItem from "./editors/form-item"; import ElFormItem from "./inputs/form-item";
import PropsEditorDialog from "./PropsEditorDialog"; import PropsEditorDialog from "./PropsEditorDialog";
import copy from 'copy-to-clipboard'
export default { export default {
name: "MetaEditorDialog", name: "MetaEditorDialog",
...@@ -69,7 +82,7 @@ ...@@ -69,7 +82,7 @@
}, },
computed: { computed: {
editable() { editable() {
return this.meta && this.meta.type !== 'builtin'; return this.meta;// && this.meta.type !== 'builtin';
}, },
props() { props() {
return Object.keys(this.meta.props).join(',') return Object.keys(this.meta.props).join(',')
...@@ -103,8 +116,25 @@ ...@@ -103,8 +116,25 @@
cancel() { cancel() {
this.visible = false; this.visible = false;
}, },
printMeta() { copyMeta() {
console.log(JSON.stringify(this.meta)); copy(JSON.stringify(this.meta));
},
pasteMeta() {
//setTimeout(this.focusPasteBoard, 1000, this);
},
onPaste(e) {
let metaStr = e.clipboardData.getData("Text");
if(metaStr){
try {
let meta = JSON.parse(metaStr);
this.meta = meta;
}catch (e) {
}
}
},
focusPasteBoard(){
this.$refs.pasteBoard.focus();
}, },
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
view-class="scrollbar-view"> view-class="scrollbar-view">
<el-form v-model="process" size="mini" label-width="80px" label-position="left" @submit.native.prevent> <el-form v-model="process" size="mini" label-width="80px" label-position="left" @submit.native.prevent>
<component v-for="(property, key) in process.meta.props" <component v-for="(property, key) in process.meta.props"
:is="getEditor(property)" :is="getInput(property)"
v-model="process.data.props[key]" v-model="process.data.props[key]"
:propertyName="key" :propertyName="key"
:property="property" :property="property"
...@@ -22,27 +22,31 @@ ...@@ -22,27 +22,31 @@
<script> <script>
import {mapState} from "vuex"; import {mapState} from "vuex";
import NumberEditor from "./editors/NumberEditor"; import NumberInput from "./inputs/NumberInput";
import StringEditor from "./editors/StringEditor"; import StringInput from "./inputs/StringInput";
import EnumEditor from "./editors/EnumEditor"; import EnumInput from "./inputs/EnumInput";
import BooleanEditor from "./editors/BooleanEditor"; import BooleanInput from "./inputs/BooleanInput";
import ColorEditor from "./editors/ColorEditor"; import ColorInput from "./inputs/ColorInput";
import AssetEditor from "./editors/AssetEditor"; import AssetInput from "./inputs/AssetInput";
import NodeSelectEditor from "./editors/NodeSelectEditor"; import NodeSelectInput from "./inputs/NodeSelectInput";
import DataInput from "./inputs/DataInput";
const editorMapping = { const inputMapping = {
number: 'NumberEditor', number: 'NumberInput',
string: 'StringEditor', string: 'StringInput',
enum: 'EnumEditor', enum: 'EnumInput',
boolean: 'BooleanEditor', boolean: 'BooleanInput',
color: 'ColorEditor', color: 'ColorInput',
asset: 'AssetEditor', asset: 'AssetInput',
node: 'NodeSelectEditor', node: 'NodeSelectInput',
data: 'DataInput',
}; };
export default { export default {
name: "PropertiesEditor", name: "PropertiesInput",
components: {NodeSelectEditor, AssetEditor, ColorEditor, BooleanEditor, EnumEditor, NumberEditor, StringEditor}, components: {
DataInput,
NodeSelectInput, AssetInput, ColorInput, BooleanInput, EnumInput, NumberInput, StringInput},
data() { data() {
return { return {
process: null, process: null,
...@@ -57,8 +61,8 @@ ...@@ -57,8 +61,8 @@
edit(process) { edit(process) {
this.process = process; this.process = process;
}, },
getEditor(property) { getInput(property) {
return editorMapping[property.type]; return inputMapping[property.type];
}, },
} }
} }
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
'color', 'color',
'asset', 'asset',
'node', 'node',
'data',
], ],
} }
}, },
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName">
<el-select :disabled="!editable" :value="editValue" filterable @input="onInput" :placeholder="property.default" class="el-select"> <el-select :disabled="!editable" :value="editValue" filterable @input="onInput" :placeholder="property.default" class="el-select">
<el-option <el-option
v-for="(item, key) in assets" v-for="(item, key) in assets"
...@@ -9,16 +9,16 @@ ...@@ -9,16 +9,16 @@
<span>{{item.name}}</span> <span>{{item.name}}</span>
</el-option> </el-option>
</el-select> </el-select>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import {mapMutations} from 'vuex' import {mapMutations} from 'vuex'
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
export default { export default {
name: "AssetEditor", name: "AssetInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
computed: { computed: {
editValue() { editValue() {
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName">
<el-switch :disabled="!editable" :value="editValue" @input="onInput" <el-switch :disabled="!editable" :value="editValue" @input="onInput"
class="picker"></el-switch> class="picker"></el-switch>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
export default { export default {
name: "BooleanEditor", name: "BooleanInput",
components: {EditorWrapper}, components: {InputWrapper},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
data() { data() {
return {} return {}
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName" class="color-editor-container"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName" class="color-input-container">
<el-color-picker <el-color-picker
:disabled="!editable" :disabled="!editable"
class="picker" class="picker"
...@@ -8,15 +8,15 @@ ...@@ -8,15 +8,15 @@
show-alpha show-alpha
:predefine="predefineColors"> :predefine="predefineColors">
</el-color-picker> </el-color-picker>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
export default { export default {
name: "ColorEditor", name: "ColorInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
data() { data() {
return { return {
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
</script> </script>
<style scoped> <style scoped>
.color-editor-container { .color-input-container {
height: 29px; height: 29px;
overflow: hidden; overflow: hidden;
} }
......
<template>
<input-wrapper :editable="editable" :value="value" :container="container" :property="property"
:propertyName="propertyName">
<div style="display: flex;flex: 1;">
<el-popover
placement="top"
popper-class="input-area-popover"
class="string-input-container"
trigger="manual"
v-model="popoverVisible"
:disabled="!editable"
>
<el-radio-group v-model="editValue.type" size="mini" @change="onChange" :disabled="!editable">
<el-radio-button v-for="(item, key) in dataTypes" :label="key">{{item}}</el-radio-button>
</el-radio-group>
<el-input clearable slot="reference" :value="editValue.value" @input="onInput" @change="onChange"
:readonly="!editable"
:placeholder="defaultValue"/>
</el-popover>
<el-button-group>
<el-button @click="onClickEdit" :disabled="!editable">{{editValue.type[0].toUpperCase()}}</el-button>
<el-button icon="el-icon-delete" @click="onClickClean" :disabled="!editable"></el-button>
</el-button-group>
</div>
</input-wrapper>
</template>
<script>
import InputWrapper from "./InputWrapper";
import {getInputDefaultValue} from "../../../../utils";
export default {
name: "DataInput",
components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'],
data() {
let dataTypes = this.$t('dataTypes');
return {
editValue: this.value || {type: 'static'},
popoverEditValue: this.value,
popoverVisible: false,
dataTypes,
}
},
computed: {
defaultValue() {
return getInputDefaultValue(this.property);
},
},
watch: {
value(v) {
this.editValue = v || {type: 'static'};
},
},
methods: {
onClickEdit() {
this.popoverVisible = !this.popoverVisible;
},
onClickClean() {
this.$emit('input', undefined, this.container, this.propertyName, this.value);
},
onInput(v) {
this.$set(this.editValue, 'value', v);
},
onChange() {
this.$emit('input', this.editValue, this.container, this.propertyName, this.value);
},
},
}
</script>
<style scoped>
.bottom-bar {
margin-top: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName">
<el-select :disabled="!editable" :value="editValue" @input="onInput" :placeholder="property.default" class="el-select"> <el-select :disabled="!editable" :value="editValue" @input="onInput" :placeholder="property.default" class="el-select">
<el-option <el-option
v-for="(item, key) in property.enum" v-for="(item, key) in property.enum"
...@@ -10,15 +10,15 @@ ...@@ -10,15 +10,15 @@
<span class="comment"></span> <span class="comment"></span>
</el-option> </el-option>
</el-select> </el-select>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
export default { export default {
name: "EnumEditor", name: "EnumInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
computed: { computed: {
editValue() { editValue() {
......
<template> <template>
<el-form-item class="editor-wrapper" :label="property.alias || propertyName" content-float="right" <el-form-item class="input-wrapper" :label="property.alias || propertyName" content-float="right"
:content-width="contentWidth" :labelOffsetTop="labelOffsetTop"> :content-width="contentWidth" :labelOffsetTop="labelOffsetTop">
<template v-if="linked"> <template v-if="linked">
<span class="linked">Linked to parent</span> <span class="linked">Linked to parent</span>
...@@ -11,9 +11,14 @@ ...@@ -11,9 +11,14 @@
trigger="click" trigger="click"
:disabled="!editable" :disabled="!editable"
> >
<div> <div class="linked-prop-popover">
<span>{{$t('Link to parent')}}: </span> <div>
<el-switch :value="linked" @input="onChange"/> <span>{{$t('Link to parent')}}: </span>
<el-switch :value="linked" @input="onChange"/>
</div>
<div v-if="linked">
<el-input size="mini" v-model="value.alias" :placeholder="$t('Alias')"/>
</div>
</div> </div>
<el-link style="padding: 3px;" slot="reference" icon="el-icon-link" :underline="false" <el-link style="padding: 3px;" slot="reference" icon="el-icon-link" :underline="false"
:type="linked ? 'success' : 'default'" :disabled="!editable"/> :type="linked ? 'success' : 'default'" :disabled="!editable"/>
...@@ -24,10 +29,9 @@ ...@@ -24,10 +29,9 @@
<script> <script>
import camelcase from 'camelcase' import camelcase from 'camelcase'
import ElFormItem from "./form-item"; import ElFormItem from "./form-item";
import {linkedFlag} from "../../../../utils";
export default { export default {
name: "EditorWrapper", name: "InputWrapper",
components: {ElFormItem}, components: {ElFormItem},
props: { props: {
property: Object, property: Object,
...@@ -44,15 +48,28 @@ ...@@ -44,15 +48,28 @@
default: 0, default: 0,
}, },
}, },
data(){
return {
}
},
watch: {
value(v){
}
},
computed: { computed: {
linked() { linked() {
return this.value === linkedFlag return typeof this.value === 'object' && this.value.type === 'link'
} }
}, },
methods: { methods: {
onChange(v) { onChange(v) {
if (v) { if (v) {
this.$set(this.container.data.props, this.propertyName, linkedFlag); this.$set(this.container.data.props, this.propertyName, {
type: 'link',
alias: undefined,
});
} else { } else {
this.$delete(this.container.data.props, this.propertyName); this.$delete(this.container.data.props, this.propertyName);
} }
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property"
:propertyName="propertyName">
<div style="display: flex;flex: 1;"> <div style="display: flex;flex: 1;">
<el-popover <el-popover
placement="top" placement="top"
...@@ -34,7 +35,8 @@ ...@@ -34,7 +35,8 @@
</el-button-group> </el-button-group>
</div> </div>
</div> </div>
<el-input clearable slot="reference" v-model="editValue" @change="onInput" placeholder="unset" :readonly="!editable"> <el-input clearable slot="reference" v-model="editValue" @change="onInput" placeholder="unset"
:readonly="!editable">
<template slot="prepend">node://</template> <template slot="prepend">node://</template>
</el-input> </el-input>
</el-popover> </el-popover>
...@@ -43,18 +45,18 @@ ...@@ -43,18 +45,18 @@
<el-button icon="el-icon-delete" @click="onClickClean" :disabled="!editable"></el-button> <el-button icon="el-icon-delete" @click="onClickClean" :disabled="!editable"></el-button>
</el-button-group> </el-button-group>
</div> </div>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
const nodeScheme = 'node://'; const nodeScheme = 'node://';
export default { export default {
name: "NodeSelectEditor", name: "NodeSelectInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
data() { data() {
return { return {
...@@ -66,15 +68,20 @@ ...@@ -66,15 +68,20 @@
}, },
} }
}, },
watch: {
value(v) {
this.editValueOrigin = v;
}
},
computed: { computed: {
...mapGetters([ ...mapGetters([
'behavior_views' 'behavior_views'
]), ]),
editValue: { editValue: {
get(){ get() {
return this.editValueOrigin ? this.editValueOrigin.replace(nodeScheme) : ''; return this.editValueOrigin && typeof this.editValueOrigin !== 'object'? this.editValueOrigin.replace(nodeScheme, '') : '';
}, },
set(v){ set(v) {
this.editValueOrigin = v; this.editValueOrigin = v;
}, },
}, },
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName">
<el-input-number :disabled="!editable" :value="editValue" @input="onInput" controls-position="right" <el-input-number :disabled="!editable" :value="editValue" @input="onInput" controls-position="right"
:placeholder="defaultValue"></el-input-number> :placeholder="defaultValue"></el-input-number>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
import {getEditorDefaultValue} from "../../../../utils"; import {getInputDefaultValue} from "../../../../utils";
export default { export default {
name: "NumberEditor", name: "NumberInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
computed: { computed: {
editValue() { editValue() {
return this.value === undefined ? this.property.default : this.value; return this.value === undefined ? this.property.default : this.value;
}, },
defaultValue(){ defaultValue(){
return getEditorDefaultValue(this.property); return getInputDefaultValue(this.property);
}, },
}, },
methods: { methods: {
......
<template> <template>
<editor-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName"> <input-wrapper :editable="editable" :value="value" :container="container" :property="property" :propertyName="propertyName">
<div style="display: flex;flex: 1;"> <div style="display: flex;flex: 1;">
<el-popover <el-popover
placement="top" placement="top"
popper-class="input-area-popover" popper-class="input-area-popover"
class="string-editor-container" class="string-input-container"
trigger="manual" trigger="manual"
width="400" width="400"
v-model="popoverVisible" v-model="popoverVisible"
...@@ -34,16 +34,16 @@ ...@@ -34,16 +34,16 @@
<el-button icon="el-icon-delete" @click="onClickClean" :disabled="!editable"></el-button> <el-button icon="el-icon-delete" @click="onClickClean" :disabled="!editable"></el-button>
</el-button-group> </el-button-group>
</div> </div>
</editor-wrapper> </input-wrapper>
</template> </template>
<script> <script>
import EditorWrapper from "./EditorWrapper"; import InputWrapper from "./InputWrapper";
import {getEditorDefaultValue, linkedFlag} from "../../../../utils"; import {getInputDefaultValue} from "../../../../utils";
export default { export default {
name: "StringEditor", name: "StringInput",
components: {EditorWrapper,}, components: {InputWrapper,},
props: ['value', 'container', 'property', 'propertyName', 'editable'], props: ['value', 'container', 'property', 'propertyName', 'editable'],
data() { data() {
return { return {
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
return this.popoverVisible ? 'el-icon-check' : 'el-icon-edit'; return this.popoverVisible ? 'el-icon-check' : 'el-icon-edit';
}, },
defaultValue() { defaultValue() {
return getEditorDefaultValue(this.property); return getInputDefaultValue(this.property);
}, },
}, },
watch: { watch: {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<template slot-scope="scope"> <template slot-scope="scope">
<div class="project-info"> <div class="project-info">
<span class="project-name">{{scope.row.name}}</span> <span class="project-name">{{scope.row.name}}</span>
<el-tag size="mini" type="success">{{scope.row.creator}}</el-tag> <el-tag size="mini" type="success">{{scope.row.operator}}</el-tag>
<el-tag size="mini" type="warning">{{moment(scope.row.update_time)}}</el-tag> <el-tag size="mini" type="warning">{{moment(scope.row.update_time)}}</el-tag>
</div> </div>
</template> </template>
......
const serverHost = 'http://10.10.95.74:7777';
module.exports = { module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '//yun.duiba.com.cn/editor/zeroing/v1/' : '',
pluginOptions: { pluginOptions: {
i18n: { i18n: {
locale: 'en', locale: 'en',
...@@ -6,5 +9,20 @@ module.exports = { ...@@ -6,5 +9,20 @@ module.exports = {
localeDir: 'locales', localeDir: 'locales',
enableInSFC: true enableInSFC: true
} }
},
devServer: {
host: '0.0.0.0',
port: '8080',
proxy: {
'/sso': {
target: serverHost,
},
'/api': {
target: serverHost,
},
}
},
configureWebpack: {
} }
} };
This source diff could not be displayed because it is too large. You can view the blob instead.
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