Skip to content

Commit

Permalink
feat(webui): add pagination to readlist/collection browse view
Browse files Browse the repository at this point in the history
Closes: #817
  • Loading branch information
gotson committed Jan 18, 2023
1 parent 17ca7f7 commit ff70fea
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 39 deletions.
142 changes: 121 additions & 21 deletions komga-webui/src/views/BrowseCollection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
</v-tooltip>
</v-btn>

<page-size-select v-model="pageSize"/>

<v-btn icon @click="drawer = !drawer">
<v-icon :color="filterActive ? 'secondary' : ''">mdi-filter-variant</v-icon>
</v-btn>
Expand Down Expand Up @@ -90,7 +92,7 @@

<v-container fluid>
<empty-state
v-if="series.length === 0"
v-if="totalPages === 0"
:title="$t('common.filter_no_matches')"
:sub-title="$t('common.use_filter_panel_to_change_filter')"
icon="mdi-book-multiple"
Expand All @@ -99,14 +101,29 @@
<v-btn @click="resetFilters">{{ $t('common.reset_filters') }}</v-btn>
</empty-state>

<item-browser
v-else
:items.sync="series"
:selected.sync="selectedSeries"
:edit-function="isAdmin ? editSingleSeries : undefined"
:draggable="editElements && collection.ordered"
:deletable="editElements"
/>
<template v-else>
<v-pagination
v-if="totalPages > 1"
v-model="page"
:total-visible="paginationVisible"
:length="totalPages"
/>

<item-browser
:items.sync="series"
:selected.sync="selectedSeries"
:edit-function="isAdmin ? editSingleSeries : undefined"
:draggable="editElements && collection.ordered"
:deletable="editElements"
/>

<v-pagination
v-if="totalPages > 1"
v-model="page"
:total-visible="paginationVisible"
:length="totalPages"
/>
</template>

</v-container>

