feat: paginate list views, fix stale page titles, tidy admin filter bar
Bundle of small UI/UX fixes plus a build hygiene tweak.
* List pagination — Home (`/`) and `/authors/[id]` silently capped at
the backend default of 50 with no UI to advance. New reusable
`Pager.svelte` (Prev/Next + numbered with ellipsis), URL-synced
`?page=N`, and filter/search/sort reset to page 1 so users aren't
stranded on an out-of-range page. Count label now shows a range
("Showing 51–100 of 237").
* Stale page title — Pages without a `<svelte:head><title>` left the
document title at whatever the last manga / author / collection page
set it to. Move static-route titles into a route-id → title map in
the root layout and invert every dynamic title to brand-first
(`Mangalord | {X}`) for consistency.
* Admin filter bar — `/admin/mangas` search input had `flex: 1` and
ballooned across the row, shoving the sync-state select + Search
button to the far right. Cap at 24rem, vertical-align the row, and
promote the previously aria-only "Sync state" label to visible text.
* Build hygiene — `backend/target` had grown to 68 GiB. Cleaned and
added `[profile.dev] debug = "line-tables-only"` (and `[profile.test]`
too) to cut future dev builds by ~50–70% while keeping line numbers
in backtraces.
Also: configure vitest to resolve Svelte's browser entry so
`@testing-library/svelte` can mount components in jsdom — needed for
the new `Pager.svelte.test.ts`.
Bump 0.48.0 -> 0.49.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { logout } from '$lib/api/auth';
|
||||
import { authConfig } from '$lib/auth-config.svelte';
|
||||
import { preferences } from '$lib/preferences.svelte';
|
||||
@@ -18,6 +19,32 @@
|
||||
let loggingOut = $state(false);
|
||||
let headerEl: HTMLElement | undefined = $state();
|
||||
|
||||
// Static-route title map. Dynamic pages (manga / author / collection /
|
||||
// chapter) override this via their own <svelte:head><title>, since the
|
||||
// title depends on data the layout doesn't have. Routes omitted here
|
||||
// (notably the dynamic ones) fall through to the bare brand and rely
|
||||
// on the page to set the descriptive form.
|
||||
const STATIC_TITLES: Record<string, string> = {
|
||||
'/': 'Mangalord',
|
||||
'/login': 'Mangalord | Login',
|
||||
'/register': 'Mangalord | Register',
|
||||
'/upload': 'Mangalord | Upload',
|
||||
'/bookmarks': 'Mangalord | Bookmarks',
|
||||
'/collections': 'Mangalord | Collections',
|
||||
'/profile': 'Mangalord | Profile',
|
||||
'/profile/account': 'Mangalord | Account',
|
||||
'/profile/bookmarks': 'Mangalord | Bookmarks',
|
||||
'/profile/collections': 'Mangalord | Collections',
|
||||
'/profile/history': 'Mangalord | Reading history',
|
||||
'/profile/preferences': 'Mangalord | Preferences',
|
||||
'/admin': 'Mangalord | Admin',
|
||||
'/admin/mangas': 'Mangalord | Admin · Mangas',
|
||||
'/admin/users': 'Mangalord | Admin · Users',
|
||||
'/admin/system': 'Mangalord | Admin · System'
|
||||
};
|
||||
|
||||
const layoutTitle = $derived(STATIC_TITLES[$page.route?.id ?? ''] ?? 'Mangalord');
|
||||
|
||||
// Seed authConfig from the universal layout load. $effect keeps
|
||||
// the store in sync if `data` is replaced by a subsequent layout
|
||||
// load (client-side nav). The first run also covers initial
|
||||
@@ -78,6 +105,10 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{layoutTitle}</title>
|
||||
</svelte:head>
|
||||
|
||||
<header bind:this={headerEl}>
|
||||
<nav aria-label="primary">
|
||||
<a class="brand" href="/">Mangalord</a>
|
||||
|
||||
Reference in New Issue
Block a user