From 65c0ff8e9eea59914345742e5479d331845dd302 Mon Sep 17 00:00:00 2001 From: Shreya Pandit Date: Fri, 24 Mar 2023 00:17:48 +0200 Subject: [PATCH 1/3] changed nomination wording for journal events --- .../components/ApplicationForm.js | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/webapp/src/pages/applicationForm/components/ApplicationForm.js b/webapp/src/pages/applicationForm/components/ApplicationForm.js index c12bb1a44..a38957fd9 100644 --- a/webapp/src/pages/applicationForm/components/ApplicationForm.js +++ b/webapp/src/pages/applicationForm/components/ApplicationForm.js @@ -21,6 +21,7 @@ import AnswerValue from '../../../components/answerValue' import FormSelectOther from "../../../components/form/FormSelectOther"; import FormMultiCheckboxOther from "../../../components/form/FormMultiCheckboxOther"; import FormCheckbox from "../../../components/form/FormCheckbox"; +import { eventService } from "../../../services/events"; const baseUrl = process.env.REACT_APP_API_URL; @@ -1009,6 +1010,14 @@ class ApplicationListComponent extends Component { } } + componentDidMount() { + eventService.getEvent(this.props.formSpec.event_id).then(response => { + this.setState({ + event_type: response.event.event_type + }); + })}; + + getCandidate = (allQuestions, response) => { const nominating_capacity = answerByQuestionKey("nominating_capacity", allQuestions, response.answers); if (nominating_capacity === "other") { @@ -1016,7 +1025,7 @@ class ApplicationListComponent extends Component { let lastname = answerByQuestionKey("nomination_lastname", allQuestions, response.answers); return firstname + " " + lastname; } - return this.props.t("Self Nomination"); + return (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission " + response.id) : this.props.t("Self Nomination"); } getStatus = (response) => { @@ -1039,12 +1048,14 @@ class ApplicationListComponent extends Component { render() { let allQuestions = _.flatMap(this.props.formSpec.sections, s => s.questions); + let title = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Your Submissions") : this.props.t("Your Nominations"); + let firstColumn = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission") : this.props.t("Nominee"); return
-

{this.props.t("Your Nominations")}

+

{title}

- + @@ -1084,9 +1095,10 @@ class ApplicationForm extends Component { const eventId = this.props.event ? this.props.event.id : 0; Promise.all([ applicationFormService.getForEvent(eventId), - applicationFormService.getResponse(eventId) + applicationFormService.getResponse(eventId), + eventService.getEvent(eventId) ]).then(responses => { - let [formResponse, responseResponse] = responses; + let [formResponse, responseResponse, eventResponse] = responses; let selectFirstResponse = !formResponse.formSpec.nominations && responseResponse.response.length > 0; this.setState({ formSpec: formResponse.formSpec, @@ -1095,7 +1107,8 @@ class ApplicationForm extends Component { errorMessage: (formResponse.error + " " + responseResponse.error).trim(), isLoading: false, selectedResponse: selectFirstResponse ? responseResponse.response[0] : null, - responseSelected: selectFirstResponse + responseSelected: selectFirstResponse, + event_type: eventResponse.event.event_type }); }); } @@ -1132,9 +1145,10 @@ class ApplicationForm extends Component { } if (formSpec.nominations && responses.length > 0 && !responseSelected) { + let newForm = (this.props.event.event_type ==='JOURNAL' || this.props.event.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("New Submission") + " " : this.props.t("New Nomination") + " "; return

- +
} else { From 91d391ef7491bd7f9ed30a3b3eb629e943ab7cb7 Mon Sep 17 00:00:00 2001 From: Shreya Pandit Date: Mon, 27 Mar 2023 12:57:07 +0200 Subject: [PATCH 2/3] added translation --- webapp/public/locales/en/translation.json | 3 +++ webapp/public/locales/fr/translation.json | 3 +++ .../src/pages/applicationForm/components/ApplicationForm.js | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/webapp/public/locales/en/translation.json b/webapp/public/locales/en/translation.json index b5d76a141..2e3d23c29 100644 --- a/webapp/public/locales/en/translation.json +++ b/webapp/public/locales/en/translation.json @@ -119,8 +119,11 @@ "View": "View", "Your Nominations": "Your Nominations", "Nominee": "Nominee", + "Your Submissions": "Your Submissions", + "Submission": "Submission", "Status": "Status", "New Nomination": "New Nomination", + "New Submission": "New Submission", "Title": "Title", "Email": "Email", "Relation": "Relation", diff --git a/webapp/public/locales/fr/translation.json b/webapp/public/locales/fr/translation.json index e867a8096..8b800bc73 100644 --- a/webapp/public/locales/fr/translation.json +++ b/webapp/public/locales/fr/translation.json @@ -119,8 +119,11 @@ "View": "Afficher", "Your Nominations": "Vos nominations", "Nominee": "Candidat(e)", + "Your Submission": "Vos soumissions", + "Submission": "Soumission", "Status": "État", "New Nomination": "Nouvelle nomination", + "New Submission": "Nouvelle soumission", "Title": "Titre", "Email": "Courriel", "Relation": "Relation", diff --git a/webapp/src/pages/applicationForm/components/ApplicationForm.js b/webapp/src/pages/applicationForm/components/ApplicationForm.js index a38957fd9..87d8a3919 100644 --- a/webapp/src/pages/applicationForm/components/ApplicationForm.js +++ b/webapp/src/pages/applicationForm/components/ApplicationForm.js @@ -1025,7 +1025,7 @@ class ApplicationListComponent extends Component { let lastname = answerByQuestionKey("nomination_lastname", allQuestions, response.answers); return firstname + " " + lastname; } - return (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission " + response.id) : this.props.t("Self Nomination"); + return (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission") + " " + response.id : this.props.t("Self Nomination"); } getStatus = (response) => { @@ -1048,7 +1048,7 @@ class ApplicationListComponent extends Component { render() { let allQuestions = _.flatMap(this.props.formSpec.sections, s => s.questions); - let title = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Your Submissions") : this.props.t("Your Nominations"); + const title = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Your Submissions") : this.props.t("Your Nominations"); let firstColumn = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission") : this.props.t("Nominee"); return

{title}

From 5aa539525e82e6cb3d740c3cf5969388a1bb716d Mon Sep 17 00:00:00 2001 From: Shreya Pandit Date: Tue, 28 Mar 2023 12:06:58 +0200 Subject: [PATCH 3/3] added submission + revision UI --- api/app/responses/api.py | 2 + webapp/public/locales/en/translation.json | 3 + webapp/public/locales/fr/translation.json | 3 + .../components/ApplicationForm.js | 119 +++++++++++++----- 4 files changed, 95 insertions(+), 32 deletions(-) diff --git a/api/app/responses/api.py b/api/app/responses/api.py index 593bceb5f..94500bb84 100644 --- a/api/app/responses/api.py +++ b/api/app/responses/api.py @@ -38,6 +38,8 @@ class ResponseAPI(ResponseMixin, restful.Resource): response_fields = { 'id': fields.Integer, + 'submission_id': fields.Integer, + 'version_id': fields.Integer, 'application_form_id': fields.Integer, 'user_id': fields.Integer, 'is_submitted': fields.Boolean, diff --git a/webapp/public/locales/en/translation.json b/webapp/public/locales/en/translation.json index 2e3d23c29..1e5102733 100644 --- a/webapp/public/locales/en/translation.json +++ b/webapp/public/locales/en/translation.json @@ -121,9 +121,12 @@ "Nominee": "Nominee", "Your Submissions": "Your Submissions", "Submission": "Submission", + "Your Revisions": "Your Revisions", + "Revision": "Revision", "Status": "Status", "New Nomination": "New Nomination", "New Submission": "New Submission", + "New Revision": "New Revision", "Title": "Title", "Email": "Email", "Relation": "Relation", diff --git a/webapp/public/locales/fr/translation.json b/webapp/public/locales/fr/translation.json index 8b800bc73..4bfe24a2f 100644 --- a/webapp/public/locales/fr/translation.json +++ b/webapp/public/locales/fr/translation.json @@ -121,9 +121,12 @@ "Nominee": "Candidat(e)", "Your Submission": "Vos soumissions", "Submission": "Soumission", + "Your Revisions": "Vos révisions", + "Revision": "Révision", "Status": "État", "New Nomination": "Nouvelle nomination", "New Submission": "Nouvelle soumission", + "New Revision": "Nouvelle révision", "Title": "Titre", "Email": "Courriel", "Relation": "Relation", diff --git a/webapp/src/pages/applicationForm/components/ApplicationForm.js b/webapp/src/pages/applicationForm/components/ApplicationForm.js index 87d8a3919..534a1ed4c 100644 --- a/webapp/src/pages/applicationForm/components/ApplicationForm.js +++ b/webapp/src/pages/applicationForm/components/ApplicationForm.js @@ -67,6 +67,22 @@ const answerByQuestionKey = (key, allQuestions, answers) => { return null; } +function ResponsesBySubmission(responses) { + var by_submissions = {}; + + responses.forEach(response => { + if (!(response.submission_id in by_submissions)){ + by_submissions[response.submission_id] = [response] + } else { + // add responses with the same submission id to the same array and sort by revision_id in descending order + by_submissions[response.submission_id].push(response) + by_submissions[response.submission_id].sort((a, b) => a.version_id < b.version_id ? 1 : -1) + } + } + ) + return by_submissions; +} + class FieldEditor extends React.Component { constructor(props) { super(props); @@ -1013,7 +1029,7 @@ class ApplicationListComponent extends Component { componentDidMount() { eventService.getEvent(this.props.formSpec.event_id).then(response => { this.setState({ - event_type: response.event.event_type + isJournalEvent: response.event.event_type === 'JOURNAL' || response.event.event_type ==='CONTINUOUS_JOURNAL' }); })}; @@ -1025,7 +1041,7 @@ class ApplicationListComponent extends Component { let lastname = answerByQuestionKey("nomination_lastname", allQuestions, response.answers); return firstname + " " + lastname; } - return (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission") + " " + response.id : this.props.t("Self Nomination"); + return this.state.isJournalEvent ? (this.props.submissionSelected ? this.props.t("Revision") + " " + response.version_id: this.props.t("Submission") + " " + response.submission_id) : this.props.t("Self Nomination"); } getStatus = (response) => { @@ -1037,8 +1053,8 @@ class ApplicationListComponent extends Component { } } - getAction = (response) => { - if (response.is_submitted) { + getAction = (response, submitted) => { + if (submitted) { return } else { @@ -1047,29 +1063,45 @@ class ApplicationListComponent extends Component { } render() { + const by_submissions = ResponsesBySubmission(this.props.responses); let allQuestions = _.flatMap(this.props.formSpec.sections, s => s.questions); - const title = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Your Submissions") : this.props.t("Your Nominations"); - let firstColumn = (this.state.event_type ==='JOURNAL' || this.state.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("Submission") : this.props.t("Nominee"); + const title = this.state.isJournalEvent ? + (this.props.submissionSelected ? this.props.t("Your Revisions") : this.props.t("Your Submissions")) + : this.props.t("Your Nominations"); + let firstColumn = this.state.isJournalEvent ? (this.props.submissionSelected ? this.props.t("Revision") : this.props.t("Submission")) : this.props.t("Nominee"); return
-

{title}

-
{this.props.t("Nominee")}{firstColumn} {this.props.t("Status")}
- - - - - - - - - {this.props.responses.map(response => { - return - - - - - })} - -
{firstColumn}{this.props.t("Status")}
{this.getCandidate(allQuestions, response)}{this.getStatus(response)}{this.getAction(response)}
+

{title}

+ + + + + + + + + {this.state.isJournalEvent && !this.props.submissionSelected && ( + + {Object.keys(by_submissions).map(submission_id => { + return + + + + + })} + + )} + {(!this.state.isJournalEvent || this.props.submissionSelected) && ( + + {this.props.responses.map(response => { + return + + + + + })} + + )} +
{firstColumn}{this.props.t("Status")}
{this.getCandidate(allQuestions, by_submissions[submission_id][0])}{this.getStatus(by_submissions[submission_id][0])}{this.getAction(by_submissions[submission_id], by_submissions[submission_id][0].is_submitted)}
{this.getCandidate(allQuestions, response)}{this.getStatus(response)}{this.getAction(response, response.is_submitted)}
} } @@ -1087,7 +1119,8 @@ class ApplicationForm extends Component { errorMessage: "", formSpec: null, responses: [], - selectedResponse: null + selectedResponse: null, + selectedSubmission: null } } @@ -1108,7 +1141,8 @@ class ApplicationForm extends Component { isLoading: false, selectedResponse: selectFirstResponse ? responseResponse.response[0] : null, responseSelected: selectFirstResponse, - event_type: eventResponse.event.event_type + event_type: eventResponse.event.event_type, + isJournalEvent: eventResponse.event.event_type === 'JOURNAL' || eventResponse.event.event_type ==='CONTINUOUS_JOURNAL' }); }); } @@ -1122,7 +1156,15 @@ class ApplicationForm extends Component { newNomination = () => { this.setState({ - responseSelected: true + responseSelected: true, + submissionSelected: true + }); + } + + submissionSelected = (response_array) => { + this.setState({ + selectedSubmission: response_array, + submissionSelected: true }); } @@ -1134,7 +1176,9 @@ class ApplicationForm extends Component { formSpec, responses, selectedResponse, - responseSelected } = this.state; + responseSelected, + selectedSubmission, + submissionSelected } = this.state; if (isLoading) { return (); @@ -1144,11 +1188,22 @@ class ApplicationForm extends Component { return
{errorMessage}
; } - if (formSpec.nominations && responses.length > 0 && !responseSelected) { - let newForm = (this.props.event.event_type ==='JOURNAL' || this.props.event.event_type ==='CONTINUOUS_JOURNAL') ? this.props.t("New Submission") + " " : this.props.t("New Nomination") + " "; + if (!this.state.isJournalEvent && formSpec.nominations && responses.length > 0 && !responseSelected) { return

- + +
+ } + else if (this.state.isJournalEvent && formSpec.nominations && responses.length > 0 && !responseSelected && !submissionSelected) { + return
+
+ +
+ } + else if (this.state.isJournalEvent && formSpec.nominations && responses.length > 0 && !responseSelected) { + return
+
+
} else {