refactor(webui): move dialogs to single instance

This commit is contained in:
Gauthier Roebroeck 2020-06-28 12:07:47 +08:00
parent ee151b96fd
commit a09d3f65e4
11 changed files with 110 additions and 50 deletions

View file

@ -17,6 +17,19 @@
:library="deleteLibrary"
@deleted="libraryDeleted"
/>
<edit-books-dialog
v-model="updateBooksDialog"
:books="updateBooks"
@updated="bookUpdated"
/>
<edit-series-dialog
v-model="updateSeriesDialog"
:series="updateSeries"
@updated="seriesUpdated"
/>
</div>
</template>
@ -24,12 +37,20 @@
import CollectionAddToDialog from '@/components/dialogs/CollectionAddToDialog.vue'
import CollectionDeleteDialog from '@/components/dialogs/CollectionDeleteDialog.vue'
import LibraryDeleteDialog from '@/components/dialogs/LibraryDeleteDialog.vue'
import { COLLECTION_CHANGED, COLLECTION_DELETED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
import { BOOK_CHANGED, COLLECTION_CHANGED, COLLECTION_DELETED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
import Vue from 'vue'
import EditBooksDialog from '@/components/dialogs/EditBooksDialog.vue'
import EditSeriesDialog from '@/components/dialogs/EditSeriesDialog.vue'
export default Vue.extend({
name: 'Dialogs',
components: { CollectionAddToDialog, CollectionDeleteDialog, LibraryDeleteDialog },
components: {
CollectionAddToDialog,
CollectionDeleteDialog,
LibraryDeleteDialog,
EditBooksDialog,
EditSeriesDialog,
},
computed: {
addToCollectionDialog: {
get (): boolean {
@ -64,6 +85,28 @@ export default Vue.extend({
deleteLibrary (): LibraryDto {
return this.$store.state.deleteLibrary
},
updateBooksDialog: {
get (): boolean {
return this.$store.state.updateBooksDialog
},
set (val) {
this.$store.dispatch('dialogUpdateBooksDisplay', val)
},
},
updateBooks (): BookDto | BookDto[] {
return this.$store.state.updateBooks
},
updateSeriesDialog: {
get (): boolean {
return this.$store.state.updateSeriesDialog
},
set (val) {
this.$store.dispatch('dialogUpdateSeriesDisplay', val)
},
},
updateSeries (): SeriesDto | SeriesDto[] {
return this.$store.state.updateSeries
},
},
methods: {
collectionAdded () {
@ -92,6 +135,16 @@ export default Vue.extend({
id: this.deleteLibrary.id,
} as EventLibraryDeleted)
},
bookUpdated (book: BookDto) {
this.$eventHub.$emit(BOOK_CHANGED, {
id: book.id,
} as EventBookChanged)
},
seriesUpdated (series: SeriesDto) {
this.$eventHub.$emit(SERIES_CHANGED, {
id: series.id,
} as EventSeriesChanged)
},
},
})
</script>

View file

@ -559,14 +559,12 @@ export default Vue.extend({
const toUpdate = (this.single ? [this.books] : this.books) as BookDto[]
for (const b of toUpdate) {
try {
const updatedBooks = await this.$komgaBooks.updateMetadata(b.id, metadata)
updated.push(updatedBooks)
await this.$komgaBooks.updateMetadata(b.id, metadata)
this.$emit('updated', b)
} catch (e) {
this.showSnack(e.message)
updated.push(b)
}
}
this.$emit('update:books', this.single ? updated[0] : updated)
return true
} else return false
},
@ -575,5 +573,5 @@ export default Vue.extend({
</script>
<style lang="sass" scoped>
@import 'src/styles/tabbed-dialog'
@import '../../styles/tabbed-dialog'
</style>

View file

@ -281,14 +281,12 @@ export default Vue.extend({
const toUpdate = (this.single ? [this.series] : this.series) as SeriesDto[]
for (const s of toUpdate) {
try {
const updatedSeries = await this.$komgaSeries.updateMetadata(s.id, metadata)
updated.push(updatedSeries)
await this.$komgaSeries.updateMetadata(s.id, metadata)
this.$emit('updated', s)
} catch (e) {
this.showSnack(e.message)
updated.push(s)
}
}
this.$emit('update:series', this.single ? updated[0] : updated)
return true
} else return false
},

View file

@ -125,9 +125,9 @@ export default class KomgaBooksService {
}
}
async updateMetadata (bookId: number, metadata: BookMetadataUpdateDto): Promise<BookDto> {
async updateMetadata (bookId: number, metadata: BookMetadataUpdateDto) {
try {
return (await this.http.patch(`${API_BOOKS}/${bookId}/metadata`, metadata)).data
await this.http.patch(`${API_BOOKS}/${bookId}/metadata`, metadata)
} catch (e) {
let msg = `An error occurred while trying to update book metadata`
if (e.response.data.message) {

View file

@ -136,9 +136,9 @@ export default class KomgaSeriesService {
}
}
async updateMetadata (seriesId: number, metadata: SeriesMetadataUpdateDto): Promise<SeriesDto> {
async updateMetadata (seriesId: number, metadata: SeriesMetadataUpdateDto) {
try {
return (await this.http.patch(`${API_SERIES}/${seriesId}/metadata`, metadata)).data
await this.http.patch(`${API_SERIES}/${seriesId}/metadata`, metadata)
} catch (e) {
let msg = `An error occurred while trying to update series metadata`
if (e.response.data.message) {

View file

@ -11,6 +11,10 @@ export default new Vuex.Store({
deleteCollectionDialog: false,
deleteLibrary: {} as LibraryDto,
deleteLibraryDialog: false,
updateBooks: {} as BookDto | BookDto[],
updateBooksDialog: false,
updateSeries: {} as SeriesDto | SeriesDto[],
updateSeriesDialog: false,
},
mutations: {
setAddToCollectionSeries (state, series) {
@ -31,6 +35,18 @@ export default new Vuex.Store({
setDeleteLibraryDialog (state, dialog) {
state.deleteLibraryDialog = dialog
},
setUpdateBooks (state, books) {
state.updateBooks = books
},
setUpdateBooksDialog (state, dialog) {
state.updateBooksDialog = dialog
},
setUpdateSeries (state, series) {
state.updateSeries = series
},
setUpdateSeriesDialog (state, dialog) {
state.updateSeriesDialog = dialog
},
},
actions: {
dialogAddSeriesToCollection ({ commit }, series) {
@ -54,5 +70,19 @@ export default new Vuex.Store({
dialogDeleteLibraryDisplay ({ commit }, value) {
commit('setDeleteLibraryDialog', value)
},
dialogUpdateBooks ({ commit }, books) {
commit('setUpdateBooks', books)
commit('setUpdateBooksDialog', true)
},
dialogUpdateBooksDisplay ({ commit }, value) {
commit('setUpdateBooksDialog', value)
},
dialogUpdateSeries ({ commit }, series) {
commit('setUpdateSeries', series)
commit('setUpdateSeriesDialog', true)
},
dialogUpdateSeriesDisplay ({ commit }, value) {
commit('setUpdateSeriesDialog', value)
},
},
})

View file

@ -11,7 +11,7 @@
<v-spacer/>
<v-btn icon @click="dialogEdit = true" v-if="isAdmin">
<v-btn icon @click="editBook" v-if="isAdmin">
<v-icon>mdi-pencil</v-icon>
</v-btn>
@ -139,16 +139,12 @@
</v-container>
<edit-books-dialog v-model="dialogEdit"
:books.sync="book"
/>
</div>
</template>
<script lang="ts">
import Badge from '@/components/Badge.vue'
import BookActionsMenu from '@/components/menus/BookActionsMenu.vue'
import EditBooksDialog from '@/components/dialogs/EditBooksDialog.vue'
import ItemCard from '@/components/ItemCard.vue'
import ToolbarSticky from '@/components/ToolbarSticky.vue'
import { groupAuthorsByRolePlural } from '@/functions/authors'
@ -162,12 +158,11 @@ import Vue from 'vue'
export default Vue.extend({
name: 'BrowseBook',
components: { ToolbarSticky, Badge, EditBooksDialog, ItemCard, BookActionsMenu },
components: { ToolbarSticky, Badge, ItemCard, BookActionsMenu },
data: () => {
return {
book: {} as BookDto,
series: {} as SeriesDto,
dialogEdit: false,
}
},
async created () {
@ -253,6 +248,9 @@ export default Vue.extend({
refreshMetadata () {
this.$komgaBooks.refreshMetadata(this.book)
},
editBook () {
this.$store.dispatch('dialogUpdateBooks', this.book)
},
},
})
</script>

View file

@ -20,7 +20,7 @@
<v-spacer/>
<v-btn icon @click="dialogEdit = true" v-if="isAdmin">
<v-btn icon @click="editSeries" v-if="isAdmin">
<v-icon>mdi-pencil</v-icon>
</v-btn>
@ -194,15 +194,12 @@
</v-container>
<edit-series-dialog v-model="dialogEdit" :series.sync="series"/>
</div>
</template>
<script lang="ts">
import Badge from '@/components/Badge.vue'
import EditBooksDialog from '@/components/dialogs/EditBooksDialog.vue'
import EditSeriesDialog from '@/components/dialogs/EditSeriesDialog.vue'
import EmptyState from '@/components/EmptyState.vue'
import FilterMenuButton from '@/components/FilterMenuButton.vue'
import HorizontalScroller from '@/components/HorizontalScroller.vue'
@ -227,7 +224,6 @@ export default Vue.extend({
SortMenuButton,
FilterMenuButton,
Badge,
EditSeriesDialog,
EditBooksDialog,
ItemBrowser,
PageSizeSelect,
@ -456,6 +452,9 @@ export default Vue.extend({
refreshMetadata () {
this.$komgaSeries.refreshMetadata(this.series)
},
editSeries () {
this.$store.dispatch('dialogUpdateSeries', this.series)
},
singleEdit (book: BookDto) {
this.editBookSingle = book
this.dialogEditBookSingle = true

View file

@ -1,14 +1,6 @@
<template>
<div class="ma-3">
<edit-series-dialog v-model="dialogEditSeriesSingle"
:series.sync="editSeriesSingle"
/>
<edit-books-dialog v-model="dialogEditBookSingle"
:books.sync="editBookSingle"
/>
<empty-state v-if="allEmpty"
title="Nothing to show"
icon="mdi-help-circle"
@ -83,8 +75,6 @@
</template>
<script lang="ts">
import EditBooksDialog from '@/components/dialogs/EditBooksDialog.vue'
import EditSeriesDialog from '@/components/dialogs/EditSeriesDialog.vue'
import EmptyState from '@/components/EmptyState.vue'
import HorizontalScroller from '@/components/HorizontalScroller.vue'
import ItemCard from '@/components/ItemCard.vue'
@ -94,7 +84,7 @@ import Vue from 'vue'
export default Vue.extend({
name: 'Dashboard',
components: { ItemCard, HorizontalScroller, EditSeriesDialog, EditBooksDialog, EmptyState },
components: { ItemCard, HorizontalScroller, EmptyState },
data: () => {
return {
newSeries: [] as SeriesDto[],
@ -102,10 +92,6 @@ export default Vue.extend({
latestBooks: [] as BookDto[],
inProgressBooks: [] as BookDto[],
onDeckBooks: [] as BookDto[],
editSeriesSingle: {} as SeriesDto,
dialogEditSeriesSingle: false,
editBookSingle: {} as BookDto,
dialogEditBookSingle: false,
}
},
created () {
@ -194,12 +180,10 @@ export default Vue.extend({
this.onDeckBooks = (await this.$komgaBooks.getBooksOnDeck()).content
},
singleEditSeries (series: SeriesDto) {
this.editSeriesSingle = series
this.dialogEditSeriesSingle = true
this.$store.dispatch('dialogUpdateSeries', series)
},
singleEditBook (book: BookDto) {
this.editBookSingle = book
this.dialogEditBookSingle = true
this.$store.dispatch('dialogUpdateBooks', book)
},
},
})

View file

@ -367,12 +367,13 @@ class BookController(
@PatchMapping("api/v1/books/{bookId}/metadata")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateMetadata(
@PathVariable bookId: Long,
@Parameter(description = "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.")
@Valid @RequestBody newMetadata: BookMetadataUpdateDto,
@AuthenticationPrincipal principal: KomgaPrincipal
): BookDto =
) =
bookMetadataRepository.findByIdOrNull(bookId)?.let { existing ->
val updated = with(newMetadata) {
existing.copy(
@ -399,7 +400,6 @@ class BookController(
)
}
bookMetadataRepository.update(updated)
bookDtoRepository.findByIdOrNull(bookId, principal.user.id)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PatchMapping("api/v1/books/{bookId}/read-progress")

View file

@ -268,12 +268,13 @@ class SeriesController(
@PatchMapping("{seriesId}/metadata")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateMetadata(
@PathVariable seriesId: Long,
@Parameter(description = "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.")
@Valid @RequestBody newMetadata: SeriesMetadataUpdateDto,
@AuthenticationPrincipal principal: KomgaPrincipal
): SeriesDto =
) =
seriesMetadataRepository.findByIdOrNull(seriesId)?.let { existing ->
val updated = with(newMetadata) {
existing.copy(
@ -286,7 +287,6 @@ class SeriesController(
)
}
seriesMetadataRepository.update(updated)
seriesDtoRepository.findByIdOrNull(seriesId, principal.user.id)!!
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PostMapping("{seriesId}/read-progress")