From 453a977e4899360289786467d3e2f752e96dc28e Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 11 Oct 2026 18:20:53 -0400 Subject: [PATCH] refactor: the admin and user Requests pages draw a request with one RequestRow, and the kind chip is one KindPill there and on Hidden tracks (#5651) Co-Authored-By: Claude Opus 5.5 --- web/src/lib/components/KindPill.svelte | 22 ++++ web/src/lib/components/RequestRow.svelte | 74 +++++++++++ web/src/lib/components/RequestRow.test.ts | 60 +++++++++ web/src/routes/admin/requests/+page.svelte | 136 ++++++--------------- web/src/routes/library/hidden/+page.svelte | 18 +-- web/src/routes/requests/+page.svelte | 88 ++----------- 6 files changed, 206 insertions(+), 192 deletions(-) create mode 100644 web/src/lib/components/KindPill.svelte create mode 100644 web/src/lib/components/RequestRow.svelte create mode 100644 web/src/lib/components/RequestRow.test.ts diff --git a/web/src/lib/components/KindPill.svelte b/web/src/lib/components/KindPill.svelte new file mode 100644 index 00000000..d75d80db --- /dev/null +++ b/web/src/lib/components/KindPill.svelte @@ -0,0 +1,22 @@ + + +{@render children()} + + diff --git a/web/src/lib/components/RequestRow.svelte b/web/src/lib/components/RequestRow.svelte new file mode 100644 index 00000000..9807734c --- /dev/null +++ b/web/src/lib/components/RequestRow.svelte @@ -0,0 +1,74 @@ + + + + +
  • + + +
    +
    + {r.kind[0].toUpperCase() + r.kind.slice(1)} + +
    +
    {title}
    +
    {meta}
    + {#if r.imported_album_count > 0 || r.imported_track_count > 0} +
    + {#if r.kind === 'artist'} + {plural(r.imported_album_count, 'album', 'albums')} + · {plural(r.imported_track_count, 'track', 'tracks')} ingested + {:else if r.kind === 'album'} + {plural(r.imported_track_count, 'track', 'tracks')} ingested + {:else} + Track ingested + {/if} +
    + {/if} + {@render details?.()} +
    + + {#if actions} +
    {@render actions()}
    + {/if} +
  • diff --git a/web/src/lib/components/RequestRow.test.ts b/web/src/lib/components/RequestRow.test.ts new file mode 100644 index 00000000..bc05151e --- /dev/null +++ b/web/src/lib/components/RequestRow.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, test } from 'vitest'; +import { render, screen } from '@testing-library/svelte'; +import type { MusicRequest } from '#lib/api/types.js'; +import RequestRow, { requestName } from './RequestRow.svelte'; + +function req(over: Partial = {}): MusicRequest { + return { + id: 'r1', + user_id: 'u1', + status: 'approved', + kind: 'album', + artist_mbid: 'art-mbid', + artist_name: 'Boards of Canada', + album_title: 'Geogaddi', + track_title: null, + requested_at: '2026-04-28T12:00:00Z', + updated_at: '2026-04-28T12:00:00Z', + imported_album_count: 0, + imported_track_count: 0, + ...over + }; +} + +const text = (el: HTMLElement) => (el.textContent ?? '').replace(/\s+/g, ' ').trim(); + +// The row both Requests pages draw (#5651): the admin queue and the +// requester's own list read the same request the same way. +describe('RequestRow', () => { + test('says what was asked for, where it stands, and who or when', () => { + render(RequestRow, { request: req(), meta: 'by Boards of Canada · 4/28/2026', testid: 'request-row' }); + const row = screen.getByTestId('request-row'); + expect(row.dataset.status).toBe('approved'); + expect(text(row)).toMatch(/^Album Approved · downloading Geogaddi by Boards of Canada · 4\/28\/2026$/); + }); + + test('says how much has arrived, in the words for each kind', () => { + const { unmount } = render(RequestRow, { + request: req({ kind: 'artist', imported_album_count: 3, imported_track_count: 41 }), + meta: '', + testid: 'r' + }); + expect(text(screen.getByTestId('ingest-progress'))).toBe('3 albums · 41 tracks ingested'); + unmount(); + + render(RequestRow, { request: req({ kind: 'track', track_title: 'Roygbiv', imported_track_count: 1 }), meta: '', testid: 'r' }); + expect(text(screen.getByTestId('ingest-progress'))).toBe('Track ingested'); + }); + + test('nothing arrived yet says nothing about it', () => { + render(RequestRow, { request: req(), meta: '', testid: 'r' }); + expect(screen.queryByTestId('ingest-progress')).toBeNull(); + }); + + test('a request with no title still has a name a screen reader can say', () => { + render(RequestRow, { request: req({ album_title: null }), meta: '', testid: 'r' }); + expect(text(screen.getByTestId('r'))).toMatch(/—/); + expect(requestName(req({ album_title: null }))).toBe('this album by Boards of Canada'); + expect(requestName(req({ kind: 'artist' }))).toBe('Boards of Canada'); + }); +}); diff --git a/web/src/routes/admin/requests/+page.svelte b/web/src/routes/admin/requests/+page.svelte index a597f300..d7e3ced4 100644 --- a/web/src/routes/admin/requests/+page.svelte +++ b/web/src/routes/admin/requests/+page.svelte @@ -1,7 +1,6 @@