diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js index 5e1e96ca2..15f15bf2c 100644 --- a/frontend/src/utils/exam-correct/exam-correct.js +++ b/frontend/src/utils/exam-correct/exam-correct.js @@ -14,9 +14,13 @@ const EXAM_CORRECT_PART_INPUT_ATTR = 'uw-exam-correct--part-input'; const EXAM_CORRECT_SEND_BTN_ID = 'exam-correct__send-btn'; const EXAM_CORRECT_PARTICIPANT_INPUT_ID = 'exam-correct__participant'; const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new'; +const EXAM_CORRECT_PARTICIPANT_ATTR = 'exam-correct--participant'; const INPUT_EMPTY_CLASS = 'input--invalid'; +// TODO get from settings +const MOMENT_FORMAT = 'DD.MM.YY HH:mm:ss'; + @Utility({ selector: `table[${EXAM_CORRECT_IDENT}]`, @@ -100,9 +104,12 @@ export class ExamCorrect { const correctionRow = document.createElement('TR'); correctionRow.classList.add('table__row'); const dateTD = document.createElement('TD'); - dateTD.appendChild(document.createTextNode(moment().format())); + const now = moment(); + dateTD.appendChild(document.createTextNode(now.format(MOMENT_FORMAT))); + dateTD.setAttribute('date', moment()); const participantTD = document.createElement('TD'); participantTD.appendChild(document.createTextNode(participant)); + participantTD.setAttribute(EXAM_CORRECT_PARTICIPANT_ATTR, participant); const partTDs = this._partInputs.map((input) => { const partTD = document.createElement('TD'); const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR); @@ -110,7 +117,11 @@ export class ExamCorrect { partTD.appendChild(document.createTextNode(results[partKey])); return partTD; }); - [dateTD,participantTD,...partTDs].forEach((td) => { + const statusTD = document.createElement('TD'); + const statusDiv = document.createElement('DIV'); + statusDiv.classList.add('exam-correct--loading'); + statusTD.appendChild(statusDiv); + [dateTD,participantTD,...partTDs, statusTD].forEach((td) => { td.classList.add('table__td'); correctionRow.appendChild(td); }); @@ -143,19 +154,43 @@ export class ExamCorrect { ).catch((error) => { console.error('Error while processing response', error); }); - - // TODO wait for response and replace status icon accordingly (add edit button to paste content in current input) } _processResponse(response, participant) { console.log('WIP ExamCorrect._processResponse', response, participant); - // TODO find the first corresponding row (participant matches cell entry in second column) top-down - // if found: - // if the response status is 'success' (i.e. the results have been upserted into the DB), - // replace loading spinner in this row with tick mark icon - // otherwise, - // replace loading spinner with error icon (error message as tooltip if present?) + if (response) { + for (let row of [...this._element.rows]) { + const participantElem = row.cells.item(1); + const participantIdent = participantElem && participantElem.getAttribute(EXAM_CORRECT_PARTICIPANT_ATTR); + if (participantIdent === participant) { + let faIcon, ecClass; + switch (response.status) { + case 'success': + // TODO replace loading spinner class with fontawesome tick mark icon + // TODO replace participant identifier with participant from response + faIcon = 'fa-check'; + ecClass = 'exam-correct--success'; + break; + case 'error': + // TODO replace loading spinner class with fontawesome error icon + // TODO show tooltip with error message? + faIcon = 'fa-times'; + ecClass = 'exam-correct--error'; + break; + default: + console.error('Invalid response'); + faIcon = 'fa-times'; + ecClass = 'exam-correct--error'; + } + row.querySelectorAll('.exam-correct--loading').forEach((elem) => { + elem.classList.remove('exam-correct--loading'); + elem.classList.add('fa', faIcon, ecClass); + }); + break; + } + } + } } _removeInputEmptyClassHandler() { diff --git a/frontend/src/utils/exam-correct/exam-correct.sass b/frontend/src/utils/exam-correct/exam-correct.sass index a6a646bed..63fd21145 100644 --- a/frontend/src/utils/exam-correct/exam-correct.sass +++ b/frontend/src/utils/exam-correct/exam-correct.sass @@ -1,2 +1,22 @@ #exam-correct__participant.input--invalid border: 2px solid var(--color-error) + +.exam-correct--success + color: var(--color-success) + +.exam-correct--error + color: var(--color-error) + +.exam-correct--loading + border: 3px solid var(--color-grey-light) + border-top: 3px solid var(--color-primary) + border-radius: 50% + width: 20px + height: 20px + animation: spin 2s linear infinite + +@keyframes spin + 0% + transform: rotate(0deg) + 100% + transform: rotate(360deg)