refactor(web): replace slideout panel window event with jotai atom (f…#1432
Conversation
…ixes MODSetter#1358) Replace the `SLIDEOUT_PANEL_OPENED_EVENT` window event with a `slideoutOpenedTickAtom` jotai atom. The dispatcher in `SidebarSlideOutPanel` now bumps the tick via `useSetAtom`, and the listener in `Thread` reads it via `useAtomValue` and reacts on change behind a ref guard that skips the initial render — preserving the one-shot-per-open semantics of the previous event. This removes the implicit cross-module string contract, makes the signal traceable through React DevTools / jotai inspector, and lets TypeScript catch typos that the string-based event API silently swallowed.
|
@suryo12 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR replaces a global window event used to signal sidebar slide-out opens with a Jotai atom “tick” that consumers can observe to react (e.g., closing the document picker).
Changes:
- Introduces
slideoutOpenedTickAtomto represent slide-out “opened” events as an incrementing counter. - Updates
SidebarSlideOutPanelto increment the atom when the panel opens. - Updates the assistant composer to react to the atom tick instead of a
windowevent listener.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| surfsense_web/lib/layout-events.ts | Replaces exported DOM event name with a Jotai atom tick for slide-out opens. |
| surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx | Emits “opened” by incrementing the atom instead of dispatching a window event. |
| surfsense_web/components/assistant-ui/thread.tsx | Listens to the atom tick to close the document popover instead of adding/removing a DOM event listener. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace the boolean "skip first render" ref with a ref that stores the previously-seen tick value. The effect now compares against the stored value and only fires when it differs, which makes the dependency naturally used (removes the `void slideoutOpenedTick;` acknowledgement) and self-documents the intent of the guard. Behavior is unchanged — both forms preserve the one-shot-per-event semantics of the prior window-event implementation. The JSDoc on `slideoutOpenedTickAtom` is updated to describe the new pattern.
Replaces the
SLIDEOUT_PANEL_OPENED_EVENTwindow event with aslideoutOpenedTickAtomjotai atom so the sidebar→thread signal becomes typed, traceable, and free of string-based contracts spread across modules.Description
surfsense_web/lib/layout-events.ts— replaces theSLIDEOUT_PANEL_OPENED_EVENTstring constant withslideoutOpenedTickAtom, a jotai number atom that increments on each open.surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx— switches the dispatcher touseSetAtom(slideoutOpenedTickAtom)and bumps the tick via the functional updater whenopentransitions to true.surfsense_web/components/assistant-ui/thread.tsx— switches the listener touseAtomValue(slideoutOpenedTickAtom)and reacts on change inside auseEffect, guarded by auseRefthat skips the initial render so the previous one-shot-per-open semantics are preserved.Motivation and Context
The previous implementation passed a signal between two unrelated modules via a global
windowevent keyed by a string constant. That contract was invisible to TypeScript — a typo on either side would silently drop the signal, and the linkage never showed up in DevTools or jotai inspector. Replacing it with an atom makes the connection explicit, type-safe, and observable via the existing state tooling already used across the codebase.FIX #1358
Screenshots
N/A — refactor, no user-facing behavior change.
API Changes
Change Type
Testing Performed
pnpm exec biome checkpasses on all three files with no warnings.pnpm exec tsc --noEmitintroduces no new type errors in the touched files. Behavior verified by code inspection: dispatcher bumps the atom only whenopentransitions to true (matching the priorif (open) dispatchEventguard), and the listener'suseReffirst-render guard preserves the previous one-shot-per-event semantics.Checklist
High-level PR Summary
This PR refactors the communication mechanism between the sidebar slideout panel and the assistant thread component by replacing a global
windowevent with a Jotai atom. The change eliminates a string-based contract in favor of a type-safe, traceable state signal that increments a tick counter each time the slideout panel opens, allowing the thread component to close its document picker in response while preserving the original one-shot-per-open behavior.⏱️ Estimated Review Time: 5-15 minutes
💡 Review Order Suggestion
surfsense_web/lib/layout-events.tssurfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsxsurfsense_web/components/assistant-ui/thread.tsx