From 543e7055b979913fe969425b0eebbdd5d1aa6d11 Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 3 Apr 2026 14:55:30 +0200 Subject: [PATCH] feat(manacore/web): add undo toasts to all 14 DetailViews + task completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend undo toast coverage to all modules: - Delete undo in cards, storage, presi, planta, inventar, skilltree, memoro, questions, uload, mukke, citycorners DetailViews - Task completion toggle in todo ListView shows undo toast All deletions can now be reversed within 5 seconds via "Rückgängig". Co-Authored-By: Claude Opus 4.6 (1M context) --- .../web/src/lib/modules/cards/views/DetailView.svelte | 7 ++++++- .../lib/modules/citycorners/views/DetailView.svelte | 10 +++++++++- .../src/lib/modules/inventar/views/DetailView.svelte | 10 +++++++++- .../web/src/lib/modules/memoro/views/DetailView.svelte | 7 ++++++- .../web/src/lib/modules/mukke/views/DetailView.svelte | 7 ++++++- .../web/src/lib/modules/planta/views/DetailView.svelte | 7 ++++++- .../web/src/lib/modules/presi/views/DetailView.svelte | 10 +++++++++- .../src/lib/modules/questions/views/DetailView.svelte | 10 +++++++++- .../src/lib/modules/skilltree/views/DetailView.svelte | 7 ++++++- .../src/lib/modules/storage/views/DetailView.svelte | 7 ++++++- .../apps/web/src/lib/modules/todo/ListView.svelte | 6 ++++++ .../web/src/lib/modules/uload/views/DetailView.svelte | 7 ++++++- 12 files changed, 84 insertions(+), 11 deletions(-) diff --git a/apps/manacore/apps/web/src/lib/modules/cards/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/cards/views/DetailView.svelte index c3a8c42f8..dae352167 100644 --- a/apps/manacore/apps/web/src/lib/modules/cards/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/cards/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { deckStore } from '../stores/decks.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Trash } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalDeck, LocalCard } from '../types'; @@ -78,8 +79,12 @@ } async function deleteDeck() { - await deckStore.deleteDeck(deckId); + const id = deckId; + await deckStore.deleteDeck(id); goBack(); + toastStore.undo('Deck gelöscht', () => { + db.table('decks').update(id, { deletedAt: undefined, updatedAt: new Date().toISOString() }); + }); } diff --git a/apps/manacore/apps/web/src/lib/modules/citycorners/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/citycorners/views/DetailView.svelte index 33476746d..f4be32d29 100644 --- a/apps/manacore/apps/web/src/lib/modules/citycorners/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/citycorners/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { favoritesStore } from '../stores/favorites.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Star, Trash } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalLocation, LocalFavorite } from '../types'; @@ -80,11 +81,18 @@ } async function deleteLocation() { - await db.table('ccLocations').update(locationId, { + const id = locationId; + await db.table('ccLocations').update(id, { deletedAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }); goBack(); + toastStore.undo('Ort gelöscht', () => { + db.table('ccLocations').update(id, { + deletedAt: undefined, + updatedAt: new Date().toISOString(), + }); + }); } const categoryLabels: Record = { diff --git a/apps/manacore/apps/web/src/lib/modules/inventar/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/inventar/views/DetailView.svelte index 1e3690bcf..193963a24 100644 --- a/apps/manacore/apps/web/src/lib/modules/inventar/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/inventar/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { collectionsStore } from '../stores/collections.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Trash } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalCollection, LocalItem } from '../types'; @@ -71,8 +72,15 @@ } async function deleteCollection() { - await collectionsStore.delete(collectionId); + const id = collectionId; + await collectionsStore.delete(id); goBack(); + toastStore.undo('Sammlung gelöscht', () => { + db.table('invCollections').update(id, { + deletedAt: undefined, + updatedAt: new Date().toISOString(), + }); + }); } diff --git a/apps/manacore/apps/web/src/lib/modules/memoro/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/memoro/views/DetailView.svelte index 3cb1f9496..3ec625be6 100644 --- a/apps/manacore/apps/web/src/lib/modules/memoro/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/memoro/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { memosStore } from '../stores/memos.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Trash, PushPin } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalMemo, ProcessingStatus } from '../types'; @@ -60,8 +61,12 @@ } async function deleteMemo() { - await memosStore.delete(memoId); + const id = memoId; + await memosStore.delete(id); goBack(); + toastStore.undo('Memo gelöscht', () => { + db.table('memos').update(id, { deletedAt: undefined, updatedAt: new Date().toISOString() }); + }); } function formatDuration(ms: number | null): string { diff --git a/apps/manacore/apps/web/src/lib/modules/mukke/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/mukke/views/DetailView.svelte index 7d4a9a344..70109340c 100644 --- a/apps/manacore/apps/web/src/lib/modules/mukke/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/mukke/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { libraryStore } from '../stores/library.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Heart, Trash } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalSong } from '../types'; @@ -64,8 +65,12 @@ } async function deleteSong() { - await libraryStore.delete(songId); + const id = songId; + await libraryStore.delete(id); goBack(); + toastStore.undo('Song gelöscht', () => { + db.table('songs').update(id, { deletedAt: undefined, updatedAt: new Date().toISOString() }); + }); } function formatDuration(sec?: number | null): string { diff --git a/apps/manacore/apps/web/src/lib/modules/planta/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/planta/views/DetailView.svelte index 77746d48e..f6689f029 100644 --- a/apps/manacore/apps/web/src/lib/modules/planta/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/planta/views/DetailView.svelte @@ -5,6 +5,7 @@ diff --git a/apps/manacore/apps/web/src/lib/modules/questions/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/questions/views/DetailView.svelte index a3db9496b..a8f741d12 100644 --- a/apps/manacore/apps/web/src/lib/modules/questions/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/questions/views/DetailView.svelte @@ -5,6 +5,7 @@ diff --git a/apps/manacore/apps/web/src/lib/modules/storage/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/storage/views/DetailView.svelte index f5c7a5eac..66c045a0b 100644 --- a/apps/manacore/apps/web/src/lib/modules/storage/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/storage/views/DetailView.svelte @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; import { filesStore } from '../stores/files.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Heart, Trash } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import type { LocalFile } from '../types'; @@ -48,8 +49,12 @@ } async function deleteFile() { - await filesStore.deleteFile(fileId); + const id = fileId; + await filesStore.deleteFile(id); goBack(); + toastStore.undo('Datei gelöscht', () => { + db.table('files').update(id, { deletedAt: undefined, updatedAt: new Date().toISOString() }); + }); } function formatSize(bytes: number): string { diff --git a/apps/manacore/apps/web/src/lib/modules/todo/ListView.svelte b/apps/manacore/apps/web/src/lib/modules/todo/ListView.svelte index a6d03f672..9c17666b0 100644 --- a/apps/manacore/apps/web/src/lib/modules/todo/ListView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/todo/ListView.svelte @@ -13,6 +13,7 @@ getTaskStats, } from './queries'; import { tasksStore } from './stores/tasks.svelte'; + import { toastStore } from '@manacore/shared-ui/toast'; import { Circle, Check } from '@manacore/shared-icons'; import type { ViewProps } from '$lib/app-registry'; import { dropTarget, dragSource } from '@manacore/shared-ui/dnd'; @@ -75,7 +76,12 @@ async function toggleComplete(e: Event, id: string) { e.stopPropagation(); + const task = tasks.find((t) => t.id === id); + const wasCompleted = task?.isCompleted ?? false; await tasksStore.toggleComplete(id); + toastStore.undo(wasCompleted ? 'Aufgabe wiederhergestellt' : 'Aufgabe erledigt', () => + tasksStore.toggleComplete(id) + ); } diff --git a/apps/manacore/apps/web/src/lib/modules/uload/views/DetailView.svelte b/apps/manacore/apps/web/src/lib/modules/uload/views/DetailView.svelte index a98c52072..be1cd38ed 100644 --- a/apps/manacore/apps/web/src/lib/modules/uload/views/DetailView.svelte +++ b/apps/manacore/apps/web/src/lib/modules/uload/views/DetailView.svelte @@ -5,6 +5,7 @@