From eb122c73991bad0e730e7b77df3d2c162792d841 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 18 Nov 2019 11:24:04 +0100 Subject: [PATCH] fixed some issues with forms and (auto)update of exams --- .../seb/sebserver/gbl/model/exam/Exam.java | 2 +- .../seb/sebserver/gui/content/ExamForm.java | 64 ++++++++++++++----- .../seb/sebserver/gui/form/FormBuilder.java | 12 +++- .../gui/form/SelectionFieldBuilder.java | 6 +- .../sebserver/gui/form/TextFieldBuilder.java | 3 +- .../gui/widget/PopupListSelection.java | 17 ----- .../session/impl/ExamSessionControlTask.java | 3 - .../session/impl/ExamUpdateHandler.java | 3 +- src/main/resources/messages.properties | 1 + 9 files changed, 69 insertions(+), 42 deletions(-) delete mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/widget/PopupListSelection.java diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java index eabf6899..7ec51fd4 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java @@ -377,7 +377,7 @@ public final class Exam implements GrantEntity { } else if (endTime != null && now.isAfter(endTime)) { return ExamStatus.FINISHED; } else { - return ExamStatus.UP_COMING; + return null; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java index bdd0dfe3..65a1f5bb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java @@ -108,6 +108,8 @@ public class ExamForm implements TemplateComposer { new LocTextKey("sebserver.exam.form.name"); private static final LocTextKey FORM_QUIZID_TEXT_KEY = new LocTextKey("sebserver.exam.form.quizid"); + private static final LocTextKey FORM_QUIZ_URL_TEXT_KEY = + new LocTextKey("sebserver.exam.form.quizurl"); private static final LocTextKey FORM_LMSSETUP_TEXT_KEY = new LocTextKey("sebserver.exam.form.lmssetup"); @@ -243,7 +245,10 @@ public class ExamForm implements TemplateComposer { // The Exam form final FormHandle formHandle = this.pageService.formBuilder( - formContext.copyOf(content), 4) + formContext.copyOf(content), 8) + .withDefaultSpanLabel(1) + .withDefaultSpanInput(4) + .withDefaultSpanEmptyCell(3) .readonly(readonly) .putStaticValueIf(isNotNew, Domain.EXAM.ATTR_ID, @@ -263,48 +268,75 @@ public class ExamForm implements TemplateComposer { .putStaticValueIf(isNew, QuizData.QUIZ_ATTR_ID, exam.externalId) + + .addField(FormBuilder.text( + Domain.EXAM.ATTR_EXTERNAL_ID, + FORM_QUIZID_TEXT_KEY, + exam.externalId) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSeparation(false)) + .addField(FormBuilder.singleSelection( Domain.EXAM.ATTR_LMS_SETUP_ID, FORM_LMSSETUP_TEXT_KEY, String.valueOf(exam.lmsSetupId), this.resourceService::lmsSetupResource) - .readonly(true)) - .addField(FormBuilder.text( - Domain.EXAM.ATTR_EXTERNAL_ID, - FORM_QUIZID_TEXT_KEY, - exam.externalId) - .readonly(true)) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSeparation(false)) + .addField(FormBuilder.text( QuizData.QUIZ_ATTR_NAME, FORM_NAME_TEXT_KEY, exam.name) - .readonly(true)) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSeparation(false)) + .addField(FormBuilder.text( + QuizData.QUIZ_ATTR_START_URL, + FORM_QUIZ_URL_TEXT_KEY, + exam.startURL) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSeparation(false)) + .addField(FormBuilder.text( QuizData.QUIZ_ATTR_DESCRIPTION, FORM_DESCRIPTION_TEXT_KEY, exam.description) .asArea() - .readonly(true)) + .readonly(true) + .withInputSpan(6) + .withEmptyCellSeparation(false)) + .addField(FormBuilder.text( QuizData.QUIZ_ATTR_START_TIME, FORM_STARTTIME_TEXT_KEY, i18nSupport.formatDisplayDate(exam.startTime)) - .readonly(true)) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSpan(1)) .addField(FormBuilder.text( QuizData.QUIZ_ATTR_END_TIME, FORM_ENDTIME_TEXT_KEY, i18nSupport.formatDisplayDate(exam.endTime)) - .readonly(true)) + .readonly(true) + .withInputSpan(3) + .withEmptyCellSeparation(false)) + + .addField(FormBuilder.text( + Domain.EXAM.ATTR_STATUS + "_display", + FORM_STATUS_TEXT_KEY, + i18nSupport.getText(new LocTextKey("sebserver.exam.status." + examStatus.name()))) + .readonly(true) + .withEmptyCellSeparation(false)) .addField(FormBuilder.singleSelection( Domain.EXAM.ATTR_TYPE, FORM_TYPE_TEXT_KEY, String.valueOf(exam.type), this.resourceService::examTypeResources)) - .addField(FormBuilder.text( - Domain.EXAM.ATTR_STATUS, - FORM_STATUS_TEXT_KEY, - i18nSupport.getText(new LocTextKey("sebserver.exam.status." + examStatus.name()))) - .readonly(true)) + .addField(FormBuilder.multiComboSelection( Domain.EXAM.ATTR_SUPPORTER, FORM_SUPPORTER_TEXT_KEY, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java index 493b0fcd..30921290 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java @@ -287,11 +287,21 @@ public class FormBuilder { final String defaultText, final int hspan) { + return labelLocalized(parent, locTextKey, defaultText, hspan, SWT.CENTER); + } + + Label labelLocalized( + final Composite parent, + final LocTextKey locTextKey, + final String defaultText, + final int hspan, + final int verticalAlignment) { + final Label label = this.widgetFactory.labelLocalized( parent, locTextKey, (StringUtils.isNotBlank(defaultText) ? defaultText : locTextKey.name)); - final GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, true, true, hspan, 1); + final GridData gridData = new GridData(SWT.LEFT, verticalAlignment, true, true, hspan, 1); gridData.heightHint = FORM_ROW_HEIGHT; label.setLayoutData(gridData); label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java index 150e02cc..3a7e9eb2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java @@ -60,7 +60,8 @@ public final class SelectionFieldBuilder extends FieldBuilder { builder.formParent, this.label, this.defaultLabel, - this.spanLabel) + this.spanLabel, + SWT.TOP) : null; if (builder.readonly || this.readonly) { @@ -103,7 +104,8 @@ public final class SelectionFieldBuilder extends FieldBuilder { if (this.type == Type.MULTI || this.type == Type.MULTI_COMBO) { final Composite composite = new Composite(builder.formParent, SWT.NONE); final GridLayout gridLayout = new GridLayout(1, true); - gridLayout.verticalSpacing = 5; + //gridLayout.verticalSpacing = 5; + gridLayout.marginBottom = 5; gridLayout.horizontalSpacing = 0; gridLayout.marginLeft = 0; gridLayout.marginHeight = 0; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java index ad15eb2f..8d5c8c2d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java @@ -61,7 +61,8 @@ public final class TextFieldBuilder extends FieldBuilder { builder.formParent, this.label, this.defaultLabel, - this.spanLabel) + this.spanLabel, + (this.isArea) ? SWT.TOP : SWT.CENTER) : null; final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/PopupListSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/PopupListSelection.java deleted file mode 100644 index 36f75e97..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/PopupListSelection.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package ch.ethz.seb.sebserver.gui.widget; - -public class PopupListSelection { - - public PopupListSelection() { - // TODO Auto-generated constructor stub - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java index 069aff68..68dd1874 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java @@ -19,7 +19,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; @@ -49,7 +48,6 @@ class ExamSessionControlTask { @Async @Scheduled(cron = "${sebserver.webservice.api.exam.update-interval:1 * * * * *}") - @Transactional public void execTask() { final String updateId = this.examUpdateHandler.createUpdateId(); @@ -70,7 +68,6 @@ class ExamSessionControlTask { try { final DateTime now = DateTime.now(DateTimeZone.UTC); - final Map updated = this.examDAO.allForRunCheck() .getOrThrow() .stream() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java index b8593245..722a7d0a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java @@ -91,7 +91,8 @@ class ExamUpdateHandler { ExamStatus.RUNNING))) .flatMap(this::applySebClientRestriction) .flatMap(e -> this.examDAO.releaseLock(e.id, updateId)) - .onError(error -> this.examDAO.forceUnlock(exam.id)) + .onError(error -> this.examDAO.forceUnlock(exam.id) + .onError(unlookError -> log.error("Failed to force unlook update look for exam: {}" + exam.id))) .getOrThrow(); } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 643ef227..887d7354 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -312,6 +312,7 @@ sebserver.exam.form.title.import=Import Exam sebserver.exam.form.title=Exam sebserver.exam.form.lmssetup=LMS Setup sebserver.exam.form.quizid=Quiz Identifier +sebserver.exam.form.quizurl=Quiz URL sebserver.exam.form.name=Name sebserver.exam.form.description=Description sebserver.exam.form.starttime=Start Time