diff --git a/komga-webui/src/components/dialogs/EditSeriesDialog.vue b/komga-webui/src/components/dialogs/EditSeriesDialog.vue index 586d45797..bf6d57aa1 100644 --- a/komga-webui/src/components/dialogs/EditSeriesDialog.vue +++ b/komga-webui/src/components/dialogs/EditSeriesDialog.vue @@ -35,6 +35,10 @@ mdi-image {{ $t('dialog.edit_series.tab_poster') }} + + mdi-account-multiple + {{ $t('dialog.edit_series.tab_sharing') }} + @@ -347,6 +351,46 @@ + + + + + + {{ $t('dialog.edit_series.tags_notice_multiple_edit') }} + + + + + + {{ $t('dialog.edit_series.field_labels') }} + + + + + + + + @@ -403,6 +447,8 @@ export default Vue.extend({ tagsLock: false, totalBookCount: undefined as number | undefined, totalBookCountLock: false, + sharingLabels: [], + sharingLabelsLock: false, }, mixed: { status: false, @@ -419,6 +465,7 @@ export default Vue.extend({ }, genresAvailable: [] as string[], tagsAvailable: [] as string[], + sharingLabelsAvailable: [] as string[], } }, props: { @@ -437,6 +484,7 @@ export default Vue.extend({ this.getThumbnails(this.series) this.loadAvailableTags() this.loadAvailableGenres() + this.loadAvailableSharingLabels() } else { this.dialogCancel() } @@ -469,6 +517,7 @@ export default Vue.extend({ }, genres: {}, tags: {}, + sharingLabels: {}, ageRating: {minValue: minValue(0)}, readingDirection: {}, publisher: {}, @@ -523,6 +572,9 @@ export default Vue.extend({ async loadAvailableGenres() { this.genresAvailable = await this.$komgaReferential.getGenres() }, + async loadAvailableSharingLabels() { + this.sharingLabelsAvailable = await this.$komgaReferential.getSharingLabels() + }, requiredErrors(fieldName: string): string[] { const errors = [] as string[] const formField = this.$v.form!![fieldName] as any @@ -579,9 +631,15 @@ export default Vue.extend({ const tagsLock = this.$_.uniq(series.map(x => x.metadata.tagsLock)) this.form.tagsLock = tagsLock.length > 1 ? false : tagsLock[0] + + this.form.sharingLabels = [] + + const sharingLabelsLock = this.$_.uniq(series.map(x => x.metadata.sharingLabelsLock)) + this.form.sharingLabelsLock = sharingLabelsLock.length > 1 ? false : sharingLabelsLock[0] } else { this.form.genres = [] this.form.tags = [] + this.form.sharingLabels = [] this.$_.merge(this.form, (series as SeriesDto).metadata) this.poster.selectedThumbnail = '' this.poster.deleteQueue = [] @@ -609,6 +667,7 @@ export default Vue.extend({ genresLock: this.form.genresLock, tagsLock: this.form.tagsLock, totalBookCountLock: this.form.totalBookCountLock, + sharingLabelsLock: this.form.sharingLabelsLock, } if (this.$v.form?.status?.$dirty) { @@ -639,6 +698,10 @@ export default Vue.extend({ this.$_.merge(metadata, {language: this.form.language}) } + if (this.$v.form?.sharingLabels?.$dirty) { + this.$_.merge(metadata, {sharingLabels: this.form.sharingLabels}) + } + if (this.single) { this.$_.merge(metadata, { titleLock: this.form.titleLock, diff --git a/komga-webui/src/locales/en.json b/komga-webui/src/locales/en.json index 1b59106eb..eaf9f83f5 100644 --- a/komga-webui/src/locales/en.json +++ b/komga-webui/src/locales/en.json @@ -428,6 +428,7 @@ "field_age_rating": "Age Rating", "field_age_rating_error": "Age rating must be 0 or more", "field_genres": "Genres", + "field_labels": "Labels", "field_language": "Language", "field_language_hint": "IETF BCP 47 language tag", "field_publisher": "Publisher", @@ -442,6 +443,7 @@ "mixed": "MIXED", "tab_general": "General", "tab_poster": "Poster", + "tab_sharing": "Sharing", "tab_tags": "Tags", "tags_notice_multiple_edit": "You are editing tags for multiple series. This will override existing tags of each series." }, diff --git a/komga-webui/src/services/komga-referential.service.ts b/komga-webui/src/services/komga-referential.service.ts index 724401db4..17509a518 100644 --- a/komga-webui/src/services/komga-referential.service.ts +++ b/komga-webui/src/services/komga-referential.service.ts @@ -84,6 +84,25 @@ export default class KomgaReferentialService { } } + async getSharingLabels(libraryId?: string, collectionId?: string): Promise { + try { + const params = {} as any + if (libraryId) params.library_id = libraryId + if (collectionId) params.collection_id = collectionId + + return (await this.http.get('/api/v1/sharing-labels', { + params: params, + paramsSerializer: params => qs.stringify(params, {indices: false}), + })).data + } catch (e) { + let msg = 'An error occurred while trying to retrieve sharing labels' + if (e.response.data.message) { + msg += `: ${e.response.data.message}` + } + throw new Error(msg) + } + } + async getSeriesAndBookTags(libraryId?: string, collectionId?: string): Promise { try { const params = {} as any diff --git a/komga-webui/src/types/komga-series.ts b/komga-webui/src/types/komga-series.ts index 408f0cf34..cc7ede8ad 100644 --- a/komga-webui/src/types/komga-series.ts +++ b/komga-webui/src/types/komga-series.ts @@ -41,6 +41,8 @@ export interface SeriesMetadataDto { tagsLock: boolean, totalBookCount?: number, totalBookCountLock: boolean, + sharingLabels: string[], + sharingLabelsLock: boolean, } export interface SeriesBooksMetadataDto { @@ -76,6 +78,8 @@ export interface SeriesMetadataUpdateDto { tagsLock?: boolean, totalBookCount?: number, totalBookCountLock: boolean, + sharingLabels?: string[], + sharingLabelsLock: boolean, } export interface GroupCountDto {