mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-05-25 12:51:31 +00:00
Merge 5431665dfe into 47ea6b5092
This commit is contained in:
commit
4ec234952f
4 changed files with 49 additions and 7 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="bg-bg rounded-lg px-2 py-6 sm:p-6 md:p-8" @click.stop>
|
<div class="bg-bg rounded-lg px-2 py-6 sm:p-6 md:p-8" @click.stop>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="grow p-1 min-w-48 sm:min-w-64 md:min-w-80">
|
<div class="grow p-1 min-w-48 sm:min-w-64 md:min-w-80">
|
||||||
<ui-input-dropdown ref="newSeriesSelect" v-model="selectedSeries.name" :items="existingSeriesNames" :disabled="!isNewSeries" :label="$strings.LabelSeriesName" @input="seriesNameInputHandler" />
|
<ui-input-dropdown ref="newSeriesSelect" v-model="selectedSeries.name" :items="existingSeriesNames" :label="$strings.LabelSeriesName" @input="seriesNameInputHandler" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-24 sm:w-28 md:w-40 p-1">
|
<div class="w-24 sm:w-28 md:w-40 p-1">
|
||||||
<ui-text-input-with-label ref="sequenceInput" v-model="selectedSeries.sequence" :label="$strings.LabelSequence" />
|
<ui-text-input-with-label ref="sequenceInput" v-model="selectedSeries.sequence" :label="$strings.LabelSequence" />
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
selectedSeries: null,
|
selectedSeries: null,
|
||||||
originalSeriesSequence: null,
|
originalSeriesSequence: null,
|
||||||
|
originalSeriesName: null,
|
||||||
showSeriesForm: false
|
showSeriesForm: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -61,6 +62,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.originalSeriesSequence = _series.sequence
|
this.originalSeriesSequence = _series.sequence
|
||||||
|
this.originalSeriesName = _series.name
|
||||||
this.showSeriesForm = true
|
this.showSeriesForm = true
|
||||||
},
|
},
|
||||||
addNewSeries() {
|
addNewSeries() {
|
||||||
|
|
@ -71,6 +73,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.originalSeriesSequence = null
|
this.originalSeriesSequence = null
|
||||||
|
this.originalSeriesName = null
|
||||||
this.showSeriesForm = true
|
this.showSeriesForm = true
|
||||||
},
|
},
|
||||||
submitSeriesForm() {
|
submitSeriesForm() {
|
||||||
|
|
@ -81,6 +84,18 @@ export default {
|
||||||
|
|
||||||
var existingSeriesIndex = this.seriesItems.findIndex((se) => se.id === this.selectedSeries.id)
|
var existingSeriesIndex = this.seriesItems.findIndex((se) => se.id === this.selectedSeries.id)
|
||||||
|
|
||||||
|
// Check if renaming to a name that already exists in the library (different series)
|
||||||
|
var seriesSameName = this.series.find((se) => se.name.toLowerCase() === this.selectedSeries.name.toLowerCase())
|
||||||
|
if (seriesSameName && seriesSameName.id !== this.selectedSeries.id) {
|
||||||
|
// If editing an existing series and trying to rename to an existing name, block it
|
||||||
|
if (!this.selectedSeries.id.startsWith('new-')) {
|
||||||
|
this.$toast.error(this.$strings.ToastSeriesDuplicateName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// For new series, use the existing series id instead
|
||||||
|
this.selectedSeries.id = seriesSameName.id
|
||||||
|
}
|
||||||
|
|
||||||
var existingSeriesSameName = this.seriesItems.findIndex((se) => se.name.toLowerCase() === this.selectedSeries.name.toLowerCase())
|
var existingSeriesSameName = this.seriesItems.findIndex((se) => se.name.toLowerCase() === this.selectedSeries.name.toLowerCase())
|
||||||
if (existingSeriesSameName >= 0 && existingSeriesIndex < 0) {
|
if (existingSeriesSameName >= 0 && existingSeriesIndex < 0) {
|
||||||
console.error('Attempt to add duplicate series')
|
console.error('Attempt to add duplicate series')
|
||||||
|
|
@ -88,11 +103,6 @@ export default {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var seriesSameName = this.series.find((se) => se.name.toLowerCase() === this.selectedSeries.name.toLowerCase())
|
|
||||||
if (existingSeriesIndex < 0 && seriesSameName) {
|
|
||||||
this.selectedSeries.id = seriesSameName.id
|
|
||||||
}
|
|
||||||
|
|
||||||
var selectedSeriesCopy = { ...this.selectedSeries }
|
var selectedSeriesCopy = { ...this.selectedSeries }
|
||||||
selectedSeriesCopy.displayName = selectedSeriesCopy.sequence ? `${selectedSeriesCopy.name} #${selectedSeriesCopy.sequence}` : selectedSeriesCopy.name
|
selectedSeriesCopy.displayName = selectedSeriesCopy.sequence ? `${selectedSeriesCopy.name} #${selectedSeriesCopy.sequence}` : selectedSeriesCopy.name
|
||||||
|
|
||||||
|
|
@ -105,7 +115,25 @@ export default {
|
||||||
this.seriesItems = seriesCopy
|
this.seriesItems = seriesCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is an existing series (not new), update the series name immediately
|
||||||
|
if (!this.selectedSeries.id.startsWith('new-')) {
|
||||||
|
const hasNameChanged = this.originalSeriesName && this.selectedSeries.name !== this.originalSeriesName
|
||||||
|
if (hasNameChanged) {
|
||||||
|
this.updateSeriesName(this.selectedSeries.id, this.selectedSeries.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.showSeriesForm = false
|
this.showSeriesForm = false
|
||||||
|
},
|
||||||
|
async updateSeriesName(seriesId, name) {
|
||||||
|
try {
|
||||||
|
await this.$axios.$patch(`/api/series/${seriesId}`, { name })
|
||||||
|
this.$toast.success(this.$strings.ToastSeriesUpdateSuccess)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to update series name:', error)
|
||||||
|
const errorMsg = error.response?.data || this.$strings.ToastSeriesUpdateFailed
|
||||||
|
this.$toast.error(errorMsg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1127,6 +1127,7 @@
|
||||||
"ToastSelectAtLeastOneUser": "Select at least one user",
|
"ToastSelectAtLeastOneUser": "Select at least one user",
|
||||||
"ToastSendEbookToDeviceFailed": "Failed to send ebook to device",
|
"ToastSendEbookToDeviceFailed": "Failed to send ebook to device",
|
||||||
"ToastSendEbookToDeviceSuccess": "Ebook sent to device \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "Ebook sent to device \"{0}\"",
|
||||||
|
"ToastSeriesDuplicateName": "A series with that name already exists in this library",
|
||||||
"ToastSeriesSubmitFailedSameName": "Cannot add two series with the same name",
|
"ToastSeriesSubmitFailedSameName": "Cannot add two series with the same name",
|
||||||
"ToastSeriesUpdateFailed": "Series update failed",
|
"ToastSeriesUpdateFailed": "Series update failed",
|
||||||
"ToastSeriesUpdateSuccess": "Series update success",
|
"ToastSeriesUpdateSuccess": "Series update success",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const Database = require('../Database')
|
||||||
const RssFeedManager = require('../managers/RssFeedManager')
|
const RssFeedManager = require('../managers/RssFeedManager')
|
||||||
|
|
||||||
const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilters')
|
const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilters')
|
||||||
|
const { getTitleIgnorePrefix } = require('../utils/index')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef RequestUserObject
|
* @typedef RequestUserObject
|
||||||
|
|
@ -62,7 +63,8 @@ class SeriesController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Currently unused in the client, should check for duplicate name
|
* PATCH /api/series/:id
|
||||||
|
* Update series metadata (name, description)
|
||||||
*
|
*
|
||||||
* @param {SeriesControllerRequest} req
|
* @param {SeriesControllerRequest} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
|
|
@ -78,6 +80,17 @@ class SeriesController {
|
||||||
if (!Object.keys(payload).length) {
|
if (!Object.keys(payload).length) {
|
||||||
return res.status(400).send('No valid fields to update')
|
return res.status(400).send('No valid fields to update')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for duplicate series name in the same library
|
||||||
|
if (payload.name && payload.name.toLowerCase() !== req.series.name.toLowerCase()) {
|
||||||
|
const existingSeries = await Database.seriesModel.getByNameAndLibrary(payload.name, req.series.libraryId)
|
||||||
|
if (existingSeries && existingSeries.id !== req.series.id) {
|
||||||
|
return res.status(400).send('A series with that name already exists in this library')
|
||||||
|
}
|
||||||
|
// Update nameIgnorePrefix when name changes
|
||||||
|
payload.nameIgnorePrefix = getTitleIgnorePrefix(payload.name)
|
||||||
|
}
|
||||||
|
|
||||||
req.series.set(payload)
|
req.series.set(payload)
|
||||||
if (req.series.changed()) {
|
if (req.series.changed()) {
|
||||||
await req.series.save()
|
await req.series.save()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue