+
+
-
-
+
{{$L('子任务')}}
+{{item.sub_my.length}}
@@ -107,9 +73,10 @@
import {mapGetters, mapState} from "vuex";
import AppDown from "../../components/AppDown";
import {Store} from "le5le-store";
+import TaskMenu from "./components/TaskMenu";
export default {
- components: {AppDown},
+ components: {TaskMenu, AppDown},
data() {
return {
nowTime: $A.Time(),
@@ -117,10 +84,6 @@ export default {
loadIng: 0,
dashboard: 'today',
-
- taskLoad: {},
-
- tempShowTasks: [],
}
},
@@ -156,7 +119,7 @@ export default {
},
list() {
- const {dashboard, tempShowTasks} = this;
+ const {dashboard} = this;
let data = [];
switch (dashboard) {
case 'today':
@@ -166,112 +129,17 @@ export default {
data = this.transforTasks(this.dashboardTask.overdue);
break
}
- if (tempShowTasks.length > 0) {
- data.push(...tempShowTasks);
- }
return data.sort((a, b) => {
return $A.Date(a.end_at) - $A.Date(b.end_at);
});
},
},
- watch: {
- '$route'() {
- this.tempShowTasks = [];
- },
- dashboard() {
- this.tempShowTasks = [];
- }
- },
-
methods: {
- dropTask(task, command) {
- switch (command) {
- case 'complete':
- if (task.complete_at) return;
- this.updateTask(task, {
- complete_at: $A.formatDate("Y-m-d H:i:s")
- }).then(() => {
- this.tempShowTasks.push(task)
- })
- break;
- case 'uncomplete':
- if (!task.complete_at) return;
- this.updateTask(task, {
- complete_at: false
- }).then(() => {
- this.tempShowTasks = this.tempShowTasks.filter(({id}) => id != task.id)
- })
- break;
- case 'archived':
- case 'remove':
- this.archivedOrRemoveTask(task, command);
- break;
- default:
- if (command.name) {
- this.updateTask(task, {
- color: command.color
- })
- }
- break;
- }
- },
-
openTask(task) {
this.$store.dispatch("openTask", task)
},
- updateTask(task, updata) {
- return new Promise((resolve, reject) => {
- if (this.taskLoad[task.id] === true) {
- reject()
- return;
- }
- this.$set(this.taskLoad, task.id, true);
- //
- Object.keys(updata).forEach(key => this.$set(task, key, updata[key]));
- //
- this.$store.dispatch("taskUpdate", Object.assign(updata, {
- task_id: task.id,
- })).then(() => {
- this.$set(this.taskLoad, task.id, false);
- resolve()
- }).catch(({msg}) => {
- $A.modalError(msg);
- this.$set(this.taskLoad, task.id, false);
- this.$store.dispatch("getTaskOne", task.id);
- reject();
- });
- })
- },
-
- archivedOrRemoveTask(task, type) {
- let typeDispatch = type == 'remove' ? 'removeTask' : 'archivedTask';
- let typeName = type == 'remove' ? '删除' : '归档';
- let typeTask = task.parent_id > 0 ? '子任务' : '任务';
- $A.modalConfirm({
- title: typeName + typeTask,
- content: '你确定要' + typeName + typeTask + '【' + task.name + '】吗?',
- loading: true,
- onOk: () => {
- if (this.taskLoad[task.id] === true) {
- this.$Modal.remove();
- return;
- }
- this.$set(this.taskLoad, task.id, true);
- this.$store.dispatch(typeDispatch, task.id).then(({msg}) => {
- $A.messageSuccess(msg);
- this.$Modal.remove();
- this.$set(this.taskLoad, task.id, false);
- }).catch(({msg}) => {
- $A.modalError(msg, 301);
- this.$Modal.remove();
- this.$set(this.taskLoad, task.id, false);
- });
- }
- });
- },
-
expiresFormat(date) {
return $A.countDownFormat(date, this.nowTime)
},
diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js
index 29aeff4e..afdecbdb 100644
--- a/resources/assets/js/store/actions.js
+++ b/resources/assets/js/store/actions.js
@@ -1135,6 +1135,7 @@ export default {
reject({msg: 'Parameter error'});
return;
}
+ dispatch("taskLoadAdd", task_id)
dispatch("call", {
url: 'project/task/remove',
data: {
@@ -1142,10 +1143,12 @@ export default {
},
}).then(result => {
dispatch("forgetTask", task_id)
+ dispatch("taskLoadSub", task_id)
resolve(result)
}).catch(e => {
console.error(e);
dispatch("getTaskOne", task_id);
+ dispatch("taskLoadSub", task_id)
reject(e)
});
});
@@ -1164,6 +1167,7 @@ export default {
reject({msg: 'Parameter error'});
return;
}
+ dispatch("taskLoadAdd", task_id)
dispatch("call", {
url: 'project/task/archived',
data: {
@@ -1171,10 +1175,12 @@ export default {
},
}).then(result => {
dispatch("forgetTask", task_id)
+ dispatch("taskLoadSub", task_id)
resolve(result)
}).catch(e => {
console.error(e);
- dispatch("getTaskOne", task_id);
+ dispatch("getTaskOne", task_id)
+ dispatch("taskLoadSub", task_id)
reject(e)
});
});
@@ -1365,28 +1371,67 @@ export default {
* 更新任务
* @param state
* @param dispatch
- * @param data
+ * @param data {task_id, ?}
* @returns {Promise}
*/
taskUpdate({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
const post = $A.cloneJSON($A.date2string(data));
//
+ dispatch("taskLoadAdd", post.task_id)
dispatch("call", {
url: 'project/task/update',
data: post,
method: 'post',
}).then(result => {
+ dispatch("taskLoadSub", post.task_id)
dispatch("saveTask", result.data)
resolve(result)
}).catch(e => {
console.error(e);
+ dispatch("taskLoadSub", post.task_id)
dispatch("getTaskOne", post.task_id);
reject(e)
});
});
},
+ /**
+ * 任务增加等待
+ * @param state
+ * @param task_id
+ */
+ taskLoadAdd({state}, task_id) {
+ setTimeout(() => {
+ const load = state.taskLoading.find(({id}) => id == task_id)
+ if (!load) {
+ state.taskLoading.push({
+ id: task_id,
+ num: 1
+ })
+ } else {
+ load.num++;
+ }
+ }, 300)
+ },
+
+ /**
+ * 任务减少等待
+ * @param state
+ * @param task_id
+ */
+ taskLoadSub({state}, task_id) {
+ const load = state.taskLoading.find(({id}) => id == task_id)
+ if (!load) {
+ state.taskLoading.push({
+ id: task_id,
+ num: -1
+ })
+ } else {
+ load.num--;
+ }
+ },
+
/**
* 获取任务优先级预设数据
* @param state
diff --git a/resources/assets/js/store/state.js b/resources/assets/js/store/state.js
index 31c5a572..fdd82c7f 100644
--- a/resources/assets/js/store/state.js
+++ b/resources/assets/js/store/state.js
@@ -67,6 +67,7 @@ state.taskId = 0;
state.taskContents = [];
state.taskFiles = [];
state.taskLogs = [];
+state.taskLoading = [];
// 任务优先级
state.taskPriority = [];
diff --git a/resources/assets/sass/pages/components/_.scss b/resources/assets/sass/pages/components/_.scss
index 2217113b..e848824d 100755
--- a/resources/assets/sass/pages/components/_.scss
+++ b/resources/assets/sass/pages/components/_.scss
@@ -10,5 +10,6 @@
@import "task-add-simple";
@import "task-archived";
@import "task-detail";
+@import "task-menu";
@import "task-priority";
@import "team-management";
diff --git a/resources/assets/sass/pages/components/project-list.scss b/resources/assets/sass/pages/components/project-list.scss
index 36d2add9..d463b93f 100644
--- a/resources/assets/sass/pages/components/project-list.scss
+++ b/resources/assets/sass/pages/components/project-list.scss
@@ -380,10 +380,11 @@
}
.ivu-icon {
font-size: 22px;
- color: #777777;
- cursor: pointer;
- &:hover {
- color: #555555;
+ &.uncomplete {
+ color: #777777;
+ &:hover {
+ color: #555555;
+ }
}
}
}
@@ -651,31 +652,12 @@
align-items: flex-start;
padding: 12px 12px 12px 34px;
line-height: 24px;
- .drop-icon {
- position: relative;
- }
.loading {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- width: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- .common-loading {
- margin: 0;
- width: 14px;
- height: 14px;
- }
+ height: 24px;
}
.ivu-icon {
cursor: pointer;
font-size: 16px;
- color: #cccccc;
- &.completed {
- color: $primary-color;
- }
&.sub-icon {
font-size: 16px;
width: 16px;
@@ -689,6 +671,9 @@
transform: rotate(90deg);
}
}
+ &.uncomplete {
+ color: #cccccc;
+ }
}
.item-title {
flex: 1;
diff --git a/resources/assets/sass/pages/components/task-detail.scss b/resources/assets/sass/pages/components/task-detail.scss
index ea691001..2a7b4092 100644
--- a/resources/assets/sass/pages/components/task-detail.scss
+++ b/resources/assets/sass/pages/components/task-detail.scss
@@ -26,11 +26,23 @@
background-color: #f4f5f5;
}
.icon {
- width: 18px;
- font-size: 18px;
- cursor: pointer;
- &.completed {
- color: $primary-color;
+ .task-menu-icon {
+ display: flex;
+ align-items: center;
+ .ivu-icon {
+ font-size: 18px;
+ }
+ .loading {
+ width: 18px;
+ height: 18px;
+ .common-loading {
+ width: 16px;
+ height: 16px;
+ }
+ }
+ .uncomplete {
+ color: #888888;
+ }
}
}
.nav {
@@ -78,8 +90,12 @@
}
.menu {
margin-left: 12px;
- font-size: 22px;
- cursor: pointer;
+ display: flex;
+ align-items: center;
+ .ivu-icon {
+ font-size: 22px;
+ color: #606266;
+ }
}
}
}
@@ -243,37 +259,22 @@
&:last-child {
margin-bottom: -6px;
}
+ &:hover {
+ .subtask-time {
+ .clock {
+ transform: translateX(0);
+ opacity: 0.8;
+ }
+ }
+ }
.subtask-icon {
width: 16px;
height: 26px;
line-height: 26px;
margin-right: 6px;
+ display: flex;
+ align-items: center;
cursor: pointer;
- .loading {
- width: 16px;
- height: 16px;
- margin: 0;
- padding: 2px;
- }
- .ivu-icon {
- font-size: 16px;
- color: #cccccc;
- &.completed {
- color: $primary-color;
- }
- }
- &.sub-icon {
- font-size: 16px;
- width: 16px;
- height: 16px;
- margin-left: -20px;
- margin-right: 4px;
- color: #cfcfcf;
- transition: transform 0.2s;
- &.active {
- transform: rotate(90deg);
- }
- }
}
.subtask-name {
flex: 1;
@@ -309,6 +310,13 @@
color: #ff9900;
}
}
+ .clock {
+ margin: 3px 2px;
+ font-size: 20px;
+ transition: all 0.2s;
+ transform: translateX(50%);
+ opacity: 0;
+ }
}
.subtask-avatar {
height: 20px;
diff --git a/resources/assets/sass/pages/components/task-menu.scss b/resources/assets/sass/pages/components/task-menu.scss
new file mode 100644
index 00000000..75c2b5ae
--- /dev/null
+++ b/resources/assets/sass/pages/components/task-menu.scss
@@ -0,0 +1,50 @@
+.task-menu-icon {
+ position: relative;
+
+ .loading {
+ width: 16px;
+ height: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .common-loading {
+ margin: 0;
+ width: 14px;
+ height: 14px;
+ }
+ }
+
+ .ivu-icon {
+ cursor: pointer;
+ font-size: 16px;
+ color: #cccccc;
+
+ &.completed {
+ color: $primary-color;
+ }
+ }
+}
+
+.task-menu-more-dropdown {
+ > li {
+ .item {
+ display: flex;
+ align-items: center;
+
+ > i {
+ width: 18px;
+ height: 18px;
+ line-height: 18px;
+ font-size: 18px;
+ margin-right: 8px;
+ padding: 0;
+ color: #bbbbbb;
+
+ &.ivu-icon {
+ font-size: 16px;
+ }
+ }
+ }
+ }
+}