From 17ed7530ee6903dc9922ac90e87c3d7e78035e8b Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 21 Nov 2019 15:35:51 +0100 Subject: [PATCH] SEBSERV-98 done --- .../gui/content/ConfigTemplateForm.java | 2 +- .../seb/sebserver/gui/content/ExamForm.java | 15 +- .../gui/content/ExamSebConfigMapForm.java | 211 -------------- .../gui/content/ExamToConfigBindPopup.java | 266 ++++++++++++++++++ ...s.java => SebExamConfigCreationPopup.java} | 4 +- ...ils.java => SebExamConfigImportPopup.java} | 4 +- .../gui/content/SebExamConfigList.java | 2 +- .../gui/content/SebExamConfigPropForm.java | 6 +- .../content/SebExamConfigSettingsForm.java | 2 +- .../gui/content/action/ActionDefinition.java | 4 +- .../activity/PageStateDefinitionImpl.java | 2 - .../service/page/impl/ModalInputDialog.java | 16 +- .../impl/ConfigurationDAOBatchService.java | 15 + 13 files changed, 308 insertions(+), 241 deletions(-) delete mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebConfigMapForm.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/content/ExamToConfigBindPopup.java rename src/main/java/ch/ethz/seb/sebserver/gui/content/{SebExamConfigCreationUtils.java => SebExamConfigCreationPopup.java} (96%) rename src/main/java/ch/ethz/seb/sebserver/gui/content/{SebExamConfigImportUtils.java => SebExamConfigImportPopup.java} (97%) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java index d495699c..72d0fa9c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java @@ -278,7 +278,7 @@ public class ConfigTemplateForm implements TemplateComposer { .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG) .withEntityKey(entityKey) - .withExec(SebExamConfigCreationUtils.configCreationFunction( + .withExec(SebExamConfigCreationPopup.configCreationFunction( this.pageService, pageContext .withAttribute( 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 b4b6c09c..052f9eb9 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 @@ -54,7 +54,6 @@ 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.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; -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; @@ -113,8 +112,6 @@ public class ExamForm implements TemplateComposer { private static final LocTextKey FORM_LMSSETUP_TEXT_KEY = new LocTextKey("sebserver.exam.form.lmssetup"); - private final static LocTextKey CONFIG_ACTION_NO_CONFIG_MESSAGE = - new LocTextKey("sebserver.exam.configuration.action.noconfig.message"); private final static LocTextKey CONFIG_LIST_TITLE_KEY = new LocTextKey("sebserver.exam.configuration.list.title"); private final static LocTextKey CONFIG_NAME_COLUMN_KEY = @@ -429,20 +426,12 @@ public class ExamForm implements TemplateComposer { EntityType.CONFIGURATION_NODE) : null; - final boolean noConfigsAvailable = this.resourceService - .examConfigurationSelectionResources() - .isEmpty(); - actionBuilder .newAction(ActionDefinition.EXAM_CONFIGURATION_NEW) .withParentEntityKey(entityKey) - .withExec(action -> { - if (noConfigsAvailable) { - throw new PageMessageException(CONFIG_ACTION_NO_CONFIG_MESSAGE); - } - return action; - }) + .withExec(ExamToConfigBindPopup.bindFunction(this.pageService)) + .noEventPropagation() .publishIf(() -> modifyGrant && editable && !configurationTable.hasAnyContent()) .newAction(ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebConfigMapForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebConfigMapForm.java deleted file mode 100644 index 37c23264..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamSebConfigMapForm.java +++ /dev/null @@ -1,211 +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.content; - -import org.apache.commons.lang3.StringUtils; -import org.eclipse.swt.widgets.Composite; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.model.Domain; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; -import ch.ethz.seb.sebserver.gbl.model.exam.Exam; -import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; -import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.form.Form; -import ch.ethz.seb.sebserver.gui.form.FormBuilder; -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.PageService; -import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMapping; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewExamConfigMapping; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExamConfigMapping; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; -import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; - -@Lazy -@Component -@GuiProfile -public class ExamSebConfigMapForm implements TemplateComposer { - - private static final Logger log = LoggerFactory.getLogger(ExamSebConfigMapForm.class); - - private static final LocTextKey NEW_CONFIG_MAPPING_TILE_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.title.new"); - private static final LocTextKey CONFIG_MAPPING_TILE_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.title"); - private static final LocTextKey CONFIG_MAPPING_NAME_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.name"); - private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.description"); - private static final LocTextKey FORM_STATUS_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.status"); - private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.encryptSecret"); - private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY = - new LocTextKey("sebserver.exam.configuration.form.encryptSecret.confirm"); - - private final PageService pageService; - private final ResourceService resourceService; - - protected ExamSebConfigMapForm( - final PageService pageService, - final ResourceService resourceService) { - - this.pageService = pageService; - this.resourceService = resourceService; - } - - @Override - public void compose(final PageContext pageContext) { - final RestService restService = this.resourceService.getRestService(); - final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); - - final EntityKey entityKey = pageContext.getEntityKey(); - final EntityKey parentEntityKey = pageContext.getParentEntityKey(); - final boolean isNew = entityKey == null; - final boolean isReadonly = pageContext.isReadonly(); - - final Exam exam = (isNew) - ? restService - .getBuilder(GetExam.class) - .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId) - .call() - .get(pageContext::notifyError) - : null; - - // get data or create new. Handle error if happen - final ExamConfigurationMap examConfigurationMap = (isNew) - ? ExamConfigurationMap.createNew(exam) - : restService - .getBuilder(GetExamConfigMapping.class) - .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) - .call() - .get(pageContext::notifyError); - - if (examConfigurationMap == null) { - log.error("Failed to get ExamConfigurationMap. " - + "Error is notified to the User. " - + "See previous logs for more infomation"); - return; - } - - // new PageContext with actual EntityKey - final PageContext formContext = pageContext.withEntityKey(examConfigurationMap.getEntityKey()); - - // the default page layout - final LocTextKey titleKey = (isNew) - ? NEW_CONFIG_MAPPING_TILE_TEXT_KEY - : CONFIG_MAPPING_TILE_TEXT_KEY; - final Composite content = widgetFactory.defaultPageLayout( - formContext.getParent(), - titleKey); - - final FormHandle formHandle = this.pageService.formBuilder( - formContext.copyOf(content), 4) - .readonly(isReadonly) - .putStaticValueIf(() -> !isNew, - Domain.EXAM_CONFIGURATION_MAP.ATTR_ID, - examConfigurationMap.getModelId()) - .putStaticValue( - Domain.EXAM_CONFIGURATION_MAP.ATTR_INSTITUTION_ID, - String.valueOf(examConfigurationMap.getInstitutionId())) - .putStaticValue( - Domain.EXAM_CONFIGURATION_MAP.ATTR_EXAM_ID, - String.valueOf(examConfigurationMap.examId)) - - .addField(FormBuilder.singleSelection( - Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID, - CONFIG_MAPPING_NAME_TEXT_KEY, - String.valueOf(examConfigurationMap.configurationNodeId), - this.resourceService::examConfigurationSelectionResources) - .withSelectionListener(this::updateFormValuesFromConfigSelection)) - - .addField(FormBuilder.text( - Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, - FORM_DESCRIPTION_TEXT_KEY, - examConfigurationMap.configDescription) - .asArea() - .readonly(true)) - - .addField(FormBuilder.text( - Domain.CONFIGURATION_NODE.ATTR_STATUS, - FORM_STATUS_TEXT_KEY, - this.resourceService.localizedExamConfigStatusName(examConfigurationMap)) - .readonly(true)) - - .addField(FormBuilder.text( - Domain.EXAM_CONFIGURATION_MAP.ATTR_ENCRYPT_SECRET, - FORM_ENCRYPT_SECRET_TEXT_KEY) - .asPasswordField()) - .addField(FormBuilder.text( - ExamConfigurationMap.ATTR_CONFIRM_ENCRYPT_SECRET, - FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY) - .asPasswordField()) - - .buildFor((isNew) - ? restService.getRestCall(NewExamConfigMapping.class) - : restService.getRestCall(SaveExamConfigMapping.class)); - - // propagate content actions to action-pane - this.pageService.pageActionBuilder(formContext.clearEntityKeys()) - - .newAction(ActionDefinition.EXAM_CONFIGURATION_SAVE) - .withEntityKey(parentEntityKey) - .withExec(formHandle::processFormSave) - .ignoreMoveAwayFromEdit() - .publishIf(() -> !isReadonly) - - .newAction(ActionDefinition.EXAM_CONFIGURATION_CANCEL_MODIFY) - .withEntityKey(parentEntityKey) - .withExec(this.pageService.backToCurrentFunction()) - .publishIf(() -> !isReadonly); - } - - private void updateFormValuesFromConfigSelection(final Form form) { - final String configId = form.getFieldValue(Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID); - if (StringUtils.isBlank(configId)) { - form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, null); - form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS, null); - } else { - try { - - final ConfigurationNode configuration = this.resourceService - .getRestService() - .getBuilder(GetExamConfigNode.class) - .withURIVariable(API.PARAM_MODEL_ID, configId) - .call() - .getOrThrow(); - - form.setFieldValue( - Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, - configuration.description); - form.setFieldValue( - Domain.CONFIGURATION_NODE.ATTR_STATUS, - this.resourceService.localizedExamConfigStatusName(configuration)); - - } catch (final Exception e) { - log.error("Failed to update form values from SEB Configuration selection", e); - form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, null); - form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS, null); - } - } - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamToConfigBindPopup.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamToConfigBindPopup.java new file mode 100644 index 00000000..afa89535 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamToConfigBindPopup.java @@ -0,0 +1,266 @@ +/* + * 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.content; + +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.swt.widgets.Composite; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.exam.Exam; +import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; +import ch.ethz.seb.sebserver.gbl.util.Utils; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.form.Form; +import ch.ethz.seb.sebserver.gui.form.FormBuilder; +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.ModalInputDialogComposer; +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.impl.ModalInputDialog; +import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMapping; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewExamConfigMapping; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExamConfigMapping; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; + +final class ExamToConfigBindPopup { + + private static final Logger log = LoggerFactory.getLogger(ExamToConfigBindPopup.class); + + private static final LocTextKey NEW_CONFIG_MAPPING_TILE_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.title.new"); + private static final LocTextKey CONFIG_MAPPING_TILE_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.title"); + private static final LocTextKey CONFIG_MAPPING_NAME_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.name"); + private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.description"); + private static final LocTextKey FORM_STATUS_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.status"); + private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.encryptSecret"); + private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY = + new LocTextKey("sebserver.exam.configuration.form.encryptSecret.confirm"); + private final static LocTextKey CONFIG_ACTION_NO_CONFIG_MESSAGE = + new LocTextKey("sebserver.exam.configuration.action.noconfig.message"); + + static Function bindFunction(final PageService pageService) { + + return action -> { + + final PageContext pageContext = action.pageContext(); + final EntityKey entityKey = pageContext.getEntityKey(); + final boolean isNew = entityKey == null; + + if (isNew) { + final boolean noConfigsAvailable = pageService.getResourceService() + .examConfigurationSelectionResources() + .isEmpty(); + + if (noConfigsAvailable) { + throw new PageMessageException(CONFIG_ACTION_NO_CONFIG_MESSAGE); + } + } + + final ModalInputDialog> dialog = + new ModalInputDialog>( + action.pageContext().getParent().getShell(), + pageService.getWidgetFactory()) + .setLargeDialogWidth(); + + final BindFormContext bindFormContext = new BindFormContext( + pageService, + action.pageContext()); + + final Predicate> doBind = formHandle -> doCreate( + pageService, + pageContext, + formHandle); + + // the default page layout + final LocTextKey titleKey = (isNew) + ? NEW_CONFIG_MAPPING_TILE_TEXT_KEY + : CONFIG_MAPPING_TILE_TEXT_KEY; + + dialog.open( + titleKey, + doBind, + Utils.EMPTY_EXECUTION, + bindFormContext); + + return action; + }; + } + + private static final boolean doCreate( + final PageService pageService, + final PageContext pageContext, + final FormHandle formHandle) { + + final EntityKey entityKey = pageContext.getEntityKey(); + final boolean isNew = entityKey == null; + + final Class> restCall = (isNew) + ? NewExamConfigMapping.class + : SaveExamConfigMapping.class; + + return !pageService + .getRestService() + .getBuilder(restCall) + .withFormBinding(formHandle.getFormBinding()) + .call() + .onError(formHandle::handleError) + .map(mapping -> { + pageService.executePageAction( + pageService.pageActionBuilder(pageContext.clearEntityKeys()) + .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST) + .withEntityKey(pageContext.getParentEntityKey()) + .create()); + return mapping; + }) + .hasError(); + } + + private static final class BindFormContext implements ModalInputDialogComposer> { + + private final PageService pageService; + private final PageContext pageContext; + + protected BindFormContext( + final PageService pageService, + final PageContext pageContext) { + + this.pageService = pageService; + this.pageContext = pageContext; + + } + + @Override + public Supplier> compose(final Composite parent) { + final RestService restService = this.pageService.getRestService(); + final ResourceService resourceService = this.pageService.getResourceService(); + + final EntityKey entityKey = this.pageContext.getEntityKey(); + final EntityKey parentEntityKey = this.pageContext.getParentEntityKey(); + final boolean isNew = entityKey == null; + + final Exam exam = (isNew) + ? restService + .getBuilder(GetExam.class) + .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId) + .call() + .get(this.pageContext::notifyError) + : null; + + // get data or create new. Handle error if happen + final ExamConfigurationMap examConfigurationMap = (isNew) + ? ExamConfigurationMap.createNew(exam) + : restService + .getBuilder(GetExamConfigMapping.class) + .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) + .call() + .get(this.pageContext::notifyError); + + // new PageContext with actual EntityKey + final PageContext formContext = this.pageContext.withEntityKey(examConfigurationMap.getEntityKey()); + + final FormHandle formHandle = this.pageService.formBuilder( + formContext.copyOf(parent), 4) + .readonly(false) + .putStaticValueIf(() -> !isNew, + Domain.EXAM_CONFIGURATION_MAP.ATTR_ID, + examConfigurationMap.getModelId()) + .putStaticValue( + Domain.EXAM_CONFIGURATION_MAP.ATTR_INSTITUTION_ID, + String.valueOf(examConfigurationMap.getInstitutionId())) + .putStaticValue( + Domain.EXAM_CONFIGURATION_MAP.ATTR_EXAM_ID, + String.valueOf(examConfigurationMap.examId)) + + .addField(FormBuilder.singleSelection( + Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID, + CONFIG_MAPPING_NAME_TEXT_KEY, + String.valueOf(examConfigurationMap.configurationNodeId), + resourceService::examConfigurationSelectionResources) + .withSelectionListener(form -> updateFormValuesFromConfigSelection(form, resourceService))) + + .addField(FormBuilder.text( + Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, + FORM_DESCRIPTION_TEXT_KEY, + examConfigurationMap.configDescription) + .asArea() + .readonly(true)) + + .addField(FormBuilder.text( + Domain.CONFIGURATION_NODE.ATTR_STATUS, + FORM_STATUS_TEXT_KEY, + resourceService.localizedExamConfigStatusName(examConfigurationMap)) + .readonly(true)) + + .addField(FormBuilder.text( + Domain.EXAM_CONFIGURATION_MAP.ATTR_ENCRYPT_SECRET, + FORM_ENCRYPT_SECRET_TEXT_KEY) + .asPasswordField()) + .addField(FormBuilder.text( + ExamConfigurationMap.ATTR_CONFIRM_ENCRYPT_SECRET, + FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY) + .asPasswordField()) + + .build(); + + return () -> formHandle; + } + } + + private static void updateFormValuesFromConfigSelection(final Form form, final ResourceService resourceService) { + final String configId = form.getFieldValue(Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID); + if (StringUtils.isBlank(configId)) { + form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, null); + form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS, null); + } else { + try { + + final ConfigurationNode configuration = resourceService + .getRestService() + .getBuilder(GetExamConfigNode.class) + .withURIVariable(API.PARAM_MODEL_ID, configId) + .call() + .getOrThrow(); + + form.setFieldValue( + Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, + configuration.description); + form.setFieldValue( + Domain.CONFIGURATION_NODE.ATTR_STATUS, + resourceService.localizedExamConfigStatusName(configuration)); + + } catch (final Exception e) { + log.error("Failed to update form values from SEB Configuration selection", e); + form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, null); + form.setFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS, null); + } + } + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationUtils.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationPopup.java similarity index 96% rename from src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationUtils.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationPopup.java index fa37623a..e065bb37 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationUtils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigCreationPopup.java @@ -35,7 +35,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.CopyConfiguration; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig; -public final class SebExamConfigCreationUtils { +final class SebExamConfigCreationPopup { static final LocTextKey FORM_COPY_TEXT_KEY = new LocTextKey("sebserver.examconfig.action.copy.dialog"); @@ -59,7 +59,7 @@ public final class SebExamConfigCreationUtils { new ModalInputDialog>( action.pageContext().getParent().getShell(), pageService.getWidgetFactory()) - .setDialogWidth(600); + .setLargeDialogWidth(); final CreationFormContext formContext = new CreationFormContext( pageService, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportUtils.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportPopup.java similarity index 97% rename from src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportUtils.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportPopup.java index 41a79441..c45d75a5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportUtils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImportPopup.java @@ -45,7 +45,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.Im import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ImportNewExamConfig; import ch.ethz.seb.sebserver.gui.widget.FileUploadSelection; -public final class SebExamConfigImportUtils { +final class SebExamConfigImportPopup { private final static PageMessageException MISSING_PASSWORD = new PageMessageException( new LocTextKey("sebserver.examconfig.action.import.missing-password")); @@ -60,7 +60,7 @@ public final class SebExamConfigImportUtils { new ModalInputDialog>( action.pageContext().getParent().getShell(), pageService.getWidgetFactory()) - .setDialogWidth(600); + .setLargeDialogWidth(); final ImportFormContext importFormContext = new ImportFormContext( pageService, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java index cba466e0..05923eec 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java @@ -208,7 +208,7 @@ public class SebExamConfigList implements TemplateComposer { .publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent()) .newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG) - .withExec(SebExamConfigImportUtils.importFunction(this.pageService, true)) + .withExec(SebExamConfigImportPopup.importFunction(this.pageService, true)) .noEventPropagation() .publishIf(() -> examConfigGrant.im()) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java index a7ebe31b..4db98c0b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java @@ -252,13 +252,13 @@ public class SebExamConfigPropForm implements TemplateComposer { .newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG) .withEntityKey(entityKey) - .withExec(SebExamConfigImportUtils.importFunction(this.pageService, false)) + .withExec(SebExamConfigImportPopup.importFunction(this.pageService, false)) .noEventPropagation() .publishIf(() -> modifyGrant && isReadonly && !isAttachedToExam) .newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG) .withEntityKey(entityKey) - .withExec(SebExamConfigCreationUtils.configCreationFunction( + .withExec(SebExamConfigCreationPopup.configCreationFunction( this.pageService, actionContext .withEntityKey(entityKey) @@ -273,7 +273,7 @@ public class SebExamConfigPropForm implements TemplateComposer { .newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE) .withEntityKey(entityKey) - .withExec(SebExamConfigCreationUtils.configCreationFunction( + .withExec(SebExamConfigCreationPopup.configCreationFunction( this.pageService, pageContext.withAttribute( PageContext.AttributeKeys.COPY_AS_TEMPLATE, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigSettingsForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigSettingsForm.java index 4eecfe9e..29157ccc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigSettingsForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigSettingsForm.java @@ -177,7 +177,7 @@ public class SebExamConfigSettingsForm implements TemplateComposer { .newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE) .withEntityKey(entityKey) - .withExec(SebExamConfigCreationUtils.configCreationFunction( + .withExec(SebExamConfigCreationPopup.configCreationFunction( this.pageService, pageContext .withAttribute( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java index 6e6169bc..dc451b81 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java @@ -240,12 +240,12 @@ public enum ActionDefinition { EXAM_CONFIGURATION_NEW( new LocTextKey("sebserver.exam.configuration.action.list.new"), ImageIcon.NEW, - PageStateDefinitionImpl.EXAM_CONFIG_MAP_EDIT, + PageStateDefinitionImpl.EXAM_VIEW, ActionCategory.EXAM_CONFIG_MAPPING_LIST), EXAM_CONFIGURATION_MODIFY_FROM_LIST( new LocTextKey("sebserver.exam.configuration.action.list.modify"), ImageIcon.EDIT, - PageStateDefinitionImpl.EXAM_CONFIG_MAP_EDIT, + PageStateDefinitionImpl.EXAM_VIEW, ActionCategory.EXAM_CONFIG_MAPPING_LIST), EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP( new LocTextKey("sebserver.examconfig.action.view"), 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 c740ca53..451f6e2c 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 @@ -12,7 +12,6 @@ import ch.ethz.seb.sebserver.gui.content.ConfigTemplateAttributeForm; import ch.ethz.seb.sebserver.gui.content.ConfigTemplateForm; import ch.ethz.seb.sebserver.gui.content.ExamForm; import ch.ethz.seb.sebserver.gui.content.ExamList; -import ch.ethz.seb.sebserver.gui.content.ExamSebConfigMapForm; import ch.ethz.seb.sebserver.gui.content.IndicatorForm; import ch.ethz.seb.sebserver.gui.content.InstitutionForm; import ch.ethz.seb.sebserver.gui.content.InstitutionList; @@ -57,7 +56,6 @@ public enum PageStateDefinitionImpl implements PageStateDefinition { EXAM_LIST(Type.LIST_VIEW, ExamList.class, ActivityDefinition.EXAM), EXAM_VIEW(Type.FORM_VIEW, ExamForm.class, ActivityDefinition.EXAM), EXAM_EDIT(Type.FORM_EDIT, ExamForm.class, ActivityDefinition.EXAM), - EXAM_CONFIG_MAP_EDIT(Type.FORM_EDIT, ExamSebConfigMapForm.class, ActivityDefinition.EXAM), INDICATOR_EDIT(Type.FORM_EDIT, IndicatorForm.class, ActivityDefinition.EXAM), SEB_CLIENT_CONFIG_LIST(Type.LIST_VIEW, SebClientConfigList.class, ActivityDefinition.SEB_CLIENT_CONFIG), diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java index 14d2166b..9042316a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java @@ -32,6 +32,11 @@ public class ModalInputDialog extends Dialog { private static final long serialVersionUID = -3448614119078234374L; + public static final int DEFAULT_DIALOG_WIDTH = 400; + public static final int DEFAULT_DIALOG_HEIGHT = 600; + public static final int DEFAULT_DIALOG_BUTTON_WIDTH = 100; + public static final int LARGE_DIALOG_WIDTH = 600; + private static final LocTextKey CANCEL_TEXT_KEY = new LocTextKey("sebserver.overall.action.cancel"); private static final LocTextKey OK_TEXT_KEY = @@ -40,9 +45,9 @@ public class ModalInputDialog extends Dialog { new LocTextKey("sebserver.overall.action.close"); private final WidgetFactory widgetFactory; - private int dialogWidth = 400; - private int dialogHeight = 600; - private int buttonWidth = 100; + private int dialogWidth = DEFAULT_DIALOG_WIDTH; + private int dialogHeight = DEFAULT_DIALOG_HEIGHT; + private int buttonWidth = DEFAULT_DIALOG_BUTTON_WIDTH; public ModalInputDialog( final Shell parent, @@ -57,6 +62,11 @@ public class ModalInputDialog extends Dialog { return this; } + public ModalInputDialog setLargeDialogWidth() { + this.dialogWidth = LARGE_DIALOG_WIDTH; + return this; + } + public ModalInputDialog setDialogHeight(final int dialogHeight) { this.dialogHeight = dialogHeight; return this; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java index 04204825..4762fb36 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java @@ -350,6 +350,21 @@ class ConfigurationDAOBatchService { final ConfigCreationInfo copyInfo) { return Result.tryCatch(() -> { + + final Long count = this.batchConfigurationNodeRecordMapper.countByExample() + .where( + ConfigurationNodeRecordDynamicSqlSupport.name, + isEqualTo(copyInfo.name)) + .and( + ConfigurationNodeRecordDynamicSqlSupport.institutionId, + isEqualTo(institutionId)) + .build() + .execute(); + + if (count != null && count.longValue() > 0) { + throw new FieldValidationException("name", "configurationNode:name:exists"); + } + final ConfigurationNodeRecord sourceNode = this.batchConfigurationNodeRecordMapper .selectByPrimaryKey(copyInfo.configurationNodeId);