feat(webui): multi-select in dashboard page

This commit is contained in:
Gauthier Roebroeck 2020-06-28 21:44:05 +08:00
parent c5417ac8da
commit 8e33be78e2

View file

@ -1,58 +1,100 @@
<template> <template>
<div class="ma-3"> <div>
<series-multi-select-bar
v-model="selectedSeries"
@unselect-all="selectedSeries = []"
@mark-read="markSelectedSeriesRead"
@mark-unread="markSelectedSeriesUnread"
@add-to-collection="addToCollection"
@edit="editMultipleSeries"
/>
<empty-state v-if="allEmpty" <books-multi-select-bar
title="Nothing to show" v-model="selectedBooks"
icon="mdi-help-circle" @unselect-all="selectedBooks = []"
icon-color="secondary" @mark-read="markSelectedBooksRead"
> @mark-unread="markSelectedBooksUnread"
</empty-state> @edit="editMultipleBooks"
/>
<horizontal-scroller v-if="inProgressBooks.length !== 0" class="my-4"> <v-container fluid class="px-6">
<template v-slot:prepend> <empty-state v-if="allEmpty"
<div class="title">Keep Reading</div> title="Nothing to show"
</template> icon="mdi-help-circle"
<template v-slot:content> icon-color="secondary"
<item-browser :items="inProgressBooks" nowrap :edit-function="singleEditBook" :selectable="false"/> >
</template> </empty-state>
</horizontal-scroller>
<horizontal-scroller v-if="onDeckBooks.length !== 0" class="my-4"> <horizontal-scroller v-if="inProgressBooks.length !== 0" class="my-4">
<template v-slot:prepend> <template v-slot:prepend>
<div class="title">On Deck</div> <div class="title">Keep Reading</div>
</template> </template>
<template v-slot:content> <template v-slot:content>
<item-browser :items="onDeckBooks" nowrap :edit-function="singleEditBook" :selectable="false"/> <item-browser :items="inProgressBooks"
</template> nowrap
</horizontal-scroller> :edit-function="singleEditBook"
:selected.sync="selectedBooks"
:selectable="selectedSeries.length === 0"
/>
</template>
</horizontal-scroller>
<horizontal-scroller v-if="newSeries.length !== 0" class="my-4"> <horizontal-scroller v-if="onDeckBooks.length !== 0" class="my-4">
<template v-slot:prepend> <template v-slot:prepend>
<div class="title">Recently Added Series</div> <div class="title">On Deck</div>
</template> </template>
<template v-slot:content> <template v-slot:content>
<item-browser :items="newSeries" nowrap :edit-function="singleEditSeries" :selectable="false"/> <item-browser :items="onDeckBooks"
</template> nowrap
</horizontal-scroller> :edit-function="singleEditBook"
:selected.sync="selectedBooks"
:selectable="selectedSeries.length === 0"
/>
</template>
</horizontal-scroller>
<horizontal-scroller v-if="updatedSeries.length !== 0" class="my-4"> <horizontal-scroller v-if="newSeries.length !== 0" class="my-4">
<template v-slot:prepend> <template v-slot:prepend>
<div class="title">Recently Updated Series</div> <div class="title">Recently Added Series</div>
</template> </template>
<template v-slot:content> <template v-slot:content>
<item-browser :items="updatedSeries" nowrap :edit-function="singleEditSeries" :selectable="false"/> <item-browser :items="newSeries"
</template> nowrap
</horizontal-scroller> :edit-function="singleEditSeries"
:selected.sync="selectedSeries"
:selectable="selectedBooks.length === 0"
/>
</template>
</horizontal-scroller>
<horizontal-scroller v-if="latestBooks.length !== 0" class="my-4"> <horizontal-scroller v-if="updatedSeries.length !== 0" class="my-4">
<template v-slot:prepend> <template v-slot:prepend>
<div class="title">Recently Added Books</div> <div class="title">Recently Updated Series</div>
</template> </template>
<template v-slot:content> <template v-slot:content>
<item-browser :items="latestBooks" nowrap :edit-function="singleEditBook" :selectable="false"/> <item-browser :items="updatedSeries"
</template> nowrap
</horizontal-scroller> :edit-function="singleEditSeries"
:selected.sync="selectedSeries"
:selectable="selectedBooks.length === 0"
/>
</template>
</horizontal-scroller>
<horizontal-scroller v-if="latestBooks.length !== 0" class="my-4">
<template v-slot:prepend>
<div class="title">Recently Added Books</div>
</template>
<template v-slot:content>
<item-browser :items="latestBooks"
nowrap
:edit-function="singleEditBook"
:selected.sync="selectedBooks"
:selectable="selectedSeries.length === 0"
/>
</template>
</horizontal-scroller>
</v-container>
</div> </div>
</template> </template>
@ -63,10 +105,18 @@ import { ReadStatus } from '@/types/enum-books'
import { BOOK_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events' import { BOOK_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
import Vue from 'vue' import Vue from 'vue'
import ItemBrowser from '@/components/ItemBrowser.vue' import ItemBrowser from '@/components/ItemBrowser.vue'
import SeriesMultiSelectBar from '@/components/bars/SeriesMultiSelectBar.vue'
import BooksMultiSelectBar from '@/components/bars/BooksMultiSelectBar.vue'
export default Vue.extend({ export default Vue.extend({
name: 'Dashboard', name: 'Dashboard',
components: { HorizontalScroller, EmptyState, ItemBrowser }, components: {
HorizontalScroller,
EmptyState,
ItemBrowser,
BooksMultiSelectBar,
SeriesMultiSelectBar,
},
data: () => { data: () => {
return { return {
newSeries: [] as SeriesDto[], newSeries: [] as SeriesDto[],
@ -74,6 +124,8 @@ export default Vue.extend({
latestBooks: [] as BookDto[], latestBooks: [] as BookDto[],
inProgressBooks: [] as BookDto[], inProgressBooks: [] as BookDto[],
onDeckBooks: [] as BookDto[], onDeckBooks: [] as BookDto[],
selectedSeries: [] as SeriesDto[],
selectedBooks: [] as BookDto[],
} }
}, },
created () { created () {
@ -90,11 +142,11 @@ export default Vue.extend({
this.loadAll() this.loadAll()
}, },
watch: { watch: {
editSeriesSingle (val: SeriesDto) { selectedSeries (val: SeriesDto[]) {
this.replaceSeries(val) val.forEach(i => this.replaceSeries(i))
}, },
editBookSingle (val: BookDto) { selectedBooks (val: BookDto[]) {
this.replaceBook(val) val.forEach(i => this.replaceBook(i))
}, },
}, },
computed: { computed: {
@ -167,6 +219,47 @@ export default Vue.extend({
singleEditBook (book: BookDto) { singleEditBook (book: BookDto) {
this.$store.dispatch('dialogUpdateBooks', book) this.$store.dispatch('dialogUpdateBooks', book)
}, },
async markSelectedSeriesRead () {
await Promise.all(this.selectedSeries.map(s =>
this.$komgaSeries.markAsRead(s.id),
))
this.selectedSeries = await Promise.all(this.selectedSeries.map(s =>
this.$komgaSeries.getOneSeries(s.id),
))
},
async markSelectedSeriesUnread () {
await Promise.all(this.selectedSeries.map(s =>
this.$komgaSeries.markAsUnread(s.id),
))
this.selectedSeries = await Promise.all(this.selectedSeries.map(s =>
this.$komgaSeries.getOneSeries(s.id),
))
},
addToCollection () {
this.$store.dispatch('dialogAddSeriesToCollection', this.selectedSeries)
},
editMultipleSeries () {
this.$store.dispatch('dialogUpdateSeries', this.selectedSeries)
},
editMultipleBooks () {
this.$store.dispatch('dialogUpdateBooks', this.selectedBooks)
},
async markSelectedBooksRead () {
await Promise.all(this.selectedBooks.map(b =>
this.$komgaBooks.updateReadProgress(b.id, { completed: true }),
))
this.selectedBooks = await Promise.all(this.selectedBooks.map(b =>
this.$komgaBooks.getBook(b.id),
))
},
async markSelectedBooksUnread () {
await Promise.all(this.selectedBooks.map(b =>
this.$komgaBooks.deleteReadProgress(b.id),
))
this.selectedBooks = await Promise.all(this.selectedBooks.map(b =>
this.$komgaBooks.getBook(b.id),
))
},
}, },
}) })
</script> </script>