diff --git a/komga-webui/src/locales/en.json b/komga-webui/src/locales/en.json index 0ee9ab67..a090a66b 100644 --- a/komga-webui/src/locales/en.json +++ b/komga-webui/src/locales/en.json @@ -5,6 +5,12 @@ "RIGHT_TO_LEFT": "Right to left", "VERTICAL": "Vertical", "WEBTOON": "Webtoon" + }, + "series_status": { + "ENDED": "Ended", + "ONGOING": "Ongoing", + "HIATUS": "Hiatus", + "ABANDONED":"Abandoned" } }, "theme": { diff --git a/komga-webui/src/locales/fr.json b/komga-webui/src/locales/fr.json index 2e36deb9..dc7eacca 100644 --- a/komga-webui/src/locales/fr.json +++ b/komga-webui/src/locales/fr.json @@ -5,6 +5,12 @@ "RIGHT_TO_LEFT": "Droite à gauche", "VERTICAL": "Vertical", "WEBTOON": "Webtoon" + }, + "series_status": { + "ENDED": "Finie", + "ONGOING": "En cours", + "HIATUS": "Hiatus", + "ABANDONED":"Abandonnée" } }, "theme": { diff --git a/komga-webui/src/types/enum-series.ts b/komga-webui/src/types/enum-series.ts index 2ab45ec8..ca9136b7 100644 --- a/komga-webui/src/types/enum-series.ts +++ b/komga-webui/src/types/enum-series.ts @@ -1,4 +1,4 @@ -import { capitalize } from 'lodash' +import i18n from "@/i18n"; export enum SeriesStatus { ENDED = 'ENDED', @@ -7,7 +7,9 @@ export enum SeriesStatus { HIATUS = 'HIATUS' } -export const SeriesStatusKeyValue = Object.values(SeriesStatus).map(x => ({ - name: capitalize(x), - value: x, -} as NameValue)) +export function SeriesStatusKeyValue(): NameValue[] { + return Object.values(SeriesStatus).map(x => ({ + name: i18n.t(`enums.series_status.${x}`), + value: x, + } as NameValue)) +} diff --git a/komga-webui/src/views/BrowseCollection.vue b/komga-webui/src/views/BrowseCollection.vue index 3ff0b243..732709b7 100644 --- a/komga-webui/src/views/BrowseCollection.vue +++ b/komga-webui/src/views/BrowseCollection.vue @@ -143,19 +143,6 @@ export default Vue.extend({ seriesCopy: [] as SeriesDto[], selectedSeries: [] as SeriesDto[], editElements: false, - filterOptionsList: { - readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, - } as FiltersOptions, - filterOptionsPanel: { - library: {name: this.$i18n.t('filter.library').toString(), values: []}, - status: {name: this.$i18n.t('filter.status').toString(), values: SeriesStatusKeyValue}, - genre: {name: this.$i18n.t('filter.genre').toString(), values: []}, - tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, - publisher: {name: this.$i18n.t('filter.publisher').toString(), values: []}, - language: {name: this.$i18n.t('filter.language').toString(), values: []}, - ageRating: {name: this.$i18n.t('filter.age_rating').toString(), values: []}, - releaseDate: {name: this.$i18n.t('filter.release_date').toString(), values: []}, - } as FiltersOptions, filters: {} as FiltersActive, filterUnwatch: null as any, drawer: false, @@ -168,7 +155,7 @@ export default Vue.extend({ }, }, watch: { - selectedSeries (val: SeriesDto[]) { + selectedSeries(val: SeriesDto[]) { val.forEach(s => { let index = this.series.findIndex(x => x.id === s.id) if (index !== -1) { @@ -181,24 +168,24 @@ export default Vue.extend({ }) }, }, - created () { + created() { this.$eventHub.$on(COLLECTION_CHANGED, this.collectionChanged) this.$eventHub.$on(COLLECTION_DELETED, this.afterDelete) this.$eventHub.$on(SERIES_CHANGED, this.reloadSeries) }, - beforeDestroy () { + beforeDestroy() { this.$eventHub.$off(COLLECTION_CHANGED, this.collectionChanged) this.$eventHub.$off(COLLECTION_DELETED, this.afterDelete) this.$eventHub.$off(SERIES_CHANGED, this.reloadSeries) }, - mounted () { + mounted() { this.loadCollection(this.collectionId) this.resetParams(this.$route) this.setWatches() }, - beforeRouteUpdate (to, from, next) { + beforeRouteUpdate(to, from, next) { if (to.params.collectionId !== from.params.collectionId) { this.unsetWatches() @@ -222,15 +209,32 @@ export default Vue.extend({ next() }, computed: { - isAdmin (): boolean { + filterOptionsList(): FiltersOptions { + return { + readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, + } as FiltersOptions + }, + filterOptionsPanel(): FiltersOptions { + return { + library: {name: this.$i18n.t('filter.library').toString(), values: []}, + status: {name: this.$i18n.t('filter.status').toString(), values: SeriesStatusKeyValue()}, + genre: {name: this.$i18n.t('filter.genre').toString(), values: []}, + tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, + publisher: {name: this.$i18n.t('filter.publisher').toString(), values: []}, + language: {name: this.$i18n.t('filter.language').toString(), values: []}, + ageRating: {name: this.$i18n.t('filter.age_rating').toString(), values: []}, + releaseDate: {name: this.$i18n.t('filter.release_date').toString(), values: []}, + } as FiltersOptions + }, + isAdmin(): boolean { return this.$store.getters.meAdmin }, - filterActive (): boolean { + filterActive(): boolean { return Object.keys(this.filters).some(x => this.filters[x].length !== 0) }, }, methods: { - resetParams (route: any) { + 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)) @@ -243,24 +247,24 @@ export default Vue.extend({ this.filters = this.$cookies.get(this.cookieFilter(route.params.collectionId)) || {} as FiltersActive } }, - cookieFilter (collectionId: string): string { + cookieFilter(collectionId: string): string { return `collection.filter.${collectionId}` }, - setWatches () { + setWatches() { this.filterUnwatch = this.$watch('filters', (val) => { this.$cookies.set(this.cookieFilter(this.collectionId), val, Infinity) this.updateRouteAndReload() }) }, - unsetWatches () { + unsetWatches() { this.filterUnwatch() }, - collectionChanged (event: EventCollectionChanged) { + collectionChanged(event: EventCollectionChanged) { if (event.id === this.collectionId) { this.loadCollection(this.collectionId) } }, - updateRouteAndReload () { + updateRouteAndReload() { this.unsetWatches() this.updateRoute() @@ -268,12 +272,12 @@ export default Vue.extend({ 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, this.filters.releaseDate)).content + 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, this.filters.releaseDate)).content this.seriesCopy = [...this.series] this.selectedSeries = [] }, - async loadCollection (collectionId: string) { + async loadCollection(collectionId: string) { this.collection = await this.$komgaCollections.getOneCollection(collectionId) await this.loadSeries(collectionId) @@ -288,23 +292,23 @@ export default Vue.extend({ this.filterOptionsPanel.ageRating.values = toNameValue(await this.$komgaReferential.getAgeRatings(undefined, collectionId)) this.filterOptionsPanel.releaseDate.values = toNameValue(await this.$komgaReferential.getSeriesReleaseDates(undefined, collectionId)) }, - updateRoute () { + updateRoute() { const loc = { name: this.$route.name, - params: { collectionId: this.$route.params.collectionId }, + params: {collectionId: this.$route.params.collectionId}, query: {}, } as Location mergeFilterParams(this.filters, loc.query) this.$router.replace(loc).catch((_: any) => { }) }, - editSingleSeries (series: SeriesDto) { + editSingleSeries(series: SeriesDto) { this.$store.dispatch('dialogUpdateSeries', series) }, - editMultipleSeries () { + editMultipleSeries() { this.$store.dispatch('dialogUpdateSeries', this.selectedSeries) }, - async markSelectedRead () { + async markSelectedRead() { await Promise.all(this.selectedSeries.map(s => this.$komgaSeries.markAsRead(s.id), )) @@ -312,7 +316,7 @@ export default Vue.extend({ this.$komgaSeries.getOneSeries(s.id), )) }, - async markSelectedUnread () { + async markSelectedUnread() { await Promise.all(this.selectedSeries.map(s => this.$komgaSeries.markAsUnread(s.id), )) @@ -320,18 +324,18 @@ export default Vue.extend({ this.$komgaSeries.getOneSeries(s.id), )) }, - addToCollection () { + addToCollection() { this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries) }, - startEditElements () { + startEditElements() { this.filters = {} this.editElements = true }, - cancelEditElements () { + cancelEditElements() { this.editElements = false this.series = [...this.seriesCopy] }, - doEditElements () { + doEditElements() { this.editElements = false const update = { seriesIds: this.series.map(x => x.id), @@ -339,13 +343,13 @@ export default Vue.extend({ this.$komgaCollections.patchCollection(this.collectionId, update) this.loadCollection(this.collectionId) }, - editCollection () { + editCollection() { this.$store.dispatch('dialogEditCollection', this.collection) }, - afterDelete () { - this.$router.push({ name: 'browse-collections', params: { libraryId: LIBRARIES_ALL } }) + afterDelete() { + this.$router.push({name: 'browse-collections', params: {libraryId: LIBRARIES_ALL}}) }, - reloadSeries (event: EventSeriesChanged) { + reloadSeries(event: EventSeriesChanged) { if (this.series.some(s => s.id === event.id)) this.loadCollection(this.collectionId) }, }, diff --git a/komga-webui/src/views/BrowseLibraries.vue b/komga-webui/src/views/BrowseLibraries.vue index a67333dc..2ec095cc 100644 --- a/komga-webui/src/views/BrowseLibraries.vue +++ b/komga-webui/src/views/BrowseLibraries.vue @@ -133,25 +133,8 @@ export default Vue.extend({ pageSize: 20, totalPages: 1, totalElements: null as number | null, - sortOptions: [ - {name: this.$i18n.t('sort.name').toString(), key: 'metadata.titleSort'}, - {name: this.$i18n.t('sort.date_added').toString(), key: 'createdDate'}, - {name: this.$i18n.t('sort.date_updated').toString(), key: 'lastModifiedDate'}, - ] as SortOption[], sortActive: {} as SortActive, sortDefault: {key: 'metadata.titleSort', order: 'asc'} as SortActive, - filterOptionsList: { - readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, - } as FiltersOptions, - filterOptionsPanel: { - status: {name: this.$i18n.t('filter.status').toString(), values: SeriesStatusKeyValue}, - genre: {name: this.$i18n.t('filter.genre').toString(), values: []}, - tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, - publisher: {name: this.$i18n.t('filter.publisher').toString(), values: []}, - language: {name: this.$i18n.t('filter.language').toString(), values: []}, - ageRating: {name: this.$i18n.t('filter.age_rating').toString(), values: []}, - releaseDate: {name: this.$i18n.t('filter.release_date').toString(), values: []}, - } as FiltersOptions, filters: {} as FiltersActive, sortUnwatch: null as any, filterUnwatch: null as any, @@ -167,7 +150,7 @@ export default Vue.extend({ }, }, watch: { - selectedSeries (val: SeriesDto[]) { + selectedSeries(val: SeriesDto[]) { val.forEach(s => { const index = this.series.findIndex(x => x.id === s.id) if (index !== -1) { @@ -176,17 +159,17 @@ export default Vue.extend({ }) }, }, - created () { + created() { this.$eventHub.$on(SERIES_CHANGED, this.reloadSeries) this.$eventHub.$on(LIBRARY_DELETED, this.libraryDeleted) this.$eventHub.$on(LIBRARY_CHANGED, this.reloadLibrary) }, - beforeDestroy () { + beforeDestroy() { this.$eventHub.$off(SERIES_CHANGED, this.reloadSeries) this.$eventHub.$off(LIBRARY_DELETED, this.libraryDeleted) this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary) }, - async mounted () { + async mounted() { if (this.$cookies.isKey(cookiePageSize)) { this.pageSize = Number(this.$cookies.get(cookiePageSize)) } @@ -200,7 +183,7 @@ export default Vue.extend({ this.setWatches() }, - beforeRouteUpdate (to, from, next) { + beforeRouteUpdate(to, from, next) { if (to.params.libraryId !== from.params.libraryId) { this.unsetWatches() @@ -225,10 +208,33 @@ export default Vue.extend({ next() }, computed: { - isAdmin (): boolean { + sortOptions(): SortOption[] { + return [ + {name: this.$i18n.t('sort.name').toString(), key: 'metadata.titleSort'}, + {name: this.$i18n.t('sort.date_added').toString(), key: 'createdDate'}, + {name: this.$i18n.t('sort.date_updated').toString(), key: 'lastModifiedDate'}, + ] as SortOption[] + }, + filterOptionsList(): FiltersOptions { + return { + readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, + } as FiltersOptions + }, + filterOptionsPanel(): FiltersOptions { + return { + status: {name: this.$i18n.t('filter.status').toString(), values: SeriesStatusKeyValue()}, + genre: {name: this.$i18n.t('filter.genre').toString(), values: []}, + tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, + publisher: {name: this.$i18n.t('filter.publisher').toString(), values: []}, + language: {name: this.$i18n.t('filter.language').toString(), values: []}, + ageRating: {name: this.$i18n.t('filter.age_rating').toString(), values: []}, + releaseDate: {name: this.$i18n.t('filter.release_date').toString(), values: []}, + } as FiltersOptions + }, + isAdmin(): boolean { return this.$store.getters.meAdmin }, - paginationVisible (): number { + paginationVisible(): number { switch (this.$vuetify.breakpoint.name) { case 'xs': return 5 @@ -241,18 +247,18 @@ export default Vue.extend({ return 15 } }, - sortOrFilterActive (): boolean { + sortOrFilterActive(): boolean { return sortOrFilterActive(this.sortActive, this.sortDefault, this.filters) }, }, methods: { - cookieSort (libraryId: string): string { + cookieSort(libraryId: string): string { return `library.sort.${libraryId}` }, - cookieFilter (libraryId: string): string { + cookieFilter(libraryId: string): string { return `library.filter.${libraryId}` }, - resetParams (route: any) { + resetParams(route: any) { this.sortActive = parseQuerySort(route.query.sort, this.sortOptions) || this.$cookies.get(this.cookieSort(route.params.libraryId)) || this.$_.clone(this.sortDefault) @@ -269,14 +275,14 @@ export default Vue.extend({ this.filters = this.$cookies.get(this.cookieFilter(route.params.libraryId)) || {} as FiltersActive } }, - libraryDeleted (event: EventLibraryDeleted) { + libraryDeleted(event: EventLibraryDeleted) { if (event.id === this.libraryId) { - this.$router.push({ name: 'home' }) + this.$router.push({name: 'home'}) } else if (this.libraryId === LIBRARIES_ALL) { this.loadLibrary(this.libraryId) } }, - setWatches () { + setWatches() { this.sortUnwatch = this.$watch('sortActive', (val) => { this.$cookies.set(this.cookieSort(this.libraryId), val, Infinity) this.updateRouteAndReload() @@ -295,13 +301,13 @@ export default Vue.extend({ this.loadPage(this.libraryId, val, this.sortActive) }) }, - unsetWatches () { + unsetWatches() { this.sortUnwatch() this.filterUnwatch() this.pageUnwatch() this.pageSizeUnwatch() }, - updateRouteAndReload () { + updateRouteAndReload() { this.unsetWatches() this.page = 1 @@ -311,17 +317,17 @@ export default Vue.extend({ this.setWatches() }, - reloadSeries (event: EventSeriesChanged) { + reloadSeries(event: EventSeriesChanged) { if (this.libraryId === LIBRARIES_ALL || event.libraryId === this.libraryId) { this.loadPage(this.libraryId, this.page, this.sortActive) } }, - reloadLibrary (event: EventLibraryChanged) { + reloadLibrary(event: EventLibraryChanged) { if (this.libraryId === LIBRARIES_ALL || event.id === this.libraryId) { this.loadLibrary(this.libraryId) } }, - async loadLibrary (libraryId: string) { + async loadLibrary(libraryId: string) { this.library = this.getLibraryLazy(libraryId) const requestLibraryId = libraryId !== LIBRARIES_ALL ? libraryId : undefined @@ -334,10 +340,10 @@ export default Vue.extend({ await this.loadPage(libraryId, this.page, this.sortActive) }, - updateRoute () { + updateRoute() { const loc = { name: this.$route.name, - params: { libraryId: this.$route.params.libraryId }, + params: {libraryId: this.$route.params.libraryId}, query: { page: `${this.page}`, pageSize: `${this.pageSize}`, @@ -348,7 +354,7 @@ export default Vue.extend({ this.$router.replace(loc).catch((_: any) => { }) }, - async loadPage (libraryId: string, page: number, sort: SortActive) { + async loadPage(libraryId: string, page: number, sort: SortActive) { this.selectedSeries = [] const pageRequest = { @@ -367,14 +373,14 @@ export default Vue.extend({ this.totalElements = seriesPage.totalElements this.series = seriesPage.content }, - getLibraryLazy (libraryId: any): LibraryDto | undefined { + getLibraryLazy(libraryId: any): LibraryDto | undefined { if (libraryId !== 0) { return this.$store.getters.getLibraryById(libraryId) } else { return undefined } }, - async markSelectedRead () { + async markSelectedRead() { await Promise.all(this.selectedSeries.map(s => this.$komgaSeries.markAsRead(s.id), )) @@ -382,7 +388,7 @@ export default Vue.extend({ this.$komgaSeries.getOneSeries(s.id), )) }, - async markSelectedUnread () { + async markSelectedUnread() { await Promise.all(this.selectedSeries.map(s => this.$komgaSeries.markAsUnread(s.id), )) @@ -390,13 +396,13 @@ export default Vue.extend({ this.$komgaSeries.getOneSeries(s.id), )) }, - addToCollection () { + addToCollection() { this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries) }, - editSingleSeries (series: SeriesDto) { + editSingleSeries(series: SeriesDto) { this.$store.dispatch('dialogUpdateSeries', series) }, - editMultipleSeries () { + editMultipleSeries() { this.$store.dispatch('dialogUpdateSeries', this.selectedSeries) }, }, diff --git a/komga-webui/src/views/BrowseSeries.vue b/komga-webui/src/views/BrowseSeries.vue index 04f0906f..fafd5e85 100644 --- a/komga-webui/src/views/BrowseSeries.vue +++ b/komga-webui/src/views/BrowseSeries.vue @@ -115,7 +115,9 @@ Summary from book {{ series.booksMetadata.summaryNumber }}: - {{ $t('browse_series.series_no_summary') }} + + {{ $t('browse_series.series_no_summary') }} + {{ series.booksMetadata.summary }} @@ -126,7 +128,9 @@ {{ $t('browse_series.earliest_year_from_release_dates') }} + + {{ $t('browse_series.earliest_year_from_release_dates') }} + @@ -277,20 +281,8 @@ export default Vue.extend({ pageSize: 20, totalPages: 1, totalElements: null as number | null, - sortOptions: [ - {name: this.$i18n.t('sort.number').toString(), key: 'metadata.numberSort'}, - {name: this.$i18n.t('sort.date_added').toString(), key: 'createdDate'}, - {name: this.$i18n.t('sort.release_date').toString(), key: 'metadata.releaseDate'}, - {name: this.$i18n.t('sort.file_size').toString(), key: 'fileSize'}, - ] as SortOption[], sortActive: {} as SortActive, sortDefault: {key: 'metadata.numberSort', order: 'asc'} as SortActive, - filterOptionsList: { - readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, - } as FiltersOptions, - filterOptionsPanel: { - tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, - } as FiltersOptions, filters: {} as FiltersActive, sortUnwatch: null as any, filterUnwatch: null as any, @@ -301,6 +293,24 @@ export default Vue.extend({ } }, computed: { + sortOptions(): SortOption[] { + return [ + {name: this.$i18n.t('sort.number').toString(), key: 'metadata.numberSort'}, + {name: this.$i18n.t('sort.date_added').toString(), key: 'createdDate'}, + {name: this.$i18n.t('sort.release_date').toString(), key: 'metadata.releaseDate'}, + {name: this.$i18n.t('sort.file_size').toString(), key: 'fileSize'}, + ] as SortOption[] + }, + filterOptionsList(): FiltersOptions { + return { + readStatus: {values: [{name: this.$i18n.t('filter.unread').toString(), value: ReadStatus.UNREAD}]}, + } as FiltersOptions + }, + filterOptionsPanel(): FiltersOptions { + return { + tag: {name: this.$i18n.t('filter.tag').toString(), values: []}, + } as FiltersOptions + }, isAdmin(): boolean { return this.$store.getters.meAdmin },