SEBSERV-45 added applications view
This commit is contained in:
parent
3654366dc8
commit
3a2a7847ee
32 changed files with 619 additions and 369 deletions
|
@ -46,7 +46,9 @@ public enum AttributeType {
|
||||||
/** Table type is a list of a composite of single types */
|
/** Table type is a list of a composite of single types */
|
||||||
TABLE(COMPOSITE_LIST),
|
TABLE(COMPOSITE_LIST),
|
||||||
|
|
||||||
STATIC_TABLE(COMPOSITE_LIST);
|
INLINE_TABLE(COMPOSITE_LIST),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
public final AttributeValueType attributeValueType;
|
public final AttributeValueType attributeValueType;
|
||||||
|
|
||||||
|
|
|
@ -8,33 +8,38 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.TabFolder;
|
||||||
|
import org.eclipse.swt.widgets.TabItem;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.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.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.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.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.GetExamConfigNode;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -44,127 +49,92 @@ public class SebExamConfigForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigForm.class);
|
private static final Logger log = LoggerFactory.getLogger(SebExamConfigForm.class);
|
||||||
|
|
||||||
private static final LocTextKey FORM_TITLE_NEW =
|
private static final String VIEW_TEXT_KEY_PREFIX = "sebserver.examconfig.props.form.views.";
|
||||||
new LocTextKey("sebserver.examconfig.form.title.new");
|
private static final String VIEW_TOOLTIP_TEXT_KEY_SUFFIX = ".tooltip";
|
||||||
private static final LocTextKey FORM_TITLE =
|
|
||||||
new LocTextKey("sebserver.examconfig.form.title");
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.props.from.title");
|
||||||
new LocTextKey("sebserver.examconfig.form.name");
|
|
||||||
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
|
||||||
new LocTextKey("sebserver.examconfig.form.description");
|
|
||||||
private static final LocTextKey FORM_STATUS_TEXT_KEY =
|
|
||||||
new LocTextKey("sebserver.examconfig.form.status");
|
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
|
private final ExamConfigurationService examConfigurationService;
|
||||||
|
|
||||||
protected SebExamConfigForm(
|
protected SebExamConfigForm(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser) {
|
final CurrentUser currentUser,
|
||||||
|
final ExamConfigurationService examConfigurationService) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
|
this.examConfigurationService = examConfigurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final ResourceService resourceService = this.pageService.getResourceService();
|
|
||||||
|
|
||||||
final UserInfo user = this.currentUser.get();
|
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||||
|
|
||||||
final boolean isNew = entityKey == null;
|
|
||||||
|
|
||||||
// get data or create new. Handle error if happen
|
|
||||||
final ConfigurationNode examConfig = (isNew)
|
|
||||||
? ConfigurationNode.createNewExamConfig((parentEntityKey != null)
|
|
||||||
? Long.valueOf(parentEntityKey.modelId)
|
|
||||||
: user.institutionId)
|
|
||||||
: this.restService
|
|
||||||
.getBuilder(GetExamConfigNode.class)
|
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
|
||||||
.call()
|
|
||||||
.get(pageContext::notifyError);
|
|
||||||
|
|
||||||
if (examConfig == null) {
|
|
||||||
log.error("Failed to get ConfigurationNode. "
|
|
||||||
+ "Error was notified to the User. "
|
|
||||||
+ "See previous logs for more infomation");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
|
||||||
final boolean writeGrant = entityGrant.w();
|
|
||||||
final boolean modifyGrant = entityGrant.m();
|
|
||||||
final boolean isReadonly = pageContext.isReadonly();
|
|
||||||
|
|
||||||
// new PageContext with actual EntityKey
|
|
||||||
final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey());
|
|
||||||
|
|
||||||
// the default page layout with interactive title
|
|
||||||
final LocTextKey titleKey = (isNew)
|
|
||||||
? FORM_TITLE_NEW
|
|
||||||
: FORM_TITLE;
|
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
formContext.getParent(),
|
pageContext.getParent(),
|
||||||
titleKey);
|
TITLE_TEXT_KEY);
|
||||||
|
|
||||||
// The SebClientConfig form
|
try {
|
||||||
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
|
||||||
formContext.copyOf(content), 4)
|
|
||||||
.readonly(isReadonly)
|
|
||||||
.putStaticValueIf(() -> !isNew,
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_ID,
|
|
||||||
examConfig.getModelId())
|
|
||||||
.putStaticValue(
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
|
||||||
String.valueOf(examConfig.getInstitutionId()))
|
|
||||||
.putStaticValue(
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
|
||||||
ConfigurationType.EXAM_CONFIG.name())
|
|
||||||
.addField(FormBuilder.text(
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
|
||||||
FORM_NAME_TEXT_KEY,
|
|
||||||
examConfig.name))
|
|
||||||
.addField(FormBuilder.text(
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
|
||||||
FORM_DESCRIPTION_TEXT_KEY,
|
|
||||||
examConfig.description).asArea())
|
|
||||||
.addField(FormBuilder.singleSelection(
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
|
||||||
FORM_STATUS_TEXT_KEY,
|
|
||||||
examConfig.status.name(),
|
|
||||||
resourceService::examConfigStatusResources))
|
|
||||||
.buildFor((isNew)
|
|
||||||
? this.restService.getRestCall(NewExamConfig.class)
|
|
||||||
: this.restService.getRestCall(SaveExamConfig.class));
|
|
||||||
|
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class)
|
||||||
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
|
.call()
|
||||||
|
.onError(pageContext::notifyError)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
||||||
.publishIf(() -> writeGrant && isReadonly)
|
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId())
|
||||||
|
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
||||||
|
.call()
|
||||||
|
.map(Utils::toSingleton)
|
||||||
|
.onError(pageContext::notifyError)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
final AttributeMapping attributes = this.examConfigurationService
|
||||||
.withEntityKey(entityKey)
|
.getAttributes(configNode.templateId)
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.onError(pageContext::notifyError)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE)
|
final List<View> views = this.examConfigurationService.getViews(attributes);
|
||||||
.withEntityKey(entityKey)
|
|
||||||
.withExec(formHandle::processFormSave)
|
|
||||||
.ignoreMoveAwayFromEdit()
|
|
||||||
.publishIf(() -> !isReadonly)
|
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_CANCEL_MODIFY)
|
final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content);
|
||||||
.withEntityKey(entityKey)
|
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
.withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
|
|
||||||
action,
|
final List<ViewContext> viewContexts = new ArrayList<>();
|
||||||
ActionDefinition.SEB_EXAM_CONFIG_LIST))
|
for (final View view : views) {
|
||||||
.publishIf(() -> !isReadonly);
|
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
||||||
|
pageContext,
|
||||||
|
configuration,
|
||||||
|
view,
|
||||||
|
attributes,
|
||||||
|
20);
|
||||||
|
viewContexts.add(viewContext);
|
||||||
|
|
||||||
|
final Composite viewGrid = this.examConfigurationService.createViewGrid(
|
||||||
|
tabFolder,
|
||||||
|
viewContext);
|
||||||
|
|
||||||
|
final TabItem tabItem = widgetFactory.tabItemLocalized(
|
||||||
|
tabFolder,
|
||||||
|
new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name));
|
||||||
|
tabItem.setControl(viewGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts);
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
|
||||||
|
pageContext.notifyError(e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class SebExamConfigList implements TemplateComposer {
|
||||||
this.statusFilter,
|
this.statusFilter,
|
||||||
true))
|
true))
|
||||||
.withDefaultAction(pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
||||||
.create())
|
.create())
|
||||||
.compose(content);
|
.compose(content);
|
||||||
|
|
||||||
|
@ -147,15 +147,15 @@ public class SebExamConfigList implements TemplateComposer {
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
||||||
.publishIf(examConfigGrant::iw)
|
.publishIf(examConfigGrant::iw)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
||||||
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> table.hasAnyContent())
|
.publishIf(() -> table.hasAnyContent())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
|
||||||
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent())
|
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROPERTIES_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST)
|
||||||
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent());
|
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* 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.content;
|
||||||
|
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
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.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
@GuiProfile
|
||||||
|
public class SebExamConfigPropForm implements TemplateComposer {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(SebExamConfigPropForm.class);
|
||||||
|
|
||||||
|
private static final LocTextKey FORM_TITLE_NEW =
|
||||||
|
new LocTextKey("sebserver.examconfig.form.title.new");
|
||||||
|
private static final LocTextKey FORM_TITLE =
|
||||||
|
new LocTextKey("sebserver.examconfig.form.title");
|
||||||
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.examconfig.form.name");
|
||||||
|
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.examconfig.form.description");
|
||||||
|
private static final LocTextKey FORM_STATUS_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.examconfig.form.status");
|
||||||
|
|
||||||
|
private final PageService pageService;
|
||||||
|
private final RestService restService;
|
||||||
|
private final CurrentUser currentUser;
|
||||||
|
|
||||||
|
protected SebExamConfigPropForm(
|
||||||
|
final PageService pageService,
|
||||||
|
final RestService restService,
|
||||||
|
final CurrentUser currentUser) {
|
||||||
|
|
||||||
|
this.pageService = pageService;
|
||||||
|
this.restService = restService;
|
||||||
|
this.currentUser = currentUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void compose(final PageContext pageContext) {
|
||||||
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
|
final ResourceService resourceService = this.pageService.getResourceService();
|
||||||
|
|
||||||
|
final UserInfo user = this.currentUser.get();
|
||||||
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
|
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||||
|
|
||||||
|
final boolean isNew = entityKey == null;
|
||||||
|
|
||||||
|
// get data or create new. Handle error if happen
|
||||||
|
final ConfigurationNode examConfig = (isNew)
|
||||||
|
? ConfigurationNode.createNewExamConfig((parentEntityKey != null)
|
||||||
|
? Long.valueOf(parentEntityKey.modelId)
|
||||||
|
: user.institutionId)
|
||||||
|
: this.restService
|
||||||
|
.getBuilder(GetExamConfigNode.class)
|
||||||
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
|
.call()
|
||||||
|
.get(pageContext::notifyError);
|
||||||
|
|
||||||
|
if (examConfig == null) {
|
||||||
|
log.error("Failed to get ConfigurationNode. "
|
||||||
|
+ "Error was notified to the User. "
|
||||||
|
+ "See previous logs for more infomation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
||||||
|
final boolean writeGrant = entityGrant.w();
|
||||||
|
final boolean modifyGrant = entityGrant.m();
|
||||||
|
final boolean isReadonly = pageContext.isReadonly();
|
||||||
|
|
||||||
|
// new PageContext with actual EntityKey
|
||||||
|
final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey());
|
||||||
|
|
||||||
|
// the default page layout with interactive title
|
||||||
|
final LocTextKey titleKey = (isNew)
|
||||||
|
? FORM_TITLE_NEW
|
||||||
|
: FORM_TITLE;
|
||||||
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
|
formContext.getParent(),
|
||||||
|
titleKey);
|
||||||
|
|
||||||
|
// The SebClientConfig form
|
||||||
|
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
||||||
|
formContext.copyOf(content), 4)
|
||||||
|
.readonly(isReadonly)
|
||||||
|
.putStaticValueIf(() -> !isNew,
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_ID,
|
||||||
|
examConfig.getModelId())
|
||||||
|
.putStaticValue(
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
||||||
|
String.valueOf(examConfig.getInstitutionId()))
|
||||||
|
.putStaticValue(
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||||
|
ConfigurationType.EXAM_CONFIG.name())
|
||||||
|
.addField(FormBuilder.text(
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||||
|
FORM_NAME_TEXT_KEY,
|
||||||
|
examConfig.name))
|
||||||
|
.addField(FormBuilder.text(
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||||
|
FORM_DESCRIPTION_TEXT_KEY,
|
||||||
|
examConfig.description).asArea())
|
||||||
|
.addField(FormBuilder.singleSelection(
|
||||||
|
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
||||||
|
FORM_STATUS_TEXT_KEY,
|
||||||
|
examConfig.status.name(),
|
||||||
|
resourceService::examConfigStatusResources))
|
||||||
|
.buildFor((isNew)
|
||||||
|
? this.restService.getRestCall(NewExamConfig.class)
|
||||||
|
: this.restService.getRestCall(SaveExamConfig.class));
|
||||||
|
|
||||||
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
||||||
|
.publishIf(() -> writeGrant && isReadonly)
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_MODIFY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(formHandle::processFormSave)
|
||||||
|
.ignoreMoveAwayFromEdit()
|
||||||
|
.publishIf(() -> !isReadonly)
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_CANCEL_MODIFY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
|
||||||
|
action,
|
||||||
|
ActionDefinition.SEB_EXAM_CONFIG_LIST))
|
||||||
|
.publishIf(() -> !isReadonly);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,141 +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.content;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.TabFolder;
|
|
||||||
import org.eclipse.swt.widgets.TabItem;
|
|
||||||
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.api.API;
|
|
||||||
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.service.examconfig.ExamConfigurationService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.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.auth.CurrentUser;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Component
|
|
||||||
@GuiProfile
|
|
||||||
public class SebExamConfigPropertiesForm implements TemplateComposer {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigPropertiesForm.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 LocTextKey TITLE_TEXT_KEY =
|
|
||||||
new LocTextKey("sebserver.examconfig.props.from.title");
|
|
||||||
|
|
||||||
private final PageService pageService;
|
|
||||||
private final RestService restService;
|
|
||||||
private final CurrentUser currentUser;
|
|
||||||
private final ExamConfigurationService examConfigurationService;
|
|
||||||
|
|
||||||
protected SebExamConfigPropertiesForm(
|
|
||||||
final PageService pageService,
|
|
||||||
final RestService restService,
|
|
||||||
final CurrentUser currentUser,
|
|
||||||
final ExamConfigurationService examConfigurationService) {
|
|
||||||
|
|
||||||
this.pageService = pageService;
|
|
||||||
this.restService = restService;
|
|
||||||
this.currentUser = currentUser;
|
|
||||||
this.examConfigurationService = examConfigurationService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void compose(final PageContext pageContext) {
|
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
|
||||||
|
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
|
||||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
|
||||||
|
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
|
||||||
pageContext.getParent(),
|
|
||||||
TITLE_TEXT_KEY);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class)
|
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
|
||||||
.call()
|
|
||||||
.onError(pageContext::notifyError)
|
|
||||||
.getOrThrow();
|
|
||||||
|
|
||||||
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId())
|
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
|
||||||
.call()
|
|
||||||
.map(Utils::toSingleton)
|
|
||||||
.onError(pageContext::notifyError)
|
|
||||||
.getOrThrow();
|
|
||||||
|
|
||||||
final AttributeMapping attributes = this.examConfigurationService
|
|
||||||
.getAttributes(configNode.templateId)
|
|
||||||
.onError(pageContext::notifyError)
|
|
||||||
.getOrThrow();
|
|
||||||
|
|
||||||
final List<View> views = this.examConfigurationService.getViews(attributes);
|
|
||||||
|
|
||||||
final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content);
|
|
||||||
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
|
||||||
|
|
||||||
final List<ViewContext> viewContexts = new ArrayList<>();
|
|
||||||
for (final View view : views) {
|
|
||||||
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
|
||||||
pageContext,
|
|
||||||
configuration,
|
|
||||||
view,
|
|
||||||
attributes,
|
|
||||||
20);
|
|
||||||
viewContexts.add(viewContext);
|
|
||||||
|
|
||||||
final Composite viewGrid = this.examConfigurationService.createViewGrid(
|
|
||||||
tabFolder,
|
|
||||||
viewContext);
|
|
||||||
|
|
||||||
final TabItem tabItem = widgetFactory.tabItemLocalized(
|
|
||||||
tabFolder,
|
|
||||||
new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name));
|
|
||||||
tabItem.setControl(viewGrid);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts);
|
|
||||||
|
|
||||||
} catch (final Exception e) {
|
|
||||||
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
|
|
||||||
pageContext.notifyError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -307,17 +307,22 @@ public enum ActionDefinition {
|
||||||
SEB_EXAM_CONFIG_NEW(
|
SEB_EXAM_CONFIG_NEW(
|
||||||
new LocTextKey("sebserver.examconfig.action.list.new"),
|
new LocTextKey("sebserver.examconfig.action.list.new"),
|
||||||
ImageIcon.NEW,
|
ImageIcon.NEW,
|
||||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT),
|
PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT),
|
||||||
SEB_EXAM_CONFIG_VIEW_FROM_LIST(
|
SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST(
|
||||||
new LocTextKey("sebserver.examconfig.action.list.view"),
|
new LocTextKey("sebserver.examconfig.action.list.view"),
|
||||||
ImageIcon.SHOW,
|
ImageIcon.SHOW,
|
||||||
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
||||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||||
SEB_EXAM_CONFIG_MODIFY_FROM_LIST(
|
SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST(
|
||||||
new LocTextKey("sebserver.examconfig.action.list.modify"),
|
new LocTextKey("sebserver.examconfig.action.list.modify.properties"),
|
||||||
ImageIcon.EDIT,
|
ImageIcon.EDIT,
|
||||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT,
|
||||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||||
|
SEB_EXAM_CONFIG_PROP_MODIFY(
|
||||||
|
new LocTextKey("sebserver.examconfig.action.modify.properties"),
|
||||||
|
ImageIcon.EDIT,
|
||||||
|
PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT,
|
||||||
|
ActionCategory.FORM),
|
||||||
SEB_EXAM_CONFIG_MODIFY(
|
SEB_EXAM_CONFIG_MODIFY(
|
||||||
new LocTextKey("sebserver.examconfig.action.modify"),
|
new LocTextKey("sebserver.examconfig.action.modify"),
|
||||||
ImageIcon.EDIT,
|
ImageIcon.EDIT,
|
||||||
|
@ -334,10 +339,10 @@ public enum ActionDefinition {
|
||||||
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
||||||
ActionCategory.FORM),
|
ActionCategory.FORM),
|
||||||
|
|
||||||
SEB_EXAM_CONFIG_MODIFY_PROPERTIES_FROM_LIST(
|
SEB_EXAM_CONFIG_MODIFY_FROM_LIST(
|
||||||
new LocTextKey("sebserver.examconfig.action.list.modify.properties"),
|
new LocTextKey("sebserver.examconfig.action.list.modify"),
|
||||||
ImageIcon.EDIT,
|
ImageIcon.EDIT,
|
||||||
PageStateDefinition.SEB_EXAM_CONFIG_PROPERTIES_EDIT,
|
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import ch.ethz.seb.sebserver.gui.content.SebClientConfigForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebClientConfigList;
|
import ch.ethz.seb.sebserver.gui.content.SebClientConfigList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigForm;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigList;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropertiesForm;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
|
||||||
|
@ -56,10 +56,9 @@ public enum PageStateDefinition implements PageState {
|
||||||
SEB_CLIENT_CONFIG_EDIT(Type.FORM_EDIT, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
SEB_CLIENT_CONFIG_EDIT(Type.FORM_EDIT, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
||||||
|
|
||||||
SEB_EXAM_CONFIG_LIST(Type.LIST_VIEW, SebExamConfigList.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_LIST(Type.LIST_VIEW, SebExamConfigList.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_EDIT(Type.FORM_EDIT, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_PROP_EDIT(Type.FORM_EDIT, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_PROPERTIES_EDIT(Type.FORM_VIEW, SebExamConfigPropertiesForm.class,
|
SEB_EXAM_CONFIG_EDIT(Type.FORM_VIEW, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
ActivityDefinition.SEB_EXAM_CONFIG),
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ public interface ExamConfigurationService {
|
||||||
public static final String ATTRIBUTE_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.label.";
|
public static final String ATTRIBUTE_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.label.";
|
||||||
public static final String GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group.";
|
public static final String GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group.";
|
||||||
public static final String TOOL_TIP_SUFFIX = ".tooltip";
|
public static final String TOOL_TIP_SUFFIX = ".tooltip";
|
||||||
|
public static final String TABLE_ROW_TITLE_SUFFIX = ".row.title";
|
||||||
|
|
||||||
WidgetFactory getWidgetFactory();
|
WidgetFactory getWidgetFactory();
|
||||||
|
|
||||||
|
@ -85,4 +86,11 @@ public interface ExamConfigurationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LocTextKey getTablePopupTitleKey(
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final I18nSupport i18nSupport) {
|
||||||
|
|
||||||
|
return new LocTextKey(ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + TABLE_ROW_TITLE_SUFFIX);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ public interface InputField {
|
||||||
|
|
||||||
String getValue();
|
String getValue();
|
||||||
|
|
||||||
|
String getReadableValue();
|
||||||
|
|
||||||
void showError(String errorMessage);
|
void showError(String errorMessage);
|
||||||
|
|
||||||
void clearError();
|
void clearError();
|
||||||
|
|
|
@ -48,13 +48,15 @@ public interface InputFieldBuilder {
|
||||||
|
|
||||||
static Composite createInnerGrid(
|
static Composite createInnerGrid(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
return createInnerGrid(parent, orientation, 1);
|
return createInnerGrid(parent, attribute, orientation, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Composite createInnerGrid(
|
static Composite createInnerGrid(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation,
|
final Orientation orientation,
|
||||||
final int numColumns) {
|
final int numColumns) {
|
||||||
|
|
||||||
|
@ -69,8 +71,8 @@ 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) ? orientation.width() : 1,
|
(orientation != null && attribute.parentId == null) ? orientation.width() : 1,
|
||||||
(orientation != null) ? orientation.height() : 1);
|
(orientation != null && attribute.parentId == null) ? orientation.height() : 1);
|
||||||
comp.setLayoutData(gridData);
|
comp.setLayoutData(gridData);
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,12 @@ public abstract class AbstractInputField<T extends Control> implements InputFiel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReadableValue() {
|
||||||
|
return getValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void setValueToControl(String value);
|
protected abstract void setValueToControl(String value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,6 @@ public class AttributeMapping {
|
||||||
Objects.requireNonNull(orientations);
|
Objects.requireNonNull(orientations);
|
||||||
|
|
||||||
this.templateId = templateId;
|
this.templateId = templateId;
|
||||||
this.attributeIdMapping = Utils.immutableMapOf(attributes
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
attr -> attr.id,
|
|
||||||
Function.identity())));
|
|
||||||
|
|
||||||
this.orientationAttributeMapping = Utils.immutableMapOf(orientations
|
this.orientationAttributeMapping = Utils.immutableMapOf(orientations
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -57,8 +52,16 @@ public class AttributeMapping {
|
||||||
o -> o.attributeId,
|
o -> o.attributeId,
|
||||||
Function.identity())));
|
Function.identity())));
|
||||||
|
|
||||||
|
this.attributeIdMapping = Utils.immutableMapOf(attributes
|
||||||
|
.stream()
|
||||||
|
.filter(attr -> this.orientationAttributeMapping.containsKey(attr.id))
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
attr -> attr.id,
|
||||||
|
Function.identity())));
|
||||||
|
|
||||||
this.attributeNameIdMapping = Utils.immutableMapOf(attributes
|
this.attributeNameIdMapping = Utils.immutableMapOf(attributes
|
||||||
.stream()
|
.stream()
|
||||||
|
.filter(attr -> this.orientationAttributeMapping.containsKey(attr.id))
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
attr -> attr.name,
|
attr -> attr.name,
|
||||||
attr -> attr.id)));
|
attr -> attr.id)));
|
||||||
|
@ -71,6 +74,7 @@ public class AttributeMapping {
|
||||||
|
|
||||||
this.childAttributeMapping = Utils.immutableMapOf(attributes
|
this.childAttributeMapping = Utils.immutableMapOf(attributes
|
||||||
.stream()
|
.stream()
|
||||||
|
.filter(attr -> this.orientationAttributeMapping.containsKey(attr.id))
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
attr -> attr.id,
|
attr -> attr.id,
|
||||||
this::getChildAttributes)));
|
this::getChildAttributes)));
|
||||||
|
@ -184,7 +188,7 @@ public class AttributeMapping {
|
||||||
.values()
|
.values()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(o -> groupName.equals(o.groupId))
|
.filter(o -> groupName.equals(o.groupId))
|
||||||
.sorted((o1, o2) -> (o1.yPosition == o2.yPosition)
|
.sorted((o1, o2) -> (o1.yPosition != null && o1.yPosition.equals(o2.yPosition))
|
||||||
? o1.xPosition.compareTo(o2.xPosition)
|
? o1.xPosition.compareTo(o2.xPosition)
|
||||||
: o1.yPosition.compareTo(o2.yPosition))
|
: o1.yPosition.compareTo(o2.yPosition))
|
||||||
.map(o -> this.attributeIdMapping.get(o.attributeId))
|
.map(o -> this.attributeIdMapping.get(o.attributeId))
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
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 java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
|
@ -28,6 +30,10 @@ interface CellFieldBuilderAdapter {
|
||||||
|
|
||||||
void createCell(ViewGridBuilder builder);
|
void createCell(ViewGridBuilder builder);
|
||||||
|
|
||||||
|
default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static CellFieldBuilderAdapter dummyBuilderAdapter() {
|
static CellFieldBuilderAdapter dummyBuilderAdapter() {
|
||||||
return new CellFieldBuilderAdapter() {
|
return new CellFieldBuilderAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,6 +77,9 @@ interface CellFieldBuilderAdapter {
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
return new CellFieldBuilderAdapter() {
|
return new CellFieldBuilderAdapter() {
|
||||||
|
|
||||||
|
private int span = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
|
|
||||||
|
@ -88,21 +97,16 @@ interface CellFieldBuilderAdapter {
|
||||||
gridData.verticalIndent = 5;
|
gridData.verticalIndent = 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RIGHT_SPAN:
|
||||||
case LEFT_SPAN: {
|
case LEFT_SPAN: {
|
||||||
label.setAlignment(SWT.LEFT);
|
label.setAlignment(SWT.LEFT);
|
||||||
gridData.horizontalSpan = orientation.width;
|
gridData.horizontalSpan = (span > 1) ? span : orientation.width;
|
||||||
gridData.verticalIndent = 5;
|
gridData.verticalIndent = 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RIGHT_SPAN: {
|
|
||||||
label.setAlignment(SWT.LEFT);
|
|
||||||
gridData.verticalIndent = 5;
|
|
||||||
gridData.horizontalSpan = orientation.width;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TOP: {
|
case TOP: {
|
||||||
gridData.horizontalSpan = orientation.width;
|
gridData.horizontalSpan = orientation.width;
|
||||||
label.setAlignment(SWT.LEFT);
|
gridData.verticalAlignment = SWT.BOTTOM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +118,22 @@ interface CellFieldBuilderAdapter {
|
||||||
label.pack();
|
label.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||||
|
if (grid[y][x] != this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (orientation.title == TitleOrientation.LEFT_SPAN) {
|
||||||
|
int xpos = x - 1;
|
||||||
|
while (xpos >= 0 && grid[y][xpos] == null && span < orientation.width) {
|
||||||
|
grid[y][xpos] = this;
|
||||||
|
grid[y][xpos + 1] = dummyBuilderAdapter();
|
||||||
|
this.span++;
|
||||||
|
xpos--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[LABEL]";
|
return "[LABEL]";
|
||||||
|
@ -185,7 +205,7 @@ interface CellFieldBuilderAdapter {
|
||||||
builder.parent,
|
builder.parent,
|
||||||
this.width,
|
this.width,
|
||||||
groupLabelKey);
|
groupLabelKey);
|
||||||
group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, this.width, this.height));
|
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, this.width, this.height));
|
||||||
|
|
||||||
final ViewGridBuilder groupBuilder = new ViewGridBuilder(
|
final ViewGridBuilder groupBuilder = new ViewGridBuilder(
|
||||||
group,
|
group,
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -20,6 +21,7 @@ import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
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.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.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;
|
||||||
|
@ -64,14 +66,20 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Button checkbox = this.widgetFactory.buttonLocalized(
|
final Button checkbox = this.widgetFactory.buttonLocalized(
|
||||||
innerGrid,
|
innerGrid,
|
||||||
SWT.CHECK,
|
SWT.CHECK,
|
||||||
ExamConfigurationService.attributeNameLocKey(attribute),
|
(orientation.title == TitleOrientation.NONE)
|
||||||
|
? ExamConfigurationService.attributeNameLocKey(attribute)
|
||||||
|
: null,
|
||||||
ExamConfigurationService.getToolTipKey(attribute, i18nSupport));
|
ExamConfigurationService.getToolTipKey(attribute, i18nSupport));
|
||||||
|
|
||||||
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||||
|
gridData.verticalIndent = 0;
|
||||||
|
checkbox.setLayoutData(gridData);
|
||||||
|
|
||||||
final CheckboxField checkboxField = new CheckboxField(
|
final CheckboxField checkboxField = new CheckboxField(
|
||||||
attribute,
|
attribute,
|
||||||
viewContext.getOrientation(attribute.id),
|
viewContext.getOrientation(attribute.id),
|
||||||
|
@ -95,9 +103,7 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
||||||
final Orientation orientation,
|
final Orientation orientation,
|
||||||
final Button control) {
|
final Button control) {
|
||||||
|
|
||||||
super(attribute, orientation, control, (orientation.groupId == null)
|
super(attribute, orientation, control, null);
|
||||||
? InputFieldBuilder.createErrorLabel(control.getParent())
|
|
||||||
: null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,6 +117,14 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
||||||
? Constants.TRUE_STRING
|
? Constants.TRUE_STRING
|
||||||
: Constants.FALSE_STRING;
|
: Constants.FALSE_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReadableValue() {
|
||||||
|
return this.control.getSelection()
|
||||||
|
? "Active"
|
||||||
|
: "Inactive";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public class InlineTableFieldBuilder {
|
||||||
|
|
||||||
|
public InlineTableFieldBuilder() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,14 +54,14 @@ public class MultiCheckboxSelection extends SelectionFieldBuilder implements Inp
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final MultiSelectionCheckbox selection = this.widgetFactory.selectionLocalized(
|
final MultiSelectionCheckbox selection = this.widgetFactory.selectionLocalized(
|
||||||
Selection.Type.MULTI_CHECKBOX,
|
Selection.Type.MULTI_CHECKBOX,
|
||||||
innerGrid,
|
innerGrid,
|
||||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
() -> this.getLocalizedResources(attribute, viewContext),
|
||||||
null,
|
null,
|
||||||
() -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport))
|
() -> this.getLocalizedResourcesAsToolTip(attribute, viewContext))
|
||||||
.getTypeInstance();
|
.getTypeInstance();
|
||||||
|
|
||||||
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class PassworFieldBuilder implements InputFieldBuilder {
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Text passwordInput = new Text(innerGrid, SWT.LEFT | SWT.BORDER | SWT.PASSWORD);
|
final Text passwordInput = new Text(innerGrid, SWT.LEFT | SWT.BORDER | SWT.PASSWORD);
|
||||||
passwordInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
passwordInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
|
|
|
@ -56,14 +56,14 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final RadioSelection selection = this.widgetFactory.selectionLocalized(
|
final RadioSelection selection = this.widgetFactory.selectionLocalized(
|
||||||
Selection.Type.RADIO,
|
Selection.Type.RADIO,
|
||||||
innerGrid,
|
innerGrid,
|
||||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
() -> this.getLocalizedResources(attribute, viewContext),
|
||||||
null,
|
null,
|
||||||
() -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport))
|
() -> this.getLocalizedResourcesAsToolTip(attribute, viewContext))
|
||||||
.getTypeInstance();
|
.getTypeInstance();
|
||||||
|
|
||||||
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
|
@ -71,7 +71,7 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements
|
||||||
attribute,
|
attribute,
|
||||||
orientation,
|
orientation,
|
||||||
selection,
|
selection,
|
||||||
InputFieldBuilder.createErrorLabel(innerGrid));
|
null);
|
||||||
|
|
||||||
selection.setSelectionListener(event -> {
|
selection.setSelectionListener(event -> {
|
||||||
radioSelectionInputField.clearError();
|
radioSelectionInputField.clearError();
|
||||||
|
|
|
@ -21,27 +21,26 @@ 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.gbl.util.Utils;
|
||||||
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.i18n.I18nSupport;
|
|
||||||
|
|
||||||
public abstract class SelectionFieldBuilder {
|
public abstract class SelectionFieldBuilder {
|
||||||
|
|
||||||
protected List<Tuple<String>> getLocalizedResources(
|
protected List<Tuple<String>> getLocalizedResources(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final I18nSupport i18nSupport) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
return getLocalizedRes(attribute, i18nSupport, false);
|
return getLocalizedRes(attribute, viewContext, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Tuple<String>> getLocalizedResourcesAsToolTip(
|
protected List<Tuple<String>> getLocalizedResourcesAsToolTip(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final I18nSupport i18nSupport) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
return getLocalizedRes(attribute, i18nSupport, true);
|
return getLocalizedRes(attribute, viewContext, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Tuple<String>> getLocalizedRes(
|
private List<Tuple<String>> getLocalizedRes(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final I18nSupport i18nSupport,
|
final ViewContext viewContext,
|
||||||
final boolean toolTipResources) {
|
final boolean toolTipResources) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
|
@ -62,7 +61,7 @@ public abstract class SelectionFieldBuilder {
|
||||||
final String key = prefix + value + ((toolTipResources)
|
final String key = prefix + value + ((toolTipResources)
|
||||||
? ExamConfigurationService.TOOL_TIP_SUFFIX
|
? ExamConfigurationService.TOOL_TIP_SUFFIX
|
||||||
: "");
|
: "");
|
||||||
final String text = i18nSupport.getText(key, "");
|
final String text = viewContext.i18nSupport.getText(key, "");
|
||||||
return new Tuple<>(value, (StringUtils.isBlank(text))
|
return new Tuple<>(value, (StringUtils.isBlank(text))
|
||||||
? (toolTipResources)
|
? (toolTipResources)
|
||||||
? text
|
? text
|
||||||
|
|
|
@ -57,14 +57,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final SingleSelection selection = this.widgetFactory.selectionLocalized(
|
final SingleSelection selection = this.widgetFactory.selectionLocalized(
|
||||||
(attribute.type == AttributeType.COMBO_SELECTION)
|
(attribute.type == AttributeType.COMBO_SELECTION)
|
||||||
? Selection.Type.SINGLE_COMBO
|
? Selection.Type.SINGLE_COMBO
|
||||||
: Selection.Type.SINGLE,
|
: Selection.Type.SINGLE,
|
||||||
innerGrid,
|
innerGrid,
|
||||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
() -> this.getLocalizedResources(attribute, viewContext),
|
||||||
ExamConfigurationService.getToolTipKey(attribute, i18nSupport))
|
ExamConfigurationService.getToolTipKey(attribute, i18nSupport))
|
||||||
.getTypeInstance();
|
.getTypeInstance();
|
||||||
|
|
||||||
|
@ -107,6 +107,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement
|
||||||
protected void setValueToControl(final String value) {
|
protected void setValueToControl(final String value) {
|
||||||
this.control.select(value);
|
this.control.select(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReadableValue() {
|
||||||
|
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return super.getReadableValue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class SliderFieldBuilder implements InputFieldBuilder {
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Slider slider = new Slider(innerGrid, SWT.NONE);
|
final Slider slider = new Slider(innerGrid, SWT.NONE);
|
||||||
slider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
slider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
|
|
|
@ -16,6 +16,7 @@ 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.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -23,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.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.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;
|
||||||
|
@ -58,8 +60,8 @@ public class TableContext {
|
||||||
this.attribute = Objects.requireNonNull(attribute);
|
this.attribute = Objects.requireNonNull(attribute);
|
||||||
this.viewContext = Objects.requireNonNull(viewContext);
|
this.viewContext = Objects.requireNonNull(viewContext);
|
||||||
|
|
||||||
this.orientation = viewContext
|
this.orientation = Objects.requireNonNull(viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id));
|
||||||
|
|
||||||
this.rowAttributes = viewContext.getChildAttributes(attribute.id)
|
this.rowAttributes = viewContext.getChildAttributes(attribute.id)
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -183,4 +185,29 @@ public class TableContext {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRowValue(final TableValue tableValue) {
|
||||||
|
final ConfigurationAttribute attribute = this.viewContext.getAttribute(tableValue.attributeId);
|
||||||
|
if (attribute != null) {
|
||||||
|
switch (attribute.type) {
|
||||||
|
case CHECKBOX: {
|
||||||
|
return BooleanUtils.toBoolean(tableValue.value)
|
||||||
|
? "Active"
|
||||||
|
: "Inactive";
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
return this.viewContext.i18nSupport.getText(key, tableValue.value);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return tableValue.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableValue.value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
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;
|
||||||
|
@ -40,7 +39,6 @@ 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.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.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;
|
||||||
|
@ -105,15 +103,16 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
true, false,
|
true, false,
|
||||||
(tableContext.orientation != null) ? tableContext.orientation.width() : 1,
|
(tableContext.orientation != null) ? tableContext.orientation.width() : 1,
|
||||||
(tableContext.orientation != null) ? tableContext.orientation.height() : 1);
|
(tableContext.orientation != null) ? tableContext.orientation.height() : 1);
|
||||||
gridData.heightHint = tableContext.orientation.height * 40;
|
gridData.heightHint = tableContext.orientation.height * 20 + 40;
|
||||||
table.setLayoutData(gridData);
|
table.setLayoutData(gridData);
|
||||||
table.setHeaderVisible(true);
|
table.setHeaderVisible(true);
|
||||||
table.addListener(SWT.Resize, this::adaptColumnWidth);
|
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 = new TableColumn(table, SWT.NONE);
|
||||||
final String text = i18nSupport.getText(
|
final String text = i18nSupport.getText(
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + columnAttribute.name,
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
|
columnAttribute.name,
|
||||||
columnAttribute.name);
|
columnAttribute.name);
|
||||||
column.setText(text);
|
column.setText(text);
|
||||||
column.setWidth(100);
|
column.setWidth(100);
|
||||||
|
@ -159,14 +158,25 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
return tableField;
|
return tableField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void adaptColumnWidth(final Event event) {
|
private void adaptColumnWidth(
|
||||||
|
final Table table,
|
||||||
|
final TableContext tableContext) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Table table = (Table) event.widget;
|
|
||||||
final int currentTableWidth = table.getClientArea().width - 50;
|
final int currentTableWidth = table.getClientArea().width - 50;
|
||||||
final TableColumn[] columns = table.getColumns();
|
final TableColumn[] columns = table.getColumns();
|
||||||
final int columnWidth = currentTableWidth / (columns.length - 2);
|
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++) {
|
for (int i = 0; i < columns.length - 2; i++) {
|
||||||
columns[i].setWidth(columnWidth);
|
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.warn("Failed to adaptColumnWidth: ", e);
|
log.warn("Failed to adaptColumnWidth: ", e);
|
||||||
|
@ -196,6 +206,12 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
.map(TableValue::of)
|
.map(TableValue::of)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
initValue(tableValues);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initValue(final List<TableValue> tableValues) {
|
||||||
final Map<Integer, Map<Long, TableValue>> _initValue = new HashMap<>();
|
final Map<Integer, Map<Long, TableValue>> _initValue = new HashMap<>();
|
||||||
for (final TableValue tableValue : tableValues) {
|
for (final TableValue tableValue : tableValues) {
|
||||||
final Map<Long, TableValue> rowValues = _initValue.computeIfAbsent(
|
final Map<Long, TableValue> rowValues = _initValue.computeIfAbsent(
|
||||||
|
@ -215,13 +231,24 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
this.values.add(rowValues);
|
this.values.add(rowValues);
|
||||||
addTableRow(rowValues);
|
addTableRow(rowValues);
|
||||||
});
|
});
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChildValue(final ConfigurationValue value) {
|
private boolean isChildValue(final ConfigurationValue value) {
|
||||||
return this.attribute.id.equals(
|
if (!this.tableContext.getViewContext().attributeMapping.attributeIdMapping
|
||||||
this.tableContext.getAttribute(value.attributeId).parentId);
|
.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) {
|
||||||
|
@ -254,22 +281,7 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
final TableItem tableItem = new TableItem(this.control, SWT.NONE);
|
final TableItem tableItem = new TableItem(this.control, SWT.NONE);
|
||||||
applyTableRowValues(this.values.size() - 1);
|
applyTableRowValues(this.values.size() - 1);
|
||||||
|
|
||||||
// TODO delete icon is not working on row as expected
|
// TODO try to add delete button within table row?
|
||||||
// final TableEditor editor = new TableEditor(this.control);
|
|
||||||
// editor.horizontalAlignment = SWT.CENTER;
|
|
||||||
// editor.grabHorizontal = true;
|
|
||||||
// editor.minimumWidth = 20;
|
|
||||||
// final Image image = ImageIcon.REMOVE_BOX.getImage(this.control.getDisplay());
|
|
||||||
// final Label imageLabel = new Label(this.control, SWT.NONE);
|
|
||||||
// imageLabel.setAlignment(SWT.CENTER);
|
|
||||||
// imageLabel.setImage(image);
|
|
||||||
// imageLabel.addListener(SWT.MouseDown, event -> System.out.println("*************** removeRow"));
|
|
||||||
// editor.setEditor(imageLabel, tableItem, this.columnAttributes.size());
|
|
||||||
// tableItem.setData("EDITOR", editor);
|
|
||||||
//
|
|
||||||
// editor.layout();
|
|
||||||
// this.control.layout(true, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyTableRowValues(final int index) {
|
private void applyTableRowValues(final int index) {
|
||||||
|
@ -279,7 +291,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
int cellIndex = 0;
|
int cellIndex = 0;
|
||||||
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
||||||
if (rowValues.containsKey(attr.id)) {
|
if (rowValues.containsKey(attr.id)) {
|
||||||
item.setText(cellIndex, rowValues.get(attr.id).value);
|
item.setText(
|
||||||
|
cellIndex,
|
||||||
|
this.tableContext.getRowValue(rowValues.get(attr.id)));
|
||||||
}
|
}
|
||||||
cellIndex++;
|
cellIndex++;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +313,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
this.tableContext.getWidgetFactory())
|
this.tableContext.getWidgetFactory())
|
||||||
.setDialogWidth(500)
|
.setDialogWidth(500)
|
||||||
.open(
|
.open(
|
||||||
new LocTextKey("Title"),
|
ExamConfigurationService.getTablePopupTitleKey(
|
||||||
|
this.attribute,
|
||||||
|
this.tableContext.getViewContext().i18nSupport),
|
||||||
values -> applyFormValues(values, selectionIndex),
|
values -> applyFormValues(values, selectionIndex),
|
||||||
builder);
|
builder);
|
||||||
}
|
}
|
||||||
|
@ -313,6 +329,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
this.values.remove(index);
|
this.values.remove(index);
|
||||||
this.values.add(index, tableRowValues);
|
this.values.add(index, tableRowValues);
|
||||||
applyTableRowValues(index);
|
applyTableRowValues(index);
|
||||||
|
// send new values to web-service
|
||||||
|
this.tableContext.getValueChangeListener()
|
||||||
|
.tableChanged(extractTableValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurationTableValues extractTableValue() {
|
private ConfigurationTableValues extractTableValue() {
|
||||||
|
@ -353,12 +372,13 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setValueToControl(final String value) {
|
protected void setValueToControl(final String value) {
|
||||||
throw new UnsupportedOperationException();
|
//throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
throw new UnsupportedOperationException();
|
return null;
|
||||||
|
//throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ 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.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
@ -82,25 +83,27 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute) {
|
final ConfigurationAttribute attribute) {
|
||||||
|
|
||||||
if (attribute.type == AttributeType.TABLE) {
|
// if (attribute.type == AttributeType.TABLE) {
|
||||||
throw new UnsupportedOperationException(
|
// throw new UnsupportedOperationException(
|
||||||
"Table type is currently not supported within a table row form view!");
|
// "Table type is currently not supported within a table row form view!");
|
||||||
}
|
// }
|
||||||
|
|
||||||
final Orientation orientation = this.tableContext
|
final Orientation orientation = this.tableContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
|
|
||||||
final InputFieldBuilder inputFieldBuilder = this.tableContext
|
final InputFieldBuilder inputFieldBuilder = this.tableContext
|
||||||
.getInputFieldBuilder(attribute, orientation);
|
.getInputFieldBuilder(attribute, orientation);
|
||||||
|
|
||||||
final InputField inputField = inputFieldBuilder.createInputField(
|
final InputField inputField = inputFieldBuilder.createInputField(
|
||||||
parent,
|
parent,
|
||||||
attribute,
|
attribute,
|
||||||
this.tableContext.getViewContext());
|
this.tableContext.getViewContext());
|
||||||
|
|
||||||
inputField.initValue(
|
if (attribute.type == AttributeType.TABLE) {
|
||||||
this.rowValues.get(attribute.id).value,
|
((TableInputField) inputField).initValue(new ArrayList<>(this.rowValues.values()));
|
||||||
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);
|
||||||
|
@ -108,9 +111,13 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
||||||
return inputField;
|
return inputField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createLabel(final Composite parent, final ConfigurationAttribute attribute) {
|
private void createLabel(
|
||||||
|
final Composite parent,
|
||||||
|
final ConfigurationAttribute attribute) {
|
||||||
|
|
||||||
final LocTextKey locTextKey = new LocTextKey(
|
final LocTextKey locTextKey = new LocTextKey(
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name,
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
|
attribute.name,
|
||||||
attribute.name);
|
attribute.name);
|
||||||
final Label label = this.tableContext
|
final Label label = this.tableContext
|
||||||
.getWidgetFactory()
|
.getWidgetFactory()
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class TextFieldBuilder implements InputFieldBuilder {
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Text text;
|
final Text text;
|
||||||
if (attribute.type == AttributeType.INTEGER ||
|
if (attribute.type == AttributeType.INTEGER ||
|
||||||
|
|
|
@ -33,10 +33,10 @@ public final class ViewContext {
|
||||||
private final View view;
|
private final View view;
|
||||||
private final int rows;
|
private final int rows;
|
||||||
|
|
||||||
private final AttributeMapping attributeMapping;
|
final AttributeMapping attributeMapping;
|
||||||
private final Map<Long, InputField> inputFieldMapping;
|
final Map<Long, InputField> inputFieldMapping;
|
||||||
private final ValueChangeListener valueChangeListener;
|
final ValueChangeListener valueChangeListener;
|
||||||
private final I18nSupport i18nSupport;
|
final I18nSupport i18nSupport;
|
||||||
|
|
||||||
ViewContext(
|
ViewContext(
|
||||||
final Configuration configuration,
|
final Configuration configuration,
|
||||||
|
|
|
@ -67,6 +67,10 @@ public class ViewGridBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewGridBuilder add(final ConfigurationAttribute attribute) {
|
ViewGridBuilder add(final ConfigurationAttribute attribute) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Add SEB Configuration Attribute: " + attribute);
|
||||||
|
}
|
||||||
|
|
||||||
// ignore nested attributes here
|
// ignore nested attributes here
|
||||||
if (attribute.parentId != null) {
|
if (attribute.parentId != null) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -115,7 +119,8 @@ public class ViewGridBuilder {
|
||||||
orientation);
|
orientation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LEFT: {
|
case LEFT:
|
||||||
|
case LEFT_SPAN: {
|
||||||
this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder(
|
this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
|
@ -127,17 +132,17 @@ public class ViewGridBuilder {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LEFT_SPAN: {
|
// case LEFT_SPAN: {
|
||||||
int spanxpos = xpos - orientation.width;
|
// int spanxpos = xpos - orientation.width;
|
||||||
if (spanxpos < 0) {
|
// if (spanxpos < 0) {
|
||||||
spanxpos = 0;
|
// spanxpos = 0;
|
||||||
}
|
// }
|
||||||
fillDummy(spanxpos, ypos, orientation.width, 1);
|
// fillDummy(spanxpos, ypos, orientation.width, 1);
|
||||||
this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder(
|
// this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
attribute,
|
// attribute,
|
||||||
orientation);
|
// orientation);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case TOP: {
|
case TOP: {
|
||||||
fillDummy(xpos, ypos - 1, orientation.width, 1);
|
fillDummy(xpos, ypos - 1, orientation.width, 1);
|
||||||
this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder(
|
this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
|
@ -160,9 +165,11 @@ public class ViewGridBuilder {
|
||||||
log.debug("Compose grid view: \n" + gridToString());
|
log.debug("Compose grid view: \n" + gridToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// balance grid (optimize span and grab empty spaces for labels where applicable)
|
||||||
for (int y = 0; y < this.grid.length; y++) {
|
for (int y = 0; y < this.grid.length; y++) {
|
||||||
for (int x = 0; x < this.grid[y].length; x++) {
|
for (int x = 0; x < this.grid[y].length; x++) {
|
||||||
if (this.grid[y][x] != null) {
|
if (this.grid[y][x] != null) {
|
||||||
|
this.grid[y][x].balanceGrid(this.grid, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +181,7 @@ public class ViewGridBuilder {
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||||
gridData.verticalIndent = 8;
|
gridData.verticalIndent = 8;
|
||||||
empty.setLayoutData(gridData);
|
empty.setLayoutData(gridData);
|
||||||
empty.setText("");
|
empty.setText("" /* "empty " + x + " " + y */);
|
||||||
} else {
|
} else {
|
||||||
this.grid[y][x].createCell(this);
|
this.grid[y][x].createCell(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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 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.gui.service.examconfig.ValueChangeRule;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Service
|
||||||
|
@GuiProfile
|
||||||
|
public class AllowFlashFullscreenRule implements ValueChangeRule {
|
||||||
|
|
||||||
|
public static final String KEY_THIRD_PART = "allowSwitchToApplications";
|
||||||
|
public static final String KEY_FULL_SCREEN = "allowFlashFullscreen";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean observesAttribute(final ConfigurationAttribute attribute) {
|
||||||
|
return KEY_THIRD_PART.equals(attribute.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyRule(
|
||||||
|
final ViewContext context,
|
||||||
|
final ConfigurationAttribute attribut,
|
||||||
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
|
if (BooleanUtils.toBoolean(value.value)) {
|
||||||
|
context.enable(KEY_FULL_SCREEN);
|
||||||
|
} else {
|
||||||
|
context.disable(KEY_FULL_SCREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,10 @@ public interface Selection {
|
||||||
|
|
||||||
String getSelectionValue();
|
String getSelectionValue();
|
||||||
|
|
||||||
|
default String getSelectionReadableValue() {
|
||||||
|
return getSelectionValue();
|
||||||
|
}
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void setVisible(boolean visible);
|
void setVisible(boolean visible);
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.eclipse.swt.widgets.Combo;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Listener;
|
import org.eclipse.swt.widgets.Listener;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
|
||||||
public final class SingleSelection extends Combo implements Selection {
|
public final class SingleSelection extends Combo implements Selection {
|
||||||
|
@ -73,6 +74,16 @@ public final class SingleSelection extends Combo implements Selection {
|
||||||
return this.keyMapping.get(selectionindex);
|
return this.keyMapping.get(selectionindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSelectionReadableValue() {
|
||||||
|
final int selectionindex = super.getSelectionIndex();
|
||||||
|
if (selectionindex < 0) {
|
||||||
|
return Constants.EMPTY_NOTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.valueMapping.get(selectionindex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
super.clearSelection();
|
super.clearSelection();
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this.configurationValueRecordMapper.selectByExample()
|
return !this.configurationValueRecordMapper.selectByExample()
|
||||||
.join(ConfigurationAttributeRecordDynamicSqlSupport.configurationAttributeRecord)
|
.join(ConfigurationAttributeRecordDynamicSqlSupport.configurationAttributeRecord)
|
||||||
.on(
|
.on(
|
||||||
ConfigurationAttributeRecordDynamicSqlSupport.id,
|
ConfigurationAttributeRecordDynamicSqlSupport.id,
|
||||||
|
@ -75,7 +75,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(val -> value.value.equals(val.getValue()))
|
.filter(val -> value.value.equals(val.getValue()))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.isEmpty();
|
.isPresent();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("unexpected error while trying to validate SEB exam configuration attributes: {}", ATTR_NAMES, e);
|
log.error("unexpected error while trying to validate SEB exam configuration attributes: {}", ATTR_NAMES, e);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -358,6 +358,7 @@ sebserver.examconfig.action.list.view=View Configuration
|
||||||
sebserver.examconfig.action.list.modify=Edit
|
sebserver.examconfig.action.list.modify=Edit
|
||||||
sebserver.examconfig.action.list.modify.properties=Edit Properties
|
sebserver.examconfig.action.list.modify.properties=Edit Properties
|
||||||
sebserver.examconfig.action.modify=Edit
|
sebserver.examconfig.action.modify=Edit
|
||||||
|
sebserver.examconfig.action.modify.properties=Edit Properties
|
||||||
sebserver.examconfig.action.save=Save
|
sebserver.examconfig.action.save=Save
|
||||||
|
|
||||||
sebserver.examconfig.form.title.new=New Exam Configuration
|
sebserver.examconfig.form.title.new=New Exam Configuration
|
||||||
|
@ -376,6 +377,7 @@ sebserver.examconfig.props.form.views.user_interface=User Interface
|
||||||
sebserver.examconfig.props.form.views.browser=Browser
|
sebserver.examconfig.props.form.views.browser=Browser
|
||||||
sebserver.examconfig.props.form.views.down_upload=Down/Uploads
|
sebserver.examconfig.props.form.views.down_upload=Down/Uploads
|
||||||
sebserver.examconfig.props.form.views.exam=Exam
|
sebserver.examconfig.props.form.views.exam=Exam
|
||||||
|
sebserver.examconfig.props.form.views.applications=Applications
|
||||||
|
|
||||||
sebserver.examconfig.props.label.hashedAdminPassword=Administrator password
|
sebserver.examconfig.props.label.hashedAdminPassword=Administrator password
|
||||||
sebserver.examconfig.props.label.hashedAdminPassword.confirm=Confirm password
|
sebserver.examconfig.props.label.hashedAdminPassword.confirm=Confirm password
|
||||||
|
@ -532,6 +534,42 @@ sebserver.examconfig.props.label.restartExamURL=Enter custom URL or select 'Use
|
||||||
sebserver.examconfig.props.label.restartExamText=Title/tool tip text for the back to start button (leave empty for localized standard text)
|
sebserver.examconfig.props.label.restartExamText=Title/tool tip text for the back to start button (leave empty for localized standard text)
|
||||||
sebserver.examconfig.props.label.restartExamPasswordProtected=Protect back to start button with the quit/unlock password
|
sebserver.examconfig.props.label.restartExamPasswordProtected=Protect back to start button with the quit/unlock password
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.allowSwitchToApplications=Allow switching to third party application (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=Permitted Processes
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.active=Activity
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.os=OS
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.os.0=Win
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.os.1=OS X
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.title=Title
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.description=Description
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.executable=Executable
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.originalName=Original Name
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.allowedExecutables=Window handling process
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.path=Path
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.arguments=Arguments
|
||||||
|
sebserver.examconfig.props.label.arguments.active=Activity
|
||||||
|
sebserver.examconfig.props.label.arguments.argument=Argument
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.identifier=Identifier
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.iconInTaskbar=Icon in taskbar
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.autostart=Autostart
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.runInBackground=Allow running in background
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.allowUserToChooseApp=Allow user to select location of application
|
||||||
|
sebserver.examconfig.props.label.permittedProcesses.strongKill=Force quit (risk of data loss)
|
||||||
|
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.row.title=Prohibited Processes
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses=Prohibited Processes
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.active=Activity
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.os=OS
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.os.0=Win
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.os.1=OS X
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.description=Description
|
||||||
|
sebserver.examconfig.props.label.prohibitedProcesses.executable=Executable
|
||||||
|
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.validation.password.confirm=Please enter correct confirm password
|
sebserver.examconfig.props.validation.password.confirm=Please enter correct confirm password
|
||||||
sebserver.examconfig.props.validation.unexpected=Unexpected error happened. Value was not set correctly
|
sebserver.examconfig.props.validation.unexpected=Unexpected error happened. Value was not set correctly
|
||||||
|
|
Loading…
Reference in a new issue