SEBSERV-45 finished rest of views with some missing attributes so far
This commit is contained in:
parent
fc07b5b80c
commit
eaf34ebeed
27 changed files with 480 additions and 112 deletions
|
@ -67,6 +67,7 @@ public final class API {
|
|||
public static final String CONFIGURATION_FOLLOWUP_PATH_SEGMENT = "/followup";
|
||||
public static final String CONFIGURATION_ENDPOINT = "/configuration";
|
||||
public static final String CONFIGURATION_SAVE_TO_HISTORY_PATH_SEGMENT = "/save_to_history";
|
||||
public static final String CONFIGURATION_UNDO_PATH_SEGMENT = "/undo";
|
||||
public static final String CONFIGURATION_RESTORE_FROM_HISTORY_PATH_SEGMENT = "/restore";
|
||||
|
||||
public static final String CONFIGURATION_VALUE_ENDPOINT = "/configuration_value";
|
||||
|
|
|
@ -23,12 +23,14 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||
|
@ -39,7 +41,10 @@ import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigHistory;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SebExamConfigUndo;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
@Lazy
|
||||
|
@ -50,7 +55,10 @@ public class SebExamConfigForm implements TemplateComposer {
|
|||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigForm.class);
|
||||
|
||||
private static final String VIEW_TEXT_KEY_PREFIX = "sebserver.examconfig.props.form.views.";
|
||||
private static final String VIEW_TOOLTIP_TEXT_KEY_SUFFIX = ".tooltip";
|
||||
private static final String KEY_SAVE_TO_HISTORY_SUCCESS =
|
||||
"sebserver.examconfig.action.saveToHistory.success";
|
||||
private static final String KEY_UNDO_SUCCESS =
|
||||
"sebserver.examconfig.action.undo.success";
|
||||
|
||||
private static final LocTextKey TITLE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.examconfig.props.from.title");
|
||||
|
@ -77,7 +85,6 @@ public class SebExamConfigForm implements TemplateComposer {
|
|||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||
|
||||
final EntityKey entityKey = pageContext.getEntityKey();
|
||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||
|
||||
final Composite content = widgetFactory.defaultPageLayout(
|
||||
pageContext.getParent(),
|
||||
|
@ -131,6 +138,36 @@ public class SebExamConfigForm implements TemplateComposer {
|
|||
|
||||
this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts);
|
||||
|
||||
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys())
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE_TO_HISTORY)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(action -> {
|
||||
this.restService.getBuilder(SaveExamConfigHistory.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
||||
.call()
|
||||
.onError(pageContext::notifyError)
|
||||
.getOrThrow();
|
||||
return action;
|
||||
})
|
||||
.withSuccess(KEY_SAVE_TO_HISTORY_SUCCESS)
|
||||
.publishIf(() -> examConfigGrant.iw())
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_UNDO)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(action -> {
|
||||
this.restService.getBuilder(SebExamConfigUndo.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
||||
.call()
|
||||
.onError(pageContext::notifyError)
|
||||
.getOrThrow();
|
||||
return action;
|
||||
})
|
||||
.withSuccess(KEY_UNDO_SUCCESS)
|
||||
.publishIf(() -> examConfigGrant.iw())
|
||||
|
||||
;
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
|
||||
pageContext.notifyError(e);
|
||||
|
|
|
@ -345,6 +345,17 @@ public enum ActionDefinition {
|
|||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||
|
||||
SEB_EXAM_CONFIG_SAVE_TO_HISTORY(
|
||||
new LocTextKey("sebserver.examconfig.action.saveToHistory"),
|
||||
ImageIcon.SAVE,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||
SEB_EXAM_CONFIG_UNDO(
|
||||
new LocTextKey("sebserver.examconfig.action.undo"),
|
||||
ImageIcon.SAVE,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||
|
||||
;
|
||||
|
||||
public final LocTextKey title;
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||
|
||||
import static ch.ethz.seb.sebserver.gui.service.examconfig.impl.CellFieldBuilderAdapter.dummyBuilderAdapter;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
|
@ -28,23 +26,20 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|||
|
||||
interface CellFieldBuilderAdapter {
|
||||
|
||||
static CellFieldBuilderAdapter DUMMY_BUILDER_ADAPTER = new CellFieldBuilderAdapter() {
|
||||
@Override
|
||||
public void createCell(final ViewGridBuilder builder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[DUMMY]";
|
||||
}
|
||||
};
|
||||
|
||||
void createCell(ViewGridBuilder builder);
|
||||
|
||||
default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||
|
||||
}
|
||||
|
||||
static CellFieldBuilderAdapter dummyBuilderAdapter() {
|
||||
return new CellFieldBuilderAdapter() {
|
||||
@Override
|
||||
public void createCell(final ViewGridBuilder builder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[DUMMY]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static CellFieldBuilderAdapter fieldBuilderAdapter(
|
||||
|
@ -127,7 +122,7 @@ interface CellFieldBuilderAdapter {
|
|||
int xpos = x - 1;
|
||||
while (xpos >= 0 && grid[y][xpos] == null && span < orientation.width) {
|
||||
grid[y][xpos] = this;
|
||||
grid[y][xpos + 1] = dummyBuilderAdapter();
|
||||
grid[y][xpos + 1] = DUMMY_BUILDER_ADAPTER;
|
||||
this.span++;
|
||||
xpos--;
|
||||
}
|
||||
|
@ -198,13 +193,20 @@ interface CellFieldBuilderAdapter {
|
|||
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
||||
final Orientation o = this.orientationsOfGroup.stream().findFirst().get();
|
||||
final LocTextKey groupLabelKey = new LocTextKey(
|
||||
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX + o.groupId,
|
||||
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
||||
o.groupId,
|
||||
o.groupId);
|
||||
final LocTextKey groupTooltipKey = new LocTextKey(
|
||||
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
||||
o.groupId +
|
||||
ExamConfigurationService.TOOL_TIP_SUFFIX,
|
||||
o.groupId);
|
||||
|
||||
final Group group = widgetFactory.groupLocalized(
|
||||
builder.parent,
|
||||
this.width,
|
||||
groupLabelKey);
|
||||
groupLabelKey,
|
||||
groupTooltipKey);
|
||||
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, this.width, this.height));
|
||||
|
||||
final ViewGridBuilder groupBuilder = new ViewGridBuilder(
|
||||
|
|
|
@ -20,7 +20,6 @@ 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.InputField;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
import ch.ethz.seb.sebserver.gui.widget.MultiSelectionCheckbox;
|
||||
import ch.ethz.seb.sebserver.gui.widget.Selection;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
@ -50,7 +49,6 @@ public class MultiCheckboxSelection extends SelectionFieldBuilder implements Inp
|
|||
final ConfigurationAttribute attribute,
|
||||
final ViewContext viewContext) {
|
||||
|
||||
final I18nSupport i18nSupport = this.widgetFactory.getI18nSupport();
|
||||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
|
|
|
@ -21,7 +21,6 @@ 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.InputField;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
import ch.ethz.seb.sebserver.gui.widget.RadioSelection;
|
||||
import ch.ethz.seb.sebserver.gui.widget.Selection;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
@ -52,7 +51,6 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements
|
|||
final ConfigurationAttribute attribute,
|
||||
final ViewContext viewContext) {
|
||||
|
||||
final I18nSupport i18nSupport = this.widgetFactory.getI18nSupport();
|
||||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
|
|
|
@ -24,6 +24,7 @@ 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.ConfigurationTableValues.TableValue;
|
||||
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.InputFieldBuilder;
|
||||
|
@ -191,12 +192,10 @@ public class TableContext {
|
|||
switch (attribute.type) {
|
||||
case CHECKBOX: {
|
||||
return BooleanUtils.toBoolean(tableValue.value)
|
||||
? "Active"
|
||||
: "Inactive";
|
||||
? this.viewContext.i18nSupport.getText(ResourceService.ACTIVE_TEXT_KEY)
|
||||
: this.viewContext.i18nSupport.getText(ResourceService.INACTIVE_TEXT_KEY);
|
||||
}
|
||||
case SINGLE_SELECTION: {
|
||||
final ConfigurationAttribute tableAttr =
|
||||
this.viewContext.attributeMapping.getAttribute(attribute.parentId);
|
||||
final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||
attribute.getName() + "." +
|
||||
tableValue.value;
|
||||
|
|
|
@ -278,7 +278,7 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
}
|
||||
|
||||
private void addTableRow(final Map<Long, TableValue> rowValues) {
|
||||
final TableItem tableItem = new TableItem(this.control, SWT.NONE);
|
||||
new TableItem(this.control, SWT.NONE);
|
||||
applyTableRowValues(this.values.size() - 1);
|
||||
|
||||
// TODO try to add delete button within table row?
|
||||
|
|
|
@ -83,10 +83,10 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
|||
final Composite parent,
|
||||
final ConfigurationAttribute attribute) {
|
||||
|
||||
// if (attribute.type == AttributeType.TABLE) {
|
||||
// throw new UnsupportedOperationException(
|
||||
// "Table type is currently not supported within a table row form view!");
|
||||
// }
|
||||
if (attribute.type == AttributeType.TABLE) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Table type is currently not supported within a table row form view!");
|
||||
}
|
||||
|
||||
final Orientation orientation = this.tableContext
|
||||
.getOrientation(attribute.id);
|
||||
|
|
|
@ -161,8 +161,8 @@ public class ViewGridBuilder {
|
|||
}
|
||||
|
||||
void compose() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Compose grid view: \n" + gridToString());
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Compose grid view: \n" + gridToString());
|
||||
}
|
||||
|
||||
// balance grid (optimize span and grab empty spaces for labels where applicable)
|
||||
|
@ -181,7 +181,7 @@ public class ViewGridBuilder {
|
|||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||
gridData.verticalIndent = 8;
|
||||
empty.setLayoutData(gridData);
|
||||
empty.setText("" /* "empty " + x + " " + y */);
|
||||
empty.setText(StringUtils.EMPTY /* "empty " + x + " " + y */);
|
||||
} else {
|
||||
this.grid[y][x].createCell(this);
|
||||
}
|
||||
|
@ -194,7 +194,11 @@ public class ViewGridBuilder {
|
|||
final int upperBoundY = y + height;
|
||||
for (int _y = y; _y < upperBoundY; _y++) {
|
||||
for (int _x = x; _x < upperBoundX; _x++) {
|
||||
this.grid[_y][_x] = CellFieldBuilderAdapter.dummyBuilderAdapter();
|
||||
if (_y < 0 || _x < 0 || _y >= this.grid.length || _x >= this.grid[_y].length) {
|
||||
log.warn("Out of bounds: {} {}", _x, _y);
|
||||
continue;
|
||||
}
|
||||
this.grid[_y][_x] = CellFieldBuilderAdapter.DUMMY_BUILDER_ADAPTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,15 @@ public interface I18nSupport {
|
|||
* @return date/time column title suffix for current user */
|
||||
String getUsersTimeZoneTitleSuffix();
|
||||
|
||||
/** Get localized text of specified key for currently set Locale.
|
||||
*
|
||||
* @param key LocTextKey instance
|
||||
* @param def default text
|
||||
* @return the text in current language parsed from localized text */
|
||||
default String getText(final LocTextKey key, final String def) {
|
||||
return getText(key.name, def, key.args);
|
||||
}
|
||||
|
||||
/** Get localized text of specified key for currently set Locale.
|
||||
*
|
||||
* @param key LocTextKey instance
|
||||
|
|
|
@ -31,6 +31,8 @@ public final class PageAction {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger(PageAction.class);
|
||||
|
||||
public static final LocTextKey SUCCESS_MSG_TITLE = new LocTextKey("sebserver.page.message");
|
||||
|
||||
public final ActionDefinition definition;
|
||||
private final Supplier<LocTextKey> confirm;
|
||||
final LocTextKey successMessage;
|
||||
|
@ -126,7 +128,11 @@ public final class PageAction {
|
|||
private Result<PageAction> exec() {
|
||||
try {
|
||||
|
||||
return Result.of(this.exec.apply(this));
|
||||
final PageAction apply = this.exec.apply(this);
|
||||
if (this.successMessage != null) {
|
||||
apply.pageContext.publishPageMessage(SUCCESS_MSG_TITLE, this.successMessage);
|
||||
}
|
||||
return Result.of(apply);
|
||||
|
||||
} catch (final PageMessageException pme) {
|
||||
PageAction.this.pageContext.publishPageMessage(pme);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class SaveExamConfigHistory extends RestCall<Configuration> {
|
||||
|
||||
protected SaveExamConfigHistory() {
|
||||
super(new TypeKey<>(
|
||||
CallType.SAVE,
|
||||
EntityType.CONFIGURATION,
|
||||
new TypeReference<Configuration>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CONFIGURATION_ENDPOINT +
|
||||
API.CONFIGURATION_SAVE_TO_HISTORY_PATH_SEGMENT +
|
||||
API.MODEL_ID_VAR_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class SebExamConfigUndo extends RestCall<Configuration> {
|
||||
|
||||
protected SebExamConfigUndo() {
|
||||
super(new TypeKey<>(
|
||||
CallType.SAVE,
|
||||
EntityType.CONFIGURATION,
|
||||
new TypeReference<Configuration>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CONFIGURATION_ENDPOINT +
|
||||
API.CONFIGURATION_UNDO_PATH_SEGMENT +
|
||||
API.MODEL_ID_VAR_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -60,7 +60,6 @@ public class EntityTable<ROW extends Entity> {
|
|||
final I18nSupport i18nSupport;
|
||||
|
||||
final List<ColumnDefinition<ROW>> columns;
|
||||
final List<TableRowAction> actions;
|
||||
final LocTextKey emptyMessage;
|
||||
|
||||
final Composite composite;
|
||||
|
@ -82,7 +81,6 @@ public class EntityTable<ROW extends Entity> {
|
|||
final Function<RestCall<Page<ROW>>.RestCallBuilder, RestCall<Page<ROW>>.RestCallBuilder> restCallAdapter,
|
||||
final PageService pageService,
|
||||
final List<ColumnDefinition<ROW>> columns,
|
||||
final List<TableRowAction> actions,
|
||||
final int pageSize,
|
||||
final LocTextKey emptyMessage,
|
||||
final Function<EntityTable<ROW>, PageAction> defaultActionFunction,
|
||||
|
@ -95,7 +93,6 @@ public class EntityTable<ROW extends Entity> {
|
|||
this.restCall = restCall;
|
||||
this.restCallAdapter = (restCallAdapter != null) ? restCallAdapter : Function.identity();
|
||||
this.columns = Utils.immutableListOf(columns);
|
||||
this.actions = Utils.immutableListOf(actions);
|
||||
this.emptyMessage = emptyMessage;
|
||||
this.hideNavigation = hideNavigation;
|
||||
|
||||
|
@ -324,9 +321,6 @@ public class EntityTable<ROW extends Entity> {
|
|||
setValueToCell(item, index, column.valueSupplier.apply(row));
|
||||
index++;
|
||||
}
|
||||
if (this.actions != null) {
|
||||
// TODO??
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
|
|
|
@ -29,13 +29,12 @@ public class TableBuilder<ROW extends Entity> {
|
|||
private final PageService pageService;
|
||||
final RestCall<Page<ROW>> restCall;
|
||||
final List<ColumnDefinition<ROW>> columns = new ArrayList<>();
|
||||
final List<TableRowAction> actions = new ArrayList<>();
|
||||
LocTextKey emptyMessage;
|
||||
private Function<EntityTable<ROW>, PageAction> defaultActionFunction;
|
||||
private int pageSize = -1;
|
||||
private int type = SWT.NONE;
|
||||
private boolean hideNavigation = false;
|
||||
private Function<RestCall<Page<ROW>>.RestCallBuilder, RestCall<Page<ROW>>.RestCallBuilder> restCallAdapter;;
|
||||
private Function<RestCall<Page<ROW>>.RestCallBuilder, RestCall<Page<ROW>>.RestCallBuilder> restCallAdapter;
|
||||
|
||||
public TableBuilder(
|
||||
final PageService pageService,
|
||||
|
@ -75,11 +74,6 @@ public class TableBuilder<ROW extends Entity> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TableBuilder<ROW> withAction(final TableRowAction action) {
|
||||
this.actions.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TableBuilder<ROW> withRestCallAdapter(
|
||||
final Function<RestCall<Page<ROW>>.RestCallBuilder, RestCall<Page<ROW>>.RestCallBuilder> adapter) {
|
||||
this.restCallAdapter = adapter;
|
||||
|
@ -120,7 +114,6 @@ public class TableBuilder<ROW extends Entity> {
|
|||
this.restCallAdapter,
|
||||
this.pageService,
|
||||
this.columns,
|
||||
this.actions,
|
||||
this.pageSize,
|
||||
this.emptyMessage,
|
||||
this.defaultActionFunction,
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* 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.table;
|
||||
|
||||
public class TableRowAction {
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ import java.util.Locale;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Device;
|
||||
|
@ -309,6 +310,15 @@ public class WidgetFactory {
|
|||
final int columns,
|
||||
final LocTextKey locTextKey) {
|
||||
|
||||
return groupLocalized(parent, columns, locTextKey, null);
|
||||
}
|
||||
|
||||
public Group groupLocalized(
|
||||
final Composite parent,
|
||||
final int columns,
|
||||
final LocTextKey locTextKey,
|
||||
final LocTextKey locTooltipKey) {
|
||||
|
||||
final Group group = new Group(parent, SWT.NONE);
|
||||
final GridLayout gridLayout = new GridLayout(columns, true);
|
||||
gridLayout.verticalSpacing = 0;
|
||||
|
@ -316,7 +326,7 @@ public class WidgetFactory {
|
|||
gridLayout.marginHeight = 0;
|
||||
group.setLayout(gridLayout);
|
||||
|
||||
this.injectI18n(group, locTextKey);
|
||||
this.injectI18n(group, locTextKey, locTooltipKey);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -521,8 +531,8 @@ public class WidgetFactory {
|
|||
labelFunction.accept(label);
|
||||
}
|
||||
|
||||
public void injectI18n(final Group group, final LocTextKey locTextKey) {
|
||||
final Consumer<Group> groupFunction = groupFunction(locTextKey, null, this.i18nSupport);
|
||||
public void injectI18n(final Group group, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||
final Consumer<Group> groupFunction = groupFunction(locTextKey, locTooltipKey, this.i18nSupport);
|
||||
group.setData(POLYGLOT_WIDGET_FUNCTION_KEY, groupFunction);
|
||||
groupFunction.accept(group);
|
||||
}
|
||||
|
@ -656,7 +666,7 @@ public class WidgetFactory {
|
|||
group.setText(i18nSupport.getText(locTextKey));
|
||||
}
|
||||
if (locToolTipKey != null) {
|
||||
group.setToolTipText(i18nSupport.getText(locToolTipKey));
|
||||
group.setToolTipText(i18nSupport.getText(locToolTipKey, StringUtils.EMPTY));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ public interface ConfigurationDAO extends EntityDAO<Configuration, Configuration
|
|||
* @return the new follow-up Configuration model */
|
||||
Result<Configuration> saveToHistory(Long configurationNodeId);
|
||||
|
||||
Result<Configuration> undo(Long configurationNodeId);
|
||||
|
||||
/** Restores the current follow-up Configuration to the values of a given Configuration
|
||||
* in the history of the specified ConfigurationNode.
|
||||
*
|
||||
|
|
|
@ -165,18 +165,7 @@ public class ConfigurationDAOImpl implements ConfigurationDAO {
|
|||
return Result.tryCatch(() -> {
|
||||
|
||||
// get follow-up configuration...
|
||||
final ConfigurationRecord followupConfig = this.configurationRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ConfigurationRecordDynamicSqlSupport.configurationNodeId,
|
||||
isEqualTo(configurationNodeId))
|
||||
.and(
|
||||
ConfigurationRecordDynamicSqlSupport.followup,
|
||||
isEqualTo(BooleanUtils.toInteger(true)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.collect(Utils.toSingleton());
|
||||
final ConfigurationRecord followupConfig = getFollowupConfigurationRecord(configurationNodeId);
|
||||
|
||||
// with actual attribute values
|
||||
final List<ConfigurationValueRecord> allValues = this.configurationValueRecordMapper
|
||||
|
@ -239,6 +228,41 @@ public class ConfigurationDAOImpl implements ConfigurationDAO {
|
|||
.onError(TransactionHandler::rollback);
|
||||
}
|
||||
|
||||
private ConfigurationRecord getFollowupConfigurationRecord(final Long configurationNodeId) {
|
||||
return this.configurationRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ConfigurationRecordDynamicSqlSupport.configurationNodeId,
|
||||
isEqualTo(configurationNodeId))
|
||||
.and(
|
||||
ConfigurationRecordDynamicSqlSupport.followup,
|
||||
isEqualTo(BooleanUtils.toInteger(true)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.collect(Utils.toSingleton());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<Configuration> undo(final Long configurationNodeId) {
|
||||
return Result.tryCatch(() -> {
|
||||
// get all configurations of the node
|
||||
final List<ConfigurationRecord> configs = this.configurationRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ConfigurationRecordDynamicSqlSupport.configurationNodeId,
|
||||
isEqualTo(configurationNodeId))
|
||||
.orderBy(ConfigurationRecordDynamicSqlSupport.versionDate)
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
return configs.get(configs.size() - 1);
|
||||
})
|
||||
.flatMap(rec -> restoreToVersion(configurationNodeId, rec.getId()))
|
||||
.onError(TransactionHandler::rollback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<Configuration> restoreToVersion(final Long configurationNodeId, final Long configId) {
|
||||
|
@ -268,28 +292,17 @@ public class ConfigurationDAOImpl implements ConfigurationDAO {
|
|||
.execute();
|
||||
|
||||
// get follow-up configuration id
|
||||
final ConfigurationRecord followup = this.configurationRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ConfigurationRecordDynamicSqlSupport.configurationNodeId,
|
||||
isEqualTo(configurationNodeId))
|
||||
.and(
|
||||
ConfigurationRecordDynamicSqlSupport.followup,
|
||||
isEqualTo(BooleanUtils.toInteger(true)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.collect(Utils.toSingleton());
|
||||
final ConfigurationRecord followup = getFollowupConfigurationRecord(configurationNodeId);
|
||||
|
||||
// restore all current values of the follow-up with historic values
|
||||
// TODO batch here for better performance
|
||||
historicValues.stream()
|
||||
.map(historicValRec -> new ConfigurationValueRecord(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
followup.getInstitutionId(),
|
||||
followup.getId(),
|
||||
historicValRec.getConfigurationAttributeId(),
|
||||
null,
|
||||
historicValRec.getListIndex(),
|
||||
historicValRec.getValue(),
|
||||
historicValRec.getText()))
|
||||
.forEach(newValRec -> this.configurationValueRecordMapper
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||
|
||||
|
@ -17,4 +19,8 @@ public interface SebExamConfigService {
|
|||
|
||||
void validate(ConfigurationTableValues tableValue);
|
||||
|
||||
void exportXML(OutputStream out, Long configurationNodeId);
|
||||
|
||||
void exportForExam(OutputStream out, Long configExamMappingId);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||
|
||||
public interface XMLValueConverter {
|
||||
|
||||
String name();
|
||||
|
||||
void convertToXML(
|
||||
OutputStream out,
|
||||
ConfigurationAttribute attribute,
|
||||
ConfigurationValue value);
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -22,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationValueValidator;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
|
@ -32,13 +34,16 @@ public class SebExamConfigServiceImpl implements SebExamConfigService {
|
|||
|
||||
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
||||
private final Collection<ConfigurationValueValidator> validators;
|
||||
private final Collection<XMLValueConverter> converters;
|
||||
|
||||
protected SebExamConfigServiceImpl(
|
||||
final ConfigurationAttributeDAO configurationAttributeDAO,
|
||||
final Collection<ConfigurationValueValidator> validators) {
|
||||
final Collection<ConfigurationValueValidator> validators,
|
||||
final Collection<XMLValueConverter> converters) {
|
||||
|
||||
this.configurationAttributeDAO = configurationAttributeDAO;
|
||||
this.validators = validators;
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,4 +70,16 @@ public class SebExamConfigServiceImpl implements SebExamConfigService {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportXML(final OutputStream out, final Long configurationNodeId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportForExam(final OutputStream out, final Long configExamMappingId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.converter;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@WebServiceProfile
|
||||
public class KioskModeConverter implements XMLValueConverter {
|
||||
|
||||
public static final String NAME = "KioskModeConverter";
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToXML(
|
||||
final OutputStream out,
|
||||
final ConfigurationAttribute attribute,
|
||||
final ConfigurationValue value) {
|
||||
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -64,24 +64,37 @@ public class ConfigurationController extends EntityController<Configuration, Con
|
|||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Configuration saveToHistory(@PathVariable final String configId) {
|
||||
public Configuration saveToHistory(@PathVariable final String modelId) {
|
||||
|
||||
return this.entityDAO.byModelId(configId)
|
||||
return this.entityDAO.byModelId(modelId)
|
||||
.flatMap(this::checkModifyAccess)
|
||||
.flatMap(config -> this.configurationDAO.saveToHistory(config.configurationNodeId))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.CONFIGURATION_UNDO_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT,
|
||||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Configuration undo(@PathVariable final String modelId) {
|
||||
|
||||
return this.entityDAO.byModelId(modelId)
|
||||
.flatMap(this::checkModifyAccess)
|
||||
.flatMap(config -> this.configurationDAO.undo(config.configurationNodeId))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.CONFIGURATION_RESTORE_FROM_HISTORY_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT,
|
||||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Configuration restoreFormHistory(
|
||||
@PathVariable final String configId,
|
||||
@PathVariable final String modelId,
|
||||
@RequestParam(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long configurationNodeId) {
|
||||
|
||||
return this.entityDAO.byModelId(configId)
|
||||
return this.entityDAO.byModelId(modelId)
|
||||
.flatMap(this::checkModifyAccess)
|
||||
.flatMap(config -> this.configurationDAO.restoreToVersion(configurationNodeId, config.getId()))
|
||||
.getOrThrow();
|
||||
|
|
|
@ -360,6 +360,10 @@ sebserver.examconfig.action.list.modify.properties=Edit Properties
|
|||
sebserver.examconfig.action.modify=Edit
|
||||
sebserver.examconfig.action.modify.properties=Edit Properties
|
||||
sebserver.examconfig.action.save=Save
|
||||
sebserver.examconfig.action.saveToHistory=Save In History
|
||||
sebserver.examconfig.action.saveToHistory.success=Successfully saved in history
|
||||
sebserver.examconfig.action.undo=Undo
|
||||
sebserver.examconfig.action.undo.success=Successfully reverted to last saved state
|
||||
|
||||
sebserver.examconfig.form.title.new=New Exam Configuration
|
||||
sebserver.examconfig.form.title=Exam Configuration
|
||||
|
@ -378,6 +382,11 @@ sebserver.examconfig.props.form.views.browser=Browser
|
|||
sebserver.examconfig.props.form.views.down_upload=Down/Uploads
|
||||
sebserver.examconfig.props.form.views.exam=Exam
|
||||
sebserver.examconfig.props.form.views.applications=Applications
|
||||
sebserver.examconfig.props.form.views.resources=Additional Resources
|
||||
sebserver.examconfig.props.form.views.network=Network
|
||||
sebserver.examconfig.props.form.views.security=Security
|
||||
sebserver.examconfig.props.form.views.registry=Registry
|
||||
sebserver.examconfig.props.form.views.hooked_keys=Hooked Keys
|
||||
|
||||
sebserver.examconfig.props.label.hashedAdminPassword=Administrator password
|
||||
sebserver.examconfig.props.label.hashedAdminPassword.confirm=Confirm password
|
||||
|
@ -570,6 +579,122 @@ sebserver.examconfig.props.label.prohibitedProcesses.originalName=Original Name
|
|||
sebserver.examconfig.props.label.prohibitedProcesses.identifier=Identifier
|
||||
sebserver.examconfig.props.label.prohibitedProcesses.strongKill=Force quit (risk of data loss)
|
||||
|
||||
sebserver.examconfig.props.label.URLFilterEnable=Activate URL Filtering
|
||||
sebserver.examconfig.props.label.URLFilterEnableContentFilter=Filter also embedded content
|
||||
sebserver.examconfig.props.label.URLFilterRules=Filter
|
||||
sebserver.examconfig.props.label.URLFilterRules.active=Activity
|
||||
sebserver.examconfig.props.label.URLFilterRules.regex=Regex
|
||||
sebserver.examconfig.props.label.URLFilterRules.expression=Expression
|
||||
sebserver.examconfig.props.label.URLFilterRules.action=Action
|
||||
sebserver.examconfig.props.label.URLFilterRules.action.0=Block
|
||||
sebserver.examconfig.props.label.URLFilterRules.action.1=Allow
|
||||
|
||||
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.1=display warning when service is not running
|
||||
sebserver.examconfig.props.label.sebServicePolicy.2=allow to use SEB only with service
|
||||
sebserver.examconfig.props.label.sebServicePolicy.tooltip=Policy that applies when an exam client doesn't have the SEB client running
|
||||
|
||||
sebserver.examconfig.props.group.kioskMode=Kiosk Mode
|
||||
sebserver.examconfig.props.label.kioskMode.tooltip=The kiosk mode setting reflects how the computer is locked down into SEB.
|
||||
sebserver.examconfig.props.label.kioskMode.0=Create new desktop
|
||||
sebserver.examconfig.props.label.kioskMode.0.tooltip=This kiosk mode may prevent specific third party software to run correctly together with SEB, like some screen recording software or the Windows onscreen keyboard.
|
||||
sebserver.examconfig.props.label.kioskMode.1=Disable explorer Shell
|
||||
sebserver.examconfig.props.label.kioskMode.1.tooltip=This kiosk mode is compatible with some screen recording/proctoring software and the Windows onscreen keyboard.
|
||||
sebserver.examconfig.props.label.kioskMode.2=None (for debugging only)
|
||||
sebserver.examconfig.props.label.kioskMode.2.tooltip=SEB runs without kiosk mode, switching to other applications is possible. Use this for debugging purposes only.
|
||||
|
||||
sebserver.examconfig.props.label.allowVirtualMachine=Allow to run inside virtual machine
|
||||
sebserver.examconfig.props.label.allowVirtualMachine.tooltip=Indicates if SEB is allowed to run in a virtual machine or not (in order to prevent potential manipulation).
|
||||
sebserver.examconfig.props.label.allowScreenSharing=Allow remote session/screen sharing
|
||||
sebserver.examconfig.props.label.allowScreenSharing.tootlip=Allows Windows remote sessions and macOS screen sharing to be used
|
||||
sebserver.examconfig.props.label.enablePrivateClipboard=Use private clipboard (Mac)
|
||||
sebserver.examconfig.props.label.enablePrivateClipboard.tooltip=Private clipboard should always be used beside when working with third party application in managed/virtual machine
|
||||
|
||||
sebserver.examconfig.props.group.logging=Logging
|
||||
sebserver.examconfig.props.label.enableLogging=Enable logging
|
||||
sebserver.examconfig.props.label.enableLogging.tooltip=The log can help debugging SEB (send it to the developers) and to find out about possible manipulations
|
||||
sebserver.examconfig.props.label.logDirectoryWin=Log file directory on Windows
|
||||
sebserver.examconfig.props.label.logDirectoryOSX=Log file directory on Mac
|
||||
|
||||
sebserver.examconfig.props.group.macSettings=macOS specific settings
|
||||
sebserver.examconfig.props.label.minMacOSVersion=Enforce minimal macOS version:
|
||||
sebserver.examconfig.props.label.minMacOSVersion.0=OS X 10.7 Lion
|
||||
sebserver.examconfig.props.label.minMacOSVersion.1=OS X 10.8 Mountain Lion
|
||||
sebserver.examconfig.props.label.minMacOSVersion.2=OS X 10.9 Mavericks
|
||||
sebserver.examconfig.props.label.minMacOSVersion.3=OS X 10.10 Yosemite
|
||||
sebserver.examconfig.props.label.minMacOSVersion.4=OS X 10.11 El Capitan
|
||||
sebserver.examconfig.props.label.minMacOSVersion.5=OS X 10.12 Sierra
|
||||
sebserver.examconfig.props.label.minMacOSVersion.6=OS X 10.13 Hight Sierra
|
||||
sebserver.examconfig.props.label.minMacOSVersion.7=OS X 10.14 Mojave
|
||||
sebserver.examconfig.props.label.enableAppSwitcherCheck=Disable app switcher when starting
|
||||
sebserver.examconfig.props.label.enableAppSwitcherCheck.tooltip=SEB checks for the command key being held down while SEB is starting up. This prevents using the application switcher to mess with SEB\'s kiosk mode
|
||||
sebserver.examconfig.props.label.forceAppFolderInstall=Force installation in Applications folder
|
||||
sebserver.examconfig.props.label.forceAppFolderInstall.tooltip=SEB enforces to be installed in an Applications folder (/Applications or ~/Applications)
|
||||
sebserver.examconfig.props.label.allowUserAppFolderInstall=Allow also user's ~/Applications folder
|
||||
sebserver.examconfig.props.label.allowUserAppFolderInstall.tooltip=SEB can also be installed in the Applications folder of the current user (~/Applications)
|
||||
sebserver.examconfig.props.label.allowSiri=Allow to use Siri
|
||||
sebserver.examconfig.props.label.allowSiri.tooltip=If enabled, Siri can be used by tapping th emenu bar icon, Touch Bar icon or shortcut set in System Preferences/Siri (default: hold command space). The Siri window won't be displayed though
|
||||
sebserver.examconfig.props.label.detectStoppedProcess=Detect when SEB process was stopped
|
||||
sebserver.examconfig.props.label.detectStoppedProcess.tooltip=SEB displays a lock screen (requiring to enter the quit/unlock password) if it detects its process was stopped, which can indicate manipulation
|
||||
sebserver.examconfig.props.label.allowDisplayMirroring=Allow display mirroring (affects also AirPlay Display)
|
||||
sebserver.examconfig.props.label.allowDisplayMirroring.tooltip=If not selected, SEB prevents to mirror the main display to another
|
||||
sebserver.examconfig.props.label.allowedDisplaysMaxNumber=Maximum allowed number of connected displays
|
||||
sebserver.examconfig.props.label.allowedDisplaysMaxNumber.tooltip=If more displays are connected, this are blanked with an orange full screen window
|
||||
sebserver.examconfig.props.label.allowedDisplayBuiltin=Use built-in display
|
||||
sebserver.examconfig.props.label.allowedDisplayBuiltin.tooltip=Use the built-in display (if available) when only one display is allowed or when switching off display mirroring
|
||||
|
||||
sebserver.examconfig.props.group.registry=While running SEB
|
||||
sebserver.examconfig.props.group.registry.tooltip=Options in the Windows Security Screen invoked by Ctrl-Alt-Del
|
||||
sebserver.examconfig.props.label.insideSebEnableSwitchUser=Enable Switch User
|
||||
sebserver.examconfig.props.label.insideSebEnableSwitchUser.tooltip=Activates the button "Switch User"
|
||||
sebserver.examconfig.props.label.insideSebEnableLockThisComputer=Enable Lock this computer
|
||||
sebserver.examconfig.props.label.insideSebEnableLockThisComputer.tooltip=Activates the button "Lock this computer"
|
||||
sebserver.examconfig.props.label.insideSebEnableChangeAPassword=Enable Change a password
|
||||
sebserver.examconfig.props.label.insideSebEnableChangeAPassword.tooltip=Activates the button "Change a password..."
|
||||
sebserver.examconfig.props.label.insideSebEnableStartTaskManager=Enable Start Task Manager
|
||||
sebserver.examconfig.props.label.insideSebEnableStartTaskManager.tooltip=Activates the button "Start Task Manager"
|
||||
sebserver.examconfig.props.label.insideSebEnableLogOff=Enable Log off
|
||||
sebserver.examconfig.props.label.insideSebEnableLogOff.tooltip=Activates the button "Log off"
|
||||
sebserver.examconfig.props.label.insideSebEnableShutDown=Enable Shut down
|
||||
sebserver.examconfig.props.label.insideSebEnableShutDown.tooltip=Activates the button "Shutdown"
|
||||
sebserver.examconfig.props.label.insideSebEnableEaseOfAccess=Enable Ease of Access
|
||||
sebserver.examconfig.props.label.insideSebEnableEaseOfAccess.tooltip=Shows options when the button "Ease of Access" in the lower left corner is clicked,\nwhich offers help e.g. to visually or aurally handicapped persons, like the Magnifier Glass.
|
||||
sebserver.examconfig.props.label.insideSebEnableVmWareClientShade=Enable VMware Client Shade
|
||||
sebserver.examconfig.props.label.insideSebEnableVmWareClientShade.tooltip=Activates the "Shade" bar at the upper edge of a virtual desktop, if existent. If you're not using VMware, this setting doesn't have any effect.
|
||||
sebserver.examconfig.props.label.insideSebEnableNetworkConnectionSelector=Enable network connection selector
|
||||
sebserver.examconfig.props.label.insideSebEnableNetworkConnectionSelector.tooltip=Activates the button which allows to connect to WiFi networks, introduces in Windows 10.
|
||||
|
||||
sebserver.examconfig.props.group.specialKeys=Special Keys
|
||||
sebserver.examconfig.props.group.specialKeys.tooltip=Settings to enable or block (hook) keys, key combinations and mouse buttons.
|
||||
sebserver.examconfig.props.label.enableEsc=Enable Esc
|
||||
sebserver.examconfig.props.label.enablePrintScreen=Enable Print Screen
|
||||
sebserver.examconfig.props.label.enablePrintScreen.tooltip=Controls Print Screen and OS X screen capture, corresponds with Enable screen capture in Security settings.
|
||||
sebserver.examconfig.props.label.enableCtrlEsc=Enable Ctrl-Esc
|
||||
sebserver.examconfig.props.label.enableAltEsc=Enable Alt-Esc
|
||||
sebserver.examconfig.props.label.enableAltTab=Enable Alt-Tap
|
||||
sebserver.examconfig.props.label.enableAltF4=Enable Alt-F4
|
||||
sebserver.examconfig.props.label.enableStartMenu=Enable Start Menu
|
||||
sebserver.examconfig.props.label.enableRightMouse=Enable Right Mouse
|
||||
sebserver.examconfig.props.label.enableAltMouseWheel=Enable Alt-Mousewheel
|
||||
sebserver.examconfig.props.label.enableAltMouseWheel.tooltip=Corresponds to 'Allow browsing back/forward' in Browser pane. Disabling browsing to previously visited pages may increase security, because browsing back might allow to leave an exam
|
||||
|
||||
sebserver.examconfig.props.group.functionKeys=Function Keys
|
||||
sebserver.examconfig.props.group.functionKeys.tooltip=Enable or block function keys. This doesn't have any effect on the SEB exit sequence. Depending on specific keyboards some function keys cannot be blocked.
|
||||
sebserver.examconfig.props.label.enableF1=Enable F1
|
||||
sebserver.examconfig.props.label.enableF2=Enable F2
|
||||
sebserver.examconfig.props.label.enableF3=Enable F3
|
||||
sebserver.examconfig.props.label.enableF4=Enable F4
|
||||
sebserver.examconfig.props.label.enableF5=Enable F5
|
||||
sebserver.examconfig.props.label.enableF6=Enable F6
|
||||
sebserver.examconfig.props.label.enableF7=Enable F7
|
||||
sebserver.examconfig.props.label.enableF8=Enable F8
|
||||
sebserver.examconfig.props.label.enableF9=Enable F9
|
||||
sebserver.examconfig.props.label.enableF10=Enable F10
|
||||
sebserver.examconfig.props.label.enableF11=Enable F11
|
||||
sebserver.examconfig.props.label.enableF12=Enable F12
|
||||
|
||||
|
||||
|
||||
sebserver.examconfig.props.validation.password.confirm=Please enter correct confirm password
|
||||
sebserver.examconfig.props.validation.unexpected=Unexpected error happened. Value was not set correctly
|
||||
|
|
|
@ -604,7 +604,7 @@ TabItem {
|
|||
text-decoration: none;
|
||||
text-shadow: none;
|
||||
background-image: none;
|
||||
margin: 1px 0px 0px -1px;
|
||||
margin: 1px 0px 0px 0px;
|
||||
border: 1px solid #bdbdbd;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
|
@ -734,15 +734,6 @@ Widget-ToolTip-Pointer {
|
|||
background-image: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Table default theme */
|
||||
Table {
|
||||
font: 12px Arial, Helvetica, sans-serif;
|
||||
|
|
Loading…
Reference in a new issue