1- import React , { useState } from 'react' ;
1+ import React , { useState , useEffect } from 'react' ;
22import Radio from '@mui/material/Radio' ;
33import RadioGroup from '@mui/material/RadioGroup' ;
44import FormControlLabel from '@mui/material/FormControlLabel' ;
@@ -16,29 +16,51 @@ import Tabs from '@mui/material/Tabs';
1616import Tab from '@mui/material/Tab' ;
1717import Alert from 'AppComponents/Shared/Alert' ;
1818
19- const cache = { } ;
2019/**
2120 * Renders the certificate add/edit page.
2221 * @param {JSON } props Input props form parent components.
2322 * @returns {JSX } Certificate upload/add UI.
2423 */
2524export default function Certificates ( props ) {
2625 const intl = useIntl ( ) ;
27- const { certificates : { type, value } , dispatch, isConfigCert } = props ;
26+ const {
27+ fieldName,
28+ [ fieldName ] : { type, value } ,
29+ dispatch,
30+ isJwksNeeded,
31+ } = props ;
2832 const [ selectedTab , setSelectedTab ] = useState ( 0 ) ;
2933 const [ file , setFile ] = useState ( null ) ;
30- cache [ type ] = value ;
34+ // Keep certificate cache local to this instance
35+ const [ certCache , setCertCache ] = useState ( {
36+ PEM : '' ,
37+ JWKS : '' ,
38+ } ) ;
39+
40+ // Update cache when value changes
41+ useEffect ( ( ) => {
42+ setCertCache ( ( prev ) => ( {
43+ ...prev ,
44+ [ type ] : value ,
45+ } ) ) ;
46+ } , [ type , value ] ) ;
3147
3248 const onDrop = ( acceptedFile ) => {
3349 const reader = new FileReader ( ) ;
3450 setFile ( acceptedFile [ 0 ] ) ;
3551 reader . readAsText ( acceptedFile [ 0 ] , 'UTF-8' ) ;
3652 reader . onload = ( evt ) => {
53+ const newValue = btoa ( evt . target . result ) ;
54+ // Update both cache and parent
55+ setCertCache ( ( prev ) => ( {
56+ ...prev ,
57+ [ type ] : newValue ,
58+ } ) ) ;
3759 dispatch ( {
38- field : 'certificates' ,
60+ field : fieldName ,
3961 value : {
4062 type,
41- value : btoa ( evt . target . result ) ,
63+ value : newValue ,
4264 } ,
4365 } ) ;
4466 } ;
@@ -53,19 +75,26 @@ export default function Certificates(props) {
5375 const handleChange = ( event ) => {
5476 const { value : selected , name } = event . target ;
5577 if ( name === 'certificateType' ) {
78+ // When switching certificate type, use the cached value for that type
5679 dispatch ( {
57- field : 'certificates' ,
80+ field : fieldName ,
5881 value : {
5982 type : selected ,
60- value : cache [ selected ] ,
83+ value : certCache [ selected ] || '' ,
6184 } ,
6285 } ) ;
6386 } else {
87+ // When updating certificate value, update both cache and parent
88+ const newValue = name === 'certificateValueUrl' ? selected : btoa ( selected ) ;
89+ setCertCache ( ( prev ) => ( {
90+ ...prev ,
91+ [ type ] : newValue ,
92+ } ) ) ;
6493 dispatch ( {
65- field : 'certificates' ,
94+ field : fieldName ,
6695 value : {
6796 type,
68- value : name === 'certificateValueUrl' ? selected : btoa ( selected ) ,
97+ value : newValue ,
6998 } ,
7099 } ) ;
71100 }
@@ -75,7 +104,7 @@ export default function Certificates(props) {
75104 } ;
76105 return (
77106 < >
78- { ! isConfigCert && (
107+ { isJwksNeeded && (
79108 < FormControl variant = 'standard' component = 'fieldset' >
80109 < RadioGroup
81110 style = { { flexDirection : 'row' } }
@@ -106,7 +135,7 @@ export default function Certificates(props) {
106135 onChange = { handleChange }
107136 />
108137 ) }
109- { ( isConfigCert || type === 'PEM' ) && (
138+ { ( ! isJwksNeeded || type === 'PEM' ) && (
110139 < >
111140 < AppBar position = 'static' color = 'default' >
112141 < Tabs value = { selectedTab } onChange = { handleTabChange } >
@@ -175,7 +204,13 @@ export default function Certificates(props) {
175204 </ >
176205 ) ;
177206}
207+ Certificates . defaultProps = {
208+ fieldName : 'certificates' ,
209+ isJwksNeeded : false ,
210+ } ;
211+
178212Certificates . propTypes = {
179- certificates : PropTypes . shape ( { } ) . isRequired ,
213+ fieldName : PropTypes . string ,
180214 dispatch : PropTypes . func . isRequired ,
215+ isJwksNeeded : PropTypes . bool ,
181216} ;
0 commit comments