Skip to content

Commit

Permalink
feat(webui): build author on reset when bulk editing
Browse files Browse the repository at this point in the history
  • Loading branch information
noaione committed Jan 19, 2023
1 parent 0b57dc9 commit e27c76e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
25 changes: 21 additions & 4 deletions komga-webui/src/components/dialogs/EditBooksDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@
</template>

<script lang="ts">
import {groupAuthorsByRole} from '@/functions/authors'
import {buildManyAuthorsByRole, groupAuthorsByRole} from '@/functions/authors'
import {authorRoles} from '@/types/author-roles'
import Vue from 'vue'
import {helpers, requiredIf} from 'vuelidate/lib/validators'
Expand Down Expand Up @@ -460,6 +460,7 @@ export default Vue.extend({
authorSearch: [],
authorSearchResults: [] as string[],
tagsAvailable: [] as string[],
isMultiBookAuthorDirty: false, // workaround for author consistency in bulk mode
}
},
props: {
Expand Down Expand Up @@ -605,11 +606,27 @@ export default Vue.extend({
if (Array.isArray(books) && books.length === 0) return
else if (this.$_.isEmpty(books)) return
if (Array.isArray(books) && books.length > 0) {
this.form.authors = {}
this.form.authors = buildManyAuthorsByRole(books)
this.form.links = []
const currentRoles = this.$_.keys(this.form.authors)
// Use authorRoles from computed value, so we can extend if needed
const ignoreRoles = this.authorRoles.map(r => r.value)
.filter((r) => !this.customRoles.includes(r)) // remove old custom roles
.filter((r) => !authorRoles.includes(r)) // remove native roles
this.customRoles = currentRoles.filter((r) => !ignoreRoles.includes(r)) // add new custom roles
let forceAuthorLock = false
for (const book of books) {
const bookAuthor = groupAuthorsByRole(book.metadata.authors)
if (!this.$_.isEqual(bookAuthor, this.form.authors)) {
this.isMultiBookAuthorDirty = true
forceAuthorLock = true
break
}
}
const authorsLock = this.$_.uniq(books.map(x => x.metadata.authorsLock))
this.form.authorsLock = authorsLock.length > 1 ? false : authorsLock[0]
this.form.authorsLock = authorsLock.length > 1 ? false : authorsLock[0] || forceAuthorLock
this.form.tags = []
Expand Down Expand Up @@ -643,7 +660,7 @@ export default Vue.extend({
tagsLock: this.form.tagsLock,
}
if (this.$v.form?.authors?.$dirty) {
if (this.$v.form?.authors?.$dirty || this.isMultiBookAuthorDirty) {
this.$_.merge(metadata, {
authors: this.$_.keys(this.form.authors).flatMap((role: string) =>
this.$_.get(this.form.authors, role).map((name: string) => ({name: name, role: role})),
Expand Down
38 changes: 36 additions & 2 deletions komga-webui/src/functions/authors.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
import {groupBy, mapValues} from 'lodash'
import {AuthorDto} from '@/types/komga-books'
import {AuthorDto, BookDto} from '@/types/komga-books'

type AuthorsByRole = {[role: string]: string[]}

// return an object where keys are roles, and values are string[]
export function groupAuthorsByRole (authors: AuthorDto[]): any {
export function groupAuthorsByRole (authors: AuthorDto[]): AuthorsByRole {
return mapValues(groupBy(authors, 'role'),
authors => authors.map((author: AuthorDto) => author.name))
}

// create an object where keys are roles and values are arrays of authors
// if the authors in a given roles is different between books, the value is an empty array.
export function buildManyAuthorsByRole(books: BookDto[]): AuthorsByRole {
const authorsByRole = groupAuthorsByRole(books[0].metadata.authors)
const ignoreRoles = [] as string[]

for (const book of books) {
const bookAuthorsByRole = groupAuthorsByRole(book.metadata.authors)

for (const role in bookAuthorsByRole) {
if (ignoreRoles.includes(role)) {
continue
}
const authors = authorsByRole[role] || []
const currentAuthors = bookAuthorsByRole[role] || []
if (authors.length === 0) {
authorsByRole[role] = currentAuthors
continue
}
// check if the authors are different
// sort the arrays to make sure we compare the same authors
if (currentAuthors && authors.sort().join() !== currentAuthors.sort().join()) {
// remove the role from the authorsByRole
authorsByRole[role] = []
ignoreRoles.push(role)
}
}
}

return authorsByRole
}

0 comments on commit e27c76e

Please sign in to comment.