SEBSERV-96 added also create config action in template view
This commit is contained in:
parent
b0ca9dd136
commit
745e0870cb
18 changed files with 326 additions and 1292 deletions
|
@ -16,8 +16,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_NODE;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||
|
||||
public final class ConfigCopyInfo implements Entity {
|
||||
public final class ConfigCreationInfo implements Entity {
|
||||
|
||||
public static final String ATTR_COPY_WITH_HISTORY = "with-history";
|
||||
|
||||
|
@ -37,16 +38,23 @@ public final class ConfigCopyInfo implements Entity {
|
|||
@JsonProperty(ATTR_COPY_WITH_HISTORY)
|
||||
public final Boolean withHistory;
|
||||
|
||||
protected ConfigCopyInfo(
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_TYPE)
|
||||
public final ConfigurationType configurationType;
|
||||
|
||||
protected ConfigCreationInfo(
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_ID) final Long configurationNodeId,
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_NAME) final String name,
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_DESCRIPTION) final String description,
|
||||
@JsonProperty(ATTR_COPY_WITH_HISTORY) final Boolean withHistory) {
|
||||
@JsonProperty(ATTR_COPY_WITH_HISTORY) final Boolean withHistory,
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_TYPE) final ConfigurationType configurationType) {
|
||||
|
||||
this.configurationNodeId = configurationNodeId;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.withHistory = withHistory;
|
||||
this.configurationType = (configurationType != null)
|
||||
? configurationType
|
||||
: ConfigurationType.EXAM_CONFIG;
|
||||
}
|
||||
|
||||
public Long getConfigurationNodeId() {
|
||||
|
@ -66,6 +74,10 @@ public final class ConfigCopyInfo implements Entity {
|
|||
return this.withHistory;
|
||||
}
|
||||
|
||||
public ConfigurationType getConfigurationType() {
|
||||
return this.configurationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModelId() {
|
||||
return (this.configurationNodeId != null)
|
||||
|
@ -89,6 +101,8 @@ public final class ConfigCopyInfo implements Entity {
|
|||
builder.append(this.description);
|
||||
builder.append(", withHistory=");
|
||||
builder.append(this.withHistory);
|
||||
builder.append(", configurationType=");
|
||||
builder.append(this.configurationType);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
|
@ -14,6 +14,7 @@ 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;
|
||||
|
@ -275,6 +276,19 @@ public class ConfigTemplateForm implements TemplateComposer {
|
|||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(SebExamConfigCreationUtils.configCreationFunction(
|
||||
this.pageService,
|
||||
pageContext
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||
Constants.TRUE_STRING)
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||
Constants.FALSE_STRING)))
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_SAVE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(formHandle::processFormSave)
|
||||
|
|
|
@ -1,128 +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.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCopyInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
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.page.ModalInputDialogComposer;
|
||||
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.impl.ModalInputDialog;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.CopyConfiguration;
|
||||
|
||||
public final class SebExamConfigCopy {
|
||||
|
||||
static Function<PageAction, PageAction> copyConfigFunction(
|
||||
final PageService pageService,
|
||||
final PageContext pageContext) {
|
||||
|
||||
return action -> {
|
||||
|
||||
final ModalInputDialog<FormHandle<ConfigCopyInfo>> dialog =
|
||||
new ModalInputDialog<FormHandle<ConfigCopyInfo>>(
|
||||
action.pageContext().getParent().getShell(),
|
||||
pageService.getWidgetFactory())
|
||||
.setDialogWidth(600);
|
||||
|
||||
final CopyFormContext formContext = new CopyFormContext(
|
||||
pageService,
|
||||
action.pageContext());
|
||||
|
||||
final Predicate<FormHandle<ConfigCopyInfo>> doCopy = formHandle -> doCopy(
|
||||
pageService,
|
||||
pageContext,
|
||||
formHandle);
|
||||
|
||||
dialog.open(
|
||||
SebExamConfigPropForm.FORM_COPY_TEXT_KEY,
|
||||
doCopy,
|
||||
Utils.EMPTY_EXECUTION,
|
||||
formContext);
|
||||
|
||||
return action;
|
||||
};
|
||||
}
|
||||
|
||||
private static final boolean doCopy(
|
||||
final PageService pageService,
|
||||
final PageContext pageContext,
|
||||
final FormHandle<ConfigCopyInfo> formHandle) {
|
||||
|
||||
final ConfigurationNode newConfig = pageService.getRestService().getBuilder(CopyConfiguration.class)
|
||||
.withFormBinding(formHandle.getFormBinding())
|
||||
.call()
|
||||
.onError(formHandle::handleError)
|
||||
.getOr(null);
|
||||
|
||||
if (newConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PageAction viewNewConfig = pageService.pageActionBuilder(pageContext)
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
||||
.withEntityKey(new EntityKey(newConfig.id, EntityType.CONFIGURATION_NODE))
|
||||
.create();
|
||||
|
||||
pageService.executePageAction(viewNewConfig);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final class CopyFormContext implements ModalInputDialogComposer<FormHandle<ConfigCopyInfo>> {
|
||||
|
||||
private final PageService pageService;
|
||||
private final PageContext pageContext;
|
||||
|
||||
protected CopyFormContext(final PageService pageService, final PageContext pageContext) {
|
||||
this.pageService = pageService;
|
||||
this.pageContext = pageContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<FormHandle<ConfigCopyInfo>> compose(final Composite parent) {
|
||||
|
||||
final EntityKey entityKey = this.pageContext.getEntityKey();
|
||||
final FormHandle<ConfigCopyInfo> formHandle = this.pageService.formBuilder(
|
||||
this.pageContext.copyOf(parent), 4)
|
||||
.readonly(false)
|
||||
.putStaticValue(
|
||||
Domain.CONFIGURATION_NODE.ATTR_ID,
|
||||
entityKey.getModelId())
|
||||
.addField(FormBuilder.text(
|
||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||
SebExamConfigPropForm.FORM_NAME_TEXT_KEY))
|
||||
.addField(FormBuilder.text(
|
||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||
SebExamConfigPropForm.FORM_DESCRIPTION_TEXT_KEY)
|
||||
.asArea())
|
||||
.addField(FormBuilder.checkbox(
|
||||
ConfigCopyInfo.ATTR_COPY_WITH_HISTORY,
|
||||
SebExamConfigPropForm.FORM_HISTORY_TEXT_KEY))
|
||||
.build();
|
||||
|
||||
return () -> formHandle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCreationInfo;
|
||||
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.util.Utils;
|
||||
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.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
|
||||
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.impl.ModalInputDialog;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.CopyConfiguration;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
||||
|
||||
public final class SebExamConfigCreationUtils {
|
||||
|
||||
static final LocTextKey FORM_COPY_TEXT_KEY =
|
||||
new LocTextKey("sebserver.examconfig.action.copy.dialog");
|
||||
static final LocTextKey FORM_COPY_AS_TEMPLATE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.examconfig.action.copy-as-template.dialog");
|
||||
static final LocTextKey FORM_CREATE_FROM_TEMPLATE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.configtemplate.action.create-config.dialog");
|
||||
|
||||
static Function<PageAction, PageAction> configCreationFunction(
|
||||
final PageService pageService,
|
||||
final PageContext pageContext) {
|
||||
|
||||
final boolean copyAsTemplate = BooleanUtils.toBoolean(
|
||||
pageContext.getAttribute(PageContext.AttributeKeys.COPY_AS_TEMPLATE));
|
||||
final boolean createFromTemplate = BooleanUtils.toBoolean(
|
||||
pageContext.getAttribute(PageContext.AttributeKeys.CREATE_FROM_TEMPLATE));
|
||||
|
||||
return action -> {
|
||||
|
||||
final ModalInputDialog<FormHandle<ConfigCreationInfo>> dialog =
|
||||
new ModalInputDialog<FormHandle<ConfigCreationInfo>>(
|
||||
action.pageContext().getParent().getShell(),
|
||||
pageService.getWidgetFactory())
|
||||
.setDialogWidth(600);
|
||||
|
||||
final CreationFormContext formContext = new CreationFormContext(
|
||||
pageService,
|
||||
pageContext,
|
||||
copyAsTemplate,
|
||||
createFromTemplate);
|
||||
|
||||
final Predicate<FormHandle<ConfigCreationInfo>> doCopy = formHandle -> doCreate(
|
||||
pageService,
|
||||
pageContext,
|
||||
copyAsTemplate,
|
||||
createFromTemplate,
|
||||
formHandle);
|
||||
|
||||
final LocTextKey title = (copyAsTemplate)
|
||||
? FORM_COPY_AS_TEMPLATE_TEXT_KEY
|
||||
: (createFromTemplate)
|
||||
? FORM_CREATE_FROM_TEMPLATE_TEXT_KEY
|
||||
: FORM_COPY_TEXT_KEY;
|
||||
|
||||
dialog.open(
|
||||
title,
|
||||
doCopy,
|
||||
Utils.EMPTY_EXECUTION,
|
||||
formContext);
|
||||
|
||||
return action;
|
||||
};
|
||||
}
|
||||
|
||||
private static final boolean doCreate(
|
||||
final PageService pageService,
|
||||
final PageContext pageContext,
|
||||
final boolean copyAsTemplate,
|
||||
final boolean createFromTemplate,
|
||||
final FormHandle<ConfigCreationInfo> formHandle) {
|
||||
|
||||
// create either a new configuration form template or from other configuration
|
||||
final Class<? extends RestCall<ConfigurationNode>> restCall = (createFromTemplate)
|
||||
? NewExamConfig.class
|
||||
: CopyConfiguration.class;
|
||||
|
||||
final ConfigurationNode newConfig = pageService
|
||||
.getRestService()
|
||||
.getBuilder(restCall)
|
||||
.withFormBinding(formHandle.getFormBinding())
|
||||
.call()
|
||||
.onError(formHandle::handleError)
|
||||
.getOr(null);
|
||||
|
||||
if (newConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// view either new template or configuration
|
||||
final PageAction viewCopy = (copyAsTemplate)
|
||||
? pageService.pageActionBuilder(pageContext)
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW)
|
||||
.withEntityKey(new EntityKey(newConfig.id, EntityType.CONFIGURATION_NODE))
|
||||
.create()
|
||||
: pageService.pageActionBuilder(pageContext)
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
||||
.withEntityKey(new EntityKey(newConfig.id, EntityType.CONFIGURATION_NODE))
|
||||
.create();
|
||||
|
||||
pageService.executePageAction(viewCopy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final class CreationFormContext implements ModalInputDialogComposer<FormHandle<ConfigCreationInfo>> {
|
||||
|
||||
private final PageService pageService;
|
||||
private final PageContext pageContext;
|
||||
private final boolean copyAsTemplate;
|
||||
private final boolean createFromTemplate;
|
||||
|
||||
protected CreationFormContext(
|
||||
final PageService pageService,
|
||||
final PageContext pageContext,
|
||||
final boolean copyAsTemplate,
|
||||
final boolean createFromTemplate) {
|
||||
|
||||
this.pageService = pageService;
|
||||
this.pageContext = pageContext;
|
||||
this.copyAsTemplate = copyAsTemplate;
|
||||
this.createFromTemplate = createFromTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<FormHandle<ConfigCreationInfo>> compose(final Composite parent) {
|
||||
|
||||
final EntityKey entityKey = this.pageContext.getEntityKey();
|
||||
final FormHandle<ConfigCreationInfo> formHandle = this.pageService.formBuilder(
|
||||
this.pageContext.copyOf(parent), 4)
|
||||
.readonly(false)
|
||||
.putStaticValueIf(
|
||||
() -> !this.createFromTemplate,
|
||||
Domain.CONFIGURATION_NODE.ATTR_ID,
|
||||
entityKey.getModelId())
|
||||
.putStaticValue(
|
||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||
(this.copyAsTemplate)
|
||||
? ConfigurationType.TEMPLATE.name()
|
||||
: ConfigurationType.EXAM_CONFIG.name())
|
||||
.putStaticValueIf(
|
||||
() -> this.createFromTemplate,
|
||||
Domain.CONFIGURATION_NODE.ATTR_TEMPLATE_ID,
|
||||
entityKey.getModelId())
|
||||
.addField(FormBuilder.text(
|
||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||
SebExamConfigPropForm.FORM_NAME_TEXT_KEY))
|
||||
.addField(FormBuilder.text(
|
||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||
SebExamConfigPropForm.FORM_DESCRIPTION_TEXT_KEY)
|
||||
.asArea())
|
||||
.addFieldIf(
|
||||
() -> !this.copyAsTemplate && !this.createFromTemplate,
|
||||
() -> FormBuilder.checkbox(
|
||||
ConfigCreationInfo.ATTR_COPY_WITH_HISTORY,
|
||||
SebExamConfigPropForm.FORM_HISTORY_TEXT_KEY))
|
||||
.build();
|
||||
|
||||
return () -> formHandle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.Im
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ImportNewExamConfig;
|
||||
import ch.ethz.seb.sebserver.gui.widget.FileUploadSelection;
|
||||
|
||||
public final class SebExamConfigImport {
|
||||
public final class SebExamConfigImportUtils {
|
||||
|
||||
private final static PageMessageException MISSING_PASSWORD = new PageMessageException(
|
||||
new LocTextKey("sebserver.examconfig.action.import.missing-password"));
|
|
@ -208,7 +208,7 @@ public class SebExamConfigList implements TemplateComposer {
|
|||
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent())
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
||||
.withExec(SebExamConfigImport.importFunction(this.pageService, true))
|
||||
.withExec(SebExamConfigImportUtils.importFunction(this.pageService, true))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> examConfigGrant.im())
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
|
@ -99,8 +100,6 @@ public class SebExamConfigPropForm implements TemplateComposer {
|
|||
static final LocTextKey FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.examconfig.form.attched-to");
|
||||
|
||||
static final LocTextKey FORM_COPY_TEXT_KEY =
|
||||
new LocTextKey("sebserver.examconfig.action.copy");
|
||||
static final LocTextKey SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED =
|
||||
new LocTextKey("sebserver.examconfig.action.state-change.confirm");
|
||||
|
||||
|
@ -253,13 +252,32 @@ public class SebExamConfigPropForm implements TemplateComposer {
|
|||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(SebExamConfigImport.importFunction(this.pageService, false))
|
||||
.withExec(SebExamConfigImportUtils.importFunction(this.pageService, false))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> modifyGrant && isReadonly && !isAttachedToExam)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(SebExamConfigCopy.copyConfigFunction(this.pageService, actionContext))
|
||||
.withExec(SebExamConfigCreationUtils.configCreationFunction(
|
||||
this.pageService,
|
||||
actionContext
|
||||
.withEntityKey(entityKey)
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||
Constants.FALSE_STRING)
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||
Constants.FALSE_STRING)))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(SebExamConfigCreationUtils.configCreationFunction(
|
||||
this.pageService,
|
||||
pageContext.withAttribute(
|
||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||
Constants.TRUE_STRING)))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
|
||||
|
|
|
@ -175,6 +175,20 @@ public class SebExamConfigSettingsForm implements TemplateComposer {
|
|||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(SebExamConfigCreationUtils.configCreationFunction(
|
||||
this.pageService,
|
||||
pageContext
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||
Constants.TRUE_STRING)
|
||||
.withAttribute(
|
||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||
Constants.FALSE_STRING)))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> examConfigGrant.iw())
|
||||
|
||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
||||
.withEntityKey(entityKey)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
|
|
|
@ -421,6 +421,10 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.examconfig.action.copy"),
|
||||
ImageIcon.COPY,
|
||||
ActionCategory.FORM),
|
||||
SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE(
|
||||
new LocTextKey("sebserver.examconfig.action.copy-as-template"),
|
||||
ImageIcon.TEMPLATE,
|
||||
ActionCategory.FORM),
|
||||
|
||||
SEB_EXAM_CONFIG_MODIFY_FROM_LIST(
|
||||
new LocTextKey("sebserver.examconfig.action.list.modify"),
|
||||
|
@ -464,6 +468,11 @@ public enum ActionDefinition {
|
|||
ImageIcon.EDIT,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_EDIT,
|
||||
ActionCategory.FORM),
|
||||
SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG(
|
||||
new LocTextKey("sebserver.configtemplate.action.create-config"),
|
||||
ImageIcon.NEW,
|
||||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW,
|
||||
ActionCategory.FORM),
|
||||
SEB_EXAM_CONFIG_TEMPLATE_CANCEL_MODIFY(
|
||||
new LocTextKey("sebserver.overall.action.modify.cancel"),
|
||||
ImageIcon.CANCEL,
|
||||
|
|
|
@ -39,6 +39,9 @@ public interface PageContext {
|
|||
|
||||
public static final String IMPORT_FROM_QUIZ_DATA = "IMPORT_FROM_QUIZ_DATA";
|
||||
|
||||
public static final String COPY_AS_TEMPLATE = "COPY_AS_TEMPLATE";
|
||||
public static final String CREATE_FROM_TEMPLATE = "CREATE_FROM_TEMPLATE";
|
||||
|
||||
}
|
||||
|
||||
/** Get the I18nSupport service
|
||||
|
|
|
@ -407,7 +407,9 @@ public class EntityTable<ROW extends Entity> {
|
|||
}
|
||||
|
||||
final GridData gridData = (GridData) this.table.getLayoutData();
|
||||
gridData.heightHint = (page.content.size() * ROW_HEIGHT) + HEADER_HEIGHT;
|
||||
gridData.heightHint = (this.pageNumber > 1)
|
||||
? (this.pageSize * ROW_HEIGHT) + HEADER_HEIGHT
|
||||
: (page.content.size() * ROW_HEIGHT) + HEADER_HEIGHT;
|
||||
|
||||
for (final ROW row : page.content) {
|
||||
final TableItem item = new TableItem(this.table, SWT.NONE);
|
||||
|
|
|
@ -22,7 +22,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
|||
|
||||
public class TableNavigator {
|
||||
|
||||
private final static int PAGE_NAV_SIZE = 3;
|
||||
private final static int PAGE_NAV_SIZE = 10;
|
||||
|
||||
private final Composite composite;
|
||||
private final EntityTable<?> entityTable;
|
||||
|
@ -31,10 +31,6 @@ public class TableNavigator {
|
|||
this.composite = new Composite(entityTable.composite, SWT.NONE);
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||
this.composite.setLayoutData(gridData);
|
||||
|
||||
// TODO just for debugging, remove when tested
|
||||
// this.composite.setBackground(new Color(entityTable.composite.getDisplay(), new RGB(200, 0, 0)));
|
||||
|
||||
final GridLayout layout = new GridLayout(3, true);
|
||||
layout.marginLeft = 20;
|
||||
this.composite.setLayout(layout);
|
||||
|
@ -75,11 +71,20 @@ public class TableNavigator {
|
|||
|
||||
if (numberOfPages > 1) {
|
||||
createBackwardLabel(pageNumber > 1, pageNumber, numNav);
|
||||
final int pageNavSize = (numberOfPages > PAGE_NAV_SIZE) ? PAGE_NAV_SIZE : numberOfPages;
|
||||
final int half = pageNavSize / 2;
|
||||
int start = pageNumber - half;
|
||||
if (start < 1) {
|
||||
start = 1;
|
||||
}
|
||||
int end = start + pageNavSize;
|
||||
if (end > numberOfPages) {
|
||||
end = numberOfPages + 1;
|
||||
start = end - pageNavSize;
|
||||
}
|
||||
|
||||
for (int i = pageNumber - PAGE_NAV_SIZE; i < pageNumber + PAGE_NAV_SIZE; i++) {
|
||||
if (i >= 1 && i <= numberOfPages) {
|
||||
createPageNumberLabel(i, i != pageNumber, numNav);
|
||||
}
|
||||
for (int i = start; i < end; i++) {
|
||||
createPageNumberLabel(i, i != pageNumber, numNav);
|
||||
}
|
||||
|
||||
createForwardLabel(pageNumber < numberOfPages, pageNumber, numNav);
|
||||
|
@ -94,7 +99,11 @@ public class TableNavigator {
|
|||
pageHeader.setText("Page " + page + "/" + of);
|
||||
}
|
||||
|
||||
private void createPageNumberLabel(final int page, final boolean selectable, final Composite parent) {
|
||||
private void createPageNumberLabel(
|
||||
final int page,
|
||||
final boolean selectable,
|
||||
final Composite parent) {
|
||||
|
||||
final Label pageLabel = new Label(parent, SWT.NONE);
|
||||
|
||||
pageLabel.setText(" " + String.valueOf(page) + " ");
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCopyInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCreationInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO;
|
||||
|
@ -20,6 +20,6 @@ public interface ConfigurationNodeDAO extends
|
|||
Result<ConfigurationNode> createCopy(
|
||||
Long institutionId,
|
||||
String newOwner,
|
||||
ConfigCopyInfo copyInfo);
|
||||
ConfigCreationInfo copyInfo);
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.springframework.stereotype.Component;
|
|||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCopyInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCreationInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
|
@ -347,7 +347,7 @@ class ConfigurationDAOBatchService {
|
|||
Result<ConfigurationNode> createCopy(
|
||||
final Long institutionId,
|
||||
final String newOwner,
|
||||
final ConfigCopyInfo copyInfo) {
|
||||
final ConfigCreationInfo copyInfo) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
final ConfigurationNodeRecord sourceNode = this.batchConfigurationNodeRecordMapper
|
||||
|
@ -366,7 +366,7 @@ class ConfigurationDAOBatchService {
|
|||
private ConfigurationNodeRecord copyNodeRecord(
|
||||
final ConfigurationNodeRecord nodeRec,
|
||||
final String newOwner,
|
||||
final ConfigCopyInfo copyInfo) {
|
||||
final ConfigCreationInfo copyInfo) {
|
||||
|
||||
final ConfigurationNodeRecord newNodeRec = new ConfigurationNodeRecord(
|
||||
null,
|
||||
|
@ -375,8 +375,9 @@ class ConfigurationDAOBatchService {
|
|||
StringUtils.isNotBlank(newOwner) ? newOwner : nodeRec.getOwner(),
|
||||
copyInfo.getName(),
|
||||
copyInfo.getDescription(),
|
||||
nodeRec.getType(),
|
||||
copyInfo.configurationType.name(),
|
||||
ConfigurationStatus.CONSTRUCTION.name());
|
||||
|
||||
this.batchConfigurationNodeRecordMapper.insert(newNodeRec);
|
||||
this.batchSqlSessionTemplate.flushStatements();
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCopyInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCreationInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||
|
@ -197,9 +197,12 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
|
|||
public Result<ConfigurationNode> createCopy(
|
||||
final Long institutionId,
|
||||
final String newOwner,
|
||||
final ConfigCopyInfo copyInfo) {
|
||||
final ConfigCreationInfo copyInfo) {
|
||||
|
||||
return this.configurationDAOBatchService.createCopy(institutionId, newOwner, copyInfo);
|
||||
return this.configurationDAOBatchService.createCopy(
|
||||
institutionId,
|
||||
newOwner,
|
||||
copyInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,7 +44,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCopyInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigCreationInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||
|
@ -152,7 +152,7 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@Valid @RequestBody final ConfigCopyInfo copyInfo) {
|
||||
@Valid @RequestBody final ConfigCreationInfo copyInfo) {
|
||||
|
||||
this.entityDAO.byPK(copyInfo.configurationNodeId)
|
||||
.flatMap(this.authorization::checkWrite);
|
||||
|
@ -165,6 +165,13 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
institutionId,
|
||||
currentUser.getUserInfo().uuid,
|
||||
copyInfo)
|
||||
.map(config -> {
|
||||
if (config.type == ConfigurationType.TEMPLATE) {
|
||||
return this.createTemplate(config);
|
||||
} else {
|
||||
return config;
|
||||
}
|
||||
})
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -456,6 +456,9 @@ sebserver.examconfig.action.saveToHistory.integrity-violation=There is currently
|
|||
sebserver.examconfig.action.undo=Undo
|
||||
sebserver.examconfig.action.undo.success=Successfully reverted to last saved state
|
||||
sebserver.examconfig.action.copy=Copy Configuration
|
||||
sebserver.examconfig.action.copy.dialog=Exam Configuration
|
||||
sebserver.examconfig.action.copy-as-template=Save As Template
|
||||
sebserver.examconfig.action.copy-as-template.dialog=Configuration Template
|
||||
sebserver.examconfig.action.export.plainxml=Export Configuration
|
||||
sebserver.examconfig.action.get-config-key=Export Config-Key
|
||||
sebserver.examconfig.action.import-config=Import Exam Configuration
|
||||
|
@ -961,15 +964,17 @@ sebserver.configtemplate.info.pleaseSelect=Please select an exam configuration t
|
|||
|
||||
sebserver.configtemplate.action.list.new=Add Configuration Template
|
||||
sebserver.configtemplate.action.list.view=View Configuration Template
|
||||
sebserver.configtemplate.action.view=View Configuration Template
|
||||
sebserver.configtemplate.action.list.modify=Edit Configuration Template
|
||||
sebserver.configtemplate.action.modify=Edit Configuration Template
|
||||
sebserver.configtemplate.action.view=View Template
|
||||
sebserver.configtemplate.action.list.modify=Edit Template
|
||||
sebserver.configtemplate.action.modify=Edit Template
|
||||
sebserver.configtemplate.action.create-config=Create Configuration
|
||||
sebserver.configtemplate.action.create-config.dialog=Exam Configuration
|
||||
|
||||
sebserver.configtemplate.form.title.new=Add Configuration Template
|
||||
sebserver.configtemplate.form.title.new=Add Template
|
||||
sebserver.configtemplate.form.title=Configuration Template
|
||||
sebserver.configtemplate.form.name=Name
|
||||
sebserver.configtemplate.form.description=Description
|
||||
sebserver.configtemplate.action.save=Save Configuration Template
|
||||
sebserver.configtemplate.action.save=Save Template
|
||||
|
||||
sebserver.configtemplate.attr.type.TEXT_FIELD=Text Field
|
||||
sebserver.configtemplate.attr.type.PASSWORD_FIELD=Password Field
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue