mirror of
https://github.com/gotson/komga.git
synced 2025-12-22 00:13:30 +01:00
parent
dc064f20ec
commit
fc905ef9b5
3 changed files with 160 additions and 9 deletions
|
|
@ -78,11 +78,24 @@ export default class KomgaCollectionsService {
|
|||
}
|
||||
}
|
||||
|
||||
async getSeries (collectionId: string, pageRequest?: PageRequest): Promise<Page<SeriesDto>> {
|
||||
async getSeries (collectionId: string, pageRequest?: PageRequest,
|
||||
libraryId?: string[], status?: string[],
|
||||
readStatus?: string[], genre?: string[], tag?: string[], language?: string[],
|
||||
publisher?: string[], ageRating?: string[]): Promise<Page<SeriesDto>> {
|
||||
try {
|
||||
const params = { ...pageRequest }
|
||||
const params = { ...pageRequest } as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (status) params.status = status
|
||||
if (readStatus) params.read_status = readStatus
|
||||
if (genre) params.genre = genre
|
||||
if (tag) params.tag = tag
|
||||
if (language) params.language = language
|
||||
if (publisher) params.publisher = publisher
|
||||
if (ageRating) params.age_rating = ageRating
|
||||
|
||||
return (await this.http.get(`${API_COLLECTIONS}/${collectionId}/series`, {
|
||||
params: params,
|
||||
paramsSerializer: params => qs.stringify(params, { indices: false }),
|
||||
})).data
|
||||
} catch (e) {
|
||||
let msg = 'An error occurred while trying to retrieve series'
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ export default class KomgaReferentialService {
|
|||
}
|
||||
}
|
||||
|
||||
async getGenres (libraryId?: string): Promise<string[]> {
|
||||
async getGenres (libraryId?: string, collectionId?: string): Promise<string[]> {
|
||||
try {
|
||||
const params = {} as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (collectionId) params.collection_id = collectionId
|
||||
|
||||
return (await this.http.get('/api/v1/genres', {
|
||||
params: params,
|
||||
|
|
@ -47,11 +48,12 @@ export default class KomgaReferentialService {
|
|||
}
|
||||
}
|
||||
|
||||
async getTags (libraryId?: string, seriesId?: string): Promise<string[]> {
|
||||
async getTags (libraryId?: string, seriesId?: string, collectionId?: string): Promise<string[]> {
|
||||
try {
|
||||
const params = {} as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (seriesId) params.series_id = seriesId
|
||||
if (collectionId) params.collection_id = collectionId
|
||||
|
||||
return (await this.http.get('/api/v1/tags', {
|
||||
params: params,
|
||||
|
|
@ -66,10 +68,11 @@ export default class KomgaReferentialService {
|
|||
}
|
||||
}
|
||||
|
||||
async getPublishers (libraryId?: string): Promise<string[]> {
|
||||
async getPublishers (libraryId?: string, collectionId?: string): Promise<string[]> {
|
||||
try {
|
||||
const params = {} as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (collectionId) params.collection_id = collectionId
|
||||
|
||||
return (await this.http.get('/api/v1/publishers', {
|
||||
params: params,
|
||||
|
|
@ -84,10 +87,11 @@ export default class KomgaReferentialService {
|
|||
}
|
||||
}
|
||||
|
||||
async getAgeRatings (libraryId?: string): Promise<string[]> {
|
||||
async getAgeRatings (libraryId?: string, collectionId?: string): Promise<string[]> {
|
||||
try {
|
||||
const params = {} as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (collectionId) params.collection_id = collectionId
|
||||
|
||||
return (await this.http.get('/api/v1/age-ratings', {
|
||||
params: params,
|
||||
|
|
@ -102,10 +106,11 @@ export default class KomgaReferentialService {
|
|||
}
|
||||
}
|
||||
|
||||
async getLanguages (libraryId?: string): Promise<NameValue[]> {
|
||||
async getLanguages (libraryId?: string, collectionId?: string): Promise<NameValue[]> {
|
||||
try {
|
||||
const params = {} as any
|
||||
if (libraryId) params.library_id = libraryId
|
||||
if (collectionId) params.collection_id = collectionId
|
||||
|
||||
const data = (await this.http.get('/api/v1/languages', {
|
||||
params: params,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@
|
|||
</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
<v-btn icon @click="drawer = !drawer">
|
||||
<v-icon :color="filterActive ? 'secondary' : ''">mdi-filter-variant</v-icon>
|
||||
</v-btn>
|
||||
|
||||
</toolbar-sticky>
|
||||
|
||||
<series-multi-select-bar
|
||||
|
|
@ -61,9 +65,34 @@
|
|||
</toolbar-sticky>
|
||||
</v-scroll-y-transition>
|
||||
|
||||
<filter-drawer v-model="drawer">
|
||||
<template v-slot:default>
|
||||
<filter-list
|
||||
:filters-options="filterOptionsList"
|
||||
:filters-active.sync="filters"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:filter>
|
||||
<filter-panels
|
||||
:filters-options="filterOptionsPanel"
|
||||
:filters-active.sync="filters"
|
||||
/>
|
||||
</template>
|
||||
</filter-drawer>
|
||||
|
||||
<v-container fluid>
|
||||
<empty-state
|
||||
v-if="series.length === 0"
|
||||
title="The active filter has no matches"
|
||||
sub-title="Use the filter panel to change the active filter"
|
||||
icon="mdi-book-multiple"
|
||||
icon-color="secondary"
|
||||
>
|
||||
</empty-state>
|
||||
|
||||
<item-browser
|
||||
v-else
|
||||
:items.sync="series"
|
||||
:selected.sync="selectedSeries"
|
||||
:edit-function="editSingleSeries"
|
||||
|
|
@ -84,6 +113,15 @@ import { COLLECTION_CHANGED, COLLECTION_DELETED, SERIES_CHANGED } from '@/types/
|
|||
import Vue from 'vue'
|
||||
import SeriesMultiSelectBar from '@/components/bars/SeriesMultiSelectBar.vue'
|
||||
import { LIBRARIES_ALL } from '@/types/library'
|
||||
import { ReadStatus } from '@/types/enum-books'
|
||||
import { SeriesStatus, SeriesStatusKeyValue } from '@/types/enum-series'
|
||||
import { mergeFilterParams, toNameValue } from '@/functions/filter'
|
||||
import FilterDrawer from '@/components/FilterDrawer.vue'
|
||||
import FilterPanels from '@/components/FilterPanels.vue'
|
||||
import FilterList from '@/components/FilterList.vue'
|
||||
import { Location } from 'vue-router'
|
||||
import EmptyState from '@/components/EmptyState.vue'
|
||||
import { parseQueryFilter } from '@/functions/query-params'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'BrowseCollection',
|
||||
|
|
@ -92,6 +130,10 @@ export default Vue.extend({
|
|||
ItemBrowser,
|
||||
CollectionActionsMenu,
|
||||
SeriesMultiSelectBar,
|
||||
FilterDrawer,
|
||||
FilterPanels,
|
||||
FilterList,
|
||||
EmptyState,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
|
|
@ -100,6 +142,21 @@ export default Vue.extend({
|
|||
seriesCopy: [] as SeriesDto[],
|
||||
selectedSeries: [] as SeriesDto[],
|
||||
editElements: false,
|
||||
filterOptionsList: {
|
||||
readStatus: { values: [{ name: 'Unread', value: ReadStatus.UNREAD }] },
|
||||
} as FiltersOptions,
|
||||
filterOptionsPanel: {
|
||||
library: { name: 'LIBRARY', values: [] },
|
||||
status: { name: 'STATUS', values: SeriesStatusKeyValue },
|
||||
genre: { name: 'GENRE', values: [] },
|
||||
tag: { name: 'TAG', values: [] },
|
||||
publisher: { name: 'PUBLISHER', values: [] },
|
||||
language: { name: 'LANGUAGE', values: [] },
|
||||
ageRating: { name: 'AGE RATING', values: [] },
|
||||
} as FiltersOptions,
|
||||
filters: {} as FiltersActive,
|
||||
filterUnwatch: null as any,
|
||||
drawer: false,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
|
@ -134,14 +191,29 @@ export default Vue.extend({
|
|||
},
|
||||
mounted () {
|
||||
this.loadCollection(this.collectionId)
|
||||
|
||||
this.resetParams(this.$route)
|
||||
|
||||
this.setWatches()
|
||||
},
|
||||
beforeRouteUpdate (to, from, next) {
|
||||
if (to.params.collectionId !== from.params.collectionId) {
|
||||
this.unsetWatches()
|
||||
|
||||
// reset
|
||||
this.resetParams(this.$route)
|
||||
this.series = []
|
||||
this.editElements = false
|
||||
this.filterOptionsPanel.library.values = []
|
||||
this.filterOptionsPanel.genre.values = []
|
||||
this.filterOptionsPanel.tag.values = []
|
||||
this.filterOptionsPanel.publisher.values = []
|
||||
this.filterOptionsPanel.language.values = []
|
||||
this.filterOptionsPanel.ageRating.values = []
|
||||
|
||||
this.loadCollection(to.params.collectionId)
|
||||
|
||||
this.setWatches()
|
||||
}
|
||||
|
||||
next()
|
||||
|
|
@ -150,17 +222,77 @@ export default Vue.extend({
|
|||
isAdmin (): boolean {
|
||||
return this.$store.getters.meAdmin
|
||||
},
|
||||
filterActive (): boolean {
|
||||
return Object.keys(this.filters).some(x => this.filters[x].length !== 0)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetParams (route: any) {
|
||||
if (route.query.status || route.query.readStatus || route.query.genre || route.query.tag || route.query.language || route.query.ageRating) {
|
||||
this.filters.status = parseQueryFilter(route.query.status, Object.keys(SeriesStatus))
|
||||
this.filters.readStatus = parseQueryFilter(route.query.readStatus, Object.keys(ReadStatus))
|
||||
this.filters.genre = parseQueryFilter(route.query.genre, this.filterOptionsPanel.genre.values.map(x => x.value))
|
||||
this.filters.tag = parseQueryFilter(route.query.tag, this.filterOptionsPanel.tag.values.map(x => x.value))
|
||||
this.filters.language = parseQueryFilter(route.query.language, this.filterOptionsPanel.language.values.map(x => x.value))
|
||||
this.filters.ageRating = parseQueryFilter(route.query.ageRating, this.filterOptionsPanel.ageRating.values.map(x => x.value))
|
||||
} else {
|
||||
this.filters = this.$cookies.get(this.cookieFilter(route.params.collectionId)) || {} as FiltersActive
|
||||
}
|
||||
},
|
||||
cookieFilter (collectionId: string): string {
|
||||
return `collection.filter.${collectionId}`
|
||||
},
|
||||
setWatches () {
|
||||
this.filterUnwatch = this.$watch('filters', (val) => {
|
||||
this.$cookies.set(this.cookieFilter(this.collectionId), val, Infinity)
|
||||
this.updateRouteAndReload()
|
||||
})
|
||||
},
|
||||
unsetWatches () {
|
||||
this.filterUnwatch()
|
||||
},
|
||||
collectionChanged (event: EventCollectionChanged) {
|
||||
if (event.id === this.collectionId) {
|
||||
this.loadCollection(this.collectionId)
|
||||
}
|
||||
},
|
||||
updateRouteAndReload () {
|
||||
this.unsetWatches()
|
||||
|
||||
this.selectedSeries = []
|
||||
|
||||
this.updateRoute()
|
||||
this.loadSeries(this.collectionId)
|
||||
|
||||
this.setWatches()
|
||||
},
|
||||
async loadSeries (collectionId: string) {
|
||||
this.series = (await this.$komgaCollections.getSeries(collectionId, { unpaged: true } as PageRequest, this.filters.library, this.filters.status, this.filters.readStatus, this.filters.genre, this.filters.tag, this.filters.language, this.filters.publisher, this.filters.ageRating)).content
|
||||
this.seriesCopy = [...this.series]
|
||||
},
|
||||
async loadCollection (collectionId: string) {
|
||||
this.collection = await this.$komgaCollections.getOneCollection(collectionId)
|
||||
this.series = (await this.$komgaCollections.getSeries(collectionId, { unpaged: true } as PageRequest)).content
|
||||
this.seriesCopy = [...this.series]
|
||||
await this.loadSeries(collectionId)
|
||||
|
||||
this.filterOptionsPanel.library.values.push(...this.$store.state.komgaLibraries.libraries.map((x: LibraryDto) => ({
|
||||
name: x.name,
|
||||
value: x.id,
|
||||
})))
|
||||
this.filterOptionsPanel.genre.values.push(...toNameValue(await this.$komgaReferential.getGenres(undefined, collectionId)))
|
||||
this.filterOptionsPanel.tag.values.push(...toNameValue(await this.$komgaReferential.getTags(undefined, undefined, collectionId)))
|
||||
this.filterOptionsPanel.publisher.values.push(...toNameValue(await this.$komgaReferential.getPublishers(undefined, collectionId)))
|
||||
this.filterOptionsPanel.language.values.push(...(await this.$komgaReferential.getLanguages(undefined, collectionId)))
|
||||
this.filterOptionsPanel.ageRating.values.push(...toNameValue(await this.$komgaReferential.getAgeRatings(undefined, collectionId)))
|
||||
},
|
||||
updateRoute () {
|
||||
const loc = {
|
||||
name: this.$route.name,
|
||||
params: { collectionId: this.$route.params.collectionId },
|
||||
query: {},
|
||||
} as Location
|
||||
mergeFilterParams(this.filters, loc.query)
|
||||
this.$router.replace(loc).catch((_: any) => {
|
||||
})
|
||||
},
|
||||
editSingleSeries (series: SeriesDto) {
|
||||
this.$store.dispatch('dialogUpdateSeries', series)
|
||||
|
|
@ -188,6 +320,7 @@ export default Vue.extend({
|
|||
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries)
|
||||
},
|
||||
startEditElements () {
|
||||
this.filters = {}
|
||||
this.editElements = true
|
||||
},
|
||||
cancelEditElements () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue