mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-17 19:23:26 +00:00
perf: 优化项目面板
This commit is contained in:
parent
a1ce6e6928
commit
783c21ad18
@ -81,7 +81,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="project-switch">
|
<div class="project-switch">
|
||||||
<div v-if="completedCount > 0" class="project-checkbox">
|
<div v-if="completedCount > 0" class="project-checkbox">
|
||||||
<Checkbox :value="projectData.cacheParameter.completedTask" @on-change="toggleCompleted">{{$L('显示已完成')}}</Checkbox>
|
<Checkbox :value="projectData.cacheParameter.completedTask" @on-change="toggleParameter('completedTask')">{{$L('显示已完成')}}</Checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-select">
|
<div class="project-select">
|
||||||
<Cascader ref="flow" :data="flowData" @on-change="flowChange" transfer-class-name="project-panel-flow-cascader" transfer>
|
<Cascader ref="flow" :data="flowData" @on-change="flowChange" transfer-class-name="project-panel-flow-cascader" transfer>
|
||||||
@ -249,7 +249,12 @@
|
|||||||
</li>
|
</li>
|
||||||
</Draggable>
|
</Draggable>
|
||||||
</div>
|
</div>
|
||||||
<Scrollbar v-else-if="tabTypeActive === 'table'" class="project-table" enable-x>
|
<Scrollbar
|
||||||
|
v-else-if="tabTypeActive === 'table'"
|
||||||
|
ref="projectTableScroll"
|
||||||
|
class="project-table"
|
||||||
|
enable-x
|
||||||
|
@on-scroll="handleTaskScroll">
|
||||||
<div class="project-table-head">
|
<div class="project-table-head">
|
||||||
<Row class="task-row">
|
<Row class="task-row">
|
||||||
<Col span="12">
|
<Col span="12">
|
||||||
@ -294,7 +299,13 @@
|
|||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
</Row>
|
</Row>
|
||||||
<TaskRow v-if="projectData.cacheParameter.showMy" :list="transforTasks(myList)" open-key="my" @on-priority="addTaskOpen" fast-add-task/>
|
<TaskRow
|
||||||
|
v-if="projectData.cacheParameter.showMy"
|
||||||
|
:list="transforTasks(myList)"
|
||||||
|
:task-visibilitys="taskRowVisibilitys"
|
||||||
|
open-key="my"
|
||||||
|
@on-priority="addTaskOpen"
|
||||||
|
fast-add-task/>
|
||||||
</div>
|
</div>
|
||||||
<!--协助的任务-->
|
<!--协助的任务-->
|
||||||
<div v-if="helpList.length" :class="['project-table-body', !projectData.cacheParameter.showHelp ? 'project-table-hide' : '']">
|
<div v-if="helpList.length" :class="['project-table-body', !projectData.cacheParameter.showHelp ? 'project-table-hide' : '']">
|
||||||
@ -309,7 +320,12 @@
|
|||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
</Row>
|
</Row>
|
||||||
<TaskRow v-if="projectData.cacheParameter.showHelp" :list="helpList" open-key="help" @on-priority="addTaskOpen"/>
|
<TaskRow
|
||||||
|
v-if="projectData.cacheParameter.showHelp"
|
||||||
|
:list="helpList"
|
||||||
|
:task-visibilitys="taskRowVisibilitys"
|
||||||
|
open-key="help"
|
||||||
|
@on-priority="addTaskOpen"/>
|
||||||
</div>
|
</div>
|
||||||
<!--未完成任务-->
|
<!--未完成任务-->
|
||||||
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectData.cacheParameter.showUndone ? 'project-table-hide' : '']">
|
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectData.cacheParameter.showUndone ? 'project-table-hide' : '']">
|
||||||
@ -324,7 +340,12 @@
|
|||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
<Col span="3"></Col>
|
<Col span="3"></Col>
|
||||||
</Row>
|
</Row>
|
||||||
<TaskRow v-if="projectData.cacheParameter.showUndone" :list="unList" open-key="undone" @on-priority="addTaskOpen"/>
|
<TaskRow
|
||||||
|
v-if="projectData.cacheParameter.showUndone"
|
||||||
|
:list="unList"
|
||||||
|
:task-visibilitys="taskRowVisibilitys"
|
||||||
|
open-key="undone"
|
||||||
|
@on-priority="addTaskOpen"/>
|
||||||
</div>
|
</div>
|
||||||
<!--已完成任务-->
|
<!--已完成任务-->
|
||||||
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectData.cacheParameter.showCompleted ? 'project-table-hide' : '']">
|
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectData.cacheParameter.showCompleted ? 'project-table-hide' : '']">
|
||||||
@ -341,7 +362,13 @@
|
|||||||
<div class="ellipsis">{{projectData.task_num > 0 && projectData.cacheParameter.showCompleted ? $L('完成时间') : ''}}</div>
|
<div class="ellipsis">{{projectData.task_num > 0 && projectData.cacheParameter.showCompleted ? $L('完成时间') : ''}}</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<TaskRow v-if="projectData.cacheParameter.showCompleted" :list="completedList" open-key="completed" @on-priority="addTaskOpen" showCompleteAt/>
|
<TaskRow
|
||||||
|
v-if="projectData.cacheParameter.showCompleted"
|
||||||
|
:list="completedList"
|
||||||
|
:task-visibilitys="taskRowVisibilitys"
|
||||||
|
open-key="completed"
|
||||||
|
@on-priority="addTaskOpen"
|
||||||
|
showCompleteAt/>
|
||||||
</div>
|
</div>
|
||||||
</Scrollbar>
|
</Scrollbar>
|
||||||
<div v-else-if="tabTypeActive === 'gantt'" class="project-gantt">
|
<div v-else-if="tabTypeActive === 'gantt'" class="project-gantt">
|
||||||
@ -624,8 +651,9 @@ export default {
|
|||||||
flowInfo: {},
|
flowInfo: {},
|
||||||
flowList: [],
|
flowList: [],
|
||||||
|
|
||||||
columnVisibility: {},
|
columnVisibilitys: {},
|
||||||
taskVisibility: {},
|
taskVisibilitys: {},
|
||||||
|
taskRowVisibilitys: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -971,6 +999,21 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
projectId: {
|
||||||
|
handler(id) {
|
||||||
|
if (id > 0) {
|
||||||
|
this.getFlowData();
|
||||||
|
this.handleColumnDebounce();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
'allTask.length'() {
|
||||||
|
this.handleColumnDebounce();
|
||||||
|
},
|
||||||
|
windowWidth() {
|
||||||
|
this.handleColumnDebounce();
|
||||||
|
},
|
||||||
projectData() {
|
projectData() {
|
||||||
this.sortData = this.getSort();
|
this.sortData = this.getSort();
|
||||||
},
|
},
|
||||||
@ -984,24 +1027,6 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
projectId: {
|
|
||||||
handler(val) {
|
|
||||||
if (val > 0) {
|
|
||||||
this.getFlowData();
|
|
||||||
this.handleColumnDebounce();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
},
|
|
||||||
'allTask.length'() {
|
|
||||||
this.handleColumnDebounce();
|
|
||||||
},
|
|
||||||
'projectData.cacheParameter.completedTask'() {
|
|
||||||
this.handleColumnDebounce();
|
|
||||||
},
|
|
||||||
windowWidth() {
|
|
||||||
this.handleColumnDebounce();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -1507,8 +1532,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
flowChange(value, data) {
|
flowChange(_, data) {
|
||||||
this.flowInfo = data.pop() || {};
|
this.flowInfo = data.pop() || {};
|
||||||
|
this.handleColumnDebounce();
|
||||||
},
|
},
|
||||||
|
|
||||||
inviteCopy() {
|
inviteCopy() {
|
||||||
@ -1525,10 +1551,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleCompleted() {
|
|
||||||
this.toggleParameter('completedTask');
|
|
||||||
},
|
|
||||||
|
|
||||||
workflowBeforeClose() {
|
workflowBeforeClose() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (!this.$refs.workflow) {
|
if (!this.$refs.workflow) {
|
||||||
@ -1629,15 +1651,16 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggleParameter(data) {
|
toggleParameter(data) {
|
||||||
if (data === 'completedTask') {
|
if (data === 'chat') {
|
||||||
this.$store.dispatch("forgetTaskCompleteTemp", true);
|
|
||||||
} else if (data === 'chat') {
|
|
||||||
if (this.windowPortrait) {
|
if (this.windowPortrait) {
|
||||||
this.$store.dispatch('openDialog', this.projectData.dialog_id)
|
this.$store.dispatch('openDialog', this.projectData.dialog_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (data === 'completedTask') {
|
||||||
|
this.$store.dispatch("forgetTaskCompleteTemp", true);
|
||||||
}
|
}
|
||||||
this.$store.dispatch('toggleProjectParameter', data);
|
this.$store.dispatch('toggleProjectParameter', data);
|
||||||
|
this.handleColumnDebounce();
|
||||||
},
|
},
|
||||||
|
|
||||||
onBack() {
|
onBack() {
|
||||||
@ -1654,7 +1677,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
taskItemVisible({id, column_id}) {
|
taskItemVisible({id, column_id}) {
|
||||||
return this.columnVisibility[column_id] && this.taskVisibility[id]?.visible
|
return this.columnVisibilitys[column_id] && this.taskVisibilitys[id]?.visible
|
||||||
},
|
},
|
||||||
|
|
||||||
taskItemStyle({id, column_id, color}) {
|
taskItemStyle({id, column_id, color}) {
|
||||||
@ -1663,7 +1686,7 @@ export default {
|
|||||||
style.backgroundColor = color;
|
style.backgroundColor = color;
|
||||||
}
|
}
|
||||||
if (!this.taskItemVisible({id, column_id})) {
|
if (!this.taskItemVisible({id, column_id})) {
|
||||||
style.height = (this.taskVisibility[id]?.height || 146) + 'px';
|
style.height = (this.taskVisibilitys[id]?.height || 146) + 'px';
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
@ -1671,9 +1694,16 @@ export default {
|
|||||||
handleColumnDebounce() {
|
handleColumnDebounce() {
|
||||||
if (!this.columnDebounceInvoke) {
|
if (!this.columnDebounceInvoke) {
|
||||||
this.columnDebounceInvoke = debounce(_ => {
|
this.columnDebounceInvoke = debounce(_ => {
|
||||||
if (this.tabTypeActive === 'column') {
|
this.$nextTick(_ => {
|
||||||
this.$nextTick(this.handleColumnScroll)
|
switch (this.tabTypeActive) {
|
||||||
|
case 'column':
|
||||||
|
this.handleColumnScroll()
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
this.handleTaskScroll({target: this.$refs.projectTableScroll?.$el})
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
this.columnDebounceInvoke();
|
this.columnDebounceInvoke();
|
||||||
@ -1690,8 +1720,8 @@ export default {
|
|||||||
if (!columnContainer) {
|
if (!columnContainer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const columnId = parseInt(columnContainer.getAttribute('data-id'))
|
const dataId = columnContainer.getAttribute('data-id')
|
||||||
if (!columnId) {
|
if (!dataId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const mainContainer = this.$refs.projectColumn;
|
const mainContainer = this.$refs.projectColumn;
|
||||||
@ -1711,11 +1741,9 @@ export default {
|
|||||||
columnRect.bottom > mainRect.top
|
columnRect.bottom > mainRect.top
|
||||||
)
|
)
|
||||||
if (visible) {
|
if (visible) {
|
||||||
this.handleTaskScroll({
|
this.handleTaskScroll({target: columnContainer.querySelector('.task-scrollbar')})
|
||||||
target: columnContainer.querySelector('.task-scrollbar')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
this.$set(this.columnVisibility, columnId, visible)
|
this.$set(this.columnVisibilitys, dataId, visible)
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleTaskScroll({target}) {
|
async handleTaskScroll({target}) {
|
||||||
@ -1726,14 +1754,25 @@ export default {
|
|||||||
if (!targetItem.length) {
|
if (!targetItem.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let visibleType = null;
|
||||||
|
switch (this.tabTypeActive) {
|
||||||
|
case 'column':
|
||||||
|
visibleType = 'taskVisibilitys'
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
visibleType = 'taskRowVisibilitys'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
const targetRect = target.getBoundingClientRect();
|
const targetRect = target.getBoundingClientRect();
|
||||||
for (const item of targetItem) {
|
for (const item of targetItem) {
|
||||||
const taskId = parseInt(item.getAttribute('data-id'));
|
const dataId = item.getAttribute('data-id');
|
||||||
if (!taskId) {
|
if (!dataId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const taskRect = item.getBoundingClientRect();
|
const taskRect = item.getBoundingClientRect();
|
||||||
const originalVisible = this.taskVisibility[taskId]?.visible || false;
|
const originalVisible = this[visibleType][dataId]?.visible || false;
|
||||||
const currentVisible = (
|
const currentVisible = (
|
||||||
taskRect.top >= targetRect.top - taskRect.height &&
|
taskRect.top >= targetRect.top - taskRect.height &&
|
||||||
taskRect.bottom <= targetRect.bottom + taskRect.height
|
taskRect.bottom <= targetRect.bottom + taskRect.height
|
||||||
@ -1741,8 +1780,8 @@ export default {
|
|||||||
if (currentVisible === originalVisible) {
|
if (currentVisible === originalVisible) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const firstVisible = this.taskVisibility[taskId] === undefined && currentVisible;
|
const firstVisible = this[visibleType][dataId] === undefined && currentVisible;
|
||||||
this.$set(this.taskVisibility, taskId, {
|
this.$set(this[visibleType], dataId, {
|
||||||
visible: currentVisible,
|
visible: currentVisible,
|
||||||
height: taskRect.height
|
height: taskRect.height
|
||||||
});
|
});
|
||||||
@ -1750,7 +1789,7 @@ export default {
|
|||||||
await this.$nextTick();
|
await this.$nextTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,7 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="task-rows">
|
<div class="task-rows">
|
||||||
<div v-for="(item, key) in list" :key="key" :ref="`task_${item.id}`">
|
<div
|
||||||
<Row class="task-row" :style="item.color ? {backgroundColor: item.color, borderBottomColor: item.color} : {}">
|
v-for="(item, key) in list"
|
||||||
|
:key="key"
|
||||||
|
:ref="`task_${item.id}`"
|
||||||
|
:data-id="`${openKey}_${item.id}`"
|
||||||
|
class="task-item">
|
||||||
|
<Row
|
||||||
|
class="task-row"
|
||||||
|
:style="taskItemStyle(item)">
|
||||||
|
<template v-if="taskItemVisible(`${openKey}_${item.id}`)">
|
||||||
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
|
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
|
||||||
<Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']">
|
<Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']">
|
||||||
<Icon
|
<Icon
|
||||||
@ -93,6 +101,7 @@
|
|||||||
</ETooltip>
|
</ETooltip>
|
||||||
<div v-else-if="showCompleteAt && item.complete_at" :title="item.complete_at">{{completeAtFormat(item.complete_at)}}</div>
|
<div v-else-if="showCompleteAt && item.complete_at" :title="item.complete_at">{{completeAtFormat(item.complete_at)}}</div>
|
||||||
</Col>
|
</Col>
|
||||||
|
</template>
|
||||||
</Row>
|
</Row>
|
||||||
<TaskRow
|
<TaskRow
|
||||||
v-if="taskOpen[item.id]===true"
|
v-if="taskOpen[item.id]===true"
|
||||||
@ -139,6 +148,10 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
taskVisibilitys: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -279,6 +292,23 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
return time.format('YYYY-MM-DD')
|
return time.format('YYYY-MM-DD')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
taskItemVisible(key) {
|
||||||
|
return this.parentId > 0 || this.taskVisibilitys[key]?.visible
|
||||||
|
},
|
||||||
|
|
||||||
|
taskItemStyle({id, color}) {
|
||||||
|
const style = {}
|
||||||
|
if (color) {
|
||||||
|
style.backgroundColor = color;
|
||||||
|
style.borderBottomColor = color;
|
||||||
|
}
|
||||||
|
const key = `${this.openKey}_${id}`;
|
||||||
|
if (!this.taskItemVisible(key)) {
|
||||||
|
style.height = (this.taskVisibilitys[key]?.height || 49) + 'px';
|
||||||
|
}
|
||||||
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user