@ -971,7 +971,7 @@ function ServiceDataCard(props: { cm: ClientModule; name: string; fieldSpec: Fie
const [ pw , setPw ] = useState ( '' )
const [ pw , setPw ] = useState ( '' )
const [ busy , setBusy ] = useState ( false )
const [ busy , setBusy ] = useState ( false )
const [ editing , setEditing ] = useState ( false )
const [ editing , setEditing ] = useState ( false )
const [ f , setF ] = useState ( { provider : '' , username : '' , remark : '' } )
const [ f , setF ] = useState ( { provider : '' , username : '' , remark : '' , password : '' } )
const [ details , setDetails ] = useState < ServiceDetail [ ] > ( [ ] )
const [ details , setDetails ] = useState < ServiceDetail [ ] > ( [ ] )
const copy = ( text : string , what : string ) = > {
const copy = ( text : string , what : string ) = > {
@ -994,7 +994,7 @@ function ServiceDataCard(props: { cm: ClientModule; name: string; fieldSpec: Fie
. finally ( ( ) = > setBusy ( false ) )
. finally ( ( ) = > setBusy ( false ) )
}
}
const startEdit = ( ) = > {
const startEdit = ( ) = > {
setF ( { provider : cm.provider ? ? '' , username : cm.username ? ? '' , remark : cm.remark ? ? '' } )
setF ( { provider : cm.provider ? ? '' , username : cm.username ? ? '' , remark : cm.remark ? ? '' , password : '' } )
setDetails ( cm . details . map ( ( d ) = > ( { . . . d } ) ) )
setDetails ( cm . details . map ( ( d ) = > ( { . . . d } ) ) )
setEditing ( true )
setEditing ( true )
}
}
@ -1006,6 +1006,8 @@ function ServiceDataCard(props: { cm: ClientModule; name: string; fieldSpec: Fie
patchClientModule ( cm . id , {
patchClientModule ( cm . id , {
provider : f.provider , username : f.username , remark : f.remark ,
provider : f.provider , username : f.username , remark : f.remark ,
details : cleaned.map ( ( d ) = > ( { label : d.label.trim ( ) , value : d.value } ) ) ,
details : cleaned.map ( ( d ) = > ( { label : d.label.trim ( ) , value : d.value } ) ) ,
// Password only when the managerial user typed one (blank = keep current).
. . . ( managerial && f . password . trim ( ) !== '' ? { password : f.password } : { } ) ,
} )
} )
. then ( ( ) = > { toast . ok ( 'Service data saved' ) ; setEditing ( false ) ; props . onChanged ( ) } )
. then ( ( ) = > { toast . ok ( 'Service data saved' ) ; setEditing ( false ) ; props . onChanged ( ) } )
. catch ( ( e : Error ) = > toast . err ( e . message ) )
. catch ( ( e : Error ) = > toast . err ( e . message ) )
@ -1027,6 +1029,12 @@ function ServiceDataCard(props: { cm: ClientModule; name: string; fieldSpec: Fie
< div style = { { display : 'flex' , gap : 10 , flexWrap : 'wrap' , alignItems : 'flex-end' , marginBottom : 8 } } >
< div style = { { display : 'flex' , gap : 10 , flexWrap : 'wrap' , alignItems : 'flex-end' , marginBottom : 8 } } >
< Field label = "Provider" > < input className = "wf" style = { { width : 140 } } value = { f . provider } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , provider : e.target.value } ) ) } / > < / Field >
< Field label = "Provider" > < input className = "wf" style = { { width : 140 } } value = { f . provider } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , provider : e.target.value } ) ) } / > < / Field >
< Field label = "Username" > < input className = "wf mono" style = { { width : 160 } } value = { f . username } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , username : e.target.value } ) ) } / > < / Field >
< Field label = "Username" > < input className = "wf mono" style = { { width : 160 } } value = { f . username } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , username : e.target.value } ) ) } / > < / Field >
{ managerial && (
< Field label = "Password" >
< input className = "wf mono" style = { { width : 160 } } placeholder = { cm . hasPassword ? 'leave blank to keep' : 'set password' }
value = { f . password } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , password : e.target.value } ) ) } / >
< / Field >
) }
< Field label = "Remark" > < input className = "wf" style = { { width : 220 } } value = { f . remark } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , remark : e.target.value } ) ) } / > < / Field >
< Field label = "Remark" > < input className = "wf" style = { { width : 220 } } value = { f . remark } onChange = { ( e ) = > setF ( ( p ) = > ( { . . . p , remark : e.target.value } ) ) } / > < / Field >
< / div >
< / div >
{ details . map ( ( d , i ) = > (
{ details . map ( ( d , i ) = > (