New data model batch routes and batch editor

This commit is contained in:
advplyr 2022-03-13 17:10:48 -05:00
parent 6597fca576
commit 4bdef893af
19 changed files with 743 additions and 604 deletions

View file

@ -44,8 +44,8 @@
</nuxt-link>
</div>
<div v-show="numAudiobooksSelected" class="absolute top-0 left-0 w-full h-full px-4 bg-primary flex items-center">
<h1 class="text-2xl px-4">{{ numAudiobooksSelected }} Selected</h1>
<div v-show="numLibraryItemsSelected" class="absolute top-0 left-0 w-full h-full px-4 bg-primary flex items-center">
<h1 class="text-2xl px-4">{{ numLibraryItemsSelected }} Selected</h1>
<div class="flex-grow" />
<ui-tooltip :text="`Mark as ${selectedIsRead ? 'Not Read' : 'Read'}`" direction="bottom">
<ui-read-icon-btn :disabled="processingBatch" :is-read="selectedIsRead" @click="toggleBatchRead" class="mx-1.5" />
@ -53,7 +53,7 @@
<ui-tooltip v-if="userCanUpdate" text="Add to Collection" direction="bottom">
<ui-icon-btn :disabled="processingBatch" icon="collections_bookmark" @click="batchAddToCollectionClick" class="mx-1.5" />
</ui-tooltip>
<template v-if="userCanUpdate && numAudiobooksSelected < 50">
<template v-if="userCanUpdate && numLibraryItemsSelected < 50">
<ui-icon-btn v-show="!processingBatchDelete" icon="edit" bg-color="warning" class="mx-1.5" @click="batchEditClick" />
</template>
<ui-icon-btn v-show="userCanDelete" :disabled="processingBatchDelete" icon="delete" bg-color="error" class="mx-1.5" @click="batchDeleteClick" />
@ -94,11 +94,11 @@ export default {
username() {
return this.user ? this.user.username : 'err'
},
numAudiobooksSelected() {
return this.selectedAudiobooks.length
numLibraryItemsSelected() {
return this.selectedLibraryItems.length
},
selectedAudiobooks() {
return this.$store.state.selectedAudiobooks
selectedLibraryItems() {
return this.$store.state.selectedLibraryItems
},
userAudiobooks() {
return this.$store.state.user.user.audiobooks || {}
@ -117,8 +117,8 @@ export default {
},
selectedIsRead() {
// Find an audiobook that is not read, if none then all audiobooks read
return !this.selectedAudiobooks.find((ab) => {
var userAb = this.userAudiobooks[ab]
return !this.selectedLibraryItems.find((li) => {
var userAb = this.userAudiobooks[li]
return !userAb || !userAb.isRead
})
},
@ -150,16 +150,16 @@ export default {
},
cancelSelectionMode() {
if (this.processingBatchDelete) return
this.$store.commit('setSelectedAudiobooks', [])
this.$store.commit('setSelectedLibraryItems', [])
this.$eventBus.$emit('bookshelf-clear-selection')
this.isAllSelected = false
},
toggleBatchRead() {
this.$store.commit('setProcessingBatch', true)
var newIsRead = !this.selectedIsRead
var updateProgressPayloads = this.selectedAudiobooks.map((ab) => {
var updateProgressPayloads = this.selectedLibraryItems.map((lid) => {
return {
audiobookId: ab,
audiobookId: lid,
isRead: newIsRead
}
})
@ -168,7 +168,7 @@ export default {
.then(() => {
this.$toast.success('Batch update success!')
this.$store.commit('setProcessingBatch', false)
this.$store.commit('setSelectedAudiobooks', [])
this.$store.commit('setSelectedLibraryItems', [])
this.$eventBus.$emit('bookshelf-clear-selection')
})
.catch((error) => {
@ -178,20 +178,20 @@ export default {
})
},
batchDeleteClick() {
var audiobookText = this.numAudiobooksSelected > 1 ? `these ${this.numAudiobooksSelected} audiobooks` : 'this audiobook'
var audiobookText = this.numLibraryItemsSelected > 1 ? `these ${this.numLibraryItemsSelected} audiobooks` : 'this audiobook'
var confirmMsg = `Are you sure you want to remove ${audiobookText}?\n\n*Does not delete your files, only removes the audiobooks from AudioBookshelf`
if (confirm(confirmMsg)) {
this.processingBatchDelete = true
this.$store.commit('setProcessingBatch', true)
this.$axios
.$post(`/api/books/batch/delete`, {
audiobookIds: this.selectedAudiobooks
.$post(`/api/items/batch/delete`, {
libraryItemIds: this.selectedLibraryItems
})
.then(() => {
this.$toast.success('Batch delete success!')
this.processingBatchDelete = false
this.$store.commit('setProcessingBatch', false)
this.$store.commit('setSelectedAudiobooks', [])
this.$store.commit('setSelectedLibraryItems', [])
this.$eventBus.$emit('bookshelf-clear-selection')
})
.catch((error) => {

View file

@ -69,16 +69,16 @@ export default {
showExperimentalFeatures() {
return this.$store.state.showExperimentalFeatures
},
audiobookId() {
libraryItemId() {
return this.book.id
},
selected: {
get() {
return this.$store.getters['getIsAudiobookSelected'](this.audiobookId)
return this.$store.getters['getIsLibraryItemSelected'](this.libraryItemId)
},
set(val) {
if (this.processingBatch) return
this.$store.commit('setAudiobookSelected', { audiobookId: this.audiobookId, selected: val })
this.$store.commit('setLibraryItemSelected', { libraryItemId: this.libraryItemId, selected: val })
}
},
processingBatch() {
@ -118,7 +118,7 @@ export default {
return this.book.numTracks
},
isStreaming() {
return this.$store.getters['getLibraryItemIdStreaming'] === this.audiobookId
return this.$store.getters['getLibraryItemIdStreaming'] === this.libraryItemId
},
showReadButton() {
return this.showExperimentalFeatures && this.numEbooks
@ -142,7 +142,7 @@ export default {
methods: {
selectBtnClick() {
if (this.processingBatch) return
this.$store.commit('toggleAudiobookSelected', this.audiobookId)
this.$store.commit('toggleLibraryItemSelected', this.libraryItemId)
},
openEbook() {
this.$store.commit('showEReader', this.book)
@ -156,7 +156,7 @@ export default {
}
this.isProcessingReadUpdate = true
this.$axios
.$patch(`/api/me/audiobook/${this.audiobookId}`, updatePayload)
.$patch(`/api/me/audiobook/${this.libraryItemId}`, updatePayload)
.then(() => {
this.isProcessingReadUpdate = false
this.$toast.success(`"${this.title}" Marked as ${updatePayload.isRead ? 'Read' : 'Not Read'}`)

View file

@ -4,7 +4,7 @@
<div class="w-full h-full pt-6">
<div v-if="shelf.type === 'books'" class="flex items-center">
<template v-for="(entity, index) in shelf.entities">
<cards-lazy-book-card :key="entity.id" :ref="`shelf-book-${entity.id}`" :index="index" :width="bookCoverWidth" :height="bookCoverHeight" :book-cover-aspect-ratio="bookCoverAspectRatio" :book-mount="entity" class="relative mx-2" @hook:updated="updatedBookCard" @select="selectBook" @edit="editBook" />
<cards-lazy-book-card :key="entity.id" :ref="`shelf-book-${entity.id}`" :index="index" :width="bookCoverWidth" :height="bookCoverHeight" :book-cover-aspect-ratio="bookCoverAspectRatio" :book-mount="entity" class="relative mx-2" @hook:updated="updatedBookCard" @select="selectItem" @edit="editBook" />
</template>
</div>
<div v-if="shelf.type === 'series'" class="flex items-center">
@ -90,7 +90,7 @@ export default {
return this.$store.state.libraries.currentLibraryId
},
isSelectionMode() {
return this.$store.getters['getNumAudiobooksSelected'] > 0
return this.$store.getters['getNumLibraryItemsSelected'] > 0
}
},
methods: {
@ -100,19 +100,19 @@ export default {
this.$store.commit('showEditModal', audiobook)
},
updateSelectionMode(val) {
var selectedAudiobooks = this.$store.state.selectedAudiobooks
var selectedLibraryItems = this.$store.state.selectedLibraryItems
if (this.shelf.type === 'books') {
this.shelf.entities.forEach((ent) => {
var component = this.$refs[`shelf-book-${ent.id}`]
if (!component || !component.length) return
component = component[0]
component.setSelectionMode(val)
component.selected = selectedAudiobooks.includes(ent.id)
component.selected = selectedLibraryItems.includes(ent.id)
})
}
},
selectBook(audiobook) {
this.$store.commit('toggleAudiobookSelected', audiobook.id)
selectItem(libraryItem) {
this.$store.commit('toggleLibraryItemSelected', libraryItem.id)
},
scrolled() {
clearTimeout(this.scrollTimer)

View file

@ -183,8 +183,8 @@ export default {
// Includes margin
return this.entityWidth + 24
},
selectedAudiobooks() {
return this.$store.state.selectedAudiobooks || []
selectedLibraryItems() {
return this.$store.state.selectedLibraryItems || []
},
sizeMultiplier() {
var baseSize = this.isCoverSquareAspectRatio ? 192 : 120
@ -214,9 +214,9 @@ export default {
},
selectEntity(entity) {
if (this.entityName === 'books' || this.entityName === 'series-books') {
this.$store.commit('toggleAudiobookSelected', entity.id)
this.$store.commit('toggleLibraryItemSelected', entity.id)
var newIsSelectionMode = !!this.selectedAudiobooks.length
var newIsSelectionMode = !!this.selectedLibraryItems.length
if (this.isSelectionMode !== newIsSelectionMode) {
this.isSelectionMode = newIsSelectionMode
this.updateBookSelectionMode(newIsSelectionMode)