Commit fdaf0b39 authored by rockyl's avatar rockyl

项目列表分页问题

修复版本列表排序错乱的问题
版本列表排序问题
打包素材分组时,没有把link://的素材加载
完成行为独立编辑器
parent ed7bfeea
......@@ -251,6 +251,9 @@
"Next Conflict": "下一个冲突",
"To Verify": "去验证",
"Transform options": "转换参数",
"Save behavior successfully": "保存行为成功",
"The main editor is closed and cannot be saved": "主编辑器已关闭,无法保存",
"A behavior is being edited. Please save it first": "有行为正在编辑,请先保存",
"eventGroup": {
"in": "接收",
"out": "派发"
......@@ -359,6 +362,10 @@
"webgl": "WEBGL",
"canvas": "CANVAS"
},
"behaviorEditors": {
"builtin": "内建",
"standalone": "独立"
},
"pxEnvs": {
"dev": "开发环境",
"test": "测试环境",
......
......@@ -24,9 +24,9 @@ export default new Router({
component: () => import('./views/Preview.vue')
},
{
path: '/diff',
name: 'diff',
component: () => import('./views/ProjectDiff.vue')
path: '/process-editor',
name: 'process-editor',
component: () => import('./views/ProcessEditor.vue')
},
]
})
......@@ -7,8 +7,7 @@
import Vue from "vue";
import i18n from "../../i18n";
import generateUUID from "uuid/v4";
import {clonePureObj, getViewNodePath, findMetaDepById, searchViewNode, updateProcesses} from "../../utils";
import {arrayFind} from "element-ui/src/utils/util";
import {clonePureObj, findMetaDepById, searchViewNode, updateProcesses} from "../../utils";
export const behaviorStore = {
state: {
......@@ -35,13 +34,16 @@ export const behaviorStore = {
makeBehaviorDirty(state) {
state.dirty = true;
},
behavior_startEdit(state, {originData, behavior}) {
clearBehavior(state) {
state.dirty = false;
},
behavior_startEdit(state, {originData, behavior}) {
state.projectData = originData;
state.originProcesses = originData.processes;
state.processes = clonePureObj(originData.processes);
state.currentBehavior = clonePureObj(behavior);
this.commit('clearBehavior');
this.commit('updateCustomProcesses', state.processes);
},
behavior_save(state) {
......@@ -162,13 +164,12 @@ export const behaviorStore = {
if (uuid) {
return searchViewNode(state.projectData.views, uuid);
}
}
},
actions: {
behavior_save({commit, state}) {
commit('behavior_save');
return state.currentBehavior;
processesInEditor(state) {
return state.processes;
},
},
actions: {
addCustomProcessMeta({commit, state}, {masterProcess, isInline, processId, name}) {
let meta = {
id: generateUUID(),
......
......@@ -17,7 +17,7 @@ export const editorStore = {
state: {
initialized: false,
name: 'Zeroing Editor',
version: '0.2.0',
version: '0.2.1',
templates: {
builtin: ['blank'],
custom: [],
......
......@@ -4,10 +4,11 @@
import db from "../../utils/db-storage";
import {packageApi} from "../../api";
import maxSatisfying from "semver/ranges/max-satisfying";
import semverMaxSatisfying from "semver/ranges/max-satisfying";
import semverRSort from "semver/functions/rsort";
import i18n from "../../i18n";
import events from "@/global-events.js"
import {timeFormat, typeMapping} from "../../utils";
import {clonePureObj, timeFormat, typeMapping} from "../../utils";
const storeName = 'packages';
......@@ -30,15 +31,38 @@ export const packageStore = {
customProcesses: [],
},
mutations: {
resetPackageStore(state, sourceState) {
for (let key in sourceState) {
state[key] = sourceState[key];
}
},
updatePackageInfos(state, packageInfos) {
for (let i = 0, li = typeMapping.length; i < li; i++) {
state.packageInfos[typeMapping[i]].splice(0);
}
for (let packageInfo of packageInfos) {
packageInfo.versions = packageInfo.versions.split(',').reverse();
packageInfo.remarks = packageInfo.remarks.split(',').reverse();
packageInfo.update_times = packageInfo.update_times.split(',').map(time => timeFormat(time)).reverse();
packageInfo.update_time = timeFormat(packageInfo.update_time);
let {versions, remarks, update_times, update_time} = packageInfo;
versions = versions.split(',');
remarks = remarks.split(',');
update_times = update_times.split(',').map(time => timeFormat(time));
let sortedVersions = semverRSort(versions.concat());
let sortedRemarks = [];
let sortedUpdate_times = [];
for (let i = 0, li = sortedVersions.length; i < li; i++) {
const version = sortedVersions[i];
let index = versions.indexOf(version);
sortedRemarks[i] = remarks[index];
sortedUpdate_times[i] = update_times[index];
}
packageInfo.versions = sortedVersions;
packageInfo.remarks = sortedRemarks;
packageInfo.update_times = sortedUpdate_times;
packageInfo.update_time = timeFormat(update_time);
state.packageInfos[typeMapping[packageInfo.type]].push(packageInfo);
}
},
......
......@@ -31,6 +31,7 @@ const storeName = 'project';
const psStoreName = 'pack-history';
const defaultOptions = {
behaviorEditor: 'builtin',
pageTitle: 'no title',
entrySceneView: '',
loadingView: '',
......@@ -92,11 +93,14 @@ export const projectStore = {
},
makeProjectDirty() {
},
resetProjectData(state, data) {
state.data = data;
},
updateProjectUpdateTime(state, {time, dirty = true}) {
state.update_time = time;
if(dirty){
if (dirty) {
this.commit('makeProjectDirty');
}
},
......@@ -136,6 +140,10 @@ export const projectStore = {
localData.options.pxEnv = getDefaultOptions().pxEnv;
}
if (!localData.options.behaviorEditor) {
localData.options.behaviorEditor = 'builtin';
}
this.dispatch('fillLastVersion');
this.commit('updateAssetDep');
......@@ -543,7 +551,13 @@ export const projectStore = {
view.depCustoms = depCustoms;
this.commit('makeProjectDirty');
}
},
overwriteProcesses(state, {processes}) {
state.data.processes.splice(0);
state.data.processes.push(...processes);
this.commit('makeProjectDirty');
},
},
getters: {
project(state) {
......@@ -557,6 +571,9 @@ export const projectStore = {
data: JSON.stringify(newData),
};
},
behaviorEditor(state) {
return state.data.options.behaviorEditor;
},
menuBadge: (state) => (key) => {
let result = false;
switch (key) {
......
......@@ -4,11 +4,39 @@ $dock-pin-width: 9px;
.behavior-editor-dialog {
.process-pane {
}
.process-editor-dialog {
flex: 1;
display: flex;
flex-direction: column;
.editor-wrapper{
flex: 1;
display: flex;
}
.behavior-editor {
flex: 1;
}
.bottom-bar {
display: flex;
justify-content: space-between;
padding: 10px;
&>div{
*:not(:first-child){
margin-left: 5px;
}
}
}
}
.process-pane {
.process-tree {
}
.process-tree {
display: flex;
flex-direction: column;
......@@ -41,10 +69,10 @@ $dock-pin-width: 9px;
}
}
}
}
}
.behavior {
border: 1px solid $--border-color-base;
.behavior {
//border: 1px solid $--border-color-base;
.background {
background-color: $--background-color-base;
......@@ -324,7 +352,6 @@ $dock-pin-width: 9px;
}
}
}
}
}
.meta-editor-wrapper {
......
......@@ -25,7 +25,7 @@
</template>
<script>
import {mapState, mapActions, mapMutations} from 'vuex'
import {mapState, mapActions, mapMutations, mapGetters} from 'vuex'
import SplitPanes from 'splitpanes'
import ToolBar from "./Editor/ToolBar";
import Inspector from "./Editor/Inspector";
......@@ -33,7 +33,7 @@
import Playground from "./Editor/Playground";
import Assets from "./Editor/Assets";
import DetailsDialog from "./Editor/dialogs/DetailsDialog";
import {openPreview, playWaiting} from "../utils";
import {clonePureObj, openPreview, playWaiting} from "../utils";
import i18n from "../i18n";
import events from "@/global-events.js"
import db from "../utils/db-storage";
......@@ -92,8 +92,18 @@
operators: (state) => state.project.operators,
currentOperator: (state) => state.editor.operator,
}),
...mapGetters(['behaviorEditor'])
},
async mounted() {
if (!window.saveProcesses) {
window.saveProcesses = (processes)=> {
this.overwriteProcesses({processes});
this.$message({
message: this.$t('Save behavior successfully'),
type: 'success'
});
}
}
document.addEventListener('keydown', this.onKeyPress);
events.$on('save-and-preview', () => {
this.clickMenu("preview");
......@@ -238,7 +248,7 @@
async onConflictResolved(data) {
const {projectID, project} = this.$route.params;
let cancel = await this.saveProject(true, data);
if(!cancel){
if (!cancel) {
this.loadRemoteVersion(projectID, project, undefined, data);
}
},
......@@ -385,12 +395,46 @@
this.$refs.missingPackagesDialog.show(missingPackages);
},
editBehavior(path, index) {
switch (this.behaviorEditor) {
case 'builtin':
this.$refs.behaviorEditorDialog.show(path, index);
break;
case 'standalone':
this.onOpenStandalone(path, index);
break;
}
},
onOpenStandalone(path, index) {
let processEditorUrl = location.href.substr(0, location.href.indexOf('#')) + '#/process-editor';
let processEditorWin = this.processEditorWin = open(processEditorUrl, 'Process Editor', 'width=800, height=600');
if (processEditorWin.reset) {
if(processEditorWin.editable()){
this.showStandaloneEditor(path, index);
}else{
this.$message({
message: this.$t('A behavior is being edited. Please save it first'),
type: 'warning'
});
}
} else {
processEditorWin.onload = () => {
this.showStandaloneEditor(path, index);
}
}
},
showStandaloneEditor(path, index) {
let processEditorWin = this.processEditorWin;
let projectData = clonePureObj(this.$store.state.project.data);
let packageState = clonePureObj(this.$store.state.project.package);
processEditorWin.reset({projectData, packageState});
processEditorWin.edit(path, index);
},
handleBehaviorsChange() {
this.makeProjectDirty();
},
...mapMutations(['makeProjectDirty']),
...mapMutations(['makeProjectDirty', 'overwriteProcesses']),
...mapActions([
'loadPackages',
'localVersionExist',
......
......@@ -4,7 +4,7 @@
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick">
<div class="top-bar" v-if="meta.id !== 'entry' && editable">
<el-link icon="el-icon-magic-stick" :underline="false" v-if="meta.type !== 'builtin'" @mousedown.stop.prevent @click.stop="onClickTransform"/>
<el-link icon="el-icon-magic-stick" :underline="false" v-if="false && meta.type !== 'builtin'" @mousedown.stop.prevent @click.stop="onClickTransform"/>
<el-link icon="el-icon-delete" :underline="false" @mousedown.stop.prevent @click.stop="onClickDelete"/>
<el-link icon="el-icon-edit" :underline="false" v-if="meta.type !== 'builtin' && !meta.isDivider"
@mousedown.stop.prevent @click.stop="onClickEdit"/>
......
......@@ -4,7 +4,9 @@
:append-to-body="true" custom-class="flex-dialog behavior-editor-dialog">
<behavior-editor v-if="editorReady" ref="behaviorEditor" class="full-size"></behavior-editor>
<div slot="footer" class="dialog-footer">
<div></div>
<div>
</div>
<div>
<!--<el-button size="mini" @click="onSave(true)">{{$t('Save And Preview')}}</el-button>
<el-button size="mini" type="primary" @click="onSave(false)">{{$t('Save And Close')}}</el-button>-->
......@@ -20,6 +22,7 @@
import {mapState, mapMutations, mapActions} from 'vuex'
import BehaviorEditor from "../behavior-editor/BehaviorEditor";
import events from "@/global-events.js"
import {clonePureObj} from "../../../utils";
export default {
name: "BehaviorEditorDialog",
......@@ -49,7 +52,7 @@
this.visible = true;
},
async onSave() {
const behavior = await this.behavior_save();
this.behavior_save();
/*for (let i = 0, li = this.behaviors.length; i < li; i++) {
const b = this.behaviors[i];
if (b.uuid === behavior.uuid) {
......@@ -95,8 +98,6 @@
},
...mapMutations([
'behavior_cancel',
]),
...mapActions([
'behavior_save',
])
}
......
......@@ -2,6 +2,15 @@
<el-scrollbar v-if="editData" class="project-scrollbar" wrap-class="wrap-x-hidden" view-class="project-editor">
<el-form @submit.native.prevent ref="form" :model="editData" size="mini" label-position="right"
label-width="150px">
<el-form-item prop="behaviorEditor" :label="$t('Behavior Editor')">
<el-select v-model="editData.behaviorEditor">
<el-option v-for="(label, key) in behaviorEditors"
:key="key"
:value="key"
:label="label"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="pageTitle" :label="$t('Page title')">
<el-input v-model="editData.pageTitle"/>
</el-form-item>
......@@ -83,12 +92,14 @@
data() {
const scaleMode = this.$t('scaleMode');
const rendererType = this.$t('rendererType');
const behaviorEditors = this.$t('behaviorEditors');
return {
visible: false,
editData: null,
scaleMode,
rendererType,
monacoEditorOptions,
behaviorEditors,
}
},
computed: {
......
<template>
<div class="process-editor-dialog">
<div class="editor-wrapper">
<behavior-editor v-if="editorReady" ref="behaviorEditor" class="behavior-editor"></behavior-editor>
</div>
<div class="bottom-bar">
<div>
</div>
<div>
<el-button size="mini" type="danger" @click="onClose()">{{$t('Close')}}</el-button>
<el-badge :hidden="!showBadge" is-dot>
<el-button size="mini" type="primary" @click="onSave()">{{$t('Save')}}</el-button>
</el-badge>
</div>
</div>
</div>
</template>
<script>
import {mapMutations, mapState, mapGetters} from 'vuex'
import BehaviorEditor from "./Editor/behavior-editor/BehaviorEditor";
import {clonePureObj} from "../utils";
export default {
name: "ProcessEditor",
components: {BehaviorEditor},
data() {
return {
editorReady: false,
}
},
mounted() {
window.reset = ({projectData, packageState}) => {
console.log('reset');
this.resetProjectData(projectData);
this.resetPackageStore(packageState);
};
window.editable = () => {
return !this.showBadge;
};
window.edit = (path, index) => {
this.edit(path, index);
};
window.onbeforeunload = (e) => {
return this.showBadge ? true : null;
};
},
computed: {
...mapState({
showBadge: state => state.behavior.dirty,
}),
...mapGetters(['processesInEditor'])
},
methods: {
edit(path, index) {
this.path = path;
this.index = index;
this.editorReady = true;
this.$nextTick(this.startEdit);
},
startEdit() {
this.$refs.behaviorEditor.edit(this.path, this.index);
},
async onSave() {
if (!this.showBadge) {
return;
}
let opener;
try {
if (window.opener && window.opener.saveProcesses) {
opener = window.opener;
}
} catch (e) {
}
if (opener) {
let processes = clonePureObj(this.processesInEditor);
window.opener.saveProcesses(processes);
this.clearBehavior();
/*this.$message({
message: this.$t('Save behavior successfully'),
type: 'success'
});*/
} else {
this.$alert(this.$t('The main editor is closed and cannot be saved'));
}
},
onClose() {
if (this.showBadge) {
this.$confirm(this.$t('Save this behavior before'), this.$t('Alert'), {
closeOnClickModal: false,
closeOnPressEscape: false,
confirmButtonText: this.$t('Save And Close'),
cancelButtonText: this.$t('Still Close'),
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
this.onSave();
this.close();
}).catch((action) => {
switch (action) {
case 'close':
break;
case 'cancel':
this.close();
break;
}
});
} else {
this.close();
}
},
close() {
window.close();
},
...mapMutations(['clearBehavior', 'resetProjectData', 'resetPackageStore', 'behavior_save'])
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<monaco-editor
class="script-editor"
ref="editor"
v-model="code"
language="json"
:options="monacoEditorOptions"
diff-editor
:original="originalCode"
/>
</template>
<script>
import MonacoEditor from "vue-monaco";
import {monacoEditorOptions} from "../utils";
//import old from './old.json'
//let originalCode = JSON.stringify(old, null, '\t');
let originalCode = `hello`;
console.log(originalCode);
export default {
name: "ProjectDiff",
components: {MonacoEditor},
data() {
return {
monacoEditorOptions,
code: '',
originalCode,
}
},
mounted() {
let editor = this.$refs.editor.getEditor();
editor.onDidUpdateDiff(()=>{
let m = editor.getLineChanges();
console.log(m);
})
}
}
</script>
<style scoped>
.script-editor{
width: 100%;
}
</style>
\ No newline at end of file
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