Repository navigation
FEAT GUI: Add dataset navigation and cards #2747
Description
Is your feature request related to a problem? Please describe.
CoPyRIT has no dataset exploration section. Users cannot see which seed datasets are already in memory or compare their size, modalities, and harm labels before choosing one.
Work item 3 of 17 in #2744. Ready for contributions: the summary API (#2746/#2762) and paginated browsing API (#2748/#2989) are complete. This is the next main-sequence item and is marked help wanted. Please coordinate on this issue before starting so contributors do not duplicate work. The prompt table/details remain the separate next item, #2745.
Describe the solution you'd like
Add a Datasets navigation entry and route with a responsive set of dataset cards. Use the existing Fluent UI theme, spacing, navigation, error, and loading patterns.
Cards should show the dataset name, meaningful example/prompt counts, modalities, harm categories when supplied, and loaded/source information. Use the shipped summary contract from GET /api/datasets ({ items: DatasetInfo[] }), with loaded_only=true available for a loaded-only view:
- Retain the API-provided
selection_keyas the stable card and navigation identity, not the display name. Preservedataset:unnamedand named keys containing spaces or URL-special characters through the shared query builder. A literal named dataset such as__unnamed__is not the unnamed population. - Display
logical_examples,seed_pieces, andobjectiveswith distinct labels and the API's semantics. Readmodalities,harm_categories, andhas_unlabeled_harm_categoriesdirectly. Null/unknown counts are not zero, and missing harm labels mean "Not labeled", not "Safe". Do not sum a page of seeds to obtain card counts. - Use
loadedandprovider_availableas separate facts. Provider availability alone does not mean examples are stored, access is granted, or a particular provider supplied the stored data. Provider-only cards, if shown, must say they are not loaded and must not trigger downloads or pretend to have browsable rows. Provider-loading controls and richer provider metadata remain FEAT GUI: Expose built-in dataset provider metadata #2754/FEAT GUI: Load built-in datasets into memory on request #2753/FEAT GUI: Add dataset loading controls and access guidance #2756. - Name search, summary facets, and sorting can operate on the catalog metadata already returned. Do not request every dataset's seed pages to populate cards or assume the catalog endpoint implements the seed-list filters.
Add name search, appropriate facets from the summary contract, sorting, clear filters, and explicit empty/error/retry states. Browsing must work without an active target. Preserve route/search state through browser Back/Forward and route refresh where applicable. Establish the dataset-detail route/query-state contract using selection_key for #2745 without presenting a dead action as a completed feature. The subsequent table uses GET /api/datasets/seeds?selection_key=<key> and GET /api/datasets/seeds/{example_id}?selection_key=<key>; the key is not a path segment before /seeds. Do not implement the full table or import/scenario flows in this catalog milestone.
Acceptance criteria:
- Datasets is accessible from primary navigation and supports direct navigation.
- Cards use the actual summary fields and selection keys, with distinct example/piece/objective counts, unknown counts, missing labels, and large-count handling.
- Search, filtering, sorting, clear filters, empty memory, and no-match states work.
- Keyboard activation, accessible names, focus, narrow viewports, and existing themes are supported.
- Catalog viewing causes no provider downloads or attack creation.
- Component and routing tests cover success/failure/navigation, empty memory, unnamed and URL-sensitive dataset keys, and loaded versus provider-only metadata, without credentials or seed-page prefetches.
Describe alternatives you've considered, if relevant
Do not introduce a new UI library, a separate visual identity, provider-loading controls, or a second API client. Full prompt browsing arrives in item 4; provider discovery/loading is items 9-11.
Additional context
The shipped API reference is in #2748 and the merged browsing guide. Use final code/OpenAPI contracts, not the earlier #2989 description that returned reconstructed domain seeds. Detail now returns SeedRecord inspection data; no new backend or memory change is needed to deliver these cards.
Start with frontend\src\components\Sidebar\Navigation.tsx, App.tsx, components\Layout, components\Scenarios\ScenarioCatalog, services\api.ts, and types\index.ts. Put feature components under components\Datasets and follow the frontend style/test instructions.
Activity
juliosuas commentedon Oct 9, 2026
Hi Roman Lutz (@romanlutz), I'd like to pick this up.
Rough plan: a Datasets route and nav entry, cards built only from
GET /api/datasets(keyed byselection_key, counts kept separate, unknown and unlabeled shown as such), and client-side search, facets and sort kept in the URL. ScenarioCatalog is the model, and I'll use the existing api client and query builder.Two questions before I start:
/datasets/detail?selection_key=<encoded>fine as the route?loaded_only=true?romanlutz commentedon Oct 9, 2026
Thanks Julio César Suástegui (@juliosuas), happy for you to take this on. Your plan fits the intended scope.
Route:
/datasets/detail?selection_key=<encoded>works. Keepselection_keyopaque and use the shared query builder so unnamed datasets and names containing special characters round-trip correctly. Establish that navigation contract here, but leave the actual prompt table and detail view to #2745.Default view: For this first milestone, default to loaded datasets with
loaded_only=true. That keeps the page focused on examples people can actually browse. Show a clear empty state when memory has no datasets. The available-to-load view and loading controls can come with the later provider-loading work; no need to add those here.Keeping catalog search, facets, and sorting in the URL sounds right. Please continue using only the catalog response for the cards, without fetching seed pages to calculate counts or filters.