274 lines
9.7 KiB
Vue
274 lines
9.7 KiB
Vue
<template>
|
|
<EDropdown
|
|
ref="dropdown"
|
|
trigger="click"
|
|
:size="size"
|
|
placement="bottom"
|
|
@command="dropTask"
|
|
@visible-change="visibleChange">
|
|
<slot name="icon">
|
|
<div class="task-menu-icon">
|
|
<div v-if="loadIng" class="loading"><Loading/></div>
|
|
<template v-else>
|
|
<Icon v-if="task.complete_at" class="completed" :type="completedIcon" />
|
|
<Icon v-else :type="icon" class="uncomplete"/>
|
|
</template>
|
|
</div>
|
|
</slot>
|
|
<EDropdownMenu slot="dropdown" class="task-menu-more-dropdown">
|
|
<li class="task-menu-more-warp" :class="size">
|
|
<ul>
|
|
<EDropdownItem v-if="!flow" class="load-flow" disabled>
|
|
<div class="load-flow-warp">
|
|
<Loading/>
|
|
</div>
|
|
</EDropdownItem>
|
|
<template v-else-if="turns.length > 0">
|
|
<EDropdownItem v-for="item in turns" :key="item.id" :command="`turn::${item.id}`">
|
|
<div class="item flow">
|
|
<Icon v-if="item.id == task.flow_item_id && flow.auto_assign !== true" class="check" type="md-checkmark-circle-outline" />
|
|
<Icon v-else type="md-radio-button-off" />
|
|
<div class="flow-name" :class="item.status">{{item.name}}</div>
|
|
</div>
|
|
</EDropdownItem>
|
|
</template>
|
|
<template v-else>
|
|
<EDropdownItem v-if="task.complete_at" command="uncomplete">
|
|
<div class="item red">
|
|
<Icon type="md-checkmark-circle-outline" />{{$L('标记未完成')}}
|
|
</div>
|
|
</EDropdownItem>
|
|
<EDropdownItem v-else command="complete">
|
|
<div class="item">
|
|
<Icon type="md-radio-button-off" />{{$L('完成')}}
|
|
</div>
|
|
</EDropdownItem>
|
|
</template>
|
|
|
|
<template v-if="task.parent_id === 0">
|
|
<EDropdownItem :divided="turns.length > 0" command="archived">
|
|
<div class="item">
|
|
<Icon type="ios-filing" />{{$L('归档')}}
|
|
</div>
|
|
</EDropdownItem>
|
|
<EDropdownItem command="remove">
|
|
<div class="item hover-del">
|
|
<Icon type="md-trash" />{{$L('删除')}}
|
|
</div>
|
|
</EDropdownItem>
|
|
<template v-if="colorShow">
|
|
<EDropdownItem v-for="(c, k) in taskColorList" :key="'c_' + k" :divided="k==0" :command="c">
|
|
<div class="item">
|
|
<i class="taskfont" :style="{color:c.color||'#f9f9f9'}" v-html="c.color == task.color ? '' : ''"></i>{{$L(c.name)}}
|
|
</div>
|
|
</EDropdownItem>
|
|
</template>
|
|
</template>
|
|
<EDropdownItem v-else command="remove" :divided="turns.length > 0">
|
|
<div class="item">
|
|
<Icon type="md-trash" />{{$L('删除')}}
|
|
</div>
|
|
</EDropdownItem>
|
|
</ul>
|
|
</li>
|
|
</EDropdownMenu>
|
|
</EDropdown>
|
|
</template>
|
|
|
|
<script>
|
|
import {mapState} from "vuex";
|
|
|
|
export default {
|
|
name: "TaskMenu",
|
|
props: {
|
|
task: {
|
|
type: Object,
|
|
default: () => {
|
|
return {};
|
|
}
|
|
},
|
|
loadStatus: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
colorShow: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
updateBefore: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
size: {
|
|
type: String,
|
|
default: 'small'
|
|
},
|
|
icon: {
|
|
type: String,
|
|
default: 'md-radio-button-off'
|
|
},
|
|
completedIcon: {
|
|
type: String,
|
|
default: 'md-checkmark-circle'
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState(['taskColorList', 'taskLoading', 'taskFlows', 'taskFlowItems']),
|
|
|
|
loadIng() {
|
|
if (this.loadStatus) {
|
|
return true;
|
|
}
|
|
const load = this.taskLoading.find(({id}) => id == this.task.id);
|
|
return load && load.num > 0
|
|
},
|
|
|
|
flow() {
|
|
return this.taskFlows.find(({task_id}) => task_id == this.task.id);
|
|
},
|
|
|
|
turns() {
|
|
if (!this.flow) {
|
|
return [];
|
|
}
|
|
let item = this.taskFlowItems.find(({id}) => id == this.flow.flow_item_id);
|
|
if (!item) {
|
|
return [];
|
|
}
|
|
return this.taskFlowItems.filter(({id}) => item.turns.includes(id))
|
|
},
|
|
},
|
|
methods: {
|
|
show() {
|
|
this.$refs.dropdown.show()
|
|
},
|
|
|
|
hide() {
|
|
this.$refs.dropdown.hide()
|
|
},
|
|
|
|
handleClick() {
|
|
this.$refs.dropdown.handleClick()
|
|
},
|
|
|
|
dropTask(command) {
|
|
if ($A.isJson(command)) {
|
|
if (command.name) {
|
|
// 修改背景色
|
|
this.updateTask({
|
|
color: command.color
|
|
}).catch(() => {})
|
|
}
|
|
return;
|
|
}
|
|
if ($A.leftExists(command, 'turn::')) {
|
|
// 修改工作流状态
|
|
let flow_item_id = $A.leftDelete(command, 'turn::');
|
|
if (flow_item_id == this.task.flow_item_id) return;
|
|
this.updateTask({
|
|
flow_item_id
|
|
}).catch(() => {})
|
|
return;
|
|
}
|
|
const cacheTask = this.task;
|
|
switch (command) {
|
|
case 'complete':
|
|
if (this.task.complete_at) {
|
|
return;
|
|
}
|
|
if (this.updateBefore) {
|
|
this.$store.dispatch("saveTaskCompleteTemp", cacheTask)
|
|
}
|
|
this.updateTask({
|
|
complete_at: $A.formatDate("Y-m-d H:i:s")
|
|
}).then(() => {
|
|
this.$store.dispatch("saveTaskCompleteTemp", cacheTask)
|
|
}).catch(() => {
|
|
this.$store.dispatch("forgetTaskCompleteTemp", cacheTask.id)
|
|
})
|
|
break;
|
|
|
|
case 'uncomplete':
|
|
if (!this.task.complete_at) {
|
|
return;
|
|
}
|
|
if (this.updateBefore) {
|
|
this.$store.dispatch("forgetTaskCompleteTemp", cacheTask.id)
|
|
}
|
|
this.updateTask({
|
|
complete_at: false
|
|
}).then(() => {
|
|
this.$store.dispatch("forgetTaskCompleteTemp", cacheTask.id)
|
|
}).catch(() => {
|
|
this.$store.dispatch("saveTaskCompleteTemp", cacheTask)
|
|
})
|
|
break;
|
|
|
|
case 'archived':
|
|
case 'remove':
|
|
this.archivedOrRemoveTask(command);
|
|
break;
|
|
}
|
|
},
|
|
|
|
visibleChange(visible) {
|
|
if (visible) {
|
|
this.$store.dispatch("getTaskFlow", this.task.id).catch(() => {})
|
|
}
|
|
},
|
|
|
|
updateTask(updata) {
|
|
return new Promise((resolve, reject) => {
|
|
if (this.loadIng) {
|
|
reject()
|
|
return;
|
|
}
|
|
//
|
|
Object.keys(updata).forEach(key => this.$set(this.task, key, updata[key]));
|
|
//
|
|
this.$store.dispatch("taskUpdate", Object.assign(updata, {
|
|
task_id: this.task.id,
|
|
})).then(({data, msg}) => {
|
|
$A.messageSuccess(msg);
|
|
resolve()
|
|
this.$emit("on-update", data)
|
|
}).catch(({msg}) => {
|
|
$A.modalError(msg);
|
|
this.$store.dispatch("getTaskOne", this.task.id).catch(() => {})
|
|
reject()
|
|
});
|
|
})
|
|
},
|
|
|
|
archivedOrRemoveTask(type) {
|
|
let typeDispatch = type == 'remove' ? 'removeTask' : 'archivedTask';
|
|
let typeName = type == 'remove' ? '删除' : '归档';
|
|
let typeTask = this.task.parent_id > 0 ? '子任务' : '任务';
|
|
$A.modalConfirm({
|
|
title: typeName + typeTask,
|
|
content: '你确定要' + typeName + typeTask + '【' + this.task.name + '】吗?',
|
|
loading: true,
|
|
onOk: () => {
|
|
if (this.loadIng) {
|
|
this.$Modal.remove();
|
|
return;
|
|
}
|
|
this.$store.dispatch(typeDispatch, this.task.id).then(({msg}) => {
|
|
$A.messageSuccess(msg);
|
|
this.$Modal.remove();
|
|
}).catch(({msg}) => {
|
|
$A.modalError(msg, 301);
|
|
this.$Modal.remove();
|
|
});
|
|
}
|
|
});
|
|
},
|
|
},
|
|
}
|
|
</script>
|