feat(webui): show and edit ISBN for book

This commit is contained in:
Gauthier Roebroeck 2021-03-10 15:23:30 +08:00
parent 6fa0324666
commit 65c16f109f
6 changed files with 74 additions and 13 deletions

View file

@ -7,6 +7,7 @@
"": {
"version": "0.1.0",
"dependencies": {
"@saekitominaga/isbn-verify": "^1.2.3",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"jquery": "^3.5.1",
@ -1738,6 +1739,11 @@
"node": ">= 6"
}
},
"node_modules/@saekitominaga/isbn-verify": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@saekitominaga/isbn-verify/-/isbn-verify-1.2.3.tgz",
"integrity": "sha512-SMN3ZaioJCDKuHi1YY24HelLDs6936zH0w7qdaI3k6Uv3dRKmkhP5MSoqUjj//SjTYDbeuGCNq1HSaezhpQdJg=="
},
"node_modules/@soda/friendly-errors-webpack-plugin": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz",
@ -22420,6 +22426,11 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
"dev": true
},
"@saekitominaga/isbn-verify": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@saekitominaga/isbn-verify/-/isbn-verify-1.2.3.tgz",
"integrity": "sha512-SMN3ZaioJCDKuHi1YY24HelLDs6936zH0w7qdaI3k6Uv3dRKmkhP5MSoqUjj//SjTYDbeuGCNq1HSaezhpQdJg=="
},
"@soda/friendly-errors-webpack-plugin": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz",

View file

