feat(exam-correct): display more info

This commit is contained in:
Sarah Vaupel 2020-08-12 17:14:00 +02:00
parent e941083a44
commit ef52f02d78
4 changed files with 26 additions and 2 deletions

View File

@ -19,6 +19,7 @@ const EXAM_CORRECT_SEND_BTN_ID = 'exam-correct__send-btn';
const EXAM_CORRECT_USER_INPUT_ID = 'exam-correct__user'; const EXAM_CORRECT_USER_INPUT_ID = 'exam-correct__user';
const EXAM_CORRECT_USER_INPUT_STATUS_ID = 'exam-correct__user-status'; const EXAM_CORRECT_USER_INPUT_STATUS_ID = 'exam-correct__user-status';
const EXAM_CORRECT_USER_INPUT_CANDIDATES_ID = 'exam-correct__user-candidates'; const EXAM_CORRECT_USER_INPUT_CANDIDATES_ID = 'exam-correct__user-candidates';
const EXAM_CORRECT_USER_INPUT_CANDIDATES_MORE_ID = 'exam-correct__user-candidates-more';
const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new'; const EXAM_CORRECT_INPUT_BODY_ID = 'exam-correct__new';
const EXAM_CORRECT_USER_ATTR = 'exam-correct--user-id'; const EXAM_CORRECT_USER_ATTR = 'exam-correct--user-id';
const EXAM_CORRECT_USER_DNAME_ATTR = 'exam-correct--user-dname'; const EXAM_CORRECT_USER_DNAME_ATTR = 'exam-correct--user-dname';
@ -45,6 +46,7 @@ export class ExamCorrect {
_userInput; _userInput;
_userInputStatus; _userInputStatus;
_userInputCandidates; _userInputCandidates;
_userInputCandidatesMore;
_partInputs; _partInputs;
_resultSelect; _resultSelect;
_resultGradeSelect; _resultGradeSelect;
@ -77,6 +79,7 @@ export class ExamCorrect {
this._userInput = document.getElementById(EXAM_CORRECT_USER_INPUT_ID); this._userInput = document.getElementById(EXAM_CORRECT_USER_INPUT_ID);
this._userInputStatus = document.getElementById(EXAM_CORRECT_USER_INPUT_STATUS_ID); this._userInputStatus = document.getElementById(EXAM_CORRECT_USER_INPUT_STATUS_ID);
this._userInputCandidates = document.getElementById(EXAM_CORRECT_USER_INPUT_CANDIDATES_ID); this._userInputCandidates = document.getElementById(EXAM_CORRECT_USER_INPUT_CANDIDATES_ID);
this._userInputCandidatesMore = document.getElementById(EXAM_CORRECT_USER_INPUT_CANDIDATES_MORE_ID);
this._partInputs = [...this._element.querySelectorAll(`input[${EXAM_CORRECT_PART_INPUT_ATTR}]`)]; this._partInputs = [...this._element.querySelectorAll(`input[${EXAM_CORRECT_PART_INPUT_ATTR}]`)];
const resultCell = document.getElementById('uw-exam-correct__result'); const resultCell = document.getElementById('uw-exam-correct__result');
this._resultSelect = resultCell && resultCell.querySelector('select'); this._resultSelect = resultCell && resultCell.querySelector('select');
@ -109,6 +112,10 @@ export class ExamCorrect {
throw new Error('ExamCorrect utility could not detect user input candidate list!'); throw new Error('ExamCorrect utility could not detect user input candidate list!');
} }
if (!this._userInputCandidatesMore) {
throw new Error('ExamCorrect utility could not detect user input candidate more element');
}
// TODO get date format by post request // TODO get date format by post request
this._dateFormat = 'DD.MM.YYYY HH:mm:ss'; this._dateFormat = 'DD.MM.YYYY HH:mm:ss';
@ -178,6 +185,7 @@ export class ExamCorrect {
// do nothing in case of empty or invalid input // do nothing in case of empty or invalid input
if (!this._userInput.value || this._userInput.reportValidity && !this._userInput.reportValidity()) { if (!this._userInput.value || this._userInput.reportValidity && !this._userInput.reportValidity()) {
removeAllChildren(this._userInputCandidates); removeAllChildren(this._userInputCandidates);
this._userInputCandidatesMore.hidden = true;
setStatus(this._userInputStatus, STATUS.NONE); setStatus(this._userInputStatus, STATUS.NONE);
return; return;
} }
@ -212,6 +220,7 @@ export class ExamCorrect {
// TODO avoid code duplication // TODO avoid code duplication
if (this._userInput.reportValidity && !this._userInput.reportValidity()) { if (this._userInput.reportValidity && !this._userInput.reportValidity()) {
removeAllChildren(this._userInputCandidates); removeAllChildren(this._userInputCandidates);
this._userInputCandidatesMore.hidden = true;
setStatus(this._userInput, STATUS.NONE); setStatus(this._userInput, STATUS.NONE);
return; return;
} }
@ -305,6 +314,7 @@ export class ExamCorrect {
if (response.users) { if (response.users) {
// delete candidate list entries from previous requests // delete candidate list entries from previous requests
removeAllChildren(this._userInputCandidates); removeAllChildren(this._userInputCandidates);
this._userInputCandidatesMore.hidden = true;
// show error if there are no matches for this input // show error if there are no matches for this input
if (response.users.length === 0) { if (response.users.length === 0) {
@ -335,6 +345,7 @@ export class ExamCorrect {
// remove all candidates on accept // remove all candidates on accept
removeAllChildren(this._userInputCandidates); removeAllChildren(this._userInputCandidates);
this._userInputCandidatesMore.hidden = true;
setStatus(this._userInputStatus, STATUS.SUCCESS); setStatus(this._userInputStatus, STATUS.SUCCESS);
@ -344,6 +355,7 @@ export class ExamCorrect {
this._userInputCandidates.appendChild(candidateItem); this._userInputCandidates.appendChild(candidateItem);
}); });
this._userInputCandidatesMore.hidden = response['has-more'] !== true;
} else { } else {
// TODO what to do in this case? // TODO what to do in this case?
setStatus(this._userInputStatus, STATUS.FAILURE); setStatus(this._userInputStatus, STATUS.FAILURE);
@ -388,6 +400,7 @@ export class ExamCorrect {
// TODO set edit button visibility // TODO set edit button visibility
status = STATUS.AMBIGUOUS; status = STATUS.AMBIGUOUS;
newEntry.users = response.users; newEntry.users = response.users;
newEntry.hasMore = response['has-more'] === true;
newEntry.message = response.message || null; newEntry.message = response.message || null;
break; break;
case 'failure': case 'failure':
@ -426,7 +439,7 @@ export class ExamCorrect {
userElem.innerHTML = userToHTML(user); userElem.innerHTML = userToHTML(user);
userElem.setAttribute(EXAM_CORRECT_USER_ATTR, user.id || user); userElem.setAttribute(EXAM_CORRECT_USER_ATTR, user.id || user);
} else if (userElem && newEntry.users) { } else if (userElem && newEntry.users) {
row.replaceChild(userElem, this._showUserList(row, newEntry.users, { partResults: request.results, result: request.grade } )); row.replaceChild(userElem, this._showUserList(row, newEntry.users, { partResults: request.results, result: request.grade }, newEntry.hasMore === true));
} }
for (let [k, v] of Object.entries(newEntry.results)) { for (let [k, v] of Object.entries(newEntry.results)) {
@ -477,7 +490,7 @@ export class ExamCorrect {
} }
// TODO better name // TODO better name
_showUserList(row, users, results) { _showUserList(row, users, results, hasMore) {
let userElem = row.cells.item(this._cIndices.get('user')); let userElem = row.cells.item(this._cIndices.get('user'));
if (!userElem) { if (!userElem) {
userElem = document.createElement('TD'); userElem = document.createElement('TD');
@ -499,6 +512,12 @@ export class ExamCorrect {
list.appendChild(listItem); list.appendChild(listItem);
} }
userElem.appendChild(list); userElem.appendChild(list);
if (hasMore === true) {
const moreElem = this._userInputCandidatesMore.cloneNode(true); // TODO I'm lazy
moreElem.removeAttribute('id');
moreElem.hidden = false;
userElem.appendChild(moreElem);
}
} else { } else {
console.error('Unable to show users from invalid response'); console.error('Unable to show users from invalid response');
} }
@ -598,6 +617,7 @@ export class ExamCorrect {
_clearUserInput() { _clearUserInput() {
removeAllChildren(this._userInputCandidates); removeAllChildren(this._userInputCandidates);
this._userInputCandidatesMore.hidden = true;
clearInput(this._userInput); clearInput(this._userInput);
this._userInput.removeAttribute(EXAM_CORRECT_USER_ATTR); this._userInput.removeAttribute(EXAM_CORRECT_USER_ATTR);
this._userInput.removeAttribute(EXAM_CORRECT_USER_DNAME_ATTR); this._userInput.removeAttribute(EXAM_CORRECT_USER_DNAME_ATTR);

View File

@ -1577,6 +1577,7 @@ ExamRegistrationInviteExplanation: Sie wurden eingeladen, Prüfungsteilnehmer zu
ExamCorrectHeading examname@Text: Prüfungsergebnisse für #{examname} eintragen ExamCorrectHeading examname@Text: Prüfungsergebnisse für #{examname} eintragen
ExamCorrectExamResultDelete: Prüfungsergebnis löschen ExamCorrectExamResultDelete: Prüfungsergebnis löschen
ExamCorrectExamResultNone: Keine Änderung ExamCorrectExamResultNone: Keine Änderung
ExamCorrectUserCandidatesMore: und weitere
ExamCorrectHeadDate: Zeit ExamCorrectHeadDate: Zeit
ExamCorrectHeadParticipant: Teilnehmer ExamCorrectHeadParticipant: Teilnehmer

View File

@ -1590,6 +1590,7 @@ ExamCorrectErrorPartResultOutOfBoundsMax examPartNumber maxPoints: Exam part res
ExamCorrectExamResultDelete: Delete exam result ExamCorrectExamResultDelete: Delete exam result
ExamCorrectExamResultNone: No change ExamCorrectExamResultNone: No change
ExamCorrectUserCandidatesMore: and more
SubmissionUserInvitationAccepted shn: You now participate in a submission for #{shn} SubmissionUserInvitationAccepted shn: You now participate in a submission for #{shn}
SubmissionUserInvitationDeclined shn: You have declined the invitation to participate in a submission for #{shn} SubmissionUserInvitationDeclined shn: You have declined the invitation to participate in a submission for #{shn}

View File

@ -26,6 +26,8 @@ $newline never
<input #exam-correct__user .uw-exam-correct--user-cell type="text" autofocus minLength=#{minNeedleLength}> <input #exam-correct__user .uw-exam-correct--user-cell type="text" autofocus minLength=#{minNeedleLength}>
<i #exam-correct__user-status .fas .fa-fw> <i #exam-correct__user-status .fas .fa-fw>
<ul #exam-correct__user-candidates> <ul #exam-correct__user-candidates>
<div #exam-correct__user-candidates-more hidden=true>
_{MsgExamCorrectUserCandidatesMore}
$forall ExamPart{examPartNumber} <- examParts $forall ExamPart{examPartNumber} <- examParts
<td .table__td .uw-exam-correct--part-cell> <td .table__td .uw-exam-correct--part-cell>
^{ptsInput examPartNumber} ^{ptsInput examPartNumber}