Add sidebar navigation and global command search

This commit is contained in:
2026-10-07 18:59:39 -04:00
parent 9999e80226
commit e4f37f6964
33 changed files with 660 additions and 151 deletions
+34
View File
@@ -0,0 +1,34 @@
import { describe, expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
const { page } = await vi.hoisted(async () => {
const { writable } = await import('svelte/store');
return { page: writable({ url: new URL('http://localhost/servers/t5_zombie_theater_1'), data: { user: { role: 'admin' } } }) };
});
vi.mock('$app/stores', () => ({ page }));
import Breadcrumbs from '../../src/lib/ui/components/primitives/Breadcrumbs.svelte';
const items = [{ label: 'Fleet', href: '/' }, { label: 'Kino Der Toten' }];
describe('contextual breadcrumbs', () => {
it('restores the parent list filters in its only parent link', () => {
page.set({ url: new URL('http://localhost/servers/t5_zombie_theater_1?returnTo=%2F%3Ffilter%3Doccupied%26sort%3Dround'), data: { user: { role: 'admin' } } });
const html = render(Breadcrumbs, { props: { items } }).body;
expect(html).toContain('href="/?filter=occupied&sort=round"');
expect(html.match(/<a\b/g)).toHaveLength(1);
expect(html).toContain('aria-current="page"');
});
it('names a contextual parent and retains its saved section', () => {
page.set({ url: new URL('http://localhost/servers/t5_zombie_theater_1?returnTo=%2Fmaintenance%3Fview%3Dactivity'), data: { user: { role: 'admin' } } });
const html = render(Breadcrumbs, { props: { items } }).body;
expect(html).toContain('href="/maintenance?view=activity"');
expect(html).toContain('Maintenance');
});
it('rejects external and API destinations while preserving the filtered fallback', () => {
for (const returnTo of ['https://evil.invalid/', '/api/auth/logout']) {
page.set({ url: new URL(`http://localhost/servers/t5_zombie_theater_1?returnTo=${encodeURIComponent(returnTo)}`), data: { user: { role: 'admin' } } });
const html = render(Breadcrumbs, { props: { items, fallback: '/?filter=pinned' } }).body;
expect(html).toContain('href="/?filter=pinned"');
expect(html).not.toContain(returnTo);
}
});
});