fix(channels): drop a stale column filter when sent to "without full history"

A focus-channel deep-link sets (and persists) the channel-name column filter
via the DataTable's externalFilter. That persisted value then survived into
unrelated visits: clicking the header's "N without full history" link landed
on the right tab with the right status chip, but a leftover name filter (e.g.
a channel focused in a past session) hid every row — "No channels".

Add a resetFiltersToken to DataTable that clears its column filters when it
advances, and bump it from the header intent. The token's ref starts at 0 so
the clear fires even when the table remounts on navigation, while a plain
reload (token still 0) keeps the user's persisted filters.
This commit is contained in:
npeter83 2026-06-19 03:55:55 +02:00
parent 39cd025e79
commit 52a5d1fef8
3 changed files with 26 additions and 0 deletions

View file

@ -67,6 +67,7 @@ export default function DataTable<T>({
controlsPosition = "bottom",
controlsLeading,
externalFilter,
resetFiltersToken,
}: {
rows: T[];
columns: Column<T>[];
@ -81,6 +82,10 @@ export default function DataTable<T>({
// Set a column's filter from outside (e.g. "focus this channel" deep-links here). Applied
// whenever its value changes; the user can still clear it from the header afterwards.
externalFilter?: { key: string; value: string } | null;
// Bump this to clear all column filters — for navigation intents that mean "show me this
// set" (e.g. the header's "without full history" link), so a stale persisted filter can't
// hide the rows the user was just sent to see.
resetFiltersToken?: number;
}) {
const { t } = useTranslation();
const initial = loadPersist(persistKey);
@ -104,6 +109,18 @@ export default function DataTable<T>({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [externalFilter?.key, externalFilter?.value]);
// Clear column filters when the reset token advances. The ref starts at 0 (not at the prop)
// so a navigation that bumped the token still clears even when it remounts this table fresh
// (e.g. arriving from another page); a plain reload keeps the token at 0 and the effect is a
// no-op, so the user's persisted filters survive.
const resetRef = useRef(0);
useEffect(() => {
if (resetFiltersToken === undefined || resetFiltersToken === resetRef.current) return;
resetRef.current = resetFiltersToken;
setFilters({});
setPage(0);
}, [resetFiltersToken]);
useEffect(() => {
if (!openFilter) return;
function onDown(e: MouseEvent) {