diff --git a/frontend/src/lib/components/forms/edit-book/edit-book.svelte b/frontend/src/lib/components/forms/edit-book/edit-book.svelte index cfcc300..edbc865 100644 --- a/frontend/src/lib/components/forms/edit-book/edit-book.svelte +++ b/frontend/src/lib/components/forms/edit-book/edit-book.svelte @@ -1,18 +1,25 @@ - - - + +
+ - - - - +
+ +
+
- - - - - - + + +

Cover and file changes apply immediately

+
+ + +
+
+ {/key} {/if} diff --git a/frontend/src/lib/components/forms/edit-book/edit-cover.svelte b/frontend/src/lib/components/forms/edit-book/edit-cover.svelte index 86b31f4..ab834f9 100644 --- a/frontend/src/lib/components/forms/edit-book/edit-cover.svelte +++ b/frontend/src/lib/components/forms/edit-book/edit-cover.svelte @@ -1,34 +1,23 @@ -
{ - try { - await submit(); - form.reset(); - open = false; - toast.success('Updated book cover!'); - } catch (error) { - console.error('Failed to update book cover: ', error); - toast.error('Failed to update cover.'); - } - })} - enctype="multipart/form-data" - class="grid grid-cols-[1fr_2fr] gap-4 p-6" -> - +
+

Cover

-
- -
+ + + { + try { + await submit(); + form.reset(); + // Deliberately does not close the dialog. The cover is one panel of a + // larger form now, and closing here would throw away metadata edits + // the reader has not saved yet. + toast.success('Cover updated'); + } catch (error) { + console.error('Failed to update book cover: ', error); + toast.error('Failed to update the cover'); + } + })} + enctype="multipart/form-data" + class="flex flex-col gap-2" + > + + -
- -
- {#if updateBookCover.fields.file.value()} -
-
- {updateBookCover.fields.file.value().name} - {displaySize(updateBookCover.fields.file.value().size)} -
- -
- {/if} -
- -
- - Auto upload on file drop - -
-
- + +
diff --git a/frontend/src/lib/components/forms/edit-book/edit-files.svelte b/frontend/src/lib/components/forms/edit-book/edit-files.svelte index e932bd8..31dbf95 100644 --- a/frontend/src/lib/components/forms/edit-book/edit-files.svelte +++ b/frontend/src/lib/components/forms/edit-book/edit-files.svelte @@ -1,98 +1,196 @@ -
{ - try { - await submit(); +
+

Files

- // Check if there are any validation issues - const issues = uploadBookFiles.fields.allIssues(); - if (issues && issues.length > 0) { - return; - } + {#if files.length === 0} +

+ No files yet. Add one below so this book can be read or downloaded. +

+ {/if} - // Reset the files field - uploadBookFiles.fields.files.set([]); - toast.success('Files successfully added!'); - } catch (error) { - console.error('Failed to upload files: ', error); - toast.error('Failed to upload files'); - } - })} - bind:this={formEl} - enctype="multipart/form-data" - class="flex w-full flex-col gap-2 p-4" -> - - - - -
- {#each files as file, idx} -
-
- {file.name} - {displaySize(file.size)} -
- -
- {/each} -
+ {getFileType(file.filename)} + -
- - Auto upload on file drop - -
- + + {file.filename} + + {formatFileSize(file.size)} + + + + + + + + {/each} + + {#each pending as file (file.name)} +
  • + + + {file.name} + Uploading… + +
  • + {/each} + + +
    { + try { + await submit(); + + const issues = uploadBookFiles.fields.allIssues(); + if (issues && issues.length > 0) return; + + // The endpoint answers with the updated book, so the new files come + // back with their ids rather than having to be guessed at. + files = uploadBookFiles.result?.files ?? files; + uploadBookFiles.fields.files.set([]); + toast.success('Files added'); + } catch (error) { + console.error('Failed to add files: ', error); + toast.error('Failed to add files'); + } + })} + enctype="multipart/form-data" + class="flex flex-col gap-2" + > + + + + + +
    + + + + + Remove {fileToDelete?.filename}? + + This cannot be undone. The other files on this book are not affected. + + + + +
    + + + Also delete the file from the filesystem + +
    + + + Cancel + + Remove + + +
    +
    diff --git a/frontend/src/lib/components/forms/edit-book/edit-metadata.svelte b/frontend/src/lib/components/forms/edit-book/edit-metadata.svelte index 5345d6c..45e149f 100644 --- a/frontend/src/lib/components/forms/edit-book/edit-metadata.svelte +++ b/frontend/src/lib/components/forms/edit-book/edit-metadata.svelte @@ -1,18 +1,23 @@ - -
    { - try { - await submit(); - - // Check if there are any validation issues - const issues = updateBookMetadata.fields.allIssues(); - if (issues && issues.length > 0) { - return; - } - - open = false; - book = book; - toast.success('Updated book metadata!'); - } catch (error) { - console.error('Error occurred updating book metadata: ', error); - toast.error('Failed to update book metadata.'); - } - })} +{#snippet groupHeading(label: string)} +

    - - - - - + {label} +

    +{/snippet} - - - Title - - {#each updateBookMetadata.fields.title.issues() ?? [] as issue} - {issue.message} - {/each} - + { + try { + await submit(); - - - Subtitle - - {#each updateBookMetadata.fields.subtitle.issues() ?? [] as issue} - {issue.message} - {/each} - + // Check if there are any validation issues + const issues = updateBookMetadata.fields.allIssues(); + if (issues && issues.length > 0) { + return; + } -
    - - - Series - - {#each updateBookMetadata.fields.series.issues() ?? [] as issue} - {issue.message} - {/each} - + open = false; + toast.success('Updated book metadata!'); + } catch (error) { + console.error('Error occurred updating book metadata: ', error); + toast.error('Failed to update book metadata.'); + } + })} + class="grid grid-cols-1 items-start gap-x-4 gap-y-3 sm:grid-cols-2" +> + - - - Series position - - {#each updateBookMetadata.fields.series_position.issues() ?? [] as issue} - {issue.message} - {/each} - -
    + {@render groupHeading('Identity')} - - - Authors - - {#each authors as author} - - {/each} - {#each updateBookMetadata.fields.authors.issues() ?? [] as issue} - {issue.message} - {/each} - + + Title + + {#each updateBookMetadata.fields.title.issues() ?? [] as issue} + {issue.message} + {/each} + - - - Tags - - {#each tags as tag} - - {/each} - {#each updateBookMetadata.fields.tags.issues() ?? [] as issue} - {issue.message} - {/each} - + + Subtitle + + {#each updateBookMetadata.fields.subtitle.issues() ?? [] as issue} + {issue.message} + {/each} + - - - Description -