diff --git a/webapp/src/components/VaultPage.tsx b/webapp/src/components/VaultPage.tsx index e5dc5a6..7947a2b 100644 --- a/webapp/src/components/VaultPage.tsx +++ b/webapp/src/components/VaultPage.tsx @@ -79,7 +79,9 @@ export default function VaultPage(props: VaultPageProps) { const [fieldLabel, setFieldLabel] = useState(''); const [fieldValue, setFieldValue] = useState(''); const [localError, setLocalError] = useState(''); + const [pendingArchive, setPendingArchive] = useState(null); const [pendingDelete, setPendingDelete] = useState(null); + const [bulkArchiveOpen, setBulkArchiveOpen] = useState(false); const [bulkDeleteOpen, setBulkDeleteOpen] = useState(false); const [moveOpen, setMoveOpen] = useState(false); const [moveFolderId, setMoveFolderId] = useState('__none__'); @@ -684,6 +686,20 @@ function folderName(id: string | null | undefined): string { } } + async function confirmArchiveSelected(): Promise { + if (!pendingArchive) return; + setBusy(true); + try { + await props.onArchive(pendingArchive); + setPendingArchive(null); + if (isMobileLayout && selectedCipherId === pendingArchive.id) { + setMobilePanel('list'); + } + } finally { + setBusy(false); + } + } + async function confirmBulkArchive(): Promise { const ids = Object.entries(selectedMap) .filter(([, selected]) => selected) @@ -693,6 +709,7 @@ function folderName(id: string | null | undefined): string { try { await props.onBulkArchive(ids); setSelectedMap({}); + setBulkArchiveOpen(false); } finally { setBusy(false); } @@ -795,7 +812,7 @@ function folderName(id: string | null | undefined): string { onToggleCreateMenu={() => setCreateMenuOpen((open) => !open)} onStartCreate={startCreate} onBulkRestore={() => void confirmBulkRestore()} - onBulkArchive={() => void confirmBulkArchive()} + onBulkArchive={() => setBulkArchiveOpen(true)} onBulkUnarchive={() => void confirmBulkUnarchive()} onOpenMove={() => { setMoveFolderId('__none__'); @@ -888,7 +905,7 @@ function folderName(id: string | null | undefined): string { attachmentDownloadPercent={props.attachmentDownloadPercent} onStartEdit={startEdit} onDelete={setPendingDelete} - onArchive={props.onArchive} + onArchive={(cipher) => setPendingArchive(cipher)} onUnarchive={props.onUnarchive} /> )} @@ -902,6 +919,8 @@ function folderName(id: string | null | undefined): string { fieldType={fieldType} fieldLabel={fieldLabel} fieldValue={fieldValue} + archiveConfirmOpen={!!pendingArchive} + bulkArchiveOpen={bulkArchiveOpen} pendingDeleteOpen={!!pendingDelete} bulkDeleteOpen={bulkDeleteOpen} sidebarTrashMode={sidebarFilter.kind === 'trash'} @@ -944,6 +963,10 @@ function folderName(id: string | null | undefined): string { onFieldTypeChange={setFieldType} onFieldLabelChange={setFieldLabel} onFieldValueChange={setFieldValue} + onConfirmArchive={() => void confirmArchiveSelected()} + onCancelArchive={() => setPendingArchive(null)} + onConfirmBulkArchive={() => void confirmBulkArchive()} + onCancelBulkArchive={() => setBulkArchiveOpen(false)} onConfirmDelete={() => void deleteSelected()} onCancelDelete={() => setPendingDelete(null)} onConfirmBulkDelete={() => void confirmBulkDelete()} diff --git a/webapp/src/components/vault/VaultDialogs.tsx b/webapp/src/components/vault/VaultDialogs.tsx index ae748e3..0d5e0af 100644 --- a/webapp/src/components/vault/VaultDialogs.tsx +++ b/webapp/src/components/vault/VaultDialogs.tsx @@ -8,6 +8,8 @@ interface VaultDialogsProps { fieldType: CustomFieldType; fieldLabel: string; fieldValue: string; + archiveConfirmOpen: boolean; + bulkArchiveOpen: boolean; pendingDeleteOpen: boolean; bulkDeleteOpen: boolean; sidebarTrashMode: boolean; @@ -26,6 +28,10 @@ interface VaultDialogsProps { onFieldTypeChange: (value: CustomFieldType) => void; onFieldLabelChange: (value: string) => void; onFieldValueChange: (value: string) => void; + onConfirmArchive: () => void; + onCancelArchive: () => void; + onConfirmBulkArchive: () => void; + onCancelBulkArchive: () => void; onConfirmDelete: () => void; onCancelDelete: () => void; onConfirmBulkDelete: () => void; @@ -88,6 +94,26 @@ export default function VaultDialogs(props: VaultDialogsProps) { )} + + + + > = { txt_delete_item_failed: "Delete item failed", txt_delete_permanently: "Delete Permanently", txt_archive: "Archive", + txt_archive_item: "Archive Item", + txt_archive_item_message: "After archiving, this item will be excluded from general search results and autofill suggestions.", + txt_archive_selected_items: "Archive Items", + txt_archive_selected_items_message: "After archiving, {count} selected items will be excluded from general search results and autofill suggestions.", txt_archived: "Archived", txt_archive_selected: "Archive", txt_item_archived: "Item archived", @@ -1376,6 +1380,10 @@ zhCNOverrides.txt_import_export_title = '导入导出'; zhCNOverrides.txt_new_type_header = '新建{type}'; zhCNOverrides.txt_edit_type_header = '编辑{type}'; zhCNOverrides.txt_archive = '归档'; +zhCNOverrides.txt_archive_item = '归档项目'; +zhCNOverrides.txt_archive_item_message = '归档后,此项目将被排除在一般搜索结果和自动填充建议之外。'; +zhCNOverrides.txt_archive_selected_items = '归档项目'; +zhCNOverrides.txt_archive_selected_items_message = '归档后,所选的 {count} 个项目将被排除在一般搜索结果和自动填充建议之外。'; zhCNOverrides.txt_archived = '已归档'; zhCNOverrides.txt_archive_selected = '归档'; zhCNOverrides.txt_item_archived = '项目已归档';