feat(webui): add all books from series to read list from multi-select bar

Closes: #1535
This commit is contained in:
Gauthier Roebroeck 2025-01-21 11:31:10 +08:00
parent da35e012d4
commit 3582114efc
5 changed files with 31 additions and 13 deletions

View file

@ -52,7 +52,7 @@
</v-tooltip>
</v-btn>
<v-btn icon @click="addToReadList" v-if="isAdmin && (kind === 'books' || (kind === 'series' && oneshots))">
<v-btn icon @click="addToReadList" v-if="isAdmin && (kind === 'books' || kind === 'series')">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon v-on="on">mdi-book-plus-multiple</v-icon>

View file

@ -165,7 +165,7 @@ import {LibraryDto} from '@/types/komga-libraries'
import {parseBooleanFilter} from '@/functions/query-params'
import {ContextOrigin} from '@/types/context'
import PageSizeSelect from '@/components/PageSizeSelect.vue'
import {BookSearch, SearchConditionSeriesId, SearchOperatorIs} from '@/types/komga-search'
import {BookSearch, SearchConditionAnyOfBook, SearchConditionSeriesId, SearchOperatorIs} from '@/types/komga-search'
import {FiltersActive, FiltersOptions, NameValue} from '@/types/filter'
export default Vue.extend({
@ -533,10 +533,11 @@ export default Vue.extend({
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries.map(s => s.id))
},
async addToReadList() {
const books = await Promise.all(this.selectedSeries.map(s => this.$komgaBooks.getBooksList({
condition: new SearchConditionSeriesId(new SearchOperatorIs(s.id)),
} as BookSearch)))
this.$store.dispatch('dialogAddBooksToReadList', books.map(b => b.content[0].id))
const conditions = this.selectedSeries.map(s => new SearchConditionSeriesId(new SearchOperatorIs(s.id)))
const books = await this.$komgaBooks.getBooksList({
condition: new SearchConditionAnyOfBook(conditions),
} as BookSearch, {unpaged: true})
this.$store.dispatch('dialogAddBooksToReadList', books.content.map(b => b.id))
},
async startEditElements() {
this.filters = {}

View file

@ -167,7 +167,7 @@ import {ItemContext} from '@/types/items'
import {
BookSearch,
SearchConditionAgeRating,
SearchConditionAllOfSeries,
SearchConditionAllOfSeries, SearchConditionAnyOfBook,
SearchConditionAnyOfSeries,
SearchConditionAuthor,
SearchConditionComplete,
@ -747,10 +747,11 @@ export default Vue.extend({
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries.map(s => s.id))
},
async addToReadList() {
const books = await Promise.all(this.selectedSeries.map(s => this.$komgaBooks.getBooksList({
condition: new SearchConditionSeriesId(new SearchOperatorIs(s.id)),
} as BookSearch)))
this.$store.dispatch('dialogAddBooksToReadList', books.map(b => b.content[0].id))
const conditions = this.selectedSeries.map(s => new SearchConditionSeriesId(new SearchOperatorIs(s.id)))
const books = await this.$komgaBooks.getBooksList({
condition: new SearchConditionAnyOfBook(conditions),
} as BookSearch, {unpaged: true})
this.$store.dispatch('dialogAddBooksToReadList', books.content.map(b => b.id))
},
async editSingleSeries(series: SeriesDto) {
if (series.oneshot) {

View file

@ -27,6 +27,7 @@
@mark-read="markSelectedSeriesRead"
@mark-unread="markSelectedSeriesUnread"
@add-to-collection="addToCollection"
@add-to-readlist="addSeriesBooksToReadList"
@edit="editMultipleSeries"
@delete="deleteSeries"
/>
@ -234,7 +235,7 @@ import {PageLoader} from '@/types/pageLoader'
import {ItemContext} from '@/types/items'
import {
BookSearch,
SearchConditionAllOfBook,
SearchConditionAllOfBook, SearchConditionAnyOfBook,
SearchConditionBook,
SearchConditionLibraryId,
SearchConditionReadStatus, SearchConditionReleaseDate, SearchConditionSeriesId, SearchOperatorAfter,
@ -514,6 +515,13 @@ export default Vue.extend({
this.$store.dispatch('dialogAddBooksToReadList', this.selectedBooks.map(b => b.id))
this.selectedBooks = []
},
async addSeriesBooksToReadList() {
const conditions = this.selectedSeries.map(s => new SearchConditionSeriesId(new SearchOperatorIs(s.id)))
const books = await this.$komgaBooks.getBooksList({
condition: new SearchConditionAnyOfBook(conditions),
} as BookSearch, {unpaged: true})
this.$store.dispatch('dialogAddBooksToReadList', books.content.map(b => b.id))
},
async markSelectedBooksRead() {
await Promise.all(this.selectedBooks.map(b =>
this.$komgaBooks.updateReadProgress(b.id, {completed: true}),

View file

@ -13,6 +13,7 @@
@mark-read="markSelectedSeriesRead"
@mark-unread="markSelectedSeriesUnread"
@add-to-collection="addToCollection"
@add-to-readlist="addSeriesBooksToReadList"
@edit="editMultipleSeries"
@delete="deleteSeries"
/>
@ -181,7 +182,7 @@ import {PageLoader} from '@/types/pageLoader'
import {ItemContext} from '@/types/items'
import {ReadListDto} from '@/types/komga-readlists'
import {
BookSearch,
BookSearch, SearchConditionAnyOfBook, SearchConditionAnyOfSeries,
SearchConditionOneShot,
SearchConditionSeriesId, SearchOperatorIs,
SearchOperatorIsFalse,
@ -355,6 +356,13 @@ export default Vue.extend({
addToReadList() {
this.$store.dispatch('dialogAddBooksToReadList', this.selectedBooks.map(b => b.id))
},
async addSeriesBooksToReadList() {
const conditions = this.selectedSeries.map(s => new SearchConditionSeriesId(new SearchOperatorIs(s.id)))
const books = await this.$komgaBooks.getBooksList({
condition: new SearchConditionAnyOfBook(conditions),
} as BookSearch, {unpaged: true})
this.$store.dispatch('dialogAddBooksToReadList', books.content.map(b => b.id))
},
addOneshotsToCollection() {
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedBooks.map(b => b.seriesId))
},