Skip to content

Commit 8cc7f99

Browse files
committed
[new_profile] Use API for candidate creation and swal for success
This updates the candidate creation on the new profile page to se the LORIS API instead of duplicating the logic in PHP. The form already collects the exact data that a POST request to the API requires, but submits it to a different endpoint in a form encoding instead of a json encoding. At the same time, the logic for the response is simplified by using a swal instead of a (very empty looking) new page. swals are already used for errors in the module, just not success. This change simplifies both the code and the UX.
1 parent 973fb26 commit 8cc7f99

File tree

2 files changed

+109
-304
lines changed

2 files changed

+109
-304
lines changed

modules/new_profile/jsx/NewProfileIndex.js

Lines changed: 109 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ class NewProfileIndex extends React.Component {
1919
this.state = {
2020
configData: {},
2121
formData: {},
22-
newData: {},
2322
isLoaded: false,
24-
isCreated: false,
2523
error: false,
2624
submitDisabled: false,
2725
};
@@ -83,33 +81,63 @@ class NewProfileIndex extends React.Component {
8381
e.preventDefault();
8482
const match = this.validateMatchDate();
8583
if (!match) {
86-
this.setState({
87-
isCreated: false,
88-
});
89-
} else {
90-
let formData = this.state.formData;
91-
let formObject = new FormData();
92-
for (let key in formData) {
93-
if (formData[key] !== '') {
94-
formObject.append(key, formData[key]);
95-
}
96-
}
97-
formObject.append('fire_away', 'New Candidate');
84+
return;
85+
}
86+
const formData = this.state.formData;
87+
const configData = this.state.configData;
9888

99-
// disable button to prevent form resubmission.
100-
this.setState({submitDisabled: true});
89+
let candidateObject = {
90+
'Candidate': {
91+
'Project': configData.project[formData.project],
92+
// 'PSCID' : conditionally included below
93+
// 'EDC' : conditionally included below
94+
'DoB': formData.dobDate,
95+
'Sex': formData.sex,
96+
'Site': configData.site[formData.site],
97+
},
98+
};
99+
100+
if (this.state.configData['edc'] === 'true') {
101+
candidateObject.Candidate.EDC = formData.edc;
102+
}
103+
if (this.state.configData['pscidSet'] === 'true') {
104+
candidateObject.Candidate.PSCID = formData.pscid;
105+
}
101106

102-
fetch(this.props.submitURL, {
103-
method: 'POST',
104-
cache: 'no-cache',
105-
credentials: 'same-origin',
106-
body: formObject,
107-
})
108-
.then((resp) => {
109-
if (resp.ok && resp.status === 201) {
110-
resp.json().then((data) => {
111-
this.setState({newData: data});
112-
this.setState({isCreated: true});
107+
// disable button to prevent form resubmission.
108+
this.setState({submitDisabled: true});
109+
110+
fetch(this.props.submitURL, {
111+
method: 'POST',
112+
cache: 'no-cache',
113+
credentials: 'same-origin',
114+
body: JSON.stringify(candidateObject),
115+
})
116+
.then((resp) => {
117+
if (resp.ok && resp.status === 201) {
118+
resp.json().then((data) => {
119+
swal.fire({
120+
type: 'success',
121+
title: 'New Candidate Created',
122+
html: 'DCCID: ' + data.CandID + ' '
123+
+ 'PSCID: ' + data.PSCID + ' ',
124+
confirmButtonText: 'Access Profile',
125+
// Repurpose "cancel" as "recruit another candidate".
126+
// Use the same colour for both buttons, since one
127+
// isn't more "right" than the other.
128+
showCancelButton: true,
129+
cancelButtonColor: '#3085d6',
130+
cancelButtonText: 'Recruit another candidate',
131+
}).then((result) => {
132+
if (result.value === true) {
133+
window.location.href = '/' + data.CandID;
134+
} else {
135+
this.setState({
136+
formData: {},
137+
submitDisabled: false,
138+
});
139+
}
140+
});
113141
});
114142
} else {
115143
resp.json().then((message) => {
@@ -122,7 +150,6 @@ class NewProfileIndex extends React.Component {
122150
.catch((error) => {
123151
console.error(error);
124152
});
125-
}
126153
}
127154

128155
/**
@@ -153,7 +180,6 @@ class NewProfileIndex extends React.Component {
153180
if (!this.state.isLoaded) {
154181
return <Loader/>;
155182
}
156-
let profile = null;
157183
let edc = null;
158184
let pscid = null;
159185
let site = null;
@@ -211,73 +237,59 @@ class NewProfileIndex extends React.Component {
211237
required = {true}
212238
/>;
213239
}
214-
if (!this.state.isCreated) {
215-
profile = (
216-
<FormElement
217-
name = "newProfileForm"
218-
onSubmit = {this.handleSubmit}
219-
>
220-
<DateElement
221-
name = "dobDate"
222-
label = "Date of Birth"
223-
minYear = {minYear}
224-
maxYear = {dobMaxYear}
225-
dateFormat = {dateFormat}
226-
onUserInput = {this.setFormData}
227-
value = {this.state.formData.dobDate}
228-
required = {requireBirthDate}
229-
/>
230-
<DateElement
231-
name = "dobDateConfirm"
232-
label = "Date of Birth Confirm"
233-
minYear = {minYear}
234-
maxYear = {dobMaxYear}
235-
dateFormat = {dateFormat}
236-
onUserInput = {this.setFormData}
237-
value = {this.state.formData.dobDateConfirm}
238-
required = {requireBirthDate}
239-
/>
240-
{edc}
241-
<SelectElement
242-
name = "sex"
243-
label = "Sex"
244-
options = {this.state.configData.sex}
245-
onUserInput = {this.setFormData}
246-
value = {this.state.formData.sex}
247-
required = {true}
248-
/>
249-
{site}
250-
{pscid}
251-
<SelectElement
252-
name = "project"
253-
label = "Project"
254-
options = {this.state.configData.project}
255-
onUserInput = {this.setFormData}
256-
value = {this.state.formData.project}
257-
required = {true}
258-
/>
259-
<ButtonElement
260-
name = "fire_away"
261-
label = "Create"
262-
id = "button"
263-
type = "submit"
264-
disabled={this.state.submitDisabled}
265-
/>
266-
</FormElement>
267-
);
268-
} else {
269-
profile = (
270-
<div>
271-
<p>{'New candidate created. '
272-
+ 'DCCID: ' + this.state.newData.candID + ' '
273-
+ 'PSCID: ' + this.state.newData.pscid + ' '}</p>
274-
<p><a href = {'/' + this.state.newData.candID}>
275-
Access this candidate
276-
</a></p>
277-
<p><a href = "/new_profile/" > Recruit another candidate </a></p>
278-
</div>
279-
);
280-
}
240+
const profile = (
241+
<FormElement
242+
name = "newProfileForm"
243+
onSubmit = {this.handleSubmit}
244+
>
245+
<DateElement
246+
name = "dobDate"
247+
label = "Date of Birth"
248+
minYear = {minYear}
249+
maxYear = {dobMaxYear}
250+
dateFormat = {dateFormat}
251+
onUserInput = {this.setFormData}
252+
value = {this.state.formData.dobDate}
253+
required = {requireBirthDate}
254+
/>
255+
<DateElement
256+
name = "dobDateConfirm"
257+
label = "Date of Birth Confirm"
258+
minYear = {minYear}
259+
maxYear = {dobMaxYear}
260+
dateFormat = {dateFormat}
261+
onUserInput = {this.setFormData}
262+
value = {this.state.formData.dobDateConfirm}
263+
required = {requireBirthDate}
264+
/>
265+
{edc}
266+
<SelectElement
267+
name = "sex"
268+
label = "Sex"
269+
options = {this.state.configData.sex}
270+
onUserInput = {this.setFormData}
271+
value = {this.state.formData.sex}
272+
required = {true}
273+
/>
274+
{site}
275+
{pscid}
276+
<SelectElement
277+
name = "project"
278+
label = "Project"
279+
options = {this.state.configData.project}
280+
onUserInput = {this.setFormData}
281+
value = {this.state.formData.project}
282+
required = {true}
283+
/>
284+
<ButtonElement
285+
name = "fire_away"
286+
label = "Create"
287+
id = "button"
288+
type = "submit"
289+
disabled={this.state.submitDisabled}
290+
/>
291+
</FormElement>
292+
);
281293
return (
282294
<FieldsetElement legend={'Create a New Profile'}>
283295
{profile}
@@ -289,7 +301,7 @@ window.addEventListener('load', () => {
289301
ReactDOM.render(
290302
<NewProfileIndex
291303
dataURL = {`${loris.BaseURL}/new_profile/?format=json`}
292-
submitURL = {`${loris.BaseURL}/new_profile/`}
304+
submitURL = {`${loris.BaseURL}/api/v0.0.3/candidates/`}
293305
hasPermission = {loris.userHasPermission}
294306
/>,
295307
document.getElementById('lorisworkspace')

0 commit comments

Comments
 (0)