From e63a2aec4451db630114202beaee5fa98250f0df Mon Sep 17 00:00:00 2001
From: Yan <75355375+yancat160@users.noreply.github.com>
Date: Fri, 8 May 2026 13:16:06 -0400
Subject: [PATCH] guard the localStorage read and drop the empty span
placeholder
Address Greptile review on PR #4262.
P2 (line 62): the value read back from localStorage was typed as
any and trusted blindly, so a value written by an extension or a
manual edit could end up as the chart's displayMode. Read it once,
keep only 'table' or 'cards', otherwise fall back to null and let
the existing useMobile-driven default decide. Self-correcting on the
next click is no longer necessary because the next render is already
clean.
P2 (line 114): the empty was a flex placeholder that
existed only to make justify-content: space-between push the toggle
button to the right when allowSearch was false. Drop the span, drop
space-between, and put marginLeft: auto on the inner Row holding the
actions and the toggle. The toggle now hugs the right edge whether
search is rendered or not, with no extra DOM node. style={{}} is
used because the react-zen Row marginLeft prop only accepts spacing
tokens, not auto.
Verified in Playwright at 1400 viewport: the toggle is now flush
with the right edge of the action row, the toggle still flips
between table and cards on click, and a deliberately invalid
localStorage value ({"malicious":true}) is rejected on reload so
the page falls back to the table default.
---
src/components/common/DataGrid.tsx | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/components/common/DataGrid.tsx b/src/components/common/DataGrid.tsx
index 4ac8e72af..7d790c050 100644
--- a/src/components/common/DataGrid.tsx
+++ b/src/components/common/DataGrid.tsx
@@ -57,9 +57,13 @@ export function DataGrid({
const [search, setSearch] = useState(queryParams?.search || data?.search || '');
const showPager = allowPaging && data && data.count > data.pageSize;
const { isMobile } = useMobile();
- const [userDisplayMode, setUserDisplayMode] = useState(
- () => getItem(DISPLAY_MODE_STORAGE_KEY) ?? null,
- );
+ const [userDisplayMode, setUserDisplayMode] = useState(() => {
+ // localStorage can hold anything (extensions, manual edits, schema drift),
+ // so accept only the two values we know how to render and otherwise fall
+ // back to the useMobile-driven default.
+ const stored = getItem(DISPLAY_MODE_STORAGE_KEY);
+ return stored === 'table' || stored === 'cards' ? stored : null;
+ });
// Effective mode: explicit user choice wins, otherwise fall back to the
// mobile-driven default (cards on small viewports, table elsewhere).
@@ -100,8 +104,8 @@ export function DataGrid({
return (
-
- {allowSearch ? (
+
+ {allowSearch && (
- ) : (
-
)}
-
+
{renderActions?.()}
{viewToggleButton}