!72 czh-20260701-优化未收藏的计划的显示
Merge pull request !72 from 陈志浩/refactor/tasklist-20260701
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -274,7 +274,7 @@
|
||||
<div class="list-group-col list-group-col-secret">密级</div>
|
||||
<div class="list-group-col list-group-col-time">创建时间</div>
|
||||
</div>
|
||||
<div v-for="list in allTaskLists" :key="list.id" class="list-group-row" @click="emit('list-select', list.id)">
|
||||
<div v-for="list in allTaskLists" :key="list.id" class="list-group-row" @click="onListRowClick(list)">
|
||||
<div class="list-group-col list-group-col-name">
|
||||
<Icon icon="ant-design:file-text-outlined" class="list-icon" size="16" />
|
||||
<span class="list-name-text">{{ list.name }}</span>
|
||||
@@ -915,6 +915,7 @@
|
||||
'create-list': [];
|
||||
'load-more': [];
|
||||
'search-keyword': [keyword: string];
|
||||
'preview-list': [list: TaskList];
|
||||
}>();
|
||||
|
||||
const userStore = useUserStore();
|
||||
@@ -1255,6 +1256,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onListRowClick(list: TaskList) {
|
||||
if (isFavorited(list.id)) {
|
||||
emit('list-select', list.id);
|
||||
} else {
|
||||
emit('preview-list', list);
|
||||
}
|
||||
}
|
||||
|
||||
const _isOwner = computed(() => props.currentList?.myPermission === '1');
|
||||
const canEdit = computed(() => props.currentList?.myPermission === '1' || props.currentList?.myPermission === '2');
|
||||
const isReadOnly = computed(() => props.currentList?.myPermission === '3');
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
<Icon icon="tasklist-desc|svg" />
|
||||
</span>
|
||||
<div class="detail-row-content">
|
||||
<a-textarea v-if="showDescEditor && !isFullReadOnly" v-model:value="taskData.taskDesc" :rows="3" placeholder="添加描述..." autofocus @blur="onDescBlur" />
|
||||
<a-textarea ref="descTextareaRef" v-if="showDescEditor && !isFullReadOnly" v-model:value="taskData.taskDesc" :rows="3" placeholder="添加描述..." @blur="onDescBlur" />
|
||||
<span v-else class="desc-trigger" :class="{ 'readonly-field': isFullReadOnly }" @click="!isFullReadOnly && (showDescEditor = true)">
|
||||
{{ taskData.taskDesc || '添加描述' }}
|
||||
</span>
|
||||
@@ -218,11 +218,11 @@
|
||||
</span>
|
||||
<div class="detail-row-content">
|
||||
<a-textarea
|
||||
ref="remarkTextareaRef"
|
||||
v-if="showRemarkEditor && !isFullReadOnly"
|
||||
v-model:value="taskData.remark"
|
||||
:rows="3"
|
||||
placeholder="添加其他事项说明..."
|
||||
autofocus
|
||||
@blur="onRemarkBlur"
|
||||
/>
|
||||
<span v-else class="desc-trigger" :class="{ 'readonly-field': isFullReadOnly }" @click="!isFullReadOnly && (showRemarkEditor = true)">
|
||||
@@ -309,10 +309,10 @@
|
||||
<span class="feishu-subtask-drag-placeholder"></span>
|
||||
<span class="feishu-subtask-check feishu-subtask-check-empty"></span>
|
||||
<a-input
|
||||
ref="subTaskInputRef"
|
||||
v-model:value="newSubTaskName"
|
||||
size="small"
|
||||
placeholder="输入子事项标题,按回车确认..."
|
||||
autofocus
|
||||
class="feishu-subtask-input"
|
||||
@press-enter="handleSubmitSubTask"
|
||||
@blur="showNewSubTaskInput = false"
|
||||
@@ -330,16 +330,10 @@
|
||||
<span class="detail-row-icon">
|
||||
<Icon icon="tasklist-followers|svg" />
|
||||
</span>
|
||||
<div v-if="!isFullReadOnly" class="follower-clickable" @click="openDrawerUserSelect('followers')">
|
||||
<div class="follower-clickable" @click="isFullReadOnly ? toggleFollow() : openDrawerUserSelect('followers')">
|
||||
<span class="follower-label">添加关注人</span>
|
||||
<AvatarDisplay v-if="followers.length > 0" :names="taskData.followersName" :size="24" :show-name="false" />
|
||||
<AvatarDisplay v-if="followers.length > 0" :names="taskData.followersName" :size="24" :show-name="followers.length === 1" />
|
||||
</div>
|
||||
<template v-else>
|
||||
<span v-if="followers.length === 0" class="follower-empty">无关注人</span>
|
||||
<a-tooltip v-else :title="taskData.followersName" placement="top">
|
||||
<AvatarDisplay :names="taskData.followersName" :size="24" :show-name="false" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -408,11 +402,14 @@
|
||||
const isFullReadOnly = computed(() => isReadOnly.value && !isAssigneeEdit.value);
|
||||
const showNewSubTaskInput = ref(false);
|
||||
const newSubTaskName = ref('');
|
||||
const subTaskInputRef = ref();
|
||||
const startTimeDayjs = ref<string | null>(null);
|
||||
const endTimeDayjs = ref<string | null>(null);
|
||||
const editingTitle = ref(false);
|
||||
const showDescEditor = ref(false);
|
||||
const showRemarkEditor = ref(false);
|
||||
const descTextareaRef = ref();
|
||||
const remarkTextareaRef = ref();
|
||||
const subtaskExpanded = ref(true);
|
||||
|
||||
const subTaskUserSelectId = ref<string>('');
|
||||
@@ -526,6 +523,27 @@
|
||||
endTimeDayjs.value = data?.task?.endTime || null;
|
||||
});
|
||||
|
||||
watch(showNewSubTaskInput, async (val) => {
|
||||
if (val) {
|
||||
await nextTick();
|
||||
subTaskInputRef.value?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
watch(showDescEditor, async (val) => {
|
||||
if (val) {
|
||||
await nextTick();
|
||||
descTextareaRef.value?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
watch(showRemarkEditor, async (val) => {
|
||||
if (val) {
|
||||
await nextTick();
|
||||
remarkTextareaRef.value?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
function autoSave() {
|
||||
if (taskData.value) {
|
||||
const updated = {
|
||||
@@ -589,7 +607,7 @@
|
||||
}
|
||||
taskData.value.followersId = idList.join(',');
|
||||
taskData.value.followersName = nameList.join(',');
|
||||
autoSave();
|
||||
emit('unfollow-task', taskData.value.id);
|
||||
} else {
|
||||
const idList = (taskData.value.followersId || '').split(',').filter(Boolean);
|
||||
const nameList = (taskData.value.followersName || '').split(/[,,、]/).map((s) => s.trim()).filter(Boolean);
|
||||
@@ -599,7 +617,7 @@
|
||||
}
|
||||
taskData.value.followersId = idList.join(',');
|
||||
taskData.value.followersName = nameList.join(',');
|
||||
autoSave();
|
||||
emit('follow-task', taskData.value.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
@create-list="onCreateListModal('')"
|
||||
@load-more="onLoadMoreListViews"
|
||||
@search-keyword="onSearchKeywordChange"
|
||||
@preview-list="onPreviewList"
|
||||
/>
|
||||
<TaskFlatView
|
||||
v-else
|
||||
@@ -103,6 +104,19 @@
|
||||
@move-task="onMoveTask"
|
||||
/>
|
||||
<CollaboratorModal ref="collaboratorModalRef" :task-list-id="collaboratorTargetListId || currentListId" :secret-level="collaboratorTargetList ? collaboratorTargetList.secretLevel || 1 : currentList?.secretLevel || 1" @changed="onCollaboratorsChanged" />
|
||||
<PlanPreviewModal
|
||||
:visible="previewModalVisible"
|
||||
:list-id="previewListId"
|
||||
:list-name="previewListName"
|
||||
:secret-level="previewSecretLevel"
|
||||
:secret-text="previewSecretText"
|
||||
:collaborator-names="previewCollaboratorNames"
|
||||
:is-favorited="previewIsFavorited"
|
||||
@update:visible="(v) => (previewModalVisible = v)"
|
||||
@add-to-favorites="onAddToFavorites"
|
||||
@remove-from-favorites="onRemoveFavorite"
|
||||
@task-click="onPreviewTaskClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -119,6 +133,7 @@
|
||||
import CreateListModal from './components/CreateListModal.vue';
|
||||
import TaskDetailDrawer from './components/TaskDetailDrawer.vue';
|
||||
import CollaboratorModal from './components/CollaboratorModal.vue';
|
||||
import PlanPreviewModal from './components/PlanPreviewModal.vue';
|
||||
import {
|
||||
getMyFavorites,
|
||||
addTaskListGroup,
|
||||
@@ -198,6 +213,14 @@
|
||||
const collaboratorTargetListId = ref('');
|
||||
const defaultGroupRealIdMap = ref<Record<string, string>>({});
|
||||
|
||||
const previewModalVisible = ref(false);
|
||||
const previewListId = ref('');
|
||||
const previewListName = ref('');
|
||||
const previewSecretLevel = ref(1);
|
||||
const previewSecretText = ref('非密');
|
||||
const previewCollaboratorNames = ref('');
|
||||
const previewIsFavorited = computed(() => favoriteIdMap.value.has(previewListId.value));
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const currentUserSecurityLevel = ref<number>(3);
|
||||
@@ -531,6 +554,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onPreviewList(list: TaskList) {
|
||||
previewListId.value = list.id;
|
||||
previewListName.value = list.name;
|
||||
previewSecretLevel.value = (list as any).secretLevel || 1;
|
||||
previewSecretText.value = (list as any).secretText || '非密';
|
||||
previewCollaboratorNames.value = list.collaboratorNames || '';
|
||||
previewModalVisible.value = true;
|
||||
}
|
||||
|
||||
function onPreviewTaskClick(task: TaskItem, allPreviewTasks: TaskItem[]) {
|
||||
currentDrawerTaskId.value = task.id;
|
||||
const readOnly = false;
|
||||
openDetailDrawer(true, { task, allTasks: allPreviewTasks, readOnly, secretLevel: previewSecretLevel.value || 1 });
|
||||
}
|
||||
|
||||
function onOpenCollaborator() {
|
||||
collaboratorTargetListId.value = '';
|
||||
collaboratorModalRef.value?.open(currentListId.value);
|
||||
@@ -600,6 +638,11 @@
|
||||
try {
|
||||
await addToFavorites({ taskListId, pid: pid || undefined });
|
||||
await loadFavorites();
|
||||
if (previewModalVisible.value) {
|
||||
previewModalVisible.value = false;
|
||||
onListSelect(taskListId);
|
||||
}
|
||||
message.success('已添加收藏');
|
||||
} catch (e) {
|
||||
console.error('[TaskList] 添加收藏失败', e);
|
||||
}
|
||||
@@ -1386,8 +1429,7 @@
|
||||
await deleteTaskListApi({ id: listId });
|
||||
}
|
||||
if (currentListId.value === listId) {
|
||||
const firstAvailable = findFirstAvailableList();
|
||||
currentListId.value = firstAvailable?.id || '';
|
||||
onQuickAccessTabClick('all');
|
||||
}
|
||||
await loadFavorites();
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user