Merge {selectedBooks.length} books
@@ -247,16 +318,13 @@ (value) => { // Bound, not passed as a bare `true`: the dialog closes itself on an // outside click or Escape, and if that never reaches `mergingBooks` - // the snapshot stays set — the button then re-assigns the same + // the snapshot stays set — the menu item then re-assigns the same // selection, nothing changes, and the dialog never reopens. if (!value) mergingBooks = null; } } onmerged={(_survivor, folded) => { - // Only the folded records are gone; the survivor is still in the library. - libraryState.activeLibrary!.total! -= folded.length; - bookshelfState.deletedBooks(folded); - selectionState.deselectAll(); + afterMerge(folded); mergingBooks = null; }} /> diff --git a/frontend/src/routes/(root)/settings/libraries/[libraryId]/duplicates/+page.svelte b/frontend/src/routes/(root)/settings/libraries/[libraryId]/duplicates/+page.svelte index 7e0f2b7..de35cdc 100644 --- a/frontend/src/routes/(root)/settings/libraries/[libraryId]/duplicates/+page.svelte +++ b/frontend/src/routes/(root)/settings/libraries/[libraryId]/duplicates/+page.svelte @@ -3,21 +3,23 @@ import { resolve } from '$app/paths'; import { invalidate } from '$app/navigation'; import { toast } from 'svelte-sonner'; - import { CopyCheck, Fingerprint, Type } from '@lucide/svelte'; + import { CopyCheck, Fingerprint, GitMerge, SlidersHorizontal, Type } from '@lucide/svelte'; import * as Card from '$lib/components/ui/card/index.js'; import * as Empty from '$lib/components/ui/empty/index.js'; + import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js'; import { Badge } from '$lib/components/ui/badge/index.js'; - import { Button } from '$lib/components/ui/button/index.js'; + import { Button, buttonVariants } from '$lib/components/ui/button/index.js'; import BookImage from '$lib/components/view/book-image.svelte'; import GeneratedCover from '$lib/components/view/generated-cover.svelte'; import { dismissDuplicateBooks } from '$lib/api/book.remote'; import MergeBooks from '$lib/components/forms/merge-books/merge-books.svelte'; + import { mergeInto } from '$lib/components/forms/merge-books/merge'; import type { Book, DuplicateBookGroup } from '$lib/schema'; let { data }: { data: { groups: DuplicateBookGroup[]; books: Book[] } } = $props(); - // The group being merged, or null when the dialog is closed. + // The group open in the workbench, or null when it is closed. let merging = $state