fixed some issues with forms and (auto)update of exams
This commit is contained in:
parent
31b0c4f7da
commit
eb122c7399
9 changed files with 69 additions and 42 deletions
|
@ -377,7 +377,7 @@ public final class Exam implements GrantEntity {
|
||||||
} else if (endTime != null && now.isAfter(endTime)) {
|
} else if (endTime != null && now.isAfter(endTime)) {
|
||||||
return ExamStatus.FINISHED;
|
return ExamStatus.FINISHED;
|
||||||
} else {
|
} else {
|
||||||
return ExamStatus.UP_COMING;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@ public class ExamForm implements TemplateComposer {
|
||||||
new LocTextKey("sebserver.exam.form.name");
|
new LocTextKey("sebserver.exam.form.name");
|
||||||
private static final LocTextKey FORM_QUIZID_TEXT_KEY =
|
private static final LocTextKey FORM_QUIZID_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.quizid");
|
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 =
|
private static final LocTextKey FORM_LMSSETUP_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.lmssetup");
|
new LocTextKey("sebserver.exam.form.lmssetup");
|
||||||
|
|
||||||
|
@ -243,7 +245,10 @@ public class ExamForm implements TemplateComposer {
|
||||||
|
|
||||||
// The Exam form
|
// The Exam form
|
||||||
final FormHandle<Exam> formHandle = this.pageService.formBuilder(
|
final FormHandle<Exam> formHandle = this.pageService.formBuilder(
|
||||||
formContext.copyOf(content), 4)
|
formContext.copyOf(content), 8)
|
||||||
|
.withDefaultSpanLabel(1)
|
||||||
|
.withDefaultSpanInput(4)
|
||||||
|
.withDefaultSpanEmptyCell(3)
|
||||||
.readonly(readonly)
|
.readonly(readonly)
|
||||||
.putStaticValueIf(isNotNew,
|
.putStaticValueIf(isNotNew,
|
||||||
Domain.EXAM.ATTR_ID,
|
Domain.EXAM.ATTR_ID,
|
||||||
|
@ -263,48 +268,75 @@ public class ExamForm implements TemplateComposer {
|
||||||
.putStaticValueIf(isNew,
|
.putStaticValueIf(isNew,
|
||||||
QuizData.QUIZ_ATTR_ID,
|
QuizData.QUIZ_ATTR_ID,
|
||||||
exam.externalId)
|
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(
|
.addField(FormBuilder.singleSelection(
|
||||||
Domain.EXAM.ATTR_LMS_SETUP_ID,
|
Domain.EXAM.ATTR_LMS_SETUP_ID,
|
||||||
FORM_LMSSETUP_TEXT_KEY,
|
FORM_LMSSETUP_TEXT_KEY,
|
||||||
String.valueOf(exam.lmsSetupId),
|
String.valueOf(exam.lmsSetupId),
|
||||||
this.resourceService::lmsSetupResource)
|
this.resourceService::lmsSetupResource)
|
||||||
.readonly(true))
|
.readonly(true)
|
||||||
.addField(FormBuilder.text(
|
.withInputSpan(3)
|
||||||
Domain.EXAM.ATTR_EXTERNAL_ID,
|
.withEmptyCellSeparation(false))
|
||||||
FORM_QUIZID_TEXT_KEY,
|
|
||||||
exam.externalId)
|
|
||||||
.readonly(true))
|
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_NAME,
|
QuizData.QUIZ_ATTR_NAME,
|
||||||
FORM_NAME_TEXT_KEY,
|
FORM_NAME_TEXT_KEY,
|
||||||
exam.name)
|
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(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_DESCRIPTION,
|
QuizData.QUIZ_ATTR_DESCRIPTION,
|
||||||
FORM_DESCRIPTION_TEXT_KEY,
|
FORM_DESCRIPTION_TEXT_KEY,
|
||||||
exam.description)
|
exam.description)
|
||||||
.asArea()
|
.asArea()
|
||||||
.readonly(true))
|
.readonly(true)
|
||||||
|
.withInputSpan(6)
|
||||||
|
.withEmptyCellSeparation(false))
|
||||||
|
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_START_TIME,
|
QuizData.QUIZ_ATTR_START_TIME,
|
||||||
FORM_STARTTIME_TEXT_KEY,
|
FORM_STARTTIME_TEXT_KEY,
|
||||||
i18nSupport.formatDisplayDate(exam.startTime))
|
i18nSupport.formatDisplayDate(exam.startTime))
|
||||||
.readonly(true))
|
.readonly(true)
|
||||||
|
.withInputSpan(3)
|
||||||
|
.withEmptyCellSpan(1))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_END_TIME,
|
QuizData.QUIZ_ATTR_END_TIME,
|
||||||
FORM_ENDTIME_TEXT_KEY,
|
FORM_ENDTIME_TEXT_KEY,
|
||||||
i18nSupport.formatDisplayDate(exam.endTime))
|
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(
|
.addField(FormBuilder.singleSelection(
|
||||||
Domain.EXAM.ATTR_TYPE,
|
Domain.EXAM.ATTR_TYPE,
|
||||||
FORM_TYPE_TEXT_KEY,
|
FORM_TYPE_TEXT_KEY,
|
||||||
String.valueOf(exam.type),
|
String.valueOf(exam.type),
|
||||||
this.resourceService::examTypeResources))
|
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(
|
.addField(FormBuilder.multiComboSelection(
|
||||||
Domain.EXAM.ATTR_SUPPORTER,
|
Domain.EXAM.ATTR_SUPPORTER,
|
||||||
FORM_SUPPORTER_TEXT_KEY,
|
FORM_SUPPORTER_TEXT_KEY,
|
||||||
|
|
|
@ -287,11 +287,21 @@ public class FormBuilder {
|
||||||
final String defaultText,
|
final String defaultText,
|
||||||
final int hspan) {
|
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(
|
final Label label = this.widgetFactory.labelLocalized(
|
||||||
parent,
|
parent,
|
||||||
locTextKey,
|
locTextKey,
|
||||||
(StringUtils.isNotBlank(defaultText) ? defaultText : locTextKey.name));
|
(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;
|
gridData.heightHint = FORM_ROW_HEIGHT;
|
||||||
label.setLayoutData(gridData);
|
label.setLayoutData(gridData);
|
||||||
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
||||||
|
|
|
@ -60,7 +60,8 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
||||||
builder.formParent,
|
builder.formParent,
|
||||||
this.label,
|
this.label,
|
||||||
this.defaultLabel,
|
this.defaultLabel,
|
||||||
this.spanLabel)
|
this.spanLabel,
|
||||||
|
SWT.TOP)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
if (builder.readonly || this.readonly) {
|
if (builder.readonly || this.readonly) {
|
||||||
|
@ -103,7 +104,8 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
||||||
if (this.type == Type.MULTI || this.type == Type.MULTI_COMBO) {
|
if (this.type == Type.MULTI || this.type == Type.MULTI_COMBO) {
|
||||||
final Composite composite = new Composite(builder.formParent, SWT.NONE);
|
final Composite composite = new Composite(builder.formParent, SWT.NONE);
|
||||||
final GridLayout gridLayout = new GridLayout(1, true);
|
final GridLayout gridLayout = new GridLayout(1, true);
|
||||||
gridLayout.verticalSpacing = 5;
|
//gridLayout.verticalSpacing = 5;
|
||||||
|
gridLayout.marginBottom = 5;
|
||||||
gridLayout.horizontalSpacing = 0;
|
gridLayout.horizontalSpacing = 0;
|
||||||
gridLayout.marginLeft = 0;
|
gridLayout.marginLeft = 0;
|
||||||
gridLayout.marginHeight = 0;
|
gridLayout.marginHeight = 0;
|
||||||
|
|
|
@ -61,7 +61,8 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
|
||||||
builder.formParent,
|
builder.formParent,
|
||||||
this.label,
|
this.label,
|
||||||
this.defaultLabel,
|
this.defaultLabel,
|
||||||
this.spanLabel)
|
this.spanLabel,
|
||||||
|
(this.isArea) ? SWT.TOP : SWT.CENTER)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
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.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
||||||
|
@ -49,7 +48,6 @@ class ExamSessionControlTask {
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
@Scheduled(cron = "${sebserver.webservice.api.exam.update-interval:1 * * * * *}")
|
@Scheduled(cron = "${sebserver.webservice.api.exam.update-interval:1 * * * * *}")
|
||||||
@Transactional
|
|
||||||
public void execTask() {
|
public void execTask() {
|
||||||
|
|
||||||
final String updateId = this.examUpdateHandler.createUpdateId();
|
final String updateId = this.examUpdateHandler.createUpdateId();
|
||||||
|
@ -70,7 +68,6 @@ class ExamSessionControlTask {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||||
|
|
||||||
final Map<Long, String> updated = this.examDAO.allForRunCheck()
|
final Map<Long, String> updated = this.examDAO.allForRunCheck()
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
|
|
|
@ -91,7 +91,8 @@ class ExamUpdateHandler {
|
||||||
ExamStatus.RUNNING)))
|
ExamStatus.RUNNING)))
|
||||||
.flatMap(this::applySebClientRestriction)
|
.flatMap(this::applySebClientRestriction)
|
||||||
.flatMap(e -> this.examDAO.releaseLock(e.id, updateId))
|
.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();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,7 @@ sebserver.exam.form.title.import=Import Exam
|
||||||
sebserver.exam.form.title=Exam
|
sebserver.exam.form.title=Exam
|
||||||
sebserver.exam.form.lmssetup=LMS Setup
|
sebserver.exam.form.lmssetup=LMS Setup
|
||||||
sebserver.exam.form.quizid=Quiz Identifier
|
sebserver.exam.form.quizid=Quiz Identifier
|
||||||
|
sebserver.exam.form.quizurl=Quiz URL
|
||||||
sebserver.exam.form.name=Name
|
sebserver.exam.form.name=Name
|
||||||
sebserver.exam.form.description=Description
|
sebserver.exam.form.description=Description
|
||||||
sebserver.exam.form.starttime=Start Time
|
sebserver.exam.form.starttime=Start Time
|
||||||
|
|
Loading…
Reference in a new issue