fix(ui): R3 S1 review fixes — don't blank data on transient refetch errors

- The honest-state branch now guards on `isError && !data`, so a background/window-focus refetch
  failure keeps already-visible content instead of replacing the list with a full error screen
  (regression the bare `isError` introduced). Applied to AuditLog, Channels, ChannelDiscovery,
  PlexBrowse, PlexPlaylistView, Messages(people), Feed — matching the guard already used in
  Messages(conversations)/NotificationsPanel/Scheduler.
- Drop the unused DataTable loading/error/onRetry props (every table page uses the outer
  StateMessage branch, not the props) — reverts DataTable to its simple empty block.
- StateMessage announces errors with role=alert/aria-live=assertive (was polite for all tones).
- Remove the now-unused common.empty string (en+hu), left over from the removed QueryState render-prop.
This commit is contained in:
2026-07-22 04:14:46 +02:00
parent d9a08892a5
commit a393fd2fb1
11 changed files with 19 additions and 35 deletions
+8 -6
View File
@@ -22,8 +22,9 @@ export function StateMessage({
return (
<div
className={`flex flex-col items-center gap-3 py-10 text-sm text-muted ${className}`}
role="status"
aria-live="polite"
// An error is announced promptly (assertive); a plain loading line is polite.
role={tone === "error" ? "alert" : "status"}
aria-live={tone === "error" ? "assertive" : "polite"}
>
<span className="inline-flex items-center gap-2 text-center">
{tone === "error" && <AlertTriangle className="w-4 h-4 shrink-0 text-red-400" />}
@@ -42,7 +43,8 @@ export function StateMessage({
);
}
// The honest-state convention every page now follows: check `isError` BEFORE the empty branch so a
// failed fetch renders this message (with Retry) instead of the page's "empty" text — the R3 bug
// where a backend restart read as "No channels". `StateMessage` is the shared building block;
// pages wire it into their existing loading/empty ternary (and DataTable takes loading/error props).
// The honest-state convention every page now follows: check `isError && <no data>` BEFORE the empty
// branch, so a failed fetch renders this message (with Retry) instead of the page's "empty" text
// — the R3 bug where a backend restart read as "No channels". The `&& <no data>` guard matters: a
// transient refetch error while data is already on screen keeps the data rather than blanking it to
// an error. `StateMessage` is the shared building block pages wire into their loading/empty ternary.