From c96901472b66122b638ed4108e7867d984d975c6 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 16 Oct 2019 12:53:28 +0200 Subject: [PATCH] SEBSERV-72 front- and back-end implementation of template attributes --- .../ch/ethz/seb/sebserver/gbl/api/API.java | 2 - .../model/sebconfig/TemplateAttribute.java | 4 +- .../content/ConfigTemplateAttributeForm.java | 145 +++++++++++++++++- .../gui/content/ConfigTemplateForm.java | 82 ++++++++-- .../gui/content/action/ActionDefinition.java | 17 +- .../activity/PageStateDefinitionImpl.java | 4 - .../gui/service/ResourceService.java | 9 ++ .../examconfig/ExamConfigurationService.java | 5 + .../impl/ExamConfigurationServiceImpl.java | 19 +++ .../service/examconfig/impl/ViewContext.java | 2 +- .../seb/examconfig/GetTemplateAttribute.java | 43 ++++++ .../examconfig/GetTemplateAttributePage.java | 2 +- .../dao/ConfigurationAttributeDAO.java | 2 + .../dao/ConfigurationValueDAO.java | 5 + .../servicelayer/dao/OrientationDAO.java | 2 + .../impl/ConfigurationAttributeDAOImpl.java | 16 ++ .../dao/impl/ConfigurationValueDAOImpl.java | 90 ++++++++++- .../dao/impl/OrientationDAOImpl.java | 22 ++- .../SebExamConfigTemplateService.java | 37 +++++ .../SebExamConfigTemplateServiceImpl.java | 143 +++++++++++++++++ .../api/ConfigurationNodeController.java | 105 ++++++++----- src/main/resources/messages.properties | 13 +- 22 files changed, 688 insertions(+), 81 deletions(-) create mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttribute.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java 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 f8eb51bc..bfea404f 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 @@ -129,8 +129,6 @@ public final class API { public static final String TEMPLATE_ATTRIBUTE_ENDPOINT = "/template-attribute"; - public static final String CONFIGURATION_TEMPLATE_ENDPOINT = "/exam-config-template"; - public static final String ORIENTATION_ENDPOINT = "/orientation"; public static final String VIEW_ENDPOINT = ORIENTATION_ENDPOINT + "/view"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/TemplateAttribute.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/TemplateAttribute.java index 5a4c1687..65682434 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/TemplateAttribute.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/TemplateAttribute.java @@ -58,8 +58,8 @@ public final class TemplateAttribute implements Entity { @Override public String getModelId() { - return this.institutionId != null - ? String.valueOf(this.institutionId) + return this.configAttribute != null + ? String.valueOf(this.configAttribute.id) : null; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java index 427287c2..93b2f2ed 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java @@ -8,42 +8,183 @@ package ch.ethz.seb.sebserver.gui.content; +import java.util.Arrays; + +import org.eclipse.swt.widgets.Composite; 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.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.View; +import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gbl.util.Utils; +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; import ch.ethz.seb.sebserver.gui.service.ResourceService; +import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; +import ch.ethz.seb.sebserver.gui.service.examconfig.InputField; +import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; +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.PageService.PageActionBuilder; 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.seb.examconfig.GetConfigurations; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttribute; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component @GuiProfile public class ConfigTemplateAttributeForm implements TemplateComposer { + private static final LocTextKey FORM_TITLE = + new LocTextKey("sebserver.configtemplate.attr.form.title"); + private static final LocTextKey FORM_NAME_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.form.name"); + private static final LocTextKey FORM_TYPE_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.form.type"); + private static final LocTextKey FORM_VIEW_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.form.view"); + private static final LocTextKey FORM_GROUP_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.form.group"); + private static final LocTextKey FORM_VALUE_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.form.value"); + private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; private final ResourceService resourceService; + private final ExamConfigurationService examConfigurationService; protected ConfigTemplateAttributeForm( final PageService pageService, final RestService restService, - final CurrentUser currentUser) { + final CurrentUser currentUser, + final ExamConfigurationService examConfigurationService) { this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; this.resourceService = pageService.getResourceService(); + this.examConfigurationService = examConfigurationService; } @Override public void compose(final PageContext pageContext) { - // TODO Auto-generated method stub + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); + + final UserInfo user = this.currentUser.get(); + final EntityKey attributeKey = pageContext.getEntityKey(); + final EntityKey templateKey = pageContext.getParentEntityKey(); + final Long templateId = Long.valueOf(templateKey.modelId); + + // the attribute + final TemplateAttribute attribute = this.restService.getBuilder(GetTemplateAttribute.class) + .withURIVariable(API.PARAM_PARENT_MODEL_ID, templateKey.modelId) + .withURIVariable(API.PARAM_MODEL_ID, attributeKey.modelId) + .call() + .getOrThrow(); + + // the follow-up configuration + final Configuration configuration = this.restService.getBuilder(GetConfigurations.class) + .withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, templateKey.getModelId()) + .withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING) + .call() + .map(Utils::toSingleton) + .onError(pageContext::notifyError) + .getOrThrow(); + + // the default page layout with title + final Composite content = widgetFactory.defaultPageLayout( + pageContext.getParent(), + FORM_TITLE); + + final PageContext formContext = pageContext.copyOf(content); + + final boolean hasView = attribute.getOrientation() != null; + + final FormHandle formHandle = this.pageService.formBuilder( + formContext, 4) + .readonly(true) // TODO change this for next version + .addField(FormBuilder.text( + Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME, + FORM_NAME_TEXT_KEY, + attribute::getName)) + .addField(FormBuilder.text( + Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE, + FORM_TYPE_TEXT_KEY, + () -> attribute.getConfigAttribute().getType().name())) + .addFieldIf( + () -> hasView, + () -> FormBuilder.singleSelection( + Domain.ORIENTATION.ATTR_VIEW_ID, + FORM_VIEW_TEXT_KEY, + attribute.getViewModelId(), + () -> this.resourceService.getViewResources(templateKey.modelId))) + .addFieldIf( + () -> hasView, + () -> FormBuilder.text( + Domain.ORIENTATION.ATTR_GROUP_ID, + FORM_GROUP_TEXT_KEY, + attribute.getGroupId())) + .build(); + + widgetFactory.labelLocalizedTitle( + content, + FORM_VALUE_TEXT_KEY); + + final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder( + attribute.getConfigAttribute(), + attribute.getOrientation()); + final AttributeMapping attributeMapping = this.examConfigurationService + .getAttributes(templateId) + .getOrThrow(); + + final ViewContext viewContext = this.examConfigurationService.createViewContext( + formContext, + configuration, + new View(-1L, "template", 10, 0, templateId), + attributeMapping, + 1); + + final InputField createInputField = inputFieldBuilder.createInputField( + content, + attribute.getConfigAttribute(), + viewContext); + + viewContext.registerInputField(createInputField); + + this.examConfigurationService.initInputFieldValues( + configuration.id, + Arrays.asList(viewContext)); + + final PageActionBuilder pageActionBuilder = this.pageService + .pageActionBuilder(formContext.clearEntityKeys()); + pageActionBuilder + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_SET_DEFAULT) + .withEntityKey(attributeKey) + .withParentEntityKey(templateKey) + .withExec(this.examConfigurationService::resetToDefaults) + .ignoreMoveAwayFromEdit() + .publish() + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_EDIT_TEMPLATE) + .withEntityKey(templateKey) + .publish(); } 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 62ec1ef1..9332565b 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 @@ -8,10 +8,6 @@ package ch.ethz.seb.sebserver.gui.content; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,10 +27,13 @@ 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; import ch.ethz.seb.sebserver.gui.service.ResourceService; +import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; 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.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.GetExamConfigNode; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttributePage; @@ -71,11 +70,14 @@ public class ConfigTemplateForm implements TemplateComposer { new LocTextKey("sebserver.configtemplate.attrs.list.view"); private static final LocTextKey ATTRIBUTES_LIST_GROUP_TEXT_KEY = new LocTextKey("sebserver.configtemplate.attrs.list.group"); + private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY = + new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect"); private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; private final ResourceService resourceService; + private final ExamConfigurationService examConfigurationService; private final TableFilterAttribute nameFilter = new TableFilterAttribute(CriteriaType.TEXT, TemplateAttribute.FILTER_ATTR_NAME); @@ -85,12 +87,14 @@ public class ConfigTemplateForm implements TemplateComposer { protected ConfigTemplateForm( final PageService pageService, final RestService restService, - final CurrentUser currentUser) { + final CurrentUser currentUser, + final ExamConfigurationService examConfigurationService) { this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; this.resourceService = pageService.getResourceService(); + this.examConfigurationService = examConfigurationService; } @@ -166,6 +170,9 @@ public class ConfigTemplateForm implements TemplateComposer { ? this.restService.getRestCall(NewExamConfig.class) : this.restService.getRestCall(SaveExamConfig.class)); + final PageActionBuilder pageActionBuilder = this.pageService + .pageActionBuilder(formContext.clearEntityKeys()); + if (isReadonly) { widgetFactory.label(content, ""); @@ -181,7 +188,7 @@ public class ConfigTemplateForm implements TemplateComposer { final EntityTable attrTable = this.pageService.entityTableBuilder(this.restService.getRestCall(GetTemplateAttributePage.class)) .withRestCallAdapter(restCall -> restCall.withURIVariable( - API.PARAM_MODEL_ID, + API.PARAM_PARENT_MODEL_ID, entityKey.modelId)) .withPaging(15) .withColumn(new ColumnDefinition<>( @@ -193,7 +200,7 @@ public class ConfigTemplateForm implements TemplateComposer { .withColumn(new ColumnDefinition<>( Domain.ORIENTATION.ATTR_VIEW_ID, ATTRIBUTES_LIST_VIEW_TEXT_KEY, - getViewNameFunction(entityKey)) + resourceService.getViewNameFunction(entityKey.modelId)) .withFilter(viewFilter) .sortable()) .withColumn(new ColumnDefinition<>( @@ -202,15 +209,44 @@ public class ConfigTemplateForm implements TemplateComposer { TemplateAttribute::getGroupId) .withFilter(this.groupFilter) .sortable()) -// .withDefaultAction(pageActionBuilder -// .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST) -// .create()) + .withDefaultAction(pageActionBuilder + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT) + .withParentEntityKey(entityKey) + .create()) .compose(pageContext.copyOf(content)); - // TODO list of all attributes with filter + pageActionBuilder + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT) + .withParentEntityKey(entityKey) + .withSelect( + attrTable::getSelection, + PageAction::applySingleSelection, + EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY) + .publishIf(() -> attrTable.hasAnyContent()) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_SET_DEFAULT) + .withParentEntityKey(entityKey) + .withSelect( + attrTable::getSelection, + action -> this.resetToDefaults(action, attrTable), + EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY) + .noEventPropagation() + .publishIf(() -> attrTable.hasAnyContent()) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW) + .withParentEntityKey(entityKey) + .withSelect( + attrTable::getSelection, + action -> this.removeFormView(action, attrTable), + EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY) + .noEventPropagation() + .publishIf(() -> attrTable.hasAnyContent()) + + ; } - this.pageService.pageActionBuilder(formContext.clearEntityKeys()) + pageActionBuilder .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_NEW) .publishIf(() -> writeGrant && isReadonly) @@ -232,12 +268,24 @@ public class ConfigTemplateForm implements TemplateComposer { } - private final Function getViewNameFunction(final EntityKey templateId) { - final Map mapping = this.resourceService.getViewResources(templateId.modelId) - .stream() - .collect(Collectors.toMap(tuple -> tuple._1, tuple -> tuple._2)); + private final PageAction resetToDefaults( + final PageAction action, + final EntityTable attrTable) { - return attr -> mapping.get(attr.getViewModelId()); + final PageAction resetToDefaults = this.examConfigurationService.resetToDefaults(action); + // reload the list + attrTable.applyFilter(); + return resetToDefaults; + } + + private final PageAction removeFormView( + final PageAction action, + final EntityTable attrTable) { + + final PageAction removeFormView = this.examConfigurationService.removeFormView(action); + // reload the list + attrTable.applyFilter(); + return removeFormView; } } 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 750fd402..e85f3cf9 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 @@ -454,17 +454,28 @@ public enum ActionDefinition { SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT( new LocTextKey("sebserver.configtemplate.attr.list.actions.modify"), ImageIcon.EDIT, - PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_VIEW, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT, ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST), SEB_EXAM_CONFIG_TEMPLATE_ATTR_SET_DEFAULT( new LocTextKey("sebserver.configtemplate.attr.list.actions.setdefault"), ImageIcon.SAVE, - PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_VIEW, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW, ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST), SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW( new LocTextKey("sebserver.configtemplate.attr.list.actions.removeview"), ImageIcon.DELETE, - PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_VIEW, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW, + ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST), + + SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_SET_DEFAULT( + new LocTextKey("sebserver.configtemplate.attr.action.setdefault"), + ImageIcon.UNDO, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT, + ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST), + SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_EDIT_TEMPLATE( + new LocTextKey("sebserver.configtemplate.attr.action.template"), + ImageIcon.SHOW, + PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW, ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST), RUNNING_EXAM_VIEW_LIST( 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 5321ffc0..e17df9af 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 @@ -72,10 +72,6 @@ public enum PageStateDefinitionImpl implements PageStateDefinition { SEB_EXAM_CONFIG_TEMPLATE_VIEW(Type.FORM_VIEW, ConfigTemplateForm.class, ActivityDefinition.SEB_EXAM_CONFIG), SEB_EXAM_CONFIG_TEMPLATE_EDIT(Type.FORM_EDIT, ConfigTemplateForm.class, ActivityDefinition.SEB_EXAM_CONFIG), - SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_VIEW( - Type.FORM_VIEW, - ConfigTemplateAttributeForm.class, - ActivityDefinition.SEB_EXAM_CONFIG), SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT( Type.FORM_EDIT, ConfigTemplateAttributeForm.class, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java index 6b5f589e..ae811bc3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java @@ -41,6 +41,7 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; 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.sebconfig.View; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus; import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent; @@ -485,6 +486,14 @@ public class ResourceService { .collect(Collectors.toList()); } + public final Function getViewNameFunction(final String templateId) { + final Map mapping = this.getViewResources(templateId) + .stream() + .collect(Collectors.toMap(tuple -> tuple._1, tuple -> tuple._2)); + + return attr -> mapping.get(attr.getViewModelId()); + } + public Map getExamNameMapping() { final UserInfo userInfo = this.currentUser.get(); return this.restService.getBuilder(GetExamNames.class) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java index 7ba05c46..2414dc36 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java @@ -24,6 +24,7 @@ import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; 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.impl.PageAction; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; public interface ExamConfigurationService { @@ -58,6 +59,10 @@ public interface ExamConfigurationService { Long configurationId, Collection viewContexts); + PageAction resetToDefaults(PageAction action); + + PageAction removeFormView(PageAction action); + static String attributeNameKey(final ConfigurationAttribute attribute) { if (attribute == null) { return null; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java index 2c020087..ade45dd6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java @@ -28,6 +28,7 @@ import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues; @@ -44,6 +45,7 @@ import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeRule; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError; import ch.ethz.seb.sebserver.gui.service.page.PageContext; +import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes; @@ -209,6 +211,23 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService { .forEach(vc -> vc.setValuesToInputFields(attributeValues)); } + @Override + public final PageAction resetToDefaults(final PageAction action) { + final EntityKey singleSelection = action.getSingleSelection(); + + // TODO + return action; + } + + @Override + public final PageAction removeFormView(final PageAction action) { + final EntityKey singleSelection = action.getSingleSelection(); + + // TODO + + return action; + } + private static final class ValueChangeListenerImpl implements ValueChangeListener { public static final String VALIDATION_ERROR_KEY_PREFIX = "sebserver.examconfig.props.validation."; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewContext.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewContext.java index f4c8dc82..d12f3dc6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewContext.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewContext.java @@ -214,7 +214,7 @@ public final class ViewContext { inputField.clearError(); } - void registerInputField(final InputField inputField) { + public void registerInputField(final InputField inputField) { this.inputFieldMapping.put( inputField.getAttribute().id, inputField); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttribute.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttribute.java new file mode 100644 index 00000000..a5254cd1 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttribute.java @@ -0,0 +1,43 @@ +/* + * 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 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.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; + +@Lazy +@Component +@GuiProfile +public class GetTemplateAttribute extends RestCall { + + public GetTemplateAttribute() { + super(new TypeKey<>( + CallType.GET_SINGLE, + EntityType.CONFIGURATION_NODE, + new TypeReference() { + }), + HttpMethod.GET, + MediaType.APPLICATION_FORM_URLENCODED, + API.CONFIGURATION_NODE_ENDPOINT + + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttributePage.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttributePage.java index ebf92b9f..e4e16f07 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttributePage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/GetTemplateAttributePage.java @@ -36,7 +36,7 @@ public class GetTemplateAttributePage extends RestCall> HttpMethod.GET, MediaType.APPLICATION_FORM_URLENCODED, API.CONFIGURATION_NODE_ENDPOINT - + API.MODEL_ID_VAR_PATH_SEGMENT + + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + API.TEMPLATE_ATTRIBUTE_ENDPOINT); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationAttributeDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationAttributeDAO.java index e8a750cf..fe583a4f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationAttributeDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationAttributeDAO.java @@ -21,4 +21,6 @@ public interface ConfigurationAttributeDAO extends EntityDAO> getAllRootAttributes(); + Result> allChildAttributes(final Long parentId); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationValueDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationValueDAO.java index d72200b9..5fa8e89a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationValueDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ConfigurationValueDAO.java @@ -68,4 +68,9 @@ public interface ConfigurationValueDAO extends EntityDAO saveTableValues(ConfigurationTableValues value); + Result> setDefaultValues( + Long institutionId, + Long configurationId, + Long attributeId); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java index f61e9518..bdd23d7a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java @@ -30,4 +30,6 @@ public interface OrientationDAO extends EntityDAO { Result> getAllOfTemplate(Long templateId); + Result getAttributeOfTemplate(Long templateId, Long attributeId); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java index dbab9327..bd9ec510 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java @@ -110,6 +110,22 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO .collect(Collectors.toList())); } + @Override + @Transactional(readOnly = true) + public Result> allChildAttributes(final Long parentId) { + return Result.tryCatch(() -> this.configurationAttributeRecordMapper + .selectByExample() + .where( + ConfigurationAttributeRecordDynamicSqlSupport.parentId, + SqlBuilder.isEqualTo(parentId)) + .build() + .execute() + .stream() + .map(ConfigurationAttributeDAOImpl::toDomainModel) + .flatMap(DAOLoggingSupport::logAndSkipOnError) + .collect(Collectors.toList())); + } + @Override @Transactional(readOnly = true) public Result> getAllRootAttributes() { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java index f863fbd2..1bf6934d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java @@ -14,6 +14,7 @@ import static org.mybatis.dynamic.sql.SqlBuilder.isIn; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -31,6 +32,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; @@ -334,6 +336,86 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO { }); } + @Override + @Transactional + public Result saveTableValues(final ConfigurationTableValues value) { + return this.configurationDAOBatchService + .saveNewTableValues(value) + .onError(TransactionHandler::rollback); + } + + @Override + @Transactional + public Result> setDefaultValues( + final Long institutionId, + final Long configurationId, + final Long attributeId) { + + return attributeRecordById(attributeId) + .flatMap(this::getAttributeMapping) + .map(attributeMapping -> { + + final Set tableValues = this.configurationValueRecordMapper.selectByExample() + .where( + ConfigurationValueRecordDynamicSqlSupport.institutionId, + isEqualTo(institutionId)) + .and( + ConfigurationValueRecordDynamicSqlSupport.configurationId, + isEqualTo(configurationId)) + .and( + ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId, + SqlBuilder.isIn(new ArrayList<>(attributeMapping.keySet()))) + .build() + .execute() + .stream() + .map(r -> new EntityKey(r.getId(), EntityType.CONFIGURATION_VALUE)) + .collect(Collectors.toSet()); + + // if there are table values, delete them first + if (tableValues != null && !tableValues.isEmpty()) { + this.delete(tableValues) + .getOrThrow(); + } + + // get the attribute value reset to defaultValue and save + final List values = this.configurationValueRecordMapper.selectByExample() + .where( + ConfigurationValueRecordDynamicSqlSupport.institutionId, + isEqualTo(institutionId)) + .and( + ConfigurationValueRecordDynamicSqlSupport.configurationId, + isEqualTo(configurationId)) + .and( + ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId, + SqlBuilder.isEqualTo(attributeId)) + .build() + .execute(); + + if (values.isEmpty()) { + return tableValues; + } else { + if (values.size() > 1) { + throw new IllegalStateException("Expacted one but get: " + values.size()); + } + + final ConfigurationAttributeRecord attribute = this.configurationAttributeRecordMapper + .selectByPrimaryKey(attributeId); + final String defaultValue = attribute.getDefaultValue(); + + final ConfigurationValueRecord oldRec = values.get(0); + final ConfigurationValueRecord newRec = new ConfigurationValueRecord( + oldRec.getId(), null, null, null, null, defaultValue); + + this.configurationValueRecordMapper.updateByPrimaryKeySelective(newRec); + + final HashSet result = new HashSet<>(); + result.add(new EntityKey(newRec.getId(), EntityType.CONFIGURATION_VALUE)); + result.addAll(tableValues); + return result; + } + }); + } + // get all attributes of the table (columns) mapped to attribute id private Result> getAttributeMapping( final ConfigurationAttributeRecord attributeRecord) { @@ -353,14 +435,6 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO { }); } - @Override - @Transactional - public Result saveTableValues(final ConfigurationTableValues value) { - return this.configurationDAOBatchService - .saveNewTableValues(value) - .onError(TransactionHandler::rollback); - } - private Result attributeRecord(final ConfigurationValue value) { return attributeRecordById(value.attributeId); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java index d535c144..0006a402 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java @@ -31,6 +31,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gbl.util.Utils; 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.model.OrientationRecord; @@ -193,7 +194,7 @@ public class OrientationDAOImpl implements OrientationDAO { .selectByExample() .where( OrientationRecordDynamicSqlSupport.templateId, - SqlBuilder.isEqualToWhenPresent(templateId)) + SqlBuilder.isEqualTo(templateId)) .build() .execute() .stream() @@ -202,6 +203,24 @@ public class OrientationDAOImpl implements OrientationDAO { .collect(Collectors.toList())); } + @Override + public Result getAttributeOfTemplate(final Long templateId, final Long attributeId) { + return Result.tryCatch(() -> this.orientationRecordMapper + .selectByExample() + .where( + OrientationRecordDynamicSqlSupport.templateId, + SqlBuilder.isEqualTo(templateId)) + .and( + OrientationRecordDynamicSqlSupport.configAttributeId, + SqlBuilder.isEqualTo(attributeId)) + .build() + .execute() + .stream() + .map(OrientationDAOImpl::toDomainModel) + .flatMap(DAOLoggingSupport::logAndSkipOnError) + .collect(Utils.toSingleton())); + } + @Override @Transactional public Result> delete(final Set all) { @@ -266,4 +285,5 @@ public class OrientationDAOImpl implements OrientationDAO { record.getHeight(), TitleOrientation.valueOf(record.getTitle()))); } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java new file mode 100644 index 00000000..d08399e6 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java @@ -0,0 +1,37 @@ +/* + * 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.webservice.servicelayer.sebconfig; + +import java.util.List; +import java.util.Set; + +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; + +public interface SebExamConfigTemplateService { + + Result> getTemplateAttributes( + final Long institutionId, + final Long templateId, + final String sort, + final FilterMap filterMap); + + Result getAttribute( + final Long institutionId, + final Long templateId, + final Long attributeId); + + Result> setDefaultValues( + final Long institutionId, + final Long templateId, + final Long attributeId); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java new file mode 100644 index 00000000..52a1086d --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java @@ -0,0 +1,143 @@ +/* + * 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.webservice.servicelayer.sebconfig.impl; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import ch.ethz.seb.sebserver.gbl.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ViewDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemplateService; + +@Lazy +@Service +@WebServiceProfile +public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateService { + + private final ConfigurationNodeDAO ConfigurationNodeDAO; + private final ConfigurationDAO configurationDAO; + private final ViewDAO viewDAO; + private final OrientationDAO orientationDAO; + private final ConfigurationAttributeDAO configurationAttributeDAO; + private final ConfigurationValueDAO configurationValueDAO; + private final SebExamConfigService sebExamConfigService; + + protected SebExamConfigTemplateServiceImpl( + final ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO configurationNodeDAO, + final ConfigurationDAO configurationDAO, final ViewDAO viewDAO, final OrientationDAO orientationDAO, + final ConfigurationAttributeDAO configurationAttributeDAO, + final ConfigurationValueDAO configurationValueDAO, + final SebExamConfigService sebExamConfigService) { + super(); + this.ConfigurationNodeDAO = configurationNodeDAO; + this.configurationDAO = configurationDAO; + this.viewDAO = viewDAO; + this.orientationDAO = orientationDAO; + this.configurationAttributeDAO = configurationAttributeDAO; + this.configurationValueDAO = configurationValueDAO; + this.sebExamConfigService = sebExamConfigService; + } + + @Override + public Result> getTemplateAttributes( + final Long institutionId, + final Long templateId, + final String sort, + final FilterMap filterMap) { + + return Result.tryCatch(() -> { + final Map orentiations = this.orientationDAO + .getAllOfTemplate(templateId) + .getOrThrow() + .stream() + .collect(Collectors.toMap( + o -> o.attributeId, + Function.identity())); + + final List attrs = this.configurationAttributeDAO + .getAllRootAttributes() + .getOrThrow() + .stream() + .map(attr -> new TemplateAttribute(institutionId, templateId, attr, orentiations.get(attr.id))) + .filter(attr -> attr.isNameLike(filterMap.getString(TemplateAttribute.FILTER_ATTR_NAME)) + && attr.isGroupLike(filterMap.getString(TemplateAttribute.FILTER_ATTR_GROUP)) + && attr.isInView(filterMap.getLong(TemplateAttribute.FILTER_ATTR_VIEW))) + .collect(Collectors.toList()); + + if (!StringUtils.isBlank(sort)) { + final String sortBy = PageSortOrder.decode(sort); + final PageSortOrder sortOrder = PageSortOrder.getSortOrder(sort); + if (sortBy.equals(Domain.CONFIGURATION_NODE.ATTR_NAME)) { + Collections.sort(attrs, TemplateAttribute.nameComparator(sortOrder == PageSortOrder.DESCENDING)); + } + } + return attrs; + }); + } + + @Override + public Result getAttribute( + final Long institutionId, + final Long templateId, + final Long attributeId) { + + return Result.tryCatch(() -> { + final ConfigurationAttribute attribute = this.configurationAttributeDAO + .byPK(attributeId) + .getOrThrow(); + + final Orientation orientation = this.orientationDAO + .getAttributeOfTemplate(templateId, attributeId) + .getOr(null); + + return new TemplateAttribute( + institutionId, + templateId, + attribute, + orientation); + }); + } + + @Override + public Result> setDefaultValues( + final Long institutionId, + final Long templateId, + final Long attributeId) { + + return this.configurationDAO.getFollowupConfiguration(templateId) + .flatMap(config -> this.configurationValueDAO + .setDefaultValues( + institutionId, + config.id, + attributeId)); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java index c5202c57..6c9f94bb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java @@ -12,18 +12,14 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; -import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.Set; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; import org.mybatis.dynamic.sql.SqlTable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,15 +38,13 @@ import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.APIMessage; 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.sebconfig.ConfigKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; @@ -61,7 +55,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.Authorization import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; -import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; @@ -69,6 +62,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ViewDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemplateService; import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService; @WebServiceProfile @@ -81,9 +75,10 @@ public class ConfigurationNodeController extends EntityController getTemplateAttributePage( - @PathVariable final Long modelId, + @PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long parentModelId, @RequestParam( name = API.PARAM_INSTITUTION_ID, required = true, @@ -261,30 +256,13 @@ public class ConfigurationNodeController extends EntityController orentiations = this.orientationDAO.getAllOfTemplate(modelId) - .getOrThrow() - .stream() - .collect(Collectors.toMap( - o -> o.attributeId, - Function.identity())); - - final List attrs = this.configurationAttributeDAO - .getAllRootAttributes() - .getOrThrow() - .stream() - .map(attr -> new TemplateAttribute(institutionId, modelId, attr, orentiations.get(attr.id))) - .filter(attr -> attr.isNameLike(filterMap.getString(TemplateAttribute.FILTER_ATTR_NAME)) - && attr.isGroupLike(filterMap.getString(TemplateAttribute.FILTER_ATTR_GROUP)) - && attr.isInView(filterMap.getLong(TemplateAttribute.FILTER_ATTR_VIEW))) - .collect(Collectors.toList()); - - if (!StringUtils.isBlank(sort)) { - final String sortBy = PageSortOrder.decode(sort); - final PageSortOrder sortOrder = PageSortOrder.getSortOrder(sort); - if (sortBy.equals(Domain.CONFIGURATION_NODE.ATTR_NAME)) { - Collections.sort(attrs, TemplateAttribute.nameComparator(sortOrder == PageSortOrder.DESCENDING)); - } - } + final List attrs = this.sebExamConfigTemplateService + .getTemplateAttributes( + institutionId, + parentModelId, + sort, + filterMap) + .getOrThrow(); final int start = (pageNumber - 1) * pageSize; int end = start + pageSize; @@ -299,6 +277,55 @@ public class ConfigurationNodeController extends EntityController resetTemplateAttribute( + @PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long parentModelId, + @PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long modelId, + @RequestParam( + name = API.PARAM_INSTITUTION_ID, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId) { + + checkModifyPrivilege(institutionId); + return this.sebExamConfigTemplateService + .setDefaultValues( + institutionId, + parentModelId, + modelId) + .getOrThrow(); + } + @Override protected Result validForSave(final ConfigurationNode entity) { return super.validForSave(entity) diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 1d768c55..0c36466e 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -955,7 +955,18 @@ sebserver.configtemplate.attrs.list.group=Group sebserver.configtemplate.attr.list.actions=Selected Attribute sebserver.configtemplate.attr.list.actions.modify=Edit Attribute sebserver.configtemplate.attr.list.actions.setdefault=Set Default Values -sebserver.configtemplate.attr.list.actions.removeview=Remove View +sebserver.configtemplate.attr.list.actions.removeview=Remove From View +sebserver.configtemplate.attr.info.pleaseSelect=Please select an attribute first + +sebserver.configtemplate.attr.form.title=Template Attribute +sebserver.configtemplate.attr.form.name=Name +sebserver.configtemplate.attr.form.type=Type +sebserver.configtemplate.attr.form.view=View +sebserver.configtemplate.attr.form.group=Group +sebserver.configtemplate.attr.form.value=Template Attribute Value + +sebserver.configtemplate.attr.action.setdefault=Set Default Values +sebserver.configtemplate.attr.action.template=View Template ################################