this.props.appState.getOffersList()}
+ getOffers={() => {
+ let session = this.props.appState.getSelectedSession();
+ if (session != '') {
+ return this.props.appState
+ .getOffersList()
+ .filter(offer => offer.get('session') == session);
+ }
+ return this.props.appState.getOffersList();
+ }}
getSelectedSortFields={() => this.props.appState.getSorts()}
getSelectedFilters={() => this.props.appState.getFilters()}
/>
@@ -278,7 +288,10 @@ const OffersMenu = props =>
const CommMenu = props =>
-
+
+
;
diff --git a/app/javascript/cp/components/navbar.js b/app/javascript/cp/components/navbar.js
index f1d04610..971b0022 100644
--- a/app/javascript/cp/components/navbar.js
+++ b/app/javascript/cp/components/navbar.js
@@ -1,7 +1,16 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
+import {
+ Navbar,
+ Nav,
+ NavItem,
+ NavDropdown,
+ MenuItem,
+ FormGroup,
+ ControlLabel,
+ FormControl,
+} from 'react-bootstrap';
/*** Navbar components ***/
@@ -34,7 +43,9 @@ const Auth = props =>
-
-
- Logout
-
+ Logout
;
/*** Navbar ***/
diff --git a/app/javascript/cp/components/sessionsForm.js b/app/javascript/cp/components/sessionsForm.js
index 542fcc83..120056ca 100644
--- a/app/javascript/cp/components/sessionsForm.js
+++ b/app/javascript/cp/components/sessionsForm.js
@@ -1,41 +1,79 @@
import React from 'react';
-import { Panel, Tabs, Tab, Form, InputGroup, FormGroup, FormControl } from 'react-bootstrap';
+import { Panel, Form, FormGroup, ControlLabel, InputGroup, FormControl } from 'react-bootstrap';
class SessionsForm extends React.Component {
render() {
return (
-
-
- Sessions} disabled />
- {this.props.appState.getSessionsList().map(session =>
-
-
-
- )}
-
-
+
+
+
);
}
}
diff --git a/app/javascript/cp/fetch.js b/app/javascript/cp/fetch.js
index e51f7dbf..1c20e6c2 100644
--- a/app/javascript/cp/fetch.js
+++ b/app/javascript/cp/fetch.js
@@ -4,9 +4,9 @@ import { appState } from './appState.js';
/* General helpers */
-function defaultFailure(resp) {
- appState.notify('Action Failed: ' + resp.statusText);
- return Promise.reject(resp);
+function defaultFailure(text) {
+ appState.alert('Action Failed: ' + text);
+ return Promise.reject();
}
// extract and display a message which is sent in the (JSON) body of a response
@@ -20,64 +20,87 @@ function showMessageInJsonBody(resp) {
}
}
-function fetchHelper(URL, init, success, failure = defaultFailure) {
- return fetch(URL, init)
- .then(function(response) {
- if (response.ok) {
- return success(response);
+function fetchHelper(URL, init) {
+ return fetch(URL, init).then(
+ function(resp) {
+ if (resp.ok) {
+ return Promise.resolve(resp);
}
- return failure(response);
+ return Promise.reject(resp);
+ },
+ function(error) {
+ appState.alert('' + init.method + ' error ' + URL + ': ' + error.message);
+ return Promise.reject(error);
+ }
+ );
+}
+
+// fetching for 'can-*' batch methods
+function fetchCheckHelper(URL, body) {
+ return fetch(URL, {
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ method: 'POST',
+ body: JSON.stringify(body),
+ })
+ .then(function(resp) {
+ if (resp.ok || resp.status == 404) {
+ return Promise.resolve(resp);
+ }
+ return Promise.reject(resp);
})
.catch(function(error) {
- appState.notify('Error: ' + URL + ' ' + error.message);
+ appState.alert('' + init.method + ' error ' + URL + ': ' + error.message);
return Promise.reject(error);
});
}
-function getHelper(URL, success, failure) {
- let init = {
+function getHelper(URL) {
+ return fetchHelper(URL, {
headers: {
Accept: 'application/json',
},
method: 'GET',
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
-function postHelper(URL, body, success, failure) {
- let init = {
+function postHelper(URL, body) {
+ return fetchHelper(URL, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
},
method: 'POST',
body: JSON.stringify(body),
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
-function deleteHelper(URL, success, failure) {
- return fetchHelper(URL, { method: 'DELETE' }, success, failure);
+function deleteHelper(URL) {
+ return fetchHelper(URL, { method: 'DELETE' });
}
-function putHelper(URL, body, success, failure) {
- let init = {
+function putHelper(URL, body) {
+ return fetchHelper(URL, {
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
method: 'PUT',
body: JSON.stringify(body),
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
/* Resource GETters */
-const getOffers = () => getHelper('/offers', resp => resp.json()).then(onFetchOffersSuccess);
-const getSessions = () => getHelper('/sessions', resp => resp.json()).then(onFetchSessionsSuccess);
+const getOffers = () =>
+ getHelper('/offers').then(resp => resp.json()).then(onFetchOffersSuccess).catch(defaultFailure);
+
+const getSessions = () =>
+ getHelper('/sessions')
+ .then(resp => resp.json())
+ .then(onFetchSessionsSuccess)
+ .catch(defaultFailure);
/* Success callbacks for resource GETters */
@@ -100,6 +123,7 @@ function onFetchOffersSuccess(resp) {
ddahStatus: offer.ddah_status,
sentAt: offer.send_date,
printedAt: offer.print_time,
+ link: offer.link,
};
});
@@ -152,72 +176,197 @@ function fetchAll() {
function importAssignments() {
appState.setImporting(true);
- return postHelper(
- '/import/locked-assignments',
- {},
+ postHelper('/import/locked-assignments', {}).then(
() => {
appState.setImporting(false, true);
- fetchAll();
+
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
},
- showMessageInJsonBody
- ).catch(() => appState.setImporting(false));
+ resp => {
+ appState.setImporting(false);
+ showMessageInJsonBody(resp);
+ }
+ );
}
// send CHASS offers data
function importOffers(data) {
appState.setImporting(true);
- return postHelper('/import/offers', { chass_offers: data }, () => {
- appState.setImporting(false, true);
- fetchAll();
- }).catch(() => appState.setImporting(false));
-}
+ postHelper('/import/offers', { chass_offers: data }).then(
+ () => {
+ appState.setImporting(false, true);
-// send contracts
-function sendContracts(offers) {
- return postHelper(
- '/offers/send-contracts',
- { offers: offers },
- fetchAll,
- showMessageInJsonBody
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ },
+ resp => {
+ appState.setImporting(false);
+ showMessageInJsonBody(resp);
+ }
);
}
-// email applicants
-function email(emails) {
- let ref =
- emails.length == 1
- ? 'mailto:' + emails[0] // if there is only a single recipient, send normally
- : 'mailto:?bcc=' + emails.join(';'); // if there are multiple recipients, bcc all
-
- var a = document.createElement('a');
- a.href = ref;
- a.click();
+// send contracts
+function sendContracts(offers) {
+ let validOffers = offers;
+
+ // check which contracts can be sent
+ fetchCheckHelper('/offers/can-send-contract', { contracts: offers })
+ .catch(defaultFailure)
+ .then(resp => {
+ if (resp.status == 404) {
+ // some contracts cannot be sent
+ return resp.json().then(res => {
+ let invalidOffers = res.invalid_offers;
+ invalidOffers.forEach(offer => {
+ appState.alert('Error: Cannot nag send contract for offer ' + offer);
+ // remove invalid offer(s) from offer list
+ validOffers.splice(validOffers.indexOf(offer), 1);
+ });
+
+ if (validOffers.length == 0) {
+ return Promise.reject();
+ }
+ }, defaultFailure);
+ }
+ })
+ // send offers to valid offers
+ .then(() => postHelper('/offers/send-contracts', { offers: offers }))
+ .then(() => {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ });
}
// nag applicants
function nag(offers) {
- return postHelper('/offers/nag', { contracts: offers }, fetchAll, showMessageInJsonBody);
+ let validOffers = offers;
+
+ // check which applicants can be nagged
+ fetchCheckHelper('/offers/can-nag', { contracts: offers })
+ .catch(defaultFailure)
+ .then(resp => {
+ if (resp.status == 404) {
+ // some contracts cannot be sent
+ return resp.json().then(res => {
+ let invalidOffers = res.invalid_offers;
+ invalidOffers.forEach(offer => {
+ appState.alert('Error: Cannot nag applicant about offer ' + offer);
+ // remove invalid offer(s) from offer list
+ validOffers.splice(validOffers.indexOf(offer), 1);
+ });
+
+ if (validOffers.length == 0) {
+ return Promise.reject();
+ }
+ }, defaultFailure);
+ }
+ })
+ // nag valid offers
+ .then(() => postHelper('/offers/nag', { contracts: validOffers }))
+ .then(() => {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ });
}
// mark contracts as hr_processed
function setHrProcessed(offers) {
- return putHelper(
- '/offers/batch-update',
- { offers: offers, hr_status: 'Processed' },
- fetchAll,
- showMessageInJsonBody
- );
+ let validOffers = offers;
+
+ // check which offers can be marked as hr_processed
+ fetchCheckHelper('/offers/can-hr-update', { offers: offers })
+ .catch(defaultFailure)
+ .then(resp => {
+ if (resp.status == 404) {
+ // some offers cannot be updated
+ return resp.json().then(res => {
+ let invalidOffers = res.invalid_offers;
+ invalidOffers.forEach(offer => {
+ appState.alert(
+ 'Error: Cannot mark offer ' + offer + ' as HR processed'
+ );
+ // remove invalid offer(s) from offer list
+ validOffers.splice(validOffers.indexOf(offer), 1);
+ });
+
+ if (validOffers.length == 0) {
+ return Promise.reject();
+ }
+ }, defaultFailure);
+ }
+ })
+ // update valid offers
+ .then(() => putHelper('/offers/batch-update', { offers: offers, hr_status: 'Processed' }))
+ .then(() => {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ });
}
// mark contracts as ddah_accepted
function setDdahAccepted(offers) {
- return putHelper(
- '/offers/batch-update',
- { offers: offers, ddah_status: 'Accepted' },
- fetchAll,
- showMessageInJsonBody
- );
+ let validOffers = offers;
+
+ // check which offers can be marked as ddah_accepted
+ fetchCheckHelper('/offers/can-ddah-update', { offers: offers })
+ .catch(defaultFailure)
+ .then(resp => {
+ if (resp.status == 404) {
+ // some offers cannot be updated
+ return resp.json().then(res => {
+ let invalidOffers = res.invalid_offers;
+ invalidOffers.forEach(offer => {
+ appState.alert(
+ 'Error: Cannot mark offer ' + offer + ' as DDAH accepted'
+ );
+ // remove invalid offer(s) from offer list
+ validOffers.splice(validOffers.indexOf(offer), 1);
+ });
+ if (validOffers.length == 0) {
+ return Promise.reject();
+ }
+ }, defaultFailure);
+ }
+ })
+ // update valid offers
+ .then(() => putHelper('/offers/batch-update', { offers: offers, ddah_status: 'Accepted' }))
+ .then(() => {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ });
}
// show the contract for this offer in a new window, as an applicant would see it
@@ -227,66 +376,113 @@ function showContractApplicant(offer) {
// show the contract for this offer in a new window, as HR would see it
function showContractHr(offer) {
- return postHelper('/offers/print', { contracts: [offer], update: false }, resp =>
- resp.blob()
- ).then(blob => {
- let fileURL = URL.createObjectURL(blob);
- let contractWindow = window.open(fileURL);
- contractWindow.onclose = () => URL.revokeObjectURL(fileURL);
- });
+ postHelper('/offers/print', { contracts: [offer], update: false })
+ .then(resp => resp.blob())
+ .then(blob => {
+ let fileURL = URL.createObjectURL(blob);
+ let contractWindow = window.open(fileURL);
+ contractWindow.onclose = () => URL.revokeObjectURL(fileURL);
+ })
+ .catch(defaultFailure);
}
// withdraw offers
function withdrawOffers(offers) {
// create an array of promises for each offer being withdrawn
- return Promise.all(
- offers.map(offer =>
- postHelper(
- '/offers/' + offer + '/decision/withdraw',
- {},
- resp => resp,
- showMessageInJsonBody
- )
+ // force each promise to resolve so that we can see which failed
+ let promises = offers.map(offer =>
+ postHelper('/offers/' + offer + '/decision/withdraw', {}).then(
+ resp => Promise.resolve(resp),
+ resp => Promise.resolve(resp)
)
- ).then(fetchAll);
+ );
+
+ Promise.all(promises).then(responses =>
+ responses.forEach(resp => {
+ if (resp.ok) {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
+ } else {
+ showMessageInJsonBody(resp);
+ }
+ })
+ );
}
// print contracts
function print(offers) {
- return postHelper(
- '/offers/print',
- { contracts: offers, update: true },
- resp => resp.blob(),
- showMessageInJsonBody
- ).then(blob => {
+ let validOffers = offers;
+
+ // check which contracts can be printed
+ let printPromise = fetchCheckHelper('/offers/can-print', { contracts: offers })
+ .catch(defaultFailure)
+ .then(resp => {
+ if (resp.status == 404) {
+ // some contracts cannot be printed
+ return resp.json().then(res => {
+ let invalidOffers = res.invalid_offers;
+ invalidOffers.forEach(offer => {
+ appState.alert('Error: Cannot print contract for offer ' + offer);
+ // remove invalid offer(s) from offer list
+ validOffers.splice(validOffers.indexOf(offer), 1);
+ });
+
+ if (validOffers.length == 0) {
+ return Promise.reject();
+ }
+ }, defaultFailure);
+ }
+ })
+ // print valid offers
+ .then(() => postHelper('/offers/print', { contracts: validOffers, update: true }))
+ .then(resp => resp.blob().catch(defaultFailure));
+
+ printPromise.then(blob => {
let fileURL = URL.createObjectURL(blob);
let pdfWindow = window.open(fileURL);
pdfWindow.onclose = () => URL.revokeObjectURL(fileURL);
pdfWindow.document.onload = pdfWindow.print();
+ });
- return fetchAll();
+ printPromise.then(() => {
+ appState.setFetchingOffersList(true);
+ getOffers()
+ .then(offers => {
+ appState.setOffersList(fromJS(offers));
+ appState.setFetchingOffersList(false, true);
+ })
+ .catch(() => appState.setFetchingOffersList(false));
});
}
-/*
- function updateSession(input, id){
- let data = {pay: input.value};
- let init = {
- headers: {
- 'Content-Type': 'application/json; charset=utf-8',
- },
- method: 'PUT',
- body: JSON.stringify(data)
- };
- fetchHelper("/sessions/"+id, init, "Pay updated");
- }*/
+// change session pay
+function updateSessionPay(session, pay) {
+ putHelper('/sessions/' + session, { pay: pay }).then(
+ () => {
+ appState.setFetchingSessionsList(true);
+ getSessions()
+ .then(sessions => {
+ appState.setSessionsList(fromJS(sessions));
+ appState.setFetchingSessionsList(false, true);
+ })
+ .catch(() => appState.setFetchingSessionsList(false));
+ },
+ resp => {
+ showMessageInJsonBody(resp);
+ }
+ );
+}
export {
fetchAll,
importOffers,
importAssignments,
sendContracts,
- email,
nag,
setHrProcessed,
setDdahAccepted,
@@ -294,4 +490,5 @@ export {
showContractHr,
withdrawOffers,
print,
+ updateSessionPay,
};
diff --git a/app/javascript/tapp/appState.js b/app/javascript/tapp/appState.js
index 4e968246..fa75f1a9 100644
--- a/app/javascript/tapp/appState.js
+++ b/app/javascript/tapp/appState.js
@@ -569,7 +569,7 @@ class AppState {
addInstructor(courseId, instructorId) {
let val = this.getCoursesList().get(courseId.toString()).get('instructors').toJS();
val.push(parseInt(instructorId));
- fetch.updateCourse(courseId, { instructors: val }, 'instructors');
+ fetch.updateCourse(courseId, { instructors: val });
}
// check if any data is being fetched
@@ -833,7 +833,7 @@ class AppState {
// get a sorted list of course codes
getCourseCodes() {
- return this.getCoursesList().valueSeq().map(course => course.get('code')).sort();
+ return this.getCoursesList().map(course => course.get('code')).flip().keySeq().sort();
}
getCourseCodeById(course) {
@@ -886,7 +886,7 @@ class AppState {
importEnrolment(data) {
fetch.importEnrolment(data);
}
-
+
importing() {
return this.get('importing') > 0;
}
@@ -934,7 +934,7 @@ class AppState {
// thinks they are strings
let val = this.getCoursesList().get(courseId.toString()).get('instructors').toJS();
val.splice(index, 1);
- fetch.updateCourse(courseId, { instructors: val }, 'instructors');
+ fetch.updateCourse(courseId, { instructors: val });
}
setApplicantsList(list) {
@@ -1073,9 +1073,9 @@ class AppState {
fetch.unlockAssignment(applicant, assignment);
}
- updateCourse(courseId, val, props) {
+ updateCourse(courseId, val, attr) {
let data = {};
- switch (props) {
+ switch (attr) {
case 'estimatedPositions':
data['estimated_count'] = val;
break;
@@ -1098,7 +1098,7 @@ class AppState {
data['num_waitlisted'] = val;
break;
}
- fetch.updateCourse(courseId, data, props);
+ fetch.updateCourse(courseId, data);
}
}
diff --git a/app/javascript/tapp/fetch.js b/app/javascript/tapp/fetch.js
index e823dbf3..fda5321f 100644
--- a/app/javascript/tapp/fetch.js
+++ b/app/javascript/tapp/fetch.js
@@ -3,9 +3,9 @@ import { appState } from './appState.js';
/* General helpers */
-function defaultFailure(resp) {
- appState.notify('Action Failed: ' + resp.statusText);
- return Promise.reject(resp);
+function defaultFailure(text) {
+ appState.alert('Action Failed: ' + text);
+ return Promise.reject();
}
// extract and display a message which is sent in the (JSON) body of a response
@@ -19,77 +19,85 @@ function showMessageInJsonBody(resp) {
}
}
-function fetchHelper(URL, init, success, failure = defaultFailure) {
+function fetchHelper(URL, init) {
return fetch(URL, init)
- .then(function(response) {
- if (response.ok) {
- // parse the body of the response as JSON
- if (['GET', 'POST'].includes(init.method)) {
- return response.json().then(resp => success(resp));
- }
-
- return success(response);
+ .then(function(resp) {
+ if (resp.ok) {
+ return Promise.resolve(resp);
}
-
- return failure(response);
+ return Promise.reject(resp);
})
.catch(function(error) {
- appState.notify('Error: ' + URL + ' ' + error.message);
+ appState.alert('' + init.method + ' error ' + URL + ': ' + error.message);
return Promise.reject(error);
});
}
-function getHelper(URL, success, failure) {
- let init = {
+function getHelper(URL) {
+ return fetchHelper(URL, {
headers: {
Accept: 'application/json',
},
method: 'GET',
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
-function postHelper(URL, body, success, failure) {
- let init = {
+function postHelper(URL, body) {
+ return fetchHelper(URL, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
},
method: 'POST',
body: JSON.stringify(body),
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
-function deleteHelper(URL, success, failure) {
- return fetchHelper(URL, { method: 'DELETE' }, success, failure);
+function deleteHelper(URL) {
+ return fetchHelper(URL, { method: 'DELETE' });
}
-function putHelper(URL, body, success, failure) {
- let init = {
+function putHelper(URL, body) {
+ return fetchHelper(URL, {
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
method: 'PUT',
body: JSON.stringify(body),
- };
-
- return fetchHelper(URL, init, success, failure);
+ });
}
/* Resource GETters */
-const getApplicants = () => getHelper('/applicants', onFetchApplicantsSuccess);
-
-const getApplications = () => getHelper('/applications', onFetchApplicationsSuccess);
-
-const getCourses = () => getHelper('/positions', onFetchCoursesSuccess);
-
-const getAssignments = () => getHelper('/assignments', onFetchAssignmentsSuccess);
-
-const getInstructors = () => getHelper('/instructors', onFetchInstructorsSuccess);
+const getApplicants = () =>
+ getHelper('/applicants')
+ .then(resp => resp.json())
+ .then(onFetchApplicantsSuccess)
+ .catch(defaultFailure);
+
+const getApplications = () =>
+ getHelper('/applications')
+ .then(resp => resp.json())
+ .then(onFetchApplicationsSuccess)
+ .catch(defaultFailure);
+
+const getCourses = () =>
+ getHelper('/positions')
+ .then(resp => resp.json())
+ .then(onFetchCoursesSuccess)
+ .catch(defaultFailure);
+
+const getAssignments = () =>
+ getHelper('/assignments')
+ .then(resp => resp.json())
+ .then(onFetchAssignmentsSuccess)
+ .catch(defaultFailure);
+
+const getInstructors = () =>
+ getHelper('/instructors')
+ .then(resp => resp.json())
+ .then(onFetchInstructorsSuccess)
+ .catch(defaultFailure);
/* Success callbacks for resource GETters */
@@ -298,158 +306,161 @@ function fetchAll() {
// create a new assignment
function postAssignment(applicant, course, hours) {
- appState.setFetchingAssignmentsList(true);
-
- return postHelper(
- '/applicants/' + applicant + '/assignments',
- { position_id: course, hours: hours },
- getAssignments
- )
- .then(assignments => {
- appState.setAssignmentsList(assignments);
- appState.setFetchingAssignmentsList(false, true);
- })
- .catch(() => appState.setFetchingAssignmentsList(false));
+ postHelper('/applicants/' + applicant + '/assignments', {
+ position_id: course,
+ hours: hours,
+ }).then(() => {
+ appState.setFetchingAssignmentsList(true);
+ getAssignments()
+ .then(assignments => {
+ appState.setAssignmentsList(assignments);
+ appState.setFetchingAssignmentsList(false, true);
+ })
+ .catch(() => appState.setFetchingAssignmentsList(false));
+ });
}
// remove an assignment
function deleteAssignment(applicant, assignment) {
- appState.setFetchingAssignmentsList(true);
-
- return deleteHelper('/applicants/' + applicant + '/assignments/' + assignment, getAssignments)
- .then(assignments => {
- appState.setAssignmentsList(assignments);
- appState.setFetchingAssignmentsList(false, true);
- })
- .catch(() => appState.setFetchingAssignmentsList(false));
+ deleteHelper('/applicants/' + applicant + '/assignments/' + assignment).then(() => {
+ appState.setFetchingAssignmentsList(true);
+ getAssignments()
+ .then(assignments => {
+ appState.setAssignmentsList(assignments);
+ appState.setFetchingAssignmentsList(false, true);
+ })
+ .catch(() => appState.setFetchingAssignmentsList(false));
+ });
}
// add/update the notes for an applicant
function noteApplicant(applicant, notes) {
- appState.setFetchingApplicantsList(true);
-
- return putHelper('/applicants/' + applicant, { commentary: notes }, getApplicants)
- .then(applicants => {
- appState.setApplicantsList(applicants);
- appState.setFetchingApplicantsList(false, true);
- })
- .catch(() => appState.setFetchingApplicantsList(false));
+ putHelper('/applicants/' + applicant, { commentary: notes }).then(() => {
+ appState.setFetchingApplicantsList(true);
+ getApplicants()
+ .then(applicants => {
+ appState.setApplicantsList(applicants);
+ appState.setFetchingApplicantsList(false, true);
+ })
+ .catch(() => appState.setFetchingApplicantsList(false));
+ });
}
// update the number of hours for an assignment
function updateAssignmentHours(applicant, assignment, hours) {
- appState.setFetchingAssignmentsList(true);
-
- return putHelper(
- '/applicants/' + applicant + '/assignments/' + assignment,
- { hours: hours },
- getAssignments
- )
- .then(assignments => {
- appState.setAssignmentsList(assignments);
- appState.setFetchingAssignmentsList(false, true);
- })
- .catch(() => appState.setFetchingAssignmentsList(false));
+ putHelper('/applicants/' + applicant + '/assignments/' + assignment, {
+ hours: hours,
+ }).then(() => {
+ appState.setFetchingAssignmentsList(true);
+ getAssignments()
+ .then(assignments => {
+ appState.setAssignmentsList(assignments);
+ appState.setFetchingAssignmentsList(false, true);
+ })
+ .catch(() => appState.setFetchingAssignmentsList(false));
+ });
}
// update attribute(s) of a course
-function updateCourse(courseId, data, attr) {
- appState.setFetchingCoursesList(true);
-
- return putHelper('/positions/' + courseId, data, getCourses)
- .then(courses => {
- appState.setCoursesList(courses);
- appState.setFetchingCoursesList(false, true);
- })
- .catch(() => appState.setFetchingCoursesList(false));
+function updateCourse(courseId, data) {
+ putHelper('/positions/' + courseId, data).then(() => {
+ appState.setFetchingCoursesList(true);
+ getCourses()
+ .then(courses => {
+ appState.setCoursesList(courses);
+ appState.setFetchingCoursesList(false, true);
+ })
+ .catch(() => appState.setFetchingCoursesList(false));
+ });
}
// send CHASS data
function importChass(data) {
appState.setImporting(true);
- return postHelper(
- '/import/chass',
- { chass_json: data },
+ postHelper('/import/chass', { chass_json: data }).then(
() => {
appState.setImporting(false, true);
fetchAll();
},
- showMessageInJsonBody
- ).catch(() => appState.setImporting(false));
+ resp => {
+ appState.setImporting(false);
+ showMessageInJsonBody(resp);
+ }
+ );
}
// send enrolment data
function importEnrolment(data) {
appState.setImporting(true);
- appState.setFetchingCoursesList(true);
- return postHelper(
- '/import/enrollment',
- { enrollment_data: data },
- resp => {
- showMessageInJsonBody(resp);
+ postHelper('/import/enrollment', { enrollment_data: data }).then(
+ () => {
appState.setImporting(false, true);
+
+ appState.setFetchingCoursesList(true);
+ getCourses()
+ .then(courses => {
+ appState.setCoursesList(courses);
+ appState.setFetchingCoursesList(false, true);
+ })
+ .catch(() => appState.setFetchingCoursesList(false));
},
resp => {
- showMessageInJsonBody(resp);
appState.setImporting(false);
+ showMessageInJsonBody(resp);
}
- )
- .then(getCourses)
- .then(courses => {
- appState.setCoursesList(courses);
- appState.setFetchingCoursesList(false, true);
- })
- .catch(() => appState.setFetchingCoursesList(false));
+ );
}
// unlock a single assignment
function unlockAssignment(applicant, assignment) {
- appState.setFetchingAssignmentsList(true);
-
- return putHelper(
- '/applicants/' + applicant + '/assignments/' + assignment,
- { export_date: null },
- getAssignments
- )
- .then(assignments => {
- appState.setAssignmentsList(assignments);
- appState.setFetchingAssignmentsList(false, true);
- })
- .catch(() => appState.setFetchingAssignmentsList(false));
+ putHelper('/applicants/' + applicant + '/assignments/' + assignment, {
+ export_date: null,
+ }).then(() => {
+ appState.setFetchingAssignmentsList(true);
+ getAssignments()
+ .then(assignments => {
+ appState.setAssignmentsList(assignments);
+ appState.setFetchingAssignmentsList(false, true);
+ })
+ .catch(() => appState.setFetchingAssignmentsList(false));
+ });
}
// export offers from CHASS (locking the corresponding assignments)
function exportOffers(round) {
- appState.setFetchingAssignmentsList(true);
+ let exportPromise = fetchHelper('/export/chass/' + round, {}).catch(defaultFailure);
let filename;
- return (
- fetchHelper('/export/chass/' + round, {}, response => {
+ exportPromise
+ .then(resp => {
// extract the filename from the response headers
- filename = response.headers.get('Content-Disposition').match(/filename="(.*)"/)[1];
+ filename = resp.headers.get('Content-Disposition').match(/filename="(.*)"/)[1];
// parse the response body as a blob
- return response.blob();
+ return resp.blob();
})
- // create a URL for the object body of the response
- .then(blob => URL.createObjectURL(blob))
- .then(url => {
- // associate the download with an anchor tag
- var a = document.createElement('a');
- a.href = url;
- a.download = filename;
- // trigger a click -> download
- a.click();
- URL.revokeObjectURL(url);
- })
- .then(getAssignments)
+ // create a URL for the object body of the response
+ .then(blob => URL.createObjectURL(blob))
+ .then(url => {
+ // associate the download with an anchor tag
+ var a = document.createElement('a');
+ a.href = url;
+ a.download = filename;
+ // trigger a click -> download
+ a.click();
+ URL.revokeObjectURL(url);
+ });
+
+ exportPromise.then(() => {
+ appState.setFetchingAssignmentsList(true);
+ getAssignments()
.then(assignments => {
appState.setAssignmentsList(assignments);
appState.setFetchingAssignmentsList(false, true);
})
- .catch(() => appState.setFetchingAssignmentsList(false))
- );
+ .catch(() => appState.setFetchingAssignmentsList(false));
+ });
}
export {