fix(diagnostics): say which read failed, and let Live restart
- "Load older" is not offered off a loading filter's placeholder rows, whose cursor belongs to the previous filter. - A failed older page, stale rows and missing counts each get their own message (HU/EN). - Live shows as off once a failed read stopped the polling; pressing it again reads now.
This commit is contained in:
@@ -105,11 +105,26 @@ export default function AdminLogs() {
|
||||
placeholderData: keepPreviousData,
|
||||
refetchInterval: (q) => (live && q.state.status !== "error" ? LIVE_MS * 4 : false),
|
||||
});
|
||||
// What "Load older" continues from — read off the data, since `hasNextPage` is off while live.
|
||||
const olderCursor = logs.data?.pages[logs.data.pages.length - 1]?.next_cursor ?? null;
|
||||
// A read failed while rows (or counts) were already on screen: they are kept, and said to be old.
|
||||
const stale = (logs.isError && !!logs.data) || facets.isError;
|
||||
const retryStale = () => {
|
||||
// A failed read stops the polling (the intervals above); the button shows that, and pressing it
|
||||
// again reads now.
|
||||
const polling = live && !logs.isError;
|
||||
// What "Load older" continues from — read off the data, since `hasNextPage` is off while live; not
|
||||
// off placeholder rows, which are the previous filter's.
|
||||
const olderCursor = logs.isPlaceholderData
|
||||
? null
|
||||
: (logs.data?.pages[logs.data.pages.length - 1]?.next_cursor ?? null);
|
||||
// A read that failed while lines were on screen: they are kept, and the message says what the
|
||||
// failure means for them. (With no lines, the list's own error state says it.)
|
||||
const failure = !logs.data
|
||||
? null
|
||||
: logs.isFetchNextPageError
|
||||
? "olderFailed"
|
||||
: logs.isError || (facets.isError && facets.data)
|
||||
? "stale"
|
||||
: facets.isError
|
||||
? "countsFailed"
|
||||
: null;
|
||||
const retryFailed = () => {
|
||||
if (logs.isFetchNextPageError) void logs.fetchNextPage();
|
||||
else if (logs.isError) void logs.refetch();
|
||||
if (facets.isError) void facets.refetch();
|
||||
@@ -129,13 +144,17 @@ export default function AdminLogs() {
|
||||
id === "none" ? t("adminLogs.noAccount") : (accounts[id] ?? `#${id}`);
|
||||
|
||||
const toggleLive = () => {
|
||||
if (!live) {
|
||||
// Watching the top: drop the older pages now; `liveRef` keeps each tick to the first page.
|
||||
qc.setQueryData<typeof logs.data>(key, (d) =>
|
||||
d ? { pages: d.pages.slice(0, 1), pageParams: d.pageParams.slice(0, 1) } : d,
|
||||
);
|
||||
if (polling) {
|
||||
setLive(false);
|
||||
return;
|
||||
}
|
||||
setLive(!live);
|
||||
// Watching the top: drop the older pages now; `liveRef` keeps each tick to the first page.
|
||||
qc.setQueryData<typeof logs.data>(key, (d) =>
|
||||
d ? { pages: d.pages.slice(0, 1), pageParams: d.pageParams.slice(0, 1) } : d,
|
||||
);
|
||||
setLive(true);
|
||||
if (logs.isError) void logs.refetch();
|
||||
if (facets.isError) void facets.refetch();
|
||||
};
|
||||
|
||||
const loadOlder = () => {
|
||||
@@ -256,10 +275,10 @@ export default function AdminLogs() {
|
||||
/>
|
||||
<span className="ml-auto flex gap-1.5">
|
||||
<Button
|
||||
variant={live ? "outline-accent" : "outline"}
|
||||
variant={polling ? "outline-accent" : "outline"}
|
||||
size="xs"
|
||||
icon={<Radio className="h-3.5 w-3.5" />}
|
||||
aria-pressed={live}
|
||||
aria-pressed={polling}
|
||||
onClick={toggleLive}
|
||||
>
|
||||
{t("adminLogs.live")}
|
||||
@@ -296,14 +315,14 @@ export default function AdminLogs() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stale && (
|
||||
{failure && (
|
||||
<StateMessage
|
||||
tone="error"
|
||||
compact
|
||||
onRetry={retryStale}
|
||||
onRetry={retryFailed}
|
||||
className="border-b border-border"
|
||||
>
|
||||
{t("adminLogs.stale")}
|
||||
{t(`adminLogs.${failure}`)}
|
||||
</StateMessage>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user