diff --git a/resources/assets/js/pages/manage/components/ProjectColumn.vue b/resources/assets/js/pages/manage/components/ProjectColumn.vue
new file mode 100644
index 000000000..ddf32cd80
--- /dev/null
+++ b/resources/assets/js/pages/manage/components/ProjectColumn.vue
@@ -0,0 +1,260 @@
+
+
+
+
+
+
({{projectPanel.panelTask(column.tasks).length}})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{item.flow_item_name}}
+
+
{{item.name}}
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
{{item.file_num}}
+
{{item.msg_num}}
+
+
+
{{item.sub_complete}}/{{item.sub_num}}
+
+
+ {{ expiresFormat(item.end_at) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/assets/js/pages/manage/components/ProjectPanel.vue b/resources/assets/js/pages/manage/components/ProjectPanel.vue
index e7c0035fb..b7ff8cbb1 100644
--- a/resources/assets/js/pages/manage/components/ProjectPanel.vue
+++ b/resources/assets/js/pages/manage/components/ProjectPanel.vue
@@ -148,140 +148,20 @@
tag="ul"
draggable=".column-item"
@sort="sortUpdate(true)">
-
{{$L('添加列表')}}
@@ -691,8 +571,8 @@ import {debounce} from "lodash";
import Draggable from 'vuedraggable'
import TaskPriority from "./TaskPriority";
import {mapGetters, mapState} from "vuex";
-import TaskAddSimple from "./TaskAddSimple";
import TaskRow from "./TaskRow";
+import ProjectColumn from "./ProjectColumn.vue";
import TaskArchived from "./TaskArchived";
import ProjectLog from "./ProjectLog";
import DrawerOverlay from "../../../components/DrawerOverlay";
@@ -700,9 +580,7 @@ import ProjectTaskTag from "./ProjectTaskTag";
import ProjectTaskTemplate from "./ProjectTaskTemplate";
import ProjectWorkflow from "./ProjectWorkflow";
import ProjectPermission from "./ProjectPermission";
-import TaskMenu from "./TaskMenu";
import TaskDeleted from "./TaskDeleted";
-import TaskTag from "./ProjectTaskTag/tags.vue";
import ProjectGantt from "./ProjectGantt";
import ProjectTableGroupDropdown from "./ProjectTableGroupDropdown.vue";
import ProjectFlowFilterDropdown from "./ProjectFlowFilterDropdown.vue";
@@ -713,6 +591,7 @@ import emitter from "../../../store/events";
import transformEmojiToHtml from "../../../utils/emoji";
import {projectTableGroups, normalizeProjectTableGroups, projectWeekRanges, taskMatchesProjectGroup} from "../../../utils/projectTableGroups";
import {scrollToStableTarget} from "../../../utils/scrollToStableTarget";
+import {updateTaskVisibilitys} from "../../../utils/taskVisibility";
import {emptyProjectFlowFilter, projectFlowFilterCount, taskMatchesProjectFlowFilter} from "../../../utils/projectFlowFilter";
export default {
@@ -721,7 +600,6 @@ export default {
VMPreviewNostyle,
UserAvatarTip,
UserSelect,
- TaskMenu,
ProjectTaskTag,
ProjectTaskTemplate,
ProjectWorkflow,
@@ -730,11 +608,10 @@ export default {
ProjectLog,
TaskArchived,
TaskRow,
+ ProjectColumn,
Draggable,
- TaskAddSimple,
TaskPriority,
TaskDeleted,
- TaskTag,
ProjectGantt,
ProjectTableGroupDropdown,
ProjectFlowFilterDropdown,
@@ -743,8 +620,6 @@ export default {
return {
loading: false,
- columnMenuIds: [],
-
nowTime: $A.dayjs().unix(),
nowInterval: null,
tableToday: $A.daytz().format('YYYY-MM-DD'),
@@ -797,12 +672,16 @@ export default {
flowFilterOpen: false,
flowList: [],
- columnVisibilitys: {},
- taskVisibilitys: {},
taskRowVisibilitys: {},
}
},
+ provide() {
+ return {
+ projectPanel: this,
+ }
+ },
+
mounted() {
this.nowInterval = setInterval(() => {
this.nowTime = $A.dayjs().unix();
@@ -1517,12 +1396,6 @@ export default {
});
},
- onColumnMenuVisible(columnId, visible) {
- if (visible && !this.columnMenuIds.includes(columnId)) {
- this.columnMenuIds.push(columnId)
- }
- },
-
dropColumn(column, command) {
if (this.isDepartmentReadonly) {
return;
@@ -1895,13 +1768,6 @@ export default {
}
},
- openMenu(event, task) {
- const el = this.$refs[`taskMenu_${task.id}`];
- if (el) {
- el[0].handleClick(event)
- }
- },
-
taskIsHidden(task) {
const {id, name, desc, complete_at} = task;
const {searchText} = this;
@@ -1921,12 +1787,6 @@ export default {
return false;
},
- ownerUser(list) {
- return list.filter(({owner}) => owner == 1).sort((a, b) => {
- return a.id - b.id;
- });
- },
-
inviteGet(refresh) {
this.inviteLoad++;
this.$store.dispatch("call", {
@@ -2060,10 +1920,6 @@ export default {
return !taskMatchesProjectFlowFilter(task, this.flowFilter);
},
- expiresFormat(date) {
- return $A.countDownFormat(this.nowTime, date)
- },
-
setTableGroupVisible(group, visible) {
const selected = this.visibleTableGroups;
if (!visible && selected.length === 1 && selected.includes(group.key)) return;
@@ -2156,21 +2012,6 @@ export default {
this.settingData = { ...this.settingData, archive_method: value };
},
- taskItemVisible({id, column_id}) {
- return this.columnVisibilitys[column_id] && this.taskVisibilitys[id]?.visible
- },
-
- taskItemStyle({id, column_id, complete_at, color}) {
- const style = {}
- if (color) {
- style.backgroundColor = color;
- }
- if (!this.taskItemVisible({id, column_id})) {
- style.height = (this.taskVisibilitys[id]?.height || (complete_at ? 46 :146)) + 'px';
- }
- return style;
- },
-
handleColumnDebounce(wait = 10, needView = false) {
if (typeof wait === "boolean") {
needView = wait
@@ -2210,85 +2051,22 @@ export default {
},
handleColumnScroll() {
+ const mainContainer = this.$refs.projectColumn;
+ if (!mainContainer) {
+ return
+ }
+ const mainRect = mainContainer.getBoundingClientRect();
this.columnList.forEach(({id}) => {
const ref = this.$refs[`column_${id}`];
- ref && this.checkColumnVisibility(ref[0])
+ ref && ref[0] && ref[0].checkVisibility(mainRect)
})
},
- checkColumnVisibility(columnContainer = null) {
- if (!columnContainer) {
+ handleTaskScroll({target}) {
+ if (this.tabTypeActive !== 'table') {
return
}
- const dataId = columnContainer.getAttribute('data-id')
- if (!dataId) {
- return
- }
- const mainContainer = this.$refs.projectColumn;
- if (!mainContainer) {
- return false;
- }
-
- // 获取容器的边界信息
- const mainRect = mainContainer.getBoundingClientRect();
- const columnRect = columnContainer.getBoundingClientRect();
-
- // 检查元素是否在容器的可视区域内
- const visible = (
- columnRect.left < mainRect.right &&
- columnRect.right > mainRect.left &&
- columnRect.top < mainRect.bottom &&
- columnRect.bottom > mainRect.top
- )
- if (visible) {
- this.handleTaskScroll({target: columnContainer.querySelector('.task-scrollbar')})
- }
- this.$set(this.columnVisibilitys, dataId, visible)
- },
-
- async handleTaskScroll({target}) {
- if (!target) {
- return
- }
- const targetItem = target.querySelectorAll('.task-item');
- if (!targetItem.length) {
- return
- }
- let visibleType = null;
- switch (this.tabTypeActive) {
- case 'column':
- visibleType = 'taskVisibilitys'
- break;
- case 'table':
- visibleType = 'taskRowVisibilitys'
- break;
- default:
- return
- }
- const targetRect = target.getBoundingClientRect();
- for (const item of targetItem) {
- const dataId = item.getAttribute('data-id');
- if (!dataId) {
- continue;
- }
- const taskRect = item.getBoundingClientRect();
- const originalVisible = this[visibleType][dataId]?.visible || false;
- const currentVisible = (
- taskRect.top >= targetRect.top - taskRect.height &&
- taskRect.bottom <= targetRect.bottom + taskRect.height
- );
- if (currentVisible === originalVisible) {
- continue;
- }
- const firstVisible = this[visibleType][dataId] === undefined && currentVisible;
- this.$set(this[visibleType], dataId, {
- visible: currentVisible,
- height: taskRect.height
- });
- if (firstVisible) {
- await this.$nextTick();
- }
- }
+ return updateTaskVisibilitys(this, target, this.taskRowVisibilitys)
},
/**
diff --git a/resources/assets/js/utils/taskVisibility.js b/resources/assets/js/utils/taskVisibility.js
new file mode 100644
index 000000000..adad31fa7
--- /dev/null
+++ b/resources/assets/js/utils/taskVisibility.js
@@ -0,0 +1,35 @@
+// 按滚动容器可视区(上下各多算一个任务高度)更新任务的可见状态,未可见的任务只渲染占位
+// 首次可见的任务逐个等待渲染,让后续任务按真实高度判断
+export async function updateTaskVisibilitys(vm, target, visibilitys) {
+ if (!target) {
+ return
+ }
+ const targetItem = target.querySelectorAll('.task-item');
+ if (!targetItem.length) {
+ return
+ }
+ const targetRect = target.getBoundingClientRect();
+ for (const item of targetItem) {
+ const dataId = item.getAttribute('data-id');
+ if (!dataId) {
+ continue;
+ }
+ const taskRect = item.getBoundingClientRect();
+ const originalVisible = visibilitys[dataId]?.visible || false;
+ const currentVisible = (
+ taskRect.top >= targetRect.top - taskRect.height &&
+ taskRect.bottom <= targetRect.bottom + taskRect.height
+ );
+ if (currentVisible === originalVisible) {
+ continue;
+ }
+ const firstVisible = visibilitys[dataId] === undefined && currentVisible;
+ vm.$set(visibilitys, dataId, {
+ visible: currentVisible,
+ height: taskRect.height
+ });
+ if (firstVisible) {
+ await vm.$nextTick();
+ }
+ }
+}