@@ -38,13 +38,25 @@ export default function TouchlinkPage() {
3838 const setTouchlinkScan = useAppStore ( ( state ) => state . setTouchlinkScan ) ;
3939 const [ scanIdx , setScanIdx ] = useState ( 0 ) ;
4040 const [ hueExtPanId , setHueExtPanId ] = useState < string > ( "" ) ;
41+ const [ hueSerialNumbersRaw , setHueSerialNumbersRaw ] = useState < string > ( "" ) ;
4142 const [ hueSerialNumbers , setHueSerialNumbers ] = useState < number [ ] > ( [ ] ) ;
4243
4344 // biome-ignore lint/correctness/useExhaustiveDependencies: specific trigger
4445 useEffect ( ( ) => {
45- setHueExtPanId ( bridgeInfo [ scanIdx ] . network . extended_pan_id ) ;
46+ setHueExtPanId ( bridgeInfo [ scanIdx ] . network ? .extended_pan_id ?? "" ) ;
4647 } , [ scanIdx ] ) ;
4748
49+ useEffect ( ( ) => {
50+ setHueSerialNumbers (
51+ hueSerialNumbersRaw
52+ ? hueSerialNumbersRaw
53+ . replaceAll ( " " , "" )
54+ . split ( "," )
55+ . map ( ( v ) => Number . parseInt ( v , v . startsWith ( "0x" ) ? 16 : 10 ) )
56+ : [ ] ,
57+ ) ;
58+ } , [ hueSerialNumbersRaw ] ) ;
59+
4860 const data = useMemo ( ( ) : TouchlinkTableData [ ] => {
4961 const renderDevices : TouchlinkTableData [ ] = [ ] ;
5062
@@ -98,11 +110,11 @@ export default function TouchlinkPage() {
98110 serial_numbers : hueSerialNumbers ,
99111 } ,
100112 } ) ;
101- setHueSerialNumbers ( [ ] ) ;
113+ setHueSerialNumbersRaw ( "" ) ;
102114 } , [ scanIdx , hueExtPanId , hueSerialNumbers ] ) ;
103115
104116 const isHueResetValid = useMemo ( ( ) => {
105- if ( hueExtPanId != null && / ^ 0 x [ a - f 0 - 9 ] { 16 } $ / . test ( hueExtPanId ) && Array . isArray ( hueSerialNumbers ) && hueSerialNumbers . length > 0 ) {
117+ if ( ( ! hueExtPanId || / ^ 0 x [ a - f 0 - 9 ] { 16 } $ / . test ( hueExtPanId ) ) && Array . isArray ( hueSerialNumbers ) && hueSerialNumbers . length > 0 ) {
106118 return hueSerialNumbers . every ( ( sn ) => Number . isInteger ( sn ) ) ;
107119 }
108120
@@ -274,28 +286,37 @@ export default function TouchlinkPage() {
274286 buttonTitle = { t ( ( $ ) => $ . philips_hue_reset ) }
275287 title = { t ( ( $ ) => $ . philips_hue_reset ) }
276288 >
289+ { MULTI_INSTANCE && (
290+ < SelectField
291+ name = "scan_idx_picker"
292+ label = { t ( ( $ ) => $ . source , { ns : "common" } ) }
293+ value = { scanIdx }
294+ onChange = { ( e ) => ! e . target . validationMessage && ! ! e . target . value && setScanIdx ( Number . parseInt ( e . target . value , 10 ) ) }
295+ className = "select"
296+ >
297+ < option value = "" disabled >
298+ { t ( ( $ ) => $ . source , { ns : "common" } ) }
299+ </ option >
300+ { API_NAMES . map ( ( name , idx ) => (
301+ < option key = { name } value = { idx } >
302+ { name }
303+ </ option >
304+ ) ) }
305+ </ SelectField >
306+ ) }
277307 < InputField
278308 name = "extended_pan_id"
279309 label = { t ( ( $ ) => $ . extended_pan_id , { ns : "zigbee" } ) }
280310 type = "text"
281- defaultValue = { hueExtPanId }
311+ value = { hueExtPanId }
282312 onChange = { ( e ) => ! e . target . validationMessage && setHueExtPanId ( e . target . value ) }
283- required
284313 />
285314 < InputField
286315 name = "serial_numbers"
287316 label = { t ( ( $ ) => $ . serial_numbers_csv ) }
288317 type = "text"
289- onChange = { ( e ) =>
290- ! e . target . validationMessage &&
291- setHueSerialNumbers (
292- e . target . value
293- . replaceAll ( " " , "" )
294- . split ( "," )
295- . map ( ( v ) => Number . parseInt ( v , v . startsWith ( "0x" ) ? 16 : 10 ) ) ,
296- )
297- }
298- required
318+ value = { hueSerialNumbersRaw }
319+ onChange = { ( e ) => ! e . target . validationMessage && setHueSerialNumbersRaw ( e . target . value ) }
299320 />
300321 </ FloatingCardButton >
301322 </ fieldset >
0 commit comments