@@ -8,14 +8,9 @@ import {
8
8
Reset ,
9
9
Tooltip ,
10
10
} from "@radix-ui/themes" ;
11
- import { atom , useAtom , useAtomValue , useSetAtom } from "jotai" ;
12
- import {
13
- setSearchLeaderSlotsAtom ,
14
- SearchType ,
15
- searchTypeAtom ,
16
- searchLeaderSlotsAtom ,
17
- } from "./atoms" ;
18
- import { useMount , useUnmount } from "react-use" ;
11
+ import { atom , useAtomValue , useSetAtom } from "jotai" ;
12
+ import { setSearchLeaderSlotsAtom , searchLeaderSlotsAtom } from "./atoms" ;
13
+ import { useMount } from "react-use" ;
19
14
import {
20
15
currentLeaderSlotAtom ,
21
16
leaderSlotsAtom ,
@@ -26,32 +21,45 @@ import { useDebouncedCallback } from "use-debounce";
26
21
import NextSlotStatus from "../Overview/SlotPerformance/NextSlotStatus" ;
27
22
import styles from "./search.module.css" ;
28
23
import { skippedSlotsAtom } from "../../api/atoms" ;
29
- import { useState } from "react" ;
24
+ import { useCallback , useEffect , useState } from "react" ;
30
25
import * as Toggle from "@radix-ui/react-toggle" ;
26
+ import { SearchTypeEnum } from "../../routes/leaderSchedule" ;
27
+ import {
28
+ useSearchTextSearchParam ,
29
+ useSearchTypeSearchParam ,
30
+ } from "./useSearchParams" ;
31
31
32
32
const isVisibleAtom = atom ( ( get ) => ! ! get ( currentLeaderSlotAtom ) ) ;
33
33
34
34
export default function Search ( ) {
35
35
const isVisible = useAtomValue ( isVisibleAtom ) ;
36
36
const setSearch = useSetAtom ( setSearchLeaderSlotsAtom ) ;
37
- const [ localSearch , setLocalSearch ] = useState ( "" ) ;
38
37
39
- const setSearchType = useSetAtom ( searchTypeAtom ) ;
40
38
const setSlotOverride = useSetAtom ( slotOverrideAtom ) ;
41
39
40
+ const { searchType } = useSearchTypeSearchParam ( ) ;
41
+ const { searchText, setSearchText } = useSearchTextSearchParam ( ) ;
42
+ const [ localValue , setLocalValue ] = useState ( searchText ) ;
43
+
42
44
const debouncedSetSearch = useDebouncedCallback ( ( value : string ) => {
43
45
setSearch ( value ) ;
44
- } , 1000 ) ;
46
+ setSearchText ( value ) ;
47
+ } , 1_000 ) ;
48
+
49
+ if ( ! debouncedSetSearch . isPending ( ) && localValue !== searchText ) {
50
+ setLocalValue ( searchText ) ;
51
+ }
45
52
46
53
const reset = ( ) => {
47
- setLocalSearch ( "" ) ;
54
+ setSearchText ( "" ) ;
48
55
setSlotOverride ( undefined ) ;
49
56
setSearch ( "" ) ;
50
57
} ;
51
58
52
- useMount ( reset ) ;
53
- useUnmount ( ( ) => {
54
- setSearchType ( SearchType . Text ) ;
59
+ useMount ( ( ) => {
60
+ if ( searchType === SearchTypeEnum . text ) {
61
+ setSearch ( searchText ) ;
62
+ }
55
63
} ) ;
56
64
57
65
if ( ! isVisible ) return ;
@@ -64,11 +72,10 @@ export default function Search() {
64
72
variant = "soft"
65
73
color = "gray"
66
74
onChange = { ( e ) => {
67
- setSearchType ( SearchType . Text ) ;
68
- setLocalSearch ( e . currentTarget . value ) ;
75
+ setLocalValue ( e . currentTarget . value ) ;
69
76
debouncedSetSearch ( e . currentTarget . value ) ;
70
77
} }
71
- value = { localSearch }
78
+ value = { localValue }
72
79
>
73
80
< TextField . Slot >
74
81
< MagnifyingGlassIcon
@@ -77,7 +84,7 @@ export default function Search() {
77
84
style = { { color : "#AFB2C2" } }
78
85
/>
79
86
</ TextField . Slot >
80
- { localSearch && (
87
+ { localValue && (
81
88
< TextField . Slot >
82
89
< IconButton size = "1" variant = "ghost" >
83
90
< Cross1Icon
@@ -107,16 +114,6 @@ function SkipRate() {
107
114
let value = "-" ;
108
115
109
116
if ( skipRate !== undefined ) {
110
- // if (skipRate.slots_processed)
111
- // if (skipRate.slots_processed === 0 || skipRate.slots_skipped === 0) {
112
- // value = "0";
113
- // } else {
114
- // const skipRatePct = skipRate.slots_skipped / skipRate.slots_processed;
115
- // value = (skipRatePct * 100).toLocaleString(undefined, {
116
- // minimumFractionDigits: 0,
117
- // maximumFractionDigits: 2,
118
- // });
119
- // }
120
117
value = ( skipRate . skip_rate * 100 ) . toLocaleString ( undefined , {
121
118
minimumFractionDigits : 0 ,
122
119
maximumFractionDigits : 2 ,
@@ -140,29 +137,41 @@ interface MySlotsProps {
140
137
}
141
138
142
139
function MySlots ( { resetSearchText } : MySlotsProps ) {
143
- const slots = useAtomValue ( leaderSlotsAtom ) ;
140
+ const leaderSlots = useAtomValue ( leaderSlotsAtom ) ;
144
141
const setSearch = useSetAtom ( searchLeaderSlotsAtom ) ;
145
142
const setSlotOverride = useSetAtom ( slotOverrideAtom ) ;
146
143
147
- const [ searchType , setSearchType ] = useAtom ( searchTypeAtom ) ;
144
+ const { searchType, setSearchType } = useSearchTypeSearchParam ( ) ;
145
+
146
+ const slotCount = ( leaderSlots ?. length ?? 0 ) * 4 ;
148
147
149
- const slotCount = ( slots ?. length ?? 0 ) * 4 ;
148
+ const setMySlots = useCallback ( ( ) => {
149
+ setSearch ( leaderSlots ) ;
150
+ } , [ setSearch , leaderSlots ] ) ;
151
+
152
+ useEffect ( ( ) => {
153
+ if ( searchType === SearchTypeEnum . mySlots ) {
154
+ setSearch ( leaderSlots ) ;
155
+ }
156
+ // On mount / data load
157
+ // eslint-disable-next-line react-hooks/exhaustive-deps
158
+ } , [ leaderSlots , setSearch ] ) ;
150
159
151
160
const handleClick = ( ) => {
152
161
resetSearchText ( ) ;
153
162
154
163
setSlotOverride ( undefined ) ;
155
164
156
- if ( searchType === SearchType . MySlots ) {
157
- setSearchType ( SearchType . Text ) ;
165
+ if ( searchType === SearchTypeEnum . mySlots ) {
166
+ setSearchType ( SearchTypeEnum . text ) ;
158
167
} else {
159
- setSearchType ( SearchType . MySlots ) ;
160
- setSearch ( slots ) ;
168
+ setSearchType ( SearchTypeEnum . mySlots ) ;
169
+ setMySlots ( ) ;
161
170
}
162
171
} ;
163
172
164
- const isSelected = searchType === SearchType . MySlots ;
165
- const isDisabled = ! slots ?. length ;
173
+ const isSelected = searchType === SearchTypeEnum . mySlots ;
174
+ const isDisabled = ! leaderSlots ?. length ;
166
175
167
176
return (
168
177
< Tooltip content = "Number of slots this validator is leader in the current epoch. Toggle to filter" >
@@ -193,26 +202,37 @@ function SkippedSlots({ resetSearchText }: SkippedSlotsProps) {
193
202
const setSearch = useSetAtom ( searchLeaderSlotsAtom ) ;
194
203
const setSlotOverride = useSetAtom ( slotOverrideAtom ) ;
195
204
196
- const [ searchType , setSearchType ] = useAtom ( searchTypeAtom ) ;
205
+ const { searchType, setSearchType } = useSearchTypeSearchParam ( ) ;
197
206
198
207
const skippedCount = skippedSlots ?. length ?? 0 ;
199
208
209
+ const setSkippedSlots = useCallback ( ( ) => {
210
+ const slotStarts = skippedSlots ?. map ( ( slot ) => slot - ( slot % 4 ) ) ;
211
+ setSearch ( [ ...new Set ( slotStarts ) ] ) ;
212
+ } , [ setSearch , skippedSlots ] ) ;
213
+
214
+ useEffect ( ( ) => {
215
+ if ( searchType === SearchTypeEnum . skippedSlots ) {
216
+ setSkippedSlots ( ) ;
217
+ }
218
+ // On mount / data load
219
+ // eslint-disable-next-line react-hooks/exhaustive-deps
220
+ } , [ setSkippedSlots ] ) ;
221
+
200
222
const handleClick = ( ) => {
201
223
resetSearchText ( ) ;
202
224
203
225
setSlotOverride ( undefined ) ;
204
226
205
- if ( searchType === SearchType . SkippedSlots ) {
206
- setSearchType ( SearchType . Text ) ;
227
+ if ( searchType === SearchTypeEnum . skippedSlots ) {
228
+ setSearchType ( SearchTypeEnum . text ) ;
207
229
} else if ( skippedSlots ?. length ) {
208
- setSearchType ( SearchType . SkippedSlots ) ;
209
-
210
- const slotStarts = skippedSlots ?. map ( ( slot ) => slot - ( slot % 4 ) ) ;
211
- setSearch ( [ ...new Set ( slotStarts ) ] ) ;
230
+ setSearchType ( SearchTypeEnum . skippedSlots ) ;
231
+ setSkippedSlots ( ) ;
212
232
}
213
233
} ;
214
234
215
- const isSelected = searchType === SearchType . SkippedSlots ;
235
+ const isSelected = searchType === SearchTypeEnum . skippedSlots ;
216
236
const isDisabled = ! skippedSlots ?. length ;
217
237
218
238
return (
@@ -224,7 +244,7 @@ function SkippedSlots({ resetSearchText }: SkippedSlotsProps) {
224
244
onClick = { handleClick }
225
245
aria-label = "Toggle skipped slots"
226
246
pressed = { isSelected }
227
- disabled = { isDisabled }
247
+ disabled = { ! isSelected && isDisabled }
228
248
>
229
249
< Text className = { styles . label } > My Skipped Slots</ Text >
230
250
< Text > { skippedCount } </ Text >
0 commit comments