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(COMPOSITE_LIST),
|
||||
|
||||
STATIC_TABLE(COMPOSITE_LIST);
|
||||
INLINE_TABLE(COMPOSITE_LIST),
|
||||
|
||||
;
|
||||
|
||||
public final AttributeValueType attributeValueType;
|
||||
|
||||
|
|
|
@ -8,33 +8,38 @@
|
|||
|
||||
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.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||
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.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.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
|
||||
|
@ -44,127 +49,92 @@ public class SebExamConfigForm implements TemplateComposer {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigForm.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 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 SebExamConfigForm(
|
||||
final PageService pageService,
|
||||
final RestService restService,
|
||||
final CurrentUser currentUser) {
|
||||
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 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);
|
||||
pageContext.getParent(),
|
||||
TITLE_TEXT_KEY);
|
||||
|
||||
// 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));
|
||||
try {
|
||||
|
||||
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)
|
||||
.publishIf(() -> writeGrant && isReadonly)
|
||||
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();
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
final AttributeMapping attributes = this.examConfigurationService
|
||||
.getAttributes(configNode.templateId)
|
||||
.onError(pageContext::notifyError)
|
||||
.getOrThrow();
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(formHandle::processFormSave)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> !isReadonly)
|
||||
final List<View> views = this.examConfigurationService.getViews(attributes);
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_CANCEL_MODIFY)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
|
||||
action,
|
||||
ActionDefinition.SEB_EXAM_CONFIG_LIST))
|
||||
.publishIf(() -> !isReadonly);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SebExamConfigList implements TemplateComposer {
|
|||
this.statusFilter,
|
||||
true))
|
||||
.withDefaultAction(pageActionBuilder
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_FROM_LIST)
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
||||
.create())
|
||||
.compose(content);
|
||||
|
||||
|
@ -147,15 +147,15 @@ public class SebExamConfigList implements TemplateComposer {
|
|||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.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(
|
||||
new LocTextKey("sebserver.examconfig.action.list.new"),
|
||||
ImageIcon.NEW,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT),
|
||||
SEB_EXAM_CONFIG_VIEW_FROM_LIST(
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT),
|
||||
SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.view"),
|
||||
ImageIcon.SHOW,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
||||
ActionCategory.SEB_EXAM_CONFIG_LIST),
|
||||
SEB_EXAM_CONFIG_MODIFY_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.modify"),
|
||||
SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.modify.properties"),
|
||||
ImageIcon.EDIT,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT,
|
||||
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(
|
||||
new LocTextKey("sebserver.examconfig.action.modify"),
|
||||
ImageIcon.EDIT,
|
||||
|
@ -334,10 +339,10 @@ public enum ActionDefinition {
|
|||
PageStateDefinition.SEB_EXAM_CONFIG_VIEW,
|
||||
ActionCategory.FORM),
|
||||
|
||||
SEB_EXAM_CONFIG_MODIFY_PROPERTIES_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.modify.properties"),
|
||||
SEB_EXAM_CONFIG_MODIFY_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.modify"),
|
||||
ImageIcon.EDIT,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_PROPERTIES_EDIT,
|
||||
PageStateDefinition.SEB_EXAM_CONFIG_EDIT,
|
||||
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.SebExamConfigForm;
|
||||
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.UserAccountForm;
|
||||
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_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_EDIT(Type.FORM_EDIT, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||
SEB_EXAM_CONFIG_PROPERTIES_EDIT(Type.FORM_VIEW, SebExamConfigPropertiesForm.class,
|
||||
ActivityDefinition.SEB_EXAM_CONFIG),
|
||||
SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||
SEB_EXAM_CONFIG_PROP_EDIT(Type.FORM_EDIT, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||
SEB_EXAM_CONFIG_EDIT(Type.FORM_VIEW, SebExamConfigForm.class, 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 GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group.";
|
||||
public static final String TOOL_TIP_SUFFIX = ".tooltip";
|
||||
public static final String TABLE_ROW_TITLE_SUFFIX = ".row.title";
|
||||
|
||||
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 getReadableValue();
|
||||
|
||||
void showError(String errorMessage);
|
||||
|
||||
void clearError();
|
||||
|
|
|
@ -48,13 +48,15 @@ public interface InputFieldBuilder {
|
|||
|
||||
static Composite createInnerGrid(
|
||||
final Composite parent,
|
||||
final ConfigurationAttribute attribute,
|
||||
final Orientation orientation) {
|
||||
|
||||
return createInnerGrid(parent, orientation, 1);
|
||||
return createInnerGrid(parent, attribute, orientation, 1);
|
||||
}
|
||||
|
||||
static Composite createInnerGrid(
|
||||
final Composite parent,
|
||||
final ConfigurationAttribute attribute,
|
||||
final Orientation orientation,
|
||||
final int numColumns) {
|
||||
|
||||
|
@ -69,8 +71,8 @@ public interface InputFieldBuilder {
|
|||
final GridData gridData = new GridData(
|
||||
SWT.FILL, SWT.FILL,
|
||||
true, false,
|
||||
(orientation != null) ? orientation.width() : 1,
|
||||
(orientation != null) ? orientation.height() : 1);
|
||||
(orientation != null && attribute.parentId == null) ? orientation.width() : 1,
|
||||
(orientation != null && attribute.parentId == null) ? orientation.height() : 1);
|
||||
comp.setLayoutData(gridData);
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
|
@ -45,11 +45,6 @@ public class AttributeMapping {
|
|||
Objects.requireNonNull(orientations);
|
||||
|
||||
this.templateId = templateId;
|
||||
this.attributeIdMapping = Utils.immutableMapOf(attributes
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
attr -> attr.id,
|
||||
Function.identity())));
|
||||
|
||||
this.orientationAttributeMapping = Utils.immutableMapOf(orientations
|
||||
.stream()
|
||||
|
@ -57,8 +52,16 @@ public class AttributeMapping {
|
|||
o -> o.attributeId,
|
||||
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
|
||||
.stream()
|
||||
.filter(attr -> this.orientationAttributeMapping.containsKey(attr.id))
|
||||
.collect(Collectors.toMap(
|
||||
attr -> attr.name,
|
||||
attr -> attr.id)));
|
||||
|
@ -71,6 +74,7 @@ public class AttributeMapping {
|
|||
|
||||
this.childAttributeMapping = Utils.immutableMapOf(attributes
|
||||
.stream()
|
||||
.filter(attr -> this.orientationAttributeMapping.containsKey(attr.id))
|
||||
.collect(Collectors.toMap(
|
||||
attr -> attr.id,
|
||||
this::getChildAttributes)));
|
||||
|
@ -184,7 +188,7 @@ public class AttributeMapping {
|
|||
.values()
|
||||
.stream()
|
||||
.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.yPosition.compareTo(o2.yPosition))
|
||||
.map(o -> this.attributeIdMapping.get(o.attributeId))
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||
|
||||
import static ch.ethz.seb.sebserver.gui.service.examconfig.impl.CellFieldBuilderAdapter.dummyBuilderAdapter;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
|
@ -28,6 +30,10 @@ interface CellFieldBuilderAdapter {
|
|||
|
||||
void createCell(ViewGridBuilder builder);
|
||||
|
||||
default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||
|
||||
}
|
||||
|
||||
static CellFieldBuilderAdapter dummyBuilderAdapter() {
|
||||
return new CellFieldBuilderAdapter() {
|
||||
@Override
|
||||
|
@ -71,6 +77,9 @@ interface CellFieldBuilderAdapter {
|
|||
final Orientation orientation) {
|
||||
|
||||
return new CellFieldBuilderAdapter() {
|
||||
|
||||
private int span = 1;
|
||||
|
||||
@Override
|
||||
public void createCell(final ViewGridBuilder builder) {
|
||||
|
||||
|
@ -88,21 +97,16 @@ interface CellFieldBuilderAdapter {
|
|||
gridData.verticalIndent = 5;
|
||||
break;
|
||||
}
|
||||
case RIGHT_SPAN:
|
||||
case LEFT_SPAN: {
|
||||
label.setAlignment(SWT.LEFT);
|
||||
gridData.horizontalSpan = orientation.width;
|
||||
gridData.horizontalSpan = (span > 1) ? span : orientation.width;
|
||||
gridData.verticalIndent = 5;
|
||||
break;
|
||||
}
|
||||
case RIGHT_SPAN: {
|
||||
label.setAlignment(SWT.LEFT);
|
||||
gridData.verticalIndent = 5;
|
||||
gridData.horizontalSpan = orientation.width;
|
||||
break;
|
||||
}
|
||||
case TOP: {
|
||||
gridData.horizontalSpan = orientation.width;
|
||||
label.setAlignment(SWT.LEFT);
|
||||
gridData.verticalAlignment = SWT.BOTTOM;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -114,6 +118,22 @@ interface CellFieldBuilderAdapter {
|
|||
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
|
||||
public String toString() {
|
||||
return "[LABEL]";
|
||||
|
@ -185,7 +205,7 @@ interface CellFieldBuilderAdapter {
|
|||
builder.parent,
|
||||
this.width,
|
||||
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(
|
||||
group,
|
||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
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.ConfigurationAttribute;
|
||||
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.gui.service.examconfig.ExamConfigurationService;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||
|
@ -64,14 +66,20 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
|||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final Button checkbox = this.widgetFactory.buttonLocalized(
|
||||
innerGrid,
|
||||
SWT.CHECK,
|
||||
ExamConfigurationService.attributeNameLocKey(attribute),
|
||||
(orientation.title == TitleOrientation.NONE)
|
||||
? ExamConfigurationService.attributeNameLocKey(attribute)
|
||||
: null,
|
||||
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(
|
||||
attribute,
|
||||
viewContext.getOrientation(attribute.id),
|
||||
|
@ -95,9 +103,7 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
|||
final Orientation orientation,
|
||||
final Button control) {
|
||||
|
||||
super(attribute, orientation, control, (orientation.groupId == null)
|
||||
? InputFieldBuilder.createErrorLabel(control.getParent())
|
||||
: null);
|
||||
super(attribute, orientation, control, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,6 +117,14 @@ public class CheckBoxBuilder implements InputFieldBuilder {
|
|||
? Constants.TRUE_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
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final MultiSelectionCheckbox selection = this.widgetFactory.selectionLocalized(
|
||||
Selection.Type.MULTI_CHECKBOX,
|
||||
innerGrid,
|
||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
||||
() -> this.getLocalizedResources(attribute, viewContext),
|
||||
null,
|
||||
() -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport))
|
||||
() -> this.getLocalizedResourcesAsToolTip(attribute, viewContext))
|
||||
.getTypeInstance();
|
||||
|
||||
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||
|
|
|
@ -64,7 +64,7 @@ public class PassworFieldBuilder implements InputFieldBuilder {
|
|||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final Text passwordInput = new Text(innerGrid, SWT.LEFT | SWT.BORDER | SWT.PASSWORD);
|
||||
passwordInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||
|
|
|
@ -56,14 +56,14 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements
|
|||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final RadioSelection selection = this.widgetFactory.selectionLocalized(
|
||||
Selection.Type.RADIO,
|
||||
innerGrid,
|
||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
||||
() -> this.getLocalizedResources(attribute, viewContext),
|
||||
null,
|
||||
() -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport))
|
||||
() -> this.getLocalizedResourcesAsToolTip(attribute, viewContext))
|
||||
.getTypeInstance();
|
||||
|
||||
selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||
|
@ -71,7 +71,7 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements
|
|||
attribute,
|
||||
orientation,
|
||||
selection,
|
||||
InputFieldBuilder.createErrorLabel(innerGrid));
|
||||
null);
|
||||
|
||||
selection.setSelectionListener(event -> {
|
||||
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.Utils;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
|
||||
public abstract class SelectionFieldBuilder {
|
||||
|
||||
protected List<Tuple<String>> getLocalizedResources(
|
||||
final ConfigurationAttribute attribute,
|
||||
final I18nSupport i18nSupport) {
|
||||
final ViewContext viewContext) {
|
||||
|
||||
return getLocalizedRes(attribute, i18nSupport, false);
|
||||
return getLocalizedRes(attribute, viewContext, false);
|
||||
}
|
||||
|
||||
protected List<Tuple<String>> getLocalizedResourcesAsToolTip(
|
||||
final ConfigurationAttribute attribute,
|
||||
final I18nSupport i18nSupport) {
|
||||
final ViewContext viewContext) {
|
||||
|
||||
return getLocalizedRes(attribute, i18nSupport, true);
|
||||
return getLocalizedRes(attribute, viewContext, true);
|
||||
}
|
||||
|
||||
private List<Tuple<String>> getLocalizedRes(
|
||||
final ConfigurationAttribute attribute,
|
||||
final I18nSupport i18nSupport,
|
||||
final ViewContext viewContext,
|
||||
final boolean toolTipResources) {
|
||||
|
||||
if (attribute == null) {
|
||||
|
@ -62,7 +61,7 @@ public abstract class SelectionFieldBuilder {
|
|||
final String key = prefix + value + ((toolTipResources)
|
||||
? ExamConfigurationService.TOOL_TIP_SUFFIX
|
||||
: "");
|
||||
final String text = i18nSupport.getText(key, "");
|
||||
final String text = viewContext.i18nSupport.getText(key, "");
|
||||
return new Tuple<>(value, (StringUtils.isBlank(text))
|
||||
? (toolTipResources)
|
||||
? text
|
||||
|
|
|
@ -57,14 +57,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement
|
|||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final SingleSelection selection = this.widgetFactory.selectionLocalized(
|
||||
(attribute.type == AttributeType.COMBO_SELECTION)
|
||||
? Selection.Type.SINGLE_COMBO
|
||||
: Selection.Type.SINGLE,
|
||||
innerGrid,
|
||||
() -> this.getLocalizedResources(attribute, i18nSupport),
|
||||
() -> this.getLocalizedResources(attribute, viewContext),
|
||||
ExamConfigurationService.getToolTipKey(attribute, i18nSupport))
|
||||
.getTypeInstance();
|
||||
|
||||
|
@ -107,6 +107,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement
|
|||
protected void setValueToControl(final String 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
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final Slider slider = new Slider(innerGrid, SWT.NONE);
|
||||
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.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.slf4j.Logger;
|
||||
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.ConfigurationTableValues.TableValue;
|
||||
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.InputFieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
||||
|
@ -58,8 +60,8 @@ public class TableContext {
|
|||
this.attribute = Objects.requireNonNull(attribute);
|
||||
this.viewContext = Objects.requireNonNull(viewContext);
|
||||
|
||||
this.orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
this.orientation = Objects.requireNonNull(viewContext
|
||||
.getOrientation(attribute.id));
|
||||
|
||||
this.rowAttributes = viewContext.getChildAttributes(attribute.id)
|
||||
.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.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
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.InputFieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
@ -105,15 +103,16 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
true, false,
|
||||
(tableContext.orientation != null) ? tableContext.orientation.width() : 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.setHeaderVisible(true);
|
||||
table.addListener(SWT.Resize, this::adaptColumnWidth);
|
||||
table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext));
|
||||
|
||||
for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) {
|
||||
final TableColumn column = new TableColumn(table, SWT.NONE);
|
||||
final String text = i18nSupport.getText(
|
||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + columnAttribute.name,
|
||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||
columnAttribute.name,
|
||||
columnAttribute.name);
|
||||
column.setText(text);
|
||||
column.setWidth(100);
|
||||
|
@ -159,14 +158,25 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
return tableField;
|
||||
}
|
||||
|
||||
private void adaptColumnWidth(final Event event) {
|
||||
private void adaptColumnWidth(
|
||||
final Table table,
|
||||
final TableContext tableContext) {
|
||||
|
||||
try {
|
||||
final Table table = (Table) event.widget;
|
||||
final int currentTableWidth = table.getClientArea().width - 50;
|
||||
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++) {
|
||||
columns[i].setWidth(columnWidth);
|
||||
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to adaptColumnWidth: ", e);
|
||||
|
@ -196,6 +206,12 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
.map(TableValue::of)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
initValue(tableValues);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void initValue(final List<TableValue> tableValues) {
|
||||
final Map<Integer, Map<Long, TableValue>> _initValue = new HashMap<>();
|
||||
for (final TableValue tableValue : tableValues) {
|
||||
final Map<Long, TableValue> rowValues = _initValue.computeIfAbsent(
|
||||
|
@ -215,13 +231,24 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
this.values.add(rowValues);
|
||||
addTableRow(rowValues);
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isChildValue(final ConfigurationValue value) {
|
||||
return this.attribute.id.equals(
|
||||
this.tableContext.getAttribute(value.attributeId).parentId);
|
||||
if (!this.tableContext.getViewContext().attributeMapping.attributeIdMapping
|
||||
.containsKey(value.attributeId)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigurationAttribute attr = this.tableContext.getAttribute(value.attributeId);
|
||||
while (attr.parentId != null) {
|
||||
if (this.attribute.id.equals(attr.parentId)) {
|
||||
return true;
|
||||
}
|
||||
attr = this.tableContext.getAttribute(attr.parentId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deleteRow(final int selectionIndex) {
|
||||
|
@ -254,22 +281,7 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
final TableItem tableItem = new TableItem(this.control, SWT.NONE);
|
||||
applyTableRowValues(this.values.size() - 1);
|
||||
|
||||
// TODO delete icon is not working on row as expected
|
||||
// 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);
|
||||
|
||||
// TODO try to add delete button within table row?
|
||||
}
|
||||
|
||||
private void applyTableRowValues(final int index) {
|
||||
|
@ -279,7 +291,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
int cellIndex = 0;
|
||||
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
||||
if (rowValues.containsKey(attr.id)) {
|
||||
item.setText(cellIndex, rowValues.get(attr.id).value);
|
||||
item.setText(
|
||||
cellIndex,
|
||||
this.tableContext.getRowValue(rowValues.get(attr.id)));
|
||||
}
|
||||
cellIndex++;
|
||||
}
|
||||
|
@ -299,7 +313,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
this.tableContext.getWidgetFactory())
|
||||
.setDialogWidth(500)
|
||||
.open(
|
||||
new LocTextKey("Title"),
|
||||
ExamConfigurationService.getTablePopupTitleKey(
|
||||
this.attribute,
|
||||
this.tableContext.getViewContext().i18nSupport),
|
||||
values -> applyFormValues(values, selectionIndex),
|
||||
builder);
|
||||
}
|
||||
|
@ -313,6 +329,9 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
this.values.remove(index);
|
||||
this.values.add(index, tableRowValues);
|
||||
applyTableRowValues(index);
|
||||
// send new values to web-service
|
||||
this.tableContext.getValueChangeListener()
|
||||
.tableChanged(extractTableValue());
|
||||
}
|
||||
|
||||
private ConfigurationTableValues extractTableValue() {
|
||||
|
@ -353,12 +372,13 @@ public class TableFieldBuilder implements InputFieldBuilder {
|
|||
|
||||
@Override
|
||||
protected void setValueToControl(final String value) {
|
||||
throw new UnsupportedOperationException();
|
||||
//throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
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.InputField;
|
||||
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.page.ModalInputDialogComposer;
|
||||
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 ConfigurationAttribute attribute) {
|
||||
|
||||
if (attribute.type == AttributeType.TABLE) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Table type is currently not supported within a table row form view!");
|
||||
}
|
||||
// if (attribute.type == AttributeType.TABLE) {
|
||||
// throw new UnsupportedOperationException(
|
||||
// "Table type is currently not supported within a table row form view!");
|
||||
// }
|
||||
|
||||
final Orientation orientation = this.tableContext
|
||||
.getOrientation(attribute.id);
|
||||
|
||||
final InputFieldBuilder inputFieldBuilder = this.tableContext
|
||||
.getInputFieldBuilder(attribute, orientation);
|
||||
|
||||
final InputField inputField = inputFieldBuilder.createInputField(
|
||||
parent,
|
||||
attribute,
|
||||
this.tableContext.getViewContext());
|
||||
|
||||
inputField.initValue(
|
||||
this.rowValues.get(attribute.id).value,
|
||||
this.listIndex);
|
||||
if (attribute.type == AttributeType.TABLE) {
|
||||
((TableInputField) inputField).initValue(new ArrayList<>(this.rowValues.values()));
|
||||
} 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
|
||||
this.tableContext.registerInputField(inputField);
|
||||
|
@ -108,9 +111,13 @@ public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, T
|
|||
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(
|
||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name,
|
||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||
attribute.name,
|
||||
attribute.name);
|
||||
final Label label = this.tableContext
|
||||
.getWidgetFactory()
|
||||
|
|
|
@ -61,7 +61,7 @@ public class TextFieldBuilder implements InputFieldBuilder {
|
|||
final Orientation orientation = viewContext
|
||||
.getOrientation(attribute.id);
|
||||
final Composite innerGrid = InputFieldBuilder
|
||||
.createInnerGrid(parent, orientation);
|
||||
.createInnerGrid(parent, attribute, orientation);
|
||||
|
||||
final Text text;
|
||||
if (attribute.type == AttributeType.INTEGER ||
|
||||
|
|
|
@ -33,10 +33,10 @@ public final class ViewContext {
|
|||
private final View view;
|
||||
private final int rows;
|
||||
|
||||
private final AttributeMapping attributeMapping;
|
||||
private final Map<Long, InputField> inputFieldMapping;
|
||||
private final ValueChangeListener valueChangeListener;
|
||||
private final I18nSupport i18nSupport;
|
||||
final AttributeMapping attributeMapping;
|
||||
final Map<Long, InputField> inputFieldMapping;
|
||||
final ValueChangeListener valueChangeListener;
|
||||
final I18nSupport i18nSupport;
|
||||
|
||||
ViewContext(
|
||||
final Configuration configuration,
|
||||
|
|
|
@ -67,6 +67,10 @@ public class ViewGridBuilder {
|
|||
}
|
||||
|
||||
ViewGridBuilder add(final ConfigurationAttribute attribute) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Add SEB Configuration Attribute: " + attribute);
|
||||
}
|
||||
|
||||
// ignore nested attributes here
|
||||
if (attribute.parentId != null) {
|
||||
return this;
|
||||
|
@ -115,7 +119,8 @@ public class ViewGridBuilder {
|
|||
orientation);
|
||||
break;
|
||||
}
|
||||
case LEFT: {
|
||||
case LEFT:
|
||||
case LEFT_SPAN: {
|
||||
this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder(
|
||||
attribute,
|
||||
orientation);
|
||||
|
@ -127,17 +132,17 @@ public class ViewGridBuilder {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case LEFT_SPAN: {
|
||||
int spanxpos = xpos - orientation.width;
|
||||
if (spanxpos < 0) {
|
||||
spanxpos = 0;
|
||||
}
|
||||
fillDummy(spanxpos, ypos, orientation.width, 1);
|
||||
this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||
attribute,
|
||||
orientation);
|
||||
break;
|
||||
}
|
||||
// case LEFT_SPAN: {
|
||||
// int spanxpos = xpos - orientation.width;
|
||||
// if (spanxpos < 0) {
|
||||
// spanxpos = 0;
|
||||
// }
|
||||
// fillDummy(spanxpos, ypos, orientation.width, 1);
|
||||
// this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||
// attribute,
|
||||
// orientation);
|
||||
// break;
|
||||
// }
|
||||
case TOP: {
|
||||
fillDummy(xpos, ypos - 1, orientation.width, 1);
|
||||
this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||
|
@ -160,9 +165,11 @@ public class ViewGridBuilder {
|
|||
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 x = 0; x < this.grid[y].length; x++) {
|
||||
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);
|
||||
gridData.verticalIndent = 8;
|
||||
empty.setLayoutData(gridData);
|
||||
empty.setText("");
|
||||
empty.setText("" /* "empty " + x + " " + y */);
|
||||
} else {
|
||||
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();
|
||||
|
||||
default String getSelectionReadableValue() {
|
||||
return getSelectionValue();
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
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.Listener;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectionReadableValue() {
|
||||
final int selectionindex = super.getSelectionIndex();
|
||||
if (selectionindex < 0) {
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
|
||||
return this.valueMapping.get(selectionindex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clearSelection();
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator {
|
|||
}
|
||||
|
||||
try {
|
||||
return this.configurationValueRecordMapper.selectByExample()
|
||||
return !this.configurationValueRecordMapper.selectByExample()
|
||||
.join(ConfigurationAttributeRecordDynamicSqlSupport.configurationAttributeRecord)
|
||||
.on(
|
||||
ConfigurationAttributeRecordDynamicSqlSupport.id,
|
||||
|
@ -75,7 +75,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator {
|
|||
.stream()
|
||||
.filter(val -> value.value.equals(val.getValue()))
|
||||
.findFirst()
|
||||
.isEmpty();
|
||||
.isPresent();
|
||||
} catch (final Exception e) {
|
||||
log.error("unexpected error while trying to validate SEB exam configuration attributes: {}", ATTR_NAMES, e);
|
||||
return true;
|
||||
|
|
|
@ -358,6 +358,7 @@ sebserver.examconfig.action.list.view=View Configuration
|
|||
sebserver.examconfig.action.list.modify=Edit
|
||||
sebserver.examconfig.action.list.modify.properties=Edit Properties
|
||||
sebserver.examconfig.action.modify=Edit
|
||||
sebserver.examconfig.action.modify.properties=Edit Properties
|
||||
sebserver.examconfig.action.save=Save
|
||||
|
||||
sebserver.examconfig.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.down_upload=Down/Uploads
|
||||
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.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.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.unexpected=Unexpected error happened. Value was not set correctly
|
||||
|
|
Loading…
Reference in a new issue