@@ -17,6 +17,7 @@ import {
17
17
Popover ,
18
18
PopoverSurface ,
19
19
PopoverTrigger ,
20
+ Switch ,
20
21
tokens ,
21
22
} from '@fluentui/react-components' ;
22
23
@@ -43,13 +44,15 @@ import { getDeviceFacts } from '../Devices';
43
44
44
45
export const InventorySearchControl = ( { subnets, startCallback, endCallback, onAddFact, onAddUndiscoveredList } ) => {
45
46
const { notify } = useNotify ( ) ; // Correctly use the hook here
46
- const { settings } = useStore ( ) ;
47
+ const { settings, inventory } = useStore ( ) ;
47
48
48
49
const [ isStart , setIsStart ] = useState ( false ) ;
49
50
const [ searchRate , setSearchRate ] = useState ( 10 ) ;
50
51
const [ hostSeq , setHostSeq ] = useState ( 0 ) ;
51
52
const [ hostStatusCount , setHostStatusCount ] = useState ( { } ) ;
52
53
const [ sshClientErrorCount , setSshClientErrorCount ] = useState ( { } ) ;
54
+ const [ isSkipLocalInventory , setIsSkipLocalInventory ] = useState ( false ) ;
55
+
53
56
const isStartRef = useRef ( null ) ;
54
57
const hostSeqRef = useRef ( null ) ;
55
58
const hostStatusCountRef = useRef ( null ) ;
@@ -103,6 +106,14 @@ export const InventorySearchControl = ({ subnets, startCallback, endCallback, on
103
106
}
104
107
} ;
105
108
109
+ const isDeviceInInventory = ( device , inventory ) => {
110
+ const isInInventory = inventory . some (
111
+ ( invDevice ) => invDevice . address === device . address && invDevice . port === device . port
112
+ ) ;
113
+ // console.log(`${device.address}:${device.port} isDeviceInInventory: ${isInInventory}`);
114
+ return isInInventory ;
115
+ } ;
116
+
106
117
const fetchDeviceFacts = async ( device ) => {
107
118
const maxRetries = 2 ;
108
119
const retryInterval = 1000 ; // 1 seconds in milliseconds
@@ -196,8 +207,26 @@ export const InventorySearchControl = ({ subnets, startCallback, endCallback, on
196
207
setSshClientErrorCount ( { } ) ;
197
208
198
209
for ( const device of getHostListMultiple ( subnets ) ) {
210
+ if ( isSkipLocalInventory && isDeviceInInventory ( device , inventory ) ) {
211
+ // console.log(`>>>${device.address}:${device.port} isSkipLocalInventory: `, isSkipLocalInventory);
212
+
213
+ const status = 'Skipped' ;
214
+ const message = 'Device is already in the local inventory.' ;
215
+
216
+ updateCount ( { status, message } ) ;
217
+
218
+ await onAddUndiscoveredList ( {
219
+ device : `${ device . address } :${ device . port } ` ,
220
+ status,
221
+ message,
222
+ } ) ;
223
+
224
+ setHostSeq ( ( seq ) => seq + 1 ) ;
225
+ continue ;
226
+ }
227
+
199
228
promises . push ( fetchDeviceFacts ( device ) ) ; // Add the promise to the array
200
- setHostSeq ( n ++ ) ;
229
+ setHostSeq ( ( seq ) => seq + 1 ) ;
201
230
202
231
const expectedNextStart = startTime + n * interval ;
203
232
const currentTime = Date . now ( ) ;
@@ -207,6 +236,8 @@ export const InventorySearchControl = ({ subnets, startCallback, endCallback, on
207
236
await delay ( dynamicDelay ) ; // Adjust delay dynamically
208
237
}
209
238
239
+ n ++ ; // Increment `n` ONLY for processed devices
240
+
210
241
if ( isStartRef . current === false ) return ;
211
242
}
212
243
@@ -272,6 +303,11 @@ export const InventorySearchControl = ({ subnets, startCallback, endCallback, on
272
303
const rotateColorIndex = Math . floor ( ( ( searchRate - minRate ) / ( maxRate - minRate ) ) * ( rotateColors . length - 1 ) ) ;
273
304
const rotateColor = rotateColors [ rotateColorIndex ] ;
274
305
306
+ const onChangeIsSkipLocalInventory = async ( event ) => {
307
+ const checked = event . currentTarget . checked ;
308
+ setIsSkipLocalInventory ( checked === true ) ;
309
+ } ;
310
+
275
311
return (
276
312
< div
277
313
style = { {
@@ -289,21 +325,77 @@ export const InventorySearchControl = ({ subnets, startCallback, endCallback, on
289
325
justifyContent : 'space-between' ,
290
326
width : '100%' ,
291
327
// height: '24px',
292
- overflow : 'visible' ,
328
+ // overflow: 'visible',
293
329
gap : '10px' ,
330
+ position : 'relative' , // Enable relative positioning for the parent container
294
331
} }
295
332
>
333
+ { /* Overlay for the "Skip local inventory" switch */ }
334
+ < div
335
+ style = { {
336
+ position : 'absolute' ,
337
+ top : '-40px' , // Adjust as needed to position above the search button
338
+ left : '-25px' ,
339
+ width : '100%' ,
340
+ display : 'flex' ,
341
+ justifyContent : 'flex-start' , // Align to the left
342
+ alignItems : 'center' ,
343
+ zIndex : 10 , // Ensure it appears above other elements
344
+ pointerEvents : 'auto' , // Allow interactions
345
+ overflow : 'visible' ,
346
+ } }
347
+ >
348
+ < Tooltip
349
+ content = {
350
+ < Text size = { 100 } align = 'center' >
351
+ Skips addresses in local inventory for faster searches. Merge new inventory instead of
352
+ replacing it.
353
+ </ Text >
354
+ }
355
+ positioning = 'after'
356
+ >
357
+ < div
358
+ style = { {
359
+ display : 'flex' ,
360
+ flexDirection : 'row' ,
361
+ alignItems : 'center' ,
362
+ gap : '5px' ,
363
+ } }
364
+ >
365
+ < div
366
+ style = { {
367
+ transform : 'scale(0.4)' ,
368
+ transformOrigin : 'right' ,
369
+ } }
370
+ >
371
+ < Switch checked = { isSkipLocalInventory } onChange = { onChangeIsSkipLocalInventory } />
372
+ </ div >
373
+ < Text size = { 100 } > { isSkipLocalInventory ? 'Skip' : `Do not skip` } local inventory</ Text >
374
+ </ div >
375
+ </ Tooltip >
376
+ </ div >
377
+
296
378
{ ! isStart ? (
297
- < Button
298
- disabled = { subnets ?. length === 0 }
299
- icon = { < SearchPlayIcon /> }
300
- shape = 'circular'
301
- appearance = 'subtle'
302
- size = 'small'
303
- onClick = { onClickSearchStart }
379
+ < div
380
+ style = { {
381
+ display : 'flex' ,
382
+ flexDirection : 'row' ,
383
+ alignContent : 'center' ,
384
+ justifyContent : 'flex-start' ,
385
+ gap : '5px' ,
386
+ } }
304
387
>
305
- Search
306
- </ Button >
388
+ < Button
389
+ disabled = { subnets ?. length === 0 }
390
+ icon = { < SearchPlayIcon /> }
391
+ shape = 'circular'
392
+ appearance = 'subtle'
393
+ size = 'small'
394
+ onClick = { onClickSearchStart }
395
+ >
396
+ Search
397
+ </ Button >
398
+ </ div >
307
399
) : (
308
400
< Button
309
401
disabled = { subnets ?. length === 0 }
0 commit comments