diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java index 1e636b78..6eaca372 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java @@ -118,6 +118,7 @@ public final class API { public static final String EXAM_ADMINISTRATION_CONSISTENCY_CHECK_PATH_SEGMENT = "/check-consistency"; public static final String EXAM_ADMINISTRATION_SEB_RESTRICTION_PATH_SEGMENT = "/seb-restriction"; public static final String EXAM_ADMINISTRATION_CHECK_RESTRICTION_PATH_SEGMENT = "/check-seb-restriction"; + public static final String EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT = "/check-imported"; public static final String EXAM_INDICATOR_ENDPOINT = "/indicator"; 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 58214a90..31b4ece2 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 @@ -400,6 +400,7 @@ public class ExamForm implements TemplateComposer { .withURIVariable(API.PARAM_MODEL_ID, String.valueOf(exam.lmsSetupId)) .call() .getOrThrow().lmsType.name()) + .withAttribute(PageContext.AttributeKeys.FORCE_READ_ONLY, String.valueOf(!modifyGrant)) .noEventPropagation() .publishIf(() -> sebRestrictionAvailable && readonly) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebRestrictionSettings.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebRestrictionSettings.java index 1be69f8b..bd2c6d45 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebRestrictionSettings.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebRestrictionSettings.java @@ -16,6 +16,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.swt.widgets.Composite; @@ -104,6 +105,12 @@ public class ExamSebRestrictionSettings { final PageContext pageContext, final FormHandle formHandle) { + final boolean isReadonly = BooleanUtils.toBoolean( + pageContext.getAttribute(PageContext.AttributeKeys.FORCE_READ_ONLY)); + if (isReadonly) { + return true; + } + final EntityKey entityKey = pageContext.getEntityKey(); final LmsType lmsType = getLmsType(pageContext); SebRestriction bodyValue = null; @@ -170,6 +177,8 @@ public class ExamSebRestrictionSettings { final ResourceService resourceService = this.pageService.getResourceService(); final EntityKey entityKey = this.pageContext.getEntityKey(); final LmsType lmsType = getLmsType(this.pageContext); + final boolean isReadonly = BooleanUtils.toBoolean( + this.pageContext.getAttribute(PageContext.AttributeKeys.FORCE_READ_ONLY)); final Composite content = this.pageService .getWidgetFactory() @@ -189,12 +198,12 @@ public class ExamSebRestrictionSettings { formContext) .withDefaultSpanInput(6) .withEmptyCellSeparation(false) - .readonly(false) + .readonly(isReadonly) .addField(FormBuilder.text( "Info", SEB_RESTRICTION_FORM_INFO, - pageService.getI18nSupport().getText(SEB_RESTRICTION_FORM_INFO_TEXT)) + this.pageService.getI18nSupport().getText(SEB_RESTRICTION_FORM_INFO_TEXT)) .asArea(50) .asHTML() .readonly(true)) @@ -254,6 +263,7 @@ public class ExamSebRestrictionSettings { return () -> formHandle; } + } private static LmsType getLmsType(final PageContext pageContext) { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizLookupList.java similarity index 93% rename from src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/QuizLookupList.java index 48f3fae0..8c3392b5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizLookupList.java @@ -13,7 +13,6 @@ import java.util.Collection; import java.util.function.BooleanSupplier; import java.util.function.Function; -import ch.ethz.seb.sebserver.gbl.Constants; import org.eclipse.swt.widgets.Composite; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -21,6 +20,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; @@ -43,6 +44,7 @@ import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.CheckExamImported; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizPage; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck; @@ -55,7 +57,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component @GuiProfile -public class QuizDiscoveryList implements TemplateComposer { +public class QuizLookupList implements TemplateComposer { // localized text keys @@ -93,6 +95,8 @@ public class QuizDiscoveryList implements TemplateComposer { new LocTextKey("sebserver.quizdiscovery.quiz.details.endtime"); private final static LocTextKey NO_IMPORT_OF_OUT_DATED_QUIZ = new LocTextKey("sebserver.quizdiscovery.quiz.import.out.dated"); + private final static LocTextKey TEXT_KEY_CONFIRM_EXISTING = + new LocTextKey("sebserver.quizdiscovery.quiz.import.existing.confirm"); private final static String TEXT_KEY_ADDITIONAL_ATTR_PREFIX = "sebserver.quizdiscovery.quiz.details.additional."; @@ -109,7 +113,7 @@ public class QuizDiscoveryList implements TemplateComposer { private final PageService pageService; private final int pageSize; - protected QuizDiscoveryList( + protected QuizLookupList( final PageService pageService, final ResourceService resourceService, @Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) { @@ -232,6 +236,7 @@ public class QuizDiscoveryList implements TemplateComposer { .publishIf(table::hasAnyContent, false) .newAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT) + .withConfirm(importQuizConfirm(table, restService)) .withSelect( table::getSelection, action -> this.importQuizData(action, table), @@ -244,7 +249,31 @@ public class QuizDiscoveryList implements TemplateComposer { .apply(String.valueOf(quizData.lmsSetupId)); } - private PageAction importQuizData(final PageAction action, final EntityTable table) { + private Function importQuizConfirm( + final EntityTable table, + final RestService restService) { + + return action -> { + action.getSingleSelection(); + final QuizData selectedROWData = table.getSingleSelectedROWData(); + + final Collection existingImports = restService.getBuilder(CheckExamImported.class) + .withURIVariable(API.PARAM_MODEL_ID, selectedROWData.id) + .call() + .getOrThrow(); + + if (existingImports != null && !existingImports.isEmpty()) { + return TEXT_KEY_CONFIRM_EXISTING; + } else { + return null; + } + }; + } + + private PageAction importQuizData( + final PageAction action, + final EntityTable table) { + action.getSingleSelection(); final QuizData selectedROWData = table.getSingleSelectedROWData(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinitionImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinitionImpl.java index d6eca5f7..2f43138d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinitionImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinitionImpl.java @@ -21,7 +21,7 @@ import ch.ethz.seb.sebserver.gui.content.LmsSetupList; import ch.ethz.seb.sebserver.gui.content.MonitoringClientConnection; import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExam; import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExamList; -import ch.ethz.seb.sebserver.gui.content.QuizDiscoveryList; +import ch.ethz.seb.sebserver.gui.content.QuizLookupList; import ch.ethz.seb.sebserver.gui.content.SebClientConfigForm; import ch.ethz.seb.sebserver.gui.content.SebClientConfigList; import ch.ethz.seb.sebserver.gui.content.SebClientLogs; @@ -52,7 +52,7 @@ public enum PageStateDefinitionImpl implements PageStateDefinition { LMS_SETUP_VIEW(Type.FORM_VIEW, LmsSetupForm.class, ActivityDefinition.LMS_SETUP), LMS_SETUP_EDIT(Type.FORM_EDIT, LmsSetupForm.class, ActivityDefinition.LMS_SETUP), - QUIZ_LIST(Type.LIST_VIEW, QuizDiscoveryList.class, ActivityDefinition.QUIZ_DISCOVERY), + QUIZ_LIST(Type.LIST_VIEW, QuizLookupList.class, ActivityDefinition.QUIZ_DISCOVERY), EXAM_LIST(Type.LIST_VIEW, ExamList.class, ActivityDefinition.EXAM), EXAM_VIEW(Type.FORM_VIEW, ExamForm.class, ActivityDefinition.EXAM), 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 a586d5c8..7d624aa2 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 @@ -14,7 +14,6 @@ import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; -import ch.ethz.seb.sebserver.gui.service.page.PageService; import org.apache.commons.lang3.StringUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; @@ -28,6 +27,7 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService; +import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.widget.Selection; import ch.ethz.seb.sebserver.gui.widget.Selection.Type; @@ -73,7 +73,7 @@ public final class SelectionFieldBuilder extends FieldBuilder { this.type, fieldGrid, this.itemsSupplier, - (builder.pageService.getFormTooltipMode() == PageService.FormTooltipMode.INPUT) ? tooltip : null, + (builder.pageService.getFormTooltipMode() == PageService.FormTooltipMode.INPUT) ? this.tooltip : null, null, actionKey); @@ -108,7 +108,7 @@ public final class SelectionFieldBuilder extends FieldBuilder { final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true); label.setLayoutData(gridData); - label.setText(this.value); + label.setText((this.value != null) ? this.value : Constants.EMPTY_NOTE); } else { final Collection keys = Arrays.asList(StringUtils.split(this.value, Constants.LIST_SEPARATOR)); this.itemsSupplier.get() diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java index 7bf1367c..95041c95 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java @@ -32,6 +32,7 @@ public interface PageContext { String PAGE_TEMPLATE_COMPOSER_NAME = "ATTR_PAGE_TEMPLATE_COMPOSER_NAME"; String READ_ONLY = "READ_ONLY"; + String FORCE_READ_ONLY = "FORCE_READ_ONLY"; String READ_ONLY_FROM = "READ_ONLY_FROM"; String ENTITY_ID = "ENTITY_ID"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java index f981ebfc..f45d06bd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java @@ -129,8 +129,9 @@ public interface PageService { * * @param table the entity table * @param noSelectionText LocTextKey for missing selection message - * @param testBeforeActivation a function to test before activation. This function shall throw an error if test fails. - * My be null if no specific test is needed before activation + * @param testBeforeActivation a function to test before activation. This function shall throw an error if test + * fails. + * My be null if no specific test is needed before activation * @return page action execution function for switching the activity */ Function activationToggleActionFunction( EntityTable table, @@ -144,8 +145,8 @@ public interface PageService { * @param noSelectionText LocTextKey for missing selection message * @return page action execution function for switching the activity */ default Function activationToggleActionFunction( - EntityTable table, - LocTextKey noSelectionText) { + final EntityTable table, + final LocTextKey noSelectionText) { return this.activationToggleActionFunction(table, noSelectionText, null); } @@ -399,7 +400,7 @@ public interface PageService { private PageContext pageContext; private ActionDefinition definition; - private Supplier confirm; + private Function confirm; private LocTextKey successMessage; private Supplier> selectionSupplier; private LocTextKey noSelectionMessage; @@ -508,6 +509,11 @@ public interface PageService { } public PageActionBuilder withConfirm(final Supplier confirm) { + this.confirm = action -> confirm.get(); + return this; + } + + public PageActionBuilder withConfirm(final Function confirm) { this.confirm = confirm; return this; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java index b5f4adac..e8af5979 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java @@ -35,7 +35,7 @@ public final class PageAction { private static final Logger log = LoggerFactory.getLogger(PageAction.class); public final ActionDefinition definition; - private final Supplier confirm; + private final Function confirm; private final Supplier> selectionSupplier; private final LocTextKey noSelectionMessage; private PageContext pageContext; @@ -48,7 +48,7 @@ public final class PageAction { public PageAction( final ActionDefinition definition, - final Supplier confirm, + final Function confirm, final LocTextKey successMessage, final Supplier> selectionSupplier, final LocTextKey noSelectionMessage, @@ -154,7 +154,7 @@ public final class PageAction { } } - final LocTextKey confirmMessage = this.confirm.get(); + final LocTextKey confirmMessage = this.confirm.apply(this); if (confirmMessage != null) { this.pageContext.applyConfirmDialog(confirmMessage, confirm -> callback.accept((confirm) @@ -198,9 +198,6 @@ public final class PageAction { PageAction.this.getName(), e.getMessage(), Utils.getErrorCauseMessage(e)); - PageAction.this.pageContext.notifyError( - PageContext.UNEXPECTED_ERROR_KEY, - e); return Result.ofError(e); } catch (final Exception e) { log.error("Failed to execute action: {} | error: {} | cause: {}", diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/CheckExamImported.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/CheckExamImported.java new file mode 100644 index 00000000..917687bf --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/CheckExamImported.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 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.service.remote.webservice.api.exam; + +import java.util.Collection; + +import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; + +@Lazy +@Component +@GuiProfile +public class CheckExamImported extends RestCall> { + + public CheckExamImported() { + super(new TypeKey<>( + CallType.UNDEFINED, + EntityType.EXAM, + new TypeReference>() { + }), + HttpMethod.GET, + MediaType.APPLICATION_FORM_URLENCODED, + API.EXAM_ADMINISTRATION_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java index 8245d124..2ae97151 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java @@ -28,6 +28,8 @@ public interface ExamDAO extends ActivatableEntityDAO, BulkActionSup * happened */ Result> allIdsOfInstitution(Long institutionId); + Result> allByQuizId(String quizId); + /** Updates the exam status for specified exam * * @param examId The exam identifier diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index d55e8671..40275d18 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -111,6 +111,24 @@ public class ExamDAOImpl implements ExamDAO { .flatMap(this::toDomainModel); } + @Override + public Result> allByQuizId(final String quizId) { + return Result.tryCatch(() -> { + return this.examRecordMapper.selectByExample() + .where( + ExamRecordDynamicSqlSupport.externalId, + isEqualToWhenPresent(quizId)) + .and( + ExamRecordDynamicSqlSupport.active, + isEqualToWhenPresent(BooleanUtils.toIntegerObject(true))) + .build() + .execute() + .stream() + .map(rec -> rec.getId()) + .collect(Collectors.toList()); + }); + } + @Override @Transactional(readOnly = true) public Result> allMatching(final FilterMap filterMap, final Predicate predicate) { @@ -258,24 +276,24 @@ public class ExamDAOImpl implements ExamDAO { // used to save instead of create a new one if (records != null && records.size() > 0) { final ExamRecord examRecord = records.get(0); - // if another institution tries to import an exam that already exists - if (!exam.institutionId.equals(examRecord.getInstitutionId())) { - throw new IllegalStateException("Exam cannot be imported twice from different institutions"); - } - final ExamRecord newRecord = new ExamRecord( - examRecord.getId(), - null, null, null, null, null, - (exam.type != null) ? exam.type.name() : ExamType.UNDEFINED.name(), - null, // quitPassword - null, // browser keys - null, // status - null, // lmsSebRestriction (deprecated) - null, // updating - null, // lastUpdate - BooleanUtils.toIntegerObject(exam.active)); + // if the same institution tries to import an exam that already exists + // open the existing. otherwise create new one if requested + if (exam.institutionId.equals(examRecord.getInstitutionId())) { + final ExamRecord newRecord = new ExamRecord( + examRecord.getId(), + null, null, null, null, null, + (exam.type != null) ? exam.type.name() : ExamType.UNDEFINED.name(), + null, // quitPassword + null, // browser keys + null, // status + null, // lmsSebRestriction (deprecated) + null, // updating + null, // lastUpdate + BooleanUtils.toIntegerObject(exam.active)); - this.examRecordMapper.updateByPrimaryKeySelective(newRecord); - return this.examRecordMapper.selectByPrimaryKey(examRecord.getId()); + this.examRecordMapper.updateByPrimaryKeySelective(newRecord); + return this.examRecordMapper.selectByPrimaryKey(examRecord.getId()); + } } final ExamRecord examRecord = new ExamRecord( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java index cc734136..f7aa91c8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java @@ -45,6 +45,7 @@ import ch.ethz.seb.sebserver.gbl.api.POSTMapper; import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; @@ -208,6 +209,27 @@ public class ExamAdministrationController extends EntityController { } } + @RequestMapping( + path = API.MODEL_ID_VAR_PATH_SEGMENT + + API.EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT, + method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public Collection checkImported( + @PathVariable final String modelId, + @RequestParam( + name = API.PARAM_INSTITUTION_ID, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId) { + + checkReadPrivilege(institutionId); + return this.examDAO.allByQuizId(modelId) + .map(ids -> ids + .stream() + .map(id -> new EntityKey(id, EntityType.EXAM)) + .collect(Collectors.toList())) + .getOrThrow(); + } + @RequestMapping( path = API.MODEL_ID_VAR_PATH_SEGMENT + API.EXAM_ADMINISTRATION_CONSISTENCY_CHECK_PATH_SEGMENT, @@ -226,6 +248,9 @@ public class ExamAdministrationController extends EntityController { .getOrThrow(); } + // **************************************************************************** + // **** SEB Restriction + @RequestMapping( path = API.MODEL_ID_VAR_PATH_SEGMENT + API.EXAM_ADMINISTRATION_CHECK_RESTRICTION_PATH_SEGMENT, @@ -244,9 +269,6 @@ public class ExamAdministrationController extends EntityController { .getOrThrow(); } - // **************************************************************************** - // **** SEB Restriction - @RequestMapping( path = API.MODEL_ID_VAR_PATH_SEGMENT + API.EXAM_ADMINISTRATION_SEB_RESTRICTION_PATH_SEGMENT, diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index a84f2909..44ee4010 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -350,6 +350,7 @@ sebserver.quizdiscovery.action.list=LMS Exam Lookup sebserver.quizdiscovery.action.import=Import as Exam sebserver.quizdiscovery.quiz.import.out.dated=The Selected LMS exam is is already finished and can't be imported sebserver.quizdiscovery.action.details=Show LMS Exam Details +sebserver.quizdiscovery.quiz.import.existing.confirm=This course was already imported and import it twice may lead to
unexpected behavior within automated SEB restriction on LMS.

Do you want to import this course as exam anyways? sebserver.quizdiscovery.quiz.details.title=LMS Exam Details sebserver.quizdiscovery.quiz.details.institution=Institution