mirror of
https://github.com/gotson/komga.git
synced 2026-05-08 04:22:28 +02:00
feat(webui): add Media Analysis screen showing all books in error
located in the Settings screen, limited to administrators closes #26
This commit is contained in:
parent
d030044df3
commit
27d46d57cb
5 changed files with 99 additions and 2 deletions
80
komga-webui/src/components/SettingsMediaAnalysis.vue
Normal file
80
komga-webui/src/components/SettingsMediaAnalysis.vue
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<v-container fluid class="pa-6">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headers"
|
||||||
|
:items="books"
|
||||||
|
:options.sync="options"
|
||||||
|
:server-items-length="totalBooks"
|
||||||
|
:loading="loading"
|
||||||
|
sort-by="media.status"
|
||||||
|
multi-sort
|
||||||
|
class="elevation-1"
|
||||||
|
>
|
||||||
|
<template v-slot:item.name="{ item }">
|
||||||
|
<router-link :to="{name:'browse-book', params: {bookId: item.id}}">{{ item.name }}</router-link>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { MediaStatus } from '@/types/common'
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'SettingsMediaAnalysis',
|
||||||
|
data: () => ({
|
||||||
|
books: [] as BookDto[],
|
||||||
|
totalBooks: 0,
|
||||||
|
loading: true,
|
||||||
|
options: {} as any,
|
||||||
|
headers: [
|
||||||
|
{ text: 'Name', value: 'name' },
|
||||||
|
{ text: 'Status', value: 'media.status' },
|
||||||
|
{ text: 'Comment', value: 'media.comment' },
|
||||||
|
{ text: 'Media Type', value: 'media.mediaType' },
|
||||||
|
{ text: 'URL', value: 'url' },
|
||||||
|
{ text: 'Size', value: 'size', sortable: false }
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
watch: {
|
||||||
|
options: {
|
||||||
|
handler () {
|
||||||
|
this.loadBooks()
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
async mounted () {
|
||||||
|
this.loadBooks()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async loadBooks () {
|
||||||
|
this.loading = true
|
||||||
|
|
||||||
|
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||||
|
|
||||||
|
const pageRequest = {
|
||||||
|
page: page - 1,
|
||||||
|
size: itemsPerPage,
|
||||||
|
sort: []
|
||||||
|
} as PageRequest
|
||||||
|
|
||||||
|
for (let i = 0; i < sortBy.length; i++) {
|
||||||
|
pageRequest.sort!!.push(`${sortBy[i]},${sortDesc[i] ? 'desc' : 'asc'}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const booksPage = await this.$komgaBooks.getBooks(undefined, pageRequest, undefined, [MediaStatus.Error, MediaStatus.Unsupported])
|
||||||
|
this.totalBooks = booksPage.totalElements
|
||||||
|
this.books = booksPage.content
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -40,7 +40,7 @@ const router = new Router({
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
redirect: { name: 'settings-users' },
|
redirect: { name: 'settings-analysis' },
|
||||||
component: () => import(/* webpackChunkName: "settings" */ './views/Settings.vue'),
|
component: () => import(/* webpackChunkName: "settings" */ './views/Settings.vue'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
@ -55,6 +55,12 @@ const router = new Router({
|
||||||
component: () => import(/* webpackChunkName: "settings-user" */ './components/UserAddDialog.vue')
|
component: () => import(/* webpackChunkName: "settings-user" */ './components/UserAddDialog.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/settings/analysis',
|
||||||
|
name: 'settings-analysis',
|
||||||
|
beforeEnter: adminGuard,
|
||||||
|
component: () => import(/* webpackChunkName: "settings-users" */ './components/SettingsMediaAnalysis.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export default class KomgaBooksService {
|
||||||
this.http = http
|
this.http = http
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBooks (libraryId?: number, pageRequest?: PageRequest, search?: string): Promise<Page<BookDto>> {
|
async getBooks (libraryId?: number, pageRequest?: PageRequest, search?: string, mediaStatus?: string[]): Promise<Page<BookDto>> {
|
||||||
try {
|
try {
|
||||||
const params = { ...pageRequest } as any
|
const params = { ...pageRequest } as any
|
||||||
if (libraryId) {
|
if (libraryId) {
|
||||||
|
|
@ -20,6 +20,9 @@ export default class KomgaBooksService {
|
||||||
if (search) {
|
if (search) {
|
||||||
params.search = search
|
params.search = search
|
||||||
}
|
}
|
||||||
|
if (mediaStatus) {
|
||||||
|
params.media_status = mediaStatus
|
||||||
|
}
|
||||||
return (await this.http.get(API_BOOKS, {
|
return (await this.http.get(API_BOOKS, {
|
||||||
params: params,
|
params: params,
|
||||||
paramsSerializer: params => qs.stringify(params, { indices: false })
|
paramsSerializer: params => qs.stringify(params, { indices: false })
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,10 @@ export enum ImageFit {
|
||||||
Height = 'height',
|
Height = 'height',
|
||||||
Original = 'original'
|
Original = 'original'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum MediaStatus {
|
||||||
|
Ready = 'READY',
|
||||||
|
Unknown = 'UNKNOWN',
|
||||||
|
Error = 'ERROR',
|
||||||
|
Unsupported = 'UNSUPPORTED'
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<v-tabs>
|
<v-tabs>
|
||||||
|
<v-tab :to="{name: 'settings-analysis'}">Media analysis</v-tab>
|
||||||
<v-tab :to="{name: 'settings-users'}">Users</v-tab>
|
<v-tab :to="{name: 'settings-users'}">Users</v-tab>
|
||||||
</v-tabs>
|
</v-tabs>
|
||||||
<router-view/>
|
<router-view/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue