SEBSERV-72 back- and front-end implementation
This commit is contained in:
parent
4e40ee7f0e
commit
555d9a34e0
12 changed files with 365 additions and 63 deletions
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
@ -17,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
|
@ -28,6 +30,7 @@ public final class TemplateAttribute implements Entity {
|
|||
|
||||
public static final String FILTER_ATTR_VIEW = "view";
|
||||
public static final String FILTER_ATTR_GROUP = "group";
|
||||
public static final String FILTER_ATTR_TYPE = "type";
|
||||
|
||||
@NotNull
|
||||
@JsonProperty(CONFIGURATION.ATTR_INSTITUTION_ID)
|
||||
|
@ -133,6 +136,15 @@ public final class TemplateAttribute implements Entity {
|
|||
&& this.orientation.groupId.contains(groupId);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean hasType(final EnumSet<AttributeType> types) {
|
||||
if (types == null || types.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return types.contains(this.configAttribute.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
@ -153,4 +165,23 @@ public final class TemplateAttribute implements Entity {
|
|||
attr2.configAttribute.name) * ((descending) ? -1 : 1);
|
||||
}
|
||||
|
||||
public static final Comparator<TemplateAttribute> typeComparator(final boolean descending) {
|
||||
return (attr1, attr2) -> attr1.configAttribute.type.name().compareToIgnoreCase(
|
||||
attr2.configAttribute.type.name()) * ((descending) ? -1 : 1);
|
||||
}
|
||||
|
||||
public static final Comparator<TemplateAttribute> groupComparator(final boolean descending) {
|
||||
return (attr1, attr2) -> {
|
||||
final Orientation o1 = attr1.getOrientation();
|
||||
final Orientation o2 = attr2.getOrientation();
|
||||
final String name1 = (o1 != null && o1.getGroupId() != null)
|
||||
? o1.getGroupId()
|
||||
: Constants.EMPTY_NOTE;
|
||||
final String name2 = (o2 != null && o2.getGroupId() != null)
|
||||
? o2.getGroupId()
|
||||
: Constants.EMPTY_NOTE;
|
||||
return name1.compareToIgnoreCase(name2) * ((descending) ? -1 : 1);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,14 +22,15 @@ 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.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
||||
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;
|
||||
|
@ -42,8 +43,10 @@ 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.seb.examconfig.GetConfigurations;
|
||||
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.GetTemplateAttribute;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||
|
||||
|
@ -89,11 +92,19 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
public void compose(final PageContext pageContext) {
|
||||
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);
|
||||
|
||||
final ConfigurationNode template = this.restService
|
||||
.getBuilder(GetExamConfigNode.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, templateKey.modelId)
|
||||
.call()
|
||||
.get(pageContext::notifyError);
|
||||
|
||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(template);
|
||||
final boolean modifyGrant = entityGrant.m();
|
||||
|
||||
// the attribute
|
||||
final TemplateAttribute attribute = this.restService.getBuilder(GetTemplateAttribute.class)
|
||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, templateKey.modelId)
|
||||
|
@ -119,7 +130,7 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
|
||||
final boolean hasView = attribute.getOrientation() != null;
|
||||
|
||||
final FormHandle<TemplateAttribute> formHandle = this.pageService.formBuilder(
|
||||
this.pageService.formBuilder(
|
||||
formContext, 4)
|
||||
.readonly(true) // TODO change this for next version
|
||||
.addField(FormBuilder.text(
|
||||
|
@ -129,7 +140,7 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
.addField(FormBuilder.text(
|
||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
||||
FORM_TYPE_TEXT_KEY,
|
||||
() -> attribute.getConfigAttribute().getType().name()))
|
||||
() -> this.resourceService.getAttributeTypeName(attribute)))
|
||||
.addFieldIf(
|
||||
() -> hasView,
|
||||
() -> FormBuilder.singleSelection(
|
||||
|
@ -156,13 +167,10 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
|
||||
final PageContext valueContext = formContext.copyOf(grid);
|
||||
|
||||
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
||||
attribute.getConfigAttribute(),
|
||||
attribute.getOrientation());
|
||||
final Orientation defaultOrientation = getDefaultOrientation(attribute);
|
||||
final AttributeMapping attributeMapping = this.examConfigurationService
|
||||
.getAttributes(templateId)
|
||||
.getAttributes(attribute, defaultOrientation)
|
||||
.getOrThrow();
|
||||
|
||||
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
||||
valueContext,
|
||||
configuration,
|
||||
|
@ -170,6 +178,10 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
attributeMapping,
|
||||
1);
|
||||
|
||||
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
||||
attribute.getConfigAttribute(),
|
||||
defaultOrientation);
|
||||
|
||||
final InputField createInputField = inputFieldBuilder.createInputField(
|
||||
content,
|
||||
attribute.getConfigAttribute(),
|
||||
|
@ -188,12 +200,41 @@ public class ConfigTemplateAttributeForm implements TemplateComposer {
|
|||
.withParentEntityKey(templateKey)
|
||||
.withExec(this.examConfigurationService::resetToDefaults)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publish()
|
||||
.publishIf(() -> modifyGrant)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW)
|
||||
.withEntityKey(attributeKey)
|
||||
.withParentEntityKey(templateKey)
|
||||
.withExec(this.examConfigurationService::removeFromView)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> modifyGrant && hasView)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_ATTACH_DEFAULT_VIEW)
|
||||
.withEntityKey(attributeKey)
|
||||
.withParentEntityKey(templateKey)
|
||||
.withExec(this.examConfigurationService::attachToDefaultView)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> modifyGrant && !hasView)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_EDIT_TEMPLATE)
|
||||
.withEntityKey(templateKey)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publish();
|
||||
|
||||
}
|
||||
|
||||
private Orientation getDefaultOrientation(final TemplateAttribute attribute) {
|
||||
return new Orientation(
|
||||
-1L,
|
||||
attribute.getConfigAttribute().id,
|
||||
attribute.templateId,
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
TitleOrientation.NONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ 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 ATTRIBUTES_LIST_TYPE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.configtemplate.attrs.list.type");
|
||||
private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY =
|
||||
new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect");
|
||||
|
||||
|
@ -166,6 +168,7 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
FORM_DESCRIPTION_TEXT_KEY,
|
||||
examConfig.description)
|
||||
.asArea())
|
||||
|
||||
.buildFor((isNew)
|
||||
? this.restService.getRestCall(NewExamConfig.class)
|
||||
: this.restService.getRestCall(SaveExamConfig.class));
|
||||
|
@ -184,6 +187,10 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
CriteriaType.SINGLE_SELECTION,
|
||||
TemplateAttribute.FILTER_ATTR_VIEW,
|
||||
() -> this.resourceService.getViewResources(entityKey.modelId));
|
||||
final TableFilterAttribute typeFilter = new TableFilterAttribute(
|
||||
CriteriaType.SINGLE_SELECTION,
|
||||
TemplateAttribute.FILTER_ATTR_TYPE,
|
||||
() -> this.resourceService.getAttributeTypeResources());
|
||||
|
||||
final EntityTable<TemplateAttribute> attrTable =
|
||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetTemplateAttributePage.class))
|
||||
|
@ -197,6 +204,12 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
TemplateAttribute::getName)
|
||||
.withFilter(this.nameFilter)
|
||||
.sortable())
|
||||
.withColumn(new ColumnDefinition<TemplateAttribute>(
|
||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
||||
ATTRIBUTES_LIST_TYPE_TEXT_KEY,
|
||||
resourceService::getAttributeTypeName)
|
||||
.withFilter(typeFilter)
|
||||
.sortable())
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
Domain.ORIENTATION.ATTR_VIEW_ID,
|
||||
ATTRIBUTES_LIST_VIEW_TEXT_KEY,
|
||||
|
@ -234,7 +247,7 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
.noEventPropagation()
|
||||
.publishIf(() -> attrTable.hasAnyContent())
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW)
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_REMOVE_VIEW)
|
||||
.withParentEntityKey(entityKey)
|
||||
.withSelect(
|
||||
attrTable::getSelection,
|
||||
|
@ -243,7 +256,14 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
.noEventPropagation()
|
||||
.publishIf(() -> attrTable.hasAnyContent())
|
||||
|
||||
;
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_ATTACH_DEFAULT_VIEW)
|
||||
.withParentEntityKey(entityKey)
|
||||
.withSelect(
|
||||
attrTable::getSelection,
|
||||
action -> this.attachView(action, attrTable),
|
||||
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> attrTable.hasAnyContent());
|
||||
}
|
||||
|
||||
pageActionBuilder
|
||||
|
@ -288,4 +308,14 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
return removeFormView;
|
||||
}
|
||||
|
||||
private final PageAction attachView(
|
||||
final PageAction action,
|
||||
final EntityTable<TemplateAttribute> attrTable) {
|
||||
|
||||
final PageAction attachView = this.examConfigurationService.attachToDefaultView(action);
|
||||
// reload the list
|
||||
attrTable.applyFilter();
|
||||
return attachView;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -461,22 +461,37 @@ public enum ActionDefinition {
|
|||
ImageIcon.SAVE,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW,
|
||||
ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST),
|
||||
SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW(
|
||||
SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_REMOVE_VIEW(
|
||||
new LocTextKey("sebserver.configtemplate.attr.list.actions.removeview"),
|
||||
ImageIcon.DELETE,
|
||||
ImageIcon.REMOVE,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW,
|
||||
ActionCategory.SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST),
|
||||
SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_ATTACH_DEFAULT_VIEW(
|
||||
new LocTextKey("sebserver.configtemplate.attr.list.actions.attach-default-view"),
|
||||
ImageIcon.ADD,
|
||||
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.REMOVE,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT,
|
||||
ActionCategory.FORM),
|
||||
SEB_EXAM_CONFIG_TEMPLATE_ATTR_ATTACH_DEFAULT_VIEW(
|
||||
new LocTextKey("sebserver.configtemplate.attr.list.actions.attach-default-view"),
|
||||
ImageIcon.ADD,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT,
|
||||
ActionCategory.FORM),
|
||||
|
||||
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),
|
||||
ActionCategory.FORM),
|
||||
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),
|
||||
ActionCategory.FORM),
|
||||
|
||||
RUNNING_EXAM_VIEW_LIST(
|
||||
new LocTextKey("sebserver.monitoring.action.list"),
|
||||
|
|
|
@ -38,6 +38,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||
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;
|
||||
|
@ -95,6 +96,12 @@ public class ResourceService {
|
|||
public static final String EXAM_INDICATOR_TYPE_PREFIX = "sebserver.exam.indicator.type.";
|
||||
public static final String LMSSETUP_TYPE_PREFIX = "sebserver.lmssetup.type.";
|
||||
public static final String LMSSETUP_PROXY_AUTH_TYPE_PREFIX = "sebserver.lmssetup.form.proxy.auth-type.";
|
||||
public static final String CONFIG_ATTRIBUTE_TYPE_PREFIX = "sebserver.configtemplate.attr.type.";
|
||||
|
||||
public static final EnumSet<AttributeType> ATTRIBUTE_TYPES_NOT_DISPLAYED = EnumSet.of(
|
||||
AttributeType.LABEL,
|
||||
AttributeType.COMPOSITE_TABLE,
|
||||
AttributeType.INLINE_TABLE);
|
||||
|
||||
public static final String CLIENT_EVENT_TYPE_PREFIX = "sebserver.monitoring.exam.connection.event.type.";
|
||||
public static final String USER_ACTIVITY_TYPE_PREFIX = "sebserver.overall.types.activityType.";
|
||||
|
@ -494,6 +501,43 @@ public class ResourceService {
|
|||
return attr -> mapping.get(attr.getViewModelId());
|
||||
}
|
||||
|
||||
public List<Tuple<String>> getAttributeTypeResources() {
|
||||
return Arrays.asList(AttributeType.values())
|
||||
.stream()
|
||||
.filter(type -> !ATTRIBUTE_TYPES_NOT_DISPLAYED.contains(type))
|
||||
.map(type -> new Tuple<>(getAttributeTypeFilterName(type), getAttributeTypeName(type)))
|
||||
.sorted(RESOURCE_COMPARATOR)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String getAttributeTypeName(final TemplateAttribute attribute) {
|
||||
if (attribute != null && attribute.getConfigAttribute() != null) {
|
||||
return getAttributeTypeName(attribute.getConfigAttribute().type);
|
||||
}
|
||||
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
|
||||
private String getAttributeTypeFilterName(final AttributeType type) {
|
||||
if (type == AttributeType.TABLE) {
|
||||
return type.name()
|
||||
+ Constants.LIST_SEPARATOR
|
||||
+ AttributeType.COMPOSITE_TABLE.name()
|
||||
+ Constants.LIST_SEPARATOR
|
||||
+ AttributeType.INLINE_TABLE.name();
|
||||
} else {
|
||||
return type.name();
|
||||
}
|
||||
}
|
||||
|
||||
public String getAttributeTypeName(final AttributeType type) {
|
||||
if (type == null) {
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
return this.i18nSupport
|
||||
.getText(CONFIG_ATTRIBUTE_TYPE_PREFIX + type.name());
|
||||
}
|
||||
|
||||
public Map<Long, String> getExamNameMapping() {
|
||||
final UserInfo userInfo = this.currentUser.get();
|
||||
return this.restService.getBuilder(GetExamNames.class)
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.eclipse.swt.widgets.Composite;
|
|||
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.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
||||
|
@ -42,6 +43,10 @@ public interface ExamConfigurationService {
|
|||
|
||||
Result<AttributeMapping> getAttributes(Long templateId);
|
||||
|
||||
Result<AttributeMapping> getAttributes(
|
||||
final TemplateAttribute attribute,
|
||||
final Orientation defaultOrientation);
|
||||
|
||||
List<View> getViews(AttributeMapping allAttributes);
|
||||
|
||||
ViewContext createViewContext(
|
||||
|
|
|
@ -108,20 +108,46 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
|||
return Result.tryCatch(() -> {
|
||||
return new AttributeMapping(
|
||||
templateId,
|
||||
this.restService
|
||||
.getBuilder(GetConfigAttributes.class)
|
||||
.call()
|
||||
.onError(t -> log.error("Failed to get all ConfigurationAttribute"))
|
||||
.getOrThrow(),
|
||||
this.restService
|
||||
.getBuilder(GetOrientations.class)
|
||||
.withQueryParam(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(templateId))
|
||||
.call()
|
||||
.onError(t -> log.error("Failed to get all Orientation of template {}", templateId, t))
|
||||
.getOrThrow());
|
||||
getAttributes(),
|
||||
getOrientations(templateId));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<AttributeMapping> getAttributes(
|
||||
final TemplateAttribute attribute,
|
||||
final Orientation defaultOrientation) {
|
||||
|
||||
final List<Orientation> orientations = getOrientations(attribute.templateId);
|
||||
if (attribute.getOrientation() == null) {
|
||||
orientations.add(defaultOrientation);
|
||||
}
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
return new AttributeMapping(
|
||||
attribute.templateId,
|
||||
getAttributes(),
|
||||
orientations);
|
||||
});
|
||||
}
|
||||
|
||||
private List<Orientation> getOrientations(final Long templateId) {
|
||||
return this.restService
|
||||
.getBuilder(GetOrientations.class)
|
||||
.withQueryParam(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(templateId))
|
||||
.call()
|
||||
.onError(t -> log.error("Failed to get all Orientation of template {}", templateId, t))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private List<ConfigurationAttribute> getAttributes() {
|
||||
return this.restService
|
||||
.getBuilder(GetConfigAttributes.class)
|
||||
.call()
|
||||
.onError(t -> log.error("Failed to get all ConfigurationAttribute"))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<View> getViews(final AttributeMapping allAttributes) {
|
||||
final Collection<Long> viewIds = allAttributes.getViewIds();
|
||||
|
|
|
@ -19,15 +19,6 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
|||
|
||||
public interface ConfigurationValueDAO extends EntityDAO<ConfigurationValue, ConfigurationValue> {
|
||||
|
||||
/** NOTE: Deletion is not supported for ConfigurationValue.
|
||||
* A ConfigurationValue get automatically deleted on deletion of a Configuration */
|
||||
@Override
|
||||
default Result<Collection<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Deletion is not supported for ConfigurationValue. A ConfigurationValue get "
|
||||
+ "automatically deleted on deletion of a Configuration");
|
||||
}
|
||||
|
||||
/** Use this to get all ConfigurationValue for a specific configuration and for a all
|
||||
* root attributes that are not child attributes.
|
||||
*
|
||||
|
|
|
@ -229,6 +229,20 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO {
|
|||
.onError(TransactionHandler::rollback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<Collection<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
return Result.tryCatch(() -> {
|
||||
return extractPKsFromKeys(all)
|
||||
.stream()
|
||||
.map(pk -> {
|
||||
this.configurationValueRecordMapper.deleteByPrimaryKey(pk);
|
||||
return new EntityKey(pk, EntityType.CONFIGURATION_VALUE);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<ConfigurationTableValues> getTableValues(
|
||||
|
@ -355,26 +369,30 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO {
|
|||
.flatMap(this::getAttributeMapping)
|
||||
.map(attributeMapping -> {
|
||||
|
||||
final Set<EntityKey> 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());
|
||||
final Set<EntityKey> tableValues = new HashSet<>();
|
||||
if (attributeMapping != null && !attributeMapping.isEmpty()) {
|
||||
|
||||
// if there are table values, delete them first
|
||||
if (tableValues != null && !tableValues.isEmpty()) {
|
||||
this.delete(tableValues)
|
||||
.getOrThrow();
|
||||
tableValues.addAll(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
|
||||
|
@ -404,9 +422,14 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO {
|
|||
|
||||
final ConfigurationValueRecord oldRec = values.get(0);
|
||||
final ConfigurationValueRecord newRec = new ConfigurationValueRecord(
|
||||
oldRec.getId(), null, null, null, null, defaultValue);
|
||||
oldRec.getId(),
|
||||
oldRec.getInstitutionId(),
|
||||
oldRec.getConfigurationId(),
|
||||
oldRec.getConfigurationAttributeId(),
|
||||
oldRec.getListIndex(),
|
||||
defaultValue);
|
||||
|
||||
this.configurationValueRecordMapper.updateByPrimaryKeySelective(newRec);
|
||||
this.configurationValueRecordMapper.updateByPrimaryKey(newRec);
|
||||
|
||||
final HashSet<EntityKey> result = new HashSet<>();
|
||||
result.add(new EntityKey(newRec.getId(), EntityType.CONFIGURATION_VALUE));
|
||||
|
|
|
@ -10,6 +10,8 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -22,12 +24,15 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||
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;
|
||||
|
@ -88,14 +93,30 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe
|
|||
.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)))
|
||||
&& attr.isInView(filterMap.getLong(TemplateAttribute.FILTER_ATTR_VIEW))
|
||||
&& attr.hasType(extractTypes(filterMap)))
|
||||
.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));
|
||||
if (sortBy.equals(Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME)) {
|
||||
Collections.sort(
|
||||
attrs,
|
||||
TemplateAttribute.nameComparator(sortOrder == PageSortOrder.DESCENDING));
|
||||
} else if (sortBy.equals(Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE)) {
|
||||
Collections.sort(
|
||||
attrs,
|
||||
TemplateAttribute.typeComparator(sortOrder == PageSortOrder.DESCENDING));
|
||||
} else if (sortBy.equals(Domain.ORIENTATION.ATTR_VIEW_ID)) {
|
||||
Collections.sort(attrs, this.getViewComparator(
|
||||
institutionId,
|
||||
templateId,
|
||||
sortOrder == PageSortOrder.DESCENDING));
|
||||
} else if (sortBy.equals(Domain.ORIENTATION.ATTR_GROUP_ID)) {
|
||||
Collections.sort(
|
||||
attrs,
|
||||
TemplateAttribute.groupComparator(sortOrder == PageSortOrder.DESCENDING));
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
|
@ -203,7 +224,7 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe
|
|||
devOrientation.height,
|
||||
devOrientation.title);
|
||||
|
||||
this.orientationDAO.save(newOrientation)
|
||||
this.orientationDAO.createNew(newOrientation)
|
||||
.getOrThrow();
|
||||
|
||||
final TemplateAttribute attribute = getAttribute(institutionId, templateId, attributeId)
|
||||
|
@ -234,4 +255,60 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe
|
|||
.orElse(null);
|
||||
}
|
||||
|
||||
private Comparator<TemplateAttribute> getViewComparator(
|
||||
final Long institutionId,
|
||||
final Long templateId,
|
||||
final boolean descending) {
|
||||
|
||||
final Map<Long, View> viewMap = this.viewDAO.allMatching(new FilterMap.Builder()
|
||||
.add(View.FILTER_ATTR_INSTITUTION, String.valueOf(institutionId))
|
||||
.add(View.FILTER_ATTR_TEMPLATE, String.valueOf(templateId))
|
||||
.create())
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(v -> v.id, Function.identity()));
|
||||
|
||||
return (attr1, attr2) -> {
|
||||
|
||||
return getViewName(attr1, viewMap)
|
||||
.compareToIgnoreCase(getViewName(attr2, viewMap))
|
||||
* ((descending) ? -1 : 1);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private EnumSet<AttributeType> extractTypes(final FilterMap filterMap) {
|
||||
final EnumSet<AttributeType> result = EnumSet.noneOf(AttributeType.class);
|
||||
final String types = filterMap.getString(TemplateAttribute.FILTER_ATTR_TYPE);
|
||||
if (StringUtils.isBlank(types)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final String[] split = StringUtils.split(types, Constants.LIST_SEPARATOR);
|
||||
if (split != null) {
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
result.add(AttributeType.valueOf(split[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final String getViewName(
|
||||
final TemplateAttribute attribute,
|
||||
final Map<Long, View> viewMap) {
|
||||
|
||||
final Orientation orientation = attribute.getOrientation();
|
||||
if (orientation == null || orientation.viewId == null) {
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
|
||||
final View view = viewMap.get(orientation.viewId);
|
||||
if (view != null) {
|
||||
return view.name;
|
||||
}
|
||||
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = API.PARAM_VIEW_ID) final Long viewId) {
|
||||
@RequestParam(name = API.PARAM_VIEW_ID, required = false) final Long viewId) {
|
||||
|
||||
checkModifyPrivilege(institutionId);
|
||||
|
||||
|
|
|
@ -947,15 +947,34 @@ sebserver.configtemplate.form.name=Name
|
|||
sebserver.configtemplate.form.description=Description
|
||||
sebserver.configtemplate.action.save=Save Template
|
||||
|
||||
sebserver.configtemplate.attr.type.TEXT_FIELD=Text Field
|
||||
sebserver.configtemplate.attr.type.PASSWORD_FIELD=Password Field
|
||||
sebserver.configtemplate.attr.type.TEXT_AREA=Text Area
|
||||
sebserver.configtemplate.attr.type.CHECKBOX=Checkbox
|
||||
sebserver.configtemplate.attr.type.SLIDER=Slider
|
||||
sebserver.configtemplate.attr.type.INTEGER=Number (Integer)
|
||||
sebserver.configtemplate.attr.type.DECIMAL=Number (Decimal)
|
||||
sebserver.configtemplate.attr.type.SINGLE_SELECTION=Single Selection
|
||||
sebserver.configtemplate.attr.type.COMBO_SELECTION=Combo Selection
|
||||
sebserver.configtemplate.attr.type.RADIO_SELECTION=Radio Selection
|
||||
sebserver.configtemplate.attr.type.MULTI_SELECTION=Multi Selection
|
||||
sebserver.configtemplate.attr.type.MULTI_CHECKBOX_SELECTION=Multi Selection (Checkbox)
|
||||
sebserver.configtemplate.attr.type.FILE_UPLOAD=File Upload
|
||||
sebserver.configtemplate.attr.type.TABLE=Table
|
||||
sebserver.configtemplate.attr.type.INLINE_TABLE=Table
|
||||
sebserver.configtemplate.attr.type.COMPOSITE_TABLE=Table
|
||||
|
||||
sebserver.configtemplate.attrs.list.title=Configuration Attributes
|
||||
sebserver.configtemplate.attrs.list.name=Name
|
||||
sebserver.configtemplate.attrs.list.view=View
|
||||
sebserver.configtemplate.attrs.list.group=Group
|
||||
sebserver.configtemplate.attrs.list.type=Type
|
||||
|
||||
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 From View
|
||||
sebserver.configtemplate.attr.list.actions.attach-default-view=Attach To View
|
||||
sebserver.configtemplate.attr.info.pleaseSelect=Please select an attribute first
|
||||
|
||||
sebserver.configtemplate.attr.form.title=Template Attribute
|
||||
|
|
Loading…
Add table
Reference in a new issue