Commit 5b53ad72 authored by 张晨辰's avatar 张晨辰

feat: merge

parents e406eaeb 596fe898
No preview for this file type
{
"success": true,
"data": {
"id": "6e1c9eadf8e28",
"name": "测试",
"id": "6566c4a3f237",
"name": "呼呼",
"creator": "卞龙亭",
"operator": "卞龙亭",
"create_time": "2019-09-19T06:56:01.000Z",
"update_time": "2019-09-19T06:56:01.000Z",
"data": "{\"views\":[{\"name\":\"view1\",\"children\":[{\"name\":\"label\"},{\"name\":\"image\"}]},{\"name\":\"view2\"}],\"assets\":[{\"name\":\"bg.jpg\",\"url\":\"/bg.jpg\"},{\"name\":\"btn-join.png\",\"url\":\"/btn-join.png\"}]}"
"data": "{\"views\":[{\"name\":\"aaa\",\"type\":\"node\",\"children\":[{\"name\":\"node\",\"type\":\"image\"}]},{\"name\":\"aaa\",\"type\":\"node\",\"children\":[{\"name\":\"node\",\"type\":\"node\"},{\"name\":\"node\",\"type\":\"node\"}]}],\"assets\":[{\"name\":\"2ACA84D91EAAE90EDBFF78CBF5E727AB.png\",\"url\":\"//yun.duiba.com.cn/aurora/58323a0469a7467c99b34f8933ea65b507a0c655.png\",\"uuid\":\"3e496939-5fe6-42f2-b8fa-42c7a742e880\"},{\"name\":\"还以为是bug.jpg\",\"url\":\"//yun.duiba.com.cn/aurora/094832ace87c94bdb9e4a7821b3a3ebca0df2cd7.jpg\",\"uuid\":\"ec67a8a0-8708-43a4-888e-efb0fe7c2bd6\"},{\"name\":\"17344D055C89C3CFADB0C51E1A1E064E.gif\",\"url\":\"//yun.duiba.com.cn/aurora/1ad10a4cf3488ef1400af1d6f353d9c577fe1049.gif\",\"uuid\":\"429803eb-0f68-4071-b68c-468980883ac4\"}],\"dataMapping\":[]}"
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@
},
"dependencies": {
"cookie": "^0.4.0",
"copy-to-clipboard": "^3.2.0",
"core-js": "^2.6.5",
"duiba-draggable-resizable": "^1.0.9",
"element-ui": "^2.4.5",
......@@ -15,6 +16,7 @@
"path": "^0.12.7",
"querystringify": "^2.1.1",
"splitpanes": "^1.14.5",
"string-width": "^4.1.0",
"uuid": "^3.3.3",
"vue": "^2.6.10",
"vue-i18n": "^8.0.0",
......
......@@ -42,7 +42,7 @@
this.timer = setInterval(() => {
if (this.cd <= 0) {
clearInterval(this.timer);
this.$router.push({name: 'home'});
this.$router.replace({name: 'home'});
return;
}
this.cd--;
......
<template>
<p>{{ $t('hello') }}</p>
</template>
<script>
export default {
name: 'HelloI18n'
}
</script>
<i18n>
{
"en": {
"hello": "Hello i18n in SFC!"
}
}
</i18n>
<template>
<div class="menu">
<el-link @click="clickItem(key)" v-for="(item, key) of data" :key="key" :icon="item.icon">
<el-badge class="menu-item" v-for="(item, key) of data" :key="key" is-dot :hidden="!menuBadge(key)">
<el-link @click="clickItem(key)" :icon="item.icon">
{{item.text}}
</el-link>
</el-badge>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "SampleMenu",
props: ['data'],
data() {
return {}
},
computed: {
...mapGetters([
'menuBadge',
]),
},
methods: {
clickItem(key) {
this.$emit('click-menu', key);
......
......@@ -2,7 +2,10 @@
"Alert": "Alert",
"Confirm": "Confirm",
"Cancel": "Cancel",
"Close": "Close",
"Save": "Save",
"Copy": "Copy",
"Exit": "Exit",
"Add": "Add",
"Delete": "Delete",
"Import": "Import",
......@@ -15,6 +18,7 @@
"No projects": "No projects",
"Create": "Create",
"Project details": "Project details",
"Project does not exist": "Project does not exist",
"Project name": "Project name",
"Data mapping": "Data mapping",
"Template": "Template",
......@@ -22,6 +26,9 @@
"Deleting": "Deleting…",
"Saving": "Saving…",
"Create project": "Create project",
"Rename project": "Rename project",
"Input project name": "Input project name",
"Invalid project name": "Invalid project name",
"Creating project": "Creating project…",
"Create project success": "Create project success",
"Duplicate project": "Duplicate project",
......@@ -44,9 +51,15 @@
"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 asset": "Are you sure to delete this asset",
"Are you sure to delete this link": "Are you sure to delete this link",
"Rename asset": "Rename asset",
"Input asset name": "Input asset name",
"Invalid asset name": "Invalid asset name",
"Copied field to clipboard": "Copied {field} to clipboard",
"Unsaved Alert": "You are leaving, but the project is not saved. Do you want to save it?",
"menu": {
"save": "Save",
"details": "Details",
"preview": "Preview",
"publish": "Publish",
"data-mapping": "DataMapping",
......
......@@ -23,9 +23,15 @@ export default new Vuex.Store({
plugins: [
SaveToLocalPlugin({
mutationTypes: [
'modifyProject',
'addNode',
'deleteNode',
'addAsset',
'deleteAsset',
'modifyAsset',
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
]
})
]
......
......@@ -5,6 +5,7 @@ import Vue from "vue";
import { projectApi } from "../../api";
import { compoleteComponentData } from '../../utils/compoleteCmpData';
import path from "path";
import generateUUID from "uuid/v4";
export const projectStore = {
......@@ -18,14 +19,13 @@ export const projectStore = {
dataMapping: [],
},
activeComponent: {},
activeIdList: []
activeIdList: [],
dirty: false,
},
mutations: {
/**
* 更新state中的data
* @param {*} state
* @param {*} project
*/
setDirty(state, dirty = true) {
state.dirty = dirty;
},
updateProject(state, project) {
const { id, name, creator, data } = project;
state.id = id;
......@@ -66,6 +66,9 @@ export const projectStore = {
state.activeComponent = id;
state.activeIdList = [id];
console.log('mutations activeComponent', state);
},
modifyProject(state, ) {
},
addNode(state, { node, name, type }) {
const child = {
......@@ -87,12 +90,46 @@ export const projectStore = {
},
addAsset(state, { url, file }) {
const ext = path.extname(file.name);
state.data.assets.push({
name: file.name,
name: path.basename(file.name, ext),
ext,
url,
uuid: generateUUID(),
})
},
deleteAsset(state, uuid) {
const { assets } = state.data;
for (let i = 0, li = assets.length; i < li; i++) {
const asset = state.data.assets[i];
if (asset.uuid === uuid) {
assets.splice(i, 1);
break;
}
}
},
modifyAsset(state, asset) {
},
addDataMapping(state, link) {
if (link) {
state.data.dataMapping.push(link);
} else {
state.data.dataMapping.push({
name: '',
path: '',
});
}
},
deleteDataMapping(state, index) {
state.data.dataMapping.splice(index, 1);
},
modifyDataMapping(state) {
},
},
getters: {
project(state) {
......@@ -102,6 +139,15 @@ export const projectStore = {
data: JSON.stringify(data),
};
},
menuBadge: (state) => (key) => {
let result = false;
switch (key) {
case 'save':
result = state.dirty;
break;
}
return result;
},
/**
* 当前激活的组件
*/
......@@ -133,10 +179,11 @@ export const projectStore = {
}
},
actions: {
saveToLocal({ getters }) {
saveToLocal({ getters, commit }) {
const { project } = getters;
localStorage.setItem('project-' + project.id, JSON.stringify(project));
commit('setDirty', true);
},
localVersionExist({ commit }, projectID) {
let json = localStorage.getItem('project-' + projectID);
......@@ -147,15 +194,21 @@ export const projectStore = {
if (json) {
const project = JSON.parse(json);
commit('updateProject', project);
commit('setDirty', true);
}
},
deleteLocalVersion({ state }, projectID) {
deleteLocalVersion({ state, commit }, projectID) {
localStorage.removeItem('project-' + projectID);
commit('setDirty', false);
},
async loadFromRemote({ commit, dispatch }, projectID) {
const project = await projectApi.fetchOne(projectID);
if (project) {
dispatch('deleteLocalVersion', projectID);
commit('updateProject', project);
} else {
throw new Error('Project does not exist')
}
},
async saveToRemote({ state, dispatch, getters }) {
await projectApi.saveOne(getters.project);
......
......@@ -26,15 +26,27 @@
flex-wrap: wrap;
.file-item {
width: 60px;
padding: 5px;
color: $--color-text-regular;
&:hover {
& > .icon > .operate-bar {
display: block;
}
& > .name > .full-name {
display: block;
}
}
.icon {
width: 60px;
width: 100%;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.thumbnail {
max-width: 60px;
......@@ -44,14 +56,48 @@
.file-icon {
font-size: 60px;
}
.operate-bar {
display: none;
position: absolute;
right: 1px;
bottom: 1px;
.el-button {
padding: 2px;
margin-left: 2px;
}
}
}
.name {
text-align: center;
font-size: 12px;
width: 60px;
overflow: hidden;
position: relative;
margin-top: 2px;
span {
word-break: break-all;
overflow:hidden;
text-overflow: ellipsis;
display:-webkit-box;
-webkit-line-clamp:2;
-webkit-box-orient:vertical;
}
.full-name {
display: none;
position: absolute;
top: 0;
left: 0;
background-color: $--color-text-secondary;
color: $--color-white;
border-radius: 5px;
padding: 2px;
z-index: 2;
width: 95%;
line-height: 17px;
}
}
}
......@@ -80,6 +126,10 @@
width: 100%;
flex: 1;
}
.scrollbar-view{
padding-bottom: 5px;
}
}
}
......@@ -96,28 +146,25 @@
align-items: center;
padding: 30px;
.close-button{
.close-button {
align-self: flex-end;
}
.name-bar {
margin-top: 5px;
color: $--color-white;
align-self: stretch;
.item{
display: flex;
.el-tag {
width: 40px;
text-align: right;
margin-right: 5px;
.item + .item{
margin-top: 5px;
}
.value{
width: 0;
flex: 1;
overflow-wrap: break-word;
.item{
.field{
width: 30px;
display: block;
}
}
}
.big-image {
......@@ -130,6 +177,11 @@
}
}
.image-info{
color: $__color-white;
font-size: 12px;
}
.operate-bar {
}
......
......@@ -16,12 +16,21 @@
padding: 5px 10px;
font-size: 13px;
.menu{
.menu {
flex: 1;
a:not(:first-child){
.menu-item + .menu-item {
margin-left: 10px;
}
}
.right-part{
color: $--color-text-regular;
.el-button{
padding: 2px;
}
}
}
.pane-container {
......@@ -29,6 +38,53 @@
}
}
.bottom-bar, .toolbar{
.bottom-bar, .toolbar {
background-color: $--pane-background-color;
}
.data-mapping-dialog {
height: 200px;
display: flex;
flex-direction: column;
button{
align-self: flex-start;
}
.scrollbar{
flex: 1;
.view{
padding-right: 10px;
}
.item + .item{
margin-top: 10px;
}
.item{
display: flex;
align-items: center;
&:hover{
& > button{
visibility: visible;
}
}
.el-icon-connection{
padding: 0 5px;
}
button{
margin-left: 5px;
visibility: hidden;
}
}
}
}
.project-details-dialog {
}
\ No newline at end of file
/**
* Created by rockyl on 2019-09-19.
*/
import { Message, Loading } from "element-ui";
import i18n from './i18n'
export function messageError(e) {
Message({
dangerouslyUseHTMLString: true,
message: `<p style="margin-bottom: 5px;"><strong>${i18n.t(e.message)}</strong></p><p>${e.name}</p>`,
type: 'error'
})
}
export function playWaiting(promise, text) {
const loading = Loading.service({
lock: true,
text: text || i18n.t('In processing'),
});
return promise.catch(e => {
messageError(e);
throw e;
}).finally(() => {
loading.close();
})
}
\ No newline at end of file
......@@ -31,3 +31,17 @@ export function playWaiting(promise, text) {
export function guid() {
return `xy-${generateUUID()}`;
}
export function strEllipsis(str, maxLength = 0, rightOffset = 0) {
let result = str;
let strLen = str.length;//stringWidth(str);
if (strLen > maxLength) {
strLen += 1; //还有一个省略号占1个半角
let leftPart = str.substr(0, maxLength - rightOffset);
let rightPart = str.substr(strLen - rightOffset);
result = leftPart + '…' + rightPart;
}
return result;
}
......@@ -17,18 +17,19 @@
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import SplitPanes from 'splitpanes';
import ToolBar from './Editor/ToolBar';
import Inspector from './Editor/Inspector';
import Views from './Editor/Views';
import Playground from './Editor/Playground';
import Assets from './Editor/Assets';
import ProjectDetailsDialog from './Editor/dialogs/ProjectDetailsDialog';
import DataMappingDialog from './Editor/dialogs/DataMappingDialog';
import { playWaiting } from '../utils';
import {mapGetters, mapActions} from 'vuex'
import SplitPanes from 'splitpanes'
import ToolBar from "./Editor/ToolBar";
import Inspector from "./Editor/Inspector";
import Views from "./Editor/Views";
import Playground from "./Editor/Playground";
import Assets from "./Editor/Assets";
import ProjectDetailsDialog from "./Editor/dialogs/ProjectDetailsDialog";
import DataMappingDialog from "./Editor/dialogs/DataMappingDialog";
import {playWaiting} from "../utils";
import i18n from "../i18n";
export default {
export default {
name: 'Editor',
components: {
DataMappingDialog,
......@@ -38,19 +39,19 @@ export default {
Views,
Inspector,
ToolBar,
SplitPanes
SplitPanes,
},
data() {
const panesConfig = localStorage.panesConfig ? JSON.parse(localStorage.panesConfig) : [0.8, 0.8, 0.3];
return {
panesConfig
};
panesConfig,
}
},
computed: {
...mapGetters([])
...mapGetters([]),
},
async mounted() {
const { projectID } = this.$route.params;
const {projectID} = this.$route.params;
if (await this.localVersionExist(projectID)) {
this.$confirm(this.$t('Unsaved version found locally'), this.$t('Alert'), {
showClose: false,
......@@ -59,11 +60,9 @@ export default {
confirmButtonText: this.$t('Local Version'),
cancelButtonText: this.$t('Remote Version'),
type: 'warning'
})
.then(() => {
}).then(() => {
this.loadLocalVersion(projectID);
})
.catch(e => {
}).catch((e) => {
if (e === 'cancel') {
this.loadRemoteVersion(projectID);
} else {
......@@ -76,33 +75,44 @@ export default {
},
methods: {
loadLocalVersion(projectID) {
this.loadFromLocal(projectID);
this.loadFromLocal(projectID)
},
loadRemoteVersion(projectID) {
if (projectID) {
playWaiting(this.loadFromRemote(projectID), this.$t('Preparing')).catch(e => {});
playWaiting(this.loadFromRemote(projectID), this.$t('Preparing')).catch(e => {
this.$alert(this.$t('Project does not exist'), this.$t('Alert'), {
confirmButtonText: this.$t('Confirm'),
callback: action=>{
this.$router.replace({name: 'home'});
}
});
});
} else {
this.$router.push({ name: 'home' });
this.$router.push({name: 'home'})
}
},
getSize(id, side) {
let ratio = this.panesConfig[id];
return (side === 0 ? ratio : 1 - ratio) * 100;
return (side === 0 ? ratio : 1 - ratio) * 100
},
onPanesReSized(id, configs) {
this.panesConfig[id] = configs[0].width / 100;
localStorage.panesConfig = JSON.stringify(this.panesConfig);
},
async clickMenu(menuItem) {
switch (menuItem) {
case 'save':
try {
async saveProject() {
await playWaiting(this.saveToRemote(), this.$t('Saving'));
this.$message({
message: this.$t('Save project successfully'),
message: i18n.t('Save project successfully'), //因为message是异步出现,但是当路由回退的时候,this.i18n的实例已经置空,所以要用全局的i18n实例
type: 'success'
});
} catch (e) {}
},
async clickMenu(menuItem) {
switch (menuItem) {
case 'save':
try {
this.saveProject();
} catch (e) {
}
break;
case 'details':
this.$refs.projectDialogsDialog.show();
......@@ -111,40 +121,39 @@ export default {
this.$refs.dataMappingDialog.show();
break;
case 'exit':
this, exitConfirm();
break;
case 'publish':
this.publishConfirm();
break;
}
},
/**
* 退出
*/
async exitConfirm() {
await this.$confirm(this.$t('Confirm to exit the editor'), {
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancle'),
const {projectID} = this.$route.params;
if (await this.localVersionExist(projectID)) {
this.$confirm(this.$t('Unsaved Alert'), this.$t('Alert'), {
confirmButtonText: this.$t('Save'),
cancelButtonText: this.$t('Exit'),
type: 'warning'
}).then(() => {
try {
this.saveProject();
this.backToHome();
} catch (e) {
}
}).catch((e) => {
this.backToHome();
});
// todo
// exit
} else {
this.backToHome();
}
break;
}
},
/**
* 发布
*/
async publishConfirm() {
await this.$confirm(this.$t('Confirm to publish'), {
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancle'),
type: 'warning'
});
// todo
// publish
backToHome() {
this.$router.replace({name: 'home'});
},
...mapActions(['localVersionExist', 'loadFromLocal', 'loadFromRemote', 'saveToLocal', 'saveToRemote'])
...mapActions([
'localVersionExist',
'loadFromLocal',
'loadFromRemote',
"saveToLocal",
"saveToRemote",
])
}
}
};
</script>
<style lang="scss">
......
<template>
<pane class="assets" icon="el-icon-s-shop" :title="$t('panes.Assets')">
<div class="container">
<div class="header-bar">
<!--<div class="header-bar">
<el-link>{{$t('Upload')}}</el-link>
</div>
<el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden">
</div>-->
<el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden" view-class="scrollbar-view">
<div class="file-list">
<el-upload
class="file-uploader"
......@@ -17,7 +17,7 @@
>
<i class="el-icon-plus file-uploader-icon"></i>
</el-upload>
<file-item v-for="file in assets" :data="file" :key="file.url" @show-file-details="showFileDetails"/>
<file-item v-for="(file, index) in assets" :data="file" :key="index + '_' + file.url" @show-file-details="showFileDetails"/>
</div>
</el-scrollbar>
</div>
......@@ -55,7 +55,7 @@
},
uploadFileSuccess(response, file){
if(response.success){
console.log('upload success', response, file);
//console.log('upload success', response, file);
this.addAsset({
url: response.url,
file,
......
......@@ -12,19 +12,21 @@
<div class="wrapper">
<el-button class="close-button" size="mini" circle icon="el-icon-close" @click="hide"></el-button>
<div class="name-bar">
<div class="item">
<el-tag size="mini" type="success">name</el-tag>
<span class="value">{{file.name}}</span>
<el-input size="mini" class="item" v-model="file.name" readonly>
<template slot="prepend"><span class="field">name</span></template>
<el-button slot="append" icon="el-icon-document-copy" @click="copyValue('name')"></el-button>
</el-input>
<el-input size="mini" class="item" v-model="file.url" readonly>
<template slot="prepend"><span class="field">url</span></template>
<el-button slot="append" icon="el-icon-document-copy" @click="copyValue('url')"></el-button>
</el-input>
</div>
<div class="item">
<el-tag size="mini" type="success">url</el-tag>
<span class="value">{{file.url}}</span>
<el-image class="big-image" :src="imageUrl" fit="contain" @load="onImageLoaded"/>
<div class="image-info">
<span class="size">{{size}}</span>
</div>
</div>
<el-image class="big-image" :src="imageUrl" fit="contain"/>
<div class="operate-bar">
<el-button-group>
<el-button size="mini" icon="el-button-loading">复制</el-button>
</el-button-group>
</div>
</div>
......@@ -34,6 +36,7 @@
</template>
<script>
import copy from 'copy-to-clipboard'
export default {
name: "AssetsShow",
......@@ -41,10 +44,16 @@
return {
visible: false,
file: null,
size: '',
}
},
watch: {
file(){
this.size = '';
}
},
computed: {
imageUrl(){
imageUrl() {
return this.file.url;
},
},
......@@ -66,9 +75,21 @@
afterLeave() {
this.$emit('closed');
},
handleWrapperClick(){
handleWrapperClick() {
this.hide();
},
copyValue(field) {
copy(this.file[field]);
this.$message({
message: this.$t('Copied field to clipboard', {field}),
type: 'success',
duration: 700,
});
},
onImageLoaded(e) {
const {width, height} = e.target;
this.size = width + ' x ' + height;
}
}
}
</script>
......
<template>
<div class="file-item" @dblclick="onDbclick()">
<div class="file-item">
<div class="icon">
<i v-if="!showThumbnail" class="file-icon" :class="fileIcon"></i>
<img v-if="showThumbnail" class="thumbnail" :src="thumbnailUrl" alt="thumb">
<img v-if="showThumbnail" class="thumbnail" :src="thumbnailUrl" alt="thumb" @dblclick="onDbclick()">
<div class="operate-bar">
<el-button circle size="mini" type="success" icon="el-icon-edit" @dblclick.native.stop @click="onClickEdit"/>
<el-button circle size="mini" type="danger" icon="el-icon-delete" @dblclick.native.stop
@click="onClickDelete"/>
</div>
</div>
<div class="name">
<span>{{data.name}}</span>
<span class="full-name">{{data.name}}</span>
</div>
</div>
</template>
<script>
import {mapMutations} from "vuex";
import {fileTypeIcon} from "../../../config";
import path from "path";
import {strEllipsis} from "../../../utils";
export default {
name: "FileItem",
props: ['data'],
data() {
return {
ext: '',
}
},
watch: {
data() {
this.updateExt();
}
},
mounted() {
this.updateExt();
},
computed: {
fileIcon() {
return 'icon-' + fileTypeIcon[this.ext];
return 'icon-' + fileTypeIcon[this.data.ext];
},
showThumbnail() {
return fileTypeIcon[this.ext] === 't';
return fileTypeIcon[this.data.ext] === 't';
},
thumbnailUrl(){
thumbnailUrl() {
return this.data.url;
},
ellipsisName(){
return strEllipsis(this.data.name, 14, 5);
},
methods: {
updateExt() {
this.ext = path.extname(this.data.name);
},
onDbclick(){
methods: {
onDbclick() {
this.$emit('show-file-details', this.data);
}
},
onClickDelete() {
this.$confirm(this.$t('Are you sure to delete this asset'), this.$t('Alert'), {
showClose: false,
closeOnClickModal: false,
closeOnPressEscape: false,
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}).then(() => {
this.deleteAsset(this.data.uuid);
}).catch((e) => {
});
},
onClickEdit() {
this.$prompt(this.$t('Input asset name'), this.$t('Rename asset'), {
inputValue: this.data.name,
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
closeOnClickModal: false,
inputPattern: /^.{1,256}$/,
inputErrorMessage: this.$t('Invalid asset name'),
}).then(({value}) => {
this.$set(this.data, 'name', value);
this.modifyAsset();
}).catch(() => {
});
},
...mapMutations([
'deleteAsset',
'modifyAsset',
]),
}
}
</script>
......
<template>
<div class="tool-bar">
<sample-menu :data="menu" @click-menu="clickMenu"/>
<div>
<div class="right-part">
<span>
[{{project.name}}]
<el-button size="mini" circle icon="el-icon-edit" @click="editProjectName"/>
</span>
</div>
</div>
</template>
<script>
import {mapState, mapActions} from 'vuex'
import {mapState, mapActions, mapMutations} from 'vuex'
import SampleMenu from "../../components/SampleMenu";
export default {
......@@ -32,7 +35,24 @@
methods: {
clickMenu(menuItem) {
this.$emit('click-menu', menuItem);
}
},
editProjectName(){
this.$prompt(this.$t('Input project name'), this.$t('Rename project'), {
inputValue: this.project.name,
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
closeOnClickModal: false,
inputPattern: /^.{1,64}$/,
inputErrorMessage: this.$t('Invalid project name'),
}).then(({value}) => {
this.$set(this.project, 'name', value);
this.modifyProject();
}).catch(() => {
});
},
...mapMutations([
'modifyProject'
]),
}
}
</script>
......
<template>
<el-dialog :title="$t('Data mapping')" width="70%" :visible.sync="visible" @open="onOpen"
:append-to-body="true">
:append-to-body="true" :close-on-click-modal="false">
<div class="data-mapping-dialog">
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<div class="item" v-for="(link, index) in mapping">
<el-input size="mini" style="width: 30%" v-model="link.name" @change="onChange"/>
<el-icon class="el-icon-connection"/>
<el-input size="mini" v-model="link.path" @change="onChange"/>
<el-button icon="el-icon-minus" circle size="mini" @click="toDeleteItem(link, index)"/>
</div>
</el-scrollbar>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="visible=false">{{$t('Cancel')}}</el-button>
<el-button size="mini" type="primary" @click="onConfirm">{{$t('Save')}}</el-button>
<el-button size="mini" type="primary" @click="onAdd">{{$t('Add')}}</el-button>
<el-button size="mini" type="primary" @click="onConfirm">{{$t('Confirm')}}</el-button>
</div>
</el-dialog>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
export default {
name: "DataMappingDialog",
data() {
......@@ -17,16 +28,42 @@
visible: false,
}
},
computed: {
...mapState({
mapping: state=> state.project.data.dataMapping,
}),
},
methods: {
show(){
show() {
this.visible = true;
},
onConfirm(){
onAdd() {
this.addDataMapping();
},
onChange(){
this.modifyDataMapping();
},
toDeleteItem(link, index){
this.$confirm(this.$t('Are you sure to delete this link'), this.$t('Alert'), {
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}).then(() => {
this.deleteDataMapping(index);
}).catch((e) => {
});
},
onConfirm() {
this.visible = false;
},
onOpen(){
onOpen() {
},
...mapMutations([
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
]),
}
}
</script>
......
<template>
<el-dialog :title="$t('Project details')" width="70%" :visible.sync="visible" @open="onOpen"
:close-on-click-modal="false"
:append-to-body="true">
<div class="project-details-dialog">
<el-form v-model="project">
<el-form-item prop="">
</el-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="visible=false">{{$t('Cancel')}}</el-button>
<el-button size="mini" type="primary" @click="onConfirm">{{$t('Save')}}</el-button>
......@@ -10,6 +17,8 @@
</template>
<script>
import {mapState} from 'vuex';
export default {
name: "ProjectDetailsDialog",
data() {
......@@ -17,6 +26,11 @@
visible: false,
}
},
computed: {
...mapState([
'project',
]),
},
methods: {
show(){
this.visible = true;
......
......@@ -2248,6 +2248,13 @@ copy-descriptor@^0.1.0:
resolved "https://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
copy-to-clipboard@^3.2.0:
version "3.2.0"
resolved "https://registry.npm.taobao.org/copy-to-clipboard/download/copy-to-clipboard-3.2.0.tgz#d2724a3ccbfed89706fac8a894872c979ac74467"
integrity sha1-0nJKPMv+2JcG+siolIcsl5rHRGc=
dependencies:
toggle-selection "^1.0.6"
copy-webpack-plugin@^4.6.0:
version "4.6.0"
resolved "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-4.6.0.tgz#e7f40dd8a68477d405dd1b7a854aae324b158bae"
......@@ -2911,6 +2918,11 @@ emoji-regex@^7.0.1:
resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
......@@ -4225,6 +4237,11 @@ is-fullwidth-code-point@^2.0.0:
resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=
is-glob@^3.1.0:
version "3.1.0"
resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
......@@ -7212,6 +7229,15 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string-width@^4.1.0:
version "4.1.0"
resolved "https://registry.npm.taobao.org/string-width/download/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff"
integrity sha1-uoRtHaqXw8WWFVMIBj4HXtHJmv8=
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^5.2.0"
string.prototype.padend@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/string.prototype.padend/download/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
......@@ -7492,6 +7518,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
toggle-selection@^1.0.6:
version "1.0.6"
resolved "https://registry.npm.taobao.org/toggle-selection/download/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
......@@ -7764,12 +7795,7 @@ utils-merge@1.0.1:
resolved "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
uuid@^3.0.1, uuid@^3.3.2:
version "3.3.3"
resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz?cache=0&sync_timestamp=1566221202613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
integrity sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY=
uuid@^3.3.3:
uuid@^3.0.1, uuid@^3.3.2, uuid@^3.3.3:
version "3.3.3"
resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
integrity sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY=
......
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