feat(webui): new duplicates tab in server settings

closes #590
This commit is contained in:
Gauthier Roebroeck 2021-12-31 14:37:07 +08:00
parent 3c97c20481
commit 38ad00c307
5 changed files with 117 additions and 0 deletions

View file

@ -512,6 +512,12 @@
"title_comparison": "Book Comparison"
}
},
"duplicates": {
"file_hash": "File hash",
"size": "Size",
"title": "Duplicate Files",
"url": "URL"
},
"enums": {
"copy_mode": {
"HARDLINK": "Hardlink/Copy Files",

View file

@ -88,6 +88,12 @@ const router = new Router({
beforeEnter: adminGuard,
component: () => import(/* webpackChunkName: "settings-analysis" */ './views/SettingsMediaAnalysis.vue'),
},
{
path: '/settings/duplicates',
name: 'settings-duplicates',
beforeEnter: adminGuard,
component: () => import(/* webpackChunkName: "settings-duplicates" */ './views/SettingsDuplicates.vue'),
},
{
path: '/settings/server',
name: 'settings-server',

View file

@ -51,6 +51,21 @@ export default class KomgaBooksService {
}
}
async getDuplicateBooks(pageRequest?: PageRequest): Promise<Page<BookDto>> {
try {
return (await this.http.get(`${API_BOOKS}/duplicates`, {
params: pageRequest,
paramsSerializer: params => qs.stringify(params, {indices: false}),
})).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve duplicate books'
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}
async getBooksOnDeck(libraryId?: string, pageRequest?: PageRequest): Promise<Page<BookDto>> {
try {
const params = {...pageRequest} as any

View file

@ -0,0 +1,89 @@
<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="fileHash"
multi-sort
show-group-by
group-by="fileHash"
class="elevation-1"
:footer-props="{
itemsPerPageOptions: [20, 50, 100]
}"
>
<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 Vue from 'vue'
import {MediaStatus} from '@/types/enum-books'
import {BookDto} from '@/types/komga-books'
import {convertErrorCodes} from '@/functions/error-codes'
export default Vue.extend({
name: 'SettingsDuplicates',
data: function () {
return {
books: [] as BookDto[],
totalBooks: 0,
loading: true,
options: {} as any,
}
},
watch: {
options: {
handler() {
this.loadBooks()
},
deep: true,
},
},
computed: {
headers(): object[] {
return [
{text: this.$i18n.t('duplicates.file_hash').toString(), value: 'fileHash'},
{text: this.$i18n.t('duplicates.url').toString(), value: 'url', groupable: false},
{text: this.$i18n.t('duplicates.size').toString(), value: 'size', groupable: false},
]
},
},
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.getDuplicateBooks(pageRequest)
this.totalBooks = booksPage.totalElements
this.books = booksPage.content
this.loading = false
},
},
})
</script>
<style scoped>
</style>

View file

@ -10,6 +10,7 @@
{{ $t('media_analysis.media_analysis') }}
</v-badge>
</v-tab>
<v-tab :to="{name: 'settings-duplicates'}">{{ $t('duplicates.title') }}</v-tab>
<v-tab :to="{name: 'settings-users'}">{{ $t('users.users') }}</v-tab>
<v-tab :to="{name: 'settings-server'}">{{ $t('server.tab_title') }}</v-tab>
</v-tabs>