From cce8586235ca03196ec74ae1e082efd1c68fb3ee Mon Sep 17 00:00:00 2001 From: curo1305 Date: Sun, 31 May 2026 15:11:31 +0200 Subject: [PATCH] =?UTF-8?q?feat(06.2-03):=20frontend=20=E2=80=94=20CloudDe?= =?UTF-8?q?leteWarningModal=20+=20remove=5Fonly=20path=20in=20DocumentView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api/client.js: deleteDocument gains removeOnly param; deleteDocumentRemoveOnly wrapper added - DocumentView.vue: confirmDelete inspects response.cloud_delete_failed, shows modal on failure - DocumentView.vue: inline CloudDeleteWarningModal (C-3 contract) with Remove from app / Cancel - confirmRemoveOnly() calls DELETE ?remove_only=true and navigates to / Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/api/client.js | 9 ++++- frontend/src/views/DocumentView.vue | 59 ++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js index b71bae7..2affa11 100644 --- a/frontend/src/api/client.js +++ b/frontend/src/api/client.js @@ -72,8 +72,13 @@ export function getDocument(id) { return request(`/api/documents/${id}`) } -export function deleteDocument(id) { - return request(`/api/documents/${id}`, { method: 'DELETE' }) +export function deleteDocument(id, removeOnly = false) { + const url = removeOnly ? `/api/documents/${id}?remove_only=true` : `/api/documents/${id}` + return request(url, { method: 'DELETE' }) +} + +export function deleteDocumentRemoveOnly(id) { + return deleteDocument(id, true) } export function classifyDocument(id, topics = null) { diff --git a/frontend/src/views/DocumentView.vue b/frontend/src/views/DocumentView.vue index 5eb594f..e2dda75 100644 --- a/frontend/src/views/DocumentView.vue +++ b/frontend/src/views/DocumentView.vue @@ -108,6 +108,40 @@ :doc="doc" @close="showPreviewModal = false" /> + + +
+ +
@@ -135,6 +169,8 @@ const suggestions = ref([]) const selectedSuggestions = ref([]) const showPreviewModal = ref(false) const pdfOpenMode = ref('new_tab') +const showCloudDeleteWarning = ref(false) +const cloudProviderName = ref('your cloud storage') const isPdf = computed(() => { if (!doc.value) return false @@ -229,12 +265,33 @@ async function createSelectedTopics() { await reclassify() } +const _PROVIDER_NAMES = { google_drive: 'Google Drive', onedrive: 'OneDrive', nextcloud: 'Nextcloud', webdav: 'WebDAV' } + async function confirmDelete() { if (!confirm(`Delete "${doc.value.original_name}"?`)) return - await docsStore.remove(doc.value.id) + const resp = await api.deleteDocument(doc.value.id) + if (resp && resp.cloud_delete_failed) { + cloudProviderName.value = _PROVIDER_NAMES[doc.value.storage_backend] || 'your cloud storage' + showCloudDeleteWarning.value = true + return + } router.push('/') } +async function confirmRemoveOnly() { + try { + await api.deleteDocumentRemoveOnly(doc.value.id) + showCloudDeleteWarning.value = false + router.push('/') + } catch (e) { + // error shown inline if needed — modal stays open + } +} + +function cancelCloudDeleteWarning() { + showCloudDeleteWarning.value = false +} + function formatDate(iso) { if (!iso) return '' return new Date(iso).toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })