From d9b03e78943de89cdf068354af292002f76a1690 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 5 May 2022 13:16:07 +0200 Subject: [PATCH] SEBSERV-133 Configuration Template --- .../gui/content/action/ActionDefinition.java | 5 ++ .../content/configs/ConfigTemplateForm.java | 49 +++++++++++++++++++ .../dao/impl/ConfigurationNodeDAOImpl.java | 48 +++++++++++++++++- src/main/resources/messages.properties | 5 ++ 4 files changed, 105 insertions(+), 2 deletions(-) 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 2d37ab64..b6f8a2bb 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 @@ -685,6 +685,11 @@ public enum ActionDefinition { ImageIcon.SAVE, PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW, ActionCategory.FORM), + SEB_EXAM_CONFIG_TEMPLATE_DELETE( + new LocTextKey("sebserver.configtemplate.action.delete"), + ImageIcon.DELETE, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_LIST, + ActionCategory.FORM), SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT( new LocTextKey("sebserver.configtemplate.attr.list.actions.modify"), diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/ConfigTemplateForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/ConfigTemplateForm.java index ffadcf76..b55e7959 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/ConfigTemplateForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/ConfigTemplateForm.java @@ -18,12 +18,14 @@ 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.EntityProcessingReport; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormHandle; @@ -37,6 +39,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; 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.seb.examconfig.DeleteExamConfiguration; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttributePage; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig; @@ -77,6 +80,16 @@ public class ConfigTemplateForm implements TemplateComposer { private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY = new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect"); + static final LocTextKey CONFIRM_DELETE = + new LocTextKey("sebserver.configtemplate.message.confirm.delete"); + static final LocTextKey DELETE_CONFIRM_TITLE = + new LocTextKey("sebserver.dialog.confirm.title"); + + private final static LocTextKey DELETE_ERROR_DEPENDENCY = + new LocTextKey("sebserver.configtemplate.message.delete.partialerror"); + private final static LocTextKey DELETE_CONFIRM = + new LocTextKey("sebserver.configtemplate.message.delete.confirm"); + private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; @@ -291,6 +304,12 @@ public class ConfigTemplateForm implements TemplateComposer { .withEntityKey(entityKey) .publishIf(() -> modifyGrant && isReadonly) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_DELETE) + .withEntityKey(entityKey) + .withConfirm(() -> CONFIRM_DELETE) + .withExec(this::deleteConfiguration) + .publishIf(() -> writeGrant && isReadonly) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG) .withEntityKey(entityKey) .withExec(this.sebxamConfigCreationPopup.configCreationFunction( @@ -316,6 +335,36 @@ public class ConfigTemplateForm implements TemplateComposer { } + private PageAction deleteConfiguration(final PageAction action) { + final ConfigurationNode configNode = this.restService + .getBuilder(GetExamConfigNode.class) + .withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId) + .call() + .getOrThrow(); + + final Result call = this.restService + .getBuilder(DeleteExamConfiguration.class) + .withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId) + .call(); + + final PageContext pageContext = action.pageContext(); + + final EntityProcessingReport report = call.getOrThrow(); + final String configName = configNode.toName().name; + if (report.getErrors().isEmpty()) { + pageContext.publishPageMessage(DELETE_CONFIRM_TITLE, new LocTextKey(DELETE_CONFIRM.name, configName)); + } else { + pageContext.publishPageMessage( + DELETE_CONFIRM_TITLE, + new LocTextKey(DELETE_ERROR_DEPENDENCY.name, configName, + report.getErrors().iterator().next().getErrorMessage().systemMessage)); + } + + return this.pageService.pageActionBuilder(pageContext) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_LIST) + .create(); + } + private String getAttributeName(final TemplateAttribute attribute) { final String name = this.i18nSupport.getText( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationNodeDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationNodeDAOImpl.java index 148a868a..9851c7d0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationNodeDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationNodeDAOImpl.java @@ -46,6 +46,10 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationReco import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordMapper; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.OrientationRecordDynamicSqlSupport; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.OrientationRecordMapper; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ViewRecordDynamicSqlSupport; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ViewRecordMapper; import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationNodeRecord; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkAction; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO; @@ -63,18 +67,24 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO { private final ConfigurationNodeRecordMapper configurationNodeRecordMapper; private final ConfigurationValueRecordMapper configurationValueRecordMapper; private final ConfigurationDAOBatchService configurationDAOBatchService; + private final ViewRecordMapper viewRecordMapper; + private final OrientationRecordMapper orientationRecordMapper; protected ConfigurationNodeDAOImpl( final ConfigurationRecordMapper configurationRecordMapper, final ConfigurationNodeRecordMapper configurationNodeRecordMapper, final ConfigurationValueRecordMapper configurationValueRecordMapper, final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper, - final ConfigurationDAOBatchService ConfigurationDAOBatchService) { + final ConfigurationDAOBatchService ConfigurationDAOBatchService, + final ViewRecordMapper viewRecordMapper, + final OrientationRecordMapper orientationRecordMapper) { this.configurationRecordMapper = configurationRecordMapper; this.configurationNodeRecordMapper = configurationNodeRecordMapper; this.configurationValueRecordMapper = configurationValueRecordMapper; this.configurationDAOBatchService = ConfigurationDAOBatchService; + this.viewRecordMapper = viewRecordMapper; + this.orientationRecordMapper = orientationRecordMapper; } @Override @@ -249,7 +259,8 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO { } // find all configurations for this configuration node - final List configurationIds = this.configurationRecordMapper.selectIdsByExample() + final List configurationIds = this.configurationRecordMapper + .selectIdsByExample() .where(ConfigurationRecordDynamicSqlSupport.configurationNodeId, isIn(ids)) .build() .execute(); @@ -269,6 +280,8 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO { .execute(); } + handleConfigTemplateDeletion(ids); + // and finally delete the requested ConfigurationNode's this.configurationNodeRecordMapper.deleteByExample() .where(ConfigurationNodeRecordDynamicSqlSupport.id, isIn(ids)) @@ -281,6 +294,37 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO { }); } + private void handleConfigTemplateDeletion(final List configurationIds) { + // get all config template node ids + final List templatesIds = this.configurationNodeRecordMapper + .selectIdsByExample() + .where(ConfigurationNodeRecordDynamicSqlSupport.id, isIn(configurationIds)) + .and(ConfigurationNodeRecordDynamicSqlSupport.type, isEqualTo(ConfigurationType.TEMPLATE.name())) + .build() + .execute(); + + if (templatesIds == null || templatesIds.isEmpty()) { + return; + } + + // delete all related views and orientations + this.orientationRecordMapper.deleteByExample() + .where(OrientationRecordDynamicSqlSupport.templateId, isIn(templatesIds)) + .build() + .execute(); + this.viewRecordMapper.deleteByExample() + .where(ViewRecordDynamicSqlSupport.templateId, isIn(templatesIds)) + .build() + .execute(); + + // update all config nodes that uses one of the templates + this.configurationNodeRecordMapper.updateByExampleSelective( + new ConfigurationNodeRecord(null, null, 0L, null, null, null, null, null)) + .where(ConfigurationNodeRecordDynamicSqlSupport.templateId, isIn(configurationIds)) + .build() + .execute(); + } + private Result> allIdsOfInstitution(final EntityKey institutionKey) { return Result.tryCatch(() -> this.configurationNodeRecordMapper.selectByExample() .where( diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 63a85bd7..cea7cf8c 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -1675,6 +1675,11 @@ sebserver.configtemplate.attr.form.value.tooltip=The SEB exam configuration attr sebserver.configtemplate.attr.action.setdefault=Set Default Values sebserver.configtemplate.attr.action.template=View Configuration Template +sebserver.configtemplate.action.delete=Delete Configuration Template +sebserver.configtemplate.message.confirm.delete=This will completely delete the configuration template
and reset all exam configuration that uses this template to the default template (no SEB settings change)

Are you sure you want to delete this configuration template? +sebserver.configtemplate.message.delete.confirm=The configuration template ({0}) was successfully deleted. +sebserver.configtemplate.message.delete.partialerror=The configuration template ({0}) was deleted but there where some dependency errors:

{1} + ################################ # Exam Template ################################