@@ -20,7 +20,7 @@ type SelectionContext = {
20
20
disableBulkEdit ?: boolean
21
21
getQueryParams : ( additionalParams ?: Where ) => string
22
22
selectAll : SelectAllStatus
23
- selected : Record < number | string , boolean >
23
+ selected : Map < number | string , boolean >
24
24
setSelection : ( id : number | string ) => void
25
25
toggleAll : ( allAvailable ?: boolean ) => void
26
26
totalDocs : number
@@ -30,6 +30,7 @@ const Context = createContext({} as SelectionContext)
30
30
31
31
type Props = {
32
32
readonly children : React . ReactNode
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
34
readonly docs : any [ ]
34
35
readonly totalDocs : number
35
36
}
@@ -39,35 +40,33 @@ export const SelectionProvider: React.FC<Props> = ({ children, docs = [], totalD
39
40
40
41
const { code : locale } = useLocale ( )
41
42
const [ selected , setSelected ] = useState < SelectionContext [ 'selected' ] > ( ( ) => {
42
- const rows = { }
43
+ const rows = new Map ( )
43
44
docs . forEach ( ( { id } ) => {
44
- rows [ id ] = false
45
+ rows . set ( id , false )
45
46
} )
46
47
return rows
47
48
} )
49
+
48
50
const [ selectAll , setSelectAll ] = useState < SelectAllStatus > ( SelectAllStatus . None )
49
51
const [ count , setCount ] = useState ( 0 )
50
52
const { searchParams } = useSearchParams ( )
51
53
52
54
const toggleAll = useCallback (
53
55
( allAvailable = false ) => {
54
- const rows = { }
56
+ const rows = new Map ( )
55
57
if ( allAvailable ) {
56
58
setSelectAll ( SelectAllStatus . AllAvailable )
57
59
docs . forEach ( ( { id } ) => {
58
- rows [ id ] = true
60
+ rows . set ( id , true )
59
61
} )
60
62
} else if (
61
63
selectAll === SelectAllStatus . AllAvailable ||
62
64
selectAll === SelectAllStatus . AllInPage
63
65
) {
64
66
setSelectAll ( SelectAllStatus . None )
65
- docs . forEach ( ( { id } ) => {
66
- rows [ id ] = false
67
- } )
68
67
} else {
69
68
docs . forEach ( ( { id } ) => {
70
- rows [ id ] = selectAll !== SelectAllStatus . Some
69
+ rows . set ( id , selectAll !== SelectAllStatus . Some )
71
70
} )
72
71
}
73
72
setSelected ( rows )
@@ -77,15 +76,18 @@ export const SelectionProvider: React.FC<Props> = ({ children, docs = [], totalD
77
76
78
77
const setSelection = useCallback (
79
78
( id ) => {
80
- const isSelected = ! selected [ id ]
81
- const newSelected = {
82
- ...selected ,
83
- [ id ] : isSelected ,
84
- }
85
- if ( ! isSelected ) {
86
- setSelectAll ( SelectAllStatus . Some )
79
+ const existingValue = selected . get ( id )
80
+ const isSelected = typeof existingValue === 'boolean' ? ! existingValue : true
81
+
82
+ let newMap = new Map ( )
83
+
84
+ if ( isSelected ) {
85
+ newMap = new Map ( selected . set ( id , isSelected ) )
86
+ } else {
87
+ newMap = new Map ( selected . set ( id , false ) )
87
88
}
88
- setSelected ( newSelected )
89
+
90
+ setSelected ( newMap )
89
91
} ,
90
92
[ selected ] ,
91
93
)
@@ -99,11 +101,17 @@ export const SelectionProvider: React.FC<Props> = ({ children, docs = [], totalD
99
101
id : { not_equals : '' } ,
100
102
}
101
103
} else {
104
+ const ids = [ ]
105
+
106
+ for ( const [ key , value ] of selected ) {
107
+ if ( value ) {
108
+ ids . push ( key )
109
+ }
110
+ }
111
+
102
112
where = {
103
113
id : {
104
- in : Object . keys ( selected )
105
- . filter ( ( id ) => selected [ id ] )
106
- . map ( ( id ) => id ) ,
114
+ in : ids ,
107
115
} ,
108
116
}
109
117
}
@@ -130,30 +138,42 @@ export const SelectionProvider: React.FC<Props> = ({ children, docs = [], totalD
130
138
let some = false
131
139
let all = true
132
140
133
- if ( ! Object . values ( selected ) . length ) {
141
+ if ( ! selected . size ) {
134
142
all = false
135
143
some = false
136
144
} else {
137
- Object . values ( selected ) . forEach ( ( val ) => {
138
- all = all && val
139
- some = some || val
140
- } )
145
+ for ( const [ _ , value ] of selected ) {
146
+ all = all && value
147
+ some = some || value
148
+ }
141
149
}
142
150
143
- if ( all ) {
151
+ if ( all && selected . size === docs . length ) {
152
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
144
153
setSelectAll ( SelectAllStatus . AllInPage )
145
154
} else if ( some ) {
155
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
146
156
setSelectAll ( SelectAllStatus . Some )
147
157
} else {
158
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
148
159
setSelectAll ( SelectAllStatus . None )
149
160
}
150
- } , [ selectAll , selected ] )
161
+ } , [ selectAll , selected , totalDocs , docs ] )
151
162
152
163
useEffect ( ( ) => {
153
- const newCount =
154
- selectAll === SelectAllStatus . AllAvailable
155
- ? totalDocs
156
- : Object . keys ( selected ) . filter ( ( id ) => selected [ id ] ) . length
164
+ let newCount = 0
165
+
166
+ if ( selectAll === SelectAllStatus . AllAvailable ) {
167
+ newCount = totalDocs
168
+ } else {
169
+ for ( const [ _ , value ] of selected ) {
170
+ if ( value ) {
171
+ newCount ++
172
+ }
173
+ }
174
+ }
175
+
176
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
157
177
setCount ( newCount )
158
178
} , [ selectAll , selected , totalDocs ] )
159
179
0 commit comments