Add:Batch append details #848

This commit is contained in:
advplyr 2022-12-13 16:28:05 -06:00
parent 05d10b73c3
commit e59351566d
4 changed files with 93 additions and 47 deletions

View File

@ -113,7 +113,10 @@ export default {
if (this.searching) return if (this.searching) return
this.currentSearch = this.textInput this.currentSearch = this.textInput
this.searching = true this.searching = true
var results = await this.$axios.$get(`/api/${this.endpoint}?q=${this.currentSearch}&limit=15&token=${this.userToken}`).catch((error) => { const results = await this.$axios
.$get(`/api/${this.endpoint}?q=${this.currentSearch}&limit=15&token=${this.userToken}`)
.then((res) => res.results || res)
.catch((error) => {
console.error('Failed to get search results', error) console.error('Failed to get search results', error)
return [] return []
}) })

View File

@ -137,8 +137,24 @@ export default {
author: (this.details.authors || []).map((au) => au.name).join(', ') author: (this.details.authors || []).map((au) => au.name).join(', ')
} }
}, },
mapBatchDetails(batchDetails) { mapBatchDetails(batchDetails, mapType = 'overwrite') {
for (const key in batchDetails) { for (const key in batchDetails) {
if (mapType === 'append') {
if (key === 'tags') {
// Concat and remove dupes
this.newTags = [...new Set(this.newTags.concat(batchDetails.tags))]
} else if (key === 'genres' || key === 'narrators') {
// Concat and remove dupes
this.details[key] = [...new Set(this.details[key].concat(batchDetails[key]))]
} else if (key === 'authors' || key === 'series') {
batchDetails[key].forEach((detail) => {
const existingDetail = this.details[key].find((_d) => _d.name.toLowerCase() == detail.name.toLowerCase().trim() || _d.id == detail.id)
if (!existingDetail) {
this.details[key].push({ ...detail })
}
})
}
} else {
if (key === 'tags') { if (key === 'tags') {
this.newTags = [...batchDetails.tags] this.newTags = [...batchDetails.tags]
} else if (key === 'genres' || key === 'narrators') { } else if (key === 'genres' || key === 'narrators') {
@ -149,6 +165,7 @@ export default {
this.details[key] = batchDetails[key] this.details[key] = batchDetails[key]
} }
} }
}
}, },
forceBlur() { forceBlur() {
if (this.$refs.titleInput) this.$refs.titleInput.blur() if (this.$refs.titleInput) this.$refs.titleInput.blur()

View File

@ -107,8 +107,17 @@ export default {
author: this.details.author author: this.details.author
} }
}, },
mapBatchDetails(batchDetails) { mapBatchDetails(batchDetails, mapType = 'overwrite') {
for (const key in batchDetails) { for (const key in batchDetails) {
if (mapType === 'append') {
if (key === 'tags') {
// Concat and remove dupes
this.newTags = [...new Set(this.newTags.concat(batchDetails.tags))]
} else if (key === 'genres') {
// Concat and remove dupes
this.details[key] = [...new Set(this.details[key].concat(batchDetails[key]))]
}
} else {
if (key === 'tags') { if (key === 'tags') {
this.newTags = [...batchDetails.tags] this.newTags = [...batchDetails.tags]
} else if (key === 'genres') { } else if (key === 'genres') {
@ -117,6 +126,7 @@ export default {
this.details[key] = batchDetails[key] this.details[key] = batchDetails[key]
} }
} }
}
}, },
forceBlur() { forceBlur() {
if (this.$refs.titleInput) this.$refs.titleInput.blur() if (this.$refs.titleInput) this.$refs.titleInput.blur()

View File

@ -5,11 +5,22 @@
<span class="material-icons text-2xl">{{ openMapOptions ? 'expand_less' : 'expand_more' }}</span> <span class="material-icons text-2xl">{{ openMapOptions ? 'expand_less' : 'expand_more' }}</span>
<p class="ml-4 text-gray-200 text-lg">Map details</p> <p class="ml-4 text-gray-200 text-lg">Map details</p>
<div class="flex-grow" />
<div class="w-64 flex">
<button class="w-32 h-8 rounded-l-md shadow-md border border-gray-600" :class="!isMapOverwrite ? 'bg-bg text-white/30' : 'bg-primary'" @click.stop.prevent="mapDetailsType = 'overwrite'">
<p class="text-sm">Overwrite</p>
</button>
<button class="w-32 h-8 rounded-r-md shadow-md border border-gray-600" :class="!isMapAppend ? 'bg-bg text-white/30' : 'bg-primary'" @click.stop.prevent="mapDetailsType = 'append'">
<p class="text-sm">Append</p>
</button>
</div>
</div> </div>
<div class="overflow-hidden"> <div class="overflow-hidden">
<transition name="slide"> <transition name="slide">
<div v-if="openMapOptions" class="flex flex-wrap"> <div v-if="openMapOptions" class="flex flex-wrap">
<div v-if="!isPodcastLibrary" class="flex items-center px-4 w-1/2"> <div v-if="!isPodcastLibrary && !isMapAppend" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.subtitle" /> <ui-checkbox v-model="selectedBatchUsage.subtitle" />
<ui-text-input-with-label ref="subtitleInput" v-model="batchDetails.subtitle" :disabled="!selectedBatchUsage.subtitle" :label="$strings.LabelSubtitle" class="mb-4 ml-4" /> <ui-text-input-with-label ref="subtitleInput" v-model="batchDetails.subtitle" :disabled="!selectedBatchUsage.subtitle" :label="$strings.LabelSubtitle" class="mb-4 ml-4" />
</div> </div>
@ -18,13 +29,13 @@
<!-- Authors filter only contains authors in this library, use query input to query all authors --> <!-- Authors filter only contains authors in this library, use query input to query all authors -->
<ui-multi-select-query-input ref="authorsSelect" v-model="batchDetails.authors" :disabled="!selectedBatchUsage.authors" :label="$strings.LabelAuthors" endpoint="authors/search" class="mb-4 ml-4" /> <ui-multi-select-query-input ref="authorsSelect" v-model="batchDetails.authors" :disabled="!selectedBatchUsage.authors" :label="$strings.LabelAuthors" endpoint="authors/search" class="mb-4 ml-4" />
</div> </div>
<div v-if="!isPodcastLibrary" class="flex items-center px-4 w-1/2"> <div v-if="!isPodcastLibrary && !isMapAppend" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.publishedYear" /> <ui-checkbox v-model="selectedBatchUsage.publishedYear" />
<ui-text-input-with-label ref="publishedYearInput" v-model="batchDetails.publishedYear" :disabled="!selectedBatchUsage.publishedYear" :label="$strings.LabelPublishYear" class="mb-4 ml-4" /> <ui-text-input-with-label ref="publishedYearInput" v-model="batchDetails.publishedYear" :disabled="!selectedBatchUsage.publishedYear" :label="$strings.LabelPublishYear" class="mb-4 ml-4" />
</div> </div>
<div v-if="!isPodcastLibrary" class="flex items-center px-4 w-1/2"> <div v-if="!isPodcastLibrary" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.series" /> <ui-checkbox v-model="selectedBatchUsage.series" />
<ui-multi-select ref="seriesSelect" v-model="batchDetails.series" :disabled="!selectedBatchUsage.series" :label="$strings.LabelSeries" :items="seriesItems" @newItem="newSeriesItem" @removedItem="removedSeriesItem" class="mb-4 ml-4" /> <ui-multi-select ref="seriesSelect" v-model="batchDetails.series" :disabled="!selectedBatchUsage.series" :label="$strings.LabelSeries" :items="existingSeriesNames" @newItem="newSeriesItem" @removedItem="removedSeriesItem" class="mb-4 ml-4" />
</div> </div>
<div class="flex items-center px-4 w-1/2"> <div class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.genres" /> <ui-checkbox v-model="selectedBatchUsage.genres" />
@ -38,15 +49,15 @@
<ui-checkbox v-model="selectedBatchUsage.narrators" /> <ui-checkbox v-model="selectedBatchUsage.narrators" />
<ui-multi-select ref="narratorsSelect" v-model="batchDetails.narrators" :disabled="!selectedBatchUsage.narrators" :label="$strings.LabelNarrators" :items="narratorItems" @newItem="newNarratorItem" @removedItem="removedNarratorItem" class="mb-4 ml-4" /> <ui-multi-select ref="narratorsSelect" v-model="batchDetails.narrators" :disabled="!selectedBatchUsage.narrators" :label="$strings.LabelNarrators" :items="narratorItems" @newItem="newNarratorItem" @removedItem="removedNarratorItem" class="mb-4 ml-4" />
</div> </div>
<div v-if="!isPodcastLibrary" class="flex items-center px-4 w-1/2"> <div v-if="!isPodcastLibrary && !isMapAppend" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.publisher" /> <ui-checkbox v-model="selectedBatchUsage.publisher" />
<ui-text-input-with-label ref="publisherInput" v-model="batchDetails.publisher" :disabled="!selectedBatchUsage.publisher" :label="$strings.LabelPublisher" class="mb-4 ml-4" /> <ui-text-input-with-label ref="publisherInput" v-model="batchDetails.publisher" :disabled="!selectedBatchUsage.publisher" :label="$strings.LabelPublisher" class="mb-4 ml-4" />
</div> </div>
<div class="flex items-center px-4 w-1/2"> <div v-if="!isMapAppend" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.language" /> <ui-checkbox v-model="selectedBatchUsage.language" />
<ui-text-input-with-label ref="languageInput" v-model="batchDetails.language" :disabled="!selectedBatchUsage.language" :label="$strings.LabelLanguage" class="mb-4 ml-4" /> <ui-text-input-with-label ref="languageInput" v-model="batchDetails.language" :disabled="!selectedBatchUsage.language" :label="$strings.LabelLanguage" class="mb-4 ml-4" />
</div> </div>
<div class="flex items-center px-4 w-1/2"> <div v-if="!isMapAppend" class="flex items-center px-4 w-1/2">
<ui-checkbox v-model="selectedBatchUsage.explicit" /> <ui-checkbox v-model="selectedBatchUsage.explicit" />
<div class="ml-4"> <div class="ml-4">
<ui-checkbox <ui-checkbox
@ -114,10 +125,10 @@ export default {
isProcessing: false, isProcessing: false,
libraryItemCopies: [], libraryItemCopies: [],
isScrollable: false, isScrollable: false,
newSeriesNames: [],
newTagItems: [], newTagItems: [],
newGenreItems: [], newGenreItems: [],
newNarratorItems: [], newNarratorItems: [],
mapDetailsType: 'overwrite',
batchDetails: { batchDetails: {
subtitle: null, subtitle: null,
authors: null, authors: null,
@ -142,10 +153,17 @@ export default {
language: false, language: false,
explicit: false explicit: false
}, },
appendableKeys: ['authors', 'genres', 'tags', 'narrators', 'series'],
openMapOptions: false openMapOptions: false
} }
}, },
computed: { computed: {
isMapOverwrite() {
return this.mapDetailsType === 'overwrite'
},
isMapAppend() {
return this.mapDetailsType === 'append'
},
isPodcastLibrary() { isPodcastLibrary() {
return this.mediaType === 'podcast' return this.mediaType === 'podcast'
}, },
@ -158,9 +176,6 @@ export default {
tagItems() { tagItems() {
return this.tags.concat(this.newTagItems) return this.tags.concat(this.newTagItems)
}, },
seriesItems() {
return [...this.existingSeriesNames, ...this.newSeriesNames]
},
narratorItems() { narratorItems() {
return [...this.narrators, ...this.newNarratorItems] return [...this.narrators, ...this.newNarratorItems]
}, },
@ -219,13 +234,15 @@ export default {
mapBatchDetails() { mapBatchDetails() {
this.blurBatchForm() this.blurBatchForm()
var batchMapPayload = {} const batchMapPayload = {}
for (const key in this.selectedBatchUsage) { for (const key in this.selectedBatchUsage) {
if (this.selectedBatchUsage[key]) { if (!this.selectedBatchUsage[key]) continue
if (this.isMapAppend && !this.appendableKeys.includes(key)) continue
if (key === 'series') { if (key === 'series') {
// Map string of series to series objects // Map string of series to series objects
batchMapPayload[key] = this.batchDetails[key].map((seItem) => { batchMapPayload[key] = this.batchDetails[key].map((seItem) => {
var existingSeries = this.series.find((se) => se.name.toLowerCase() === seItem.toLowerCase().trim()) const existingSeries = this.series.find((se) => se.name.toLowerCase() === seItem.toLowerCase().trim())
if (existingSeries) { if (existingSeries) {
return existingSeries return existingSeries
} else { } else {
@ -239,11 +256,10 @@ export default {
batchMapPayload[key] = this.batchDetails[key] batchMapPayload[key] = this.batchDetails[key]
} }
} }
}
this.libraryItemCopies.forEach((li) => { this.libraryItemCopies.forEach((li) => {
var ref = this.getEditFormRef(li.id) const ref = this.getEditFormRef(li.id)
ref.mapBatchDetails(batchMapPayload) ref.mapBatchDetails(batchMapPayload, this.mapDetailsType)
}) })
this.$toast.success('Details mapped') this.$toast.success('Details mapped')
}, },