mirror of
https://github.com/gotson/komga.git
synced 2026-05-05 11:01:57 +02:00
sort by name or date added for Series
show number of Series when browsing Library add theme colors
This commit is contained in:
parent
bf94276984
commit
c55af09c8a
6 changed files with 122 additions and 33 deletions
10
komga-webui/src/assets/css/badge.css
Normal file
10
komga-webui/src/assets/css/badge.css
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.badge-count {
|
||||
background-color: #E0E0E0;
|
||||
border-radius: 4px;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
padding: 1px 8px;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
font-weight: normal;
|
||||
}
|
||||
5
komga-webui/src/assets/css/sticky-bar.css
Normal file
5
komga-webui/src/assets/css/sticky-bar.css
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.sticky-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
z-index: 2
|
||||
}
|
||||
|
|
@ -5,7 +5,44 @@
|
|||
class="sticky-bar"
|
||||
:style="barStyle"
|
||||
>
|
||||
<v-toolbar-title>{{ libraryName }}</v-toolbar-title>
|
||||
<v-toolbar-title>
|
||||
<span>{{ libraryName }}</span>
|
||||
<span class="ml-4 badge-count"
|
||||
v-if="totalElements"
|
||||
>
|
||||
{{ totalElements }}
|
||||
</span>
|
||||
</v-toolbar-title>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-toolbar-items>
|
||||
<v-menu offset-y>
|
||||
<template v-slot:activator="{on}">
|
||||
<v-btn icon v-on="on">
|
||||
<v-icon :color="sortCustom ? 'secondary' : null"
|
||||
>mdi-sort-variant
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item v-for="(item, index) in sortOptions"
|
||||
:key="index"
|
||||
@click="setSort(item)"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon color="secondary" v-if="item.key === sortActive.key && sortActive.order === 'asc'">
|
||||
mdi-chevron-up
|
||||
</v-icon>
|
||||
<v-icon color="secondary" v-if="item.key === sortActive.key && sortActive.order === 'desc'">
|
||||
mdi-chevron-down
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{ item.name }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-toolbar-items>
|
||||
</v-toolbar>
|
||||
|
||||
<v-container fluid class="mx-3">
|
||||
|
|
@ -50,10 +87,17 @@ export default Vue.extend({
|
|||
series: [] as SeriesDto[],
|
||||
lastPage: false,
|
||||
page: null as number | null,
|
||||
infiniteId: +new Date()
|
||||
totalElements: null as number | null,
|
||||
infiniteId: +new Date(),
|
||||
sortOptions: [{ name: 'Name', key: 'name' }, { name: 'Date added', key: 'createdDate' }] as SortOption[],
|
||||
sortActive: { key: 'name', order: 'asc' } as SortActive as SortActive,
|
||||
sortDefault: { key: 'name', order: 'asc' } as SortActive as SortActive
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sortCustom (): boolean {
|
||||
return this.sortActive.key !== this.sortDefault.key || this.sortActive.order !== this.sortDefault.order
|
||||
},
|
||||
barStyle (): any {
|
||||
if (this.$vuetify.breakpoint.name === 'xs') {
|
||||
return { 'top': '56px' }
|
||||
|
|
@ -74,15 +118,32 @@ export default Vue.extend({
|
|||
beforeRouteUpdate (to, from, next) {
|
||||
if (to.params.libraryId !== from.params.libraryId) {
|
||||
this.libraryName = this.getLibraryNameLazy(Number(to.params.libraryId))
|
||||
this.series = []
|
||||
this.lastPage = false
|
||||
this.page = null
|
||||
this.infiniteId += 1
|
||||
this.sortActive = this.$_.clone(this.sortDefault)
|
||||
this.resetData()
|
||||
}
|
||||
|
||||
next()
|
||||
},
|
||||
methods: {
|
||||
resetData () {
|
||||
this.series = []
|
||||
this.lastPage = false
|
||||
this.totalElements = null
|
||||
this.page = null
|
||||
this.infiniteId += 1
|
||||
},
|
||||
setSort (sort: SortOption) {
|
||||
if (this.sortActive.key === sort.key) {
|
||||
if (this.sortActive.order === 'desc') {
|
||||
this.sortActive.order = 'asc'
|
||||
} else {
|
||||
this.sortActive.order = 'desc'
|
||||
}
|
||||
} else {
|
||||
this.sortActive = { key: sort.key, order: 'desc' }
|
||||
}
|
||||
this.resetData()
|
||||
},
|
||||
async infiniteHandler ($state: any) {
|
||||
await this.loadNextPage()
|
||||
if (this.lastPage) {
|
||||
|
|
@ -107,12 +168,17 @@ export default Vue.extend({
|
|||
updateRoute = false
|
||||
}
|
||||
|
||||
if (this.sortActive != null) {
|
||||
pageRequest.sort = [`${this.sortActive.key},${this.sortActive.order}`]
|
||||
}
|
||||
|
||||
let libraryId
|
||||
if (this.libraryId !== 0) {
|
||||
libraryId = this.libraryId
|
||||
}
|
||||
const newPage = await this.$komgaSeries.getSeries(libraryId, pageRequest)
|
||||
this.lastPage = newPage.last
|
||||
this.totalElements = newPage.totalElements
|
||||
this.series = this.series.concat(newPage.content)
|
||||
|
||||
if (updateRoute) {
|
||||
|
|
@ -145,9 +211,6 @@ export default Vue.extend({
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sticky-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
z-index: 2
|
||||
}
|
||||
@import "../assets/css/badge.css";
|
||||
@import "../assets/css/sticky-bar.css";
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
<v-toolbar-title>
|
||||
<span v-if="series.name">{{ series.name }}</span>
|
||||
<span class="ml-4 badge-count"
|
||||
v-if="series.booksCount"
|
||||
v-if="totalElements"
|
||||
>
|
||||
{{ series.booksCount }}
|
||||
{{ totalElements }}
|
||||
</span>
|
||||
</v-toolbar-title>
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ export default Vue.extend({
|
|||
books: [] as BookDto[],
|
||||
lastPage: false,
|
||||
page: null as number | null,
|
||||
totalElements: null as number | null,
|
||||
infiniteId: +new Date()
|
||||
}
|
||||
},
|
||||
|
|
@ -82,15 +83,19 @@ export default Vue.extend({
|
|||
async beforeRouteUpdate (to, from, next) {
|
||||
if (to.params.seriesId !== from.params.seriesId) {
|
||||
this.series = await this.$komgaSeries.getOneSeries(this.seriesId)
|
||||
this.books = []
|
||||
this.lastPage = false
|
||||
this.page = null
|
||||
this.infiniteId += 1
|
||||
this.resetData()
|
||||
}
|
||||
|
||||
next()
|
||||
},
|
||||
methods: {
|
||||
resetData () {
|
||||
this.books = []
|
||||
this.lastPage = false
|
||||
this.totalElements = null
|
||||
this.page = null
|
||||
this.infiniteId += 1
|
||||
},
|
||||
async infiniteHandler ($state: any) {
|
||||
await this.loadNextPage()
|
||||
if (this.lastPage) {
|
||||
|
|
@ -117,6 +122,7 @@ export default Vue.extend({
|
|||
|
||||
const newPage = await this.$komgaSeries.getBooks(this.seriesId, pageRequest)
|
||||
this.lastPage = newPage.last
|
||||
this.totalElements = newPage.totalElements
|
||||
this.books = this.books.concat(newPage.content)
|
||||
|
||||
if (updateRoute) {
|
||||
|
|
@ -135,20 +141,6 @@ export default Vue.extend({
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sticky-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
z-index: 2
|
||||
}
|
||||
|
||||
.badge-count {
|
||||
background-color: #E0E0E0;
|
||||
border-radius: 4px;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
padding: 1px 8px;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
font-weight: normal;
|
||||
}
|
||||
@import "../assets/css/badge.css";
|
||||
@import "../assets/css/sticky-bar.css";
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -6,5 +6,14 @@ Vue.use(Vuetify)
|
|||
export default new Vuetify({
|
||||
icons: {
|
||||
iconfont: 'mdi'
|
||||
},
|
||||
theme: {
|
||||
themes: {
|
||||
light: {
|
||||
primary: '#005ed3',
|
||||
secondary: '#fec000',
|
||||
accent: '#ff0335'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -32,3 +32,13 @@ interface PageRequest {
|
|||
page?: number,
|
||||
sort?: string[]
|
||||
}
|
||||
|
||||
interface SortOption {
|
||||
name: string,
|
||||
key: string
|
||||
}
|
||||
|
||||
interface SortActive {
|
||||
key: string,
|
||||
order: string
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue