diff --git a/resources/assets/js/pages/manage/calendar.vue b/resources/assets/js/pages/manage/calendar.vue index d3cc7724..28562c1d 100644 --- a/resources/assets/js/pages/manage/calendar.vue +++ b/resources/assets/js/pages/manage/calendar.vue @@ -25,7 +25,8 @@ :theme="calendarTheme" :template="calendarTemplate" :calendars="calendarList" - :schedules="scheduleLists" + :schedules="calendarTasks" + @beforeCreateSchedule="onBeforeCreateSchedule" @beforeClickSchedule="onBeforeClickSchedule" @beforeUpdateSchedule="onBeforeUpdateSchedule"/> @@ -71,7 +72,6 @@ export default { calendarList: [], scheduleLoad: 0, - scheduleList: [], } }, @@ -84,10 +84,10 @@ export default { }, computed: { - ...mapState(['projectList']), + ...mapState(['projectList', 'calendarTask']), - scheduleLists() { - return this.scheduleList.filter(({complete_at}) => !complete_at) + calendarTasks() { + return this.calendarTask.filter(({complete_at}) => !complete_at) } }, @@ -99,7 +99,7 @@ export default { projectList(data) { const list = data.map((project) => { return { - id: project.id, + id: String(project.id), name: project.name, } }); @@ -121,6 +121,9 @@ export default { titlePlaceholder: () => { return this.$L("任务描述") }, + popupSave: () => { + return this.$L("保存"); + }, popupEdit: () => { return this.$L("详情"); }, @@ -143,34 +146,7 @@ export default { }).then(({data}) => { this.scheduleLoad--; data.data.some((task) => { - let schedule = { - id: task.id, - calendarId: task.project_id, - title: task.name, - category: 'allday', - start: new Date(task.start_at).toISOString(), - end: new Date(task.end_at).toISOString(), - color: "#515a6e", - bgColor: task.color || '#E3EAFD', - borderColor: task.p_color, - complete_at: task.complete_at, - preventClick: true, - isChecked: false, - }; - if (task.p_name) { - schedule.priority = '' + task.p_name + ''; - } - if (task.overdue) { - schedule.color = "#f56c6c" - schedule.bgColor = "#fef0f0" - schedule.priority+= '' + this.$L('超期未完成') + ''; - } - let index = this.scheduleList.findIndex(({id}) => id === task.id); - if (index > -1) { - this.scheduleList.splice(index, 1, schedule) - } else { - this.scheduleList.push(schedule) - } + this.$store.dispatch("saveCalendarTask", task) }); }).catch(() => { this.scheduleLoad--; @@ -224,8 +200,20 @@ export default { return currentDate.format(format); }, + onBeforeCreateSchedule(res) { + this.$store.dispatch("taskAdd", { + project_id: res.calendarId, + times: [res.start.toDate(), res.end.toDate()], + name: res.title + }).then(({msg}) => { + $A.messageSuccess(msg); + }).catch(({msg}) => { + $A.modalError(msg); + }); + }, + onBeforeClickSchedule({type, schedule}) { - let data = this.scheduleList.find(({id}) => id === schedule.id); + let data = this.calendarTask.find(({id}) => id === schedule.id); if (!data) { return; } @@ -253,7 +241,6 @@ export default { content: '你确定要删除任务【' + data.title + '】吗?', loading: true, onOk: () => { - this.scheduleList = this.scheduleList.filter(({id}) => id !== data.id); this.$store.dispatch("taskArchivedOrRemove", { task_id: data.id, type: 'delete', @@ -272,9 +259,27 @@ export default { }, onBeforeUpdateSchedule(res) { - console.group('onBeforeUpdateSchedule'); - console.log('BeforeUpdate : ', res); - console.groupEnd(); + const {changes, schedule} = res; + let data = this.calendarTask.find(({id}) => id === schedule.id); + if (!data) { + return; + } + if (changes.start || changes.end) { + const cal = this.$refs.cal.getInstance(); + cal.updateSchedule(schedule.id, schedule.calendarId, changes); + // + this.$store.dispatch("taskUpdate", { + task_id: data.id, + times: [ + (changes.start || schedule.start).toDate(), + (changes.end || schedule.end).toDate(), + ], + }).then(({msg}) => { + $A.messageSuccess(msg); + }).catch(({msg}) => { + $A.modalError(msg); + }); + } } } } diff --git a/resources/assets/js/pages/manage/components/Calendar.vue b/resources/assets/js/pages/manage/components/Calendar.vue index 106eda12..fe667ed2 100644 --- a/resources/assets/js/pages/manage/components/Calendar.vue +++ b/resources/assets/js/pages/manage/components/Calendar.vue @@ -108,10 +108,10 @@ export default { watch: { calendars(newValue) { this.calendarInstance.setCalendars(newValue); + this.$nextTick(this.resetRender) }, schedules() { - this.calendarInstance.clear(); - this.reflectSchedules(); + this.resetRender(); }, view(newValue) { this.calendarInstance.changeView(newValue, true); diff --git a/resources/assets/js/pages/manage/components/ProjectList.vue b/resources/assets/js/pages/manage/components/ProjectList.vue index 3d1fd509..49a15f50 100644 --- a/resources/assets/js/pages/manage/components/ProjectList.vue +++ b/resources/assets/js/pages/manage/components/ProjectList.vue @@ -6,9 +6,6 @@

{{projectDetail.name}}

-
{{projectDetail.desc}}
- -
-
-
- {{$L('隐藏已完成')}} -
-
-
-
-
+
+
{{projectDetail.desc}}
+
+
+ {{$L('显示已完成')}} +
+
+
+
@@ -450,7 +448,7 @@ export default { 'projectChatShow', 'projectTablePanel', - 'projectCompleteHide', + 'projectCompleteShow', 'taskMyShow', 'taskUndoneShow', 'taskCompletedShow' @@ -463,9 +461,9 @@ export default { }, panelTask() { - const {searchText, projectCompleteHide} = this; + const {searchText, projectCompleteShow} = this; return function (project_task) { - if (projectCompleteHide) { + if (!projectCompleteShow) { project_task = project_task.filter(({complete_at}) => { return !complete_at; }); @@ -480,11 +478,11 @@ export default { }, myList() { - const {searchText, projectCompleteHide, userId, projectDetail} = this; + const {searchText, projectCompleteShow, userId, projectDetail} = this; const array = []; projectDetail.project_column.forEach(({project_task, name}) => { project_task.some((task) => { - if (projectCompleteHide) { + if (!projectCompleteShow) { if (task.complete_at) { return false; } @@ -512,11 +510,11 @@ export default { }, undoneList() { - const {searchText, projectCompleteHide, projectDetail} = this; + const {searchText, projectCompleteShow, projectDetail} = this; const array = []; projectDetail.project_column.forEach(({project_task, name}) => { project_task.some((task) => { - if (projectCompleteHide) { + if (!projectCompleteShow) { if (task.complete_at) { return false; } @@ -553,11 +551,11 @@ export default { }, completedList() { - const {searchText, projectCompleteHide, projectDetail} = this; + const {searchText, projectCompleteShow, projectDetail} = this; const array = []; projectDetail.project_column.forEach(({project_task, name}) => { project_task.some((task) => { - if (projectCompleteHide) { + if (!projectCompleteShow) { if (task.complete_at) { return false; } @@ -1032,8 +1030,8 @@ export default { taskHidden(task) { const {name, desc, complete_at} = task; - const {searchText, projectCompleteHide} = this; - if (projectCompleteHide) { + const {searchText, projectCompleteShow} = this; + if (!projectCompleteShow) { if (complete_at) { return true; } diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 23716eee..d82c9c74 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -378,9 +378,10 @@ export default { /** * 保存任务信息 * @param state + * @param dispatch * @param data */ - saveTask({state}, data) { + saveTask({state, dispatch}, data) { state.projectDetail.project_column.some(({project_task}) => { let index = project_task.findIndex(({id}) => id === data.id); if (index > -1) { @@ -396,6 +397,46 @@ export default { state.projectOpenTask.sub_task.splice(index, 1, Object.assign(state.projectOpenTask.sub_task[index], data)) } } + dispatch("saveCalendarTask", data) + }, + + /** + * 保存任务信息(日历任务) + * @param state + * @param data + */ + saveCalendarTask({state}, data) { + let task = { + id: data.id, + calendarId: String(data.project_id), + title: data.name, + body: data.desc, + category: 'allday', + start: new Date(data.start_at).toISOString(), + end: new Date(data.end_at).toISOString(), + color: "#515a6e", + bgColor: data.color || '#E3EAFD', + borderColor: data.p_color, + complete_at: data.complete_at, + priority: '', + preventClick: true, + isChecked: false, + }; + if (data.p_name) { + task.priority = '' + data.p_name + ''; + } + if (data.overdue) { + task.title = '[' + $A.L('超期') + '] ' + task.title + task.color = "#f56c6c" + task.bgColor = "#fef0f0" + task.priority+= '' + $A.L('超期未完成') + ''; + } + let index = state.calendarTask.findIndex(({id}) => id === data.id); + if (index > -1) { + state.calendarTask.splice(index, 1, Object.assign(state.calendarTask[index], task)) + } else { + state.calendarTask.push(task) + } }, /** @@ -560,7 +601,7 @@ export default { */ taskAdd({state, dispatch}, data) { return new Promise(function (resolve, reject) { - const post = state.method.cloneJSON(data); + const post = state.method.cloneJSON(state.method.date2string(data)); if (state.method.isArray(post.column_id)) { post.column_id = post.column_id.find((val) => val) } @@ -587,6 +628,7 @@ export default { } } } + dispatch("saveCalendarTask", task); dispatch("getProjectOne", task.project_id); resolve(result) }).catch(result => { @@ -628,7 +670,7 @@ export default { */ taskUpdate({state, dispatch}, data) { return new Promise(function (resolve, reject) { - const post = state.method.cloneJSON(data); + const post = state.method.cloneJSON(state.method.date2string(data)); if (state.method.isArray(post.owner)) { post.owner = post.owner.find((id) => id) } @@ -684,6 +726,11 @@ export default { state.projectOpenTask.sub_task.splice(index, 1) } } + let index = state.calendarTask.findIndex(({id}) => id === data.id); + if (index > -1) { + state.calendarTask.splice(index, 1) + } + dispatch("getProjectOne", data.project_id); resolve(result); }).catch(result => { reject(result) diff --git a/resources/assets/js/store/state.js b/resources/assets/js/store/state.js index 3ad64648..47cc1640 100644 --- a/resources/assets/js/store/state.js +++ b/resources/assets/js/store/state.js @@ -236,7 +236,7 @@ const state = { method }; [ 'projectChatShow', // 项目聊天显示 - 'projectCompleteHide' // 项目面板显示已完成列表 + 'projectCompleteShow' // 项目面板显示已完成列表 ].forEach((key) => { state[key] = state.method.getStorageBoolean("boolean:" + key, false) }); @@ -275,6 +275,7 @@ state.projectOpenTask = {_show: false, id: 0, task_user: [], task_tag: []}; state.projectTaskContent = {}; state.projectTaskFiles = {}; state.projectSubTask = {}; +state.calendarTask = []; // 会话聊天 state.dialogId = 0; diff --git a/resources/assets/sass/pages/components/project-list.scss b/resources/assets/sass/pages/components/project-list.scss index c68aaccb..b0f31c08 100644 --- a/resources/assets/sass/pages/components/project-list.scss +++ b/resources/assets/sass/pages/components/project-list.scss @@ -3,11 +3,15 @@ flex-direction: column; .project-head { display: flex; + flex-direction: column; align-items: flex-start; margin: 32px 32px 0; .project-titbox { - flex: 1; - margin-bottom: 16px; + width: 100%; + display: flex; + align-items: flex-start; + justify-content: space-between; + margin-bottom: 36px; .project-title { display: flex; align-items: center; @@ -26,23 +30,11 @@ } } } - .project-subtitle { - color: #999999; - margin-top: 18px; - line-height: 24px; - } - } - .project-icobox { - display: flex; - flex-direction: column; - justify-content: space-between; - height: 100%; - margin-top: 2px; - margin-left: 80px; .project-icons { display: flex; align-items: center; flex-shrink: 0; + margin-top: 3px; > li { list-style: none; display: flex; @@ -84,63 +76,78 @@ } } } - .project-switch { + } + .project-subtitle { + width: 100%; + color: #999999; + line-height: 24px; + margin-top: -18px; + margin-bottom: 6px; + padding-right: 260px; + } + .project-switch { + width: 100%; + display: flex; + justify-content: flex-end; + .project-checkbox { display: flex; - justify-content: flex-end; - margin-top: 24px; - .project-checkbox { - display: flex; - align-items: center; - margin-right: 14px; - opacity: 0.9; + align-items: center; + margin-right: 14px; + opacity: 0.9; + .ivu-checkbox-focus { + box-shadow: none; } - .project-switch-button { + } + .project-switch-button { + display: flex; + align-items: center; + background-color: #ffffff; + border-radius: 6px; + position: relative; + transition: box-shadow 0.2s; + &:hover { + box-shadow: 0 0 10px #e6ecfa; + } + &:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 50%; + height: 100%; + z-index: 0; + color: #2d8cf0; + border-radius: 6px; + border: 1px solid #2d8cf0; + background-color: #e6f7ff; + transition: left 0.2s; + } + > div { + z-index: 1; + width: 32px; + height: 30px; display: flex; align-items: center; - background-color: #ffffff; + justify-content: center; border-radius: 6px; - position: relative; - &:before { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 50%; - height: 100%; - z-index: 0; + cursor: pointer; + color: #515a6e; + > i { + font-size: 17px; + } + &:first-child { color: #2d8cf0; - border-radius: 6px; - border: 1px solid #2d8cf0; - background-color: #e6f7ff; - transition: left 0.2s; } - > div { - z-index: 1; - width: 32px; - height: 30px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 6px; - cursor: pointer; + } + &.menu { + &:before { + left: 50%; + } + > div:first-child { color: #515a6e; - > i { - font-size: 17px; - } - &:first-child { - color: #2d8cf0; - } } - &.menu { - &:before { - left: 50%; - } - > div:first-child { - color: #515a6e; - } - > div:last-child { - color: #2d8cf0; - } + > div:last-child { + color: #2d8cf0; } } } diff --git a/resources/assets/sass/pages/page-calendar.scss b/resources/assets/sass/pages/page-calendar.scss index 84714635..3d225fae 100644 --- a/resources/assets/sass/pages/page-calendar.scss +++ b/resources/assets/sass/pages/page-calendar.scss @@ -56,6 +56,18 @@ background-color: #ffffff; z-index: 1; } + .tui-full-calendar-popup { + box-shadow: none; + .tui-full-calendar-popup-container { + border: 0; + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2); + border-radius: 6px; + } + .tui-full-calendar-arrow-top .tui-full-calendar-popup-arrow-border { + top: -8px; + border-bottom-color: rgba(217, 217, 217, .5); + } + } .tui-full-calendar-popup-creation { .tui-full-calendar-icon { &.tui-full-calendar-ic-title, @@ -73,10 +85,21 @@ .tui-full-calendar-popup-section { display: flex; justify-content: space-between; - margin-bottom: 6px; + margin-bottom: 10px; + .tui-full-calendar-popup-section-item { + height: 36px; + border-color: #e8e8e8; + border-radius: 4px; + } + .tui-full-calendar-popup-section-item input { + height: 34px; + } } .tui-full-calendar-section-title { width: 100%; + input { + width: 100%; + } } .tui-full-calendar-section-start-date, .tui-full-calendar-section-end-date { @@ -119,12 +142,16 @@ top: -2px; background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIzODU5MzMwMTc2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9Ijc5MiIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik04OTIuMjg4IDI1NmgtMTkxLjE2OEEyMDIuMjQgMjAyLjI0IDAgMCAwIDUwOS42MzIgNjIuMDggMjAxLjIxNiAyMDEuMjE2IDAgMCAwIDMxOC44NDggMjU2SDEyOGMtMTguNjg4IDAtNjYuMDQ4LTQuMjI0LTY2LjA0OCAyNC43NjhDNjEuOTUyIDMyNy43NDQgMTA5LjM3NiAzMjAgMTI4IDMyMGg2NHY1MTJhMTQ2LjQ5NiAxNDYuNDk2IDAgMCAwIDEyNy40MjQgMTI4aDM4Mi4yNzJBMTUwLjAxNiAxNTAuMDE2IDAgMCAwIDgzMiA4MzJsLTMuMzkyLTUxMmg2NGMxOC4zNjggMCA2NS4wMjQgMS40NzIgNjUuMDI0LTM5Ljc0NEE3Mi4zODQgNzIuMzg0IDAgMCAwIDg5Mi4yODggMjU2ek01MDkuNjMyIDEyOC41MTJBMTM4LjE3NiAxMzguMTc2IDAgMCAxIDYzNy40NCAyNTZIMzgyLjU5MmExMzcuOTIgMTM3LjkyIDAgMCAxIDEyNy4wNC0xMjcuNDg4ek03NjggODMyYTk3Ljk4NCA5Ny45ODQgMCAwIDEtNjYuODggNjRIMzE4Ljg0OGE5My41NjggOTMuNTY4IDAgMCAxLTY0LTY0VjMyMEg3Njh2NTEyeiBtLTM4NS40MDgtNjRWNTEyYzAtMTguNDk2IDAuOTYtNjAuOTkyIDM2LjczNi02MC45OTIgMjcuMzI4IDAgMjYuNDk2IDQzLjAwOCAyNi45NDQgNjAuOTkydjI1NmMwIDE4LjQ5Ni02LjQgMjAuMDMyLTI0Ljk2IDIwLjAzMnMtMzguNzItMS41MzYtMzguNzItMjAuMDMyeiBtMTkxLjE2OCAwVjUxMmE2NCA2NCAwIDAgMSAyMy44MDgtNjAuOTkyYzQyLjQzMiAwIDM5LjM2IDQzLjAwOCAzOS44NzIgNjAuOTkydjI1NmMwIDE4LjQ5Ni0xOS41ODQgMjAuMDMyLTM3Ljk1MiAyMC4wMzJzLTI1Ljc5Mi0xLjUzNi0yNS43OTItMjAuMDMyeiIgcC1pZD0iNzkzIiBmaWxsPSIjNTE1MTUxIj48L3BhdGg+PC9zdmc+"); } + .tui-full-calendar-popup-detail-item-separate { + padding-left: 22px; + } } .tui-datepicker { + border-color: #e8e8e8; .tui-calendar { th, td { - height: 35px; + height: 32px; } .tui-calendar-prev-month.tui-calendar-date, .tui-calendar-next-month.tui-calendar-date {