SEBSERV-44 SEBSERV-45 finished config tool and some bug fixes
This commit is contained in:
parent
7e0031cf8b
commit
de0a397567
45 changed files with 1253 additions and 522 deletions
|
@ -48,7 +48,7 @@ public enum AttributeType {
|
||||||
|
|
||||||
INLINE_TABLE(COMPOSITE_LIST),
|
INLINE_TABLE(COMPOSITE_LIST),
|
||||||
|
|
||||||
;
|
COMPOSITE_TABLE(COMPOSITE);
|
||||||
|
|
||||||
public final AttributeValueType attributeValueType;
|
public final AttributeValueType attributeValueType;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ public enum AttributeValueType {
|
||||||
BASE64_BINARY,
|
BASE64_BINARY,
|
||||||
/** A list of single values of the same type */
|
/** A list of single values of the same type */
|
||||||
LIST,
|
LIST,
|
||||||
/** A composite of different typed values like a Map or Dictionary */
|
/** A composite of different typed values like a map or dictionary */
|
||||||
COMPOSITE,
|
COMPOSITE,
|
||||||
/** A list of composites of the same type like a Table */
|
/** A list of composites (list of dictionary) of the same type like a Table */
|
||||||
COMPOSITE_LIST
|
COMPOSITE_LIST
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,23 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
|
@ -24,8 +34,25 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public final class ConfigurationAttribute implements Entity {
|
public final class ConfigurationAttribute implements Entity {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ConfigurationAttribute.class);
|
||||||
|
|
||||||
|
/** This configuration attribute dependency key can be used to set a specific localized text key prefix for
|
||||||
|
* resources. This is usually convenient if two different attributes use the same resources and to avoid
|
||||||
|
* to multiply the resources for each attribute with the attribute name prefix, we can set a specific
|
||||||
|
* resourceLocTextKey prefix to use. */
|
||||||
public static final String DEPENDENCY_RESOURCE_LOC_TEXT_KEY = "resourceLocTextKey";
|
public static final String DEPENDENCY_RESOURCE_LOC_TEXT_KEY = "resourceLocTextKey";
|
||||||
|
|
||||||
|
/** This configuration attribute dependency key indicates the group identifier for grouped COMOSITE_TYPE types */
|
||||||
|
public static final String DEPENDENCY_GROUP_ID = "groupId";
|
||||||
|
|
||||||
|
/** This configuration attribute dependency key indicates if a default value should be created even if the
|
||||||
|
* attribute is a child attribute and normally no default value is generated on creation. */
|
||||||
|
public static final String DEPENDENCY_CREATE_DEFAULT_VALUE = "createDefaultValue";
|
||||||
|
|
||||||
|
/** his configuration attribute dependency key indicates if the input field should be shown in the directly
|
||||||
|
* in the View even if the attribute is a child attribute and is usually shown in a table or composite. */
|
||||||
|
public static final String DEPENDENCY_SHOW_IN_VIEW = "showInView";
|
||||||
|
|
||||||
public static final String FILTER_ATTR_PARENT_ID = "parentId";
|
public static final String FILTER_ATTR_PARENT_ID = "parentId";
|
||||||
public static final String FILTER_ATTR_TYPE = "type";
|
public static final String FILTER_ATTR_TYPE = "type";
|
||||||
|
|
||||||
|
@ -156,4 +183,55 @@ public final class ConfigurationAttribute implements Entity {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasDependency(
|
||||||
|
final String dependencyName,
|
||||||
|
final ConfigurationAttribute attribute) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(attribute.dependencies)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return attribute.dependencies.contains(dependencyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDependencyValue(
|
||||||
|
final String dependencyName,
|
||||||
|
final ConfigurationAttribute attribute) {
|
||||||
|
|
||||||
|
return getDependencyValue(dependencyName, attribute.dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDependencyValue(
|
||||||
|
final String dependencyName,
|
||||||
|
final String dependnciesString) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(dependnciesString)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAttributeDependencyMap(dependnciesString).get(dependencyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> getAttributeDependencyMap(final ConfigurationAttribute attribute) {
|
||||||
|
if (StringUtils.isBlank(attribute.dependencies)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAttributeDependencyMap(attribute.dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> getAttributeDependencyMap(final String dependnciesString) {
|
||||||
|
try {
|
||||||
|
return Arrays.asList(StringUtils.split(dependnciesString, Constants.LIST_SEPARATOR))
|
||||||
|
.stream()
|
||||||
|
.map(s -> StringUtils.split(s, Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR))
|
||||||
|
.collect(Collectors.toMap(pair -> pair[0], pair -> pair[1]));
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to parse dependency map of: {}",
|
||||||
|
dependnciesString,
|
||||||
|
e);
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ public final class ConfigurationNode implements GrantEntity {
|
||||||
@JsonProperty(CONFIGURATION_NODE.ATTR_NAME)
|
@JsonProperty(CONFIGURATION_NODE.ATTR_NAME)
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
|
@Size(max = 4000, message = "configurationNode:description:size:{min}:{max}:${validatedValue}")
|
||||||
@JsonProperty(CONFIGURATION_NODE.ATTR_DESCRIPTION)
|
@JsonProperty(CONFIGURATION_NODE.ATTR_DESCRIPTION)
|
||||||
public final String description;
|
public final String description;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
|
||||||
|
|
||||||
public final class Utils {
|
public final class Utils {
|
||||||
|
|
||||||
|
@ -294,22 +293,4 @@ public final class Utils {
|
||||||
return toCharArray(CharBuffer.wrap(chars));
|
return toCharArray(CharBuffer.wrap(chars));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, String> getAttributeDependencyMap(final ConfigurationAttribute attribute) {
|
|
||||||
if (StringUtils.isBlank(attribute.dependencies)) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return Arrays.asList(StringUtils.split(attribute.dependencies, Constants.LIST_SEPARATOR))
|
|
||||||
.stream()
|
|
||||||
.map(s -> StringUtils.split(s, Constants.EMBEDDED_LIST_SEPARATOR))
|
|
||||||
.collect(Collectors.toMap(pair -> pair[0], pair -> pair[1]));
|
|
||||||
} catch (final Exception e) {
|
|
||||||
log.error("Unexpected error while trying to parse dependency map of ConfigurationAttribute: {}",
|
|
||||||
attribute,
|
|
||||||
e);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,14 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildInput(final FormBuilder builder, final Label lab) {
|
private void buildInput(final FormBuilder builder, final Label lab) {
|
||||||
|
final String actionKey = (this.label != null) ? this.label.name + ".action" : null;
|
||||||
final Selection selection = builder.widgetFactory.selectionLocalized(
|
final Selection selection = builder.widgetFactory.selectionLocalized(
|
||||||
this.type,
|
this.type,
|
||||||
builder.formParent,
|
builder.formParent,
|
||||||
this.itemsSupplier);
|
this.itemsSupplier,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
actionKey);
|
||||||
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1);
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1);
|
||||||
((Control) selection).setLayoutData(gridData);
|
((Control) selection).setLayoutData(gridData);
|
||||||
|
|
|
@ -59,6 +59,9 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
|
||||||
: builder.widgetFactory.textInput(builder.formParent, this.isPassword);
|
: builder.widgetFactory.textInput(builder.formParent, this.isPassword);
|
||||||
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1);
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1);
|
||||||
|
if (this.isArea) {
|
||||||
|
gridData.heightHint = 50;
|
||||||
|
}
|
||||||
textInput.setLayoutData(gridData);
|
textInput.setLayoutData(gridData);
|
||||||
if (this.value != null) {
|
if (this.value != null) {
|
||||||
textInput.setText(this.value);
|
textInput.setText(this.value);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig;
|
package ch.ethz.seb.sebserver.gui.service.examconfig;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
@ -71,12 +72,18 @@ public interface InputFieldBuilder {
|
||||||
final GridData gridData = new GridData(
|
final GridData gridData = new GridData(
|
||||||
SWT.FILL, SWT.FILL,
|
SWT.FILL, SWT.FILL,
|
||||||
true, false,
|
true, false,
|
||||||
(orientation != null && attribute.parentId == null) ? orientation.width() : 1,
|
(orientation != null && isOnView(attribute)) ? orientation.width() : 1,
|
||||||
(orientation != null && attribute.parentId == null) ? orientation.height() : 1);
|
(orientation != null && isOnView(attribute)) ? orientation.height() : 1);
|
||||||
comp.setLayoutData(gridData);
|
comp.setLayoutData(gridData);
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isOnView(final ConfigurationAttribute attribute) {
|
||||||
|
return attribute.parentId == null || BooleanUtils.toBoolean(ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_SHOW_IN_VIEW,
|
||||||
|
attribute));
|
||||||
|
}
|
||||||
|
|
||||||
static Label createErrorLabel(final Composite innerGrid) {
|
static Label createErrorLabel(final Composite innerGrid) {
|
||||||
final Label errorLabel = new Label(innerGrid, SWT.NONE);
|
final Label errorLabel = new Label(innerGrid, SWT.NONE);
|
||||||
errorLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
errorLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
|
|
|
@ -18,7 +18,7 @@ public interface ValueChangeRule {
|
||||||
|
|
||||||
void applyRule(
|
void applyRule(
|
||||||
ViewContext context,
|
ViewContext context,
|
||||||
ConfigurationAttribute attribut,
|
ConfigurationAttribute attribute,
|
||||||
ConfigurationValue value);
|
ConfigurationValue value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,335 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Table;
|
||||||
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
|
|
||||||
|
public abstract class AbstractTableFieldBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AbstractTableFieldBuilder.class);
|
||||||
|
|
||||||
|
protected final RestService restService;
|
||||||
|
protected final WidgetFactory widgetFactory;
|
||||||
|
protected InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
||||||
|
|
||||||
|
protected AbstractTableFieldBuilder(
|
||||||
|
final RestService restService,
|
||||||
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
|
this.restService = restService;
|
||||||
|
this.widgetFactory = widgetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final InputFieldBuilderSupplier inputFieldBuilderSupplier) {
|
||||||
|
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Table createTable(final Composite parent, final TableContext tableContext) {
|
||||||
|
final Table table = new Table(parent, SWT.NONE | SWT.V_SCROLL);
|
||||||
|
table.setLayout(new GridLayout());
|
||||||
|
final GridData gridData = new GridData(
|
||||||
|
SWT.FILL, SWT.FILL,
|
||||||
|
true, false,
|
||||||
|
(tableContext.orientation != null) ? tableContext.orientation.width() : 1,
|
||||||
|
(tableContext.orientation != null) ? tableContext.orientation.height() : 1);
|
||||||
|
gridData.heightHint = tableContext.orientation.height * 20 + 40;
|
||||||
|
table.setLayoutData(gridData);
|
||||||
|
table.setHeaderVisible(true);
|
||||||
|
table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext));
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TableContext createTableContext(final ConfigurationAttribute attribute, final ViewContext viewContext) {
|
||||||
|
final TableContext tableContext = new TableContext(
|
||||||
|
this.inputFieldBuilderSupplier,
|
||||||
|
this.widgetFactory,
|
||||||
|
this.restService,
|
||||||
|
attribute,
|
||||||
|
viewContext);
|
||||||
|
return tableContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSelectionListener(final Table table, final AbstractTableInputField tableField) {
|
||||||
|
table.addListener(SWT.MouseDoubleClick, event -> {
|
||||||
|
final int selectionIndex = table.getSelectionIndex();
|
||||||
|
if (selectionIndex >= 0) {
|
||||||
|
tableField.openForm(selectionIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void adaptColumnWidth(
|
||||||
|
final Table table,
|
||||||
|
final TableContext tableContext) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final int currentTableWidth = table.getClientArea().width - 50;
|
||||||
|
final TableColumn[] columns = table.getColumns();
|
||||||
|
final List<Orientation> orientations = tableContext
|
||||||
|
.getColumnAttributes()
|
||||||
|
.stream()
|
||||||
|
.map(attr -> tableContext.getOrientation(attr.id))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
final Integer div = orientations
|
||||||
|
.stream()
|
||||||
|
.map(o -> o.width)
|
||||||
|
.reduce(0, (acc, val) -> acc + val);
|
||||||
|
final int widthUnit = currentTableWidth / div;
|
||||||
|
for (int i = 0; i < columns.length - 2; i++) {
|
||||||
|
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.warn("Failed to adaptColumnWidth: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void setValueToCell(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final TableItem item,
|
||||||
|
final int cellIndex,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final TableValue tableValue) {
|
||||||
|
|
||||||
|
switch (attribute.type) {
|
||||||
|
case CHECKBOX: {
|
||||||
|
item.setImage(
|
||||||
|
cellIndex,
|
||||||
|
(BooleanUtils.toBoolean((tableValue != null) ? tableValue.value : null))
|
||||||
|
? ImageIcon.YES.getImage(item.getDisplay())
|
||||||
|
: ImageIcon.NO.getImage(item.getDisplay()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SINGLE_SELECTION: {
|
||||||
|
final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
|
attribute.getName() + "." +
|
||||||
|
tableValue.value;
|
||||||
|
item.setText(
|
||||||
|
cellIndex,
|
||||||
|
tableContext.i18nSupport().getText(key, getValue(attribute, tableValue)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
item.setText(cellIndex, getValue(attribute, tableValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getValue(
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final TableValue tableValue) {
|
||||||
|
|
||||||
|
if (tableValue == null) {
|
||||||
|
if (StringUtils.isBlank(attribute.defaultValue)) {
|
||||||
|
return Constants.EMPTY_NOTE;
|
||||||
|
} else {
|
||||||
|
return attribute.defaultValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isBlank(tableValue.value)) {
|
||||||
|
return Constants.EMPTY_NOTE;
|
||||||
|
} else {
|
||||||
|
return tableValue.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static abstract class AbstractTableInputField extends AbstractInputField<Table> {
|
||||||
|
|
||||||
|
protected final TableContext tableContext;
|
||||||
|
|
||||||
|
protected AbstractTableInputField(
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Orientation orientation,
|
||||||
|
final Table control,
|
||||||
|
final Label errorLabel,
|
||||||
|
final TableContext tableContext) {
|
||||||
|
|
||||||
|
super(attribute, orientation, control, errorLabel);
|
||||||
|
this.tableContext = tableContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationValue initValue(final Collection<ConfigurationValue> values) {
|
||||||
|
clearTable();
|
||||||
|
// get all child values as TableValues
|
||||||
|
final List<TableValue> tableValues = getChildValues(
|
||||||
|
this.tableContext,
|
||||||
|
this.attribute,
|
||||||
|
values);
|
||||||
|
|
||||||
|
initValue(tableValues);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void initValue(final List<TableValue> tableValues);
|
||||||
|
|
||||||
|
abstract void openForm(final int selectionIndex);
|
||||||
|
|
||||||
|
abstract void applyTableRowValues(final int index);
|
||||||
|
|
||||||
|
protected List<TableValue> getChildValues(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Collection<ConfigurationValue> values) {
|
||||||
|
|
||||||
|
return values.stream()
|
||||||
|
.filter(v -> isChildValue(tableContext, attribute, v))
|
||||||
|
.map(TableValue::of)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isChildValue(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
|
if (!tableContext.getViewContext().attributeMapping.attributeIdMapping
|
||||||
|
.containsKey(value.attributeId)) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
||||||
|
while (attr.parentId != null) {
|
||||||
|
if (attribute.id.equals(attr.parentId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
attr = tableContext.getAttribute(attr.parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
||||||
|
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
||||||
|
for (final TableValue tableValue : tableValues) {
|
||||||
|
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
||||||
|
tableValue.listIndex,
|
||||||
|
key -> new HashMap<>());
|
||||||
|
rowValues.put(tableValue.attributeId, tableValue);
|
||||||
|
}
|
||||||
|
return indexMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void valuesFromIndexMap(
|
||||||
|
final List<Map<Long, TableValue>> values,
|
||||||
|
final Map<Integer, Map<Long, TableValue>> indexMapping) {
|
||||||
|
|
||||||
|
values.clear();
|
||||||
|
final List<Integer> rows = new ArrayList<>(indexMapping.keySet());
|
||||||
|
rows.sort((i1, i2) -> i1.compareTo(i2));
|
||||||
|
rows
|
||||||
|
.stream()
|
||||||
|
.forEach(i -> {
|
||||||
|
final Map<Long, TableValue> rowValues = indexMapping.get(i);
|
||||||
|
values.add(rowValues);
|
||||||
|
// addTableRow(rowValues);
|
||||||
|
});
|
||||||
|
// for (int i = 0; i < rows.size(); i++) {
|
||||||
|
// final Map<Long, TableValue> rowValues = indexMapping.get(i);
|
||||||
|
// values.add(rowValues);
|
||||||
|
// addTableRow(rowValues);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void applyFormValues(
|
||||||
|
final List<Map<Long, TableValue>> values,
|
||||||
|
final Map<Long, TableValue> rowValues,
|
||||||
|
final int index) {
|
||||||
|
|
||||||
|
if (values != null && !values.isEmpty()) {
|
||||||
|
values.remove(index);
|
||||||
|
values.add(index, rowValues);
|
||||||
|
applyTableRowValues(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send values to web-service
|
||||||
|
this.tableContext.getValueChangeListener()
|
||||||
|
.tableChanged(extractTableValue(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigurationTableValues extractTableValue(final List<Map<Long, TableValue>> values) {
|
||||||
|
final List<TableValue> collect = values
|
||||||
|
.stream()
|
||||||
|
.flatMap(map -> map.values().stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return new ConfigurationTableValues(
|
||||||
|
this.tableContext.getInstitutionId(),
|
||||||
|
this.tableContext.getConfigurationId(),
|
||||||
|
this.attribute.id,
|
||||||
|
collect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultValue() {
|
||||||
|
// NOTE this just empty the list for now
|
||||||
|
// TODO do we need default values for lists?
|
||||||
|
clearTable();
|
||||||
|
final List<TableValue> values = new ArrayList<>();
|
||||||
|
this.tableContext.getValueChangeListener().tableChanged(
|
||||||
|
new ConfigurationTableValues(
|
||||||
|
this.tableContext.getInstitutionId(),
|
||||||
|
this.tableContext.getConfigurationId(),
|
||||||
|
this.attribute.id,
|
||||||
|
values));
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearTable() {
|
||||||
|
this.control.setSelection(-1);
|
||||||
|
if (this.control.getItemCount() > 0) {
|
||||||
|
for (final TableItem item : this.control.getItems()) {
|
||||||
|
item.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setValueToControl(final String value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Table;
|
||||||
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
@GuiProfile
|
||||||
|
public class CompositeTableFieldBuilder extends AbstractTableFieldBuilder {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CompositeTableFieldBuilder.class);
|
||||||
|
|
||||||
|
private static final String TABLE_ENTRY_NAME = "TABLE_ENTRY";
|
||||||
|
private static final String TABLE_COLUMN_NAME_KEY = "TABLE_COLUMN_NAME";
|
||||||
|
|
||||||
|
protected CompositeTableFieldBuilder(
|
||||||
|
final RestService restService,
|
||||||
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
|
super(restService, widgetFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean builderFor(
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Orientation orientation) {
|
||||||
|
|
||||||
|
if (attribute == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AttributeType.COMPOSITE_TABLE == attribute.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputField createInputField(
|
||||||
|
final Composite parent,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
|
final I18nSupport i18nSupport = viewContext.getI18nSupport();
|
||||||
|
final TableContext tableContext = createTableContext(attribute, viewContext);
|
||||||
|
final Table table = createTable(parent, tableContext);
|
||||||
|
|
||||||
|
final String resources = attribute.getResources();
|
||||||
|
final String[] columnsAndRows = StringUtils.split(
|
||||||
|
resources,
|
||||||
|
Constants.EMBEDDED_LIST_SEPARATOR);
|
||||||
|
final String[] columns = (columnsAndRows.length == 2)
|
||||||
|
? StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR)
|
||||||
|
: new String[] { TABLE_ENTRY_NAME };
|
||||||
|
final String[] rows = (columnsAndRows.length == 2)
|
||||||
|
? StringUtils.split(columnsAndRows[1], Constants.LIST_SEPARATOR)
|
||||||
|
: StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR);
|
||||||
|
|
||||||
|
final String attributeNameKey = ExamConfigurationService.attributeNameKey(attribute);
|
||||||
|
for (int i = 0; i < columns.length; i++) {
|
||||||
|
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
||||||
|
table,
|
||||||
|
new LocTextKey(attributeNameKey + "." + columns[i]),
|
||||||
|
new LocTextKey(attributeNameKey + "." + columns[i] + ".tootlip"));
|
||||||
|
|
||||||
|
column.setData(TABLE_COLUMN_NAME_KEY, columns[i]);
|
||||||
|
column.setWidth(100);
|
||||||
|
column.setResizable(false);
|
||||||
|
column.setMoveable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < rows.length; i++) {
|
||||||
|
final TableItem item = new TableItem(table, SWT.NONE);
|
||||||
|
for (int j = 0; j < columns.length; j++) {
|
||||||
|
if (TABLE_ENTRY_NAME.equals(columns[j])) {
|
||||||
|
item.setText(j, i18nSupport.getText(
|
||||||
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + rows[i],
|
||||||
|
rows[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompositeTableInputField tableField = new CompositeTableInputField(
|
||||||
|
tableContext,
|
||||||
|
table,
|
||||||
|
Arrays.asList(columns),
|
||||||
|
Arrays.asList(rows));
|
||||||
|
|
||||||
|
setSelectionListener(table, tableField);
|
||||||
|
return tableField;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void adaptColumnWidth(
|
||||||
|
final Table table,
|
||||||
|
final TableContext tableContext) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final int currentTableWidth = table.getClientArea().width - 50;
|
||||||
|
final TableColumn[] columns = table.getColumns();
|
||||||
|
final int widthUnit = currentTableWidth / (columns.length + 2);
|
||||||
|
for (int i = 0; i < columns.length; i++) {
|
||||||
|
final int factor = (TABLE_ENTRY_NAME.equals(columns[i].getData(TABLE_COLUMN_NAME_KEY))) ? 4 : 1;
|
||||||
|
columns[i].setWidth(widthUnit * factor);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.warn("Failed to adaptColumnWidth: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class CompositeTableInputField extends AbstractTableInputField {
|
||||||
|
|
||||||
|
final List<String> columns;
|
||||||
|
final List<String> rows;
|
||||||
|
final List<Map<Long, TableValue>> values;
|
||||||
|
|
||||||
|
CompositeTableInputField(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final Table control,
|
||||||
|
final List<String> columns,
|
||||||
|
final List<String> rows) {
|
||||||
|
|
||||||
|
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
||||||
|
this.values = new ArrayList<>();
|
||||||
|
this.columns = columns;
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initValue(final List<TableValue> tableValues) {
|
||||||
|
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
||||||
|
for (int i = 0; i < this.values.size(); i++) {
|
||||||
|
setRowValues(i, this.values.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyTableRowValues(final int index) {
|
||||||
|
setRowValues(index, this.values.get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRowValues(final int index, final Map<Long, TableValue> map) {
|
||||||
|
final TableItem rowItem = this.control.getItem(index);
|
||||||
|
for (final TableValue val : map.values()) {
|
||||||
|
final Orientation orientation = this.tableContext.getOrientation(val.attributeId);
|
||||||
|
final String groupId = orientation.getGroupId();
|
||||||
|
if (StringUtils.isNoneBlank(groupId)) {
|
||||||
|
final int cellIndex = this.columns.indexOf(groupId);
|
||||||
|
if (cellIndex >= 0) {
|
||||||
|
setValueToCell(
|
||||||
|
this.tableContext,
|
||||||
|
rowItem,
|
||||||
|
cellIndex,
|
||||||
|
this.tableContext.getAttribute(val.attributeId),
|
||||||
|
val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void openForm(final int selectionIndex) {
|
||||||
|
final String row = this.rows.get(selectionIndex);
|
||||||
|
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
||||||
|
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
||||||
|
this.tableContext,
|
||||||
|
rowValues,
|
||||||
|
row);
|
||||||
|
|
||||||
|
new ModalInputDialog<Map<Long, TableValue>>(
|
||||||
|
this.control.getShell(),
|
||||||
|
this.tableContext.getWidgetFactory())
|
||||||
|
.setDialogWidth(500)
|
||||||
|
.open(
|
||||||
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + row),
|
||||||
|
rowVals -> applyFormValues(this.values, rowVals, selectionIndex),
|
||||||
|
() -> this.tableContext.getValueChangeListener()
|
||||||
|
.tableChanged(extractTableValue(this.values)),
|
||||||
|
builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
||||||
|
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
||||||
|
for (final TableValue tableValue : tableValues) {
|
||||||
|
final ConfigurationAttribute attribute = this.tableContext
|
||||||
|
.getViewContext()
|
||||||
|
.getAttribute(tableValue.attributeId);
|
||||||
|
final String groupId = ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
||||||
|
attribute);
|
||||||
|
final int index = this.rows.indexOf(groupId);
|
||||||
|
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
||||||
|
index,
|
||||||
|
key -> new HashMap<>());
|
||||||
|
rowValues.put(tableValue.attributeId, tableValue);
|
||||||
|
}
|
||||||
|
return indexMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void clearTable() {
|
||||||
|
// nothing to clear for this table type
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isChildValue(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
|
final boolean childValue = super.isChildValue(tableContext, attribute, value);
|
||||||
|
if (childValue) {
|
||||||
|
final ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
||||||
|
return ConfigurationAttribute.hasDependency(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
||||||
|
attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return childValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -166,7 +166,6 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
||||||
gridLayout.verticalSpacing = 0;
|
gridLayout.verticalSpacing = 0;
|
||||||
composite.setLayout(gridLayout);
|
composite.setLayout(gridLayout);
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
gridData.heightHint = 200;
|
|
||||||
composite.setLayoutData(gridData);
|
composite.setLayoutData(gridData);
|
||||||
|
|
||||||
final ViewGridBuilder viewGridBuilder = new ViewGridBuilder(
|
final ViewGridBuilder viewGridBuilder = new ViewGridBuilder(
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -20,14 +17,22 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class LabelBuilder implements InputFieldBuilder {
|
public class LabelBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
|
protected LabelBuilder(final WidgetFactory widgetFactory) {
|
||||||
|
this.widgetFactory = widgetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
|
@ -46,12 +51,9 @@ public class LabelBuilder implements InputFieldBuilder {
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
Objects.requireNonNull(parent);
|
final Label label = this.widgetFactory.labelLocalized(
|
||||||
Objects.requireNonNull(attribute);
|
parent,
|
||||||
Objects.requireNonNull(viewContext);
|
ExamConfigurationService.attributeNameLocKey(attribute));
|
||||||
|
|
||||||
final Label label = new Label(parent, SWT.NONE);
|
|
||||||
label.setText(attribute.name);
|
|
||||||
|
|
||||||
return new LabelField(
|
return new LabelField(
|
||||||
attribute,
|
attribute,
|
||||||
|
|
|
@ -11,7 +11,6 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -19,7 +18,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
|
|
||||||
public abstract class SelectionFieldBuilder {
|
public abstract class SelectionFieldBuilder {
|
||||||
|
@ -47,11 +45,14 @@ public abstract class SelectionFieldBuilder {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<String, String> attributeDependencyMap = Utils.getAttributeDependencyMap(attribute);
|
|
||||||
final String prefix =
|
final String prefix =
|
||||||
(attributeDependencyMap.containsKey(ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY))
|
(ConfigurationAttribute.hasDependency(
|
||||||
? attributeDependencyMap.get(ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY) + "."
|
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
||||||
: ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".";
|
attribute))
|
||||||
|
? ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
||||||
|
attribute) + "."
|
||||||
|
: ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".";
|
||||||
|
|
||||||
return Arrays.asList(StringUtils.split(
|
return Arrays.asList(StringUtils.split(
|
||||||
attribute.resources,
|
attribute.resources,
|
||||||
|
|
|
@ -16,21 +16,18 @@ import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigTableRowValues;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigTableRowValues;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
@ -78,6 +75,10 @@ public class TableContext {
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public I18nSupport i18nSupport() {
|
||||||
|
return this.viewContext.i18nSupport;
|
||||||
|
}
|
||||||
|
|
||||||
public InputFieldBuilderSupplier getInputFieldBuilderSupplier() {
|
public InputFieldBuilderSupplier getInputFieldBuilderSupplier() {
|
||||||
return this.inputFieldBuilderSupplier;
|
return this.inputFieldBuilderSupplier;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +103,20 @@ public class TableContext {
|
||||||
return this.rowAttributes;
|
return this.rowAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ConfigurationAttribute> getRowAttributes(final String rowGroupId) {
|
||||||
|
if (StringUtils.isBlank(rowGroupId)) {
|
||||||
|
return getRowAttributes();
|
||||||
|
} else {
|
||||||
|
return this.rowAttributes
|
||||||
|
.stream()
|
||||||
|
.filter(attr -> rowGroupId.equals(ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
||||||
|
attr)))
|
||||||
|
.sorted(rowAttributeComparator(this.viewContext))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<ConfigurationAttribute> getColumnAttributes() {
|
public List<ConfigurationAttribute> getColumnAttributes() {
|
||||||
return this.columnAttributes;
|
return this.columnAttributes;
|
||||||
}
|
}
|
||||||
|
@ -188,31 +203,4 @@ public class TableContext {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRowValue(final TableValue tableValue) {
|
|
||||||
if (tableValue == null || StringUtils.isBlank(tableValue.value)) {
|
|
||||||
return Constants.EMPTY_NOTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ConfigurationAttribute attribute = this.viewContext.getAttribute(tableValue.attributeId);
|
|
||||||
if (attribute != null) {
|
|
||||||
switch (attribute.type) {
|
|
||||||
case CHECKBOX: {
|
|
||||||
return BooleanUtils.toBoolean(tableValue.value)
|
|
||||||
? this.viewContext.i18nSupport.getText(ResourceService.ACTIVE_TEXT_KEY)
|
|
||||||
: this.viewContext.i18nSupport.getText(ResourceService.INACTIVE_TEXT_KEY);
|
|
||||||
}
|
|
||||||
case SINGLE_SELECTION: {
|
|
||||||
final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
|
||||||
attribute.getName() + "." +
|
|
||||||
tableValue.value;
|
|
||||||
return this.viewContext.i18nSupport.getText(key, tableValue.value);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return tableValue.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tableValue.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,37 +9,27 @@
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
||||||
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.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
@ -48,27 +38,13 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class TableFieldBuilder implements InputFieldBuilder {
|
public class TableFieldBuilder extends AbstractTableFieldBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(TableFieldBuilder.class);
|
|
||||||
|
|
||||||
private static final String ROW_VALUE_KEY = "RowValues";
|
|
||||||
|
|
||||||
private final RestService restService;
|
|
||||||
private final WidgetFactory widgetFactory;
|
|
||||||
private InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
|
||||||
|
|
||||||
protected TableFieldBuilder(
|
protected TableFieldBuilder(
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final WidgetFactory widgetFactory) {
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
this.restService = restService;
|
super(restService, widgetFactory);
|
||||||
this.widgetFactory = widgetFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(final InputFieldBuilderSupplier inputFieldBuilderSupplier) {
|
|
||||||
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -89,35 +65,20 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
final I18nSupport i18nSupport = viewContext.getI18nSupport();
|
final TableContext tableContext = createTableContext(attribute, viewContext);
|
||||||
final TableContext tableContext = new TableContext(
|
final Table table = createTable(parent, tableContext);
|
||||||
this.inputFieldBuilderSupplier,
|
|
||||||
this.widgetFactory,
|
|
||||||
this.restService,
|
|
||||||
attribute,
|
|
||||||
viewContext);
|
|
||||||
|
|
||||||
final Table table = new Table(parent, SWT.NONE | SWT.H_SCROLL);
|
|
||||||
table.setLayout(new GridLayout());
|
|
||||||
final GridData gridData = new GridData(
|
|
||||||
SWT.FILL, SWT.FILL,
|
|
||||||
true, false,
|
|
||||||
(tableContext.orientation != null) ? tableContext.orientation.width() : 1,
|
|
||||||
(tableContext.orientation != null) ? tableContext.orientation.height() : 1);
|
|
||||||
gridData.heightHint = tableContext.orientation.height * 20 + 40;
|
|
||||||
table.setLayoutData(gridData);
|
|
||||||
table.setHeaderVisible(true);
|
|
||||||
table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext));
|
|
||||||
|
|
||||||
for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) {
|
for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) {
|
||||||
final TableColumn column = new TableColumn(table, SWT.NONE);
|
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
||||||
final String text = i18nSupport.getText(
|
table,
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
columnAttribute.name,
|
columnAttribute.name),
|
||||||
columnAttribute.name);
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
column.setText(text);
|
columnAttribute.name +
|
||||||
|
".tootltip"));
|
||||||
column.setWidth(100);
|
column.setWidth(100);
|
||||||
column.setResizable(false);
|
column.setResizable(false);
|
||||||
|
column.setMoveable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableInputField tableField = new TableInputField(
|
final TableInputField tableField = new TableInputField(
|
||||||
|
@ -149,107 +110,28 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
table.addListener(SWT.MouseDoubleClick, event -> {
|
setSelectionListener(table, tableField);
|
||||||
final int selectionIndex = table.getSelectionIndex();
|
|
||||||
if (selectionIndex >= 0) {
|
|
||||||
tableField.openForm(selectionIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return tableField;
|
return tableField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void adaptColumnWidth(
|
static final class TableInputField extends AbstractTableInputField {
|
||||||
final Table table,
|
|
||||||
final TableContext tableContext) {
|
|
||||||
|
|
||||||
try {
|
private final List<Map<Long, TableValue>> values;
|
||||||
final int currentTableWidth = table.getClientArea().width - 50;
|
|
||||||
final TableColumn[] columns = table.getColumns();
|
|
||||||
final List<Orientation> orientations = tableContext
|
|
||||||
.getColumnAttributes()
|
|
||||||
.stream()
|
|
||||||
.map(attr -> tableContext.getOrientation(attr.id))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
final Integer div = orientations
|
|
||||||
.stream()
|
|
||||||
.map(o -> o.width)
|
|
||||||
.reduce(0, (acc, val) -> acc + val);
|
|
||||||
final int widthUnit = currentTableWidth / div;
|
|
||||||
for (int i = 0; i < columns.length - 2; i++) {
|
|
||||||
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
log.warn("Failed to adaptColumnWidth: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class TableInputField extends AbstractInputField<Table> {
|
|
||||||
|
|
||||||
private final TableContext tableContext;
|
|
||||||
|
|
||||||
private List<Map<Long, TableValue>> values;
|
|
||||||
|
|
||||||
TableInputField(
|
TableInputField(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
final Table control) {
|
final Table control) {
|
||||||
|
|
||||||
super(tableContext.attribute, tableContext.orientation, control, null);
|
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
||||||
this.tableContext = tableContext;
|
this.values = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigurationValue initValue(final Collection<ConfigurationValue> values) {
|
|
||||||
clearTable();
|
|
||||||
// get all child values as TableValues
|
|
||||||
final List<TableValue> tableValues = values.stream()
|
|
||||||
.filter(this::isChildValue)
|
|
||||||
.map(TableValue::of)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
initValue(tableValues);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initValue(final List<TableValue> tableValues) {
|
void initValue(final List<TableValue> tableValues) {
|
||||||
final Map<Integer, Map<Long, TableValue>> _initValue = new HashMap<>();
|
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
||||||
for (final TableValue tableValue : tableValues) {
|
for (int i = 0; i < this.values.size(); i++) {
|
||||||
final Map<Long, TableValue> rowValues = _initValue.computeIfAbsent(
|
addTableRow(i, this.values.get(i));
|
||||||
tableValue.listIndex,
|
|
||||||
key -> new HashMap<>());
|
|
||||||
rowValues.put(tableValue.attributeId, tableValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Integer> rows = new ArrayList<>(_initValue.keySet());
|
|
||||||
rows.sort((i1, i2) -> i1.compareTo(i2));
|
|
||||||
|
|
||||||
this.values = new ArrayList<>();
|
|
||||||
rows
|
|
||||||
.stream()
|
|
||||||
.forEach(i -> {
|
|
||||||
final Map<Long, TableValue> rowValues = _initValue.get(i);
|
|
||||||
this.values.add(rowValues);
|
|
||||||
addTableRow(rowValues);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isChildValue(final ConfigurationValue value) {
|
|
||||||
if (!this.tableContext.getViewContext().attributeMapping.attributeIdMapping
|
|
||||||
.containsKey(value.attributeId)) {
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationAttribute attr = this.tableContext.getAttribute(value.attributeId);
|
|
||||||
while (attr.parentId != null) {
|
|
||||||
if (this.attribute.id.equals(attr.parentId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
attr = this.tableContext.getAttribute(attr.parentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteRow(final int selectionIndex) {
|
private void deleteRow(final int selectionIndex) {
|
||||||
|
@ -257,7 +139,7 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
this.values.remove(selectionIndex);
|
this.values.remove(selectionIndex);
|
||||||
// send new values to web-service
|
// send new values to web-service
|
||||||
this.tableContext.getValueChangeListener()
|
this.tableContext.getValueChangeListener()
|
||||||
.tableChanged(extractTableValue());
|
.tableChanged(extractTableValue(this.values));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRow() {
|
private void addRow() {
|
||||||
|
@ -271,21 +153,22 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
Function.identity()));
|
Function.identity()));
|
||||||
|
|
||||||
this.values.add(rowValues);
|
this.values.add(rowValues);
|
||||||
addTableRow(rowValues);
|
addTableRow(this.values.size() - 1, rowValues);
|
||||||
this.control.layout();
|
this.control.layout();
|
||||||
// send new values to web-service
|
// send new values to web-service
|
||||||
this.tableContext.getValueChangeListener()
|
this.tableContext.getValueChangeListener()
|
||||||
.tableChanged(extractTableValue());
|
.tableChanged(extractTableValue(this.values));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTableRow(final Map<Long, TableValue> rowValues) {
|
protected void addTableRow(final int index, final Map<Long, TableValue> rowValues) {
|
||||||
new TableItem(this.control, SWT.NONE);
|
new TableItem(this.control, SWT.NONE);
|
||||||
applyTableRowValues(this.values.size() - 1);
|
applyTableRowValues(index);
|
||||||
|
|
||||||
// TODO try to add delete button within table row?
|
// TODO try to add delete button within table row?
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyTableRowValues(final int index) {
|
@Override
|
||||||
|
protected void applyTableRowValues(final int index) {
|
||||||
final TableItem item = this.control.getItem(index);
|
final TableItem item = this.control.getItem(index);
|
||||||
final Map<Long, TableValue> rowValues = this.values.get(index);
|
final Map<Long, TableValue> rowValues = this.values.get(index);
|
||||||
|
|
||||||
|
@ -293,26 +176,14 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
||||||
if (rowValues.containsKey(attr.id)) {
|
if (rowValues.containsKey(attr.id)) {
|
||||||
final TableValue tableValue = rowValues.get(attr.id);
|
final TableValue tableValue = rowValues.get(attr.id);
|
||||||
if (attr.type == AttributeType.CHECKBOX) {
|
setValueToCell(this.tableContext, item, cellIndex, attr, tableValue);
|
||||||
|
|
||||||
item.setImage(
|
|
||||||
cellIndex,
|
|
||||||
(BooleanUtils.toBoolean((tableValue != null) ? tableValue.value : null))
|
|
||||||
? ImageIcon.YES.getImage(this.control.getDisplay())
|
|
||||||
: ImageIcon.NO.getImage(this.control.getDisplay()));
|
|
||||||
} else {
|
|
||||||
item.setText(
|
|
||||||
cellIndex,
|
|
||||||
this.tableContext.getRowValue(tableValue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cellIndex++;
|
cellIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.setData(ROW_VALUE_KEY, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openForm(final int selectionIndex) {
|
@Override
|
||||||
|
protected void openForm(final int selectionIndex) {
|
||||||
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
||||||
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
||||||
this.tableContext,
|
this.tableContext,
|
||||||
|
@ -327,69 +198,12 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
ExamConfigurationService.getTablePopupTitleKey(
|
ExamConfigurationService.getTablePopupTitleKey(
|
||||||
this.attribute,
|
this.attribute,
|
||||||
this.tableContext.getViewContext().i18nSupport),
|
this.tableContext.getViewContext().i18nSupport),
|
||||||
values -> applyFormValues(values, selectionIndex),
|
rowVals -> applyFormValues(this.values, rowVals, selectionIndex),
|
||||||
() -> this.tableContext.getValueChangeListener()
|
() -> this.tableContext.getValueChangeListener()
|
||||||
.tableChanged(extractTableValue()),
|
.tableChanged(extractTableValue(this.values)),
|
||||||
builder);
|
builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyFormValues(final Map<Long, TableValue> values, final int index) {
|
|
||||||
if (values != null && !values.isEmpty()) {
|
|
||||||
this.values.remove(index);
|
|
||||||
this.values.add(index, values);
|
|
||||||
applyTableRowValues(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send values to web-service
|
|
||||||
this.tableContext.getValueChangeListener()
|
|
||||||
.tableChanged(extractTableValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationTableValues extractTableValue() {
|
|
||||||
final List<TableValue> collect = this.values
|
|
||||||
.stream()
|
|
||||||
.flatMap(map -> map.values().stream())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return new ConfigurationTableValues(
|
|
||||||
this.tableContext.getInstitutionId(),
|
|
||||||
this.tableContext.getConfigurationId(),
|
|
||||||
this.attribute.id,
|
|
||||||
collect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDefaultValue() {
|
|
||||||
// NOTE this just empty the list for now
|
|
||||||
// TODO do we need default values for lists?
|
|
||||||
clearTable();
|
|
||||||
final List<TableValue> values = new ArrayList<>();
|
|
||||||
this.tableContext.getValueChangeListener().tableChanged(
|
|
||||||
new ConfigurationTableValues(
|
|
||||||
this.tableContext.getInstitutionId(),
|
|
||||||
this.tableContext.getConfigurationId(),
|
|
||||||
this.attribute.id,
|
|
||||||
values));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTable() {
|
|
||||||
this.control.setSelection(-1);
|
|
||||||
if (this.control.getItemCount() > 0) {
|
|
||||||
for (final TableItem item : this.control.getItems()) {
|
|
||||||
item.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setValueToControl(final String value) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,11 @@ import org.eclipse.swt.widgets.Label;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.TableFieldBuilder.TableInputField;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
|
@ -40,6 +40,7 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
private final TableContext tableContext;
|
private final TableContext tableContext;
|
||||||
private final Map<Long, TableValue> rowValues;
|
private final Map<Long, TableValue> rowValues;
|
||||||
private final int listIndex;
|
private final int listIndex;
|
||||||
|
private final String rowGroupId;
|
||||||
|
|
||||||
public TableRowFormBuilder(
|
public TableRowFormBuilder(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
|
@ -49,6 +50,18 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
this.tableContext = tableContext;
|
this.tableContext = tableContext;
|
||||||
this.rowValues = rowValues;
|
this.rowValues = rowValues;
|
||||||
this.listIndex = listIndex;
|
this.listIndex = listIndex;
|
||||||
|
this.rowGroupId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableRowFormBuilder(
|
||||||
|
final TableContext tableContext,
|
||||||
|
final Map<Long, TableValue> rowValues,
|
||||||
|
final String rowGroupId) {
|
||||||
|
|
||||||
|
this.tableContext = tableContext;
|
||||||
|
this.rowValues = rowValues;
|
||||||
|
this.listIndex = 0;
|
||||||
|
this.rowGroupId = rowGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,11 +80,25 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
false);
|
false);
|
||||||
|
|
||||||
final List<InputField> inputFields = new ArrayList<>();
|
final List<InputField> inputFields = new ArrayList<>();
|
||||||
for (final ConfigurationAttribute attribute : this.tableContext.getRowAttributes()) {
|
for (final ConfigurationAttribute attribute : this.tableContext.getRowAttributes(this.rowGroupId)) {
|
||||||
createLabel(grid, attribute);
|
createLabel(grid, attribute);
|
||||||
inputFields.add(createInputField(grid, attribute));
|
inputFields.add(createInputField(grid, attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (final InputField inputField : inputFields) {
|
||||||
|
final ConfigurationAttribute attribute = inputField.getAttribute();
|
||||||
|
this.tableContext.getValueChangeListener().notifyGUI(
|
||||||
|
this.tableContext.getViewContext(),
|
||||||
|
attribute,
|
||||||
|
new ConfigurationValue(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
attribute.id,
|
||||||
|
this.listIndex,
|
||||||
|
inputField.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
// when the pop-up gets closed we have to remove the input fields from the view context
|
// when the pop-up gets closed we have to remove the input fields from the view context
|
||||||
grid.addDisposeListener(event -> {
|
grid.addDisposeListener(event -> {
|
||||||
this.tableContext.flushInputFields(this.rowValues.keySet());
|
this.tableContext.flushInputFields(this.rowValues.keySet());
|
||||||
|
@ -103,14 +130,8 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
attribute,
|
attribute,
|
||||||
this.tableContext.getViewContext());
|
this.tableContext.getViewContext());
|
||||||
|
|
||||||
if (attribute.type == AttributeType.TABLE) {
|
final TableValue initValue = this.rowValues.get(attribute.id);
|
||||||
((TableInputField) inputField).initValue(new ArrayList<>(this.rowValues.values()));
|
inputField.initValue((initValue != null) ? initValue.value : null, this.listIndex);
|
||||||
} else {
|
|
||||||
inputField.initValue(
|
|
||||||
this.rowValues.get(attribute.id).value,
|
|
||||||
this.listIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have to register the input field within the ViewContext to receive error messages
|
// we have to register the input field within the ViewContext to receive error messages
|
||||||
this.tableContext.registerInputField(inputField);
|
this.tableContext.registerInputField(inputField);
|
||||||
|
|
||||||
|
|
|
@ -64,14 +64,23 @@ public class TextFieldBuilder implements InputFieldBuilder {
|
||||||
.createInnerGrid(parent, attribute, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Text text;
|
final Text text;
|
||||||
if (attribute.type == AttributeType.INTEGER ||
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||||
attribute.type == AttributeType.DECIMAL) {
|
switch (attribute.type) {
|
||||||
|
case INTEGER:
|
||||||
text = new Text(innerGrid, SWT.RIGHT | SWT.BORDER);
|
case DECIMAL: {
|
||||||
} else {
|
text = new Text(innerGrid, SWT.RIGHT | SWT.BORDER);
|
||||||
text = new Text(innerGrid, SWT.LEFT | SWT.BORDER);
|
break;
|
||||||
|
}
|
||||||
|
case TEXT_AREA: {
|
||||||
|
text = new Text(innerGrid, SWT.LEFT | SWT.BORDER | SWT.MULTI);
|
||||||
|
gridData.heightHint = 50;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
text = new Text(innerGrid, SWT.LEFT | SWT.BORDER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
text.setLayoutData(gridData);
|
||||||
|
|
||||||
final LocTextKey toolTipKey = ExamConfigurationService.getToolTipKey(
|
final LocTextKey toolTipKey = ExamConfigurationService.getToolTipKey(
|
||||||
attribute,
|
attribute,
|
||||||
|
|
|
@ -96,10 +96,6 @@ public final class ViewContext {
|
||||||
public View getView() {
|
public View getView() {
|
||||||
return this.view;
|
return this.view;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// public AttributeMapping getAttributeMapping() {
|
|
||||||
// return this.attributeMapping;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Collection<ConfigurationAttribute> getChildAttributes(final Long id) {
|
public Collection<ConfigurationAttribute> getChildAttributes(final Long id) {
|
||||||
return this.attributeMapping.childAttributeMapping.get(id);
|
return this.attributeMapping.childAttributeMapping.get(id);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
@ -71,8 +72,12 @@ public class ViewGridBuilder {
|
||||||
log.debug("Add SEB Configuration Attribute: " + attribute);
|
log.debug("Add SEB Configuration Attribute: " + attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore nested attributes here
|
// ignore nested attributes here (if not propagated to show up in view)
|
||||||
if (attribute.parentId != null) {
|
if (attribute.parentId != null &&
|
||||||
|
!BooleanUtils.toBoolean(ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_SHOW_IN_VIEW,
|
||||||
|
attribute))) {
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class AllowFlashFullscreenRule implements ValueChangeRule {
|
||||||
@Override
|
@Override
|
||||||
public void applyRule(
|
public void applyRule(
|
||||||
final ViewContext context,
|
final ViewContext context,
|
||||||
final ConfigurationAttribute attribut,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
if (BooleanUtils.toBoolean(value.value)) {
|
if (BooleanUtils.toBoolean(value.value)) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class BrowserViewModeRule implements ValueChangeRule {
|
||||||
@Override
|
@Override
|
||||||
public void applyRule(
|
public void applyRule(
|
||||||
final ViewContext context,
|
final ViewContext context,
|
||||||
final ConfigurationAttribute attribut,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(value.value)) {
|
if (StringUtils.isBlank(value.value)) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class ExitKeySequenceChangeRule implements ValueChangeRule {
|
||||||
@Override
|
@Override
|
||||||
public void applyRule(
|
public void applyRule(
|
||||||
final ViewContext context,
|
final ViewContext context,
|
||||||
final ConfigurationAttribute attribut,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
if (BooleanUtils.toBoolean(value.value)) {
|
if (BooleanUtils.toBoolean(value.value)) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class HideToolbarDefaultRule implements ValueChangeRule {
|
||||||
@Override
|
@Override
|
||||||
public void applyRule(
|
public void applyRule(
|
||||||
final ViewContext context,
|
final ViewContext context,
|
||||||
final ConfigurationAttribute attribut,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
if (BooleanUtils.toBoolean(value.value)) {
|
if (BooleanUtils.toBoolean(value.value)) {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl.rules;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeRule;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Service
|
||||||
|
@GuiProfile
|
||||||
|
public class ProxyPasswordRule implements ValueChangeRule {
|
||||||
|
|
||||||
|
public static final String KEY_HTTP_PWD_REQUIRED = "HTTPRequiresPassword";
|
||||||
|
|
||||||
|
private final Map<String, Tuple<String>> observed;
|
||||||
|
|
||||||
|
public ProxyPasswordRule() {
|
||||||
|
this.observed = new HashMap<>();
|
||||||
|
this.observed.put(KEY_HTTP_PWD_REQUIRED, new Tuple<>("HTTPUsername", "HTTPPassword"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean observesAttribute(final ConfigurationAttribute attribute) {
|
||||||
|
return this.observed.containsKey(attribute.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyRule(
|
||||||
|
final ViewContext context,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
|
final Tuple<String> tuple = this.observed.get(attribute.name);
|
||||||
|
if (tuple != null) {
|
||||||
|
if (BooleanUtils.toBoolean(value.value)) {
|
||||||
|
context.enable(tuple._1);
|
||||||
|
context.enable(tuple._2);
|
||||||
|
} else {
|
||||||
|
context.disable(tuple._1);
|
||||||
|
context.disable(tuple._2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -94,4 +94,6 @@ public interface I18nSupport {
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
String getText(String key, Locale locale, String def, Object... args);
|
String getText(String key, Locale locale, String def, Object... args);
|
||||||
|
|
||||||
|
boolean hasText(LocTextKey locTooltipKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
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.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -168,4 +169,13 @@ public class I18nSupportImpl implements I18nSupport {
|
||||||
return this.messageSource.getMessage(key, args, def, locale);
|
return this.messageSource.getMessage(key, args, def, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasText(final LocTextKey key) {
|
||||||
|
if (key == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getText(key.name, (String) null) != null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ public final class PolyglotPageServiceImpl implements PolyglotPageService {
|
||||||
tableColumn.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tableColumn.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
tableColumn.setText(this.i18nSupport.getText(locTextKey));
|
tableColumn.setText(this.i18nSupport.getText(locTextKey));
|
||||||
|
|
||||||
if (locTooltipKey != null) {
|
if (this.i18nSupport.hasText(locTooltipKey)) {
|
||||||
tableColumn.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
tableColumn.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
||||||
tableColumn.setToolTipText(this.i18nSupport.getText(locTooltipKey));
|
tableColumn.setToolTipText(this.i18nSupport.getText(locTooltipKey));
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ public final class PolyglotPageServiceImpl implements PolyglotPageService {
|
||||||
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
tabItem.setText(this.i18nSupport.getText(locTextKey));
|
tabItem.setText(this.i18nSupport.getText(locTextKey));
|
||||||
|
|
||||||
if (locTooltipKey != null) {
|
if (this.i18nSupport.hasText(locTooltipKey)) {
|
||||||
tabItem.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
tabItem.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
||||||
tabItem.setToolTipText(this.i18nSupport.getText(locTooltipKey));
|
tabItem.setToolTipText(this.i18nSupport.getText(locTooltipKey));
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class PageServiceImpl implements PageService {
|
||||||
.getUISession()
|
.getUISession()
|
||||||
.getHttpSession();
|
.getHttpSession();
|
||||||
|
|
||||||
log.debug("SET session PageState: {} : {}", pageAction.definition.targetState, httpSession.getId());
|
log.debug("Set session PageState: {} : {}", pageAction.definition.targetState, httpSession.getId());
|
||||||
httpSession.setAttribute(ATTR_PAGE_STATE, pageAction.definition.targetState);
|
httpSession.setAttribute(ATTR_PAGE_STATE, pageAction.definition.targetState);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
|
|
@ -308,7 +308,8 @@ public class EntityTable<ROW extends Entity> {
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
});
|
});
|
||||||
|
|
||||||
this.composite.layout(true, true);
|
this.composite.getParent().layout(true, true);
|
||||||
|
PageService.updateScrolledComposite(this.composite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page<ROW> createTableRowsFromPage(final Page<ROW> page) {
|
private Page<ROW> createTableRowsFromPage(final Page<ROW> page) {
|
||||||
|
|
|
@ -33,6 +33,8 @@ public final class ColorSelection extends Composite implements Selection {
|
||||||
private static final long serialVersionUID = 4775375044147842526L;
|
private static final long serialVersionUID = 4775375044147842526L;
|
||||||
private static final Logger log = LoggerFactory.getLogger(ColorSelection.class);
|
private static final Logger log = LoggerFactory.getLogger(ColorSelection.class);
|
||||||
|
|
||||||
|
private static final LocTextKey DEFAULT_SELECT_TOOLTIP_KEY = new LocTextKey("sebserver.overall.action.select");
|
||||||
|
|
||||||
private static final int ACTION_COLUMN_WIDTH = 20;
|
private static final int ACTION_COLUMN_WIDTH = 20;
|
||||||
private final ColorDialog colorDialog;
|
private final ColorDialog colorDialog;
|
||||||
private final Composite colorField;
|
private final Composite colorField;
|
||||||
|
@ -40,7 +42,11 @@ public final class ColorSelection extends Composite implements Selection {
|
||||||
|
|
||||||
private Listener listener = null;
|
private Listener listener = null;
|
||||||
|
|
||||||
ColorSelection(final Composite parent, final WidgetFactory widgetFactory) {
|
ColorSelection(
|
||||||
|
final Composite parent,
|
||||||
|
final WidgetFactory widgetFactory,
|
||||||
|
final String tooltipKeyPrefix) {
|
||||||
|
|
||||||
super(parent, SWT.NONE);
|
super(parent, SWT.NONE);
|
||||||
final GridLayout gridLayout = new GridLayout(2, false);
|
final GridLayout gridLayout = new GridLayout(2, false);
|
||||||
gridLayout.verticalSpacing = 1;
|
gridLayout.verticalSpacing = 1;
|
||||||
|
@ -60,7 +66,9 @@ public final class ColorSelection extends Composite implements Selection {
|
||||||
final Label imageButton = widgetFactory.imageButton(
|
final Label imageButton = widgetFactory.imageButton(
|
||||||
ImageIcon.COLOR,
|
ImageIcon.COLOR,
|
||||||
this,
|
this,
|
||||||
new LocTextKey("Set Color"),
|
(StringUtils.isNoneBlank(tooltipKeyPrefix)
|
||||||
|
? new LocTextKey(tooltipKeyPrefix)
|
||||||
|
: DEFAULT_SELECT_TOOLTIP_KEY),
|
||||||
this::addColorSelection);
|
this::addColorSelection);
|
||||||
|
|
||||||
final GridData actionCell = new GridData(SWT.LEFT, SWT.CENTER, true, false);
|
final GridData actionCell = new GridData(SWT.LEFT, SWT.CENTER, true, false);
|
||||||
|
|
|
@ -41,6 +41,9 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
||||||
private static final long serialVersionUID = -7787134114963647332L;
|
private static final long serialVersionUID = -7787134114963647332L;
|
||||||
private static final int ACTION_COLUMN_WIDTH = 20;
|
private static final int ACTION_COLUMN_WIDTH = 20;
|
||||||
|
|
||||||
|
private static final LocTextKey DEFAULT_ADD_TOOLTIP_KEY = new LocTextKey("sebserver.overall.add");
|
||||||
|
private static final LocTextKey DEFAULT_REMOVE_TOOLTIP_KEY = new LocTextKey("sebserver.overall.remove");
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final Combo combo;
|
private final Combo combo;
|
||||||
private final LocTextKey addTextKey;
|
private final LocTextKey addTextKey;
|
||||||
|
@ -64,10 +67,10 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
this.addTextKey = (locTextPrefix != null)
|
this.addTextKey = (locTextPrefix != null)
|
||||||
? new LocTextKey(locTextPrefix + ".add")
|
? new LocTextKey(locTextPrefix + ".add")
|
||||||
: new LocTextKey("sebserver.overall.add");
|
: DEFAULT_ADD_TOOLTIP_KEY;
|
||||||
this.removeTextKey = (locTextPrefix != null)
|
this.removeTextKey = (locTextPrefix != null)
|
||||||
? new LocTextKey(locTextPrefix + ".remove")
|
? new LocTextKey(locTextPrefix + ".remove")
|
||||||
: new LocTextKey("sebserver.overall.remove");
|
: DEFAULT_REMOVE_TOOLTIP_KEY;
|
||||||
|
|
||||||
final GridLayout gridLayout = new GridLayout(2, false);
|
final GridLayout gridLayout = new GridLayout(2, false);
|
||||||
gridLayout.verticalSpacing = 1;
|
gridLayout.verticalSpacing = 1;
|
||||||
|
|
|
@ -36,10 +36,11 @@ public final class ThresholdList extends Composite {
|
||||||
private static final long serialVersionUID = -2305091471607040280L;
|
private static final long serialVersionUID = -2305091471607040280L;
|
||||||
private static final int ACTION_COLUMN_WIDTH = 20;
|
private static final int ACTION_COLUMN_WIDTH = 20;
|
||||||
|
|
||||||
private static final LocTextKey valueTextKey = new LocTextKey("sebserver.exam.indicator.thresholds.list.value");
|
private static final String COLOR_SELECTION_TEXT_KEY = "sebserver.exam.indicator.thresholds.select.color";
|
||||||
private static final LocTextKey colorTextKey = new LocTextKey("sebserver.exam.indicator.thresholds.list.color");
|
private static final LocTextKey VALUE_TEXT_KEY = new LocTextKey("sebserver.exam.indicator.thresholds.list.value");
|
||||||
private static final LocTextKey addTextKey = new LocTextKey("sebserver.exam.indicator.thresholds.list.add");
|
private static final LocTextKey COLOR_TEXT_KEY = new LocTextKey("sebserver.exam.indicator.thresholds.list.color");
|
||||||
private static final LocTextKey removeTextKey = new LocTextKey("sebserver.exam.indicator.thresholds.list.remove");
|
private static final LocTextKey ADD_TEXT_KEY = new LocTextKey("sebserver.exam.indicator.thresholds.list.add");
|
||||||
|
private static final LocTextKey REMOVE_TEXT_KEY = new LocTextKey("sebserver.exam.indicator.thresholds.list.remove");
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final List<Entry> thresholds = new ArrayList<>();
|
private final List<Entry> thresholds = new ArrayList<>();
|
||||||
|
@ -62,18 +63,24 @@ public final class ThresholdList extends Composite {
|
||||||
|
|
||||||
this.addListener(SWT.Resize, this::adaptColumnWidth);
|
this.addListener(SWT.Resize, this::adaptColumnWidth);
|
||||||
|
|
||||||
final Label valueTitle = widgetFactory.labelLocalized(this, CustomVariant.TITLE_LABEL, valueTextKey);
|
final Label valueTitle = widgetFactory.labelLocalized(
|
||||||
|
this,
|
||||||
|
CustomVariant.TITLE_LABEL,
|
||||||
|
VALUE_TEXT_KEY);
|
||||||
this.valueCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
this.valueCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
valueTitle.setLayoutData(this.valueCell);
|
valueTitle.setLayoutData(this.valueCell);
|
||||||
|
|
||||||
final Label colorTitle = widgetFactory.labelLocalized(this, CustomVariant.TITLE_LABEL, colorTextKey);
|
final Label colorTitle = widgetFactory.labelLocalized(
|
||||||
|
this,
|
||||||
|
CustomVariant.TITLE_LABEL,
|
||||||
|
COLOR_TEXT_KEY);
|
||||||
this.colorCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
this.colorCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
colorTitle.setLayoutData(this.colorCell);
|
colorTitle.setLayoutData(this.colorCell);
|
||||||
|
|
||||||
final Label imageButton = widgetFactory.imageButton(
|
final Label imageButton = widgetFactory.imageButton(
|
||||||
ImageIcon.ADD_BOX,
|
ImageIcon.ADD_BOX,
|
||||||
this,
|
this,
|
||||||
addTextKey,
|
ADD_TEXT_KEY,
|
||||||
this::addThreshold);
|
this::addThreshold);
|
||||||
this.actionCell = new GridData(SWT.LEFT, SWT.CENTER, true, false);
|
this.actionCell = new GridData(SWT.LEFT, SWT.CENTER, true, false);
|
||||||
imageButton.setLayoutData(this.actionCell);
|
imageButton.setLayoutData(this.actionCell);
|
||||||
|
@ -120,7 +127,9 @@ public final class ThresholdList extends Composite {
|
||||||
final GridData valueCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
final GridData valueCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
valueInput.setLayoutData(valueCell);
|
valueInput.setLayoutData(valueCell);
|
||||||
|
|
||||||
final Selection selector = this.widgetFactory.selectionLocalized(Type.COLOR, this, null);
|
final Selection selector = this.widgetFactory.selectionLocalized(
|
||||||
|
Type.COLOR, this, null, null, null,
|
||||||
|
COLOR_SELECTION_TEXT_KEY);
|
||||||
final GridData selectorCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
final GridData selectorCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
selectorCell.horizontalIndent = 2;
|
selectorCell.horizontalIndent = 2;
|
||||||
selector.adaptToControl().setLayoutData(selectorCell);
|
selector.adaptToControl().setLayoutData(selectorCell);
|
||||||
|
@ -128,7 +137,7 @@ public final class ThresholdList extends Composite {
|
||||||
final Label imageButton = this.widgetFactory.imageButton(
|
final Label imageButton = this.widgetFactory.imageButton(
|
||||||
ImageIcon.REMOVE_BOX,
|
ImageIcon.REMOVE_BOX,
|
||||||
this,
|
this,
|
||||||
removeTextKey,
|
REMOVE_TEXT_KEY,
|
||||||
null);
|
null);
|
||||||
final GridData actionCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
final GridData actionCell = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
imageButton.setLayoutData(actionCell);
|
imageButton.setLayoutData(actionCell);
|
||||||
|
|
|
@ -281,7 +281,8 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Text textAreaInput(final Composite content) {
|
public Text textAreaInput(final Composite content) {
|
||||||
return new Text(content, SWT.LEFT | SWT.BORDER | SWT.MULTI);
|
final Text textArea = new Text(content, SWT.LEFT | SWT.BORDER | SWT.MULTI);
|
||||||
|
return textArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Text textInput(final Composite content, final boolean password) {
|
public Text textInput(final Composite content, final boolean password) {
|
||||||
|
@ -477,7 +478,7 @@ public class WidgetFactory {
|
||||||
selection = new MultiSelectionCheckbox(parent);
|
selection = new MultiSelectionCheckbox(parent);
|
||||||
break;
|
break;
|
||||||
case COLOR:
|
case COLOR:
|
||||||
selection = new ColorSelection(parent, this);
|
selection = new ColorSelection(parent, this, actionLocTextPrefix);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported Selection.Type: " + type);
|
throw new IllegalArgumentException("Unsupported Selection.Type: " + type);
|
||||||
|
|
|
@ -230,12 +230,6 @@ public class PaginationServiceImpl implements PaginationService {
|
||||||
|
|
||||||
// Exam Table
|
// Exam Table
|
||||||
final Map<String, String> examTableMap = new HashMap<>();
|
final Map<String, String> examTableMap = new HashMap<>();
|
||||||
examTableMap.put(
|
|
||||||
Domain.EXAM.ATTR_INSTITUTION_ID,
|
|
||||||
ExamRecordDynamicSqlSupport.institutionId.name());
|
|
||||||
examTableMap.put(
|
|
||||||
Domain.EXAM.ATTR_LMS_SETUP_ID,
|
|
||||||
ExamRecordDynamicSqlSupport.lmsSetupId.name());
|
|
||||||
examTableMap.put(
|
examTableMap.put(
|
||||||
Domain.EXAM.ATTR_TYPE,
|
Domain.EXAM.ATTR_TYPE,
|
||||||
ExamRecordDynamicSqlSupport.type.name());
|
ExamRecordDynamicSqlSupport.type.name());
|
||||||
|
|
|
@ -210,6 +210,7 @@ public class ConfigurationDAOImpl implements ConfigurationDAO {
|
||||||
|
|
||||||
// with the current attribute values
|
// with the current attribute values
|
||||||
// TODO batch here for better performance
|
// TODO batch here for better performance
|
||||||
|
// http://pretius.com/how-to-use-mybatis-effectively-perform-batch-db-operations/
|
||||||
allValues.stream()
|
allValues.stream()
|
||||||
.map(oldValRec -> new ConfigurationValueRecord(
|
.map(oldValRec -> new ConfigurationValueRecord(
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
|
@ -44,6 +45,7 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationReco
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationRecordMapper;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationRecordMapper;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordDynamicSqlSupport;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordDynamicSqlSupport;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordMapper;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationValueRecordMapper;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationAttributeRecord;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationNodeRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationNodeRecord;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationRecord;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationValueRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationValueRecord;
|
||||||
|
@ -361,6 +363,8 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
|
||||||
.build()
|
.build()
|
||||||
.execute()
|
.execute()
|
||||||
.stream()
|
.stream()
|
||||||
|
// filter child attributes of tables. No default value for tables. Use templates for that
|
||||||
|
.filter(ConfigurationNodeDAOImpl::filterChildAttribute)
|
||||||
.forEach(attrRec -> {
|
.forEach(attrRec -> {
|
||||||
final String value = templateValues.getOrDefault(
|
final String value = templateValues.getOrDefault(
|
||||||
attrRec.getId(),
|
attrRec.getId(),
|
||||||
|
@ -379,6 +383,17 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean filterChildAttribute(final ConfigurationAttributeRecord rec) {
|
||||||
|
|
||||||
|
if (rec.getParentId() == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BooleanUtils.toBoolean(ConfigurationAttribute.getDependencyValue(
|
||||||
|
ConfigurationAttribute.DEPENDENCY_CREATE_DEFAULT_VALUE,
|
||||||
|
rec.getDependencies()));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get values from template with configuration attribute id mapped to the value
|
* Get values from template with configuration attribute id mapped to the value
|
||||||
* returns empty list if no template available
|
* returns empty list if no template available
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
@ -293,50 +294,109 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO {
|
||||||
.flatMap(val -> attributeRecordById(val.attributeId))
|
.flatMap(val -> attributeRecordById(val.attributeId))
|
||||||
.map(attributeRecord -> {
|
.map(attributeRecord -> {
|
||||||
|
|
||||||
final Map<Long, ConfigurationAttributeRecord> attributeMap = this.configurationAttributeRecordMapper
|
final String type = attributeRecord.getType();
|
||||||
.selectByExample()
|
if (AttributeType.TABLE.name().equals(type)) {
|
||||||
.where(
|
saveAsTable(value, attributeRecord);
|
||||||
ConfigurationAttributeRecordDynamicSqlSupport.parentId,
|
} else {
|
||||||
isEqualTo(attributeRecord.getId()))
|
saveAsComposite(value);
|
||||||
.build()
|
|
||||||
.execute()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(rec -> rec.getId(), Function.identity()));
|
|
||||||
|
|
||||||
final List<Long> columnAttributeIds = attributeMap.values()
|
|
||||||
.stream()
|
|
||||||
.map(a -> a.getId())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
// first delete all old values of this table
|
|
||||||
this.configurationValueRecordMapper.deleteByExample()
|
|
||||||
.where(
|
|
||||||
ConfigurationValueRecordDynamicSqlSupport.configurationId,
|
|
||||||
isEqualTo(value.configurationId))
|
|
||||||
.and(
|
|
||||||
ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId,
|
|
||||||
SqlBuilder.isIn(columnAttributeIds))
|
|
||||||
.build()
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
// then add the new values
|
|
||||||
for (final TableValue tableValue : value.values) {
|
|
||||||
final ConfigurationAttributeRecord columnAttr = attributeMap.get(tableValue.attributeId);
|
|
||||||
final ConfigurationValueRecord valueRecord = new ConfigurationValueRecord(
|
|
||||||
null,
|
|
||||||
value.institutionId,
|
|
||||||
value.configurationId,
|
|
||||||
columnAttr.getId(),
|
|
||||||
tableValue.listIndex,
|
|
||||||
tableValue.value);
|
|
||||||
|
|
||||||
this.configurationValueRecordMapper.insert(valueRecord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveAsTable(
|
||||||
|
final ConfigurationTableValues value,
|
||||||
|
final ConfigurationAttributeRecord attributeRecord) {
|
||||||
|
|
||||||
|
final Map<Long, ConfigurationAttributeRecord> attributeMap =
|
||||||
|
this.configurationAttributeRecordMapper
|
||||||
|
.selectByExample()
|
||||||
|
.where(
|
||||||
|
ConfigurationAttributeRecordDynamicSqlSupport.parentId,
|
||||||
|
isEqualTo(attributeRecord.getId()))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(rec -> rec.getId(), Function.identity()));
|
||||||
|
|
||||||
|
final List<Long> columnAttributeIds = attributeMap.values()
|
||||||
|
.stream()
|
||||||
|
.map(a -> a.getId())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// first delete all old values of this table
|
||||||
|
this.configurationValueRecordMapper.deleteByExample()
|
||||||
|
.where(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationId,
|
||||||
|
isEqualTo(value.configurationId))
|
||||||
|
.and(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId,
|
||||||
|
SqlBuilder.isIn(columnAttributeIds))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
// then add the new values
|
||||||
|
// TODO optimize with batching
|
||||||
|
for (final TableValue tableValue : value.values) {
|
||||||
|
final ConfigurationAttributeRecord columnAttr = attributeMap.get(tableValue.attributeId);
|
||||||
|
final ConfigurationValueRecord valueRecord = new ConfigurationValueRecord(
|
||||||
|
null,
|
||||||
|
value.institutionId,
|
||||||
|
value.configurationId,
|
||||||
|
columnAttr.getId(),
|
||||||
|
tableValue.listIndex,
|
||||||
|
tableValue.value);
|
||||||
|
|
||||||
|
this.configurationValueRecordMapper.insert(valueRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveAsComposite(final ConfigurationTableValues value) {
|
||||||
|
// TODO optimize with batching
|
||||||
|
for (final TableValue tableValue : value.values) {
|
||||||
|
|
||||||
|
final List<Long> valuePK = this.configurationValueRecordMapper.selectIdsByExample()
|
||||||
|
.where(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationId,
|
||||||
|
isEqualTo(value.configurationId))
|
||||||
|
.and(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId,
|
||||||
|
isEqualTo(tableValue.attributeId))
|
||||||
|
.and(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.listIndex,
|
||||||
|
isEqualTo(tableValue.listIndex))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (valuePK != null && valuePK.size() > 1) {
|
||||||
|
throw new IllegalStateException("Expected no more then one element");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valuePK == null || valuePK.isEmpty()) {
|
||||||
|
// insert
|
||||||
|
this.configurationValueRecordMapper.insert(
|
||||||
|
new ConfigurationValueRecord(
|
||||||
|
null,
|
||||||
|
value.institutionId,
|
||||||
|
value.configurationId,
|
||||||
|
tableValue.attributeId,
|
||||||
|
tableValue.listIndex,
|
||||||
|
tableValue.value));
|
||||||
|
} else {
|
||||||
|
// update
|
||||||
|
this.configurationValueRecordMapper.updateByPrimaryKey(
|
||||||
|
new ConfigurationValueRecord(
|
||||||
|
valuePK.iterator().next(),
|
||||||
|
value.institutionId,
|
||||||
|
value.configurationId,
|
||||||
|
tableValue.attributeId,
|
||||||
|
tableValue.listIndex,
|
||||||
|
tableValue.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Result<ConfigurationAttributeRecord> attributeRecord(final ConfigurationValue value) {
|
private Result<ConfigurationAttributeRecord> attributeRecord(final ConfigurationValue value) {
|
||||||
return attributeRecordById(value.attributeId);
|
return attributeRecordById(value.attributeId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,39 +16,28 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
public interface SebClientConfigService {
|
public interface SebClientConfigService {
|
||||||
|
|
||||||
static String SEB_CLIENT_CONFIG_EXAMPLE_XML =
|
static String SEB_CLIENT_CONFIG_EXAMPLE_XML =
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
|
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n"
|
||||||
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
|
|
||||||
+
|
+
|
||||||
"<plist version=\"1.0\">" +
|
"<plist version=\"1.0\">\r\n" +
|
||||||
"<dict>" +
|
" <dict>\r\n" +
|
||||||
"<key>sebMode</key>" +
|
" <key>sebMode</key>\r\n" +
|
||||||
"<integer>1</integer>" +
|
" <integer>1</integer>\r\n" +
|
||||||
"<key>sebServerFallback</key>" +
|
" <key>sebServerFallback</key>\r\n" +
|
||||||
"<true />" +
|
" <true />\r\n" +
|
||||||
"<key>sebServerURL</key>" +
|
" <key>sebServerURL</key>\r\n" +
|
||||||
"<string>%s</string>" +
|
" <string>%s</string>\r\n" +
|
||||||
"<key>sebServerConfiguration</key>" +
|
" <key>sebServerConfiguration</key>\r\n" +
|
||||||
"<array>" +
|
" <dict>\r\n" +
|
||||||
"<dict>" +
|
" <key>institution</key>\r\n" +
|
||||||
"<key>institution</key>" +
|
" <string>%s</string>\r\n" +
|
||||||
"<string>%s</string>" +
|
" <key>clientName</key>\r\n" +
|
||||||
"<key>clientName</key>" +
|
" <string>%s</string>\r\n" +
|
||||||
"<string>%s</string>" +
|
" <key>clientSecret</key>\r\n" +
|
||||||
"<key>clientSecret</key>" +
|
" <string>%s</string>\r\n" +
|
||||||
"<string>%s</string>" +
|
" <key>apiDiscovery</key>\r\n" +
|
||||||
"<key>accessTokenEndpoint</key>" +
|
" <string>%s</string>\r\n" +
|
||||||
"<string>%s</string>" +
|
" </dict>\r\n" +
|
||||||
"<key>handshakeEndpoint</key>" +
|
" </dict>\r\n" +
|
||||||
"<string>%s</string>" +
|
|
||||||
"<key>examConfigEndpoint</key>" +
|
|
||||||
"<string>%s</string>" +
|
|
||||||
"<key>pingEndpoint</key>" +
|
|
||||||
"<string>%s</string>" +
|
|
||||||
"<key>eventEndpoint</key>" +
|
|
||||||
"<string>%s</string>" +
|
|
||||||
"</dict>" +
|
|
||||||
"</array>" +
|
|
||||||
"</dict>" +
|
|
||||||
"</plist>";
|
"</plist>";
|
||||||
|
|
||||||
boolean hasSebClientConfigurationForInstitution(Long institutionId);
|
boolean hasSebClientConfigurationForInstitution(Long institutionId);
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
@ -54,7 +53,6 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
private final String httpScheme;
|
private final String httpScheme;
|
||||||
private final String serverAddress;
|
private final String serverAddress;
|
||||||
private final String serverPort;
|
private final String serverPort;
|
||||||
private final String sebClientAPIEndpoint;
|
|
||||||
|
|
||||||
protected SebClientConfigServiceImpl(
|
protected SebClientConfigServiceImpl(
|
||||||
final InstitutionDAO institutionDAO,
|
final InstitutionDAO institutionDAO,
|
||||||
|
@ -64,8 +62,7 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
final ZipService zipService,
|
final ZipService zipService,
|
||||||
@Value("${sebserver.webservice.http.scheme}") final String httpScheme,
|
@Value("${sebserver.webservice.http.scheme}") final String httpScheme,
|
||||||
@Value("${server.address}") final String serverAddress,
|
@Value("${server.address}") final String serverAddress,
|
||||||
@Value("${server.port}") final String serverPort,
|
@Value("${server.port}") final String serverPort) {
|
||||||
@Value("${sebserver.webservice.api.exam.endpoint}") final String sebClientAPIEndpoint) {
|
|
||||||
|
|
||||||
this.institutionDAO = institutionDAO;
|
this.institutionDAO = institutionDAO;
|
||||||
this.sebClientConfigDAO = sebClientConfigDAO;
|
this.sebClientConfigDAO = sebClientConfigDAO;
|
||||||
|
@ -75,7 +72,6 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
this.httpScheme = httpScheme;
|
this.httpScheme = httpScheme;
|
||||||
this.serverAddress = serverAddress;
|
this.serverAddress = serverAddress;
|
||||||
this.serverPort = serverPort;
|
this.serverPort = serverPort;
|
||||||
this.sebClientAPIEndpoint = sebClientAPIEndpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,11 +132,7 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
String.valueOf(config.institutionId),
|
String.valueOf(config.institutionId),
|
||||||
plainClientId,
|
plainClientId,
|
||||||
plainClientSecret,
|
plainClientSecret,
|
||||||
API.OAUTH_TOKEN_ENDPOINT,
|
"TODO:/exam-api/discovery");
|
||||||
this.sebClientAPIEndpoint + API.EXAM_API_HANDSHAKE_ENDPOINT,
|
|
||||||
this.sebClientAPIEndpoint + API.EXAM_API_CONFIGURATION_REQUEST_ENDPOINT,
|
|
||||||
this.sebClientAPIEndpoint + API.EXAM_API_PING_ENDPOINT,
|
|
||||||
this.sebClientAPIEndpoint + API.EXAM_API_EVENT_ENDPOINT);
|
|
||||||
|
|
||||||
PipedOutputStream pOut = null;
|
PipedOutputStream pOut = null;
|
||||||
PipedInputStream pIn = null;
|
PipedInputStream pIn = null;
|
||||||
|
|
|
@ -27,9 +27,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||||
|
@ -140,11 +140,16 @@ public class ExamAdministrationController extends ActivatableEntityController<Ex
|
||||||
Collections.reverse(exams);
|
Collections.reverse(exams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int start = (pageNum - 1) * pSize;
|
||||||
|
int end = start + pageSize;
|
||||||
|
if (exams.size() < end) {
|
||||||
|
end = exams.size();
|
||||||
|
}
|
||||||
return new Page<>(
|
return new Page<>(
|
||||||
exams.size() / pSize,
|
exams.size() / pSize,
|
||||||
pageNum,
|
pageNum,
|
||||||
sort,
|
sort,
|
||||||
exams.subList(pageNum * pSize, pageNum * pSize + pSize));
|
exams.subList(start, end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ server.servlet.context-path=/
|
||||||
|
|
||||||
spring.datasource.initialize=true
|
spring.datasource.initialize=true
|
||||||
spring.datasource.initialization-mode=always
|
spring.datasource.initialization-mode=always
|
||||||
spring.datasource.url=jdbc:mariadb://localhost:6603/SEBServer?useSSL=false&createDatabaseIfNotExist=true&default-character-set=utf8mb4
|
spring.datasource.url=jdbc:mariadb://localhost:6603/SEBServer?useSSL=false
|
||||||
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
||||||
spring.datasource.platform=dev
|
spring.datasource.platform=dev
|
||||||
spring.datasource.hikari.max-lifetime=600000
|
spring.datasource.hikari.max-lifetime=600000
|
||||||
|
|
|
@ -23,6 +23,7 @@ sebserver.overall.status.inactive=Inactive
|
||||||
|
|
||||||
sebserver.overall.action.add=Add;
|
sebserver.overall.action.add=Add;
|
||||||
sebserver.overall.action.remove=Remove
|
sebserver.overall.action.remove=Remove
|
||||||
|
sebserver.overall.action.select=Please Select
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# Form validation and messages
|
# Form validation and messages
|
||||||
|
@ -265,6 +266,7 @@ sebserver.exam.form.endtime=End Time
|
||||||
sebserver.exam.form.status=Status
|
sebserver.exam.form.status=Status
|
||||||
sebserver.exam.form.type=Exam Type
|
sebserver.exam.form.type=Exam Type
|
||||||
sebserver.exam.form.supporter=Exam Supporter
|
sebserver.exam.form.supporter=Exam Supporter
|
||||||
|
sebserver.exam.form.supporter.add=Add as supporter for this exam
|
||||||
|
|
||||||
sebserver.exam.type.UNDEFINED=Not Defined
|
sebserver.exam.type.UNDEFINED=Not Defined
|
||||||
sebserver.exam.type.MANAGED=Managed
|
sebserver.exam.type.MANAGED=Managed
|
||||||
|
@ -319,7 +321,9 @@ sebserver.exam.indicator.form.exam=Exam
|
||||||
sebserver.exam.indicator.form.name=Name
|
sebserver.exam.indicator.form.name=Name
|
||||||
sebserver.exam.indicator.form.type=Type
|
sebserver.exam.indicator.form.type=Type
|
||||||
sebserver.exam.indicator.form.color=Default Color
|
sebserver.exam.indicator.form.color=Default Color
|
||||||
|
sebserver.exam.indicator.form.color.action=Please select a color
|
||||||
sebserver.exam.indicator.form.thresholds=Thresholds
|
sebserver.exam.indicator.form.thresholds=Thresholds
|
||||||
|
sebserver.exam.indicator.thresholds.select.color=Please select a color
|
||||||
|
|
||||||
sebserver.exam.indicator.thresholds.list.title=Thresholds
|
sebserver.exam.indicator.thresholds.list.title=Thresholds
|
||||||
sebserver.exam.indicator.thresholds.list.value=Value
|
sebserver.exam.indicator.thresholds.list.value=Value
|
||||||
|
@ -570,7 +574,7 @@ sebserver.examconfig.props.label.allowSwitchToApplications=Allow switching to th
|
||||||
sebserver.examconfig.props.label.allowFlashFullscreen=Allow Flash to switch to fullscreen mode (Mac)
|
sebserver.examconfig.props.label.allowFlashFullscreen=Allow Flash to switch to fullscreen mode (Mac)
|
||||||
sebserver.examconfig.props.label.permittedProcesses.row.title=Permitted Processes
|
sebserver.examconfig.props.label.permittedProcesses.row.title=Permitted Processes
|
||||||
sebserver.examconfig.props.label.permittedProcesses=Permitted Processes
|
sebserver.examconfig.props.label.permittedProcesses=Permitted Processes
|
||||||
sebserver.examconfig.props.label.permittedProcesses.active=Activity
|
sebserver.examconfig.props.label.permittedProcesses.active=Active
|
||||||
sebserver.examconfig.props.label.permittedProcesses.os=OS
|
sebserver.examconfig.props.label.permittedProcesses.os=OS
|
||||||
sebserver.examconfig.props.label.permittedProcesses.os.0=Win
|
sebserver.examconfig.props.label.permittedProcesses.os.0=Win
|
||||||
sebserver.examconfig.props.label.permittedProcesses.os.1=OS X
|
sebserver.examconfig.props.label.permittedProcesses.os.1=OS X
|
||||||
|
@ -594,7 +598,7 @@ sebserver.examconfig.props.label.permittedProcesses.strongKill=Force quit (risk
|
||||||
|
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.row.title=Prohibited Processes
|
sebserver.examconfig.props.label.prohibitedProcesses.row.title=Prohibited Processes
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses=Prohibited Processes
|
sebserver.examconfig.props.label.prohibitedProcesses=Prohibited Processes
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.active=Activity
|
sebserver.examconfig.props.label.prohibitedProcesses.active=Active
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.os=OS
|
sebserver.examconfig.props.label.prohibitedProcesses.os=OS
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.os.0=Win
|
sebserver.examconfig.props.label.prohibitedProcesses.os.0=Win
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.os.1=OS X
|
sebserver.examconfig.props.label.prohibitedProcesses.os.1=OS X
|
||||||
|
@ -604,16 +608,80 @@ sebserver.examconfig.props.label.prohibitedProcesses.originalName=Original Name
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.identifier=Identifier
|
sebserver.examconfig.props.label.prohibitedProcesses.identifier=Identifier
|
||||||
sebserver.examconfig.props.label.prohibitedProcesses.strongKill=Force quit (risk of data loss)
|
sebserver.examconfig.props.label.prohibitedProcesses.strongKill=Force quit (risk of data loss)
|
||||||
|
|
||||||
|
sebserver.examconfig.props.group.urlFilter=Fitler
|
||||||
sebserver.examconfig.props.label.URLFilterEnable=Activate URL Filtering
|
sebserver.examconfig.props.label.URLFilterEnable=Activate URL Filtering
|
||||||
sebserver.examconfig.props.label.URLFilterEnableContentFilter=Filter also embedded content
|
sebserver.examconfig.props.label.URLFilterEnableContentFilter=Filter also embedded content
|
||||||
sebserver.examconfig.props.label.URLFilterRules=Filter
|
sebserver.examconfig.props.label.URLFilterRules=Filter
|
||||||
sebserver.examconfig.props.label.URLFilterRules.active=Activity
|
sebserver.examconfig.props.label.URLFilterRules.row.title=URL Filter
|
||||||
|
sebserver.examconfig.props.label.URLFilterRules.active=Active
|
||||||
sebserver.examconfig.props.label.URLFilterRules.regex=Regex
|
sebserver.examconfig.props.label.URLFilterRules.regex=Regex
|
||||||
sebserver.examconfig.props.label.URLFilterRules.expression=Expression
|
sebserver.examconfig.props.label.URLFilterRules.expression=Expression
|
||||||
sebserver.examconfig.props.label.URLFilterRules.action=Action
|
sebserver.examconfig.props.label.URLFilterRules.action=Action
|
||||||
sebserver.examconfig.props.label.URLFilterRules.action.0=Block
|
sebserver.examconfig.props.label.URLFilterRules.action.0=Block
|
||||||
sebserver.examconfig.props.label.URLFilterRules.action.1=Allow
|
sebserver.examconfig.props.label.URLFilterRules.action.1=Allow
|
||||||
|
|
||||||
|
sebserver.examconfig.props.group.proxies=Proxies
|
||||||
|
sebserver.examconfig.props.label.proxySettingsPolicy=proxy settings policy
|
||||||
|
sebserver.examconfig.props.label.proxySettingsPolicy.0=Use system proxy setting
|
||||||
|
sebserver.examconfig.props.label.proxySettingsPolicy.0.tooltip=System proxy settings of the exam client computer are used
|
||||||
|
sebserver.examconfig.props.label.proxySettingsPolicy.1=Use SEB proxy settings
|
||||||
|
sebserver.examconfig.props.label.proxySettingsPolicy.1.tooltip=Proxy settings provided in these SEB settings are used
|
||||||
|
sebserver.examconfig.props.label.proxies=Double-click a protocol to configure:
|
||||||
|
sebserver.examconfig.props.label.ExcludeSimpleHostnames=Exclude simple hostnames
|
||||||
|
sebserver.examconfig.props.label.ExceptionsList=Bypass proxy settings for these hosts and domains
|
||||||
|
sebserver.examconfig.props.label.ExceptionsList.tooltip=Separate hosts / domains with comma
|
||||||
|
sebserver.examconfig.props.label.FTPPassive=Use Passive FTP Mode (PASV)
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.proxies.active=Active
|
||||||
|
sebserver.examconfig.props.label.proxies.TABLE_ENTRY=Protocol
|
||||||
|
sebserver.examconfig.props.label.autoDiscovery=Auto Proxy Discovery
|
||||||
|
sebserver.examconfig.props.label.AutoDiscoveryEnabled=Auto discovery enabled
|
||||||
|
sebserver.examconfig.props.label.autoConfiguration=Automatic Proxy Configuration
|
||||||
|
sebserver.examconfig.props.label.AutoConfigurationEnabled=Auto configuration enabeld
|
||||||
|
sebserver.examconfig.props.label.AutoConfigurationURL=Proxy configuration file URL
|
||||||
|
sebserver.examconfig.props.label.AutoConfigurationJavaScript=Proxy configuration JavaScript
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.http=Web Proxy (HTTP)
|
||||||
|
sebserver.examconfig.props.label.HTTPEnable=Web proxy eneabled
|
||||||
|
sebserver.examconfig.props.label.HTTPProxy=Web proxy server
|
||||||
|
sebserver.examconfig.props.label.HTTPPort=Web proxy port
|
||||||
|
sebserver.examconfig.props.label.HTTPRequiresPassword=Proxy server requires password
|
||||||
|
sebserver.examconfig.props.label.HTTPUsername=Username
|
||||||
|
sebserver.examconfig.props.label.HTTPPassword=Password
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.https=Secure Web Proxy (HTTPS)
|
||||||
|
sebserver.examconfig.props.label.HTTPSEnable=Secure web proxy eneabled
|
||||||
|
sebserver.examconfig.props.label.HTTPSProxy=Secure web proxy server
|
||||||
|
sebserver.examconfig.props.label.HTTPSPort=Secure web proxy port
|
||||||
|
sebserver.examconfig.props.label.HTTPSRequiresPassword=Proxy server requires password
|
||||||
|
sebserver.examconfig.props.label.HTTPSUsername=Username
|
||||||
|
sebserver.examconfig.props.label.HTTPSPassword=Password
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.ftp=FTP Proxy
|
||||||
|
sebserver.examconfig.props.label.FTPEnable=FTP proxy eneabled
|
||||||
|
sebserver.examconfig.props.label.FTPProxy=FTP proxy server
|
||||||
|
sebserver.examconfig.props.label.FTPPort=FTP proxy port
|
||||||
|
sebserver.examconfig.props.label.FTPRequiresPassword=Proxy server requires password
|
||||||
|
sebserver.examconfig.props.label.FTPUsername=Username
|
||||||
|
sebserver.examconfig.props.label.FTPPassword=Password
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.socks=SOCKS Proxy
|
||||||
|
sebserver.examconfig.props.label.SOCKSEnable=SOCKS proxy eneabled
|
||||||
|
sebserver.examconfig.props.label.SOCKSProxy=SOCKS proxy server
|
||||||
|
sebserver.examconfig.props.label.SOCKSPort=SOCKS proxy port
|
||||||
|
sebserver.examconfig.props.label.SOCKSRequiresPassword=Proxy server requires password
|
||||||
|
sebserver.examconfig.props.label.SOCKSUsername=Username
|
||||||
|
sebserver.examconfig.props.label.SOCKSPassword=Password
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.rtsp=Streaming Proxy (RTSP)
|
||||||
|
sebserver.examconfig.props.label.RTSPEnable=RTSP proxy eneabled
|
||||||
|
sebserver.examconfig.props.label.RTSPProxy=RTSP proxy server
|
||||||
|
sebserver.examconfig.props.label.RTSPPort=RTSP proxy port
|
||||||
|
sebserver.examconfig.props.label.RTSPRequiresPassword=Proxy server requires password
|
||||||
|
sebserver.examconfig.props.label.RTSPUsername=Username
|
||||||
|
sebserver.examconfig.props.label.RTSPPassword=Password
|
||||||
|
|
||||||
|
|
||||||
sebserver.examconfig.props.group.servicePolicy=SEB Service policy
|
sebserver.examconfig.props.group.servicePolicy=SEB Service policy
|
||||||
sebserver.examconfig.props.label.sebServicePolicy.0=allow to run SEB without service
|
sebserver.examconfig.props.label.sebServicePolicy.0=allow to run SEB without service
|
||||||
sebserver.examconfig.props.label.sebServicePolicy.1=display warning when service is not running
|
sebserver.examconfig.props.label.sebServicePolicy.1=display warning when service is not running
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- MySQL Script generated by MySQL Workbench
|
-- MySQL Script generated by MySQL Workbench
|
||||||
-- Fri May 24 11:57:07 2019
|
-- Wed May 29 15:30:50 2019
|
||||||
-- Model: New Model Version: 1.0
|
-- Model: New Model Version: 1.0
|
||||||
-- MySQL Workbench Forward Engineering
|
-- MySQL Workbench Forward Engineering
|
||||||
|
|
||||||
|
@ -10,13 +10,20 @@ SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Schema SEBServer
|
-- Schema SEBServer
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
|
DROP SCHEMA IF EXISTS `SEBServer` ;
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `institution`
|
-- Schema SEBServer
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `institution` ;
|
CREATE SCHEMA IF NOT EXISTS `SEBServer` DEFAULT CHARACTER SET utf8mb4 ;
|
||||||
|
USE `SEBServer` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `institution` (
|
-- -----------------------------------------------------
|
||||||
|
-- Table `SEBServer`.`institution`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
DROP TABLE IF EXISTS `SEBServer`.`institution` ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`institution` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`name` VARCHAR(255) NOT NULL,
|
`name` VARCHAR(255) NOT NULL,
|
||||||
`url_suffix` VARCHAR(45) NULL,
|
`url_suffix` VARCHAR(45) NULL,
|
||||||
|
@ -29,11 +36,11 @@ CREATE TABLE IF NOT EXISTS `institution` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `lms_setup`
|
-- Table `SEBServer`.`lms_setup`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `lms_setup` ;
|
DROP TABLE IF EXISTS `SEBServer`.`lms_setup` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `lms_setup` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`lms_setup` (
|
||||||
`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,
|
||||||
`name` VARCHAR(255) NOT NULL,
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
@ -47,18 +54,18 @@ CREATE TABLE IF NOT EXISTS `lms_setup` (
|
||||||
INDEX `setupInstitutionRef_idx` (`institution_id` ASC),
|
INDEX `setupInstitutionRef_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `setupInstitutionRef`
|
CONSTRAINT `setupInstitutionRef`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `exam`
|
-- Table `SEBServer`.`exam`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `exam` ;
|
DROP TABLE IF EXISTS `SEBServer`.`exam` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `exam` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`exam` (
|
||||||
`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,
|
||||||
`lms_setup_id` BIGINT UNSIGNED NOT NULL,
|
`lms_setup_id` BIGINT UNSIGNED NOT NULL,
|
||||||
|
@ -74,23 +81,23 @@ CREATE TABLE IF NOT EXISTS `exam` (
|
||||||
INDEX `institution_key_idx` (`institution_id` ASC),
|
INDEX `institution_key_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `examLmsSetupRef`
|
CONSTRAINT `examLmsSetupRef`
|
||||||
FOREIGN KEY (`lms_setup_id`)
|
FOREIGN KEY (`lms_setup_id`)
|
||||||
REFERENCES `lms_setup` (`id`)
|
REFERENCES `SEBServer`.`lms_setup` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `examInstitutionRef`
|
CONSTRAINT `examInstitutionRef`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `client_connection`
|
-- Table `SEBServer`.`client_connection`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `client_connection` ;
|
DROP TABLE IF EXISTS `SEBServer`.`client_connection` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `client_connection` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`client_connection` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`exam_id` BIGINT UNSIGNED NULL,
|
`exam_id` BIGINT UNSIGNED NULL,
|
||||||
`status` VARCHAR(45) NOT NULL,
|
`status` VARCHAR(45) NOT NULL,
|
||||||
|
@ -103,18 +110,18 @@ CREATE TABLE IF NOT EXISTS `client_connection` (
|
||||||
INDEX `connection_exam_ref_idx` (`exam_id` ASC),
|
INDEX `connection_exam_ref_idx` (`exam_id` ASC),
|
||||||
CONSTRAINT `clientConnectionExamRef`
|
CONSTRAINT `clientConnectionExamRef`
|
||||||
FOREIGN KEY (`exam_id`)
|
FOREIGN KEY (`exam_id`)
|
||||||
REFERENCES `exam` (`id`)
|
REFERENCES `SEBServer`.`exam` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `client_event`
|
-- Table `SEBServer`.`client_event`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `client_event` ;
|
DROP TABLE IF EXISTS `SEBServer`.`client_event` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `client_event` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`client_event` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`connection_id` BIGINT UNSIGNED NOT NULL,
|
`connection_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`user_identifier` VARCHAR(255) NOT NULL,
|
`user_identifier` VARCHAR(255) NOT NULL,
|
||||||
|
@ -126,18 +133,18 @@ CREATE TABLE IF NOT EXISTS `client_event` (
|
||||||
INDEX `eventConnectionRef_idx` (`connection_id` ASC),
|
INDEX `eventConnectionRef_idx` (`connection_id` ASC),
|
||||||
CONSTRAINT `eventConnectionRef`
|
CONSTRAINT `eventConnectionRef`
|
||||||
FOREIGN KEY (`connection_id`)
|
FOREIGN KEY (`connection_id`)
|
||||||
REFERENCES `client_connection` (`id`)
|
REFERENCES `SEBServer`.`client_connection` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `indicator`
|
-- Table `SEBServer`.`indicator`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `indicator` ;
|
DROP TABLE IF EXISTS `SEBServer`.`indicator` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `indicator` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`indicator` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`exam_id` BIGINT UNSIGNED NOT NULL,
|
`exam_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`type` VARCHAR(45) NOT NULL,
|
`type` VARCHAR(45) NOT NULL,
|
||||||
|
@ -147,18 +154,18 @@ CREATE TABLE IF NOT EXISTS `indicator` (
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
CONSTRAINT `exam_ref`
|
CONSTRAINT `exam_ref`
|
||||||
FOREIGN KEY (`exam_id`)
|
FOREIGN KEY (`exam_id`)
|
||||||
REFERENCES `exam` (`id`)
|
REFERENCES `SEBServer`.`exam` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `configuration_node`
|
-- Table `SEBServer`.`configuration_node`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `configuration_node` ;
|
DROP TABLE IF EXISTS `SEBServer`.`configuration_node` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `configuration_node` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`configuration_node` (
|
||||||
`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,
|
||||||
`template_id` BIGINT UNSIGNED NULL,
|
`template_id` BIGINT UNSIGNED NULL,
|
||||||
|
@ -171,18 +178,18 @@ CREATE TABLE IF NOT EXISTS `configuration_node` (
|
||||||
INDEX `configurationInstitutionRef_idx` (`institution_id` ASC),
|
INDEX `configurationInstitutionRef_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `configurationInstitutionRef`
|
CONSTRAINT `configurationInstitutionRef`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `configuration`
|
-- Table `SEBServer`.`configuration`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `configuration` ;
|
DROP TABLE IF EXISTS `SEBServer`.`configuration` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `configuration` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`configuration` (
|
||||||
`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_node_id` BIGINT UNSIGNED NOT NULL,
|
`configuration_node_id` BIGINT UNSIGNED NOT NULL,
|
||||||
|
@ -194,23 +201,23 @@ CREATE TABLE IF NOT EXISTS `configuration` (
|
||||||
INDEX `config_institution_ref_idx` (`institution_id` ASC),
|
INDEX `config_institution_ref_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `configuration_node_ref`
|
CONSTRAINT `configuration_node_ref`
|
||||||
FOREIGN KEY (`configuration_node_id`)
|
FOREIGN KEY (`configuration_node_id`)
|
||||||
REFERENCES `configuration_node` (`id`)
|
REFERENCES `SEBServer`.`configuration_node` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `config_institution_ref`
|
CONSTRAINT `config_institution_ref`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `configuration_attribute`
|
-- Table `SEBServer`.`configuration_attribute`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `configuration_attribute` ;
|
DROP TABLE IF EXISTS `SEBServer`.`configuration_attribute` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `configuration_attribute` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`configuration_attribute` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`name` VARCHAR(45) NOT NULL,
|
`name` VARCHAR(45) NOT NULL,
|
||||||
`type` VARCHAR(45) NOT NULL,
|
`type` VARCHAR(45) NOT NULL,
|
||||||
|
@ -223,52 +230,53 @@ CREATE TABLE IF NOT EXISTS `configuration_attribute` (
|
||||||
INDEX `parent_ref_idx` (`parent_id` ASC),
|
INDEX `parent_ref_idx` (`parent_id` ASC),
|
||||||
CONSTRAINT `parent_ref`
|
CONSTRAINT `parent_ref`
|
||||||
FOREIGN KEY (`parent_id`)
|
FOREIGN KEY (`parent_id`)
|
||||||
REFERENCES `configuration_attribute` (`id`)
|
REFERENCES `SEBServer`.`configuration_attribute` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `configuration_value`
|
-- Table `SEBServer`.`configuration_value`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `configuration_value` ;
|
DROP TABLE IF EXISTS `SEBServer`.`configuration_value` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `configuration_value` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`configuration_value` (
|
||||||
`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_id` BIGINT UNSIGNED NOT NULL,
|
`configuration_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`configuration_attribute_id` BIGINT UNSIGNED NOT NULL,
|
`configuration_attribute_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`list_index` INT NOT NULL DEFAULT 0,
|
`list_index` INT NOT NULL DEFAULT 0,
|
||||||
`value` VARCHAR(20000) NULL,
|
`value` VARCHAR(16000) NULL,
|
||||||
|
`configuration_valuecol` VARCHAR(45) NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
INDEX `configuration_value_ref_idx` (`configuration_id` ASC),
|
INDEX `configuration_value_ref_idx` (`configuration_id` ASC),
|
||||||
INDEX `configuration_attribute_ref_idx` (`configuration_attribute_id` ASC),
|
INDEX `configuration_attribute_ref_idx` (`configuration_attribute_id` ASC),
|
||||||
INDEX `configuration_value_institution_ref_idx` (`institution_id` ASC),
|
INDEX `configuration_value_institution_ref_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `configuration_ref`
|
CONSTRAINT `configuration_ref`
|
||||||
FOREIGN KEY (`configuration_id`)
|
FOREIGN KEY (`configuration_id`)
|
||||||
REFERENCES `configuration` (`id`)
|
REFERENCES `SEBServer`.`configuration` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `configuration_value_attribute_ref`
|
CONSTRAINT `configuration_value_attribute_ref`
|
||||||
FOREIGN KEY (`configuration_attribute_id`)
|
FOREIGN KEY (`configuration_attribute_id`)
|
||||||
REFERENCES `configuration_attribute` (`id`)
|
REFERENCES `SEBServer`.`configuration_attribute` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `configuration_value_institution_ref`
|
CONSTRAINT `configuration_value_institution_ref`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `view`
|
-- Table `SEBServer`.`view`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `view` ;
|
DROP TABLE IF EXISTS `SEBServer`.`view` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `view` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`view` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`name` VARCHAR(255) NULL,
|
`name` VARCHAR(255) NULL,
|
||||||
`columns` INT NOT NULL,
|
`columns` INT NOT NULL,
|
||||||
|
@ -278,11 +286,11 @@ CREATE TABLE IF NOT EXISTS `view` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `orientation`
|
-- Table `SEBServer`.`orientation`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `orientation` ;
|
DROP TABLE IF EXISTS `SEBServer`.`orientation` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `orientation` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`orientation` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`config_attribute_id` BIGINT UNSIGNED NOT NULL,
|
`config_attribute_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`template_id` BIGINT UNSIGNED NULL,
|
`template_id` BIGINT UNSIGNED NULL,
|
||||||
|
@ -298,23 +306,23 @@ CREATE TABLE IF NOT EXISTS `orientation` (
|
||||||
INDEX `orientation_view_ref_idx` (`view_id` ASC),
|
INDEX `orientation_view_ref_idx` (`view_id` ASC),
|
||||||
CONSTRAINT `config_attribute_orientation_ref`
|
CONSTRAINT `config_attribute_orientation_ref`
|
||||||
FOREIGN KEY (`config_attribute_id`)
|
FOREIGN KEY (`config_attribute_id`)
|
||||||
REFERENCES `configuration_attribute` (`id`)
|
REFERENCES `SEBServer`.`configuration_attribute` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `orientation_view_ref`
|
CONSTRAINT `orientation_view_ref`
|
||||||
FOREIGN KEY (`view_id`)
|
FOREIGN KEY (`view_id`)
|
||||||
REFERENCES `view` (`id`)
|
REFERENCES `SEBServer`.`view` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `exam_configuration_map`
|
-- Table `SEBServer`.`exam_configuration_map`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `exam_configuration_map` ;
|
DROP TABLE IF EXISTS `SEBServer`.`exam_configuration_map` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `exam_configuration_map` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`exam_configuration_map` (
|
||||||
`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,
|
||||||
`exam_id` BIGINT UNSIGNED NOT NULL,
|
`exam_id` BIGINT UNSIGNED NOT NULL,
|
||||||
|
@ -327,28 +335,28 @@ CREATE TABLE IF NOT EXISTS `exam_configuration_map` (
|
||||||
INDEX `exam_config_institution_ref_idx` (`institution_id` ASC),
|
INDEX `exam_config_institution_ref_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `exam_map_ref`
|
CONSTRAINT `exam_map_ref`
|
||||||
FOREIGN KEY (`exam_id`)
|
FOREIGN KEY (`exam_id`)
|
||||||
REFERENCES `exam` (`id`)
|
REFERENCES `SEBServer`.`exam` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `configuration_map_ref`
|
CONSTRAINT `configuration_map_ref`
|
||||||
FOREIGN KEY (`configuration_node_id`)
|
FOREIGN KEY (`configuration_node_id`)
|
||||||
REFERENCES `configuration_node` (`id`)
|
REFERENCES `SEBServer`.`configuration_node` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
CONSTRAINT `exam_config_institution_ref`
|
CONSTRAINT `exam_config_institution_ref`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `user`
|
-- Table `SEBServer`.`user`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `user` ;
|
DROP TABLE IF EXISTS `SEBServer`.`user` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `user` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`user` (
|
||||||
`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,
|
||||||
`uuid` VARCHAR(255) NOT NULL,
|
`uuid` VARCHAR(255) NOT NULL,
|
||||||
|
@ -363,18 +371,18 @@ CREATE TABLE IF NOT EXISTS `user` (
|
||||||
INDEX `institutionRef_idx` (`institution_id` ASC),
|
INDEX `institutionRef_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `userInstitutionRef`
|
CONSTRAINT `userInstitutionRef`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `user_role`
|
-- Table `SEBServer`.`user_role`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `user_role` ;
|
DROP TABLE IF EXISTS `SEBServer`.`user_role` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `user_role` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`user_role` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`user_id` BIGINT UNSIGNED NOT NULL,
|
`user_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`role_name` VARCHAR(45) NOT NULL,
|
`role_name` VARCHAR(45) NOT NULL,
|
||||||
|
@ -382,18 +390,18 @@ CREATE TABLE IF NOT EXISTS `user_role` (
|
||||||
INDEX `user_ref_idx` (`user_id` ASC),
|
INDEX `user_ref_idx` (`user_id` ASC),
|
||||||
CONSTRAINT `user_ref`
|
CONSTRAINT `user_ref`
|
||||||
FOREIGN KEY (`user_id`)
|
FOREIGN KEY (`user_id`)
|
||||||
REFERENCES `user` (`id`)
|
REFERENCES `SEBServer`.`user` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `oauth_access_token`
|
-- Table `SEBServer`.`oauth_access_token`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `oauth_access_token` ;
|
DROP TABLE IF EXISTS `SEBServer`.`oauth_access_token` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `oauth_access_token` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`oauth_access_token` (
|
||||||
`token_id` VARCHAR(255) NULL,
|
`token_id` VARCHAR(255) NULL,
|
||||||
`token` BLOB NULL,
|
`token` BLOB NULL,
|
||||||
`authentication_id` VARCHAR(255) NULL,
|
`authentication_id` VARCHAR(255) NULL,
|
||||||
|
@ -405,11 +413,11 @@ CREATE TABLE IF NOT EXISTS `oauth_access_token` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `oauth_refresh_token`
|
-- Table `SEBServer`.`oauth_refresh_token`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `oauth_refresh_token` ;
|
DROP TABLE IF EXISTS `SEBServer`.`oauth_refresh_token` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `oauth_refresh_token` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`oauth_refresh_token` (
|
||||||
`token_id` VARCHAR(255) NULL,
|
`token_id` VARCHAR(255) NULL,
|
||||||
`token` BLOB NULL,
|
`token` BLOB NULL,
|
||||||
`authentication` BLOB NULL)
|
`authentication` BLOB NULL)
|
||||||
|
@ -417,11 +425,11 @@ CREATE TABLE IF NOT EXISTS `oauth_refresh_token` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `threshold`
|
-- Table `SEBServer`.`threshold`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `threshold` ;
|
DROP TABLE IF EXISTS `SEBServer`.`threshold` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `threshold` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`threshold` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`indicator_id` BIGINT UNSIGNED NOT NULL,
|
`indicator_id` BIGINT UNSIGNED NOT NULL,
|
||||||
`value` DECIMAL(10,4) NOT NULL,
|
`value` DECIMAL(10,4) NOT NULL,
|
||||||
|
@ -430,18 +438,18 @@ CREATE TABLE IF NOT EXISTS `threshold` (
|
||||||
INDEX `indicator_threshold_id_idx` (`indicator_id` ASC),
|
INDEX `indicator_threshold_id_idx` (`indicator_id` ASC),
|
||||||
CONSTRAINT `indicator_threshold_id`
|
CONSTRAINT `indicator_threshold_id`
|
||||||
FOREIGN KEY (`indicator_id`)
|
FOREIGN KEY (`indicator_id`)
|
||||||
REFERENCES `indicator` (`id`)
|
REFERENCES `SEBServer`.`indicator` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `user_activity_log`
|
-- Table `SEBServer`.`user_activity_log`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `user_activity_log` ;
|
DROP TABLE IF EXISTS `SEBServer`.`user_activity_log` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `user_activity_log` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`user_activity_log` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`user_uuid` VARCHAR(255) NOT NULL,
|
`user_uuid` VARCHAR(255) NOT NULL,
|
||||||
`timestamp` BIGINT NOT NULL,
|
`timestamp` BIGINT NOT NULL,
|
||||||
|
@ -454,11 +462,11 @@ CREATE TABLE IF NOT EXISTS `user_activity_log` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `additional_attributes`
|
-- Table `SEBServer`.`additional_attributes`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `additional_attributes` ;
|
DROP TABLE IF EXISTS `SEBServer`.`additional_attributes` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `additional_attributes` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`additional_attributes` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL,
|
`id` BIGINT UNSIGNED NOT NULL,
|
||||||
`entity_type` VARCHAR(45) NOT NULL,
|
`entity_type` VARCHAR(45) NOT NULL,
|
||||||
`entity_id` BIGINT UNSIGNED NOT NULL,
|
`entity_id` BIGINT UNSIGNED NOT NULL,
|
||||||
|
@ -469,11 +477,11 @@ CREATE TABLE IF NOT EXISTS `additional_attributes` (
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `seb_client_configuration`
|
-- Table `SEBServer`.`seb_client_configuration`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `seb_client_configuration` ;
|
DROP TABLE IF EXISTS `SEBServer`.`seb_client_configuration` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `seb_client_configuration` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`seb_client_configuration` (
|
||||||
`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,
|
||||||
`name` VARCHAR(255) NOT NULL,
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
@ -486,18 +494,18 @@ CREATE TABLE IF NOT EXISTS `seb_client_configuration` (
|
||||||
INDEX `sebClientCredentialsInstitutionRef_idx` (`institution_id` ASC),
|
INDEX `sebClientCredentialsInstitutionRef_idx` (`institution_id` ASC),
|
||||||
CONSTRAINT `sebClientConfigInstitutionRef`
|
CONSTRAINT `sebClientConfigInstitutionRef`
|
||||||
FOREIGN KEY (`institution_id`)
|
FOREIGN KEY (`institution_id`)
|
||||||
REFERENCES `institution` (`id`)
|
REFERENCES `SEBServer`.`institution` (`id`)
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
-- Table `webservice_server_info`
|
-- Table `SEBServer`.`webservice_server_info`
|
||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `webservice_server_info` ;
|
DROP TABLE IF EXISTS `SEBServer`.`webservice_server_info` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `webservice_server_info` (
|
CREATE TABLE IF NOT EXISTS `SEBServer`.`webservice_server_info` (
|
||||||
`id` BIGINT UNSIGNED NOT NULL,
|
`id` BIGINT UNSIGNED NOT NULL,
|
||||||
`uuid` VARCHAR(255) NOT NULL,
|
`uuid` VARCHAR(255) NOT NULL,
|
||||||
`service_address` VARCHAR(255) NOT NULL,
|
`service_address` VARCHAR(255) NOT NULL,
|
||||||
|
|
|
@ -233,7 +233,7 @@ Text.error {
|
||||||
|
|
||||||
Text[MULTI] {
|
Text[MULTI] {
|
||||||
padding: 5px 10px 5px 10px;
|
padding: 5px 10px 5px 10px;
|
||||||
height: 50px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
Text[BORDER], Text[MULTI][BORDER] {
|
Text[BORDER], Text[MULTI][BORDER] {
|
||||||
|
@ -250,6 +250,7 @@ Text[BORDER]:focused, Text[MULTI][BORDER]:focused {
|
||||||
Text[BORDER]:disabled, Text[MULTI][BORDER]:disabled, Text[BORDER]:read-only,
|
Text[BORDER]:disabled, Text[MULTI][BORDER]:disabled, Text[BORDER]:read-only,
|
||||||
Text[MULTI][BORDER]:read-only {
|
Text[MULTI][BORDER]:read-only {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
color: #CFCFCF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue