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:
Gauthier Roebroeck 2020-01-17 17:10:23 +08:00
parent d030044df3
commit 27d46d57cb
5 changed files with 99 additions and 2 deletions

View 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>

View file

@ -40,7 +40,7 @@ const router = new Router({
{
path: '/settings',
name: 'settings',
redirect: { name: 'settings-users' },
redirect: { name: 'settings-analysis' },
component: () => import(/* webpackChunkName: "settings" */ './views/Settings.vue'),
children: [
{
@ -55,6 +55,12 @@ const router = new Router({
component: () => import(/* webpackChunkName: "settings-user" */ './components/UserAddDialog.vue')
}
]
},
{
path: '/settings/analysis',
name: 'settings-analysis',
beforeEnter: adminGuard,
component: () => import(/* webpackChunkName: "settings-users" */ './components/SettingsMediaAnalysis.vue')
}
]
},

View file

@ -11,7 +11,7 @@ export default class KomgaBooksService {
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 {
const params = { ...pageRequest } as any
if (libraryId) {
@ -20,6 +20,9 @@ export default class KomgaBooksService {
if (search) {
params.search = search
}
if (mediaStatus) {
params.media_status = mediaStatus
}
return (await this.http.get(API_BOOKS, {
params: params,
paramsSerializer: params => qs.stringify(params, { indices: false })

View file

@ -9,3 +9,10 @@ export enum ImageFit {
Height = 'height',
Original = 'original'
}
export enum MediaStatus {
Ready = 'READY',
Unknown = 'UNKNOWN',
Error = 'ERROR',
Unsupported = 'UNSUPPORTED'
}

View file

@ -1,6 +1,7 @@
<template>
<div>
<v-tabs>
<v-tab :to="{name: 'settings-analysis'}">Media analysis</v-tab>
<v-tab :to="{name: 'settings-users'}">Users</v-tab>
</v-tabs>
<router-view/>