From 23044b28dbcfdc82d5f1e934ab18fba034d60e4a Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 20:57:26 +0100 Subject: [PATCH 1/6] feat(exam-correct): general improvement --- .../src/utils/exam-correct/exam-correct.js | 87 ++++++++++++------- .../src/utils/exam-correct/exam-correct.sass | 17 ++-- messages/uniworx/de-de-formal.msg | 1 + messages/uniworx/en-eu.msg | 1 + src/Handler/Exam/Correct.hs | 36 +++++--- 5 files changed, 95 insertions(+), 47 deletions(-) diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js index 5a7ffc9ca..3c9a1c9f0 100644 --- a/frontend/src/utils/exam-correct/exam-correct.js +++ b/frontend/src/utils/exam-correct/exam-correct.js @@ -47,6 +47,7 @@ export class ExamCorrect { _userInputStatus; _userInputCandidates; _partInputs; + _partDeleteBoxes; _dateFormat; _cIndices; @@ -75,6 +76,7 @@ export class ExamCorrect { this._userInputStatus = document.getElementById(EXAM_CORRECT_USER_INPUT_STATUS_ID); this._userInputCandidates = document.getElementById(EXAM_CORRECT_USER_INPUT_CANDIDATES_ID); this._partInputs = [...this._element.querySelectorAll(`input[${EXAM_CORRECT_PART_INPUT_ATTR}]`)]; + this._partDeleteBoxes = [...this._element.querySelectorAll('input.uw-exam-correct--delete-exam-part')]; if (this._sendBtn) this._sendBtn.addEventListener('click', this._sendCorrectionHandler.bind(this)); @@ -84,6 +86,10 @@ export class ExamCorrect { this._userInput.addEventListener('focusout', this._validateUserInput.bind(this)); else throw new Error('ExamCorrect utility could not detect user input!'); + for (let deleteBox of this._partDeleteBoxes) { + deleteBox.addEventListener('change', (() => { this._updatePartDeleteDisabled(deleteBox); }).bind(this)); + } + if (!this._userInputStatus) { throw new Error('ExamCorrect utility could not detect user input status element!'); } @@ -93,7 +99,7 @@ export class ExamCorrect { } // TODO get date format by post request - this._dateFormat = 'YYYY-MM-DD HH:mm:ss'; + this._dateFormat = 'DD.MM.YYYY HH:mm:ss'; this._cIndices = new Map( [...this._element.querySelectorAll('[uw-exam-correct-header]')] @@ -116,6 +122,14 @@ export class ExamCorrect { // TODO destroy handlers on user input candidate elements } + _updatePartDeleteDisabled(deleteBox) { + const partInput = deleteBox.parentElement.querySelector(`input[${EXAM_CORRECT_PART_INPUT_ATTR}]`); + if (!partInput) + return; + + partInput.disabled = deleteBox.checked; + } + _validateUserInput() { (!this._userInput.value) ? this._userInput.classList.add('no-value') : this._userInput.classList.remove('no-value'); @@ -176,11 +190,17 @@ export class ExamCorrect { const results = {}; for (const input of this._partInputs) { - if (input.reportValidity && !input.reportValidity()) { + if (input.disabled) { + const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR); + if (!partKey) { + console.error('Error while parsing results: Could not detect exam part key attribute'); + return; + } + results[partKey] = null; + } else if (input.reportValidity && !input.reportValidity()) { input.focus(); return; - } - if (input.value) { + } else if (input.value) { const partKey = input.getAttribute(EXAM_CORRECT_PART_INPUT_ATTR); if (!partKey) { console.error('Error while parsing results: Could not detect exam part key attribute'); @@ -189,24 +209,25 @@ export class ExamCorrect { results[partKey] = parseFloat(input.value); } } + console.log('results', results); - const result = this._resultSelect.value !== 'none' && this._resultSelect.value; + const result = this._resultSelect && this._resultSelect.value !== 'none' && this._resultSelect.value; // abort send if there are no results (after validation) - if (Object.keys(results).length <= 0) return; + if (Object.keys(results).length <= 0 && !result) return; const rowInfo = { users: [user], results: results, + result: result === 'delete' ? null : result, status: STATUS.LOADING, }; - if (results) rowInfo.results = results; - if (result) rowInfo.result = result === 'delete' ? null : result; this._addRow(rowInfo); // clear inputs on validation success this._clearUserInput(); this._partInputs.forEach(clearInput); + this._partDeleteBoxes.forEach(box => { box.checked = false; this._updatePartDeleteDisabled(box); }); const body = { user: userId || user, @@ -305,39 +326,38 @@ export class ExamCorrect { case 'success': status = STATUS.SUCCESS; if (response.user) { - userElem.setAttribute(EXAM_CORRECT_USER_ATTR, response.user.id); - userElem.innerHTML = userToHTML(response.user); const timeElem = row.cells.item(0); timeElem.innerHTML = moment(response.time).format(this._dateFormat); timeElem.classList.remove('exam-correct--local-time'); newEntry.users = [response.user]; newEntry.results = response.results; newEntry.result = response.grade; + } else { + console.error('Invalid response'); + return; } // TODO set edit button visibility break; case 'ambiguous': // TODO set edit button visibility status = STATUS.AMBIGUOUS; - if (response.users) { - userElem = this._showUserList(row, response.users, results); - newEntry.users = response.users; - newEntry.results = results.partResults; - newEntry.result = results.result; - } + newEntry.users = response.users; + newEntry.results = typeof results === 'undefined' ? {} : results; + newEntry.result = typeof result === 'undefined' ? undefined : result; // eslint-disable-line no-undef newEntry.message = response.message || null; break; case 'failure': status = STATUS.FAILURE; newEntry.users = (response.user && [response.user]) || null; - newEntry.results = results; + newEntry.results = typeof results === 'undefined' ? {} : results; newEntry.message = response.message || null; - newEntry.result = results.result; + newEntry.result = typeof result === 'undefined' ? undefined : result; // eslint-disable-line no-undef break; default: // TODO show tooltip with 'invalid response' // TODO set edit button visibility console.error('Invalid response'); + return; } row.querySelectorAll('.fa-spin').forEach((elem) => { setStatus(elem, status); @@ -359,19 +379,23 @@ export class ExamCorrect { statusCell.appendChild(messageElem); } - const userCell = row.querySelector('.uw-exam-correct--user-cell'); - if (userCell && newEntry.users && newEntry.users.length === 1) { + if (userElem && newEntry.users && newEntry.users.length === 1) { const user = newEntry.users[0]; - userCell.innerHTML = userToHTML(user); - userCell.setAttribute(EXAM_CORRECT_USER_ATTR, user); - } else if (userCell && newEntry.users) { - row.replaceChild(userCell, this._showUserList(row, newEntry.users, request.results)); + userElem.innerHTML = userToHTML(user); + userElem.setAttribute(EXAM_CORRECT_USER_ATTR, user.id || user); + } else if (userElem && newEntry.users) { + row.replaceChild(userElem, this._showUserList(row, newEntry.users, { partResults: request.results, result: request.grade } )); } for (let [k, v] of Object.entries(newEntry.results)) { const resultCell = row.cells.item(this._cIndices.get(k)); - if (v.result) + if (v === null) { + resultCell.innerHTML = ''; + resultCell.classList.remove('exam-correct--result-unconfirmed'); + } else if (v && v.result) { resultCell.innerHTML = v.result; + resultCell.classList.remove('exam-correct--result-unconfirmed'); + } } savedEntries.push(newEntry); @@ -429,9 +453,9 @@ export class ExamCorrect { const body = { user: listItem.getAttribute(EXAM_CORRECT_USER_ATTR), - results: results.partResults, - grade: results.result, }; + if (results.partResults) body.results = results.partResults; + if (results.result || results.result === null) body.grade = results.result; this._app.httpClient.post({ url: EXAM_CORRECT_URL_POST, @@ -478,8 +502,13 @@ export class ExamCorrect { console.error('Could not determine cell index from part key!'); } else { const partCell = document.createElement('TD'); - partCell.innerHTML = partResult; - partCell.classList.add('uw-exam-correct--part-cell'); + + if (partResult === null) { + partCell.innerHTML = ''; + } else { + partCell.innerHTML = partResult; + } + partCell.classList.add('uw-exam-correct--part-cell', 'exam-correct--result-unconfirmed'); cells.set(cellIndex, partCell); } } diff --git a/frontend/src/utils/exam-correct/exam-correct.sass b/frontend/src/utils/exam-correct/exam-correct.sass index 9b5d3658a..f0554a692 100644 --- a/frontend/src/utils/exam-correct/exam-correct.sass +++ b/frontend/src/utils/exam-correct/exam-correct.sass @@ -12,7 +12,7 @@ table[uw-exam-correct] min-width: 200px th.uw-exam-correct--part-cell, td.uw-exam-correct--part-cell - width: min-content + width: 115px text-align: center white-space: nowrap @@ -24,12 +24,16 @@ table[uw-exam-correct] opacity: .5 cursor: pointer margin-left: 5px - .uw-exam-correct--delete-exam-part ~ .fa-trash:hover - opacity: 1 + + &:hover + opacity: 1 .uw-exam-correct--delete-exam-part:checked ~ .fa-trash opacity: 1 color: var(--color-error) + &:hover + color: var(--color-error-dark) + td#uw-exam-correct__result width: min-content select @@ -63,7 +67,6 @@ table[uw-exam-correct] border: 2px solid var(--color-error) [uw-exam-correct] tbody ul - list-style: none li cursor: pointer text-decoration: underline @@ -73,9 +76,11 @@ table[uw-exam-correct] width: calc(100% - 18em/14 - #{$exam-correct--input-status-margin}) i margin-left: $exam-correct--input-status-margin + ul + margin-top: 7px -.exam-correct--local-time - color: var(--color-fontsec) +.exam-correct--local-time, .exam-correct--result-unconfirmed + opacity: .5 font-style: italic .exam-correct--success diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index e79cff87f..3fcff0514 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -413,6 +413,7 @@ UnauthorizedAllocationLecturer: Sie sind nicht als Veranstalter für eine Verans UnauthorizedCorrector: Sie sind nicht als Korrektor für diese Veranstaltung eingetragen. UnauthorizedSheetCorrector: Sie sind nicht als Korrektor für dieses Übungsblatt eingetragen. UnauthorizedExamCorrector: Sie sind nicht als Korrektor für diese Prüfung eingetragen. +UnauthorizedExamCorrectorGrade: Sie haben nicht die Berechtigung für diese Prüfung Gesamtergebnisse einzutragen. UnauthorizedCorrectorAny: Sie sind nicht als Korrektor für eine Veranstaltung eingetragen. UnauthorizedRegistered: Sie sind nicht als Teilnehmer für diese Veranstaltung registriert. UnauthorizedAllocationRegistered: Sie sind nicht als Teilnehmer für diese Zentralanmeldung registriert. diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index 8f829c850..e0fa571fd 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -411,6 +411,7 @@ UnauthorizedAllocationLecturer: You are no administrator for any of the courses UnauthorizedCorrector: You are no sheet corrector for this course. UnauthorizedSheetCorrector: You are no corrector for this sheet. UnauthorizedExamCorrector: You are no corrector for this exam. +UnauthorizedExamCorrectorGrade: You may not enter overall exam achievements for this exam. UnauthorizedCorrectorAny: You are no corrector for any course. UnauthorizedRegistered: You are no participant in this course. UnauthorizedAllocationRegistered: You are no participant in this central allocation. diff --git a/src/Handler/Exam/Correct.hs b/src/Handler/Exam/Correct.hs index 35736c4c8..34633609b 100644 --- a/src/Handler/Exam/Correct.hs +++ b/src/Handler/Exam/Correct.hs @@ -10,10 +10,13 @@ import qualified Data.Aeson as JSON import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils as E +import Database.Persist.Sql (transactionUndo) import Handler.Utils import Handler.Utils.Exam (fetchExam) +import qualified Data.HashMap.Strict as HashMap + data CorrectInterfaceUser = CorrectInterfaceUser @@ -30,7 +33,7 @@ data CorrectInterfaceResponse = CorrectInterfaceResponseSuccess { cirsUser :: CorrectInterfaceUser , cirsResults :: Map ExamPartNumber (Maybe ExamResultPoints) - , cirsGrade :: Maybe ExamResultPassedGrade + , cirsGrade :: Maybe (Maybe ExamResultPassedGrade) , cirsTime :: UTCTime } | CorrectInterfaceResponseAmbiguous @@ -44,17 +47,18 @@ data CorrectInterfaceResponse | CorrectInterfaceResponseNoOp { cirnUsers :: Set CorrectInterfaceUser } -deriveJSON defaultOptions +deriveToJSON defaultOptions { constructorTagModifier = camelToPathPiece' 3 , fieldLabelModifier = camelToPathPiece' 1 , sumEncoding = TaggedObject "status" "results" + , omitNothingFields = True } ''CorrectInterfaceResponse data CorrectInterfaceRequest = CorrectInterfaceRequest { ciqUser :: Either Text (CryptoID UUID (Key User)) , ciqResults :: Maybe (NonNull (Map ExamPartNumber (Maybe Points))) - , ciqGrade :: Maybe ExamResultPassedGrade + , ciqGrade :: Maybe (Maybe ExamResultPassedGrade) } instance FromJSON CorrectInterfaceRequest where @@ -62,7 +66,11 @@ instance FromJSON CorrectInterfaceRequest where ciqUser <- Right <$> o JSON..: "user" <|> Left <$> o JSON..: "user" results <- o JSON..:? "results" ciqResults <- for results $ maybe (fail "Results may not be nullable") return . fromNullable - ciqGrade <- o JSON..:? "grade" + ciqGrade <- if + | "grade" `HashMap.member` o + -> Just <$> o JSON..: "grade" + | otherwise + -> pure Nothing return CorrectInterfaceRequest{..} @@ -104,7 +112,9 @@ postECorrectR tid ssh csh examn = do CorrectInterfaceRequest{..} <- requireCheckJsonBody - response <- exceptT return return . hoist runDB $ do + let mayEditResults = False + + response <- runDB . exceptT (<$ transactionUndo) return $ do Entity eId Exam{..} <- lift $ fetchExam tid ssh csh examn euid <- traverse decrypt ciqUser @@ -192,20 +202,22 @@ postECorrectR tid ssh csh examn = do | otherwise -> return Nothing | otherwise -> return mempty - newExamResult <- lift $ do + newExamResult <- for ciqGrade $ \ciqGrade' -> lift $ do + unless mayEditResults $ + permissionDeniedI MsgUnauthorizedExamCorrectorGrade mOldResult <- getBy $ UniqueExamResult eId uid if - | Just (Entity oldId _) <- mOldResult, is _Nothing ciqGrade -> do - delete oldId - audit $ TransactionExamResultDeleted eId uid - return Nothing - | Just result <- ciqGrade -> let + | Just (Entity oldId _) <- mOldResult, is _Nothing ciqGrade' -> do + delete oldId + audit $ TransactionExamResultDeleted eId uid + return Nothing + | Just result <- ciqGrade' -> let mOld = view passedGrade . examResultResult . entityVal <$> mOldResult resultGrade = review passedGrade result passedGrade :: Iso' ExamResultGrade ExamResultPassedGrade passedGrade = iso (fmap $ bool (Left . view passingGrade) Right examShowGrades) (fmap $ either (review passingGrade) id) in if - | ciqGrade /= mOld -> do + | ciqGrade' /= mOld -> do newResult <- upsert ExamResult { examResultExam = eId , examResultUser = uid From 10de1a7de7e6855c6c84933618aa84d20f7f07b9 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 21:17:29 +0100 Subject: [PATCH 2/6] feat(exam-correct): submit on enter --- frontend/src/utils/exam-correct/exam-correct.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js index 3c9a1c9f0..e321c6e8a 100644 --- a/frontend/src/utils/exam-correct/exam-correct.js +++ b/frontend/src/utils/exam-correct/exam-correct.js @@ -90,6 +90,10 @@ export class ExamCorrect { deleteBox.addEventListener('change', (() => { this._updatePartDeleteDisabled(deleteBox); }).bind(this)); } + for (let input of [this._userInput, ...this._partInputs]) { + input.addEventListener('keypress', this._inputKeypress.bind(this)); + } + if (!this._userInputStatus) { throw new Error('ExamCorrect utility could not detect user input status element!'); } @@ -130,6 +134,14 @@ export class ExamCorrect { partInput.disabled = deleteBox.checked; } + _inputKeypress() { + if (event.keyCode !== 13) { + return false; + } + + this._sendCorrectionHandler(); + } + _validateUserInput() { (!this._userInput.value) ? this._userInput.classList.add('no-value') : this._userInput.classList.remove('no-value'); From c5197928b12861599338a87dda9562ff16782332 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 21:33:32 +0100 Subject: [PATCH 3/6] feat(hide-columns): don't break on dom changes --- frontend/src/utils/hide-columns/hide-columns.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/src/utils/hide-columns/hide-columns.js b/frontend/src/utils/hide-columns/hide-columns.js index 0c0187f23..77382e322 100644 --- a/frontend/src/utils/hide-columns/hide-columns.js +++ b/frontend/src/utils/hide-columns/hide-columns.js @@ -31,6 +31,8 @@ export class HideColumns { _autoHide; + _mutationObserver; + headerToHider = new Map(); hiderToHeader = new Map(); @@ -69,6 +71,9 @@ export class HideColumns { } [...this._element.querySelectorAll('th')].filter(th => !th.hasAttribute(HIDE_COLUMNS_NO_HIDE)).forEach(th => this.setupHideButton(th)); + + this._mutationObserver = new MutationObserver(this._tableMutated.bind(this)); + this._mutationObserver.observe(this._element, { childList: true, subtree: true }); } setupHideButton(th) { @@ -217,6 +222,15 @@ export class HideColumns { hider.style.top = thR.height + 'px'; } + _tableMutated(mutationList, observer) { + console.log('_tableMutated', mutationList, observer); + + if (!Array.from(mutationList).some(mutation => mutation.type === 'childList')) + return; + + [...this._element.querySelectorAll('th')].filter(th => !th.hasAttribute(HIDE_COLUMNS_NO_HIDE)).forEach(th => this.updateColumnDisplay(this.colIndex(th), this.isHiddenColumn(th))); + } + getStorageKey(th) { // get handler name const handlerIdent = document.querySelector('[uw-handler]').getAttribute('uw-handler'); From 82922ee6eb4cca80f58fe27c5dae8f31a298fe44 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 21:48:08 +0100 Subject: [PATCH 4/6] chore: remove debug logs --- frontend/src/lib/storage-manager/storage-manager.js | 5 +++-- frontend/src/utils/exam-correct/exam-correct.js | 10 +++++----- frontend/src/utils/hide-columns/hide-columns.js | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/frontend/src/lib/storage-manager/storage-manager.js b/frontend/src/lib/storage-manager/storage-manager.js index 6a669e76e..d2461518c 100644 --- a/frontend/src/lib/storage-manager/storage-manager.js +++ b/frontend/src/lib/storage-manager/storage-manager.js @@ -381,8 +381,9 @@ export class StorageManager { }).catch(console.error); } - _debugLog(fName, ...args) { - console.log(`[DEBUGLOG] StorageManager.${fName}`, { args: args, instance: this }); + _debugLog() { + // _debugLog(fName, ...args) { + // console.log(`[DEBUGLOG] StorageManager.${fName}`, { args: args, instance: this }); } } diff --git a/frontend/src/utils/exam-correct/exam-correct.js b/frontend/src/utils/exam-correct/exam-correct.js index e321c6e8a..6bf962d63 100644 --- a/frontend/src/utils/exam-correct/exam-correct.js +++ b/frontend/src/utils/exam-correct/exam-correct.js @@ -221,7 +221,7 @@ export class ExamCorrect { results[partKey] = parseFloat(input.value); } } - console.log('results', results); + // console.log('results', results); const result = this._resultSelect && this._resultSelect.value !== 'none' && this._resultSelect.value; @@ -247,7 +247,7 @@ export class ExamCorrect { if (results) body.results = results; if (result) body.grade = result === 'result' ? this._resultGradeSelect.value : (result === 'delete' ? null : result); - console.log('request body', body); + // console.log('request body', body); this._app.httpClient.post({ url: EXAM_CORRECT_URL_POST, @@ -325,14 +325,14 @@ export class ExamCorrect { date: null, }; - console.log('response', response); + // console.log('response', response); const candidateRows = (targetRow && [targetRow]) || [...this._element.rows]; for (let row of candidateRows) { let userElem = row.cells.item(this._cIndices.get('user')); const userIdent = userElem && userElem.getAttribute(EXAM_CORRECT_USER_ATTR); // TODO use other attribute identifier if (userIdent === user) { - console.log('response-update', row); + // console.log('response-update', row); let status = STATUS.FAILURE; switch (response.status) { case 'success': @@ -480,7 +480,7 @@ export class ExamCorrect { } _addRow(rowInfo) { - console.log('rowInfo', rowInfo); + // console.log('rowInfo', rowInfo); // TODO create and use template for this const newRow = document.createElement('TR'); newRow.classList.add('table__row'); diff --git a/frontend/src/utils/hide-columns/hide-columns.js b/frontend/src/utils/hide-columns/hide-columns.js index 77382e322..312bb1024 100644 --- a/frontend/src/utils/hide-columns/hide-columns.js +++ b/frontend/src/utils/hide-columns/hide-columns.js @@ -222,8 +222,8 @@ export class HideColumns { hider.style.top = thR.height + 'px'; } - _tableMutated(mutationList, observer) { - console.log('_tableMutated', mutationList, observer); + _tableMutated(mutationList) { + // console.log('_tableMutated', mutationList, observer); if (!Array.from(mutationList).some(mutation => mutation.type === 'childList')) return; From cfa58b22ce86d2790c84c6f2bf0af79869191aaa Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 21:50:48 +0100 Subject: [PATCH 5/6] chore: fix tests --- src/Handler/Exam/Correct.hs | 2 +- test/Handler/HomeSpec.hs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Handler/Exam/Correct.hs b/src/Handler/Exam/Correct.hs index 34633609b..c5eab4c64 100644 --- a/src/Handler/Exam/Correct.hs +++ b/src/Handler/Exam/Correct.hs @@ -169,7 +169,7 @@ postECorrectR tid ssh csh examn = do audit $ TransactionExamPartResultDeleted examPartId uid return Nothing | Just partResult <- mPartResult -> let - mOld = (examPartResultResult . entityVal) <$> mOldResult + mOld = examPartResultResult . entityVal <$> mOldResult mNew = ExamAttended <$> mPartResult resultVal = _entityVal . _examPartResultResult in if diff --git a/test/Handler/HomeSpec.hs b/test/Handler/HomeSpec.hs index 35eb111d1..8b77d1a6e 100644 --- a/test/Handler/HomeSpec.hs +++ b/test/Handler/HomeSpec.hs @@ -10,7 +10,7 @@ spec = withApp $ do it "loads the index and checks it looks right" $ do request $ do setMethod "GET" - setUrl HomeR + setUrl NewsR addRequestHeader ("Accept-Language", "de") statusIs 200 - htmlAnyContain "h1" "Aktuelle Termine" + htmlAnyContain "h1" "Aktuelles" From 0ced94af63012feae7a82f2e6ea00dc131fed478 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 7 Feb 2020 22:00:58 +0100 Subject: [PATCH 6/6] chore(release): 11.0.0 --- CHANGELOG.md | 121 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 2 +- package.yaml | 2 +- 4 files changed, 124 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8dd6fa28..b642da743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,127 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [11.0.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v10.6.0...v11.0.0) (2020-02-07) + + +### Bug Fixes + +* merge ([a9636af](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a9636af)) +* **exam-correct:** add XSRF token to post header ([2fd996b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2fd996b)) +* **exam-correct:** add XSRF token to post header ([2b30461](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2b30461)) +* **exam-correct:** also persist local time on non-success ([41a9539](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/41a9539)) +* **exam-correct:** also persist local time on non-success ([dcb79d4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dcb79d4)) +* **exam-correct:** cut off at maxPoints for now (TODO) ([af8d77c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/af8d77c)) +* **exam-correct:** fix addRow rowInfo ([88768eb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/88768eb)) +* **storage-manager:** correctly use encryption key in decrypt call ([2667aac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2667aac)) +* **storage-manager:** post salt and timestamp only when fetching key ([6340509](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6340509)) +* fix webpack config ([50e4212](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/50e4212)) +* **exam-correct:** correctly htmlify user on failure ([ef34755](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ef34755)) +* **exam-correct:** correctly htmlify user on failure ([595f46d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/595f46d)) +* **exam-correct:** fix addRow rowInfo ([792da22](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/792da22)) +* **exam-correct:** fix attributes in template ([62bf73a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/62bf73a)) +* **exam-correct:** fix attributes in template ([000f97c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/000f97c)) +* **exam-correct:** fix hlint ([630194c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/630194c)) +* **exam-correct:** fix hlint ([c520918](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c520918)) +* **exam-correct:** fix returning null if old and new results are equal ([968c6de](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/968c6de)) +* **exam-correct:** fix returning null if old and new results are equal ([2e7bca6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2e7bca6)) +* **exam-correct:** temporarily disable exam results (WIP) ([533e748](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/533e748)) +* **storage-key:** fix types ([a0d067f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a0d067f)) +* **storage-key:** fix types ([a23a473](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a23a473)) +* **storage-manager:** remove and clear SessionStorage ([e42452e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e42452e)) +* **storage-manager:** save salt and timestamp ([0282918](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0282918)) +* better translation for "exam office" ([edbdceb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/edbdceb)) +* design tweaks ([18ae758](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/18ae758)) +* design tweaks ([68eb448](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/68eb448)) +* fix hlint ([e60aef4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e60aef4)) +* **exam-correct:** id on td instead of select ([1d0be2d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1d0be2d)) +* **storage-manager:** remove and clear SessionStorage ([38b0a8e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/38b0a8e)) +* **storage-manager:** save salt and timestamp ([8bee033](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8bee033)) +* **style:** breadcrumb bar width ([7340fc1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7340fc1)) +* do not apply target link height fix on targets in tables ([e7ff384](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e7ff384)) +* fix hlint ([9ecffc8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9ecffc8)) +* fix merge ([d19cca6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d19cca6)) +* fix webpack config ([5393a55](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5393a55)) +* typo ([4c58699](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4c58699)) +* **storage-manager:** correctly use encryption key in decrypt call ([9e9726e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9e9726e)) +* **storage-manager:** post salt and timestamp only when fetching key ([301c88f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/301c88f)) + + +### Features + +* **correction-interface:** wire up ECorrectR ([d8801a3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8801a3)) +* **exam-correct:** add basic interface stub ([623becf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/623becf)) +* **exam-correct:** add sortable style and date column ([87bda16](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/87bda16)) +* **exam-correct:** display backend error messages ([6fc0262](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6fc0262)) +* **exam-correct:** general improvement ([23044b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/23044b2)) +* **exam-correct:** more on frontend name resolving ([905d445](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/905d445)) +* **exam-correct:** more stub ([cbe6495](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cbe6495)) +* **exam-correct:** overwrite request cells from response ([c8edbb3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c8edbb3)) +* **exam-correct:** postECorrectR stub ([5f9a176](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5f9a176)) +* **exam-correct:** return user lookup result even for failure ([8e41820](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8e41820)) +* **exam-correct:** submit on enter ([10de1a7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/10de1a7)) +* **exam-correct:** work on delete ([014036e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/014036e)) +* **hide-columns:** don't break on dom changes ([c519792](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c519792)) +* pageactions for exam correct interface ([0d4dcf8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d4dcf8)) +* refine presentation of exam-correct ([95c1755](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/95c1755)) +* **exam-correct:** persist results and more ([a7cc24b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a7cc24b)) +* **exam-correct:** request refactor and handling of sent uuids ([f06ca00](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f06ca00)) +* **exam-correct:** resend option on ambiguous entries (TODO refactor) ([512f4d9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/512f4d9)) +* **exam-correct:** server date handling in frontend and refactor ([77e39be](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/77e39be)) +* **exam-correct:** setup basic session storage manager, add util stub ([9cb64f2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9cb64f2)) +* **exam-correct:** single runDB in POST handler; more response handling ([4cb62f8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4cb62f8)) +* **exam-correct:** status icons (wip) ([3cc6814](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3cc6814)) +* **exam-correct:** stub ([90359c8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/90359c8)) +* **exam-correct:** upsert exam part results (TODO) ([c0f91bc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c0f91bc)) +* **exam-correct:** use examId instead as uw-exam-correct value ([2d9a877](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2d9a877)) +* **exam-correct:** validate user input stub ([7f04862](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7f04862)) +* **pageactions:** finish restoration ([e1cac76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e1cac76)) +* **pageactions:** restore pageactions ([4bc48a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4bc48a5)) +* **pageactions:** restore pageactions ([926bd44](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/926bd44)) +* **sort-table:** add basic SortTable util stub ([53131e2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/53131e2)) +* **storage-key:** add breadcrumb and import ([8cf5d63](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8cf5d63)) +* **storage-key:** add StorageKeyR to routes; minor Handler refactor ([2d1d58f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2d1d58f)) +* **storage-key:** postStorageKeyR ([059efe5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/059efe5)) +* **storage-manager:** add en-/decryption stub (WIP) and restructure ([54d852f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/54d852f)) +* improve navigation ([95ffda2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/95ffda2)) +* navbar header containers ([1348c91](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1348c91)) +* restore & improve navbar contents ([51fc6dc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/51fc6dc)) +* **exam-correct:** examResult interface, no styling or functionality ([970076e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/970076e)) +* rename "Start" to "Beginn" in error messages ([66bd10e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/66bd10e)) +* renamed "Bewertung abgeschlossen ab" to "Ergebnisse sichtbar ab" ([6b610e1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6b610e1)) +* **correction-interface:** wire up ECorrectR ([df66c9b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/df66c9b)) +* **exam-correct:** accept grades besides exam part results ([be187ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/be187ae)) +* **exam-correct:** add basic interface stub ([cb7c9ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb7c9ac)) +* **exam-correct:** add sortable style and date column ([9fa4245](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9fa4245)) +* **exam-correct:** more on frontend name resolving ([daf9eee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/daf9eee)) +* **exam-correct:** more stub ([6727dff](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6727dff)) +* **exam-correct:** persist results and more ([53ff629](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/53ff629)) +* **exam-correct:** postECorrectR stub ([a525cab](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a525cab)) +* **exam-correct:** request refactor and handling of sent uuids ([4a36a01](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4a36a01)) +* **exam-correct:** resend option on ambiguous entries (TODO refactor) ([e252be2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e252be2)) +* **exam-correct:** server date handling in frontend and refactor ([d8a080d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8a080d)) +* **exam-correct:** setup basic session storage manager, add util stub ([9a79156](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9a79156)) +* **exam-correct:** single runDB in POST handler; more response handling ([6837c44](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6837c44)) +* **exam-correct:** status icons (wip) ([eefff9f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/eefff9f)) +* **exam-correct:** stub ([0467194](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0467194)) +* **exam-correct:** upsert exam part results (TODO) ([650598f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/650598f)) +* **exam-correct:** use examId instead as uw-exam-correct value ([5d7427a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5d7427a)) +* **exam-correct:** validate user input stub ([431d004](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/431d004)) +* **sort-table:** add basic SortTable util stub ([11c0bd0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/11c0bd0)) +* **storage-key:** add breadcrumb and import ([1580d3f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1580d3f)) +* **storage-key:** add StorageKeyR to routes; minor Handler refactor ([4d4dc8f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4d4dc8f)) +* **storage-key:** postStorageKeyR ([b51c466](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b51c466)) +* **storage-manager:** add en-/decryption stub (WIP) and restructure ([0016145](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0016145)) +* **storage-manager:** store encryption info per location ([25a7c34](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/25a7c34)) +* **storage-manager:** store encryption info per location ([8122ab1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8122ab1)) + + +### BREAKING CHANGES + +* major navigation refactor + + + ## [10.6.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v10.5.0...v10.6.0) (2020-01-30) diff --git a/package-lock.json b/package-lock.json index 2af106ef1..e3ca8f108 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "10.6.0", + "version": "11.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 43d4d1d47..f0f59b1b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "10.6.0", + "version": "11.0.0", "description": "", "keywords": [], "author": "", diff --git a/package.yaml b/package.yaml index c7001df09..9d6d466d6 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: uniworx -version: 10.6.0 +version: 11.0.0 dependencies: - base