feat(web): storage admin, search and catalog pages (M2)
- Storage admin: local folders with a folder picker and NFS sources, connection test, scan and full scan with live progress, enable, disable, delete - path pattern editor with reorder, examples and a preview table that shows which pattern matched and what came from tags; compile errors land under the broken pattern - Library page with counters, scans and unreadable files; search reindex for admins - search box in the top bar: combobox with keyboard navigation, 150 ms debounce, cancelled stale requests, "/" and Ctrl+K, layout fix hint - search page with tabs and paging, artist and album pages, album cards and track lists; unavailable tracks are dimmed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c1160cccd3
commit
a685b1b7ca
27 files changed
+2505
-9
No files matched your search
@@ -17,6 +17,17 @@ const problem = (status: number, code: string, extra: object = {}) => json({ sta
|
||||
|
||||
let seq = 0;
|
||||
|
||||
const kino = { id: '00000000-0000-4000-8000-0000000000aa', name: 'Кино' };
|
||||
const albumSummary = {
|
||||
id: '00000000-0000-4000-8000-0000000000bb',
|
||||
title: 'Группа крови',
|
||||
year: 1988,
|
||||
cover_url: null,
|
||||
cover_colors: [],
|
||||
artist: kino,
|
||||
track_count: 11,
|
||||
};
|
||||
|
||||
export function makeUser(username: string, role: Role, extra: Partial<FakeUser> = {}): FakeUser {
|
||||
seq++;
|
||||
return {
|
||||
@@ -146,6 +157,24 @@ export function fakeApi(initial: FakeUser[]) {
|
||||
}
|
||||
case 'GET /api/v1/admin/audit':
|
||||
return json({ items: [], next_cursor: null });
|
||||
case 'GET /api/v1/search/suggest':
|
||||
case 'GET /api/v1/search': {
|
||||
// «rbyj» — «кино» в английской раскладке: сервер находит и сообщает исправление.
|
||||
const q = url.searchParams.get('q') ?? '';
|
||||
const hit = q === 'кино' || q === 'rbyj';
|
||||
return json({
|
||||
artists: hit ? [kino] : [],
|
||||
albums: hit ? [albumSummary] : [],
|
||||
tracks: [],
|
||||
totals: { artists: hit ? 1 : 0, albums: hit ? 1 : 0, tracks: 0 },
|
||||
corrected_query: q === 'rbyj' ? 'кино' : null,
|
||||
next_cursor: null,
|
||||
});
|
||||
}
|
||||
case `GET /api/v1/artists/${kino.id}`:
|
||||
return json({ ...kino, album_count: 1, track_count: 0 });
|
||||
case `GET /api/v1/artists/${kino.id}/albums`:
|
||||
return json({ items: [albumSummary] });
|
||||
}
|
||||
return problem(404, 'common.not_found');
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user