新增: 项目归档
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
>▦</button>
|
||||
</div>
|
||||
<button class="btn btn-ghost" @click="openImportModal">{{ $t('projects.importHistory') }}</button>
|
||||
<button class="btn btn-ghost" @click="openArchiveBox">{{ $t('projects.archiveBox') }}</button>
|
||||
<button class="btn btn-ghost" @click="openTrash">{{ $t('projects.trash') }}</button>
|
||||
<button class="btn btn-primary" @click="showCreateModal = true">{{ $t('projects.create') }}</button>
|
||||
</div>
|
||||
@@ -91,6 +92,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 归档箱模态框(归档功能 P2,V48;对齐回收站 Modal 模式:列表+恢复,无彻底删除——归档可逆) -->
|
||||
<div v-if="showArchiveModal" class="modal-overlay" @click.self="showArchiveModal = false">
|
||||
<div class="modal-box" style="width: 520px">
|
||||
<h3 class="modal-title">{{ $t('projects.archiveBoxTitle') }}</h3>
|
||||
<div v-if="store.archivedProjects.length === 0" class="empty-state" style="padding: 30px 0">{{ $t('projects.archiveBoxEmpty') }}</div>
|
||||
<div v-else class="trash-list">
|
||||
<div class="trash-item" v-for="p in store.archivedProjects" :key="p.id">
|
||||
<div class="trash-info">
|
||||
<span class="trash-name">{{ p.name }}</span>
|
||||
<span class="trash-date">{{ $t('projects.archivedAt') }} {{ formatDate(p.updated_at) }}</span>
|
||||
</div>
|
||||
<div class="trash-actions">
|
||||
<button class="btn btn-ghost btn-sm" :disabled="!!unarchivingId" @click="handleUnarchive(p.id)">{{ $t('projects.unarchive') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-ghost" @click="showArchiveModal = false">{{ $t('common.close') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导入历史项目模态框(F-260614-06 scan 第二步) -->
|
||||
<div v-if="showImportModal" class="modal-overlay" @click.self="closeImportModal">
|
||||
<div class="modal-box import-box">
|
||||
@@ -162,6 +185,7 @@
|
||||
:project="project"
|
||||
:view="viewMode"
|
||||
@delete="handleDelete"
|
||||
@archive="handleArchive"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -348,6 +372,34 @@ async function handlePurge(project: ProjectRecord) {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 归档箱(归档功能 P2,V48;卡片 📦 归档 + 归档箱 Modal 恢复,对齐回收站动线) ──
|
||||
const showArchiveModal = ref(false)
|
||||
const unarchivingId = ref<string | null>(null)
|
||||
|
||||
/** 归档项目:确认后退出主列表(可从归档箱恢复) */
|
||||
async function handleArchive(project: ProjectRecord) {
|
||||
if (!await confirmDialog(t('projects.confirmArchive', { name: project.name }))) return
|
||||
await store.archiveProject(project.id, true)
|
||||
showToast(t('projects.archivedToast'), 'info')
|
||||
}
|
||||
|
||||
async function openArchiveBox() {
|
||||
await store.loadArchivedProjects()
|
||||
showArchiveModal.value = true
|
||||
}
|
||||
|
||||
/** 归档箱内恢复:回主列表 */
|
||||
async function handleUnarchive(id: string) {
|
||||
if (unarchivingId.value) return
|
||||
unarchivingId.value = id
|
||||
try {
|
||||
await store.unarchiveProject(id)
|
||||
showToast(t('projects.unarchivedToast'), 'success')
|
||||
} finally {
|
||||
unarchivingId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
// ── 加载 ──
|
||||
onMounted(() => {
|
||||
store.loadProjects()
|
||||
|
||||
Reference in New Issue
Block a user