fix(products-ui): review pass — show-more race, keyboard history access, a11y glyphs/aria-live, label consistency
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
// Products page (SD-0002 §5.2) — the catalog's home: where imports start and history
|
||||
// lives. SLICE-5: export is disabled (SLICE-6 ships it); the browsable list is #14's.
|
||||
import { useEffect, useState } from "react";
|
||||
import { getProductsSummary, listRuns, type ProductsSummary, type RunSummary } from "../../productsApi";
|
||||
import {
|
||||
dialectLabel,
|
||||
getProductsSummary,
|
||||
listRuns,
|
||||
type ProductsSummary,
|
||||
type RunSummary,
|
||||
} from "../../productsApi";
|
||||
import { Banner } from "../../ui/kit";
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
@@ -40,7 +46,13 @@ export default function ProductsPage() {
|
||||
</Banner>
|
||||
);
|
||||
}
|
||||
if (!summary || !runs) return <p className="note">Loading…</p>;
|
||||
if (!summary || !runs) {
|
||||
return (
|
||||
<p className="note" role="status">
|
||||
Loading…
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
const empty = summary.product_count === 0;
|
||||
return (
|
||||
@@ -51,9 +63,12 @@ export default function ProductsPage() {
|
||||
{!empty && <span className="products__count"> · {summary.product_count.toLocaleString()}</span>}
|
||||
</h1>
|
||||
<div className="products__actions">
|
||||
<button type="button" className="btn-secondary" disabled title="Export arrives in a coming release">
|
||||
Export
|
||||
</button>
|
||||
<div className="products__export">
|
||||
<button type="button" className="btn-secondary" disabled title="Export arrives in a coming release">
|
||||
Export
|
||||
</button>
|
||||
<span className="note">Export arrives in a coming release</span>
|
||||
</div>
|
||||
<a className="btn-primary" href="#/products/import">
|
||||
Import products
|
||||
</a>
|
||||
@@ -95,8 +110,13 @@ export default function ProductsPage() {
|
||||
}}
|
||||
>
|
||||
<td>{new Date(r.created_at).toLocaleString()}</td>
|
||||
<td>{r.file_name}</td>
|
||||
<td>{r.dialect}</td>
|
||||
<td>
|
||||
{/* Anchor = the keyboard/SR path (§6.6); the row onClick stays as a
|
||||
mouse convenience. Both set the same hash, so the double fire on
|
||||
an anchor click is idempotent. */}
|
||||
<a href={`#/products/imports/runs/${r.id}`}>{r.file_name}</a>
|
||||
</td>
|
||||
<td>{dialectLabel(r.dialect)}</td>
|
||||
<td>{r.products_added}</td>
|
||||
<td>{r.products_updated}</td>
|
||||
<td>{r.rows_errored}</td>
|
||||
|
||||
Reference in New Issue
Block a user