SEBSERV-73 exam config <-> exam attachment handling

This commit is contained in:
anhefti 2019-10-24 15:34:26 +02:00
parent bac8aba3eb
commit a0bb0db5ed
8 changed files with 96 additions and 12 deletions

View file

@ -8,6 +8,8 @@
package ch.ethz.seb.sebserver.gui.content;
import java.util.Arrays;
import java.util.HashSet;
import java.util.function.Function;
import org.eclipse.rap.rwt.RWT;
@ -22,6 +24,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
@ -38,6 +41,7 @@ import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
@ -90,6 +94,8 @@ public class SebExamConfigPropForm implements TemplateComposer {
new LocTextKey("sebserver.examconfig.form.config-key.title");
static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY =
new LocTextKey("sebserver.examconfig.action.import-config.confirm");
static final LocTextKey FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY =
new LocTextKey("sebserver.examconfig.form.attched-to");
static final LocTextKey FORM_COPY_TEXT_KEY =
new LocTextKey("sebserver.examconfig.action.copy");
@ -144,7 +150,7 @@ public class SebExamConfigPropForm implements TemplateComposer {
final boolean writeGrant = entityGrant.w();
final boolean modifyGrant = entityGrant.m();
final boolean isReadonly = pageContext.isReadonly();
final boolean isAttachedToExam = this.restService
final boolean isAttachedToExam = !isNew && this.restService
.getBuilder(GetExamConfigMappingNames.class)
.withQueryParam(ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId())
.call()
@ -264,6 +270,12 @@ public class SebExamConfigPropForm implements TemplateComposer {
.publishIf(() -> !isReadonly);
if (isAttachedToExam) {
widgetFactory.labelLocalized(
content,
CustomVariant.TEXT_H3,
FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY);
final EntityTable<ExamConfigurationMap> table =
this.pageService.entityTableBuilder(this.restService.getRestCall(GetExamConfigMappingsPage.class))
.withRestCallAdapter(restCall -> restCall.withQueryParam(
@ -289,21 +301,42 @@ public class SebExamConfigPropForm implements TemplateComposer {
ExamList.COLUMN_TITLE_TYPE_KEY,
resourceService::localizedExamTypeName))
.withDefaultAction(actionBuilder
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.create())
.withDefaultAction(this::showExamAction)
.compose(pageContext.copyOf(content));
actionBuilder
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection,
ExamList.EMPTY_SELECTION_TEXT_KEY)
.withExec(pageAction -> {
final ExamConfigurationMap selectedExamMapping = getSelectedExamMapping(table);
return pageAction.withEntityKey(
new EntityKey(selectedExamMapping.examId, EntityType.EXAM));
})
.publishIf(table::hasAnyContent);
}
}
private PageAction showExamAction(final EntityTable<ExamConfigurationMap> table) {
return this.pageService.pageActionBuilder(table.getPageContext())
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelectionSupplier(() -> {
final ExamConfigurationMap selectedROWData = getSelectedExamMapping(table);
return new HashSet<>(Arrays.asList(new EntityKey(selectedROWData.examId, EntityType.EXAM)));
})
.withExec(PageAction::applySingleSelection)
.create();
}
private ExamConfigurationMap getSelectedExamMapping(final EntityTable<ExamConfigurationMap> table) {
final ExamConfigurationMap selectedROWData = table.getSelectedROWData();
if (selectedROWData == null) {
throw new PageMessageException(ExamList.EMPTY_SELECTION_TEXT_KEY);
}
return selectedROWData;
}
private LocTextKey stateChangeConfirm(
final boolean isAttachedToExam,
final FormHandle<ConfigurationNode> formHandle) {

View file

@ -240,7 +240,7 @@ public enum ActionDefinition {
EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP(
new LocTextKey("sebserver.examconfig.action.view"),
ImageIcon.SHOW,
PageStateDefinitionImpl.SEB_EXAM_CONFIG_VIEW,
PageStateDefinitionImpl.SEB_EXAM_CONFIG_PROP_VIEW,
ActionCategory.EXAM_CONFIG_MAPPING_LIST),
EXAM_CONFIGURATION_DELETE_FROM_LIST(
new LocTextKey("sebserver.exam.configuration.action.list.delete"),

View file

@ -57,11 +57,11 @@ import ch.ethz.seb.sebserver.gbl.util.Tuple;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodeNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodes;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViews;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccountNames;
@ -371,7 +371,13 @@ public class ResourceService {
public List<Tuple<String>> examConfigStatusResources(final boolean isAttachedToExam) {
return Arrays.asList(ConfigurationStatus.values())
.stream()
.filter(status -> !isAttachedToExam || status != ConfigurationStatus.READY_TO_USE)
.filter(status -> {
if (isAttachedToExam) {
return status != ConfigurationStatus.READY_TO_USE;
} else {
return status != ConfigurationStatus.IN_USE;
}
})
.map(type -> new Tuple<>(
type.name(),
this.i18nSupport.getText(EXAMCONFIG_STATUS_PREFIX + type.name())))
@ -580,7 +586,7 @@ public class ResourceService {
}
private Result<List<EntityName>> getExamConfigurationSelection() {
return this.restService.getBuilder(GetExamConfigMappingNames.class)
return this.restService.getBuilder(GetExamConfigNodeNames.class)
.withQueryParam(
Entity.FILTER_ATTR_INSTITUTION,
String.valueOf(this.currentUser.get().institutionId))

View file

@ -121,6 +121,8 @@ public final class PageAction {
confirm -> callback.accept((confirm)
? exec()
: Result.ofRuntimeError("Confirm denied")));
} else {
callback.accept(exec());
}
} else {
callback.accept(exec());

View file

@ -36,7 +36,7 @@ public class GetExamConfigMappingNames extends RestCall<List<EntityName>> {
}),
HttpMethod.GET,
MediaType.APPLICATION_FORM_URLENCODED,
API.CONFIGURATION_NODE_ENDPOINT + API.NAMES_PATH_SEGMENT);
API.EXAM_CONFIGURATION_MAP_ENDPOINT + API.NAMES_PATH_SEGMENT);
}
}

View file

@ -0,0 +1,42 @@
/*
* 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.service.remote.webservice.api.seb.examconfig;
import java.util.List;
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.EntityName;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
@Lazy
@Component
@GuiProfile
public class GetExamConfigNodeNames extends RestCall<List<EntityName>> {
public GetExamConfigNodeNames() {
super(new TypeKey<>(
CallType.GET_NAMES,
EntityType.CONFIGURATION_NODE,
new TypeReference<List<EntityName>>() {
}),
HttpMethod.GET,
MediaType.APPLICATION_FORM_URLENCODED,
API.CONFIGURATION_NODE_ENDPOINT + API.NAMES_PATH_SEGMENT);
}
}

View file

@ -330,7 +330,7 @@ class ConfigurationDAOBatchService {
.selectByPrimaryKey(copyInfo.configurationNodeId);
if (!sourceNode.getInstitutionId().equals(institutionId)) {
new IllegalArgumentException("Institution integrity violation");
throw new IllegalArgumentException("Institution integrity violation");
}
return this.copyNodeRecord(sourceNode, newOwner, copyInfo);

View file

@ -467,6 +467,7 @@ sebserver.examconfig.form.with-history=With History
sebserver.examconfig.form.template=From Template
sebserver.examconfig.form.status=Status
sebserver.examconfig.form.config-key.title=Config Key
sebserver.examconfig.form.attched-to=Attached To Exam
sebserver.examconfig.status.CONSTRUCTION=Under Construction
sebserver.examconfig.status.READY_TO_USE=Ready To Use