SEBSERV-133 Configuration Template

This commit is contained in:
anhefti 2022-05-05 13:16:07 +02:00
parent e0f435c34a
commit d9b03e7894
4 changed files with 105 additions and 2 deletions

View file

@ -685,6 +685,11 @@ public enum ActionDefinition {
ImageIcon.SAVE, ImageIcon.SAVE,
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW, PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW,
ActionCategory.FORM), 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( SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT(
new LocTextKey("sebserver.configtemplate.attr.list.actions.modify"), new LocTextKey("sebserver.configtemplate.attr.list.actions.modify"),

View file

@ -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.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.EntityKey; 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;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus; 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.ConfigurationNode.ConfigurationType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; 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.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; 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.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; 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.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.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.GetTemplateAttributePage;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig; 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 = private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect"); 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 PageService pageService;
private final RestService restService; private final RestService restService;
private final CurrentUser currentUser; private final CurrentUser currentUser;
@ -291,6 +304,12 @@ public class ConfigTemplateForm implements TemplateComposer {
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && isReadonly) .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) .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(this.sebxamConfigCreationPopup.configCreationFunction( .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<EntityProcessingReport> 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) { private String getAttributeName(final TemplateAttribute attribute) {
final String name = this.i18nSupport.getText( final String name = this.i18nSupport.getText(

View file

@ -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.ConfigurationValueRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordMapper; 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.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.datalayer.batis.model.ConfigurationNodeRecord;
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkAction; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkAction;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO;
@ -63,18 +67,24 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
private final ConfigurationNodeRecordMapper configurationNodeRecordMapper; private final ConfigurationNodeRecordMapper configurationNodeRecordMapper;
private final ConfigurationValueRecordMapper configurationValueRecordMapper; private final ConfigurationValueRecordMapper configurationValueRecordMapper;
private final ConfigurationDAOBatchService configurationDAOBatchService; private final ConfigurationDAOBatchService configurationDAOBatchService;
private final ViewRecordMapper viewRecordMapper;
private final OrientationRecordMapper orientationRecordMapper;
protected ConfigurationNodeDAOImpl( protected ConfigurationNodeDAOImpl(
final ConfigurationRecordMapper configurationRecordMapper, final ConfigurationRecordMapper configurationRecordMapper,
final ConfigurationNodeRecordMapper configurationNodeRecordMapper, final ConfigurationNodeRecordMapper configurationNodeRecordMapper,
final ConfigurationValueRecordMapper configurationValueRecordMapper, final ConfigurationValueRecordMapper configurationValueRecordMapper,
final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper, final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper,
final ConfigurationDAOBatchService ConfigurationDAOBatchService) { final ConfigurationDAOBatchService ConfigurationDAOBatchService,
final ViewRecordMapper viewRecordMapper,
final OrientationRecordMapper orientationRecordMapper) {
this.configurationRecordMapper = configurationRecordMapper; this.configurationRecordMapper = configurationRecordMapper;
this.configurationNodeRecordMapper = configurationNodeRecordMapper; this.configurationNodeRecordMapper = configurationNodeRecordMapper;
this.configurationValueRecordMapper = configurationValueRecordMapper; this.configurationValueRecordMapper = configurationValueRecordMapper;
this.configurationDAOBatchService = ConfigurationDAOBatchService; this.configurationDAOBatchService = ConfigurationDAOBatchService;
this.viewRecordMapper = viewRecordMapper;
this.orientationRecordMapper = orientationRecordMapper;
} }
@Override @Override
@ -249,7 +259,8 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
} }
// find all configurations for this configuration node // find all configurations for this configuration node
final List<Long> configurationIds = this.configurationRecordMapper.selectIdsByExample() final List<Long> configurationIds = this.configurationRecordMapper
.selectIdsByExample()
.where(ConfigurationRecordDynamicSqlSupport.configurationNodeId, isIn(ids)) .where(ConfigurationRecordDynamicSqlSupport.configurationNodeId, isIn(ids))
.build() .build()
.execute(); .execute();
@ -269,6 +280,8 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
.execute(); .execute();
} }
handleConfigTemplateDeletion(ids);
// and finally delete the requested ConfigurationNode's // and finally delete the requested ConfigurationNode's
this.configurationNodeRecordMapper.deleteByExample() this.configurationNodeRecordMapper.deleteByExample()
.where(ConfigurationNodeRecordDynamicSqlSupport.id, isIn(ids)) .where(ConfigurationNodeRecordDynamicSqlSupport.id, isIn(ids))
@ -281,6 +294,37 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
}); });
} }
private void handleConfigTemplateDeletion(final List<Long> configurationIds) {
// get all config template node ids
final List<Long> 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<Collection<EntityDependency>> allIdsOfInstitution(final EntityKey institutionKey) { private Result<Collection<EntityDependency>> allIdsOfInstitution(final EntityKey institutionKey) {
return Result.tryCatch(() -> this.configurationNodeRecordMapper.selectByExample() return Result.tryCatch(() -> this.configurationNodeRecordMapper.selectByExample()
.where( .where(

View file

@ -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.setdefault=Set Default Values
sebserver.configtemplate.attr.action.template=View Configuration Template 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<br/>and reset all exam configuration that uses this template to the default template (no SEB settings change)<br/><br/>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:<br/><br/>{1}
################################ ################################
# Exam Template # Exam Template
################################ ################################