diff --git a/komga-webui/src/components/FilterMenuButton.vue b/komga-webui/src/components/FilterMenuButton.vue new file mode 100644 index 000000000..aaa0c02f1 --- /dev/null +++ b/komga-webui/src/components/FilterMenuButton.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/komga-webui/src/services/komga-series.service.ts b/komga-webui/src/services/komga-series.service.ts index 748397633..e0ad822bb 100644 --- a/komga-webui/src/services/komga-series.service.ts +++ b/komga-webui/src/services/komga-series.service.ts @@ -78,10 +78,14 @@ export default class KomgaSeriesService { } } - async getBooks (seriesId: number, pageRequest?: PageRequest): Promise> { + async getBooks (seriesId: number, pageRequest?: PageRequest, readStatus?: string[]): Promise> { try { + const params = { ...pageRequest } as any + if (readStatus) { + params.read_status = readStatus + } return (await this.http.get(`${API_SERIES}/${seriesId}/books`, { - params: { ...pageRequest }, + params: params, paramsSerializer: params => qs.stringify(params, { indices: false }), })).data } catch (e) { diff --git a/komga-webui/src/types/enum-books.ts b/komga-webui/src/types/enum-books.ts index 5c3a978ac..74a7ddcfd 100644 --- a/komga-webui/src/types/enum-books.ts +++ b/komga-webui/src/types/enum-books.ts @@ -15,6 +15,6 @@ export enum MediaStatus { export enum ReadStatus { UNREAD = 'UNREAD', - READ = 'READ', - IN_PROGRESS = 'IN_PROGRESS' + IN_PROGRESS = 'IN_PROGRESS', + READ = 'READ' } diff --git a/komga-webui/src/views/BrowseSeries.vue b/komga-webui/src/views/BrowseSeries.vue index 53bc86f2a..964bcbb22 100644 --- a/komga-webui/src/views/BrowseSeries.vue +++ b/komga-webui/src/views/BrowseSeries.vue @@ -45,6 +45,11 @@ mdi-pencil + + + - + + - + @@ -146,6 +162,8 @@ import Badge from '@/components/Badge.vue' import EditBooksDialog from '@/components/EditBooksDialog.vue' import EditSeriesDialog from '@/components/EditSeriesDialog.vue' +import EmptyState from '@/components/EmptyState.vue' +import FilterMenuButton from '@/components/FilterMenuButton.vue' import ItemBrowser from '@/components/ItemBrowser.vue' import ItemCard from '@/components/ItemCard.vue' import PageSizeSelect from '@/components/PageSizeSelect.vue' @@ -153,6 +171,7 @@ import SortMenuButton from '@/components/SortMenuButton.vue' import ToolbarSticky from '@/components/ToolbarSticky.vue' import { parseQuerySort } from '@/functions/query-params' import { seriesThumbnailUrl } from '@/functions/urls' +import { ReadStatus } from '@/types/enum-books' import Vue from 'vue' const cookiePageSize = 'pagesize' @@ -162,12 +181,14 @@ export default Vue.extend({ components: { ToolbarSticky, SortMenuButton, + FilterMenuButton, Badge, EditSeriesDialog, EditBooksDialog, ItemBrowser, PageSizeSelect, ItemCard, + EmptyState, }, data: () => { return { @@ -185,8 +206,11 @@ export default Vue.extend({ }] as SortOption[], sortActive: {} as SortActive, sortDefault: { key: 'metadata.numberSort', order: 'asc' } as SortActive, + filterOptions: [{ name: 'READ STATUS', values: ReadStatus }], + filters: [[]] as any[], dialogEdit: false, sortUnwatch: null as any, + filterUnwatch: null as any, pageUnwatch: null as any, pageSizeUnwatch: null as any, selected: [], @@ -253,6 +277,7 @@ export default Vue.extend({ // restore from query param this.sortActive = this.parseQuerySortOrDefault(this.$route.query.sort) + this.filters.splice(0, 1, this.parseQueryFilterStatus(this.$route.query.readStatus)) if (this.$route.query.page) this.page = Number(this.$route.query.page) if (this.$route.query.pageSize) this.pageSize = Number(this.$route.query.pageSize) @@ -266,6 +291,7 @@ export default Vue.extend({ // reset this.sortActive = this.parseQuerySortOrDefault(to.query.sort) + this.filters.splice(0, 1, this.parseQueryFilterStatus(to.query.readStatus)) this.page = 1 this.totalPages = 1 this.totalElements = null @@ -281,6 +307,7 @@ export default Vue.extend({ methods: { setWatches () { this.sortUnwatch = this.$watch('sortActive', this.updateRouteAndReload) + this.filterUnwatch = this.$watch('filters', this.updateRouteAndReload) this.pageSizeUnwatch = this.$watch('pageSize', (val) => { this.$cookies.set(cookiePageSize, val, Infinity) this.updateRouteAndReload() @@ -293,6 +320,7 @@ export default Vue.extend({ }, unsetWatches () { this.sortUnwatch() + this.filterUnwatch() this.pageUnwatch() this.pageSizeUnwatch() }, @@ -314,6 +342,9 @@ export default Vue.extend({ parseQuerySortOrDefault (querySort: any): SortActive { return parseQuerySort(querySort, this.sortOptions) || this.$_.clone(this.sortDefault) }, + parseQueryFilterStatus (queryStatus: any): string[] { + return queryStatus ? queryStatus.toString().split(',').filter((x: string) => Object.keys(ReadStatus).includes(x)) : [] + }, updateRoute (index?: string) { this.$router.replace({ name: this.$route.name, @@ -322,6 +353,7 @@ export default Vue.extend({ page: `${this.page}`, pageSize: `${this.pageSize}`, sort: `${this.sortActive.key},${this.sortActive.order}`, + readStatus: `${this.filters[0]}`, }, }).catch(_ => { }) @@ -335,7 +367,7 @@ export default Vue.extend({ if (sort) { pageRequest.sort = [`${sort.key},${sort.order}`] } - const booksPage = await this.$komgaSeries.getBooks(seriesId, pageRequest) + const booksPage = await this.$komgaSeries.getBooks(seriesId, pageRequest, this.filters[0]) this.totalPages = booksPage.totalPages this.totalElements = booksPage.totalElements diff --git a/komga-webui/src/views/Dashboard.vue b/komga-webui/src/views/Dashboard.vue index 626c38d22..7f1e17859 100644 --- a/komga-webui/src/views/Dashboard.vue +++ b/komga-webui/src/views/Dashboard.vue @@ -16,7 +16,7 @@ > - + @@ -29,9 +29,7 @@ -
- - + @@ -43,9 +41,7 @@ -
- - + @@ -57,9 +53,7 @@ -
- - +