Commit 420f7c0b authored by rockyl's avatar rockyl

完善各种体验

parent 3cc19fd2
...@@ -6,14 +6,18 @@ ...@@ -6,14 +6,18 @@
:disabled="!legalUrl" :disabled="!legalUrl"
:content="url" :content="url"
> >
<img style="max-width: 200px;" v-if="url" :src="url" alt="" /> <img style="max-width: 200px;" v-if="url" :src="url" alt=""/>
<el-input v-model="swvalue" slot="reference" @drop.native="drop" @dragover.native="dragOver"></el-input> <el-input v-model="swvalue" slot="reference" @drop.native="drop" @dragover.native="dragOver">
<el-button slot="append" icon="el-icon-aim" @click="locateAsset"></el-button>
</el-input>
</el-popover> </el-popover>
</template> </template>
<style> <style>
</style> </style>
<script> <script>
export default { import events from "@/global-events.js"
export default {
props: { props: {
value: [String, Number, Boolean] value: [String, Number, Boolean]
}, },
...@@ -36,10 +40,19 @@ export default { ...@@ -36,10 +40,19 @@ export default {
}, },
dragOver(e) { dragOver(e) {
e.preventDefault(); e.preventDefault();
},
locateAsset() {
let uuid = this.swvalue ? this.swvalue.split('//')[1] : null;
if (uuid) {
let asset = this.$store.state.project.data.assets.find(a => a.uuid === uuid);
if (asset) {
events.$emit('select-asset-item', asset);
}
}
} }
}, },
computed: { computed: {
url: function() { url: function () {
if (this.swvalue) { if (this.swvalue) {
if (this.swvalue.indexOf('asset://') > -1) { if (this.swvalue.indexOf('asset://') > -1) {
let uuid = this.swvalue.split('//')[1]; let uuid = this.swvalue.split('//')[1];
...@@ -52,9 +65,9 @@ export default { ...@@ -52,9 +65,9 @@ export default {
return ''; return '';
} }
}, },
legalUrl: function() { legalUrl: function () {
return (this.swvalue + '').indexOf('//') > -1; return (this.swvalue + '').indexOf('//') > -1;
} }
} }
}; };
</script> </script>
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
"Type": "类型", "Type": "类型",
"Group": "分组", "Group": "分组",
"Select from history": "打开历史版本", "Select from history": "打开历史版本",
"Meta Search": "过程元查找", "Process Search": "过程搜索定位",
"Access denied": "无权限", "Access denied": "无权限",
"Invalid router": "无效的页面", "Invalid router": "无效的页面",
"Jump after": "{cd}秒后跳转", "Jump after": "{cd}秒后跳转",
...@@ -155,6 +155,7 @@ ...@@ -155,6 +155,7 @@
"Remote Version": "远程版本", "Remote Version": "远程版本",
"Confirm to exit the editor": "确定退出编辑器吗?", "Confirm to exit the editor": "确定退出编辑器吗?",
"Confirm to publish": "确定发布吗?", "Confirm to publish": "确定发布吗?",
"Are you sure to delete this process?": "确定删除这对应的过程吗",
"Are you sure to delete it's process": "确定删除这对应的过程吗", "Are you sure to delete it's process": "确定删除这对应的过程吗",
"Are you sure to delete this asset": "确定删除这个素材吗", "Are you sure to delete this asset": "确定删除这个素材吗",
"Are you sure to delete all assets": "确定删除全部素材吗", "Are you sure to delete all assets": "确定删除全部素材吗",
...@@ -186,7 +187,7 @@ ...@@ -186,7 +187,7 @@
"Publish": "发布", "Publish": "发布",
"Publish config": "发布配置", "Publish config": "发布配置",
"Publish to projectx": "发布到星速台", "Publish to projectx": "发布到星速台",
"Are sure to delete this item?": "确定要删除这条记录吗?", "Are you sure to delete this item?": "确定要删除这条记录吗?",
"Projectx skin editor": "星速台皮肤编辑器", "Projectx skin editor": "星速台皮肤编辑器",
"Skin name required": "皮肤名必填", "Skin name required": "皮肤名必填",
"Skin html required": "皮肤代码必填", "Skin html required": "皮肤代码必填",
...@@ -201,6 +202,9 @@ ...@@ -201,6 +202,9 @@
"Index page exists": "已存在首页", "Index page exists": "已存在首页",
"Please config projectID": "请先配置{env}环境下的projectId", "Please config projectID": "请先配置{env}环境下的projectId",
"Online ticket is invalid": "线上tickct失效,请联系管理员修改", "Online ticket is invalid": "线上tickct失效,请联系管理员修改",
"Are you sure to translate to normal process?": "你确定将此转化为通用过程吗?",
"Input custom process name": "请输入自定义过程名称",
"Invalid name": "无效名称",
"eventGroup": { "eventGroup": {
"in": "接收", "in": "接收",
"out": "派发" "out": "派发"
...@@ -215,6 +219,9 @@ ...@@ -215,6 +219,9 @@
"preview-fast": { "preview-fast": {
"label": "预览" "label": "预览"
}, },
"search": {
"label": "搜索"
},
"pack": { "pack": {
"label": "打包", "label": "打包",
"sub": { "sub": {
......
...@@ -29,7 +29,7 @@ export default new Vuex.Store({ ...@@ -29,7 +29,7 @@ export default new Vuex.Store({
plugins: [ plugins: [
SaveToLocalPlugin({ SaveToLocalPlugin({
mutationTypes: [ mutationTypes: [
'makeDirty', 'makeProjectDirty',
'modifyProject', 'modifyProject',
'addNode', 'addNode',
'deleteNode', 'deleteNode',
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import Vue from "vue"; import Vue from "vue";
import i18n from "../../i18n"; import i18n from "../../i18n";
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
import {clonePureObj, getViewNodePath, metaInUse, searchViewNode, updateProcesses} from "../../utils"; import {clonePureObj, getViewNodePath, findMetaDepById, searchViewNode, updateProcesses} from "../../utils";
import {arrayFind} from "element-ui/src/utils/util"; import {arrayFind} from "element-ui/src/utils/util";
export const behaviorStore = { export const behaviorStore = {
...@@ -18,6 +18,7 @@ export const behaviorStore = { ...@@ -18,6 +18,7 @@ export const behaviorStore = {
currentBehavior: null, currentBehavior: null,
processContext: [], processContext: [],
currentProcess: null, currentProcess: null,
lastProcess: null,
processStack: [], processStack: [],
editable: false, editable: false,
...@@ -31,7 +32,7 @@ export const behaviorStore = { ...@@ -31,7 +32,7 @@ export const behaviorStore = {
dirty: false, dirty: false,
}, },
mutations: { mutations: {
makeBehaviorDirty(state){ makeBehaviorDirty(state) {
state.dirty = true; state.dirty = true;
}, },
behavior_startEdit(state, {originData, behavior}) { behavior_startEdit(state, {originData, behavior}) {
...@@ -78,7 +79,7 @@ export const behaviorStore = { ...@@ -78,7 +79,7 @@ export const behaviorStore = {
state.currentProcess = process; state.currentProcess = process;
}, },
popProcessStack(state, index) { popProcessStack(state, index) {
state.processStack.splice(index); state.lastProcess = state.processStack.splice(index)[0];
updatePropsEditable(state); updatePropsEditable(state);
state.currentProcess = state.processStack[state.processStack.length - 1]; state.currentProcess = state.processStack[state.processStack.length - 1];
}, },
...@@ -90,7 +91,15 @@ export const behaviorStore = { ...@@ -90,7 +91,15 @@ export const behaviorStore = {
scale += value; scale += value;
} }
state.drawState.boardScale = Math.max(Math.min(4, scale), 0.1); state.drawState.boardScale = Math.max(Math.min(4, scale), 0.1);
} },
translateToNormal(state, {meta, parentMeta}) {
meta.isInline = false;
let index = parentMeta.metas.indexOf(meta);
parentMeta.metas.splice(index, 1);
state.processes.push(meta);
this.commit('makeBehaviorDirty');
},
}, },
getters: { getters: {
customProcessMap: state => { customProcessMap: state => {
...@@ -101,16 +110,7 @@ export const behaviorStore = { ...@@ -101,16 +110,7 @@ export const behaviorStore = {
return map; return map;
}, },
metaInUse: state => targetMetaID => { metaInUse: state => targetMetaID => {
let allMetasInUse = []; return findMetaDepById(state.processes, targetMetaID);
for (let process of state.processes) {
let usedMetas = metaInUse(process, targetMetaID);
allMetasInUse.push(...usedMetas);
/*if (usedMetas.length > 0) {
result = true;
break;
}*/
}
return allMetasInUse;
}, },
metaIDExists: state => id => { metaIDExists: state => id => {
let result = false; let result = false;
...@@ -129,7 +129,7 @@ export const behaviorStore = { ...@@ -129,7 +129,7 @@ export const behaviorStore = {
return state.projectData.views; return state.projectData.views;
}, },
behavior_searchViewNode: state => uuid => { behavior_searchViewNode: state => uuid => {
if(uuid){ if (uuid) {
return searchViewNode(state.projectData.views, uuid); return searchViewNode(state.projectData.views, uuid);
} }
} }
...@@ -139,7 +139,7 @@ export const behaviorStore = { ...@@ -139,7 +139,7 @@ export const behaviorStore = {
commit('behavior_save'); commit('behavior_save');
return state.currentBehavior; return state.currentBehavior;
}, },
addCustomProcessMeta({commit, state}, {masterProcess, isInline, processId}) { addCustomProcessMeta({commit, state}, {masterProcess, isInline, processId, name}) {
let meta = { let meta = {
id: generateUUID(), id: generateUUID(),
script: '', script: '',
...@@ -149,11 +149,11 @@ export const behaviorStore = { ...@@ -149,11 +149,11 @@ export const behaviorStore = {
}; };
switch (processId) { switch (processId) {
case 'custom': case 'custom':
meta.name = i18n.t('Custom'); meta.name = name || i18n.t('Custom');
meta.output = ['success', 'failed']; meta.output = ['success', 'failed'];
break; break;
case 'divider': case 'divider':
meta.name = i18n.t('Divider'); meta.name = name || i18n.t('Divider');
meta.output = ['p0']; meta.output = ['p0'];
meta.isDivider = true; meta.isDivider = true;
break; break;
...@@ -172,9 +172,6 @@ export const behaviorStore = { ...@@ -172,9 +172,6 @@ export const behaviorStore = {
addProcessMeta(commit, isInline, masterProcess, meta); addProcessMeta(commit, isInline, masterProcess, meta);
return meta; return meta;
}, },
searchMeta({state}, {keyword}) {
searchMeta(state.processes, keyword);
},
} }
}; };
...@@ -193,14 +190,6 @@ function addProcessMeta(commit, isInline, masterProcess, meta) { ...@@ -193,14 +190,6 @@ function addProcessMeta(commit, isInline, masterProcess, meta) {
} }
} }
function searchMeta(processes, keyword, path) {
for (let process of processes) {
/*if(process.id === keyword || process.name === keyword){
}*/
}
}
export function addBehavior({alias, from}, processes) { export function addBehavior({alias, from}, processes) {
let metaUUID = generateUUID(); let metaUUID = generateUUID();
let behavior = { let behavior = {
...@@ -225,7 +214,7 @@ export function addBehavior({alias, from}, processes) { ...@@ -225,7 +214,7 @@ export function addBehavior({alias, from}, processes) {
}, },
}, },
}; };
if(from){ if (from) {
p.from = from; p.from = from;
} }
processes.push(p); processes.push(p);
...@@ -242,7 +231,3 @@ export function deleteProcessMeta(metaId, processes) { ...@@ -242,7 +231,3 @@ export function deleteProcessMeta(metaId, processes) {
} }
} }
} }
export function findProcess(metaId, processes) {
return arrayFind(processes, process => process.id === metaId);
}
...@@ -7,17 +7,18 @@ import {editorApi, projectApi} from "../../api" ...@@ -7,17 +7,18 @@ import {editorApi, projectApi} from "../../api"
import path from "path" import path from "path"
import generateUUID from "uuid/v4" import generateUUID from "uuid/v4"
import {flattenViews, getCmpByUUID, getCmpProps} from '../../utils/common' import {flattenViews, getCmpByUUID, getCmpProps} from '../../utils/common'
import {clonePureObj, getMockServeEnabled, saveAs} from "../../utils" import {clonePureObj, findProcess, getMockServeEnabled, saveAs, traverseViewNode} from "../../utils"
import {template} from "../../template" import {template} from "../../template"
import events from "@/global-events" import events from "@/global-events"
import {packImages} from "../../utils/sheet-pack" import {packImages} from "../../utils/sheet-pack"
import {addBehavior, deleteProcessMeta, findProcess} from "./behavior" import {addBehavior, deleteProcessMeta,} from "./behavior"
import db from "../../utils/db-storage" import db from "../../utils/db-storage"
import {preprocess} from "../../views/Preview/preview-preprocess" import {preprocess} from "../../views/Preview/preview-preprocess"
import {packageStore} from "./package" import {packageStore} from "./package"
import {fetchApi} from "../../api/common" import {fetchApi} from "../../api/common"
import {toZeroing} from "psd-parse-web" import {toZeroing} from "psd-parse-web"
import {arrayFind} from "element-ui/src/utils/util";
const storeName = 'project'; const storeName = 'project';
const psStoreName = 'pack-history'; const psStoreName = 'pack-history';
...@@ -52,16 +53,16 @@ function getDefaultOptions() { ...@@ -52,16 +53,16 @@ function getDefaultOptions() {
function setUUIDForAllChildren(node) { function setUUIDForAllChildren(node) {
if (node.children && node.children.length > 0) { if (node.children && node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) { for (let i = 0; i < node.children.length; i++) {
node.children[i] = copyBaseRoot(node.children[i]) node.children[i] = copyBaseRoot(node.children[i]);
setUUIDForAllChildren(node.children[i]) setUUIDForAllChildren(node.children[i])
} }
} }
} }
let copyNodeCatch = null let copyNodeCatch = null;
function copyBaseRoot(node) { function copyBaseRoot(node) {
let _node = JSON.parse(JSON.stringify(node)) let _node = JSON.parse(JSON.stringify(node));
let data; let data;
...@@ -118,7 +119,7 @@ export const projectStore = { ...@@ -118,7 +119,7 @@ export const projectStore = {
setDirty(state, dirty = true) { setDirty(state, dirty = true) {
state.dirty = dirty; state.dirty = dirty;
}, },
makeDirty() { makeProjectDirty() {
}, },
updateProject(state, project) { updateProject(state, project) {
...@@ -378,7 +379,7 @@ export const projectStore = { ...@@ -378,7 +379,7 @@ export const projectStore = {
copyNode(state, {node, parentNode}) { copyNode(state, {node, parentNode}) {
let _node1 = node let _node1 = node;
copyNodeCatch = _node1; copyNodeCatch = _node1;
//localStorage.copyNodeCatch=_node1; //localStorage.copyNodeCatch=_node1;
// let _node=copyBaseRoot(_node1); // let _node=copyBaseRoot(_node1);
...@@ -394,10 +395,10 @@ export const projectStore = { ...@@ -394,10 +395,10 @@ export const projectStore = {
}, },
pasteNode(state, {node, parentNode, pasteState}) { pasteNode(state, {node, parentNode, pasteState}) {
let _node1 = copyNodeCatch; let _node1 = copyNodeCatch;
console.log(copyNodeCatch) console.log(copyNodeCatch);
if (_node1) { if (_node1) {
let _node = copyBaseRoot(_node1); let _node = copyBaseRoot(_node1);
setUUIDForAllChildren(_node) setUUIDForAllChildren(_node);
if (pasteState == 1) { if (pasteState == 1) {
parentNode = parentNode; parentNode = parentNode;
} else { } else {
...@@ -482,6 +483,9 @@ export const projectStore = { ...@@ -482,6 +483,9 @@ export const projectStore = {
options(state) { options(state) {
return state.data.options; return state.data.options;
}, },
processes(state) {
return state.data.processes;
},
envKeys(state) { envKeys(state) {
return state.data.options.env.map(item => item.name); return state.data.options.env.map(item => item.name);
}, },
...@@ -534,11 +538,48 @@ export const projectStore = { ...@@ -534,11 +538,48 @@ export const projectStore = {
return state.data.assets; return state.data.assets;
}, },
getProcess: state => behavior => { getProcess: state => behavior => {
return findProcess(behavior.meta, state.data.processes); return arrayFind(state.data.processes, process => process.id === behavior.meta);
}, },
dependencies(state) { dependencies(state) {
return state.data.dependencies; return state.data.dependencies;
}, },
searchProcess: state => (keyword, searchField) => {
let result = [];
let paths = findProcess(state.data.processes, state.package.packages.process, function (process, meta) {
return meta[searchField] && meta[searchField].includes(keyword)
|| process.meta.includes(keyword)
|| (process.alias && process.alias.includes(keyword));
});
let entries = paths.map(path => path[0].id);
traverseViewNode(state.data.views, function (node, parent) {
for (let eventName in node.events) {
let event = node.events[eventName];
for (let behavior of event.behaviors) {
let index = entries.indexOf(behavior.meta);
if (index >= 0) {
let path = paths.splice(index, 1, null)[0];
path[0] = {
process: behavior,
metaName: path[0].name,
};
result.push({
node,
path,
});
}
}
}
});
/*for (let path of paths) {
if (path) {
result.push({
path,
})
}
}*/
return result;
},
}, },
actions: { actions: {
async saveToLocal({getters, commit}) { async saveToLocal({getters, commit}) {
...@@ -785,7 +826,7 @@ export const projectStore = { ...@@ -785,7 +826,7 @@ export const projectStore = {
}, },
addBehaviorDirect({state}, {behaviors, alias}) { addBehaviorDirect({state}, {behaviors, alias}) {
let behavior = addBehavior(alias, state.data.processes); let behavior = addBehavior({alias, from: 'trigger'}, state.data.processes);
behaviors.push(behavior); behaviors.push(behavior);
}, },
...@@ -828,15 +869,15 @@ async function getSheetUrlByUUID(uuid) { ...@@ -828,15 +869,15 @@ async function getSheetUrlByUUID(uuid) {
const response = await fetchApi('/api/uuid2url', { const response = await fetchApi('/api/uuid2url', {
params: {uuid}, params: {uuid},
errMessage: 'Failed to get url', errMessage: 'Failed to get url',
}) });
return response.url return response.url
} }
async function packAssets(assets) { async function packAssets(assets) {
let failedList = [] let failedList = [];
let newAssets = assets.concat() let newAssets = assets.concat();
await packImages(newAssets, {getSheetUrlByUUID}) await packImages(newAssets, {getSheetUrlByUUID});
for (let asset of newAssets) { for (let asset of newAssets) {
if (asset.file) { if (asset.file) {
...@@ -847,18 +888,18 @@ async function packAssets(assets) { ...@@ -847,18 +888,18 @@ async function packAssets(assets) {
file: url, file: url,
type: 'sheet', type: 'sheet',
frames: asset.frames, frames: asset.frames,
} };
let sheetConfigFile = new File([JSON.stringify(sheetConfig)], 'sheet.json', {type: 'plain/text'}) let sheetConfigFile = new File([JSON.stringify(sheetConfig)], 'sheet.json', {type: 'plain/text'});
const {url: sheetConfigUrl} = await editorApi.uploadFile(sheetConfigFile, false, asset.sheetUUID).catch(e => { const {url: sheetConfigUrl} = await editorApi.uploadFile(sheetConfigFile, false, asset.sheetUUID).catch(e => {
failedList.push(asset) failedList.push(asset)
}) });
asset.url = sheetConfigUrl asset.url = sheetConfigUrl;
asset.uuid = generateUUID() asset.uuid = generateUUID();
delete asset.file delete asset.file;
delete asset.frames delete asset.frames;
delete asset.sheetUUID delete asset.sheetUUID;
} }
} }
...@@ -871,18 +912,3 @@ export async function updateMock(mocks) { ...@@ -871,18 +912,3 @@ export async function updateMock(mocks) {
db.set('mock', mock); db.set('mock', mock);
} }
} }
function parseItem(list) {
let hasError, result = [];
for (let i = 0, li = list.length; i < li; i++) {
try {
result.push(JSON.parse(list[i].data));
} catch (e) {
hasError = true;
}
}
if (hasError) {
console.warn('parse env error');
}
return result;
}
...@@ -80,7 +80,9 @@ ...@@ -80,7 +80,9 @@
& > .icon > .operate-bar { & > .icon > .operate-bar {
visibility: visible; visibility: visible;
} }
}
&.select{
& > .name > .full-name { & > .name > .full-name {
visibility: visible; visibility: visible;
} }
......
...@@ -263,7 +263,7 @@ ...@@ -263,7 +263,7 @@
.wrapper { .wrapper {
height: 50vh; height: 50vh;
.form{ .form {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -272,7 +272,7 @@ ...@@ -272,7 +272,7 @@
margin-bottom: 20px; margin-bottom: 20px;
} }
.editor-form-item{ .editor-form-item {
flex: 1; flex: 1;
.el-form-item__content { .el-form-item__content {
...@@ -288,6 +288,30 @@ ...@@ -288,6 +288,30 @@
} }
} }
.meta-search-dialog {
.wrapper{
padding: 10px;
height: 50vh;
display: flex;
flex-direction: column;
.inputs{
display: flex;
align-items: center;
margin-bottom: 5px;
.input-keyword{
flex: 1;
margin-right: 5px;
}
}
.scrollbar{
flex: 1;
}
}
}
.dialog-footer { .dialog-footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
......
/**
* Created by rockyl on 2019-04-28.
*/
import Vue from 'vue';
export function addEntity(parent, target, pos) {
}
export function removeEntity(parent, target, pos) {
}
export function prepare(history){
history.regActions('add-entity', addEntity, removeEntity);
history.regActions('remove-entity', removeEntity, addEntity);
}
/**
* Created by rockyl on 2019-01-31.
*/
import Vue from 'vue'
const showLog = true;
export default class History extends Vue{
constructor(max = 200) {
super();
this.actions = {};
this.history = [];
this.position = -1;
this.max = max;
}
regActions(name, forward, backward) {
this.actions[name] = {
forward,
backward
};
}
reset() {
this.history.splice(0);
this._setPosition(- 1, true);
}
_setPosition(v, reset=false){
this.position = v;
this.$emit('change', {canUndo: this.canUndo, canRedo: this.canRedo, position: v, reset})
}
done(action, ...input) {
this.history.splice(this.position + 1);
this.history.push({
action,
input,
});
if (this.history.length > this.max) {
this.history.shift();
} else {
this._setPosition(this.history.length - 1);
}
if(showLog) console.log('done>', action, input);
}
undo() {
if (this.canUndo) {
const {action, input} = this.history[this.position];
let {backward} = this.actions[action];
backward(...input);
this._setPosition(this.position - 1);
if(showLog) console.log('undo>', action, input);
}
return this.canUndo;
}
redo() {
if (this.canRedo) {
this._setPosition(this.position + 1);
let {action, input} = this.history[this.position];
let {forward} = this.actions[action];
forward(...input);
if(showLog) console.log('redo>', action, input);
}
return this.canRedo;
}
get canUndo(){
return this.position >= 0
}
get canRedo(){
return this.position < this.history.length - 1
}
}
...@@ -77,6 +77,20 @@ export function guid() { ...@@ -77,6 +77,20 @@ export function guid() {
return `xy-${generateUUID()}`; return `xy-${generateUUID()}`;
} }
/**
* 遍历视图节点
* @param nodes
* @param callback
* @param parent
*/
export function traverseViewNode(nodes, callback, parent) {
for (let node of nodes) {
callback(node, parent);
if (node.children && node.children.length > 0) {
traverseViewNode(node.children, callback, node);
}
}
}
export function strEllipsis(str, maxLength = 0, rightOffset = 0) { export function strEllipsis(str, maxLength = 0, rightOffset = 0) {
let result = str; let result = str;
...@@ -110,20 +124,70 @@ export function updateProcesses(processes, targetMetaID, replaceMetaID) { ...@@ -110,20 +124,70 @@ export function updateProcesses(processes, targetMetaID, replaceMetaID) {
/** /**
* 过程元依赖过程 * 过程元依赖过程
* @param process * @param processMetas
* @param targetMetaID * @param metaId
* @return {Array} * @return {Array}
*/ */
export function metaInUse(process, targetMetaID) { export function findMetaDepById(processMetas, metaId) {
let result = []; let result = [];
for (let key in process.sub) { findMetaDepOnce(processMetas,
let subProcess = process.sub[key]; function findProcessFilterById(process) {
if (subProcess.meta === targetMetaID) { return process.meta === metaId;
result.push(process); }, result);
//break; return result;
}
function findMetaDepOnce(processMetas, filter, result, parentPath = []) {
for (let meta of processMetas) {
let path = parentPath.concat();
path.push(meta);
for (let key in meta.sub) {
let subProcess = meta.sub[key];
if (filter(subProcess)) {
path.push(subProcess);
result.push(path);
}
} }
if (meta.metas && meta.metas.length > 0) {
findMetaDepOnce(meta.metas, filter, result, path);
} }
}
}
export function findProcess(rootMetas, builtinMetas, filter) {
let result = [];
findOnce(rootMetas);
return result; return result;
function findOnce(metas, parentPath) {
for (let meta of metas) {
let path = parentPath ? parentPath : [];
if (!parentPath) {
path.push(meta);
}
for (let key in meta.sub) {
let subProcess = meta.sub[key];
let subMeta = meta.metas ? meta.metas.find(item => item.id === subProcess.meta) : null;
if (!subMeta) {
subMeta = rootMetas.find(item => item.id === subProcess.meta);
}
if (!subMeta) {
subMeta = builtinMetas[subProcess.meta]
}
if (subMeta) {
let newPath = path.concat();
newPath.push({
process: subProcess,
metaName: subMeta.name,
});
if (filter(subProcess, subMeta)) {
result.push(newPath);
}
findOnce([subMeta], newPath);
}
}
}
}
} }
/** /**
...@@ -324,6 +388,6 @@ export function getViewNodePath(node, sep = '/') { ...@@ -324,6 +388,6 @@ export function getViewNodePath(node, sep = '/') {
return segs.join(sep) return segs.join(sep)
} }
export function timeFormat(time, format = 'YYYY-MM-DD HH:mm:ss'){ export function timeFormat(time, format = 'YYYY-MM-DD HH:mm:ss') {
return moment(time).format(format) return moment(time).format(format)
} }
...@@ -18,11 +18,13 @@ ...@@ -18,11 +18,13 @@
<code-sync-serve-dialog ref="codeSyncServeDialog"/> <code-sync-serve-dialog ref="codeSyncServeDialog"/>
<missing-packages-dialog ref="missingPackagesDialog"/> <missing-packages-dialog ref="missingPackagesDialog"/>
<px-skin-editor-dialog ref="pxSkinEditorDialog"/> <px-skin-editor-dialog ref="pxSkinEditorDialog"/>
<process-search-dialog ref="processSearchDialog"/>
<behavior-editor-dialog @change="handleBehaviorsChange" ref="behaviorEditorDialog"></behavior-editor-dialog>
</div> </div>
</template> </template>
<script> <script>
import {mapState, mapActions} from 'vuex' import {mapState, mapActions, mapMutations} from 'vuex'
import SplitPanes from 'splitpanes' import SplitPanes from 'splitpanes'
import ToolBar from "./Editor/ToolBar"; import ToolBar from "./Editor/ToolBar";
import Inspector from "./Editor/Inspector"; import Inspector from "./Editor/Inspector";
...@@ -41,10 +43,14 @@ ...@@ -41,10 +43,14 @@
import MissingPackagesDialog from "./Editor/dialogs/MissingPackagesDialog"; import MissingPackagesDialog from "./Editor/dialogs/MissingPackagesDialog";
import PackManagerDialog from "./Editor/dialogs/PackManagerDialog"; import PackManagerDialog from "./Editor/dialogs/PackManagerDialog";
import PxSkinEditorDialog from "./Editor/dialogs/PxSkinEditorDialog"; import PxSkinEditorDialog from "./Editor/dialogs/PxSkinEditorDialog";
import BehaviorEditorDialog from "./Editor/dialogs/BehaviorEditorDialog";
import ProcessSearchDialog from "./Editor/dialogs/ProcessSearchDialog";
export default { export default {
name: 'Editor', name: 'Editor',
components: { components: {
ProcessSearchDialog,
BehaviorEditorDialog,
PxSkinEditorDialog, PxSkinEditorDialog,
PackManagerDialog, PackManagerDialog,
MissingPackagesDialog, MissingPackagesDialog,
...@@ -88,6 +94,7 @@ ...@@ -88,6 +94,7 @@
this.clickMenu("preview"); this.clickMenu("preview");
}); });
events.$on('show-missing-packages', this.showMissingPackages); events.$on('show-missing-packages', this.showMissingPackages);
events.$on('edit-behavior', this.editBehavior);
events.$on('show-code-sync-serve-dialog', () => { events.$on('show-code-sync-serve-dialog', () => {
this.$refs.codeSyncServeDialog.show(); this.$refs.codeSyncServeDialog.show();
...@@ -109,6 +116,7 @@ ...@@ -109,6 +116,7 @@
destroyed() { destroyed() {
document.removeEventListener('keydown', this.onKeyPress); document.removeEventListener('keydown', this.onKeyPress);
events.$off('show-missing-packages', this.showMissingPackages); events.$off('show-missing-packages', this.showMissingPackages);
events.$off('edit-behavior', this.editBehavior);
}, },
methods: { methods: {
...@@ -229,6 +237,9 @@ ...@@ -229,6 +237,9 @@
case 'pack-manager': case 'pack-manager':
this.$refs.packManagerDialog.show(); this.$refs.packManagerDialog.show();
break; break;
case 'search':
await this.$refs.processSearchDialog.show();
break;
case 'mock': case 'mock':
this.$refs.mockEditorDialog.show(); this.$refs.mockEditorDialog.show();
break; break;
...@@ -312,6 +323,13 @@ ...@@ -312,6 +323,13 @@
showMissingPackages(missingPackages) { showMissingPackages(missingPackages) {
this.$refs.missingPackagesDialog.show(missingPackages); this.$refs.missingPackagesDialog.show(missingPackages);
}, },
editBehavior(path, index) {
this.$refs.behaviorEditorDialog.show(path, index);
},
handleBehaviorsChange() {
this.makeProjectDirty();
},
...mapMutations(['makeProjectDirty']),
...mapActions([ ...mapActions([
'loadPackages', 'loadPackages',
'localVersionExist', 'localVersionExist',
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
</div> </div>
<el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden" <el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden"
view-class="scrollbar-view"> view-class="scrollbar-view">
<asset-list editable @show-file-details="showFileDetails" @click-item="onItemClick"> <asset-list ref="assetList" editable @show-file-details="showFileDetails" @click-item="onItemClick">
<div slot="first" class="file-uploader" @click="toUploadFile" @dragover.prevent @drop="onDropFile"> <div slot="first" class="file-uploader" @click="toUploadFile" @dragover.prevent @drop="onDropFile">
<i class="el-icon-plus file-uploader-icon"></i> <i class="el-icon-plus file-uploader-icon"></i>
</div> </div>
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
import SplitPanes from 'splitpanes' import SplitPanes from 'splitpanes'
import {scanFiles, selectFile} from "../../utils"; import {scanFiles, selectFile} from "../../utils";
import AssetList from "./Assets/AssetList"; import AssetList from "./Assets/AssetList";
import events from "@/global-events.js"
export default { export default {
name: "Assets", name: "Assets",
...@@ -60,6 +61,10 @@ ...@@ -60,6 +61,10 @@
}, },
mounted() { mounted() {
this.currentItem = null; this.currentItem = null;
events.$on('select-asset-item', this.selectAssetItem);
},
destroyed(){
events.$off('select-asset-item', this.selectAssetItem);
}, },
methods: { methods: {
toUploadFile() { toUploadFile() {
...@@ -100,6 +105,10 @@ ...@@ -100,6 +105,10 @@
}).catch((e) => { }).catch((e) => {
}); });
}, },
selectAssetItem(asset){
this.currentItem = asset;
this.$refs.assetList.selectItem(asset);
},
...mapMutations([ ...mapMutations([
'deleteAllAssets', 'deleteAllAssets',
]), ]),
......
<template> <template>
<div class="file-list"> <div class="file-list">
<slot name="first"></slot> <slot name="first"></slot>
<file-item v-for="(asset, index) in assets" :editable="editable" :data="asset" :key="index" @show-file-details="showFileDetails(asset)" <file-item v-for="(asset, index) in assets" :class="{select: isSelected(index)}" :editable="editable" :data="asset"
@click="onClickItem(asset)"/> :key="index" @show-file-details="showFileDetails(asset)"
@click="onClickItem(asset)"
@delete="onDeleteItem(asset)"
/>
</div> </div>
</template> </template>
...@@ -14,9 +17,14 @@ ...@@ -14,9 +17,14 @@
name: "AssetList", name: "AssetList",
components: {FileItem}, components: {FileItem},
props: { props: {
editable:{ editable: {
type: Boolean, type: Boolean,
default: false, default: false,
},
},
data() {
return {
selectedIndices: []
} }
}, },
computed: { computed: {
...@@ -30,7 +38,23 @@ ...@@ -30,7 +38,23 @@
}, },
onClickItem(asset) { onClickItem(asset) {
this.$emit('click-item', asset); this.$emit('click-item', asset);
this.selectItem(asset);
},
onDeleteItem(asset) {
if (this.isSelected(this.assets.indexOf(asset))) {
this.selectItem();
this.$emit('click-item', null);
}
}, },
selectItem(asset) {
this.selectedIndices.splice(0);
if (asset) {
this.selectedIndices.push(this.assets.indexOf(asset));
}
},
isSelected(index) {
return this.selectedIndices.includes(index);
}
} }
} }
</script> </script>
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
cancelButtonText: this.$t('Cancel'), cancelButtonText: this.$t('Cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$emit('delete', this.data);
this.deleteAsset(this.data.uuid); this.deleteAsset(this.data.uuid);
}).catch((e) => { }).catch((e) => {
}); });
......
...@@ -44,19 +44,17 @@ ...@@ -44,19 +44,17 @@
</el-collapse-transition> </el-collapse-transition>
</div> </div>
</el-scrollbar> </el-scrollbar>
<behavior-editor-dialog @change="handleBehaviorsChange" ref="behaviorEditorDialog"></behavior-editor-dialog>
</div> </div>
</template> </template>
<script> <script>
import {mapGetters, mapActions, mapMutations} from 'vuex'; import {mapGetters, mapActions, mapMutations} from 'vuex';
import BehaviorEditorDialog from "../dialogs/BehaviorEditorDialog";
import events from "@/global-events.js" import events from "@/global-events.js"
import EnabledSetter from "../components/EnabledSetter"; import EnabledSetter from "../components/EnabledSetter";
export default { export default {
name: "BehaviorTab", name: "BehaviorTab",
components: {EnabledSetter, BehaviorEditorDialog}, components: {EnabledSetter},
data() { data() {
const builtinEvents = this.$t('events'); const builtinEvents = this.$t('events');
return { return {
...@@ -116,7 +114,7 @@ ...@@ -116,7 +114,7 @@
alias, behaviors, alias, behaviors,
}); });
this.makeDirty(); this.makeProjectDirty();
}, },
editTriggerName(name) { editTriggerName(name) {
this.$prompt(this.$t('Input event name'), this.$t('Rename event'), { this.$prompt(this.$t('Input event name'), this.$t('Rename event'), {
...@@ -137,7 +135,7 @@ ...@@ -137,7 +135,7 @@
this.$set(events, value, events[name]); this.$set(events, value, events[name]);
this.$delete(events, name); this.$delete(events, name);
this.makeDirty(); this.makeProjectDirty();
} }
} }
}).catch(() => { }).catch(() => {
...@@ -146,20 +144,13 @@ ...@@ -146,20 +144,13 @@
deleteTrigger(name) { deleteTrigger(name) {
this.$delete(this.activeComponent.events, name); this.$delete(this.activeComponent.events, name);
this.makeDirty(); this.makeProjectDirty();
}, },
editBehavior(behavior, behaviors) { editBehavior(behavior, behaviors) {
this.$refs.behaviorEditorDialog.show(behavior, behaviors); events.$emit('edit-behavior', [{process: behavior}]);
},
handleBehaviorsChange(isPreview) {
if (isPreview) {
events.$emit('save-and-preview')
}
this.makeDirty();
}, },
onBehaviorNameChange(){ onBehaviorNameChange(){
this.makeDirty(); this.makeProjectDirty();
}, },
async deleteBehavior(index, behaviors) { async deleteBehavior(index, behaviors) {
let deleteMeta = false; let deleteMeta = false;
...@@ -172,7 +163,7 @@ ...@@ -172,7 +163,7 @@
}).then(() => { }).then(() => {
deleteMeta = true; deleteMeta = true;
this.makeDirty(); this.makeProjectDirty();
}).catch(action => { }).catch(action => {
if(action === 'close'){ if(action === 'close'){
close = true; close = true;
...@@ -194,7 +185,7 @@ ...@@ -194,7 +185,7 @@
'deleteBehaviorDirect', 'deleteBehaviorDirect',
]), ]),
...mapMutations([ ...mapMutations([
'makeDirty', 'makeProjectDirty',
]), ]),
} }
} }
......
...@@ -76,8 +76,6 @@ ...@@ -76,8 +76,6 @@
import {selectFile} from "../../utils"; import {selectFile} from "../../utils";
import events from "../../global-events"; import events from "../../global-events";
let PSD = window['require']('psd');
export default { export default {
name: 'Views', name: 'Views',
components: {Pane}, components: {Pane},
...@@ -95,6 +93,12 @@ ...@@ -95,6 +93,12 @@
nodeFilterPresets: this.$t('nodeFilterPresets'), nodeFilterPresets: this.$t('nodeFilterPresets'),
}; };
}, },
mounted() {
events.$on('locate-view-node', this.locateViewNode);
},
destroyed() {
events.$off('locate-view-node', this.locateViewNode);
},
computed: { computed: {
...mapGetters(['activeComponentId']), ...mapGetters(['activeComponentId']),
...mapState({ ...mapState({
...@@ -112,6 +116,10 @@ ...@@ -112,6 +116,10 @@
}, },
}, },
methods: { methods: {
locateViewNode(node) {
this.$refs.tree.setCurrentKey(node.uuid);
this.expandedKeys = [node.uuid];
},
updateFilter() { updateFilter() {
if (this.$refs.tree) { if (this.$refs.tree) {
this.$refs.tree.filter(this.filterText); this.$refs.tree.filter(this.filterText);
...@@ -191,11 +199,15 @@ ...@@ -191,11 +199,15 @@
this.filterText = filterText; this.filterText = filterText;
}, },
allowDrag(draggingNode) { allowDrag(draggingNode) {
return draggingNode.parent.parent; //return draggingNode.parent.parent;
return true;
}, },
allowDrop(draggingNode, dropNode, type) { allowDrop(draggingNode, dropNode, type) {
//console.log(dropNode.parent.parent, type); if(!draggingNode.parent.parent){ //根视图拖动
return !dropNode.parent.parent && type !== 'inner';
}else{
return dropNode.parent.parent || type === 'inner'; return dropNode.parent.parent || type === 'inner';
}
}, },
/** /**
* 点击左侧视图列表 * 点击左侧视图列表
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<div class="center full-size background" splitpanes-min="20" :splitpanes-size="70"> <div class="center full-size background" splitpanes-min="20" :splitpanes-size="70">
<div class="top-bar"> <div class="top-bar">
<edit-path :processStack="processStack" @pop="onPop"/> <edit-path :processStack="processStack" @pop="onPop"/>
<el-button icon="el-icon-search" circle plain size="mini" @click="onClickSearch"></el-button> <!--<el-button icon="el-icon-search" circle plain size="mini" @click="onClickSearch"></el-button>-->
</div> </div>
<!--<div class="operate-bar"> <!--<div class="operate-bar">
<el-button-group> <el-button-group>
...@@ -21,14 +21,17 @@ ...@@ -21,14 +21,17 @@
<el-button size="mini" icon="el-icon-zoom-in" @click="setScale(0.1)"/> <el-button size="mini" icon="el-icon-zoom-in" @click="setScale(0.1)"/>
</el-button-group> </el-button-group>
</div>--> </div>-->
<board ref="board" @select-process-node="onSelectProcessNode" @edit-process="editProcess" @edit-meta="onEditMeta"/> <board ref="board"
@select-process-node="onSelectProcessNode"
@edit-process="editProcess"
@translate-to-normal="onTranslateToNormal"
@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"/>
</div> </div>
</split-panes> </split-panes>
<meta-editor-dialog ref="metaEditorDialog" @input="onSaveMeta"/> <meta-editor-dialog ref="metaEditorDialog" @input="onSaveMeta"/>
<meta-search-dialog ref="metaSearchDialog"/>
</div> </div>
</template> </template>
...@@ -41,12 +44,10 @@ ...@@ -41,12 +44,10 @@
import EditPath from "./Board/EditPath"; import EditPath from "./Board/EditPath";
import Process from "./Board/Process"; import Process from "./Board/Process";
import MetaEditorDialog from "./MetaEditorDialog"; import MetaEditorDialog from "./MetaEditorDialog";
import events from "@/global-events.js"
import MetaSearchDialog from "./MetaSearchDialog";
export default { export default {
name: "BehaviorEditor", name: "BehaviorEditor",
components: {MetaSearchDialog, MetaEditorDialog, PropertiesEditor, EditPath, ProcessList, Board, SplitPanes,}, components: {MetaEditorDialog, PropertiesEditor, EditPath, ProcessList, Board, SplitPanes,},
props: [], props: [],
data() { data() {
return { return {
...@@ -62,8 +63,10 @@ ...@@ -62,8 +63,10 @@
] ]
}, },
...mapState({ ...mapState({
data: state => state.project.data,
behavior: state => state.behavior.currentBehavior, behavior: state => state.behavior.currentBehavior,
processStack: state=>state.behavior.processStack, processStack: state => state.behavior.processStack,
lastProcess: state => state.behavior.lastProcess,
}), }),
...mapGetters([ ...mapGetters([
'processTree', 'processTree',
...@@ -77,38 +80,50 @@ ...@@ -77,38 +80,50 @@
} }
} }
}, },
edit() { edit(path, index = 0) {
this.behavior_startEdit({
originData: this.data,
behavior: path[0].process,
});
this.clearProcessStack(); this.clearProcessStack();
let process = new Process(null, this.behavior, this.resolveProcess);
this.editProcess(process); let parent;
for (let i = 0; i <= index; i++) {
const item = path[i];
let subProcess = new Process(parent, item.process, this.resolveProcess);
this.pushProcessStack(subProcess);
parent = subProcess;
}
this.editProcess(parent, false);
}, },
onSelectProcessNode(process) { onSelectProcessNode(process) {
this.$refs.properties.edit(process); this.$refs.properties.edit(process);
}, },
editProcess(process) { editProcess(process, editStack = true) {
if (editStack) {
this.pushProcessStack(process); this.pushProcessStack(process);
}
this.$refs.board.edit(process, this.resolveProcess); this.$refs.board.edit(process, this.resolveProcess);
this.$refs.properties.edit(); this.$refs.properties.edit();
}, },
onPop(index) { onPop(index) {
this.popProcessStack(index + 1); this.popProcessStack(index + 1);
let process = this.processStack[this.processStack.length - 1]; let process = this.processStack[this.processStack.length - 1];
this.$refs.board.edit(process, this.resolveProcess); this.$refs.board.edit(process, this.resolveProcess, this.lastProcess);
this.$refs.properties.edit(); this.$refs.properties.edit();
}, },
onClickSearch(){ onEditMeta(meta, parentMeta) {
this.$refs.metaSearchDialog.show();
},
onEditMeta(meta) {
this.metaInEditing = meta; this.metaInEditing = meta;
this.$refs.metaEditorDialog.edit(meta); this.$refs.metaEditorDialog.edit(meta, parentMeta);
}, },
onDeleteMeta(meta) { onDeleteMeta(meta) {
const metaInUse = this.$store.getters.metaInUse(meta.id); const requirePaths = this.$store.getters.metaInUse(meta.id);
if (metaInUse.length > 0) { if (requirePaths.length > 0) {
console.log(metaInUse); let metas = requirePaths.map(path => {
let metas = metaInUse.map(meta=>`<b>→ ${meta.name}</b>`).join('<br>'); return path.map(meta => `<b>${(meta.name || meta.meta) + (meta.alias ? '[' + meta.alias + ']' : '')}</b>`).join(' > ')
this.$alert(metas, this.$t('Meta is in use, can not delete'),{ }).join('<br>');
this.$alert(metas, this.$t('Meta is in use, can not delete'), {
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
}) })
.catch((e) => { .catch((e) => {
...@@ -124,7 +139,7 @@ ...@@ -124,7 +139,7 @@
}); });
} }
}, },
onSaveMeta(meta,isPreview) { onSaveMeta(meta) {
let oldMetaID = this.metaInEditing.id; let oldMetaID = this.metaInEditing.id;
for (let key in meta) { for (let key in meta) {
this.metaInEditing[key] = meta[key]; this.metaInEditing[key] = meta[key];
...@@ -137,12 +152,16 @@ ...@@ -137,12 +152,16 @@
}); });
} }
this.$refs.board.updateProcessNode(meta.id); this.$refs.board.updateProcessNode(meta.id);
//是否预览 },
if(isPreview){ onTranslateToNormal(meta, parentMeta) {
events.$emit('behaviorSave',isPreview) this.$confirm(this.$t('Are you sure to translate to normal process?'), this.$t('Alert'))
} .then(() => {
this.translateToNormal({meta, parentMeta});
}).catch(e => {
})
}, },
...mapMutations([ ...mapMutations([
'behavior_startEdit',
'updateProcesses', 'updateProcesses',
'deleteProcessMeta', 'deleteProcessMeta',
'updatePropsEditable', 'updatePropsEditable',
...@@ -150,6 +169,7 @@ ...@@ -150,6 +169,7 @@
'pushProcessStack', 'pushProcessStack',
'popProcessStack', 'popProcessStack',
'setScale', 'setScale',
'translateToNormal',
]), ]),
...mapGetters([ ...mapGetters([
'metaInUse', 'metaInUse',
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<g id="nodes"> <g id="nodes">
<process-node v-for="(process, key, index) of subProcessMap" :ref="'pn_' + key" :process="process" <process-node v-for="(process, key, index) of subProcessMap" :ref="'pn_' + key" :process="process"
:key="index" :key="index"
@click="onClickProcessNode(process, key)" @click="selectProcessNode(process, key)"
@hover-pin="onPinHover" @hover-pin="onPinHover"
@leave-pin="onPinLeave" @leave-pin="onPinLeave"
@down-pin="onPinDown" @down-pin="onPinDown"
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
@edit-meta="onEditMeta" @edit-meta="onEditMeta"
@dblclick="editSubProcess(process)" @dblclick="editSubProcess(process)"
@meta-modified="onProcessMetaModified" @meta-modified="onProcessMetaModified"
@translate-to-normal="onTranslateToNormal"
/> />
</g> </g>
</g> </g>
...@@ -92,7 +93,9 @@ ...@@ -92,7 +93,9 @@
'setScale', 'setScale',
'makeBehaviorDirty', 'makeBehaviorDirty',
]), ]),
async edit(process, resolveProcess) { async edit(process, resolveProcess, lastProcess) {
//this.lastProcess = this.process;
this.boardOffset.x = 0; this.boardOffset.x = 0;
this.boardOffset.y = 0; this.boardOffset.y = 0;
this.setScale(0); this.setScale(0);
...@@ -107,6 +110,10 @@ ...@@ -107,6 +110,10 @@
this.updateSubProcess(); this.updateSubProcess();
this.measure(); this.measure();
this.$nextTick(function(){
this.selectProcessNode(lastProcess);
});
}, },
updateSubProcess() { updateSubProcess() {
this.subProcessMap = {}; this.subProcessMap = {};
...@@ -124,20 +131,40 @@ ...@@ -124,20 +131,40 @@
} }
}, },
showInlineChoose() { showInlineChoose() {
return this.$confirm(this.$t('As inline')); return this.$confirm(this.$t('As inline'), {
distinguishCancelAndClose: true,
});
}, },
async addSubProcessData(processId, pos) { async addSubProcessData(processId, pos) {
let meta, isInline; let meta, isInline;
if (customs.includes(processId)) { if (customs.includes(processId)) {
let name;
if (processId === 'custom') {//自定义过程必须输入名称
let result = await this.$prompt(this.$t('Input custom process name'), this.$t('Alert'), {
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
inputPattern: /^.{1,64}$/,
inputErrorMessage: this.$t('Invalid name'),
}).catch(e => {
});
if (result) {
name = result.value;
}
if (!name) {
return;
}
}
try { try {
await this.showInlineChoose(); await this.showInlineChoose();
isInline = true; isInline = true;
} catch (e) { } catch (action) {
if (action === 'close') {
return;
}
} }
meta = await this.addCustomProcessMeta({masterProcess: this.process, isInline, processId}); meta = await this.addCustomProcessMeta({masterProcess: this.process, isInline, processId, name});
} else { } else {
meta = this.process.resolveMeta(processId); meta = this.process.resolveMeta(processId);
} }
...@@ -146,8 +173,10 @@ ...@@ -146,8 +173,10 @@
try { try {
await this.showInlineChoose(); await this.showInlineChoose();
isInline = true; isInline = true;
} catch (e) { } catch (action) {
if (action === 'close') {
return;
}
} }
meta = await this.addProcessFromPrefab({masterProcess: this.process, isInline, meta}) meta = await this.addProcessFromPrefab({masterProcess: this.process, isInline, meta})
} }
...@@ -164,7 +193,6 @@ ...@@ -164,7 +193,6 @@
this.$set(this.process.meta, 'sub', {}); this.$set(this.process.meta, 'sub', {});
} }
this.$set(this.process.meta.sub, data.uuid, data); this.$set(this.process.meta.sub, data.uuid, data);
this.makeBehaviorDirty();
return data; return data;
}, },
onDragOver(e) { onDragOver(e) {
...@@ -174,8 +202,11 @@ ...@@ -174,8 +202,11 @@
} }
}, },
async onDrop(e) { async onDrop(e) {
const processId = e.dataTransfer.getData('process'); if(!this.editable){
return;
}
const processId = e.dataTransfer.getData('process');
if (processId === 'entry') { if (processId === 'entry') {
return; return;
} }
...@@ -188,6 +219,7 @@ ...@@ -188,6 +219,7 @@
return; return;
} }
this.addSubProcess(data.uuid, data); this.addSubProcess(data.uuid, data);
this.makeBehaviorDirty();
this.$nextTick(() => { this.$nextTick(() => {
events.$emit('update-dock-pin-pos'); events.$emit('update-dock-pin-pos');
...@@ -263,7 +295,7 @@ ...@@ -263,7 +295,7 @@
for (let key in process.data.output) { for (let key in process.data.output) {
let item = process.data.output[key]; let item = process.data.output[key];
let index = item.indexOf(outputID); let index = item.indexOf(outputID);
if(index >= 0){ if (index >= 0) {
item.splice(index, 1); item.splice(index, 1);
} }
} }
...@@ -321,10 +353,10 @@ ...@@ -321,10 +353,10 @@
this.$delete(this.process.meta.sub, process.uuid); this.$delete(this.process.meta.sub, process.uuid);
let remain = 0; let remain = 0;
for(let key in this.process.meta.sub){ for (let key in this.process.meta.sub) {
let p = this.process.meta.sub[key]; let p = this.process.meta.sub[key];
if (p.meta === meta.id) { if (p.meta === meta.id) {
remain ++; remain++;
} }
} }
...@@ -338,7 +370,7 @@ ...@@ -338,7 +370,7 @@
} }
if (meta.isDivider || meta.isInline) { //如果是分流节点或者内联节点还要删除对应的meta if (meta.isDivider || meta.isInline) { //如果是分流节点或者内联节点还要删除对应的meta
if(remain === 0){ if (remain === 0) {
this.deleteProcessMeta({ this.deleteProcessMeta({
meta, meta,
process: this.process, process: this.process,
...@@ -361,11 +393,14 @@ ...@@ -361,11 +393,14 @@
}); });
} }
}, },
onProcessNodeMove(data){ onProcessNodeMove(data) {
this.makeBehaviorDirty(); this.makeBehaviorDirty();
}, },
onEditMeta(data, meta) { onEditMeta(meta, parentMeta) {
this.$emit('edit-meta', meta); this.$emit('edit-meta', meta, parentMeta);
},
onTranslateToNormal(meta) {
this.$emit('translate-to-normal', meta, this.process.meta);
}, },
editSubProcess(process) { editSubProcess(process) {
if (!process.meta.isDivider && this.editable && (process.meta.type !== 'builtin' || process.meta.sub && Object.keys(process.meta.sub).length > 0)) { if (!process.meta.isDivider && this.editable && (process.meta.type !== 'builtin' || process.meta.sub && Object.keys(process.meta.sub).length > 0)) {
...@@ -387,13 +422,16 @@ ...@@ -387,13 +422,16 @@
} }
this.makeBehaviorDirty(); this.makeBehaviorDirty();
}, },
onClickProcessNode(process, uuid) { selectProcessNode(process) {
if(!process){
return;
}
for (let key in this.$refs) { for (let key in this.$refs) {
if (key.startsWith('pn_')) { if (key.startsWith('pn_')) {
const processNode = this.$refs[key][0]; const processNode = this.$refs[key][0];
if (processNode) { if (processNode) {
let hint = 'pn_' + uuid === key; let hint = 'pn_' + process.uuid === key;
processNode.setActive(hint); processNode.setActive(hint);
if (hint && this.selectedProcessNode !== processNode) { if (hint && this.selectedProcessNode !== processNode) {
this.selectedProcessNode = processNode; this.selectedProcessNode = processNode;
......
...@@ -10,16 +10,24 @@ export default class Process { ...@@ -10,16 +10,24 @@ export default class Process {
this.meta = typeof data.meta === 'string' ? this.resolveMeta(data.meta) : data.meta; this.meta = typeof data.meta === 'string' ? this.resolveMeta(data.meta) : data.meta;
} }
get data(){ get data() {
return this._data; return this._data;
} }
get parent() {
return this._parent;
}
get uuid() {
return this._data.uuid;
}
resolveMeta(id) { resolveMeta(id) {
let meta = this.meta && this.meta.metas ? this.meta.metas.find(meta=>meta.id === 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);
} }
if(!meta){ if (!meta) {
meta = this._resolveProcess(id); meta = this._resolveProcess(id);
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
@mouseenter="onMouseEnter" @mouseenter="onMouseEnter"
@mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick"> @mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick">
<div class="top-bar" v-if="meta.id !== 'entry' && editable"> <div class="top-bar" v-if="meta.id !== 'entry' && editable">
<el-link icon="el-icon-magic-stick" :underline="false" v-if="meta.isInline" @mousedown.stop.prevent @click.stop="onClickTranslate"/>
<el-link icon="el-icon-delete" :underline="false" @mousedown.stop.prevent @click.stop="onClickDelete"/> <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" <el-link icon="el-icon-edit" :underline="false" v-if="meta.type !== 'builtin' && !meta.isDivider"
@mousedown.stop.prevent @click.stop="onClickEdit"/> @mousedown.stop.prevent @click.stop="onClickEdit"/>
...@@ -248,11 +249,17 @@ ...@@ -248,11 +249,17 @@
this.$emit('down-pin', e, this.data, pin); this.$emit('down-pin', e, this.data, pin);
} }
}, },
onClickTranslate() {
this.$emit('translate-to-normal', this.meta);
},
onClickDelete() { onClickDelete() {
this.$confirm(this.$t('Are you sure to delete this process?'))
.then(()=>{
this.$emit('delete', this.data, this.meta); this.$emit('delete', this.data, this.meta);
}).catch(e=>{});
}, },
onClickEdit() { onClickEdit() {
this.$emit('edit-meta', this.data, this.meta); this.$emit('edit-meta', this.meta);
}, },
onClickCopy() { onClickCopy() {
this.$emit('copy', this.data, this.meta); this.$emit('copy', this.data, this.meta);
......
...@@ -63,7 +63,8 @@ ...@@ -63,7 +63,8 @@
size="mini" size="mini"
v-for="(option, key) in meta.props" v-for="(option, key) in meta.props"
:key="key" :key="key"
>{{ key }}</el-tag >{{ key }}
</el-tag
> >
</template> </template>
<template v-else>{{ $t("Empty") }}</template> <template v-else>{{ $t("Empty") }}</template>
...@@ -85,10 +86,11 @@ ...@@ -85,10 +86,11 @@
</template> </template>
</el-form> </el-form>
<div style="margin-top: 5px;"> <div style="margin-top: 5px;">
<code-sync-indicator /> <code-sync-indicator/>
<el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{ <el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{
item item
}}</el-tag> }}
</el-tag>
</div> </div>
<process-script-editor v-if="meta" :meta="meta"/> <process-script-editor v-if="meta" :meta="meta"/>
</div> </div>
...@@ -105,14 +107,16 @@ ...@@ -105,14 +107,16 @@
<div class="button-bar"> <div class="button-bar">
<el-button size="mini" plain @click="cancel">{{ <el-button size="mini" plain @click="cancel">{{
$t("Cancel") $t("Cancel")
}}</el-button> }}
</el-button>
<!--<el-button size="mini" plain @click="save(true)">{{$t('Save And Preview')}}</el-button>--> <!--<el-button size="mini" plain @click="save(true)">{{$t('Save And Preview')}}</el-button>-->
<el-button size="mini" type="primary" plain @click="save(false)">{{ <el-button size="mini" type="primary" @click="save(false)">{{
$t("Save") $t("Save")
}}</el-button> }}
</el-button>
</div> </div>
</div> </div>
<props-editor-dialog ref="propsEditorDialog" /> <props-editor-dialog ref="propsEditorDialog"/>
</el-dialog> </el-dialog>
</template> </template>
...@@ -126,7 +130,7 @@ ...@@ -126,7 +130,7 @@
const exposeVariables = ["args", "props", "target", "global", "vm", "engine", 'scope']; const exposeVariables = ["args", "props", "target", "global", "vm", "engine", 'scope'];
export default { export default {
name: "MetaEditorDialog", name: "MetaEditorDialog",
components: { components: {
ProcessScriptEditor, ProcessScriptEditor,
...@@ -141,8 +145,8 @@ export default { ...@@ -141,8 +145,8 @@ export default {
exposeVariables, exposeVariables,
rules: { rules: {
id: [{ required: true, trigger: "blur", }],//message: this.$t('ID required') id: [{required: true, trigger: "blur",}],//message: this.$t('ID required')
name: [{ required: true, trigger: "blur", }],//message: this.$t('Name required') name: [{required: true, trigger: "blur",}],//message: this.$t('Name required')
}, },
}; };
}, },
...@@ -174,7 +178,7 @@ export default { ...@@ -174,7 +178,7 @@ export default {
onClickEditProps() { onClickEditProps() {
this.$refs.propsEditorDialog.edit(this.meta.props); this.$refs.propsEditorDialog.edit(this.meta.props);
}, },
save(isPreview) { save() {
this.$refs.form.validate(valid => { this.$refs.form.validate(valid => {
if (valid) { if (valid) {
if ( if (
...@@ -184,9 +188,10 @@ export default { ...@@ -184,9 +188,10 @@ export default {
this.$alert( this.$alert(
this.$t("This Meta ID is in use, can not save"), this.$t("This Meta ID is in use, can not save"),
this.$t("Alert") this.$t("Alert")
).catch(e => {}); ).catch(e => {
});
} else { } else {
this.$emit("input", this.meta, isPreview); this.$emit("input", this.meta);
this.visible = false; this.visible = false;
} }
} else { } else {
...@@ -208,14 +213,15 @@ export default { ...@@ -208,14 +213,15 @@ export default {
if (metaStr) { if (metaStr) {
try { try {
this.meta = JSON.parse(metaStr); this.meta = JSON.parse(metaStr);
} catch (e) {} } catch (e) {
}
} }
}, },
focusPasteBoard() { focusPasteBoard() {
this.$refs.pasteBoard.focus(); this.$refs.pasteBoard.focus();
}, },
} }
}; };
</script> </script>
<style scoped></style> <style scoped></style>
<template>
<el-dialog :title="$t('Meta Search')" width="80%" :visible.sync="visible"
:append-to-body="true"
custom-class="behavior-editor-dialog"
>
<div style="padding: 10px;">
<el-input size="mini" v-model="keyword">
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
<div style="height: 50vh;">
</div>
</div>
<div slot="footer" class="dialog-footer">
<div></div>
<el-button size="mini" plain @click="close">{{$t('Close')}}</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: "MetaSearchDialog",
data() {
return {
visible: false,
keyword: '',
}
},
methods:{
show(){
this.visible = true;
},
close(){
this.visible = false;
},
search(){
},
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -70,10 +70,10 @@ ...@@ -70,10 +70,10 @@
}), }),
}, },
methods: { methods: {
transName(meta, node){ transName(meta, node) {
if(node.parent.parent){ if (node.parent.parent) {
return meta.name return meta.name
}else{ } else {
return this.$t('processGroups')[meta.name] || meta.name; return this.$t('processGroups')[meta.name] || meta.name;
} }
}, },
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
}, },
computed: { computed: {
...mapState({ ...mapState({
data: state => state.project.data,
showBadge: state => state.behavior.dirty, showBadge: state => state.behavior.dirty,
}), }),
}, },
...@@ -42,28 +41,24 @@ ...@@ -42,28 +41,24 @@
}); });
}, },
methods: { methods: {
show(behavior, behaviors) { show(path, index) {
this.behaviors = behaviors; this.path = path;
this.behavior_startEdit({ this.index = index;
originData: this.data, //this.behaviors = behaviors;
behavior,
});
this.editorReady = false; this.editorReady = false;
this.visible = true; this.visible = true;
}, },
async onSave(isPreview) { async onSave() {
const behavior = await this.behavior_save(); const behavior = await this.behavior_save();
for (let i = 0, li = this.behaviors.length; i < li; i++) { /*for (let i = 0, li = this.behaviors.length; i < li; i++) {
const b = this.behaviors[i]; const b = this.behaviors[i];
if (b.uuid === behavior.uuid) { if (b.uuid === behavior.uuid) {
this.$set(this.behaviors, i, behavior); this.$set(this.behaviors, i, behavior);
break; break;
} }
} }*/
this.$emit('change', isPreview); this.$emit('change');
if (!isPreview) {
this.visible = false; this.visible = false;
}
}, },
beforeClose(done) { beforeClose(done) {
if (this.$store.state.behavior.dirty) { if (this.$store.state.behavior.dirty) {
...@@ -93,12 +88,12 @@ ...@@ -93,12 +88,12 @@
onOpened() { onOpened() {
this.editorReady = true; this.editorReady = true;
this.$nextTick(() => { this.$nextTick(this.startEdit);
this.$refs.behaviorEditor.edit(); },
}); startEdit() {
this.$refs.behaviorEditor.edit(this.path, this.index);
}, },
...mapMutations([ ...mapMutations([
'behavior_startEdit',
'behavior_cancel', 'behavior_cancel',
]), ]),
...mapActions([ ...mapActions([
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
type="success" type="success"
@click="copyTpl(scope.row.packResult.tpl)" @click="copyTpl(scope.row.packResult.tpl)"
>{{$t('Copy skin')}}</el-button> >{{$t('Copy skin')}}</el-button>
<el-popconfirm :title="$t('Are sure to delete this item?')" <el-popconfirm :title="$t('Are you sure to delete this item?')"
@onConfirm="deleteItem(scope.row.id)" @onConfirm="deleteItem(scope.row.id)"
placement="top"> placement="top">
<el-button <el-button
......
<template>
<el-dialog :title="$t('Process Search')" width="80%" :visible.sync="visible"
:append-to-body="true"
custom-class="meta-search-dialog"
>
<div class="wrapper">
<div class="inputs">
<el-input class="input-keyword" size="mini" v-model="keyword" clearable @change="search">
<span slot="prepend">关键词</span>
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
<el-radio-group v-model="searchType">
<el-radio :label="1">{{$t('Name')}}</el-radio>
<el-radio :label="2">ID</el-radio>
<el-radio :label="3">{{$t('Code')}}</el-radio>
</el-radio-group>
</div>
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden">
<div v-for="(item, key) in paths" :key="key">
<template v-if="item.node">
<el-link type="success" icon="el-icon-aim" :underline="false" @click="clickMeta(item.node)">
{{item.node.name}}
</el-link>
<span> > </span>
</template>
<span v-for="(p, index) in item.path" :key="index">
<el-link type="primary" :underline="false" icon="el-icon-aim" @click="clickMeta(item.path, index)">
<span>{{p.metaName || p.process.meta}}</span>
<span v-if="p.process.alias">[{{p.process.alias}}]</span>
</el-link>
<!--<template v-if="meta.meta">
<span v-if="meta.meta">{{meta.meta}}
<span v-if="meta.alias">[{{meta.alias}}]</span>
</span>
</template>-->
<span v-if="index < item.path.length-1"> > </span>
</span>
</div>
</el-scrollbar>
</div>
<div slot="footer" class="dialog-footer">
<div></div>
<el-button size="mini" plain @click="close">{{$t('Close')}}</el-button>
</div>
</el-dialog>
</template>
<script>
import {mapGetters} from 'vuex'
import events from "@/global-events.js"
const searchFieldMap = [
'',
'name',
'id',
'script',
];
export default {
name: "ProcessSearchDialog",
data() {
return {
visible: false,
keyword: '',
searchType: 1,
paths: [],
}
},
computed: {
...mapGetters([
'searchProcess'
])
},
watch: {
searchType(){
this.search();
},
},
methods: {
show() {
this.visible = true;
},
close() {
this.visible = false;
},
search() {
if(this.keyword){
this.paths = this.searchProcess(this.keyword, searchFieldMap[this.searchType]);
}
},
clickMeta(path, index) {
if (index === undefined) { //view node
events.$emit('locate-view-node', path)
} else { //process
events.$emit('edit-behavior', path, index)
}
this.visible = false;
},
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
@click="copyUrl(scope.row)" @click="copyUrl(scope.row)"
>{{$t('Copy url')}} >{{$t('Copy url')}}
</el-button> </el-button>
<el-popconfirm :title="$t('Are sure to delete this item?')" <el-popconfirm :title="$t('Are you sure to delete this item?')"
@onConfirm="deleteItem(scope.row)" @onConfirm="deleteItem(scope.row)"
placement="top"> placement="top">
<el-button <el-button
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
}) })
}, },
methods: { methods: {
...mapMutations(["modifyProjectx", 'makeDirty']), ...mapMutations(["modifyProjectx", 'makeProjectDirty']),
edit() { edit() {
this.editData = clonePureObj(this.pxEnv); this.editData = clonePureObj(this.pxEnv);
}, },
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
this.modifyProjectx(this.editData); this.modifyProjectx(this.editData);
this.$emit('save'); this.$emit('save');
if (this.showBottomBar) { if (this.showBottomBar) {
this.makeDirty(); this.makeProjectDirty();
} }
}, },
getTpl(tpl) { getTpl(tpl) {
......
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