SEBSERV-287 finished implementation
This commit is contained in:
parent
e6697dd340
commit
eb46de835a
5 changed files with 108 additions and 26 deletions
|
@ -417,6 +417,16 @@ public enum ActionDefinition {
|
|||
ImageIcon.DELETE,
|
||||
PageStateDefinitionImpl.EXAM_TEMPLATE_LIST,
|
||||
ActionCategory.FORM),
|
||||
EXAM_TEMPLATE_PROCTORING_ON(
|
||||
new LocTextKey("sebserver.examtemplate.proctoring.actions.open"),
|
||||
ImageIcon.VISIBILITY,
|
||||
PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
|
||||
ActionCategory.FORM),
|
||||
EXAM_TEMPLATE_PROCTORING_OFF(
|
||||
new LocTextKey("sebserver.examtemplate.proctoring.actions.open"),
|
||||
ImageIcon.VISIBILITY_OFF,
|
||||
PageStateDefinitionImpl.EXAM_TEMPLATE_VIEW,
|
||||
ActionCategory.FORM),
|
||||
|
||||
INDICATOR_TEMPLATE_NEW(
|
||||
new LocTextKey("sebserver.examtemplate.indicator.action.list.new"),
|
||||
|
|
|
@ -23,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
|
@ -39,10 +40,12 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteExamTemplate;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicatorTemplate;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplate;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamTemplateProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicatorTemplatePage;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.NewExamTemplate;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExamTemplate;
|
||||
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.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
|
@ -93,13 +96,17 @@ public class ExamTemplateForm implements TemplateComposer {
|
|||
private final ResourceService resourceService;
|
||||
private final WidgetFactory widgetFactory;
|
||||
private final RestService restService;
|
||||
private final ProctoringSettingsPopup proctoringSettingsPopup;
|
||||
|
||||
public ExamTemplateForm(final PageService pageService) {
|
||||
public ExamTemplateForm(
|
||||
final PageService pageService,
|
||||
final ProctoringSettingsPopup proctoringSettingsPopup) {
|
||||
|
||||
this.pageService = pageService;
|
||||
this.resourceService = pageService.getResourceService();
|
||||
this.widgetFactory = pageService.getWidgetFactory();
|
||||
this.restService = pageService.getRestService();
|
||||
this.proctoringSettingsPopup = proctoringSettingsPopup;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,7 +192,16 @@ public class ExamTemplateForm implements TemplateComposer {
|
|||
? this.restService.getRestCall(NewExamTemplate.class)
|
||||
: this.restService.getRestCall(SaveExamTemplate.class));
|
||||
|
||||
final boolean proctoringEnabled = this.restService
|
||||
.getBuilder(GetExamTemplateProctoringSettings.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||
.call()
|
||||
.map(ProctoringServiceSettings::getEnableProctoring)
|
||||
.getOr(false);
|
||||
|
||||
final GrantCheck userGrant = currentUser.grantCheck(EntityType.EXAM_TEMPLATE);
|
||||
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(examTemplate);
|
||||
final boolean modifyGrant = userGrantCheck.m();
|
||||
// propagate content actions to action-pane
|
||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||
|
||||
|
@ -210,7 +226,17 @@ public class ExamTemplateForm implements TemplateComposer {
|
|||
.withExec(this::deleteExamTemplate)
|
||||
.publishIf(() -> userGrant.iw() && readonly)
|
||||
|
||||
;
|
||||
.newAction(ActionDefinition.EXAM_TEMPLATE_PROCTORING_ON)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(this.proctoringSettingsPopup.settingsFunction(this.pageService, modifyGrant))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> proctoringEnabled && readonly)
|
||||
|
||||
.newAction(ActionDefinition.EXAM_TEMPLATE_PROCTORING_OFF)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(this.proctoringSettingsPopup.settingsFunction(this.pageService, modifyGrant))
|
||||
.noEventPropagation()
|
||||
.publishIf(() -> !proctoringEnabled && readonly);
|
||||
|
||||
if (readonly) {
|
||||
|
||||
|
|
|
@ -193,7 +193,10 @@ public class ProctoringSettingsPopup {
|
|||
|
||||
if (saveOk) {
|
||||
final PageAction action = pageService.pageActionBuilder(pageContext)
|
||||
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
|
||||
.newAction(
|
||||
entityKey.entityType == EntityType.EXAM
|
||||
? ActionDefinition.EXAM_VIEW_FROM_LIST
|
||||
: ActionDefinition.EXAM_TEMPLATE_VIEW_FROM_LIST)
|
||||
.create();
|
||||
|
||||
pageService.firePageEvent(
|
||||
|
|
|
@ -28,6 +28,7 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
|||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
|
||||
|
@ -44,6 +45,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamTemplateDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.IndicatorDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamTemplateService;
|
||||
|
@ -177,28 +179,7 @@ public class ExamTemplateServiceImpl implements ExamTemplateService {
|
|||
|
||||
if (examTemplate.configTemplateId != null) {
|
||||
|
||||
// create new exam configuration for the exam
|
||||
final ConfigurationNode configurationNode = new ConfigurationNode(
|
||||
null,
|
||||
exam.institutionId,
|
||||
examTemplate.configTemplateId,
|
||||
replaceVars(this.defaultExamConfigNameTemplate, exam, examTemplate),
|
||||
replaceVars(this.defaultExamConfigDescTemplate, exam, examTemplate),
|
||||
ConfigurationType.EXAM_CONFIG,
|
||||
exam.owner,
|
||||
ConfigurationStatus.IN_USE);
|
||||
|
||||
final ConfigurationNode examConfig = this.configurationNodeDAO
|
||||
.createNew(configurationNode)
|
||||
.onError(error -> log.error(
|
||||
"Failed to create exam configuration for exam: {} from template: {} examConfig: {}",
|
||||
exam.name,
|
||||
examTemplate.name,
|
||||
configurationNode,
|
||||
error))
|
||||
.getOrThrow(error -> new APIMessageException(
|
||||
ErrorMessage.EXAM_IMPORT_ERROR_AUTO_CONFIG,
|
||||
error));
|
||||
final ConfigurationNode examConfig = createOrReuseConfig(exam, examTemplate);
|
||||
|
||||
// map the exam configuration to the exam
|
||||
this.examConfigurationMapDAO.createNew(new ExamConfigurationMap(
|
||||
|
@ -226,6 +207,68 @@ public class ExamTemplateServiceImpl implements ExamTemplateService {
|
|||
}).onError(error -> log.error("Failed to create exam configuration defined by template for exam: ", error));
|
||||
}
|
||||
|
||||
private ConfigurationNode createOrReuseConfig(final Exam exam, final ExamTemplate examTemplate) {
|
||||
final String configName = replaceVars(this.defaultExamConfigNameTemplate, exam, examTemplate);
|
||||
final FilterMap filterMap = new FilterMap();
|
||||
filterMap.putIfAbsent(Entity.FILTER_ATTR_INSTITUTION, exam.institutionId.toString());
|
||||
filterMap.putIfAbsent(Entity.FILTER_ATTR_NAME, configName);
|
||||
|
||||
// get existing config if available
|
||||
final ConfigurationNode examConfig = this.configurationNodeDAO
|
||||
.allMatching(filterMap)
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.filter(res -> res.name.equals(configName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (examConfig == null || examConfig.status != ConfigurationStatus.READY_TO_USE) {
|
||||
final ConfigurationNode config = new ConfigurationNode(
|
||||
null,
|
||||
exam.institutionId,
|
||||
examTemplate.configTemplateId,
|
||||
configName,
|
||||
replaceVars(this.defaultExamConfigDescTemplate, exam, examTemplate),
|
||||
ConfigurationType.EXAM_CONFIG,
|
||||
exam.owner,
|
||||
ConfigurationStatus.IN_USE);
|
||||
|
||||
return this.configurationNodeDAO
|
||||
.createNew(config)
|
||||
.onError(error -> log.error(
|
||||
"Failed to create exam configuration for exam: {} from template: {} examConfig: {}",
|
||||
exam.name,
|
||||
examTemplate.name,
|
||||
config,
|
||||
error))
|
||||
.getOrThrow(error -> new APIMessageException(
|
||||
ErrorMessage.EXAM_IMPORT_ERROR_AUTO_CONFIG,
|
||||
error));
|
||||
} else {
|
||||
final ConfigurationNode config = new ConfigurationNode(
|
||||
examConfig.id,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ConfigurationStatus.IN_USE);
|
||||
|
||||
return this.configurationNodeDAO
|
||||
.save(config)
|
||||
.onError(error -> log.error(
|
||||
"Failed to save exam configuration for exam: {} from template: {} examConfig: {}",
|
||||
exam.name,
|
||||
examTemplate.name,
|
||||
config,
|
||||
error))
|
||||
.getOrThrow(error -> new APIMessageException(
|
||||
ErrorMessage.EXAM_IMPORT_ERROR_AUTO_CONFIG,
|
||||
error));
|
||||
}
|
||||
}
|
||||
|
||||
private Result<Exam> addIndicatorsFromTemplate(final Exam exam) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
|
|
|
@ -1713,7 +1713,7 @@ sebserver.examtemplate.indicator.action.list.new=Add Indicator
|
|||
sebserver.examtemplate.indicator.action.list.modify=Edit Indicator
|
||||
sebserver.examtemplate.indicator.action.list.delete=Delete Indicator
|
||||
|
||||
|
||||
sebserver.examtemplate.proctoring.actions.open=Proctoring Settings
|
||||
|
||||
################################
|
||||
# Certificates
|
||||
|
|
Loading…
Reference in a new issue