@ -10,6 +10,7 @@
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
},
"dependencies": {
"@saekitominaga/isbn-verify": "^1.2.3",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"jquery": "^3.5.1",

View file

@ -134,9 +134,9 @@
</v-col>
</v-row>
<!-- Release Date -->
<v-row v-if="single">
<v-col cols="12">
<!-- Release Date -->
<v-col cols="6">
<v-text-field v-model="form.releaseDate"
:label="$t('dialog.edit_books.field_release_date')"
filled
@ -156,6 +156,28 @@
</template>
</v-text-field>
</v-col>
<!-- ISBN -->
<v-col cols="6">
<v-text-field v-model="form.isbn"
:label="$t('dialog.edit_books.field_isbn')"
filled
dense
placeholder="978-2-20-504375-4"
clearable
:error-messages="isbnErrors"
@blur="$v.form.isbn.$touch()"
@change="form.isbnLock = true"
>
<template v-slot:prepend>
<v-icon :color="form.isbnLock ? 'secondary' : ''"
@click="form.isbnLock = !form.isbnLock"
>
{{ form.isbnLock ? 'mdi-lock' : 'mdi-lock-open' }}
</v-icon>
</template>
</v-text-field>
</v-col>
</v-row>
</v-container>
@ -277,8 +299,13 @@ import moment from 'moment'
import Vue from 'vue'
import {helpers, requiredIf} from 'vuelidate/lib/validators'
import {BookDto} from '@/types/komga-books'
import ISBN from '@saekitominaga/isbn-verify'
const validDate = (value: any) => !helpers.req(value) || moment(value, 'YYYY-MM-DD', true).isValid()
const validDate = (value: string) => !helpers.req(value) || moment(value, 'YYYY-MM-DD', true).isValid()
const validIsbn = (value: string) => {
const isbn = new ISBN(value.replaceAll('-', ''))
return (!helpers.req(value) || (isbn.isIsbn13() && isbn.isValid()))
}
export default Vue.extend({
name: 'EditBooksDialog',
@ -303,6 +330,8 @@ export default Vue.extend({
authorsLock: false,
tags: [] as string[],
tagsLock: false,
isbn: '',
isbnLock: false,
},
authorSearch: [],
authorSearchResults: [] as string[],
@ -358,6 +387,7 @@ export default Vue.extend({
releaseDate: {validDate},
summary: {},
authors: {},
isbn: {validIsbn},
},
},
async created() {
@ -389,6 +419,12 @@ export default Vue.extend({
!this.$v?.form?.releaseDate?.validDate && errors.push(this.$t('dialog.edit_books.field_release_date_error').toString())
return errors
},
isbnErrors(): string[] {
const errors = [] as string[]
if (!this.$v.form?.isbn?.$dirty) return errors
!this.$v?.form?.isbn?.validIsbn && errors.push(this.$t('dialog.edit_books.field_isbn_error').toString())
return errors
},
},
methods: {
requiredErrors(fieldName: string): string[] {
@ -459,6 +495,7 @@ export default Vue.extend({
numberSortLock: this.form.numberSortLock,
summaryLock: this.form.summaryLock,
releaseDateLock: this.form.releaseDateLock,
isbnLock: this.form.isbnLock,
})
if (this.$v.form?.title?.$dirty) {
@ -480,6 +517,10 @@ export default Vue.extend({
if (this.$v.form?.releaseDate?.$dirty) {
this.$_.merge(metadata, {releaseDate: this.form.releaseDate ? this.form.releaseDate : null})
}
if (this.$v.form?.isbn?.$dirty) {
this.$_.merge(metadata, {isbn: this.form.isbn})
}
}
return metadata

View file

@ -91,6 +91,7 @@
"download_file": "Download file",
"file": "FILE",
"format": "FORMAT",
"isbn": "ISBN",
"navigation_within_readlist": "Navigation within the readlist",
"read_book": "Read book",
"size": "SIZE"
@ -213,6 +214,8 @@
"button_confirm": "Save changes",
"dialog_title_multiple": "Edit {count} book | Edit {count} books",
"dialog_title_single": "Edit {book}",
"field_isbn": "ISBN",
"field_isbn_error": "Must be a valid ISBN 13",
"field_number": "Number",
"field_number_sort": "Sort Number",
"field_number_sort_hint": "You can use decimal numbers",

View file

@ -1,4 +1,4 @@
import { Context } from '@/types/context'
import {Context} from '@/types/context'
export interface BookDto {
id: string,
@ -57,8 +57,10 @@ export interface BookMetadataDto {
releaseDateLock: boolean,
authors: AuthorDto[],
authorsLock: boolean,
tags: String[],
tagsLock: boolean
tags: string[],
tagsLock: boolean,
isbn: string,
isbnLock: boolean
}
export interface ReadProgressDto {
@ -81,8 +83,10 @@ export interface BookMetadataUpdateDto {
releaseDateLock?: boolean,
authors?: AuthorDto[],
authorsLock?: boolean,
tags?: String[],
tags?: string[],
tagsLock?: boolean
isbn?: string,
isbnLock?: boolean
}
export interface AuthorDto {

View file

@ -252,16 +252,17 @@
<v-row v-if="book.media.comment" class="align-center text-caption">
<v-col class="py-1" cols="4" sm="3" md="2" xl="1">{{ $t('browse_book.comment') }}</v-col>
<v-col class="py-1" cols="8" sm="9" md="10" xl="11">
<span class="error--text font-weight-bold">{{ book.media.comment }}</span>
</v-col>
<v-col class="py-1 error--text font-weight-bold" cols="8" sm="9" md="10" xl="11">{{ book.media.comment }}</v-col>
</v-row>
<v-row class="align-center text-caption">
<v-col class="py-1" cols="4" sm="3" md="2" xl="1">{{ $t('browse_book.format') }}</v-col>
<v-col class="py-1" cols="8" sm="9" md="10" xl="11">
{{ format.type }}
</v-col>
<v-col class="py-1" cols="8" sm="9" md="10" xl="11">{{ format.type }}</v-col>
</v-row>
<v-row v-if="book.metadata.isbn" class="align-center text-caption">
<v-col class="py-1" cols="4" sm="3" md="2" xl="1">{{ $t('browse_book.isbn') }}</v-col>
<v-col class="py-1" cols="8" sm="9" md="10" xl="11">{{ book.metadata.isbn }}</v-col>
</v-row>
<v-row class="align-center text-caption">