Add actions pagination

Add Manga button hides text when screen too small
This commit is contained in:
2025-10-17 19:50:23 +02:00
parent 9e9be689d5
commit cb33dd561c
6 changed files with 77 additions and 43 deletions

View File

@@ -31,7 +31,11 @@
:disabled="$route.fullPath.startsWith('/actions')"
variant="soft"
color="secondary" />
<UButton icon="i-lucide-plus" to="/search" color="primary" label="Manga" />
<UButton icon="i-lucide-plus" to="/search" color="primary">
<template #default>
<span class="max-sm:hidden">Manga</span>
</template>
</UButton>
<UColorModeButton color="secondary" />
<UButton
icon="i-lucide-settings"

View File

@@ -1,6 +1,12 @@
<template>
<UPageList class="gap-2 h-full overflow-y-scroll">
<UPageCard v-for="chapter in chapters" :id="chapter.key" :key="chapter.key" orientation="horizontal" :ui="{ container: 'p-2 sm:p-2' }" :class="[$route.hash.substring(1) == chapter.key ? 'animate-[flash_0.75s_ease_0.5s]' : '']">
<UPageCard
v-for="chapter in chapters"
:id="chapter.key"
:key="chapter.key"
orientation="horizontal"
:ui="{ container: 'p-2 sm:p-2' }"
:class="[$route.hash.substring(1) == chapter.key ? 'animate-[flash_0.75s_ease_0.5s]' : '']">
<template #title>
<p class="text-primary">{{ chapter.title }}</p>
<p class="text-secondary">

View File

@@ -23,7 +23,7 @@
</div>
</div>
<div :class="[$slots.left ? (rimless ? '' : 'min-md:mr-4 max-md:mx-2') : rimless ? '' : 'mx-4', 'h-full']">
<div v-if="$slots.center" class="flex flew-row gap-2 w-full justify-center">
<div v-if="$slots.center" class="flex flex-col min-md:flex-row gap-2 w-full min-md:justify-center max-md:items-center">
<slot name="center" />
</div>
<slot />

View File

