@@ -68,17 +68,36 @@ export function SettingsPage() {
6868
6969 // Deep-link: when another surface routes here for a specific section, scroll
7070 // it into view and briefly flash it so the user lands on the right control.
71+ // Generic over section keys — any surface can target a section by calling
72+ // `setPendingSettingsSection('<key>')` before `navigateTo('settings')`. A
73+ // section becomes targetable by wrapping its card with `registerSection` +
74+ // `sectionFlashClass` (see `<SECTION_KEYS>` below).
7175 const pendingSection = usePendingSettingsSection ( ) ;
7276 const clearPendingSection = useSetPendingSettingsSection ( ) ;
73- const securityRef = useRef < HTMLDivElement > ( null ) ;
74- const [ flashSecurity , setFlashSecurity ] = useState ( false ) ;
77+ const sectionEls = useRef < Record < string , HTMLDivElement | null > > ( { } ) ;
78+ const [ flashedSection , setFlashedSection ] = useState < string | null > ( null ) ;
79+
80+ const registerSection = ( key : string ) => ( el : HTMLDivElement | null ) => {
81+ sectionEls . current [ key ] = el ;
82+ } ;
83+ const sectionFlashClass = ( key : string ) =>
84+ flashedSection === key
85+ ? 'rounded-xl ring-2 ring-primary-500 ring-offset-2 ring-offset-[rgb(var(--background))] transition-shadow duration-500'
86+ : 'rounded-xl ring-0 transition-shadow duration-500' ;
7587
7688 useEffect ( ( ) => {
77- if ( pendingSection !== 'security' || ! securityRef . current ) return ;
78- securityRef . current . scrollIntoView ( { behavior : 'smooth' , block : 'center' } ) ;
79- setFlashSecurity ( true ) ;
89+ if ( ! pendingSection ) return ;
90+ const el = sectionEls . current [ pendingSection ] ;
91+ // Unknown or not-yet-mounted section: drop the request so a stale value
92+ // doesn't fire the flash on a later, unrelated render.
93+ if ( ! el ) {
94+ clearPendingSection ( null ) ;
95+ return ;
96+ }
97+ el . scrollIntoView ( { behavior : 'smooth' , block : 'center' } ) ;
98+ setFlashedSection ( pendingSection ) ;
8099 clearPendingSection ( null ) ;
81- const t = setTimeout ( ( ) => setFlashSecurity ( false ) , 2200 ) ;
100+ const t = setTimeout ( ( ) => setFlashedSection ( null ) , 2200 ) ;
82101 return ( ) => clearTimeout ( t ) ;
83102 } , [ pendingSection , clearPendingSection ] ) ;
84103
@@ -378,7 +397,9 @@ export function SettingsPage() {
378397 </ div >
379398
380399 { /* Updates Section */ }
381- < UpdateChecker />
400+ < div ref = { registerSection ( 'updates' ) } className = { sectionFlashClass ( 'updates' ) } >
401+ < UpdateChecker />
402+ </ div >
382403
383404 { /* Startup & System Tray Section - always show toggles so e2e and slow backends see the section */ }
384405 < Card data-testid = "settings-startup-section" >
@@ -474,6 +495,7 @@ export function SettingsPage() {
474495 </ Card >
475496
476497 { /* Gateway Section — port override + reset to default */ }
498+ < div ref = { registerSection ( 'gateway' ) } className = { sectionFlashClass ( 'gateway' ) } >
477499 < Card data-testid = "settings-gateway-section" >
478500 < CardHeader >
479501 < CardTitle className = "flex items-center gap-2" >
@@ -612,8 +634,10 @@ export function SettingsPage() {
612634 ) }
613635 </ CardContent >
614636 </ Card >
637+ </ div >
615638
616639 { /* Workspaces Section */ }
640+ < div ref = { registerSection ( 'workspaces' ) } className = { sectionFlashClass ( 'workspaces' ) } >
617641 < Card data-testid = "settings-workspaces-section" >
618642 < CardHeader >
619643 < CardTitle className = "flex items-center gap-2" >
@@ -646,16 +670,13 @@ export function SettingsPage() {
646670 </ div >
647671 </ CardContent >
648672 </ Card >
673+ </ div >
649674
650675 { /* Security Section */ }
651676 < div
652- ref = { securityRef }
677+ ref = { registerSection ( 'security' ) }
653678 id = "settings-security"
654- className = {
655- flashSecurity
656- ? 'rounded-xl ring-2 ring-primary-500 ring-offset-2 ring-offset-[rgb(var(--background))] transition-shadow duration-500'
657- : 'rounded-xl ring-0 transition-shadow duration-500'
658- }
679+ className = { sectionFlashClass ( 'security' ) }
659680 >
660681 < Card data-testid = "settings-security-section" >
661682 < CardHeader >
0 commit comments