SEBSERV-153 IndicatorTemplate implementation
This commit is contained in:
		
							parent
							
								
									446bb15a9c
								
							
						
					
					
						commit
						152955f712
					
				
					 22 changed files with 524 additions and 137 deletions
				
			
		| 
						 | 
					@ -59,7 +59,7 @@ public class ExamTemplate implements GrantEntity {
 | 
				
			||||||
    public final Long configTemplateId;
 | 
					    public final Long configTemplateId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @JsonProperty(EXAM_TEMPLATE.ATTR_INDICATOR_TEMPLATES)
 | 
					    @JsonProperty(EXAM_TEMPLATE.ATTR_INDICATOR_TEMPLATES)
 | 
				
			||||||
    public final Collection<Indicator> indicatorTemplates;
 | 
					    public final Collection<IndicatorTemplate> indicatorTemplates;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @JsonProperty(ATTR_EXAM_ATTRIBUTES)
 | 
					    @JsonProperty(ATTR_EXAM_ATTRIBUTES)
 | 
				
			||||||
    public final Map<String, String> examAttributes;
 | 
					    public final Map<String, String> examAttributes;
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ public class ExamTemplate implements GrantEntity {
 | 
				
			||||||
            @JsonProperty(EXAM_TEMPLATE.ATTR_EXAM_TYPE) final ExamType examType,
 | 
					            @JsonProperty(EXAM_TEMPLATE.ATTR_EXAM_TYPE) final ExamType examType,
 | 
				
			||||||
            @JsonProperty(EXAM_TEMPLATE.ATTR_SUPPORTER) final Collection<String> supporter,
 | 
					            @JsonProperty(EXAM_TEMPLATE.ATTR_SUPPORTER) final Collection<String> supporter,
 | 
				
			||||||
            @JsonProperty(EXAM_TEMPLATE.ATTR_CONFIGURATION_TEMPLATE_ID) final Long configTemplateId,
 | 
					            @JsonProperty(EXAM_TEMPLATE.ATTR_CONFIGURATION_TEMPLATE_ID) final Long configTemplateId,
 | 
				
			||||||
            @JsonProperty(EXAM_TEMPLATE.ATTR_INDICATOR_TEMPLATES) final Collection<Indicator> indicatorTemplates,
 | 
					            @JsonProperty(EXAM_TEMPLATE.ATTR_INDICATOR_TEMPLATES) final Collection<IndicatorTemplate> indicatorTemplates,
 | 
				
			||||||
            @JsonProperty(ATTR_EXAM_ATTRIBUTES) final Map<String, String> examAttributes) {
 | 
					            @JsonProperty(ATTR_EXAM_ATTRIBUTES) final Map<String, String> examAttributes) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.id = id;
 | 
					        this.id = id;
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ public class ExamTemplate implements GrantEntity {
 | 
				
			||||||
        return this.configTemplateId;
 | 
					        return this.configTemplateId;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Collection<Indicator> getIndicatorTemplates() {
 | 
					    public Collection<IndicatorTemplate> getIndicatorTemplates() {
 | 
				
			||||||
        return this.indicatorTemplates;
 | 
					        return this.indicatorTemplates;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,8 +217,12 @@ public final class Indicator implements Entity {
 | 
				
			||||||
        return builder.toString();
 | 
					        return builder.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static Indicator createNew(final Exam exam) {
 | 
					    public static Indicator createNew(final String examId) {
 | 
				
			||||||
        return new Indicator(null, exam.id, null, null, null, null, null, null);
 | 
					        try {
 | 
				
			||||||
 | 
					            return new Indicator(null, Long.parseLong(examId), null, null, null, null, null, null);
 | 
				
			||||||
 | 
					        } catch (final Exception e) {
 | 
				
			||||||
 | 
					            return new Indicator(null, null, null, null, null, null, null, null);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static String getDisplayValue(final IndicatorType indicatorType, final Double value) {
 | 
					    public static String getDisplayValue(final IndicatorType indicatorType, final Double value) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,175 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 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.gbl.model.exam;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.validation.constraints.NotNull;
 | 
				
			||||||
 | 
					import javax.validation.constraints.Size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonCreator;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.api.EntityType;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.Domain;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.Domain.INDICATOR;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.Domain.THRESHOLD;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.Entity;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					public class IndicatorTemplate implements Entity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final String ATTR_EXAM_TEMPLATE_ID = "examTemplateId";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_ID)
 | 
				
			||||||
 | 
					    public final Long id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(ATTR_EXAM_TEMPLATE_ID)
 | 
				
			||||||
 | 
					    public final Long examTemplateId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_NAME)
 | 
				
			||||||
 | 
					    @NotNull(message = "indicator:name:notNull")
 | 
				
			||||||
 | 
					    @Size(min = 3, max = 255, message = "indicator:name:size:{min}:{max}:${validatedValue}")
 | 
				
			||||||
 | 
					    public final String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_TYPE)
 | 
				
			||||||
 | 
					    @NotNull(message = "indicator:type:notNull")
 | 
				
			||||||
 | 
					    public final IndicatorType type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_COLOR)
 | 
				
			||||||
 | 
					    public final String defaultColor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_ICON)
 | 
				
			||||||
 | 
					    public final String defaultIcon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(INDICATOR.ATTR_TAGS)
 | 
				
			||||||
 | 
					    public final String tags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonProperty(THRESHOLD.REFERENCE_NAME)
 | 
				
			||||||
 | 
					    public final List<Threshold> thresholds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonCreator
 | 
				
			||||||
 | 
					    public IndicatorTemplate(
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_ID) final Long id,
 | 
				
			||||||
 | 
					            @JsonProperty(ATTR_EXAM_TEMPLATE_ID) final Long examTemplateId,
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_NAME) final String name,
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_TYPE) final IndicatorType type,
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_COLOR) final String defaultColor,
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_ICON) final String defaultIcon,
 | 
				
			||||||
 | 
					            @JsonProperty(INDICATOR.ATTR_TAGS) final String tags,
 | 
				
			||||||
 | 
					            @JsonProperty(THRESHOLD.REFERENCE_NAME) final Collection<Threshold> thresholds) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.id = id;
 | 
				
			||||||
 | 
					        this.examTemplateId = examTemplateId;
 | 
				
			||||||
 | 
					        this.name = name;
 | 
				
			||||||
 | 
					        this.type = type;
 | 
				
			||||||
 | 
					        this.defaultColor = defaultColor;
 | 
				
			||||||
 | 
					        this.defaultIcon = defaultIcon;
 | 
				
			||||||
 | 
					        this.tags = tags;
 | 
				
			||||||
 | 
					        this.thresholds = Utils.immutableListOf(thresholds);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** This initialize an indicator for an exam template */
 | 
				
			||||||
 | 
					    public IndicatorTemplate(final Long id, final Long examTemplateId, final POSTMapper postParams) {
 | 
				
			||||||
 | 
					        this.id = id;
 | 
				
			||||||
 | 
					        this.examTemplateId = examTemplateId;
 | 
				
			||||||
 | 
					        this.name = postParams.getString(Domain.INDICATOR.ATTR_NAME);
 | 
				
			||||||
 | 
					        this.type = postParams.getEnum(Domain.INDICATOR.ATTR_TYPE, IndicatorType.class);
 | 
				
			||||||
 | 
					        this.defaultColor = postParams.getString(Domain.INDICATOR.ATTR_COLOR);
 | 
				
			||||||
 | 
					        this.defaultIcon = postParams.getString(Domain.INDICATOR.ATTR_ICON);
 | 
				
			||||||
 | 
					        this.tags = postParams.getString(Domain.INDICATOR.ATTR_TAGS);
 | 
				
			||||||
 | 
					        this.thresholds = postParams.getThresholds();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getModelId() {
 | 
				
			||||||
 | 
					        return (this.id == null) ? null : String.valueOf(this.id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public EntityType entityType() {
 | 
				
			||||||
 | 
					        return EntityType.INDICATOR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getName() {
 | 
				
			||||||
 | 
					        return this.name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Long getId() {
 | 
				
			||||||
 | 
					        return this.id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Long getExamTemplateId() {
 | 
				
			||||||
 | 
					        return this.examTemplateId;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public IndicatorType getType() {
 | 
				
			||||||
 | 
					        return this.type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getDefaultColor() {
 | 
				
			||||||
 | 
					        return this.defaultColor;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getDefaultIcon() {
 | 
				
			||||||
 | 
					        return this.defaultIcon;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getTags() {
 | 
				
			||||||
 | 
					        return this.tags;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Collection<Threshold> getThresholds() {
 | 
				
			||||||
 | 
					        return this.thresholds;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String toString() {
 | 
				
			||||||
 | 
					        final StringBuilder builder = new StringBuilder();
 | 
				
			||||||
 | 
					        builder.append("Indicator [id=");
 | 
				
			||||||
 | 
					        builder.append(this.id);
 | 
				
			||||||
 | 
					        builder.append(", examId=");
 | 
				
			||||||
 | 
					        builder.append(this.examTemplateId);
 | 
				
			||||||
 | 
					        builder.append(", name=");
 | 
				
			||||||
 | 
					        builder.append(this.name);
 | 
				
			||||||
 | 
					        builder.append(", type=");
 | 
				
			||||||
 | 
					        builder.append(this.type);
 | 
				
			||||||
 | 
					        builder.append(", defaultColor=");
 | 
				
			||||||
 | 
					        builder.append(this.defaultColor);
 | 
				
			||||||
 | 
					        builder.append(", defaultIcon=");
 | 
				
			||||||
 | 
					        builder.append(this.defaultIcon);
 | 
				
			||||||
 | 
					        builder.append(", tags=");
 | 
				
			||||||
 | 
					        builder.append(this.tags);
 | 
				
			||||||
 | 
					        builder.append(", thresholds=");
 | 
				
			||||||
 | 
					        builder.append(this.thresholds);
 | 
				
			||||||
 | 
					        builder.append("]");
 | 
				
			||||||
 | 
					        return builder.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static String getDisplayValue(final IndicatorType indicatorType, final Double value) {
 | 
				
			||||||
 | 
					        if (value == null || indicatorType == null) {
 | 
				
			||||||
 | 
					            return StringUtils.EMPTY;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (indicatorType.integerValue) {
 | 
				
			||||||
 | 
					            return String.valueOf(value.intValue());
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return String.valueOf(value.floatValue());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ public enum ActionCategory {
 | 
				
			||||||
    QUIZ_LIST(new LocTextKey("sebserver.quizdiscovery.list.actions"), 1),
 | 
					    QUIZ_LIST(new LocTextKey("sebserver.quizdiscovery.list.actions"), 1),
 | 
				
			||||||
    EXAM_LIST(new LocTextKey("sebserver.exam.list.actions"), 1),
 | 
					    EXAM_LIST(new LocTextKey("sebserver.exam.list.actions"), 1),
 | 
				
			||||||
    EXAM_TEMPLATE_LIST(new LocTextKey("sebserver.examtemplate.list.actions"), 1),
 | 
					    EXAM_TEMPLATE_LIST(new LocTextKey("sebserver.examtemplate.list.actions"), 1),
 | 
				
			||||||
    EXAM_TEMPLATE_INDICATOR_LIST(new LocTextKey("sebserver.examtemplate.indicator.list.actions"), 2),
 | 
					    INDICATOR_TEMPLATE_LIST(new LocTextKey("sebserver.examtemplate.indicator.list.actions"), 1),
 | 
				
			||||||
    EXAM_CONFIG_MAPPING_LIST(new LocTextKey("sebserver.exam.configuration.list.actions"), 1),
 | 
					    EXAM_CONFIG_MAPPING_LIST(new LocTextKey("sebserver.exam.configuration.list.actions"), 1),
 | 
				
			||||||
    INDICATOR_LIST(new LocTextKey("sebserver.exam.indicator.list.actions"), 2),
 | 
					    INDICATOR_LIST(new LocTextKey("sebserver.exam.indicator.list.actions"), 2),
 | 
				
			||||||
    SEB_CLIENT_CONFIG_LIST(new LocTextKey("sebserver.clientconfig.list.actions"), 1),
 | 
					    SEB_CLIENT_CONFIG_LIST(new LocTextKey("sebserver.clientconfig.list.actions"), 1),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -398,12 +398,12 @@ public enum ActionDefinition {
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_EDIT,
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_EDIT,
 | 
				
			||||||
            ActionCategory.LIST_VARIA),
 | 
					            ActionCategory.LIST_VARIA),
 | 
				
			||||||
    EXAM_TEMPLATE_MODIFY(
 | 
					    EXAM_TEMPLATE_MODIFY(
 | 
				
			||||||
            new LocTextKey("sebserver.examtemplate.action.list.edit"),
 | 
					            new LocTextKey("sebserver.examtemplate.form.action.edit"),
 | 
				
			||||||
            ImageIcon.TEMPLATE,
 | 
					            ImageIcon.EDIT,
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_EDIT,
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_EDIT,
 | 
				
			||||||
            ActionCategory.LIST_VARIA),
 | 
					            ActionCategory.FORM),
 | 
				
			||||||
    EXAM_TEMPLATE_SAVE(
 | 
					    EXAM_TEMPLATE_SAVE(
 | 
				
			||||||
            new LocTextKey("sebserver.examtemplate.action.save"),
 | 
					            new LocTextKey("sebserver.examtemplate.form.action.save"),
 | 
				
			||||||
            ImageIcon.SAVE,
 | 
					            ImageIcon.SAVE,
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
				
			||||||
            ActionCategory.FORM),
 | 
					            ActionCategory.FORM),
 | 
				
			||||||
| 
						 | 
					@ -413,21 +413,31 @@ public enum ActionDefinition {
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
				
			||||||
            ActionCategory.FORM),
 | 
					            ActionCategory.FORM),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EXAM_TEMPLATE_INDICATOR_NEW(
 | 
					    INDICATOR_TEMPLATE_NEW(
 | 
				
			||||||
            new LocTextKey("sebserver.examtemplate.indicator.action.list.new"),
 | 
					            new LocTextKey("sebserver.examtemplate.indicator.action.list.new"),
 | 
				
			||||||
            ImageIcon.INDICATOR,
 | 
					            ImageIcon.INDICATOR,
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_INDICATOR_EDIT,
 | 
					            PageStateDefinitionImpl.INDICATOR_TEMPLATE_EDIT,
 | 
				
			||||||
            ActionCategory.EXAM_TEMPLATE_INDICATOR_LIST),
 | 
					            ActionCategory.INDICATOR_TEMPLATE_LIST),
 | 
				
			||||||
    EXAM_TEMPLATE_INDICATOR_MODIFY_FROM_LIST(
 | 
					    INDICATOR_TEMPLATE_MODIFY_FROM_LIST(
 | 
				
			||||||
            new LocTextKey("sebserver.examtemplate.indicator.action.list.modify"),
 | 
					            new LocTextKey("sebserver.examtemplate.indicator.action.list.modify"),
 | 
				
			||||||
            ImageIcon.EDIT,
 | 
					            ImageIcon.EDIT,
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_INDICATOR_EDIT,
 | 
					            PageStateDefinitionImpl.INDICATOR_TEMPLATE_EDIT,
 | 
				
			||||||
            ActionCategory.EXAM_TEMPLATE_INDICATOR_LIST),
 | 
					            ActionCategory.INDICATOR_TEMPLATE_LIST),
 | 
				
			||||||
    EXAM_TEMPLATE_INDICATOR_DELETE_FROM_LIST(
 | 
					    INDICATOR_TEMPLATE_DELETE_FROM_LIST(
 | 
				
			||||||
            new LocTextKey("sebserver.examtemplate.indicator.action.list.delete"),
 | 
					            new LocTextKey("sebserver.examtemplate.indicator.action.list.delete"),
 | 
				
			||||||
            ImageIcon.DELETE,
 | 
					            ImageIcon.DELETE,
 | 
				
			||||||
            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
				
			||||||
            ActionCategory.EXAM_TEMPLATE_INDICATOR_LIST),
 | 
					            ActionCategory.INDICATOR_TEMPLATE_LIST),
 | 
				
			||||||
 | 
					    INDICATOR_TEMPLATE_SAVE(
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.examtemplate.indicator.action.save"),
 | 
				
			||||||
 | 
					            ImageIcon.SAVE,
 | 
				
			||||||
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
				
			||||||
 | 
					            ActionCategory.FORM),
 | 
				
			||||||
 | 
					    INDICATOR_TEMPLATE_CANCEL_MODIFY(
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.overall.action.modify.cancel"),
 | 
				
			||||||
 | 
					            ImageIcon.CANCEL,
 | 
				
			||||||
 | 
					            PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
 | 
				
			||||||
 | 
					            ActionCategory.FORM),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SEB_CLIENT_CONFIG_LIST(
 | 
					    SEB_CLIENT_CONFIG_LIST(
 | 
				
			||||||
            new LocTextKey("sebserver.clientconfig.list.title"),
 | 
					            new LocTextKey("sebserver.clientconfig.list.title"),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,9 +27,9 @@ import ch.ethz.seb.sebserver.gui.content.configs.SEBSettingsForm;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.ExamForm;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.ExamForm;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.ExamList;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.ExamList;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.ExamTemplateForm;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.ExamTemplateForm;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.ExamTemplateIndicatorForm;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.ExamTemplateList;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.ExamTemplateList;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.IndicatorForm;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.IndicatorForm;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.IndicatorTemplateForm;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.LmsSetupForm;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.LmsSetupForm;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.LmsSetupList;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.LmsSetupList;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.exam.QuizLookupList;
 | 
					import ch.ethz.seb.sebserver.gui.content.exam.QuizLookupList;
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,7 @@ public enum PageStateDefinitionImpl implements PageStateDefinition {
 | 
				
			||||||
    EXAM_TEMPLATE_LIST(Type.LIST_VIEW, ExamTemplateList.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
					    EXAM_TEMPLATE_LIST(Type.LIST_VIEW, ExamTemplateList.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
				
			||||||
    EXAM_TEMPLATE_VIEW(Type.LIST_VIEW, ExamTemplateForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
					    EXAM_TEMPLATE_VIEW(Type.LIST_VIEW, ExamTemplateForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
				
			||||||
    EXAM_TEMPLATE_EDIT(Type.FORM_EDIT, ExamTemplateForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
					    EXAM_TEMPLATE_EDIT(Type.FORM_EDIT, ExamTemplateForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
				
			||||||
    EXAM_TEMPLATE_INDICATOR_EDIT(Type.FORM_EDIT, ExamTemplateIndicatorForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
					    INDICATOR_TEMPLATE_EDIT(Type.FORM_EDIT, IndicatorTemplateForm.class, ActivityDefinition.EXAM_TEMPLATE),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SEB_CLIENT_CONFIG_LIST(Type.LIST_VIEW, SEBClientConfigList.class, ActivityDefinition.SEB_CLIENT_CONFIG),
 | 
					    SEB_CLIENT_CONFIG_LIST(Type.LIST_VIEW, SEBClientConfigList.class, ActivityDefinition.SEB_CLIENT_CONFIG),
 | 
				
			||||||
    SEB_CLIENT_CONFIG_VIEW(Type.FORM_VIEW, SEBClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
 | 
					    SEB_CLIENT_CONFIG_VIEW(Type.FORM_VIEW, SEBClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package ch.ethz.seb.sebserver.gui.content.exam;
 | 
					package ch.ethz.seb.sebserver.gui.content.exam;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.apache.commons.lang3.BooleanUtils;
 | 
					import org.apache.commons.lang3.BooleanUtils;
 | 
				
			||||||
import org.eclipse.swt.widgets.Composite;
 | 
					import org.eclipse.swt.widgets.Composite;
 | 
				
			||||||
import org.springframework.context.annotation.Lazy;
 | 
					import org.springframework.context.annotation.Lazy;
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,8 @@ import ch.ethz.seb.sebserver.gbl.api.API;
 | 
				
			||||||
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.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
 | 
					import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
 | 
				
			||||||
| 
						 | 
					@ -104,10 +108,10 @@ public class ExamFormIndicators implements TemplateComposer {
 | 
				
			||||||
                                INDICATOR_TYPE_COLUMN_KEY,
 | 
					                                INDICATOR_TYPE_COLUMN_KEY,
 | 
				
			||||||
                                this::indicatorTypeName)
 | 
					                                this::indicatorTypeName)
 | 
				
			||||||
                                        .widthProportion(1))
 | 
					                                        .widthProportion(1))
 | 
				
			||||||
                        .withColumn(new ColumnDefinition<>(
 | 
					                        .withColumn(new ColumnDefinition<Indicator>(
 | 
				
			||||||
                                Domain.THRESHOLD.REFERENCE_NAME,
 | 
					                                Domain.THRESHOLD.REFERENCE_NAME,
 | 
				
			||||||
                                INDICATOR_THRESHOLD_COLUMN_KEY,
 | 
					                                INDICATOR_THRESHOLD_COLUMN_KEY,
 | 
				
			||||||
                                ExamFormIndicators::thresholdsValue)
 | 
					                                i -> thresholdsValue(i.thresholds, i.type))
 | 
				
			||||||
                                        .asMarkup()
 | 
					                                        .asMarkup()
 | 
				
			||||||
                                        .widthProportion(4))
 | 
					                                        .widthProportion(4))
 | 
				
			||||||
                        .withDefaultActionIf(
 | 
					                        .withDefaultActionIf(
 | 
				
			||||||
| 
						 | 
					@ -166,12 +170,15 @@ public class ExamFormIndicators implements TemplateComposer {
 | 
				
			||||||
                .getText(ResourceService.EXAM_INDICATOR_TYPE_PREFIX + indicator.type.name());
 | 
					                .getText(ResourceService.EXAM_INDICATOR_TYPE_PREFIX + indicator.type.name());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static String thresholdsValue(final Indicator indicator) {
 | 
					    static String thresholdsValue(
 | 
				
			||||||
        if (indicator.thresholds.isEmpty()) {
 | 
					            final List<Threshold> thresholds,
 | 
				
			||||||
 | 
					            final IndicatorType indicatorType) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (thresholds.isEmpty()) {
 | 
				
			||||||
            return Constants.EMPTY_NOTE;
 | 
					            return Constants.EMPTY_NOTE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final StringBuilder builder = indicator.thresholds
 | 
					        final StringBuilder builder = thresholds
 | 
				
			||||||
                .stream()
 | 
					                .stream()
 | 
				
			||||||
                .reduce(
 | 
					                .reduce(
 | 
				
			||||||
                        new StringBuilder(),
 | 
					                        new StringBuilder(),
 | 
				
			||||||
| 
						 | 
					@ -183,7 +190,7 @@ public class ExamFormIndicators implements TemplateComposer {
 | 
				
			||||||
                                        ? "color: #4a4a4a; "
 | 
					                                        ? "color: #4a4a4a; "
 | 
				
			||||||
                                        : "color: #FFFFFF;")
 | 
					                                        : "color: #FFFFFF;")
 | 
				
			||||||
                                .append("'>")
 | 
					                                .append("'>")
 | 
				
			||||||
                                .append(Indicator.getDisplayValue(indicator.type, threshold.value))
 | 
					                                .append(Indicator.getDisplayValue(indicatorType, threshold.value))
 | 
				
			||||||
                                .append(" (")
 | 
					                                .append(" (")
 | 
				
			||||||
                                .append(threshold.color)
 | 
					                                .append(threshold.color)
 | 
				
			||||||
                                .append(")")
 | 
					                                .append(")")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ 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.exam.Exam;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Tuple;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
 | 
					import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
 | 
				
			||||||
| 
						 | 
					@ -36,9 +36,9 @@ 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.exam.DeleteExamTemplateIndicator;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplateIndicatorPage;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicatorTemplatePage;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
 | 
				
			||||||
| 
						 | 
					@ -133,6 +133,9 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
                .putStaticValueIf(() -> !isNew,
 | 
					                .putStaticValueIf(() -> !isNew,
 | 
				
			||||||
                        Domain.EXAM_TEMPLATE.ATTR_ID,
 | 
					                        Domain.EXAM_TEMPLATE.ATTR_ID,
 | 
				
			||||||
                        examTemplate.getModelId())
 | 
					                        examTemplate.getModelId())
 | 
				
			||||||
 | 
					                .putStaticValueIf(() -> !isNew,
 | 
				
			||||||
 | 
					                        Domain.EXAM_TEMPLATE.ATTR_INSTITUTION_ID,
 | 
				
			||||||
 | 
					                        String.valueOf(examTemplate.getInstitutionId()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .addField(FormBuilder.text(
 | 
					                .addField(FormBuilder.text(
 | 
				
			||||||
                        Domain.EXAM_TEMPLATE.ATTR_NAME,
 | 
					                        Domain.EXAM_TEMPLATE.ATTR_NAME,
 | 
				
			||||||
| 
						 | 
					@ -176,9 +179,6 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
        // propagate content actions to action-pane
 | 
					        // propagate content actions to action-pane
 | 
				
			||||||
        this.pageService.pageActionBuilder(formContext.clearEntityKeys())
 | 
					        this.pageService.pageActionBuilder(formContext.clearEntityKeys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .newAction(ActionDefinition.EXAM_TEMPLATE_NEW)
 | 
					 | 
				
			||||||
                .publishIf(() -> userGrant.iw() && readonly)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                .newAction(ActionDefinition.EXAM_TEMPLATE_MODIFY)
 | 
					                .newAction(ActionDefinition.EXAM_TEMPLATE_MODIFY)
 | 
				
			||||||
                .withEntityKey(entityKey)
 | 
					                .withEntityKey(entityKey)
 | 
				
			||||||
                .publishIf(() -> userGrant.im() && readonly)
 | 
					                .publishIf(() -> userGrant.im() && readonly)
 | 
				
			||||||
| 
						 | 
					@ -207,9 +207,9 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
            final PageActionBuilder actionBuilder = this.pageService
 | 
					            final PageActionBuilder actionBuilder = this.pageService
 | 
				
			||||||
                    .pageActionBuilder(pageContext.clearEntityKeys());
 | 
					                    .pageActionBuilder(pageContext.clearEntityKeys());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final EntityTable<Indicator> indicatorTable =
 | 
					            final EntityTable<IndicatorTemplate> indicatorTable =
 | 
				
			||||||
                    this.pageService
 | 
					                    this.pageService
 | 
				
			||||||
                            .entityTableBuilder(this.restService.getRestCall(GetExamTemplateIndicatorPage.class))
 | 
					                            .entityTableBuilder(this.restService.getRestCall(GetIndicatorTemplatePage.class))
 | 
				
			||||||
                            .withRestCallAdapter(builder -> builder.withURIVariable(
 | 
					                            .withRestCallAdapter(builder -> builder.withURIVariable(
 | 
				
			||||||
                                    API.PARAM_PARENT_MODEL_ID,
 | 
					                                    API.PARAM_PARENT_MODEL_ID,
 | 
				
			||||||
                                    entityKey.modelId))
 | 
					                                    entityKey.modelId))
 | 
				
			||||||
| 
						 | 
					@ -220,36 +220,36 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
                            .withColumn(new ColumnDefinition<>(
 | 
					                            .withColumn(new ColumnDefinition<>(
 | 
				
			||||||
                                    Domain.INDICATOR.ATTR_NAME,
 | 
					                                    Domain.INDICATOR.ATTR_NAME,
 | 
				
			||||||
                                    INDICATOR_NAME_COLUMN_KEY,
 | 
					                                    INDICATOR_NAME_COLUMN_KEY,
 | 
				
			||||||
                                    Indicator::getName)
 | 
					                                    IndicatorTemplate::getName)
 | 
				
			||||||
                                            .widthProportion(2))
 | 
					                                            .widthProportion(2))
 | 
				
			||||||
                            .withColumn(new ColumnDefinition<>(
 | 
					                            .withColumn(new ColumnDefinition<>(
 | 
				
			||||||
                                    Domain.INDICATOR.ATTR_TYPE,
 | 
					                                    Domain.INDICATOR.ATTR_TYPE,
 | 
				
			||||||
                                    INDICATOR_TYPE_COLUMN_KEY,
 | 
					                                    INDICATOR_TYPE_COLUMN_KEY,
 | 
				
			||||||
                                    this::indicatorTypeName)
 | 
					                                    this::indicatorTypeName)
 | 
				
			||||||
                                            .widthProportion(1))
 | 
					                                            .widthProportion(1))
 | 
				
			||||||
                            .withColumn(new ColumnDefinition<>(
 | 
					                            .withColumn(new ColumnDefinition<IndicatorTemplate>(
 | 
				
			||||||
                                    Domain.THRESHOLD.REFERENCE_NAME,
 | 
					                                    Domain.THRESHOLD.REFERENCE_NAME,
 | 
				
			||||||
                                    INDICATOR_THRESHOLD_COLUMN_KEY,
 | 
					                                    INDICATOR_THRESHOLD_COLUMN_KEY,
 | 
				
			||||||
                                    ExamFormIndicators::thresholdsValue)
 | 
					                                    it -> ExamFormIndicators.thresholdsValue(it.thresholds, it.type))
 | 
				
			||||||
                                            .asMarkup()
 | 
					                                            .asMarkup()
 | 
				
			||||||
                                            .widthProportion(4))
 | 
					                                            .widthProportion(4))
 | 
				
			||||||
                            .withDefaultActionIf(
 | 
					                            .withDefaultActionIf(
 | 
				
			||||||
                                    () -> userGrant.im(),
 | 
					                                    () -> userGrant.im(),
 | 
				
			||||||
                                    () -> actionBuilder
 | 
					                                    () -> actionBuilder
 | 
				
			||||||
                                            .newAction(ActionDefinition.EXAM_TEMPLATE_INDICATOR_MODIFY_FROM_LIST)
 | 
					                                            .newAction(ActionDefinition.INDICATOR_TEMPLATE_MODIFY_FROM_LIST)
 | 
				
			||||||
                                            .withParentEntityKey(entityKey)
 | 
					                                            .withParentEntityKey(entityKey)
 | 
				
			||||||
                                            .create())
 | 
					                                            .create())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            .withSelectionListener(this.pageService.getSelectionPublisher(
 | 
					                            .withSelectionListener(this.pageService.getSelectionPublisher(
 | 
				
			||||||
                                    pageContext,
 | 
					                                    pageContext,
 | 
				
			||||||
                                    ActionDefinition.EXAM_TEMPLATE_INDICATOR_MODIFY_FROM_LIST,
 | 
					                                    ActionDefinition.INDICATOR_TEMPLATE_MODIFY_FROM_LIST,
 | 
				
			||||||
                                    ActionDefinition.EXAM_TEMPLATE_INDICATOR_DELETE_FROM_LIST))
 | 
					                                    ActionDefinition.INDICATOR_TEMPLATE_DELETE_FROM_LIST))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            .compose(pageContext.copyOf(content));
 | 
					                            .compose(pageContext.copyOf(content));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            actionBuilder
 | 
					            actionBuilder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    .newAction(ActionDefinition.EXAM_TEMPLATE_INDICATOR_MODIFY_FROM_LIST)
 | 
					                    .newAction(ActionDefinition.INDICATOR_TEMPLATE_MODIFY_FROM_LIST)
 | 
				
			||||||
                    .withParentEntityKey(entityKey)
 | 
					                    .withParentEntityKey(entityKey)
 | 
				
			||||||
                    .withSelect(
 | 
					                    .withSelect(
 | 
				
			||||||
                            indicatorTable::getSelection,
 | 
					                            indicatorTable::getSelection,
 | 
				
			||||||
| 
						 | 
					@ -257,7 +257,7 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
                            INDICATOR_EMPTY_SELECTION_TEXT_KEY)
 | 
					                            INDICATOR_EMPTY_SELECTION_TEXT_KEY)
 | 
				
			||||||
                    .publishIf(() -> userGrant.im() && indicatorTable.hasAnyContent(), false)
 | 
					                    .publishIf(() -> userGrant.im() && indicatorTable.hasAnyContent(), false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    .newAction(ActionDefinition.EXAM_TEMPLATE_INDICATOR_DELETE_FROM_LIST)
 | 
					                    .newAction(ActionDefinition.INDICATOR_TEMPLATE_DELETE_FROM_LIST)
 | 
				
			||||||
                    .withEntityKey(entityKey)
 | 
					                    .withEntityKey(entityKey)
 | 
				
			||||||
                    .withSelect(
 | 
					                    .withSelect(
 | 
				
			||||||
                            indicatorTable::getSelection,
 | 
					                            indicatorTable::getSelection,
 | 
				
			||||||
| 
						 | 
					@ -265,7 +265,7 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
                            INDICATOR_EMPTY_SELECTION_TEXT_KEY)
 | 
					                            INDICATOR_EMPTY_SELECTION_TEXT_KEY)
 | 
				
			||||||
                    .publishIf(() -> userGrant.im() && indicatorTable.hasAnyContent(), false)
 | 
					                    .publishIf(() -> userGrant.im() && indicatorTable.hasAnyContent(), false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    .newAction(ActionDefinition.EXAM_TEMPLATE_INDICATOR_NEW)
 | 
					                    .newAction(ActionDefinition.INDICATOR_TEMPLATE_NEW)
 | 
				
			||||||
                    .withParentEntityKey(entityKey)
 | 
					                    .withParentEntityKey(entityKey)
 | 
				
			||||||
                    .publishIf(() -> userGrant.im());
 | 
					                    .publishIf(() -> userGrant.im());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -275,14 +275,14 @@ public class ExamTemplateForm implements TemplateComposer {
 | 
				
			||||||
        final EntityKey entityKey = action.getEntityKey();
 | 
					        final EntityKey entityKey = action.getEntityKey();
 | 
				
			||||||
        final EntityKey indicatorKey = action.getSingleSelection();
 | 
					        final EntityKey indicatorKey = action.getSingleSelection();
 | 
				
			||||||
        this.resourceService.getRestService()
 | 
					        this.resourceService.getRestService()
 | 
				
			||||||
                .getBuilder(DeleteExamTemplateIndicator.class)
 | 
					                .getBuilder(DeleteIndicatorTemplate.class)
 | 
				
			||||||
                .withURIVariable(API.PARAM_PARENT_MODEL_ID, entityKey.modelId)
 | 
					                .withURIVariable(API.PARAM_PARENT_MODEL_ID, entityKey.modelId)
 | 
				
			||||||
                .withURIVariable(API.PARAM_MODEL_ID, indicatorKey.modelId)
 | 
					                .withURIVariable(API.PARAM_MODEL_ID, indicatorKey.modelId)
 | 
				
			||||||
                .call();
 | 
					                .call();
 | 
				
			||||||
        return action;
 | 
					        return action;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private String indicatorTypeName(final Indicator indicator) {
 | 
					    private String indicatorTypeName(final IndicatorTemplate indicator) {
 | 
				
			||||||
        if (indicator.type == null) {
 | 
					        if (indicator.type == null) {
 | 
				
			||||||
            return Constants.EMPTY_NOTE;
 | 
					            return Constants.EMPTY_NOTE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,29 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 | 
				
			||||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package ch.ethz.seb.sebserver.gui.content.exam;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.springframework.context.annotation.Lazy;
 | 
					 | 
				
			||||||
import org.springframework.stereotype.Component;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Lazy
 | 
					 | 
				
			||||||
@Component
 | 
					 | 
				
			||||||
@GuiProfile
 | 
					 | 
				
			||||||
public class ExamTemplateIndicatorForm implements TemplateComposer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void compose(final PageContext pageContext) {
 | 
					 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,7 @@ public class IndicatorForm implements TemplateComposer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // get data or create new. Handle error if happen
 | 
					        // get data or create new. Handle error if happen
 | 
				
			||||||
        final Indicator indicator = (isNew)
 | 
					        final Indicator indicator = (isNew)
 | 
				
			||||||
                ? Indicator.createNew(exam)
 | 
					                ? Indicator.createNew(exam.getModelId())
 | 
				
			||||||
                : restService
 | 
					                : restService
 | 
				
			||||||
                        .getBuilder(GetIndicator.class)
 | 
					                        .getBuilder(GetIndicator.class)
 | 
				
			||||||
                        .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
 | 
					                        .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
 | 
				
			||||||
| 
						 | 
					@ -176,7 +176,7 @@ public class IndicatorForm implements TemplateComposer {
 | 
				
			||||||
                .addField(FormBuilder.thresholdList(
 | 
					                .addField(FormBuilder.thresholdList(
 | 
				
			||||||
                        Domain.THRESHOLD.REFERENCE_NAME,
 | 
					                        Domain.THRESHOLD.REFERENCE_NAME,
 | 
				
			||||||
                        FORM_THRESHOLDS_TEXT_KEY,
 | 
					                        FORM_THRESHOLDS_TEXT_KEY,
 | 
				
			||||||
                        indicator))
 | 
					                        indicator.thresholds))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .buildFor((isNew)
 | 
					                .buildFor((isNew)
 | 
				
			||||||
                        ? restService.getRestCall(NewIndicator.class)
 | 
					                        ? restService.getRestCall(NewIndicator.class)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,221 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 | 
					 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package ch.ethz.seb.sebserver.gui.content.exam;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
 | 
					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.api.EntityType;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.Domain;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
 | 
					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.Form;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.form.FormBuilder;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.form.FormHandle;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.ResourceService;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.i18n.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.PageService;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicatorTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewIndicatorTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveIndicatorTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Lazy
 | 
				
			||||||
 | 
					@Component
 | 
				
			||||||
 | 
					@GuiProfile
 | 
				
			||||||
 | 
					public class IndicatorTemplateForm implements TemplateComposer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final LocTextKey NEW_INDICATOR_TILE_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.title.new");
 | 
				
			||||||
 | 
					    private static final LocTextKey INDICATOR_TILE_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.title");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_THRESHOLDS_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.thresholds");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_COLOR_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.color");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_TYPE_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.type");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_NAME_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.name");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_TAGS_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.tags");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_EXAM_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.exam");
 | 
				
			||||||
 | 
					    private static final LocTextKey FORM_DESC_TEXT_KEY =
 | 
				
			||||||
 | 
					            new LocTextKey("sebserver.exam.indicator.form.description");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final String INDICATOR_TYPE_DESC_PREFIX =
 | 
				
			||||||
 | 
					            "sebserver.exam.indicator.type.description.";
 | 
				
			||||||
 | 
					    private static final String TYPE_DESCRIPTION_FIELD_NAME =
 | 
				
			||||||
 | 
					            "typeDescription";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final PageService pageService;
 | 
				
			||||||
 | 
					    private final ResourceService resourceService;
 | 
				
			||||||
 | 
					    private final I18nSupport i18nSupport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected IndicatorTemplateForm(final PageService pageService) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.pageService = pageService;
 | 
				
			||||||
 | 
					        this.resourceService = pageService.getResourceService();
 | 
				
			||||||
 | 
					        this.i18nSupport = pageService.getI18nSupport();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void compose(final PageContext pageContext) {
 | 
				
			||||||
 | 
					        final RestService restService = this.resourceService.getRestService();
 | 
				
			||||||
 | 
					        final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
 | 
				
			||||||
 | 
					        final EntityKey entityKey = pageContext.getEntityKey();
 | 
				
			||||||
 | 
					        final EntityKey parentEntityKey = pageContext.getParentEntityKey();
 | 
				
			||||||
 | 
					        final boolean isNew = entityKey == null;
 | 
				
			||||||
 | 
					        final boolean isReadonly = pageContext.isReadonly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final ExamTemplate examTemplate = restService
 | 
				
			||||||
 | 
					                .getBuilder(GetExamTemplate.class)
 | 
				
			||||||
 | 
					                .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId)
 | 
				
			||||||
 | 
					                .call()
 | 
				
			||||||
 | 
					                .onError(error -> pageContext.notifyLoadError(EntityType.EXAM, error))
 | 
				
			||||||
 | 
					                .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // get data or create new. Handle error if happen
 | 
				
			||||||
 | 
					        final IndicatorTemplate indicatorTemplate = (isNew)
 | 
				
			||||||
 | 
					                ? new IndicatorTemplate(null, Long.parseLong(parentEntityKey.modelId),
 | 
				
			||||||
 | 
					                        null, null, null, null, null, null)
 | 
				
			||||||
 | 
					                : restService
 | 
				
			||||||
 | 
					                        .getBuilder(GetIndicatorTemplate.class)
 | 
				
			||||||
 | 
					                        .withURIVariable(API.PARAM_PARENT_MODEL_ID, parentEntityKey.modelId)
 | 
				
			||||||
 | 
					                        .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
 | 
				
			||||||
 | 
					                        .call()
 | 
				
			||||||
 | 
					                        .onError(error -> pageContext.notifyLoadError(EntityType.INDICATOR, error))
 | 
				
			||||||
 | 
					                        .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final boolean typeSet = indicatorTemplate.type != null;
 | 
				
			||||||
 | 
					        final String typeDescription = (typeSet)
 | 
				
			||||||
 | 
					                ? Utils.formatLineBreaks(
 | 
				
			||||||
 | 
					                        this.i18nSupport.getText(INDICATOR_TYPE_DESC_PREFIX + indicatorTemplate.type.name))
 | 
				
			||||||
 | 
					                : Constants.EMPTY_NOTE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // new PageContext with actual EntityKey
 | 
				
			||||||
 | 
					        final PageContext formContext = pageContext.withEntityKey(indicatorTemplate.getEntityKey());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // the default page layout
 | 
				
			||||||
 | 
					        final LocTextKey titleKey = (isNew)
 | 
				
			||||||
 | 
					                ? NEW_INDICATOR_TILE_TEXT_KEY
 | 
				
			||||||
 | 
					                : INDICATOR_TILE_TEXT_KEY;
 | 
				
			||||||
 | 
					        final Composite content = widgetFactory.defaultPageLayout(
 | 
				
			||||||
 | 
					                formContext.getParent(),
 | 
				
			||||||
 | 
					                titleKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final FormHandle<IndicatorTemplate> formHandle = this.pageService.formBuilder(
 | 
				
			||||||
 | 
					                formContext.copyOf(content))
 | 
				
			||||||
 | 
					                .readonly(isReadonly)
 | 
				
			||||||
 | 
					                .putStaticValueIf(() -> !isNew,
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_ID,
 | 
				
			||||||
 | 
					                        indicatorTemplate.getModelId())
 | 
				
			||||||
 | 
					                .putStaticValue(
 | 
				
			||||||
 | 
					                        Domain.EXAM.ATTR_INSTITUTION_ID,
 | 
				
			||||||
 | 
					                        String.valueOf(examTemplate.getInstitutionId()))
 | 
				
			||||||
 | 
					                .putStaticValue(
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_EXAM_ID,
 | 
				
			||||||
 | 
					                        parentEntityKey.getModelId())
 | 
				
			||||||
 | 
					                .addField(FormBuilder.text(
 | 
				
			||||||
 | 
					                        Domain.EXAM_TEMPLATE.ATTR_NAME,
 | 
				
			||||||
 | 
					                        FORM_EXAM_TEXT_KEY,
 | 
				
			||||||
 | 
					                        examTemplate.name)
 | 
				
			||||||
 | 
					                        .readonly(true))
 | 
				
			||||||
 | 
					                .addField(FormBuilder.text(
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_NAME,
 | 
				
			||||||
 | 
					                        FORM_NAME_TEXT_KEY,
 | 
				
			||||||
 | 
					                        indicatorTemplate.name)
 | 
				
			||||||
 | 
					                        .mandatory(!isReadonly))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .addField(FormBuilder.singleSelection(
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_TYPE,
 | 
				
			||||||
 | 
					                        FORM_TYPE_TEXT_KEY,
 | 
				
			||||||
 | 
					                        (indicatorTemplate.type != null) ? indicatorTemplate.type.name() : null,
 | 
				
			||||||
 | 
					                        this.resourceService::indicatorTypeResources)
 | 
				
			||||||
 | 
					                        .withSelectionListener(this::updateForm)
 | 
				
			||||||
 | 
					                        .mandatory(!isReadonly))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .addField(FormBuilder.text(
 | 
				
			||||||
 | 
					                        TYPE_DESCRIPTION_FIELD_NAME,
 | 
				
			||||||
 | 
					                        FORM_DESC_TEXT_KEY,
 | 
				
			||||||
 | 
					                        typeDescription)
 | 
				
			||||||
 | 
					                        .asArea()
 | 
				
			||||||
 | 
					                        //.asHTML(true)
 | 
				
			||||||
 | 
					                        .readonly(true)
 | 
				
			||||||
 | 
					                        .withInputSpan(6))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .addField(FormBuilder.colorSelection(
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_COLOR,
 | 
				
			||||||
 | 
					                        FORM_COLOR_TEXT_KEY,
 | 
				
			||||||
 | 
					                        indicatorTemplate.defaultColor)
 | 
				
			||||||
 | 
					                        .withEmptyCellSeparation(false))
 | 
				
			||||||
 | 
					                .addField(FormBuilder.text(
 | 
				
			||||||
 | 
					                        Domain.INDICATOR.ATTR_TAGS,
 | 
				
			||||||
 | 
					                        FORM_TAGS_TEXT_KEY,
 | 
				
			||||||
 | 
					                        indicatorTemplate.tags)
 | 
				
			||||||
 | 
					                        .visibleIf(indicatorTemplate.type != null && indicatorTemplate.type.tags
 | 
				
			||||||
 | 
					                                && !indicatorTemplate.type.tagsReadonly))
 | 
				
			||||||
 | 
					                .addField(FormBuilder.thresholdList(
 | 
				
			||||||
 | 
					                        Domain.THRESHOLD.REFERENCE_NAME,
 | 
				
			||||||
 | 
					                        FORM_THRESHOLDS_TEXT_KEY,
 | 
				
			||||||
 | 
					                        indicatorTemplate.thresholds))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .buildFor((isNew)
 | 
				
			||||||
 | 
					                        ? restService.getRestCall(NewIndicatorTemplate.class)
 | 
				
			||||||
 | 
					                        : restService.getRestCall(SaveIndicatorTemplate.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // propagate content actions to action-pane
 | 
				
			||||||
 | 
					        this.pageService.pageActionBuilder(formContext.clearEntityKeys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .newAction(ActionDefinition.INDICATOR_TEMPLATE_SAVE)
 | 
				
			||||||
 | 
					                .withEntityKey(parentEntityKey)
 | 
				
			||||||
 | 
					                .withExec(formHandle::processFormSave)
 | 
				
			||||||
 | 
					                .ignoreMoveAwayFromEdit()
 | 
				
			||||||
 | 
					                .publishIf(() -> !isReadonly)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                .newAction(ActionDefinition.INDICATOR_TEMPLATE_CANCEL_MODIFY)
 | 
				
			||||||
 | 
					                .withEntityKey(parentEntityKey)
 | 
				
			||||||
 | 
					                .withExec(this.pageService.backToCurrentFunction())
 | 
				
			||||||
 | 
					                .publishIf(() -> !isReadonly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void updateForm(final Form form) {
 | 
				
			||||||
 | 
					        final String typeValue = form.getFieldValue(Domain.INDICATOR.ATTR_TYPE);
 | 
				
			||||||
 | 
					        if (StringUtils.isNotBlank(typeValue)) {
 | 
				
			||||||
 | 
					            final String text = this.i18nSupport.getText(INDICATOR_TYPE_DESC_PREFIX + typeValue);
 | 
				
			||||||
 | 
					            form.setFieldValue(
 | 
				
			||||||
 | 
					                    TYPE_DESCRIPTION_FIELD_NAME,
 | 
				
			||||||
 | 
					                    Utils.formatLineBreaks(text));
 | 
				
			||||||
 | 
					            final IndicatorType type = IndicatorType.valueOf(typeValue);
 | 
				
			||||||
 | 
					            form.setFieldVisible(type.tags && !type.tagsReadonly, Domain.INDICATOR.ATTR_TAGS);
 | 
				
			||||||
 | 
					            if (!type.tags || type.tagsReadonly) {
 | 
				
			||||||
 | 
					                form.setFieldValue(Domain.INDICATOR.ATTR_TAGS, StringUtils.EMPTY);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            form.setFieldValue(TYPE_DESCRIPTION_FIELD_NAME, Constants.EMPTY_NOTE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ import org.slf4j.Logger;
 | 
				
			||||||
import org.slf4j.LoggerFactory;
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
 | 
					import ch.ethz.seb.sebserver.gbl.model.Entity;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Cryptor;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Tuple;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
 | 
					import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
 | 
				
			||||||
| 
						 | 
					@ -279,12 +279,12 @@ public class FormBuilder {
 | 
				
			||||||
    public static ThresholdListBuilder thresholdList(
 | 
					    public static ThresholdListBuilder thresholdList(
 | 
				
			||||||
            final String name,
 | 
					            final String name,
 | 
				
			||||||
            final LocTextKey label,
 | 
					            final LocTextKey label,
 | 
				
			||||||
            final Indicator indicator) {
 | 
					            final List<Threshold> thresholds) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new ThresholdListBuilder(
 | 
					        return new ThresholdListBuilder(
 | 
				
			||||||
                name,
 | 
					                name,
 | 
				
			||||||
                label,
 | 
					                label,
 | 
				
			||||||
                indicator.thresholds);
 | 
					                thresholds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static ImageUploadFieldBuilder imageUpload(final String name, final LocTextKey label, final String value) {
 | 
					    public static ImageUploadFieldBuilder imageUpload(final String name, final LocTextKey label, final String value) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,9 +24,9 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
@GuiProfile
 | 
					@GuiProfile
 | 
				
			||||||
public class DeleteExamTemplateIndicator extends RestCall<EntityKey> {
 | 
					public class DeleteIndicatorTemplate extends RestCall<EntityKey> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public DeleteExamTemplateIndicator() {
 | 
					    public DeleteIndicatorTemplate() {
 | 
				
			||||||
        super(new TypeKey<>(
 | 
					        super(new TypeKey<>(
 | 
				
			||||||
                CallType.DELETE,
 | 
					                CallType.DELETE,
 | 
				
			||||||
                EntityType.INDICATOR,
 | 
					                EntityType.INDICATOR,
 | 
				
			||||||
| 
						 | 
					@ -17,20 +17,20 @@ import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.api.API;
 | 
					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.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
@GuiProfile
 | 
					@GuiProfile
 | 
				
			||||||
public class GetExamTemplateIndicator extends RestCall<Indicator> {
 | 
					public class GetIndicatorTemplate extends RestCall<IndicatorTemplate> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public GetExamTemplateIndicator() {
 | 
					    public GetIndicatorTemplate() {
 | 
				
			||||||
        super(new TypeKey<>(
 | 
					        super(new TypeKey<>(
 | 
				
			||||||
                CallType.GET_SINGLE,
 | 
					                CallType.GET_SINGLE,
 | 
				
			||||||
                EntityType.INDICATOR,
 | 
					                EntityType.INDICATOR,
 | 
				
			||||||
                new TypeReference<Indicator>() {
 | 
					                new TypeReference<IndicatorTemplate>() {
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
                HttpMethod.GET,
 | 
					                HttpMethod.GET,
 | 
				
			||||||
                MediaType.APPLICATION_FORM_URLENCODED,
 | 
					                MediaType.APPLICATION_FORM_URLENCODED,
 | 
				
			||||||
| 
						 | 
					@ -18,20 +18,20 @@ import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.api.API;
 | 
					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.Page;
 | 
					import ch.ethz.seb.sebserver.gbl.model.Page;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
@GuiProfile
 | 
					@GuiProfile
 | 
				
			||||||
public class GetExamTemplateIndicatorPage extends RestCall<Page<Indicator>> {
 | 
					public class GetIndicatorTemplatePage extends RestCall<Page<IndicatorTemplate>> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public GetExamTemplateIndicatorPage() {
 | 
					    public GetIndicatorTemplatePage() {
 | 
				
			||||||
        super(new TypeKey<>(
 | 
					        super(new TypeKey<>(
 | 
				
			||||||
                CallType.GET_PAGE,
 | 
					                CallType.GET_PAGE,
 | 
				
			||||||
                EntityType.INDICATOR,
 | 
					                EntityType.INDICATOR,
 | 
				
			||||||
                new TypeReference<Page<Indicator>>() {
 | 
					                new TypeReference<Page<IndicatorTemplate>>() {
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
                HttpMethod.GET,
 | 
					                HttpMethod.GET,
 | 
				
			||||||
                MediaType.APPLICATION_FORM_URLENCODED,
 | 
					                MediaType.APPLICATION_FORM_URLENCODED,
 | 
				
			||||||
| 
						 | 
					@ -17,25 +17,24 @@ import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.api.API;
 | 
					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.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
@GuiProfile
 | 
					@GuiProfile
 | 
				
			||||||
public class NewExamTemplateIndicator extends RestCall<Indicator> {
 | 
					public class NewIndicatorTemplate extends RestCall<IndicatorTemplate> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public NewExamTemplateIndicator() {
 | 
					    public NewIndicatorTemplate() {
 | 
				
			||||||
        super(new TypeKey<>(
 | 
					        super(new TypeKey<>(
 | 
				
			||||||
                CallType.NEW,
 | 
					                CallType.NEW,
 | 
				
			||||||
                EntityType.INDICATOR,
 | 
					                EntityType.INDICATOR,
 | 
				
			||||||
                new TypeReference<Indicator>() {
 | 
					                new TypeReference<IndicatorTemplate>() {
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
                HttpMethod.POST,
 | 
					                HttpMethod.POST,
 | 
				
			||||||
                MediaType.APPLICATION_FORM_URLENCODED,
 | 
					                MediaType.APPLICATION_FORM_URLENCODED,
 | 
				
			||||||
                API.EXAM_TEMPLATE_ENDPOINT
 | 
					                API.EXAM_TEMPLATE_ENDPOINT
 | 
				
			||||||
                        + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
 | 
					 | 
				
			||||||
                        + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT);
 | 
					                        + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,27 +17,25 @@ import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.api.API;
 | 
					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.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
					import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
@GuiProfile
 | 
					@GuiProfile
 | 
				
			||||||
public class SaveExamTemplateIndicator extends RestCall<Indicator> {
 | 
					public class SaveIndicatorTemplate extends RestCall<IndicatorTemplate> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SaveExamTemplateIndicator() {
 | 
					    public SaveIndicatorTemplate() {
 | 
				
			||||||
        super(new TypeKey<>(
 | 
					        super(new TypeKey<>(
 | 
				
			||||||
                CallType.SAVE,
 | 
					                CallType.SAVE,
 | 
				
			||||||
                EntityType.INDICATOR,
 | 
					                EntityType.INDICATOR,
 | 
				
			||||||
                new TypeReference<Indicator>() {
 | 
					                new TypeReference<IndicatorTemplate>() {
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
                HttpMethod.PUT,
 | 
					                HttpMethod.PUT,
 | 
				
			||||||
                MediaType.APPLICATION_JSON,
 | 
					                MediaType.APPLICATION_JSON,
 | 
				
			||||||
                API.EXAM_TEMPLATE_ENDPOINT
 | 
					                API.EXAM_TEMPLATE_ENDPOINT
 | 
				
			||||||
                        + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
 | 
					                        + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT);
 | 
				
			||||||
                        + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT
 | 
					 | 
				
			||||||
                        + API.MODEL_ID_VAR_PATH_SEGMENT);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 | 
					import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
 | 
					import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,7 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            checkUniqueName(data);
 | 
					            checkUniqueName(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final Collection<Indicator> indicatorTemplates = data.getIndicatorTemplates();
 | 
					            final Collection<IndicatorTemplate> indicatorTemplates = data.getIndicatorTemplates();
 | 
				
			||||||
            final String indicatorsJSON = (indicatorTemplates != null && !indicatorTemplates.isEmpty())
 | 
					            final String indicatorsJSON = (indicatorTemplates != null && !indicatorTemplates.isEmpty())
 | 
				
			||||||
                    ? this.jsonMapper.writeValueAsString(indicatorTemplates)
 | 
					                    ? this.jsonMapper.writeValueAsString(indicatorTemplates)
 | 
				
			||||||
                    : null;
 | 
					                    : null;
 | 
				
			||||||
| 
						 | 
					@ -158,7 +158,7 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            checkUniqueName(data);
 | 
					            checkUniqueName(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final Collection<Indicator> indicatorTemplates = data.getIndicatorTemplates();
 | 
					            final Collection<IndicatorTemplate> indicatorTemplates = data.getIndicatorTemplates();
 | 
				
			||||||
            final String indicatorsJSON = (indicatorTemplates != null && !indicatorTemplates.isEmpty())
 | 
					            final String indicatorsJSON = (indicatorTemplates != null && !indicatorTemplates.isEmpty())
 | 
				
			||||||
                    ? this.jsonMapper.writeValueAsString(indicatorTemplates)
 | 
					                    ? this.jsonMapper.writeValueAsString(indicatorTemplates)
 | 
				
			||||||
                    : null;
 | 
					                    : null;
 | 
				
			||||||
| 
						 | 
					@ -232,9 +232,10 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
 | 
				
			||||||
        return Result.tryCatch(() -> {
 | 
					        return Result.tryCatch(() -> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final String indicatorTemplatesString = record.getIndicatorTemplates();
 | 
					            final String indicatorTemplatesString = record.getIndicatorTemplates();
 | 
				
			||||||
            final Collection<Indicator> indicators = (StringUtils.isNotBlank(indicatorTemplatesString))
 | 
					            final Collection<IndicatorTemplate> indicators = (StringUtils.isNotBlank(indicatorTemplatesString))
 | 
				
			||||||
                    ? this.jsonMapper.readValue(indicatorTemplatesString, new TypeReference<Collection<Indicator>>() {
 | 
					                    ? this.jsonMapper.readValue(indicatorTemplatesString,
 | 
				
			||||||
                    })
 | 
					                            new TypeReference<Collection<IndicatorTemplate>>() {
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
                    : null;
 | 
					                    : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final Map<String, String> examAttributes = this.additionalAttributesDAO
 | 
					            final Map<String, String> examAttributes = this.additionalAttributesDAO
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,7 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
 | 
					import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
 | 
					import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
 | 
				
			||||||
| 
						 | 
					@ -82,7 +83,7 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
            method = RequestMethod.GET,
 | 
					            method = RequestMethod.GET,
 | 
				
			||||||
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
					            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
				
			||||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
					            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
				
			||||||
    public Page<Indicator> getIndicatorPage(
 | 
					    public Page<IndicatorTemplate> getIndicatorPage(
 | 
				
			||||||
            @PathVariable final String modelId,
 | 
					            @PathVariable final String modelId,
 | 
				
			||||||
            @RequestParam(
 | 
					            @RequestParam(
 | 
				
			||||||
                    name = API.PARAM_INSTITUTION_ID,
 | 
					                    name = API.PARAM_INSTITUTION_ID,
 | 
				
			||||||
| 
						 | 
					@ -119,7 +120,7 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
            method = RequestMethod.GET,
 | 
					            method = RequestMethod.GET,
 | 
				
			||||||
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
					            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
				
			||||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
					            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
				
			||||||
    public Indicator getIndicatorBy(
 | 
					    public IndicatorTemplate getIndicatorBy(
 | 
				
			||||||
            @PathVariable final String parentModelId,
 | 
					            @PathVariable final String parentModelId,
 | 
				
			||||||
            @PathVariable final String modelId,
 | 
					            @PathVariable final String modelId,
 | 
				
			||||||
            @RequestParam(
 | 
					            @RequestParam(
 | 
				
			||||||
| 
						 | 
					@ -144,13 +145,11 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @RequestMapping(
 | 
					    @RequestMapping(
 | 
				
			||||||
            path = API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
 | 
					            path = API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT,
 | 
				
			||||||
                    + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT,
 | 
					 | 
				
			||||||
            method = RequestMethod.POST,
 | 
					            method = RequestMethod.POST,
 | 
				
			||||||
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
					            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
 | 
				
			||||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
					            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
				
			||||||
    public Indicator createIndicator(
 | 
					    public IndicatorTemplate createIndicatorTemplate(
 | 
				
			||||||
            @PathVariable final String parentModelId,
 | 
					 | 
				
			||||||
            @RequestParam final MultiValueMap<String, String> allRequestParams,
 | 
					            @RequestParam final MultiValueMap<String, String> allRequestParams,
 | 
				
			||||||
            @RequestParam(
 | 
					            @RequestParam(
 | 
				
			||||||
                    name = API.PARAM_INSTITUTION_ID,
 | 
					                    name = API.PARAM_INSTITUTION_ID,
 | 
				
			||||||
| 
						 | 
					@ -161,19 +160,21 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
        // check write privilege for requested institution and concrete entityType
 | 
					        // check write privilege for requested institution and concrete entityType
 | 
				
			||||||
        this.checkWritePrivilege(institutionId);
 | 
					        this.checkWritePrivilege(institutionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final ExamTemplate examTemplate = super.entityDAO
 | 
					 | 
				
			||||||
                .byModelId(parentModelId)
 | 
					 | 
				
			||||||
                .getOrThrow();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        final POSTMapper postMap = new POSTMapper(allRequestParams, request.getQueryString())
 | 
					        final POSTMapper postMap = new POSTMapper(allRequestParams, request.getQueryString())
 | 
				
			||||||
                .putIfAbsent(API.PARAM_INSTITUTION_ID, String.valueOf(institutionId));
 | 
					                .putIfAbsent(API.PARAM_INSTITUTION_ID, String.valueOf(institutionId));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final Indicator newIndicator = new Indicator(
 | 
					        final String examTemplateId = postMap.getString(IndicatorTemplate.ATTR_EXAM_TEMPLATE_ID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final ExamTemplate examTemplate = super.entityDAO
 | 
				
			||||||
 | 
					                .byModelId(examTemplateId)
 | 
				
			||||||
 | 
					                .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final IndicatorTemplate newIndicator = new IndicatorTemplate(
 | 
				
			||||||
                (long) examTemplate.getIndicatorTemplates().size(),
 | 
					                (long) examTemplate.getIndicatorTemplates().size(),
 | 
				
			||||||
                Long.parseLong(parentModelId),
 | 
					                Long.parseLong(examTemplateId),
 | 
				
			||||||
                postMap);
 | 
					                postMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final ArrayList<Indicator> indicators = new ArrayList<>(examTemplate.indicatorTemplates);
 | 
					        final ArrayList<IndicatorTemplate> indicators = new ArrayList<>(examTemplate.indicatorTemplates);
 | 
				
			||||||
        indicators.add(newIndicator);
 | 
					        indicators.add(newIndicator);
 | 
				
			||||||
        final ExamTemplate newExamTemplate = new ExamTemplate(
 | 
					        final ExamTemplate newExamTemplate = new ExamTemplate(
 | 
				
			||||||
                examTemplate.id,
 | 
					                examTemplate.id,
 | 
				
			||||||
| 
						 | 
					@ -189,29 +190,26 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @RequestMapping(
 | 
					    @RequestMapping(
 | 
				
			||||||
            path = API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
 | 
					            path = API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT,
 | 
				
			||||||
                    + API.EXAM_TEMPLATE_INDICATOR_PATH_SEGMENT
 | 
					 | 
				
			||||||
                    + API.MODEL_ID_VAR_PATH_SEGMENT,
 | 
					 | 
				
			||||||
            method = RequestMethod.PUT,
 | 
					            method = RequestMethod.PUT,
 | 
				
			||||||
            consumes = MediaType.APPLICATION_JSON_VALUE,
 | 
					            consumes = MediaType.APPLICATION_JSON_VALUE,
 | 
				
			||||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
					            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
				
			||||||
    public Indicator saveIndicatorPut(
 | 
					    public IndicatorTemplate saveIndicatorPut(
 | 
				
			||||||
            @PathVariable final String parentModelId,
 | 
					 | 
				
			||||||
            @PathVariable final String modelId,
 | 
					 | 
				
			||||||
            @RequestParam(
 | 
					            @RequestParam(
 | 
				
			||||||
                    name = API.PARAM_INSTITUTION_ID,
 | 
					                    name = API.PARAM_INSTITUTION_ID,
 | 
				
			||||||
                    required = true,
 | 
					                    required = true,
 | 
				
			||||||
                    defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
 | 
					                    defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
 | 
				
			||||||
            @Valid @RequestBody final Indicator modifyData) {
 | 
					            @Valid @RequestBody final IndicatorTemplate modifyData) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // check modify privilege for requested institution and concrete entityType
 | 
					        // check modify privilege for requested institution and concrete entityType
 | 
				
			||||||
        this.checkModifyPrivilege(institutionId);
 | 
					        this.checkModifyPrivilege(institutionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final ExamTemplate examTemplate = super.entityDAO
 | 
					        final ExamTemplate examTemplate = super.entityDAO
 | 
				
			||||||
                .byModelId(parentModelId)
 | 
					                .byPK(modifyData.examTemplateId)
 | 
				
			||||||
                .getOrThrow();
 | 
					                .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final List<Indicator> newIndicators = examTemplate.indicatorTemplates
 | 
					        final String modelId = modifyData.getModelId();
 | 
				
			||||||
 | 
					        final List<IndicatorTemplate> newIndicators = examTemplate.indicatorTemplates
 | 
				
			||||||
                .stream()
 | 
					                .stream()
 | 
				
			||||||
                .map(i -> {
 | 
					                .map(i -> {
 | 
				
			||||||
                    if (modelId.equals(i.getModelId())) {
 | 
					                    if (modelId.equals(i.getModelId())) {
 | 
				
			||||||
| 
						 | 
					@ -241,7 +239,7 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
                    + API.MODEL_ID_VAR_PATH_SEGMENT,
 | 
					                    + API.MODEL_ID_VAR_PATH_SEGMENT,
 | 
				
			||||||
            method = RequestMethod.DELETE,
 | 
					            method = RequestMethod.DELETE,
 | 
				
			||||||
            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
					            produces = MediaType.APPLICATION_JSON_VALUE)
 | 
				
			||||||
    public EntityKey deleteIndicator(
 | 
					    public EntityKey deleteIndicatorTemplate(
 | 
				
			||||||
            @PathVariable final String parentModelId,
 | 
					            @PathVariable final String parentModelId,
 | 
				
			||||||
            @PathVariable final String modelId,
 | 
					            @PathVariable final String modelId,
 | 
				
			||||||
            @RequestParam(
 | 
					            @RequestParam(
 | 
				
			||||||
| 
						 | 
					@ -256,7 +254,7 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
                .byModelId(parentModelId)
 | 
					                .byModelId(parentModelId)
 | 
				
			||||||
                .getOrThrow();
 | 
					                .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final List<Indicator> newIndicators = examTemplate.indicatorTemplates
 | 
					        final List<IndicatorTemplate> newIndicators = examTemplate.indicatorTemplates
 | 
				
			||||||
                .stream()
 | 
					                .stream()
 | 
				
			||||||
                .filter(i -> !modelId.equals(i.getModelId()))
 | 
					                .filter(i -> !modelId.equals(i.getModelId()))
 | 
				
			||||||
                .collect(Collectors.toList());
 | 
					                .collect(Collectors.toList());
 | 
				
			||||||
| 
						 | 
					@ -285,11 +283,11 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
 | 
				
			||||||
        return ExamTemplateRecordDynamicSqlSupport.examTemplateRecord;
 | 
					        return ExamTemplateRecordDynamicSqlSupport.examTemplateRecord;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static Function<Collection<Indicator>, List<Indicator>> pageSort(final String sort) {
 | 
					    static Function<Collection<IndicatorTemplate>, List<IndicatorTemplate>> pageSort(final String sort) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final String sortBy = PageSortOrder.decode(sort);
 | 
					        final String sortBy = PageSortOrder.decode(sort);
 | 
				
			||||||
        return indicators -> {
 | 
					        return indicators -> {
 | 
				
			||||||
            final List<Indicator> list = indicators.stream().collect(Collectors.toList());
 | 
					            final List<IndicatorTemplate> list = indicators.stream().collect(Collectors.toList());
 | 
				
			||||||
            if (StringUtils.isBlank(sort)) {
 | 
					            if (StringUtils.isBlank(sort)) {
 | 
				
			||||||
                return list;
 | 
					                return list;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ DROP TABLE IF EXISTS `exam_template` ;
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS `exam_template` (
 | 
					CREATE TABLE IF NOT EXISTS `exam_template` (
 | 
				
			||||||
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 | 
					  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 | 
				
			||||||
  `institution_id` BIGINT UNSIGNED NOT NULL,
 | 
					  `institution_id` BIGINT UNSIGNED NOT NULL,
 | 
				
			||||||
  `configuration_template_id` BIGINT UNSIGNED NOT NULL,
 | 
					  `configuration_template_id` BIGINT UNSIGNED NULL,
 | 
				
			||||||
  `name` VARCHAR(255) NOT NULL,
 | 
					  `name` VARCHAR(255) NOT NULL,
 | 
				
			||||||
  `description` VARCHAR(4000) NULL,
 | 
					  `description` VARCHAR(4000) NULL,
 | 
				
			||||||
  `exam_type` VARCHAR(45) NULL,
 | 
					  `exam_type` VARCHAR(45) NULL,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1602,8 +1602,8 @@ sebserver.examtemplate.list.title.subtitle=
 | 
				
			||||||
sebserver.examtemplate.list.empty=There is currently no exam template available. Please create a new one
 | 
					sebserver.examtemplate.list.empty=There is currently no exam template available. Please create a new one
 | 
				
			||||||
sebserver.examtemplate.list.actions=
 | 
					sebserver.examtemplate.list.actions=
 | 
				
			||||||
sebserver.examtemplate.list.action.no.modify.privilege=No Access: An Exam Template from other institution cannot be modified.
 | 
					sebserver.examtemplate.list.action.no.modify.privilege=No Access: An Exam Template from other institution cannot be modified.
 | 
				
			||||||
sebserver.examtemplate.action.list.view=View
 | 
					sebserver.examtemplate.action.list.view=View Exam Template
 | 
				
			||||||
sebserver.examtemplate.action.list.modify=Edit
 | 
					sebserver.examtemplate.action.list.modify=Edit Exam Template
 | 
				
			||||||
sebserver.examtemplate.action.list.new=Add Exam Template
 | 
					sebserver.examtemplate.action.list.new=Add Exam Template
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sebserver.examtemplate.list.column.institution=Institution
 | 
					sebserver.examtemplate.list.column.institution=Institution
 | 
				
			||||||
| 
						 | 
					@ -1629,7 +1629,10 @@ sebserver.examtemplate.form.examConfigTemplate.tooltip=The linked ecam configura
 | 
				
			||||||
sebserver.examtemplate.form.supporter=Exam Supporter
 | 
					sebserver.examtemplate.form.supporter=Exam Supporter
 | 
				
			||||||
sebserver.examtemplate.form.supporter.tooltip=List of all exam supporter user that will automatically be applied to an exam imported with this template.
 | 
					sebserver.examtemplate.form.supporter.tooltip=List of all exam supporter user that will automatically be applied to an exam imported with this template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sebserver.examtemplate.form.action.save=Save
 | 
				
			||||||
 | 
					sebserver.examtemplate.form.action.edit=Edit Template Settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sebserver.examtemplate.indicator.list.actions=
 | 
				
			||||||
sebserver.examtemplate.indicator.list.title=Indicators
 | 
					sebserver.examtemplate.indicator.list.title=Indicators
 | 
				
			||||||
sebserver.examtemplate.indicator.list.title.tooltip=A list of indicators that will automatically be created when importing a exam with this template
 | 
					sebserver.examtemplate.indicator.list.title.tooltip=A list of indicators that will automatically be created when importing a exam with this template
 | 
				
			||||||
sebserver.examtemplate.indicator.list.column.type=Type
 | 
					sebserver.examtemplate.indicator.list.column.type=Type
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -611,7 +611,7 @@ DROP TABLE IF EXISTS `exam_template` ;
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS `exam_template` (
 | 
					CREATE TABLE IF NOT EXISTS `exam_template` (
 | 
				
			||||||
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 | 
					  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 | 
				
			||||||
  `institution_id` BIGINT UNSIGNED NOT NULL,
 | 
					  `institution_id` BIGINT UNSIGNED NOT NULL,
 | 
				
			||||||
  `configuration_template_id` BIGINT UNSIGNED NOT NULL,
 | 
					  `configuration_template_id` BIGINT UNSIGNED NULL,
 | 
				
			||||||
  `name` VARCHAR(255) NOT NULL,
 | 
					  `name` VARCHAR(255) NOT NULL,
 | 
				
			||||||
  `description` VARCHAR(4000) NULL,
 | 
					  `description` VARCHAR(4000) NULL,
 | 
				
			||||||
  `exam_type` VARCHAR(45) NULL,
 | 
					  `exam_type` VARCHAR(45) NULL,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue