@@ -5,18 +5,21 @@ import PropTypes from 'prop-types';
55import { connect } from 'react-redux' ;
66import cx from 'classnames' ;
77import forIn from 'lodash/forIn' ;
8+ import axios from 'axios' ;
89
910import FormControl from '@mui/material/FormControl' ;
1011import FormLabel from '@mui/material/FormLabel' ;
12+ import MuiButton from '@mui/material/Button' ;
1113import Select from 'react-select' ;
1214import ExchangePanel from '../ExchangePanel/exchange-panel' ;
1315import MessagePanel from '../MessagePanel/message-panel' ;
1416
1517import styles from './context-view.css' ;
1618
17- import { selectService } from '../../actions/service-exchange-actions' ;
19+ import { selectService , storeExchange } from '../../actions/service-exchange-actions' ;
1820import { setContextVisibility } from '../../actions/ui-actions' ;
1921import { getServicesByHook } from '../../reducers/helpers/services-filter' ;
22+ import generateJWT from '../../retrieve-data-helpers/jwt-generator' ;
2023
2124const propTypes = {
2225 /**
@@ -48,6 +51,10 @@ const propTypes = {
4851 * Flag to determine if the context view will be visible or not (via the slide out button)
4952 */
5053 isContextVisible : PropTypes . bool . isRequired ,
54+ /**
55+ * Function to store a service exchange (request/response) in the Redux store
56+ */
57+ storeExchange : PropTypes . func . isRequired ,
5158} ;
5259
5360/**
@@ -58,10 +65,18 @@ const propTypes = {
5865export class ContextView extends Component {
5966 constructor ( props ) {
6067 super ( props ) ;
68+ this . state = {
69+ isEditingRequest : false ,
70+ draftRequest : '' ,
71+ } ;
6172 this . onSelectChange = this . onSelectChange . bind ( this ) ;
6273 this . createDropdownServices = this . createDropdownServices . bind ( this ) ;
6374 this . onContextToggle = this . onContextToggle . bind ( this ) ;
6475 this . formatOptionLabel = this . formatOptionLabel . bind ( this ) ;
76+ this . onEditRequest = this . onEditRequest . bind ( this ) ;
77+ this . onCancelEdit = this . onCancelEdit . bind ( this ) ;
78+ this . onDraftChange = this . onDraftChange . bind ( this ) ;
79+ this . onResend = this . onResend . bind ( this ) ;
6580 }
6681
6782 /**
@@ -80,6 +95,53 @@ export class ContextView extends Component {
8095 this . props . toggleContext ( ) ;
8196 }
8297
98+ onEditRequest ( ) {
99+ const serviceInContext = this . props . selectedService || this . props . initialService ;
100+ const serviceExchange = serviceInContext ? this . props . exchanges [ serviceInContext ] : null ;
101+ const request = serviceExchange ? serviceExchange . request : '' ;
102+ const draft = typeof request === 'string' ? request : JSON . stringify ( request , null , 2 ) ;
103+ this . setState ( { isEditingRequest : true , draftRequest : draft } ) ;
104+ }
105+
106+ onCancelEdit ( ) {
107+ this . setState ( { isEditingRequest : false } ) ;
108+ }
109+
110+ onDraftChange ( e ) {
111+ this . setState ( { draftRequest : e . target . value } ) ;
112+ }
113+
114+ async onResend ( ) {
115+ const serviceUrl = this . props . selectedService || this . props . initialService ;
116+ if ( ! serviceUrl ) return ;
117+
118+ let parsedRequest ;
119+ try {
120+ parsedRequest = JSON . parse ( this . state . draftRequest ) ;
121+ } catch ( e ) {
122+ parsedRequest = this . state . draftRequest ;
123+ }
124+
125+ try {
126+ const result = await axios ( {
127+ method : 'post' ,
128+ url : serviceUrl ,
129+ data : parsedRequest ,
130+ headers : {
131+ Accept : 'application/json' ,
132+ Authorization : `Bearer ${ generateJWT ( serviceUrl ) } ` ,
133+ } ,
134+ } ) ;
135+ this . props . storeExchange ( serviceUrl , parsedRequest , result . data , result . status ) ;
136+ } catch ( err ) {
137+ const status = err . response ? err . response . status : 500 ;
138+ const response = err . response ? err . response . data : err . message ;
139+ this . props . storeExchange ( serviceUrl , parsedRequest , response , status ) ;
140+ }
141+
142+ this . setState ( { isEditingRequest : false } ) ;
143+ }
144+
83145 /**
84146 * Create an array of key-value pair objects that React Select component understands
85147 * given the CDS Services allowed to be selected for this hook
@@ -157,11 +219,32 @@ export class ContextView extends Component {
157219 } }
158220 />
159221 </ FormControl >
160- < ExchangePanel
161- panelHeader = " Request"
162- panelText = { serviceExchange ? serviceExchange . request : 'No request made to CDS Service' }
163- isExpanded = { false }
164- />
222+ { this . state . isEditingRequest ? (
223+ < div >
224+ < div style = { { display : 'flex' , justifyContent : 'flex-end' , marginBottom : '8px' , gap : '8px' } } >
225+ < MuiButton variant = "outlined" size = "small" onClick = { this . onCancelEdit } > Cancel</ MuiButton >
226+ < MuiButton variant = "contained" size = "small" onClick = { this . onResend } > Resend</ MuiButton >
227+ </ div >
228+ < textarea
229+ value = { this . state . draftRequest }
230+ onChange = { this . onDraftChange }
231+ className = { styles [ 'edit-textarea' ] }
232+ />
233+ </ div >
234+ ) : (
235+ < div >
236+ < ExchangePanel
237+ panelHeader = " Request"
238+ panelText = { serviceExchange ? serviceExchange . request : 'No request made to CDS Service' }
239+ isExpanded = { false }
240+ />
241+ { serviceExchange && serviceExchange . request && (
242+ < div style = { { textAlign : 'right' , marginTop : '8px' } } >
243+ < MuiButton variant = "outlined" size = "small" onClick = { this . onEditRequest } > Edit Request</ MuiButton >
244+ </ div >
245+ ) }
246+ </ div >
247+ ) }
165248 < ExchangePanel
166249 panelHeader = " Response"
167250 panelText = { serviceExchange ? serviceExchange . response : 'No response made to CDS Service' }
@@ -208,6 +291,9 @@ const mapDispatchToProps = (dispatch) => ({
208291 toggleContext : ( ) => {
209292 dispatch ( setContextVisibility ( ) ) ;
210293 } ,
294+ storeExchange : ( url , request , response , responseStatus ) => {
295+ dispatch ( storeExchange ( url , request , response , responseStatus ) ) ;
296+ } ,
211297} ) ;
212298
213299export default connect ( mapStateToProps , mapDispatchToProps ) ( ContextView ) ;
0 commit comments