@@ -4,7 +4,6 @@ import Checkbox from '@mui/material/Checkbox';
44import FormControlLabel from '@mui/material/FormControlLabel' ;
55import Menu from '@mui/material/Menu' ;
66import MenuItem from '@mui/material/MenuItem' ;
7- import type { PayloadAction } from '@reduxjs/toolkit' ;
87import {
98 usePopupState ,
109 bindTrigger ,
@@ -13,42 +12,57 @@ import {
1312
1413import { useAppDispatch } from '../../hooks/app' ;
1514import useAdvancedColumns from '../../hooks/useAdvancedColumns' ;
15+ import useRawSearchParams from '../../hooks/useRawSearchParams' ;
1616import {
1717 updateShowCliffsDelta ,
1818 updateShowCles ,
1919} from '../../reducers/ColumnPrefsSlice' ;
20+ import type { AdvancedColumns } from '../../types/types' ;
21+ import {
22+ ADVANCED_COLUMNS_PARAM ,
23+ serializeAdvancedColumns ,
24+ } from '../../utils/advancedColumnsUrl' ;
2025
2126// Dropdown that reveals a checkbox for each advanced statistics column
2227// (Cliff's Delta, CLES). Each is toggled independently — either, both, or
23- // neither can be shown. Self-contained: reads/writes the columnPrefs Redux
24- // slice and mirrors each choice to localStorage so it persists across reloads.
25- // Shared by the main results controls and the subtests controls.
28+ // neither can be shown. The selection is stored in the URL so a shared link
29+ // reproduces it (via history.replaceState — no data refetch) and mirrored to
30+ // Redux for reactive rendering. Shared by the main and subtests controls.
2631function AdvancedColumnsMenu ( ) {
2732 const popupState = usePopupState ( {
2833 variant : 'popover' ,
2934 popupId : 'advanced-columns-menu' ,
3035 } ) ;
3136 const dispatch = useAppDispatch ( ) ;
3237 const { cliffsDelta, cles } = useAdvancedColumns ( ) ;
38+ const [ , updateRawSearchParams ] = useRawSearchParams ( ) ;
39+
40+ const applyAdvancedColumns = ( next : AdvancedColumns ) => {
41+ dispatch ( updateShowCliffsDelta ( next . cliffsDelta ) ) ;
42+ dispatch ( updateShowCles ( next . cles ) ) ;
3343
34- // Dispatch the toggle and mirror the choice to localStorage under its key.
35- const toggle =
36- ( action : ( value : boolean ) => PayloadAction < boolean > , storageKey : string ) =>
37- ( checked : boolean ) => {
38- dispatch ( action ( checked ) ) ;
39- localStorage . setItem ( storageKey , String ( checked ) ) ;
40- } ;
44+ const params = new URLSearchParams ( window . location . search ) ;
45+ const value = serializeAdvancedColumns ( next ) ;
46+ if ( value ) {
47+ params . set ( ADVANCED_COLUMNS_PARAM , value ) ;
48+ } else {
49+ params . delete ( ADVANCED_COLUMNS_PARAM ) ;
50+ }
51+ updateRawSearchParams ( params ) ;
52+ } ;
4153
4254 const columns = [
4355 {
4456 label : "Cliff's Delta" ,
4557 checked : cliffsDelta ,
46- onChange : toggle ( updateShowCliffsDelta , 'showCliffsDelta' ) ,
58+ onChange : ( checked : boolean ) =>
59+ applyAdvancedColumns ( { cliffsDelta : checked , cles } ) ,
4760 } ,
4861 {
4962 label : 'CLES' ,
5063 checked : cles ,
51- onChange : toggle ( updateShowCles , 'showCles' ) ,
64+ onChange : ( checked : boolean ) =>
65+ applyAdvancedColumns ( { cliffsDelta, cles : checked } ) ,
5266 } ,
5367 ] ;
5468
0 commit comments