@@ -2,54 +2,75 @@
<TrangaPage rimless>
<template #center>
<UButton color="primary" icon="i-lucide-rotate-ccw" @click="resetFilter" />
<USelect v-model="params.action" :items="ActionTypes" class="w-50" @change="refreshData" />
<UInput v-model="params.start" trailing-icon="i-lucide-chevron-first" type="datetime-local" @change="refreshData" />
<UButton color="primary" icon="i-lucide-infinity" @click="noTimeLimit" />
<UInput v-model="params.end" icon="i-lucide-chevron-last" type="datetime-local" @change="refreshData" />
<USelect v-model="params.action" :items="ActionTypes" class="w-70" @change="refreshData" />
<UInput v-model="params.start" icon="i-lucide-chevron-first" class="w-70" type="datetime-local" @change="refreshData" />
<UTooltip text="No timelimit">
<UButton color="primary" icon="i-lucide-infinity" @click="noTimeLimit" />
</UTooltip>
<UInput v-model="params.end" icon="i-lucide-chevron-last" type="datetime-local" class="w-70" @change="refreshData" />
</template>
<template #actions>
<UTooltip text="Reload" :kbds="['meta', 'R']">
<UButton variant="soft" color="secondary" icon="i-lucide-refresh-ccw" loading-auto @click="refreshData" />
</UTooltip>
</template>
<UTable :data="data" :columns="columns" :sticky="'header'">
<template #action-cell="{ row }">
{{ row.original.action.split(/(?=[A-Z])/).join(' ') }}
</template>
<template #timestamp-cell="{ row }">
{{ new Date(row.original.performedAt).toLocaleString() }}
</template>
<template #manga-cell="{ row }">
<UButton
v-if="row.original.mangaId"
:to="`/manga/${row.original.mangaId}?return=${$route.fullPath}`"
variant="ghost"
color="primary"
>Manga</UButton
>
</template>
<template #chapter-cell="{ row }">
<UButton
v-if="row.original.chapterId"
:to="`/manga/${row.original.mangaId}?return=${$route.fullPath}#${row.original.chapterId}`"
variant="ghost"
color="secondary"
>Chapter</UButton
>
</template>
<template #additional-cell="{ row }">
<p v-if="row.original.from">From: {{ row.original.from }}</p>
<p v-if="row.original.to">To: {{ row.original.to }}</p>
<p v-if="row.original.filename">Filename: {{ row.original.filename }}</p>
<p v-if="row.original.metadataFetcher">Metadata Fetcher: {{ row.original.metadataFetcher }}</p>
</template>
</UTable>
<div class="w-full pt-2">
<div class="flex justify-center">
<UPagination
:default-page="/* @ts-ignore */ (table?.tableApi?.getState().pagination.pageIndex || 0) + 1"
:items-per-page="/* @ts-ignore */ table?.tableApi?.getState().pagination.pageSize"
:total="/* @ts-ignore */ table?.tableApi?.getFilteredRowModel().rows.length"
@update:page="(p) => table?.tableApi?.setPageIndex(p - 1)" />
</div>
<UTable
ref="table"
v-model:pagination="pagination"
:data="data"
:columns="columns"
:sticky="'header'"
class="h-full"
:pagination-options="{ getPaginationRowModel: getPaginationRowModel() }">
<template #action-cell="{ row }">
{{ row.original.action.split(/(?=[A-Z])/).join(' ') }}
</template>
<template #timestamp-cell="{ row }">
{{ new Date(row.original.performedAt).toLocaleString() }}
</template>
<template #manga-cell="{ row }">
<UButton
v-if="row.original.mangaId"
:to="`/manga/${row.original.mangaId}?return=${$route.fullPath}`"
variant="ghost"
color="primary"
>Manga</UButton
>
</template>
<template #chapter-cell="{ row }">
<UButton
v-if="row.original.chapterId"
:to="`/manga/${row.original.mangaId}?return=${$route.fullPath}#${row.original.chapterId}`"
variant="ghost"
color="secondary"
>Chapter</UButton
>
</template>
<template #additional-cell="{ row }">
<p v-if="row.original.from">From: {{ row.original.from }}</p>
<p v-if="row.original.to">To: {{ row.original.to }}</p>
<p v-if="row.original.filename">Filename: {{ row.original.filename }}</p>
<p v-if="row.original.metadataFetcher">Metadata Fetcher: {{ row.original.metadataFetcher }}</p>
</template>
</UTable>
</div>
</TrangaPage>
</template>
<script setup lang="ts">
import type { components } from '#open-fetch-schemas/api';
import type { TableColumn } from '#ui/components/Table.vue';
import { getPaginationRowModel } from '@tanstack/vue-table';
import type { UTable } from '#components';
import { useTemplateRef } from '#imports';
import type { components } from '#open-fetch-schemas/api';
type Filter = components['schemas']['Filter'];
type ActionRecord = components['schemas']['ActionRecord'];
@@ -72,6 +93,9 @@ const columns: TableColumn<ActionRecord>[] = [
{ id: 'additional', header: 'Additional' },
];
const table = useTemplateRef<typeof UTable>('table');
const pagination = ref({ pageIndex: 0, pageSize: 10 });
const resetFilter = async () => {
params.value = {
...useRoute().query,

View File

@@ -88,7 +88,7 @@ const { $api } = useNuxtApp();
const route = useRoute();
const mangaId = route.params.mangaId as string;
const flashDownloading = route.hash.substring(1) == "download";
const flashDownloading = route.hash.substring(1) == 'download';
const { data: manga } = await useApi('/v2/Manga/{MangaId}', {
path: { MangaId: mangaId },
@@ -139,4 +139,4 @@ const refreshData = async () => {
defineShortcuts({ meta_r: { usingInput: true, handler: refreshData } });
useHead({ title: 'Manga' });
</script>
</script>

View File

@@ -38,7 +38,7 @@ const merge = async () => {
const from = reverse.value ? mangaId : targetId;
const to = reverse.value == false ? targetId : mangaId;
await $api('/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}', { method: 'POST', path: { MangaIdFrom: from, MangaIdInto: to } });
navigateTo(`/manga/${to}?return=${path}`);
navigateTo(`/manga/${to}?return=${useRoute().fullPath}`);
};
useHead({ title: 'Confirm merge' });