mirror of
https://github.com/gotson/komga.git
synced 2026-02-16 12:23:44 +01:00
feat(webui): multi-select in dashboard page
This commit is contained in:
parent
c5417ac8da
commit
8e33be78e2
1 changed files with 145 additions and 52 deletions
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue