Conversation
|
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
📝 WalkthroughWalkthroughThe Changes
Sequence Diagram(s)sequenceDiagram
participant Component
participant useBookmarkedFilters
participant LocalStorage
Component->>useBookmarkedFilters: Mount/use
useBookmarkedFilters->>LocalStorage: getLocalStorage (if browser)
useBookmarkedFilters-->>useBookmarkedFilters: Set state with saved filters
Component->>useBookmarkedFilters: Add/Toggle bookmark
useBookmarkedFilters->>LocalStorage: setLocalStorage (if browser)
useBookmarkedFilters-->>useBookmarkedFilters: Update React state
useBookmarkedFilters-->>Component: Return normalized savedFilters
Assessment against linked issues
Suggested reviewers
Tip ⚡️ Faster reviews with caching
Enjoy the performance boost—your workflow just got faster. ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Thank you for following the naming conventions for pull request titles! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
apps/dashboard/components/logs/hooks/use-bookmarked-filters.ts (4)
24-31: Prefer lazyuseStateinitialisation to avoid SSR → CSR “flicker”The first paint on the client always starts with an empty array and then re-hydrates once the
useEffectruns.
Initialising the state with the value that will be read fromlocalStorageprevents that extra render and keeps UI in sync from the very first paint.-const [savedFilters, setSavedFilters] = useState<SavedFiltersGroup<QuerySearchParams>[]>([]); +const [savedFilters, setSavedFilters] = useState<SavedFiltersGroup<QuerySearchParams>[]>(() => + JSON.parse(getLocalStorage(localStorageName)) as SavedFiltersGroup<QuerySearchParams>[], +);Because
getLocalStoragealready returns"[]"during SSR, this approach is still safe to render on the server.
61-65: Avoid shadowing thesavedFiltersstate variable
const savedFilters = …re-uses the same identifier as the React state declared above, which can be confusing while reading the effect.
Simply rename the local constant to something likestoredSavedFiltersto improve readability.-const savedFilters = JSON.parse( +const storedSavedFilters = JSON.parse( getLocalStorage(localStorageName), -) as SavedFiltersGroup<QuerySearchParams>[]; +) as SavedFiltersGroup<QuerySearchParams>[];
139-163: Sync bookmarks across tabs & avoid stale closures
toggleBookmarkreads fromlocalStorage, mutates, then callssetSavedFilters.
If the user has the dashboard open in multiple tabs, changes in one tab will not propagate to the others and can be overwritten.
- Listen to the global
"storage"event to keep local React state in sync:useEffect(() => { const handler = (e: StorageEvent) => { if (e.key === localStorageName && e.newValue) { setSavedFilters(JSON.parse(e.newValue)); } }; window.addEventListener("storage", handler); return () => window.removeEventListener("storage", handler); }, [localStorageName]);
- Inside
toggleBookmark, derive the next state from the current state to avoid a stale closure:-setSavedFilters(updatedFilters); +setSavedFilters(() => updatedFilters);
165-174: Normalise thesincefield alongsidestartTime/endTime
sinceis treated as a date filter in earlier logic but is not normalised here, leading to possibleNaNissues when re-hydrating filters...., since: Number.isNaN(Number(filter.filters.since)) ? null : Number(filter.filters.since),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/dashboard/components/logs/hooks/use-bookmarked-filters.ts(5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/components/logs/hooks/use-bookmarked-filters.ts (1)
apps/dashboard/lib/utils.ts (1)
isBrowser(8-8)
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: Test Packages / Test ./packages/nextjs
- GitHub Check: Test Packages / Test ./packages/cache
- GitHub Check: Test Packages / Test ./packages/api
- GitHub Check: Test Packages / Test ./internal/clickhouse
- GitHub Check: Test Packages / Test ./internal/encryption
- GitHub Check: autofix
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
apps/dashboard/components/logs/hooks/use-bookmarked-filters.ts (1)
75-84:crypto.randomUUID()may not exist in older runtimesAlthough most modern browsers and recent Node versions support
crypto.randomUUID, older environments (or JS runtimes locked down for CSP reasons) may not.
If supporting such environments matters, consider:const uuid = typeof crypto?.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2); // fallbackAt minimum, please verify target browser support.
mcstepp
left a comment
There was a problem hiding this comment.
the safari incognito quirk isn't a blocking issue, but we should be diligent about our supported browsers overall.
|
Yeah. I agree i'll run a sweep tomorrow for safari |
What does this PR do?
Add
isBrowsercheck and prevent localStorage failing silently during SSR.Fixes #3249
If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists
Type of change
How should this be tested?
Checklist
Required
pnpm buildpnpm fmtconsole.logsgit pull origin mainAppreciated
Summary by CodeRabbit