Expand Down Expand Up @@ -138,16 +155,18 @@ import {Location} from 'vue-router'
import EmptyState from '@/components/EmptyState.vue'
import {SeriesDto} from '@/types/komga-series'
import {authorRoles} from '@/types/author-roles'
import {AuthorDto} from '@/types/komga-books'
import {AuthorDto, BookDto} from '@/types/komga-books'
import {CollectionSseDto, ReadProgressSeriesSseDto, SeriesSseDto} from '@/types/komga-sse'
import {throttle} from 'lodash'
import {LibraryDto} from '@/types/komga-libraries'
import {parseBooleanFilter} from '@/functions/query-params'
import {ContextOrigin} from '@/types/context'
import PageSizeSelect from '@/components/PageSizeSelect.vue'
export default Vue.extend({
name: 'BrowseCollection',
components: {
PageSizeSelect,
ToolbarSticky,
ItemBrowser,
CollectionActionsMenu,
Expand All @@ -163,9 +182,16 @@ export default Vue.extend({
series: [] as SeriesDto[],
seriesCopy: [] as SeriesDto[],
selectedSeries: [] as SeriesDto[],
page: 1,
pageSize: 20,
unpaged: false,
totalPages: 1,
totalElements: null as number | null,
editElements: false,
filters: {} as FiltersActive,
filterUnwatch: null as any,
pageUnwatch: null as any,
pageSizeUnwatch: null as any,
drawer: false,
filterOptions: {
library: [] as NameValue[],
Expand Down Expand Up @@ -201,7 +227,12 @@ export default Vue.extend({
this.$eventHub.$off(READPROGRESS_SERIES_DELETED, this.readProgressChanged)
},
async mounted() {
this.pageSize = this.$store.state.persistedState.browsingPageSize || this.pageSize
// restore from query param
await this.resetParams(this.$route, this.collectionId)
if (this.$route.query.page) this.page = Number(this.$route.query.page)
if (this.$route.query.pageSize) this.pageSize = Number(this.$route.query.pageSize)
this.loadCollection(this.collectionId)
Expand All @@ -213,6 +244,9 @@ export default Vue.extend({
// reset
await this.resetParams(this.$route, to.params.collectionId)
this.page = 1
this.totalPages = 1
this.totalElements = null
this.series = []
this.editElements = false
Expand All @@ -224,6 +258,19 @@ export default Vue.extend({
next()
},
computed: {
paginationVisible(): number {
switch (this.$vuetify.breakpoint.name) {
case 'xs':
return 5
case 'sm':
case 'md':
return 10
case 'lg':
case 'xl':
default:
return 15
}
},
filterOptionsList(): FiltersOptions {
return {
readStatus: {
Expand Down Expand Up @@ -352,9 +399,20 @@ export default Vue.extend({
this.$store.commit('setCollectionFilter', {id: this.collectionId, filter: val})
this.updateRouteAndReload()
})
this.pageSizeUnwatch = this.$watch('pageSize', (val) => {
this.$store.commit('setBrowsingPageSize', val)
this.updateRouteAndReload()
})
this.pageUnwatch = this.$watch('page', (val) => {
this.updateRoute()
this.loadPage(this.collectionId, val)
})
},
unsetWatches() {
this.filterUnwatch()
this.pageUnwatch()
this.pageSizeUnwatch()
},
collectionChanged(event: CollectionSseDto) {
if (event.collectionId === this.collectionId) {
Expand All @@ -369,15 +427,25 @@ export default Vue.extend({
updateRouteAndReload() {
this.unsetWatches()
this.page = 1
this.updateRoute()
this.loadSeries(this.collectionId)
this.loadPage(this.collectionId, this.page)
this.setWatches()
},
reloadSeries: throttle(function (this: any) {
this.loadSeries(this.collectionId)
}, 1000),
async loadSeries(collectionId: string) {
// reloadSeries: throttle(function (this: any) {
// this.loadSeries(this.collectionId)
// }, 1000),
async loadPage(collectionId: string, page: number) {
this.selectedSeries = []
const pageRequest = {
page: page - 1,
size: this.pageSize,
unpaged: this.unpaged,
} as PageRequest
let authorsFilter = [] as AuthorDto[]
authorRoles.forEach((role: string) => {
if (role in this.filters) this.filters[role].forEach((name: string) => authorsFilter.push({
Expand All @@ -387,22 +455,48 @@ export default Vue.extend({
})
const complete = parseBooleanFilter(this.filters.complete)
this.series = (await this.$komgaCollections.getSeries(collectionId, {unpaged: true} as PageRequest, this.filters.library, this.filters.status, replaceCompositeReadStatus(this.filters.readStatus), this.filters.genre, this.filters.tag, this.filters.language, this.filters.publisher, this.filters.ageRating, this.filters.releaseDate, authorsFilter, complete)).content
const seriesPage = await this.$komgaCollections.getSeries(collectionId, pageRequest, this.filters.library, this.filters.status, replaceCompositeReadStatus(this.filters.readStatus), this.filters.genre, this.filters.tag, this.filters.language, this.filters.publisher, this.filters.ageRating, this.filters.releaseDate, authorsFilter, complete)
this.totalPages = seriesPage.totalPages
this.totalElements = seriesPage.totalElements
this.series = seriesPage.content
this.series.forEach((x: SeriesDto) => x.context = {origin: ContextOrigin.COLLECTION, id: collectionId})
this.seriesCopy = [...this.series]
this.selectedSeries = []
},
reloadPage: throttle(function (this: any) {
this.loadPage(this.collectionId, this.page)
}, 1000),
// async loadSeries(collectionId: string) {
// let authorsFilter = [] as AuthorDto[]
// authorRoles.forEach((role: string) => {
// if (role in this.filters) this.filters[role].forEach((name: string) => authorsFilter.push({
// name: name,
// role: role,
// }))
// })
//
// const complete = parseBooleanFilter(this.filters.complete)
// this.series = (await this.$komgaCollections.getSeries(collectionId, {unpaged: true} as PageRequest, this.filters.library, this.filters.status, replaceCompositeReadStatus(this.filters.readStatus), this.filters.genre, this.filters.tag, this.filters.language, this.filters.publisher, this.filters.ageRating, this.filters.releaseDate, authorsFilter, complete)).content
// this.series.forEach((x: SeriesDto) => x.context = {origin: ContextOrigin.COLLECTION, id: collectionId})
// this.seriesCopy = [...this.series]
// this.selectedSeries = []
// },
async loadCollection(collectionId: string) {
this.$komgaCollections.getOneCollection(collectionId)
.then(v => this.collection = v)
await this.loadSeries(collectionId)
await this.loadPage(collectionId, this.page)
},
updateRoute() {
const loc = {
name: this.$route.name,
params: {collectionId: this.$route.params.collectionId},
query: {},
query: {
page: `${this.page}`,
pageSize: `${this.pageSize}`,
},
} as Location
mergeFilterParams(this.filters, loc.query)
this.$router.replace(loc).catch((_: any) => {
Expand All @@ -429,29 +523,35 @@ export default Vue.extend({
addToCollection() {
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries)
},
startEditElements() {
async startEditElements() {
this.filters = {}
this.unpaged = true
await this.reloadPage()
this.editElements = true
},
cancelEditElements() {
this.editElements = false
this.series = [...this.seriesCopy]
this.unpaged = false
this.reloadPage()
},
doEditElements() {
this.editElements = false
const update = {
seriesIds: this.series.map(x => x.id),
} as CollectionUpdateDto
this.$komgaCollections.patchCollection(this.collectionId, update)
this.unpaged = false
this.reloadPage()
},
editCollection() {
this.$store.dispatch('dialogEditCollection', this.collection)
},
seriesChanged(event: SeriesSseDto) {
if (this.series.some(s => s.id === event.seriesId)) this.reloadSeries()
if (this.series.some(s => s.id === event.seriesId)) this.reloadPage()
},
readProgressChanged(event: ReadProgressSeriesSseDto) {
if (this.series.some(b => b.id === event.seriesId)) this.reloadSeries()
if (this.series.some(b => b.id === event.seriesId)) this.reloadPage()
},
},
})
Expand Down
Loading

0 comments on commit ff70fea

Please sign in to comment.