Basic actions page

Rimless TrangaPage
Scroll behavior
This commit is contained in:
2025-10-16 22:50:40 +02:00
parent 2b6818b09e
commit 90dd1d050d
5 changed files with 81 additions and 11 deletions

View File

@@ -24,7 +24,8 @@
<UNavigationMenu :items="items" orientation="horizontal" variant="link" color="neutral" />
</template>
<template #right>
<UButton icon="i-lucide-plus" to="/search" color="primary">Manga</UButton>
<UButton icon="i-lucide-brick-wall-shield" :to="`/actions?return=${$route.fullPath}`" variant="soft" color="secondary" />
<UButton icon="i-lucide-plus" to="/search" color="primary" label="Manga" />
<UColorModeButton color="secondary" />
<UButton icon="i-lucide-settings" variant="ghost" :to="`/settings?return=${$route.fullPath}`" color="secondary" />
</template>

View File

@@ -1,5 +1,5 @@
<template>
<UPageList class="gap-2">
<UPageList class="gap-2 h-full overflow-y-scroll">
<UPageCard v-for="chapter in chapters" :key="chapter.key" orientation="horizontal" :ui="{ container: 'p-2 sm:p-2' }">
<template #title>
<p class="text-primary">{{ chapter.title }}</p>

View File

@@ -1,11 +1,11 @@
<template>
<UPageBody v-bind="$props" class="mt-0 pb-0 min-md:pr-4 h-full">
<UPageBody v-bind="$props" class="mt-0 pb-0 h-[calc(100dvh-var(--ui-header-height))] relative min-xl:overflow-clip">
<div class="flex min-md:flex-row max-md:flex-col gap-4 h-full relative">
<div v-if="$slots.left" class="flex flex-col gap-2 bg-elevated min-md:w-3/7 min-xl:w-2/7 max-md:w-full px-4 max-md:px-2 py-4">
<div v-if="$slots.left" class="flex flex-col gap-2 bg-elevated min-md:w-3/7 min-xl:w-2/7 max-md:w-full py-4 pl-4 pr-2">
<slot name="left" />
</div>
<div :class="['flex flex-col gap-2 w-full py-4 relative max-md:px-2', $slots.left ? '' : 'pl-4']">
<div class="w-full flex flex-row justify-between mb-4">
<div class="flex flex-col gap-2 w-full h-full py-4 relative">
<div :class="['w-full flex flex-row justify-between', $slots.left ? 'min-md:pr-4 max-md:px-2' : 'px-4']">
<div class="flex flex-row gap-6">
<UButton
variant="outline"
@@ -22,9 +22,11 @@
<slot name="actions" />
</div>
</div>
<div :class="[$slots.left ? rimless ? '' : 'min-md:mr-4 max-md:mx-2' : rimless ? '' : 'mx-4', 'h-full']">
<slot />
</div>
</div>
</div>
</UPageBody>
</template>
@@ -36,6 +38,7 @@ const backUrl = route.query.return as string | undefined;
export interface PageProps extends PageBodyProps {
title?: string;
rimless?: boolean;
}
defineProps<PageProps>();

View File

@@ -1,5 +1,71 @@
<template>
<TrangaPage />
<TrangaPage rimless>
<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}`">Manga</UButton>
</template>
<template #chapter-cell="{ row }">
<UButton v-if="row.original.chapterId" :to="`/manga/${row.original.chapterId}?return=${$route.fullPath}`">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>
</TrangaPage>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import type { components } from '#open-fetch-schemas/api';
import type { TableColumn } from '#ui/components/Table.vue';
type Filter = components['schemas']['Filter'];
type ActionRecord = components['schemas']['ActionRecord'];
const params = ref<Partial<Filter>>(useRoute().query);
const { data, refresh } = useApi('/v2/Actions/Filter', { method: 'POST', body: params.value, immediate: false });
const columns: TableColumn<ActionRecord>[] = [
{
id: 'action',
accessorKey: 'action',
header: 'Action'
},
{
id: 'timestamp',
accessorKey: 'performedAt',
header: 'Timestamp'
},
{
id: 'manga',
accessorKey: 'mangaId',
header: 'Manga'
},
{
id: 'chapter',
accessorKey: 'chapterId',
header: 'Chapter'
},
{
id: 'additional',
header: 'Additional'
},
];
const refreshData = async (): Promise<void> => {
await refresh();
};
defineShortcuts({ meta_r: { usingInput: true, handler: refreshData } });
</script>

View File

@@ -1,7 +1,7 @@
<template>
<MangaDetailPage :manga="manga">
<div class="grid gap-3 max-xl:grid-flow-row-dense min-2xl:grid-cols-[70%_auto] min-xl:grid-cols-[60%_auto]">
<ChaptersList :manga-id="mangaId" />
<div class="grid gap-3 max-xl:grid-flow-row-dense min-2xl:grid-cols-[70%_auto] min-xl:grid-cols-[60%_auto] relative min-xl:h-full">
<ChaptersList :manga-id="mangaId" class="min-xl:h-full min-xl:overflow-y-scroll p-[1px]" />
<div class="flex flex-col gap-2">
<UCard :class="[flashDownloading ? 'animate-[flash_0.75s_ease_0.5s]' : '']">
<template #header>