SEBSERV-38 refactoring of PageAction handling

This commit is contained in:
anhefti 2019-04-01 10:48:05 +02:00
parent 98deb870eb
commit 6c27f2aeeb
43 changed files with 1404 additions and 1053 deletions

View file

@ -31,17 +31,20 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ActivateExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeactivateExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicator; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicator;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicators; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicators;
@ -62,7 +65,7 @@ public class ExamForm implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(ExamForm.class); private static final Logger log = LoggerFactory.getLogger(ExamForm.class);
private final PageFormService pageFormService; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
private final static LocTextKey listTitleKey = private final static LocTextKey listTitleKey =
@ -77,10 +80,10 @@ public class ExamForm implements TemplateComposer {
new LocTextKey("sebserver.exam.indicator.list.pleaseSelect"); new LocTextKey("sebserver.exam.indicator.list.pleaseSelect");
protected ExamForm( protected ExamForm(
final PageFormService pageFormService, final PageService pageService,
final ResourceService resourceService) { final ResourceService resourceService) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
} }
@ -88,7 +91,7 @@ public class ExamForm implements TemplateComposer {
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final I18nSupport i18nSupport = this.resourceService.getI18nSupport(); final I18nSupport i18nSupport = this.resourceService.getI18nSupport();
final UserInfo user = currentUser.get(); final UserInfo user = currentUser.get();
@ -131,7 +134,7 @@ public class ExamForm implements TemplateComposer {
final boolean modifyGrant = userGrantCheck.m(); final boolean modifyGrant = userGrantCheck.m();
// The Exam form // The Exam form
final FormHandle<Exam> formHandle = this.pageFormService.getBuilder( final FormHandle<Exam> formHandle = this.pageService.formBuilder(
formContext.copyOf(content), 4) formContext.copyOf(content), 4)
.readonly(readonly) .readonly(readonly)
.putStaticValueIf(isNotNew, .putStaticValueIf(isNotNew,
@ -204,34 +207,36 @@ public class ExamForm implements TemplateComposer {
? restService.getRestCall(ImportAsExam.class) ? restService.getRestCall(ImportAsExam.class)
: restService.getRestCall(SaveExam.class)); : restService.getRestCall(SaveExam.class));
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(formContext
.clearEntityKeys()
.removeAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA));
// propagate content actions to action-pane // propagate content actions to action-pane
formContext.clearEntityKeys() actionBuilder
.removeAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA)
.createAction(ActionDefinition.EXAM_MODIFY) .newAction(ActionDefinition.EXAM_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && readonly) .publishIf(() -> modifyGrant && readonly)
.createAction(ActionDefinition.EXAM_SAVE) .newAction(ActionDefinition.EXAM_SAVE)
.withExec(formHandle::processFormSave) .withExec(formHandle::processFormSave)
.ignoreMoveAwayFromEdit()
.publishIf(() -> !readonly && modifyGrant) .publishIf(() -> !readonly && modifyGrant)
.createAction(ActionDefinition.EXAM_CANCEL_MODIFY) .newAction(ActionDefinition.EXAM_CANCEL_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, String.valueOf(importFromQuizData)) .withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, String.valueOf(importFromQuizData))
.withExec(ExamForm::cancelModify) .withExec(this::cancelModify)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publishIf(() -> !readonly) .publishIf(() -> !readonly)
.createAction(ActionDefinition.EXAM_DEACTIVATE) .newAction(ActionDefinition.EXAM_DEACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(restService::activation) .withSimpleRestCall(restService, DeactivateExam.class)
.withConfirm(PageUtils.confirmDeactivation(exam, restService)) .withConfirm(PageUtils.confirmDeactivation(exam, restService))
.publishIf(() -> writeGrant && readonly && exam.isActive()) .publishIf(() -> writeGrant && readonly && exam.isActive())
.createAction(ActionDefinition.EXAM_ACTIVATE) .newAction(ActionDefinition.EXAM_ACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(restService::activation) .withSimpleRestCall(restService, ActivateExam.class)
.publishIf(() -> writeGrant && readonly && !exam.isActive()); .publishIf(() -> writeGrant && readonly && !exam.isActive());
// additional data in read-only view // additional data in read-only view
@ -244,7 +249,7 @@ public class ExamForm implements TemplateComposer {
listTitleKey); listTitleKey);
final EntityTable<Indicator> indicatorTable = final EntityTable<Indicator> indicatorTable =
widgetFactory.entityTableBuilder(restService.getRestCall(GetIndicators.class)) this.pageService.entityTableBuilder(restService.getRestCall(GetIndicators.class))
.withEmptyMessage(new LocTextKey("sebserver.exam.indicator.list.empty")) .withEmptyMessage(new LocTextKey("sebserver.exam.indicator.list.empty"))
.withPaging(3) .withPaging(3)
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
@ -265,19 +270,18 @@ public class ExamForm implements TemplateComposer {
.compose(content); .compose(content);
formContext.clearEntityKeys() actionBuilder
.removeAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA)
.createAction(ActionDefinition.EXAM_INDICATOR_NEW) .newAction(ActionDefinition.EXAM_INDICATOR_NEW)
.withParentEntityKey(entityKey) .withParentEntityKey(entityKey)
.publishIf(() -> modifyGrant) .publishIf(() -> modifyGrant)
.createAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST) .newAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST)
.withParentEntityKey(entityKey) .withParentEntityKey(entityKey)
.withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent()) .publishIf(() -> modifyGrant && indicatorTable.hasAnyContent())
.createAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST) .newAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withSelect(indicatorTable::getSelection, this::deleteSelectedIndicator, emptySelectionTextKey) .withSelect(indicatorTable::getSelection, this::deleteSelectedIndicator, emptySelectionTextKey)
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent()); .publishIf(() -> modifyGrant && indicatorTable.hasAnyContent());
@ -338,17 +342,20 @@ public class ExamForm implements TemplateComposer {
.toString(); .toString();
} }
public static PageAction cancelModify(final PageAction action) { private PageAction cancelModify(final PageAction action) {
final boolean importFromQuizData = BooleanUtils.toBoolean( final boolean importFromQuizData = BooleanUtils.toBoolean(
action.pageContext().getAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA)); action.pageContext().getAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA));
if (importFromQuizData) { if (importFromQuizData) {
final PageContext pageContext = action.pageContext(); final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(action.pageContext());
final PageAction activityHomeAction = pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST); final PageAction activityHomeAction = actionBuilder
action.pageContext().firePageEvent(new ActionEvent(activityHomeAction, false)); .newAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST)
.create();
this.pageService.firePageEvent(new ActionEvent(activityHomeAction), action.pageContext());
return activityHomeAction; return activityHomeAction;
} }
return PageAction.onEmptyEntityKeyGoToActivityHome(action); this.pageService.onEmptyEntityKeyGoTo(action, ActionDefinition.EXAM_VIEW_LIST);
return action;
} }
} }

View file

@ -28,9 +28,11 @@ import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -46,7 +48,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile @GuiProfile
public class ExamList implements TemplateComposer { public class ExamList implements TemplateComposer {
private final WidgetFactory widgetFactory; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
private final int pageSize; private final int pageSize;
@ -67,11 +69,11 @@ public class ExamList implements TemplateComposer {
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME); new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME);
protected ExamList( protected ExamList(
final WidgetFactory widgetFactory, final PageService pageService,
final ResourceService resourceService, final ResourceService resourceService,
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) { @Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20; this.pageSize = (pageSize != null) ? pageSize : 20;
@ -88,20 +90,23 @@ public class ExamList implements TemplateComposer {
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
final I18nSupport i18nSupport = this.resourceService.getI18nSupport(); final I18nSupport i18nSupport = this.resourceService.getI18nSupport();
// content page layout with title // content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout( final Composite content = widgetFactory.defaultPageLayout(
pageContext.getParent(), pageContext.getParent(),
new LocTextKey("sebserver.exam.list.title")); new LocTextKey("sebserver.exam.list.title"));
final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
// table // table
final EntityTable<Exam> table = final EntityTable<Exam> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetExams.class)) this.pageService.entityTableBuilder(restService.getRestCall(GetExams.class))
.withEmptyMessage(new LocTextKey("sebserver.exam.list.empty")) .withEmptyMessage(new LocTextKey("sebserver.exam.list.empty"))
.withPaging(this.pageSize) .withPaging(this.pageSize)
.withColumnIf(() -> isSEBAdmin, .withColumnIf(() -> isSEBAdmin,
@ -136,23 +141,23 @@ public class ExamList implements TemplateComposer {
columnTitleTypeKey, columnTitleTypeKey,
this::examTypeName, this::examTypeName,
true)) true))
.withDefaultAction(pageContext .withDefaultAction(actionBuilder
.clearEntityKeys() .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.createAction(ActionDefinition.EXAM_VIEW_FROM_LIST)) .create())
.compose(content); .compose(content);
// propagate content actions to action-pane // propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.EXAM); final GrantCheck userGrant = currentUser.grantCheck(EntityType.EXAM);
pageContext.clearEntityKeys() actionBuilder
.createAction(ActionDefinition.EXAM_IMPORT) .newAction(ActionDefinition.EXAM_IMPORT)
.publishIf(userGrant::im) .publishIf(userGrant::im)
.createAction(ActionDefinition.EXAM_VIEW_FROM_LIST) .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(table::hasAnyContent) .publishIf(table::hasAnyContent)
.createAction(ActionDefinition.EXAM_MODIFY_FROM_LIST) .newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());

View file

@ -23,11 +23,10 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
@ -43,21 +42,21 @@ public class IndicatorForm implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(IndicatorForm.class); private static final Logger log = LoggerFactory.getLogger(IndicatorForm.class);
private final PageFormService pageFormService; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
protected IndicatorForm( protected IndicatorForm(
final PageFormService pageFormService, final PageService pageService,
final ResourceService resourceService) { final ResourceService resourceService) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
} }
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey entityKey = pageContext.getEntityKey();
final EntityKey parentEntityKey = pageContext.getParentEntityKey(); final EntityKey parentEntityKey = pageContext.getParentEntityKey();
final boolean isNew = entityKey == null; final boolean isNew = entityKey == null;
@ -97,7 +96,7 @@ public class IndicatorForm implements TemplateComposer {
formContext.getParent(), formContext.getParent(),
titleKey); titleKey);
final FormHandle<Indicator> formHandle = this.pageFormService.getBuilder( final FormHandle<Indicator> formHandle = this.pageService.formBuilder(
formContext.copyOf(content), 4) formContext.copyOf(content), 4)
.readonly(isReadonly) .readonly(isReadonly)
.putStaticValueIf(() -> !isNew, .putStaticValueIf(() -> !isNew,
@ -136,16 +135,19 @@ public class IndicatorForm implements TemplateComposer {
: restService.getRestCall(SaveIndicator.class)); : restService.getRestCall(SaveIndicator.class));
// propagate content actions to action-pane // propagate content actions to action-pane
formContext.clearEntityKeys() this.pageService.pageActionBuilder(formContext.clearEntityKeys())
.createAction(ActionDefinition.EXAM_INDICATOR_SAVE)
.newAction(ActionDefinition.EXAM_INDICATOR_SAVE)
.withEntityKey(parentEntityKey) .withEntityKey(parentEntityKey)
.withExec(formHandle::processFormSave) .withExec(formHandle::processFormSave)
.ignoreMoveAwayFromEdit()
.publishIf(() -> !isReadonly) .publishIf(() -> !isReadonly)
.createAction(ActionDefinition.EXAM_INDICATOR_CANCEL_MODIFY) .newAction(ActionDefinition.EXAM_INDICATOR_CANCEL_MODIFY)
.withEntityKey(parentEntityKey) .withEntityKey(parentEntityKey)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome) .withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
.withConfirm("sebserver.overall.action.modify.cancel.confirm") action,
ActionDefinition.EXAM_VIEW_LIST))
.publishIf(() -> !isReadonly); .publishIf(() -> !isReadonly);
} }

View file

@ -26,14 +26,15 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.service.remote.SebClientConfigDownload; import ch.ethz.seb.sebserver.gui.service.remote.SebClientConfigDownload;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
@ -48,18 +49,18 @@ public class InstitutionForm implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(InstitutionForm.class); private static final Logger log = LoggerFactory.getLogger(InstitutionForm.class);
private final PageFormService pageFormService; private final PageService pageService;
private final RestService restService; private final RestService restService;
private final CurrentUser currentUser; private final CurrentUser currentUser;
private final SebClientConfigDownload sebClientConfigDownload; private final SebClientConfigDownload sebClientConfigDownload;
protected InstitutionForm( protected InstitutionForm(
final PageFormService pageFormService, final PageService pageService,
final RestService restService, final RestService restService,
final CurrentUser currentUser, final CurrentUser currentUser,
final SebClientConfigDownload sebClientConfigDownload) { final SebClientConfigDownload sebClientConfigDownload) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.restService = restService; this.restService = restService;
this.currentUser = currentUser; this.currentUser = currentUser;
this.sebClientConfigDownload = sebClientConfigDownload; this.sebClientConfigDownload = sebClientConfigDownload;
@ -68,7 +69,7 @@ public class InstitutionForm implements TemplateComposer {
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey entityKey = pageContext.getEntityKey();
final boolean isNew = entityKey == null; final boolean isNew = entityKey == null;
// get data or create new. Handle error if happen // get data or create new. Handle error if happen
@ -114,7 +115,7 @@ public class InstitutionForm implements TemplateComposer {
titleKey); titleKey);
// The Institution form // The Institution form
final FormHandle<Institution> formHandle = this.pageFormService.getBuilder( final FormHandle<Institution> formHandle = this.pageService.formBuilder(
formContext.copyOf(content), 4) formContext.copyOf(content), 4)
.readonly(isReadonly) .readonly(isReadonly)
.putStaticValueIf(() -> !isNew, .putStaticValueIf(() -> !isNew,
@ -139,20 +140,20 @@ public class InstitutionForm implements TemplateComposer {
// propagate content actions to action-pane // propagate content actions to action-pane
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class); final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
formContext.clearEntityKeys() this.pageService.pageActionBuilder(formContext.clearEntityKeys())
.createAction(ActionDefinition.INSTITUTION_NEW) .newAction(ActionDefinition.INSTITUTION_NEW)
.publishIf(() -> writeGrant && isReadonly) .publishIf(() -> writeGrant && isReadonly)
.createAction(ActionDefinition.USER_ACCOUNT_NEW) .newAction(ActionDefinition.USER_ACCOUNT_NEW)
.withParentEntityKey(entityKey) .withParentEntityKey(entityKey)
.publishIf(() -> userWriteGrant && isReadonly && institution.isActive()) .publishIf(() -> userWriteGrant && isReadonly && institution.isActive())
.createAction(ActionDefinition.INSTITUTION_MODIFY) .newAction(ActionDefinition.INSTITUTION_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && isReadonly) .publishIf(() -> modifyGrant && isReadonly)
.createAction(ActionDefinition.INSTITUTION_EXPORT_SEB_CONFIG) .newAction(ActionDefinition.INSTITUTION_EXPORT_SEB_CONFIG)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(action -> { .withExec(action -> {
final String downloadURL = this.sebClientConfigDownload.downloadSEBClientConfigURL( final String downloadURL = this.sebClientConfigDownload.downloadSEBClientConfigURL(
@ -162,26 +163,28 @@ public class InstitutionForm implements TemplateComposer {
}) })
.publishIf(() -> sebConfigWriteGrant && isReadonly && institution.isActive()) .publishIf(() -> sebConfigWriteGrant && isReadonly && institution.isActive())
.createAction(ActionDefinition.INSTITUTION_DEACTIVATE) .newAction(ActionDefinition.INSTITUTION_DEACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(this.restService::activation) .withSimpleRestCall(this.restService, DeactivateInstitution.class)
.withConfirm(PageUtils.confirmDeactivation(institution, this.restService)) .withConfirm(PageUtils.confirmDeactivation(institution, this.restService))
.publishIf(() -> writeGrant && isReadonly && institution.isActive()) .publishIf(() -> writeGrant && isReadonly && institution.isActive())
.createAction(ActionDefinition.INSTITUTION_ACTIVATE) .newAction(ActionDefinition.INSTITUTION_ACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(this.restService::activation) .withSimpleRestCall(this.restService, ActivateInstitution.class)
.publishIf(() -> writeGrant && isReadonly && !institution.isActive()) .publishIf(() -> writeGrant && isReadonly && !institution.isActive())
.createAction(ActionDefinition.INSTITUTION_SAVE) .newAction(ActionDefinition.INSTITUTION_SAVE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(formHandle::processFormSave) .withExec(formHandle::processFormSave)
.ignoreMoveAwayFromEdit()
.publishIf(() -> !isReadonly) .publishIf(() -> !isReadonly)
.createAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY) .newAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome) .withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
.withConfirm("sebserver.overall.action.modify.cancel.confirm") action,
ActionDefinition.INSTITUTION_VIEW_LIST))
.publishIf(() -> !isReadonly); .publishIf(() -> !isReadonly);
} }

View file

@ -18,16 +18,17 @@ import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck; 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.ColumnDefinition;
import ch.ethz.seb.sebserver.gui.table.EntityTable; import ch.ethz.seb.sebserver.gui.table.EntityTable;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@Lazy @Lazy
@Component @Component
@ -47,29 +48,32 @@ public class InstitutionList implements TemplateComposer {
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY = private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.institution.info.pleaseSelect"); new LocTextKey("sebserver.institution.info.pleaseSelect");
private final WidgetFactory widgetFactory; private final PageService pageService;
private final RestService restService; private final RestService restService;
private final CurrentUser currentUser; private final CurrentUser currentUser;
protected InstitutionList( protected InstitutionList(
final WidgetFactory widgetFactory, final PageService pageService,
final RestService restService, final RestService restService,
final CurrentUser currentUser) { final CurrentUser currentUser) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.restService = restService; this.restService = restService;
this.currentUser = currentUser; this.currentUser = currentUser;
} }
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final Composite content = this.widgetFactory.defaultPageLayout( final Composite content = this.pageService.getWidgetFactory().defaultPageLayout(
pageContext.getParent(), pageContext.getParent(),
TITLE_TEXT_KEY); TITLE_TEXT_KEY);
final PageActionBuilder pageActionBuilder =
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
// table // table
final EntityTable<Institution> table = final EntityTable<Institution> table =
this.widgetFactory.entityTableBuilder(this.restService.getRestCall(GetInstitutions.class)) this.pageService.entityTableBuilder(this.restService.getRestCall(GetInstitutions.class))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY) .withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(3) .withPaging(3)
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
@ -87,27 +91,28 @@ public class InstitutionList implements TemplateComposer {
ACTIVE_TEXT_KEY, ACTIVE_TEXT_KEY,
entity -> entity.active, entity -> entity.active,
true)) true))
.withDefaultAction(pageContext .withDefaultAction(pageActionBuilder
.clearEntityKeys() .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
.createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)) .create())
.compose(content); .compose(content);
// propagate content actions to action-pane // propagate content actions to action-pane
final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION); final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION);
final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER); final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER);
pageContext.clearEntityKeys()
.createAction(ActionDefinition.INSTITUTION_NEW) pageActionBuilder
.newAction(ActionDefinition.INSTITUTION_NEW)
.publishIf(instGrant::w) .publishIf(instGrant::w)
.createAction(ActionDefinition.USER_ACCOUNT_NEW) .newAction(ActionDefinition.USER_ACCOUNT_NEW)
.publishIf(userGrant::w) .publishIf(userGrant::w)
.createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST) .newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> instGrant.m() && table.hasAnyContent()); .publishIf(() -> instGrant.m() && table.hasAnyContent());
; ;

View file

@ -30,16 +30,19 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.ActivateLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.DeactivateLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetup; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.NewLmsSetup; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.NewLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.SaveLmsSetup; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.SaveLmsSetup;
@ -55,14 +58,14 @@ public class LmsSetupForm implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(LmsSetupForm.class); private static final Logger log = LoggerFactory.getLogger(LmsSetupForm.class);
private final PageFormService pageFormService; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
protected LmsSetupForm( protected LmsSetupForm(
final PageFormService pageFormService, final PageService pageService,
final ResourceService resourceService) { final ResourceService resourceService) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
} }
@ -70,7 +73,7 @@ public class LmsSetupForm implements TemplateComposer {
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final UserInfo user = currentUser.get(); final UserInfo user = currentUser.get();
final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey entityKey = pageContext.getEntityKey();
@ -122,7 +125,7 @@ public class LmsSetupForm implements TemplateComposer {
// The LMS Setup form // The LMS Setup form
final LmsType lmsType = lmsSetup.getLmsType(); final LmsType lmsType = lmsSetup.getLmsType();
final FormHandle<LmsSetup> formHandle = this.pageFormService.getBuilder( final FormHandle<LmsSetup> formHandle = this.pageService.formBuilder(
formContext.copyOf(content), 4) formContext.copyOf(content), 4)
.readonly(readonly) .readonly(readonly)
.putStaticValueIf(isNotNew, .putStaticValueIf(isNotNew,
@ -174,49 +177,58 @@ public class LmsSetupForm implements TemplateComposer {
; ;
// propagate content actions to action-pane // propagate content actions to action-pane
formContext.clearEntityKeys() this.pageService.pageActionBuilder(formContext.clearEntityKeys())
.createAction(ActionDefinition.LMS_SETUP_NEW) .newAction(ActionDefinition.LMS_SETUP_NEW)
.publishIf(() -> writeGrant && readonly && institutionActive) .publishIf(() -> writeGrant && readonly && institutionActive)
.createAction(ActionDefinition.LMS_SETUP_MODIFY) .newAction(ActionDefinition.LMS_SETUP_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && readonly && institutionActive) .publishIf(() -> modifyGrant && readonly && institutionActive)
.createAction(ActionDefinition.LMS_SETUP_TEST) .newAction(ActionDefinition.LMS_SETUP_TEST)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(action -> this.testLmsSetup(action, formHandle)) .withExec(action -> this.testLmsSetup(action, formHandle))
.publishIf(() -> modifyGrant && isNotNew.getAsBoolean() && institutionActive) .publishIf(() -> modifyGrant && isNotNew.getAsBoolean() && institutionActive)
.createAction(ActionDefinition.LMS_SETUP_DEACTIVATE) .newAction(ActionDefinition.LMS_SETUP_DEACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(restService::activation) .withSimpleRestCall(restService, DeactivateLmsSetup.class)
.withConfirm(PageUtils.confirmDeactivation(lmsSetup, restService)) .withConfirm(PageUtils.confirmDeactivation(lmsSetup, restService))
.publishIf(() -> writeGrant && readonly && institutionActive && lmsSetup.isActive()) .publishIf(() -> writeGrant && readonly && institutionActive && lmsSetup.isActive())
.createAction(ActionDefinition.LMS_SETUP_ACTIVATE) .newAction(ActionDefinition.LMS_SETUP_ACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(action -> activate(action, formHandle)) .withExec(action -> activate(action, formHandle))
.publishIf(() -> writeGrant && readonly && institutionActive && !lmsSetup.isActive()) .publishIf(() -> writeGrant && readonly && institutionActive && !lmsSetup.isActive())
.createAction(ActionDefinition.LMS_SETUP_SAVE) .newAction(ActionDefinition.LMS_SETUP_SAVE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(formHandle::processFormSave) .withExec(formHandle::processFormSave)
.ignoreMoveAwayFromEdit()
.publishIf(() -> !readonly) .publishIf(() -> !readonly)
.createAction(ActionDefinition.LMS_SETUP_CANCEL_MODIFY) .newAction(ActionDefinition.LMS_SETUP_CANCEL_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome) .withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
.withConfirm("sebserver.overall.action.modify.cancel.confirm") action,
ActionDefinition.LMS_SETUP_VIEW_LIST))
.publishIf(() -> !readonly); .publishIf(() -> !readonly);
} }
/** Save and test connection before activation */ /** Save and test connection before activation */
private PageAction activate(final PageAction action, final FormHandle<LmsSetup> formHandle) { private PageAction activate(final PageAction action, final FormHandle<LmsSetup> formHandle) {
final RestService restService = this.resourceService.getRestService(); // first test the LMS Setup. If this fails the action execution will stops
final PageAction testLmsSetup = this.testLmsSetup(action, formHandle); final PageAction testLmsSetup = this.testLmsSetup(action, formHandle);
final PageAction activation = restService.activation(testLmsSetup); // if LMS Setup test was successful, the activation action applies
return activation; this.resourceService.getRestService().getBuilder(ActivateLmsSetup.class)
.withURIVariable(
API.PARAM_MODEL_ID,
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
.call()
.onErrorDo(t -> action.pageContext().notifyError(t));
return testLmsSetup;
} }
/** LmsSetup test action implementation */ /** LmsSetup test action implementation */

View file

@ -25,9 +25,11 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetups; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetups;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -63,16 +65,16 @@ public class LmsSetupList implements TemplateComposer {
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME); new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
private final TableFilterAttribute typeFilter; private final TableFilterAttribute typeFilter;
private final WidgetFactory widgetFactory; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
private final int pageSize; private final int pageSize;
protected LmsSetupList( protected LmsSetupList(
final WidgetFactory widgetFactory, final PageService pageService,
final ResourceService resourceService, final ResourceService resourceService,
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) { @Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20; this.pageSize = (pageSize != null) ? pageSize : 20;
@ -89,20 +91,21 @@ public class LmsSetupList implements TemplateComposer {
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
// content page layout with title // content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout( final Composite content = widgetFactory.defaultPageLayout(
pageContext.getParent(), pageContext.getParent(),
TITLE_TEXT_KEY); TITLE_TEXT_KEY);
final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
// table // table
final EntityTable<LmsSetup> table = final EntityTable<LmsSetup> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetLmsSetups.class)) this.pageService.entityTableBuilder(restService.getRestCall(GetLmsSetups.class))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY) .withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(this.pageSize) .withPaging(this.pageSize)
.withColumnIf(() -> isSEBAdmin, .withColumnIf(() -> isSEBAdmin,
@ -129,23 +132,23 @@ public class LmsSetupList implements TemplateComposer {
ACTIVITY_TEXT_KEY, ACTIVITY_TEXT_KEY,
entity -> entity.active, entity -> entity.active,
true)) true))
.withDefaultAction(pageContext .withDefaultAction(actionBuilder
.clearEntityKeys() .newAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)
.createAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)) .create())
.compose(content); .compose(content);
// propagate content actions to action-pane // propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.LMS_SETUP); final GrantCheck userGrant = currentUser.grantCheck(EntityType.LMS_SETUP);
pageContext.clearEntityKeys() actionBuilder
.createAction(ActionDefinition.LMS_SETUP_NEW) .newAction(ActionDefinition.LMS_SETUP_NEW)
.publishIf(userGrant::iw) .publishIf(userGrant::iw)
.createAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST) .newAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST) .newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());

View file

@ -26,11 +26,11 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.activity.ActivitiesPane; import ch.ethz.seb.sebserver.gui.content.activity.ActivitiesPane;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.service.page.impl.MainPageState;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
@ -41,8 +41,6 @@ public class MainPage implements TemplateComposer {
static final Logger log = LoggerFactory.getLogger(MainPage.class); static final Logger log = LoggerFactory.getLogger(MainPage.class);
public static final String ATTR_MAIN_PAGE_STATE = "MAIN_PAGE_STATE";
private static final int ACTIVITY_PANE_WEIGHT = 15; private static final int ACTIVITY_PANE_WEIGHT = 15;
private static final int CONTENT_PANE_WEIGHT = 65; private static final int CONTENT_PANE_WEIGHT = 65;
private static final int ACTION_PANE_WEIGHT = 20; private static final int ACTION_PANE_WEIGHT = 20;
@ -54,14 +52,19 @@ public class MainPage implements TemplateComposer {
private static final int[] OPENED_SASH_WEIGHTS = new int[] { 0, 100, 0 }; private static final int[] OPENED_SASH_WEIGHTS = new int[] { 0, 100, 0 };
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final PageService pageStateService;
public MainPage(
final WidgetFactory widgetFactory,
final PageService pageStateService) {
public MainPage(final WidgetFactory widgetFactory) {
this.widgetFactory = widgetFactory; this.widgetFactory = widgetFactory;
this.pageStateService = pageStateService;
} }
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
MainPageState.clear(); this.pageStateService.clear();
final Composite parent = pageContext.getParent(); final Composite parent = pageContext.getParent();
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
@ -123,7 +126,7 @@ public class MainPage implements TemplateComposer {
contentObjects.setData( contentObjects.setData(
PageEventListener.LISTENER_ATTRIBUTE_KEY, PageEventListener.LISTENER_ATTRIBUTE_KEY,
new ContentActionEventListener(event -> pageContext.composerService().compose( new ContentActionEventListener(event -> pageContext.composerService().compose(
event.action.definition.contentPaneComposer, event.action.definition.targetState.contentPaneComposer(),
event.action.pageContext().copyOf(contentObjects)), 2)); event.action.pageContext().copyOf(contentObjects)), 2));
final Composite actionPane = new Composite(mainSash, SWT.NONE); final Composite actionPane = new Composite(mainSash, SWT.NONE);
@ -134,7 +137,7 @@ public class MainPage implements TemplateComposer {
actionPane.setData( actionPane.setData(
PageEventListener.LISTENER_ATTRIBUTE_KEY, PageEventListener.LISTENER_ATTRIBUTE_KEY,
new ContentActionEventListener(event -> pageContext.composerService().compose( new ContentActionEventListener(event -> pageContext.composerService().compose(
event.action.definition.actionPaneComposer, event.action.definition.targetState.actionPaneComposer(),
event.action.pageContext().copyOf(actionPane)), 1)); event.action.pageContext().copyOf(actionPane)), 1));
pageContext.composerService().compose( pageContext.composerService().compose(

View file

@ -22,15 +22,16 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialog;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizzes; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizzes;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -70,17 +71,16 @@ public class QuizDiscoveryList implements TemplateComposer {
// dependencies // dependencies
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final ResourceService resourceService; private final ResourceService resourceService;
private final PageFormService pageFormService; private final PageService pageService;
private final int pageSize; private final int pageSize;
protected QuizDiscoveryList( protected QuizDiscoveryList(
final PageFormService pageFormService, final PageService pageService,
final WidgetFactory widgetFactory,
final ResourceService resourceService, final ResourceService resourceService,
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) { @Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.widgetFactory = widgetFactory; this.widgetFactory = pageService.getWidgetFactory();
this.resourceService = resourceService; this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20; this.pageSize = (pageSize != null) ? pageSize : 20;
@ -101,9 +101,11 @@ public class QuizDiscoveryList implements TemplateComposer {
pageContext.getParent(), pageContext.getParent(),
TITLE_TEXT_KEY); TITLE_TEXT_KEY);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
// table // table
final EntityTable<QuizData> table = final EntityTable<QuizData> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetQuizzes.class)) this.pageService.entityTableBuilder(restService.getRestCall(GetQuizzes.class))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY) .withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(this.pageSize) .withPaging(this.pageSize)
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
@ -133,22 +135,22 @@ public class QuizDiscoveryList implements TemplateComposer {
i18nSupport.getUsersTimeZoneTitleSuffix()), i18nSupport.getUsersTimeZoneTitleSuffix()),
quizData -> quizData.endTime, quizData -> quizData.endTime,
true)) true))
.withDefaultAction(t -> pageContext .withDefaultAction(t -> actionBuilder
.clearEntityKeys() .newAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
.createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
.withExec(action -> this.showDetails(action, t.getSelectedROWData())) .withExec(action -> this.showDetails(action, t.getSelectedROWData()))
.noEventPropagation()) .noEventPropagation()
.create())
.compose(content); .compose(content);
// propagate content actions to action-pane // propagate content actions to action-pane
final GrantCheck lmsSetupGrant = currentUser.grantCheck(EntityType.LMS_SETUP); final GrantCheck lmsSetupGrant = currentUser.grantCheck(EntityType.LMS_SETUP);
final GrantCheck examGrant = currentUser.grantCheck(EntityType.EXAM); final GrantCheck examGrant = currentUser.grantCheck(EntityType.EXAM);
pageContext.clearEntityKeys() actionBuilder
.createAction(ActionDefinition.LMS_SETUP_NEW) .newAction(ActionDefinition.LMS_SETUP_NEW)
.publishIf(lmsSetupGrant::iw) .publishIf(lmsSetupGrant::iw)
.createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS) .newAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
.withSelect( .withSelect(
table::getSelection, table::getSelection,
action -> this.showDetails(action, table.getSelectedROWData()), action -> this.showDetails(action, table.getSelectedROWData()),
@ -156,7 +158,7 @@ public class QuizDiscoveryList implements TemplateComposer {
.noEventPropagation() .noEventPropagation()
.publishIf(table::hasAnyContent) .publishIf(table::hasAnyContent)
.createAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT) .newAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT)
.withSelect( .withSelect(
table::getSelection, table::getSelection,
action -> this.importQuizData(action, table), action -> this.importQuizData(action, table),
@ -195,7 +197,7 @@ public class QuizDiscoveryList implements TemplateComposer {
private void createDetailsForm(final QuizData quizData, final PageContext pc) { private void createDetailsForm(final QuizData quizData, final PageContext pc) {
this.widgetFactory.labelSeparator(pc.getParent()); this.widgetFactory.labelSeparator(pc.getParent());
this.pageFormService.getBuilder(pc, 4) this.pageService.formBuilder(pc, 4)
.readonly(true) .readonly(true)
.addField(FormBuilder.singleSelection( .addField(FormBuilder.singleSelection(
QuizData.QUIZ_ATTR_LMS_SETUP_ID, QuizData.QUIZ_ATTR_LMS_SETUP_ID,

View file

@ -23,12 +23,12 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
@ -46,27 +46,26 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
* password that is also required must match the administrators current password. */ * password that is also required must match the administrators current password. */
public class UserAccountChangePasswordForm implements TemplateComposer { public class UserAccountChangePasswordForm implements TemplateComposer {
private final PageFormService pageFormService; private final PageService pageService;
private final RestService restService; private final RestService restService;
private final CurrentUser currentUser; private final CurrentUser currentUser;
private final I18nSupport i18nSupport; private final I18nSupport i18nSupport;
protected UserAccountChangePasswordForm( protected UserAccountChangePasswordForm(
final PageFormService pageFormService, final PageService pageService,
final RestService restService, final RestService restService,
final CurrentUser currentUser, final CurrentUser currentUser) {
final I18nSupport i18nSupport) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.restService = restService; this.restService = restService;
this.currentUser = currentUser; this.currentUser = currentUser;
this.i18nSupport = i18nSupport; this.i18nSupport = pageService.getI18nSupport();
} }
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey entityKey = pageContext.getEntityKey();
final UserInfo userInfo = this.restService final UserInfo userInfo = this.restService
@ -82,7 +81,7 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
final boolean ownAccount = this.currentUser.get().uuid.equals(entityKey.getModelId()); final boolean ownAccount = this.currentUser.get().uuid.equals(entityKey.getModelId());
// The Password Change form // The Password Change form
final FormHandle<UserInfo> formHandle = this.pageFormService.getBuilder( final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(
pageContext.copyOf(content), 4) pageContext.copyOf(content), 4)
.readonly(false) .readonly(false)
.putStaticValueIf(() -> entityKey != null, .putStaticValueIf(() -> entityKey != null,
@ -103,9 +102,11 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
.withCondition(() -> entityKey != null)) .withCondition(() -> entityKey != null))
.buildFor(this.restService.getRestCall(ChangePassword.class)); .buildFor(this.restService.getRestCall(ChangePassword.class));
pageContext.createAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD_SAVE) this.pageService.pageActionBuilder(pageContext)
.newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD_SAVE)
.withExec(action -> { .withExec(action -> {
formHandle.processFormSave(action); final PageAction saveAction = formHandle.processFormSave(action);
if (ownAccount) { if (ownAccount) {
// NOTE: in this case the user changed the password of the own account // NOTE: in this case the user changed the password of the own account
// this should cause an logout with specified message that password change // this should cause an logout with specified message that password change
@ -118,12 +119,15 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
SWT.ERROR); SWT.ERROR);
error.open(null); error.open(null);
} }
return null; return saveAction;
}) })
.ignoreMoveAwayFromEdit()
.publish() .publish()
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome) .newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
.withConfirm("sebserver.overall.action.modify.cancel.confirm") .withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
action,
ActionDefinition.USER_ACCOUNT_VIEW_LIST))
.publish(); .publish();
} }

View file

@ -31,15 +31,17 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder; import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle; import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
@ -54,14 +56,14 @@ public class UserAccountForm implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(UserAccountForm.class); private static final Logger log = LoggerFactory.getLogger(UserAccountForm.class);
private final PageFormService pageFormService; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
protected UserAccountForm( protected UserAccountForm(
final PageFormService pageFormService, final PageService pageService,
final ResourceService resourceService) { final ResourceService resourceService) {
this.pageFormService = pageFormService; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
} }
@ -69,7 +71,7 @@ public class UserAccountForm implements TemplateComposer {
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final UserInfo user = currentUser.get(); final UserInfo user = currentUser.get();
final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey entityKey = pageContext.getEntityKey();
@ -127,7 +129,7 @@ public class UserAccountForm implements TemplateComposer {
titleKey); titleKey);
// The UserAccount form // The UserAccount form
final FormHandle<UserInfo> formHandle = this.pageFormService.getBuilder( final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(
formContext.copyOf(content), 4) formContext.copyOf(content), 4)
.readonly(readonly) .readonly(readonly)
.putStaticValueIf(isNotNew, .putStaticValueIf(isNotNew,
@ -187,46 +189,48 @@ public class UserAccountForm implements TemplateComposer {
: restService.getRestCall(SaveUserAccount.class)); : restService.getRestCall(SaveUserAccount.class));
// propagate content actions to action-pane // propagate content actions to action-pane
formContext.clearEntityKeys() this.pageService.pageActionBuilder(formContext.clearEntityKeys())
.createAction(ActionDefinition.USER_ACCOUNT_NEW) .newAction(ActionDefinition.USER_ACCOUNT_NEW)
.publishIf(() -> writeGrant && readonly && institutionActive) .publishIf(() -> writeGrant && readonly && institutionActive)
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY) .newAction(ActionDefinition.USER_ACCOUNT_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && readonly && institutionActive) .publishIf(() -> modifyGrant && readonly && institutionActive)
.createAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD) .newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive()) .publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive())
.createAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE) .newAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(restService::activation) .withSimpleRestCall(restService, DeactivateUserAccount.class)
.withConfirm(PageUtils.confirmDeactivation(userAccount, restService)) .withConfirm(PageUtils.confirmDeactivation(userAccount, restService))
.publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive()) .publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive())
.createAction(ActionDefinition.USER_ACCOUNT_ACTIVATE) .newAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(restService::activation) .withSimpleRestCall(restService, ActivateUserAccount.class)
.publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive()) .publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive())
.createAction(ActionDefinition.USER_ACCOUNT_SAVE) .newAction(ActionDefinition.USER_ACCOUNT_SAVE)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(action -> { .withExec(action -> {
final PageAction postChanges = formHandle.processFormSave(action); final PageAction saveAction = formHandle.processFormSave(action);
if (ownAccount) { if (ownAccount) {
currentUser.refresh(); currentUser.refresh();
pageContext.forwardToMainPage(); pageContext.forwardToMainPage();
} }
return postChanges; return saveAction;
}) })
.ignoreMoveAwayFromEdit()
.publishIf(() -> !readonly) .publishIf(() -> !readonly)
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY) .newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
.withEntityKey(entityKey) .withEntityKey(entityKey)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome) .withExec(action -> this.pageService.onEmptyEntityKeyGoTo(
.withConfirm("sebserver.overall.action.modify.cancel.confirm") action,
ActionDefinition.USER_ACCOUNT_VIEW_LIST))
.publishIf(() -> !readonly); .publishIf(() -> !readonly);
} }

View file

@ -26,9 +26,11 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -73,16 +75,16 @@ public class UserAccountList implements TemplateComposer {
private final TableFilterAttribute languageFilter; private final TableFilterAttribute languageFilter;
// dependencies // dependencies
private final WidgetFactory widgetFactory; private final PageService pageService;
private final ResourceService resourceService; private final ResourceService resourceService;
private final int pageSize; private final int pageSize;
protected UserAccountList( protected UserAccountList(
final WidgetFactory widgetFactory, final PageService pageService,
final ResourceService resourceService, final ResourceService resourceService,
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) { @Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.resourceService = resourceService; this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20; this.pageSize = (pageSize != null) ? pageSize : 20;
@ -99,17 +101,19 @@ public class UserAccountList implements TemplateComposer {
@Override @Override
public void compose(final PageContext pageContext) { public void compose(final PageContext pageContext) {
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
final CurrentUser currentUser = this.resourceService.getCurrentUser(); final CurrentUser currentUser = this.resourceService.getCurrentUser();
final RestService restService = this.resourceService.getRestService(); final RestService restService = this.resourceService.getRestService();
// content page layout with title // content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout( final Composite content = widgetFactory.defaultPageLayout(
pageContext.getParent(), pageContext.getParent(),
TITLE_TEXT_KEY); TITLE_TEXT_KEY);
final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
// table // table
final EntityTable<UserInfo> table = this.widgetFactory.entityTableBuilder( final EntityTable<UserInfo> table = this.pageService.entityTableBuilder(
restService.getRestCall(GetUserAccounts.class)) restService.getRestCall(GetUserAccounts.class))
.withEmptyMessage(new LocTextKey("sebserver.useraccount.list.empty")) .withEmptyMessage(new LocTextKey("sebserver.useraccount.list.empty"))
@ -150,30 +154,30 @@ public class UserAccountList implements TemplateComposer {
ACTIVE_TEXT_KEY, ACTIVE_TEXT_KEY,
entity -> entity.active, entity -> entity.active,
true)) true))
.withDefaultAction(pageContext .withDefaultAction(actionBuilder
.clearEntityKeys() .newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)) .create())
.compose(content); .compose(content);
// propagate content actions to action-pane // propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER); final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER);
pageContext.clearEntityKeys() actionBuilder
.createAction(ActionDefinition.USER_ACCOUNT_NEW) .newAction(ActionDefinition.USER_ACCOUNT_NEW)
.publishIf(userGrant::iw) .publishIf(userGrant::iw)
.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST) .newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST) .newAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());
} }
private String getLocaleDisplayText(final UserInfo userInfo) { private String getLocaleDisplayText(final UserInfo userInfo) {
return (userInfo.language != null) return (userInfo.language != null)
? userInfo.language.getDisplayLanguage(this.widgetFactory.getI18nSupport().getCurrentLocale()) ? userInfo.language.getDisplayLanguage(this.pageService.getI18nSupport().getCurrentLocale())
: Constants.EMPTY_NOTE; : Constants.EMPTY_NOTE;
} }

View file

@ -8,471 +8,276 @@
package ch.ethz.seb.sebserver.gui.content.action; package ch.ethz.seb.sebserver.gui.content.action;
import ch.ethz.seb.sebserver.gui.content.ExamForm; import ch.ethz.seb.sebserver.gui.content.activity.PageStateDefinition;
import ch.ethz.seb.sebserver.gui.content.ExamList;
import ch.ethz.seb.sebserver.gui.content.IndicatorForm;
import ch.ethz.seb.sebserver.gui.content.InstitutionForm;
import ch.ethz.seb.sebserver.gui.content.InstitutionList;
import ch.ethz.seb.sebserver.gui.content.LmsSetupForm;
import ch.ethz.seb.sebserver.gui.content.LmsSetupList;
import ch.ethz.seb.sebserver.gui.content.QuizDiscoveryList;
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.PageState;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ActivateExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeactivateExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.ActivateLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.DeactivateLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
/** Enumeration of static action data for each action within the SEB Server GUI */ /** Enumeration of static action data for each action within the SEB Server GUI */
// TODO add category to allow easy positioning of actions later
public enum ActionDefinition { public enum ActionDefinition {
INSTITUTION_VIEW_LIST( INSTITUTION_VIEW_LIST(
new LocTextKey("sebserver.institution.action.list"), new LocTextKey("sebserver.institution.action.list"),
InstitutionList.class), PageStateDefinition.INSTITUTION_LIST),
INSTITUTION_VIEW_FORM( INSTITUTION_VIEW_FORM(
new LocTextKey("sebserver.institution.action.form"), new LocTextKey("sebserver.institution.action.form"),
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW),
INSTITUTION_VIEW_LIST),
INSTITUTION_NEW( INSTITUTION_NEW(
new LocTextKey("sebserver.institution.action.new"), new LocTextKey("sebserver.institution.action.new"),
ImageIcon.NEW, ImageIcon.NEW,
InstitutionForm.class, PageStateDefinition.INSTITUTION_EDIT),
INSTITUTION_VIEW_LIST,
false),
INSTITUTION_VIEW_FROM_LIST( INSTITUTION_VIEW_FROM_LIST(
new LocTextKey("sebserver.institution.action.list.view"), new LocTextKey("sebserver.institution.action.list.view"),
ImageIcon.SHOW, ImageIcon.SHOW,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
INSTITUTION_VIEW_LIST,
ActionCategory.INSTITUTION_LIST), ActionCategory.INSTITUTION_LIST),
INSTITUTION_MODIFY_FROM_LIST( INSTITUTION_MODIFY_FROM_LIST(
new LocTextKey("sebserver.institution.action.list.modify"), new LocTextKey("sebserver.institution.action.list.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
InstitutionForm.class, PageStateDefinition.INSTITUTION_EDIT,
INSTITUTION_VIEW_LIST, ActionCategory.INSTITUTION_LIST),
ActionCategory.INSTITUTION_LIST,
false),
INSTITUTION_MODIFY( INSTITUTION_MODIFY(
new LocTextKey("sebserver.institution.action.modify"), new LocTextKey("sebserver.institution.action.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
InstitutionForm.class, PageStateDefinition.INSTITUTION_EDIT,
INSTITUTION_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
false),
INSTITUTION_CANCEL_MODIFY( INSTITUTION_CANCEL_MODIFY(
new LocTextKey("sebserver.overall.action.modify.cancel"), new LocTextKey("sebserver.overall.action.modify.cancel"),
ImageIcon.CANCEL, ImageIcon.CANCEL,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
INSTITUTION_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
true),
INSTITUTION_SAVE( INSTITUTION_SAVE(
new LocTextKey("sebserver.institution.action.save"), new LocTextKey("sebserver.institution.action.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
INSTITUTION_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
INSTITUTION_ACTIVATE( INSTITUTION_ACTIVATE(
new LocTextKey("sebserver.institution.action.activate"), new LocTextKey("sebserver.institution.action.activate"),
ImageIcon.INACTIVE, ImageIcon.INACTIVE,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
ActivateInstitution.class,
INSTITUTION_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
INSTITUTION_DEACTIVATE( INSTITUTION_DEACTIVATE(
new LocTextKey("sebserver.institution.action.deactivate"), new LocTextKey("sebserver.institution.action.deactivate"),
ImageIcon.ACTIVE, ImageIcon.ACTIVE,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
DeactivateInstitution.class,
INSTITUTION_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
INSTITUTION_DELETE(
new LocTextKey("sebserver.institution.action.modify"),
ImageIcon.DELETE,
InstitutionList.class,
INSTITUTION_VIEW_LIST),
INSTITUTION_EXPORT_SEB_CONFIG( INSTITUTION_EXPORT_SEB_CONFIG(
new LocTextKey("sebserver.institution.action.export.sebconfig"), new LocTextKey("sebserver.institution.action.export.sebconfig"),
ImageIcon.SAVE, ImageIcon.SAVE,
InstitutionForm.class, PageStateDefinition.INSTITUTION_VIEW,
INSTITUTION_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
USER_ACCOUNT_VIEW_LIST( USER_ACCOUNT_VIEW_LIST(
new LocTextKey("sebserver.useraccount.action.list"), new LocTextKey("sebserver.useraccount.action.list"),
UserAccountList.class), PageStateDefinition.USER_ACCOUNT_LIST),
USER_ACCOUNT_VIEW_FORM( USER_ACCOUNT_VIEW_FORM(
new LocTextKey("sebserver.useraccount.action.form"), new LocTextKey("sebserver.useraccount.action.form"),
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW),
USER_ACCOUNT_VIEW_LIST),
USER_ACCOUNT_NEW( USER_ACCOUNT_NEW(
new LocTextKey("sebserver.useraccount.action.new"), new LocTextKey("sebserver.useraccount.action.new"),
ImageIcon.NEW, ImageIcon.NEW,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_EDIT),
USER_ACCOUNT_VIEW_LIST, false),
USER_ACCOUNT_VIEW_FROM_LIST( USER_ACCOUNT_VIEW_FROM_LIST(
new LocTextKey("sebserver.useraccount.action.view"), new LocTextKey("sebserver.useraccount.action.view"),
ImageIcon.SHOW, ImageIcon.SHOW,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
USER_ACCOUNT_VIEW_LIST,
ActionCategory.USER_ACCOUNT_LIST), ActionCategory.USER_ACCOUNT_LIST),
USER_ACCOUNT_MODIFY_FROM_LIST( USER_ACCOUNT_MODIFY_FROM_LIST(
new LocTextKey("sebserver.useraccount.action.list.modify"), new LocTextKey("sebserver.useraccount.action.list.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_EDIT,
USER_ACCOUNT_VIEW_LIST, ActionCategory.USER_ACCOUNT_LIST),
ActionCategory.USER_ACCOUNT_LIST,
false),
USER_ACCOUNT_MODIFY( USER_ACCOUNT_MODIFY(
new LocTextKey("sebserver.useraccount.action.modify"), new LocTextKey("sebserver.useraccount.action.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_EDIT,
USER_ACCOUNT_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
false),
USER_ACCOUNT_CANCEL_MODIFY( USER_ACCOUNT_CANCEL_MODIFY(
new LocTextKey("sebserver.overall.action.modify.cancel"), new LocTextKey("sebserver.overall.action.modify.cancel"),
ImageIcon.CANCEL, ImageIcon.CANCEL,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
USER_ACCOUNT_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
true),
USER_ACCOUNT_SAVE( USER_ACCOUNT_SAVE(
new LocTextKey("sebserver.useraccount.action.save"), new LocTextKey("sebserver.useraccount.action.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
USER_ACCOUNT_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
USER_ACCOUNT_ACTIVATE( USER_ACCOUNT_ACTIVATE(
new LocTextKey("sebserver.useraccount.action.activate"), new LocTextKey("sebserver.useraccount.action.activate"),
ImageIcon.INACTIVE, ImageIcon.INACTIVE,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
ActivateUserAccount.class,
USER_ACCOUNT_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
USER_ACCOUNT_DEACTIVATE( USER_ACCOUNT_DEACTIVATE(
new LocTextKey("sebserver.useraccount.action.deactivate"), new LocTextKey("sebserver.useraccount.action.deactivate"),
ImageIcon.ACTIVE, ImageIcon.ACTIVE,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
DeactivateUserAccount.class,
USER_ACCOUNT_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
USER_ACCOUNT_DELETE(
new LocTextKey("sebserver.useraccount.action.modify"),
ImageIcon.DELETE,
UserAccountList.class,
USER_ACCOUNT_VIEW_LIST),
USER_ACCOUNT_CHANGE_PASSOWRD( USER_ACCOUNT_CHANGE_PASSOWRD(
new LocTextKey("sebserver.useraccount.action.change.password"), new LocTextKey("sebserver.useraccount.action.change.password"),
ImageIcon.EDIT, ImageIcon.EDIT,
UserAccountChangePasswordForm.class, PageStateDefinition.USER_ACCOUNT_PASSWORD_CHANGE,
USER_ACCOUNT_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
false),
USER_ACCOUNT_CHANGE_PASSOWRD_SAVE( USER_ACCOUNT_CHANGE_PASSOWRD_SAVE(
new LocTextKey("sebserver.useraccount.action.change.password.save"), new LocTextKey("sebserver.useraccount.action.change.password.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
UserAccountForm.class, PageStateDefinition.USER_ACCOUNT_VIEW,
USER_ACCOUNT_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
LMS_SETUP_VIEW_LIST( LMS_SETUP_VIEW_LIST(
new LocTextKey("sebserver.lmssetup.action.list"), new LocTextKey("sebserver.lmssetup.action.list"),
LmsSetupList.class), PageStateDefinition.LMS_SETUP_LIST),
LMS_SETUP_NEW( LMS_SETUP_NEW(
new LocTextKey("sebserver.lmssetup.action.new"), new LocTextKey("sebserver.lmssetup.action.new"),
ImageIcon.NEW, ImageIcon.NEW,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_EDIT),
LMS_SETUP_VIEW_LIST, false),
LMS_SETUP_VIEW_FROM_LIST( LMS_SETUP_VIEW_FROM_LIST(
new LocTextKey("sebserver.lmssetup.action.list.view"), new LocTextKey("sebserver.lmssetup.action.list.view"),
ImageIcon.SHOW, ImageIcon.SHOW,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
LMS_SETUP_VIEW_LIST,
ActionCategory.LMS_SETUP_LIST), ActionCategory.LMS_SETUP_LIST),
LMS_SETUP_MODIFY_FROM_LIST( LMS_SETUP_MODIFY_FROM_LIST(
new LocTextKey("sebserver.lmssetup.action.list.modify"), new LocTextKey("sebserver.lmssetup.action.list.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_EDIT,
LMS_SETUP_VIEW_LIST, ActionCategory.LMS_SETUP_LIST),
ActionCategory.LMS_SETUP_LIST,
false),
LMS_SETUP_MODIFY( LMS_SETUP_MODIFY(
new LocTextKey("sebserver.lmssetup.action.modify"), new LocTextKey("sebserver.lmssetup.action.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_EDIT,
LMS_SETUP_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
false),
LMS_SETUP_TEST( LMS_SETUP_TEST(
new LocTextKey("sebserver.lmssetup.action.test"), new LocTextKey("sebserver.lmssetup.action.test"),
ImageIcon.TEST, ImageIcon.TEST,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
LMS_SETUP_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
LMS_SETUP_CANCEL_MODIFY( LMS_SETUP_CANCEL_MODIFY(
new LocTextKey("sebserver.overall.action.modify.cancel"), new LocTextKey("sebserver.overall.action.modify.cancel"),
ImageIcon.CANCEL, ImageIcon.CANCEL,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
LMS_SETUP_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
true),
LMS_SETUP_SAVE( LMS_SETUP_SAVE(
new LocTextKey("sebserver.lmssetup.action.save"), new LocTextKey("sebserver.lmssetup.action.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
LMS_SETUP_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
LMS_SETUP_ACTIVATE( LMS_SETUP_ACTIVATE(
new LocTextKey("sebserver.lmssetup.action.activate"), new LocTextKey("sebserver.lmssetup.action.activate"),
ImageIcon.INACTIVE, ImageIcon.INACTIVE,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
ActivateLmsSetup.class,
LMS_SETUP_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
LMS_SETUP_DEACTIVATE( LMS_SETUP_DEACTIVATE(
new LocTextKey("sebserver.lmssetup.action.deactivate"), new LocTextKey("sebserver.lmssetup.action.deactivate"),
ImageIcon.ACTIVE, ImageIcon.ACTIVE,
LmsSetupForm.class, PageStateDefinition.LMS_SETUP_VIEW,
DeactivateLmsSetup.class,
LMS_SETUP_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
QUIZ_DISCOVERY_VIEW_LIST( QUIZ_DISCOVERY_VIEW_LIST(
new LocTextKey("sebserver.quizdiscovery.action.list"), new LocTextKey("sebserver.quizdiscovery.action.list"),
QuizDiscoveryList.class), PageStateDefinition.QUIZ_LIST),
QUIZ_DISCOVERY_SHOW_DETAILS( QUIZ_DISCOVERY_SHOW_DETAILS(
new LocTextKey("sebserver.quizdiscovery.action.details"), new LocTextKey("sebserver.quizdiscovery.action.details"),
ImageIcon.SHOW, ImageIcon.SHOW,
null,
ActionCategory.QUIZ_LIST), ActionCategory.QUIZ_LIST),
QUIZ_DISCOVERY_EXAM_IMPORT( QUIZ_DISCOVERY_EXAM_IMPORT(
new LocTextKey("sebserver.quizdiscovery.action.import"), new LocTextKey("sebserver.quizdiscovery.action.import"),
ImageIcon.IMPORT, ImageIcon.IMPORT,
ExamForm.class, PageStateDefinition.EXAM_EDIT,
QUIZ_DISCOVERY_VIEW_LIST, ActionCategory.QUIZ_LIST),
ActionCategory.QUIZ_LIST,
false),
EXAM_VIEW_LIST( EXAM_VIEW_LIST(
new LocTextKey("sebserver.exam.action.list"), new LocTextKey("sebserver.exam.action.list"),
ExamList.class), PageStateDefinition.EXAM_LIST),
EXAM_IMPORT( EXAM_IMPORT(
new LocTextKey("sebserver.exam.action.import"), new LocTextKey("sebserver.exam.action.import"),
ImageIcon.IMPORT, ImageIcon.IMPORT,
QuizDiscoveryList.class, PageStateDefinition.QUIZ_LIST),
QUIZ_DISCOVERY_VIEW_LIST,
false),
EXAM_VIEW_FROM_LIST( EXAM_VIEW_FROM_LIST(
new LocTextKey("sebserver.exam.action.list.view"), new LocTextKey("sebserver.exam.action.list.view"),
ImageIcon.SHOW, ImageIcon.SHOW,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_LIST,
ActionCategory.EXAM_LIST), ActionCategory.EXAM_LIST),
EXAM_MODIFY_FROM_LIST( EXAM_MODIFY_FROM_LIST(
new LocTextKey("sebserver.exam.action.list.modify"), new LocTextKey("sebserver.exam.action.list.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
ExamForm.class, PageStateDefinition.EXAM_EDIT,
EXAM_VIEW_LIST, ActionCategory.EXAM_LIST),
ActionCategory.EXAM_LIST,
false),
EXAM_MODIFY( EXAM_MODIFY(
new LocTextKey("sebserver.exam.action.modify"), new LocTextKey("sebserver.exam.action.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
ExamForm.class, PageStateDefinition.EXAM_EDIT,
EXAM_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
false),
EXAM_CANCEL_MODIFY( EXAM_CANCEL_MODIFY(
new LocTextKey("sebserver.overall.action.modify.cancel"), new LocTextKey("sebserver.overall.action.modify.cancel"),
ImageIcon.CANCEL, ImageIcon.CANCEL,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_LIST, ActionCategory.FORM),
ActionCategory.FORM,
true),
EXAM_SAVE( EXAM_SAVE(
new LocTextKey("sebserver.exam.action.save"), new LocTextKey("sebserver.exam.action.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
EXAM_ACTIVATE( EXAM_ACTIVATE(
new LocTextKey("sebserver.exam.action.activate"), new LocTextKey("sebserver.exam.action.activate"),
ImageIcon.INACTIVE, ImageIcon.INACTIVE,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
ActivateExam.class,
EXAM_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
EXAM_DEACTIVATE( EXAM_DEACTIVATE(
new LocTextKey("sebserver.exam.action.deactivate"), new LocTextKey("sebserver.exam.action.deactivate"),
ImageIcon.ACTIVE, ImageIcon.ACTIVE,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
DeactivateExam.class,
EXAM_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
EXAM_INDICATOR_NEW( EXAM_INDICATOR_NEW(
new LocTextKey("sebserver.exam.indicator.action.list.new"), new LocTextKey("sebserver.exam.indicator.action.list.new"),
ImageIcon.NEW, ImageIcon.NEW,
IndicatorForm.class, PageStateDefinition.INDICATOR_EDIT),
EXAM_VIEW_FROM_LIST,
false),
EXAM_INDICATOR_MODIFY_FROM_LIST( EXAM_INDICATOR_MODIFY_FROM_LIST(
new LocTextKey("sebserver.exam.indicator.action.list.modify"), new LocTextKey("sebserver.exam.indicator.action.list.modify"),
ImageIcon.EDIT, ImageIcon.EDIT,
IndicatorForm.class, PageStateDefinition.INDICATOR_EDIT,
EXAM_VIEW_FROM_LIST, ActionCategory.INDICATOR_LIST),
ActionCategory.INDICATOR_LIST,
false),
EXAM_INDICATOR_DELETE_FROM_LIST( EXAM_INDICATOR_DELETE_FROM_LIST(
new LocTextKey("sebserver.exam.indicator.action.list.delete"), new LocTextKey("sebserver.exam.indicator.action.list.delete"),
ImageIcon.DELETE, ImageIcon.DELETE,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_FROM_LIST, ActionCategory.INDICATOR_LIST),
ActionCategory.INDICATOR_LIST,
true),
EXAM_INDICATOR_SAVE( EXAM_INDICATOR_SAVE(
new LocTextKey("sebserver.exam.indicator.action.save"), new LocTextKey("sebserver.exam.indicator.action.save"),
ImageIcon.SAVE, ImageIcon.SAVE,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_FROM_LIST,
ActionCategory.FORM), ActionCategory.FORM),
EXAM_INDICATOR_CANCEL_MODIFY( EXAM_INDICATOR_CANCEL_MODIFY(
new LocTextKey("sebserver.overall.action.modify.cancel"), new LocTextKey("sebserver.overall.action.modify.cancel"),
ImageIcon.CANCEL, ImageIcon.CANCEL,
ExamForm.class, PageStateDefinition.EXAM_VIEW,
EXAM_VIEW_FROM_LIST,
ActionCategory.FORM,
true),
TEST_ACTION(
new LocTextKey("TEST"),
ImageIcon.TEST,
ExamList.class,
EXAM_VIEW_LIST,
ActionCategory.FORM), ActionCategory.FORM),
; ;
public final LocTextKey title; public final LocTextKey title;
public final ImageIcon icon; public final ImageIcon icon;
public final Class<? extends TemplateComposer> contentPaneComposer; public final PageState targetState;
public final Class<? extends TemplateComposer> actionPaneComposer;
public final Class<? extends RestCall<?>> restCallType;
public final ActionDefinition activityAlias;
public final ActionCategory category; public final ActionCategory category;
public final Boolean readonly;
private ActionDefinition( private ActionDefinition(final LocTextKey title, final PageState targetState) {
final LocTextKey title, this(title, null, targetState, ActionCategory.VARIA);
final Class<? extends TemplateComposer> contentPaneComposer) {
this(title, null, contentPaneComposer, ActionPane.class, null, null, null, null);
} }
private ActionDefinition( private ActionDefinition(final LocTextKey title, final ImageIcon icon, final PageState targetState) {
final LocTextKey title, this(title, icon, targetState, ActionCategory.VARIA);
final Class<? extends TemplateComposer> contentPaneComposer,
final ActionDefinition activityAlias) {
this(title, null, contentPaneComposer, ActionPane.class, null, activityAlias, null, null);
} }
private ActionDefinition( private ActionDefinition(
final LocTextKey title, final LocTextKey title,
final ImageIcon icon, final ImageIcon icon,
final PageState targetState,
final ActionCategory category) { final ActionCategory category) {
this(title, icon, null, ActionPane.class, null, null, category, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final ActionDefinition activityAlias) {
this(title, icon, contentPaneComposer, ActionPane.class, null, activityAlias, null, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final ActionDefinition activityAlias,
final ActionCategory category) {
this(title, icon, contentPaneComposer, ActionPane.class, null, activityAlias, category, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final Class<? extends RestCall<?>> restCallType,
final ActionDefinition activityAlias) {
this(title, icon, contentPaneComposer, ActionPane.class, restCallType, activityAlias, null, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final Class<? extends RestCall<?>> restCallType,
final ActionDefinition activityAlias,
final ActionCategory category) {
this(title, icon, contentPaneComposer, ActionPane.class, restCallType, activityAlias, category, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final ActionDefinition activityAlias,
final boolean readonly) {
this(title, icon, contentPaneComposer, ActionPane.class, null, activityAlias, null, readonly);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final ActionDefinition activityAlias,
final ActionCategory category,
final boolean readonly) {
this(title, icon, contentPaneComposer, ActionPane.class, null, activityAlias, category, readonly);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final Class<? extends TemplateComposer> contentPaneComposer,
final Class<? extends TemplateComposer> actionPaneComposer,
final Class<? extends RestCall<?>> restCallType,
final ActionDefinition activityAlias,
final ActionCategory category,
final Boolean readonly) {
this.title = title; this.title = title;
this.icon = icon; this.icon = icon;
this.contentPaneComposer = contentPaneComposer; this.targetState = targetState;
this.actionPaneComposer = actionPaneComposer; this.category = category;
this.restCallType = restCallType;
this.activityAlias = activityAlias;
this.category = (category != null) ? category : ActionCategory.VARIA;
this.readonly = readonly;
} }
} }

View file

@ -28,12 +28,13 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent; import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
@ -43,13 +44,14 @@ public class ActionPane implements TemplateComposer {
private static final String ACTION_EVENT_CALL_KEY = "ACTION_EVENT_CALL"; private static final String ACTION_EVENT_CALL_KEY = "ACTION_EVENT_CALL";
private final PageService pageService;
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final Map<String, Tree> actionTrees = new HashMap<>(); private final Map<String, Tree> actionTrees = new HashMap<>();
public ActionPane(final WidgetFactory widgetFactory) { protected ActionPane(final PageService pageService) {
super(); this.pageService = pageService;
this.widgetFactory = widgetFactory; this.widgetFactory = pageService.getWidgetFactory();
} }
@Override @Override
@ -161,7 +163,7 @@ public class ActionPane implements TemplateComposer {
final TreeItem treeItem = (TreeItem) event.item; final TreeItem treeItem = (TreeItem) event.item;
final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY); final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY);
action.run(); this.pageService.executePageAction(action);
if (!treeItem.isDisposed()) { if (!treeItem.isDisposed()) {
treeItem.getParent().deselectAll(); treeItem.getParent().deselectAll();

View file

@ -24,14 +24,17 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction; import ch.ethz.seb.sebserver.gui.service.page.Activity;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
import ch.ethz.seb.sebserver.gui.service.page.PageState;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener; import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.service.page.impl.MainPageState; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
@ -44,13 +47,15 @@ public class ActivitiesPane implements TemplateComposer {
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final CurrentUser currentUser; private final CurrentUser currentUser;
private final PageService pageService;
public ActivitiesPane( public ActivitiesPane(
final WidgetFactory widgetFactory, final CurrentUser currentUser,
final CurrentUser currentUser) { final PageService pageService) {
this.widgetFactory = widgetFactory; this.widgetFactory = pageService.getWidgetFactory();
this.currentUser = currentUser; this.currentUser = currentUser;
this.pageService = pageService;
} }
@Override @Override
@ -73,27 +78,32 @@ public class ActivitiesPane implements TemplateComposer {
//navigationGridData.horizontalIndent = 10; //navigationGridData.horizontalIndent = 10;
navigation.setLayoutData(navigationGridData); navigation.setLayoutData(navigationGridData);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext);
// Institution // Institution
// If current user has SEB Server Admin role, show the Institution list // If current user has SEB Server Admin role, show the Institution list
if (userInfo.hasRole(UserRole.SEB_SERVER_ADMIN)) { if (userInfo.hasRole(UserRole.SEB_SERVER_ADMIN)) {
// institutions (list) as root // institutions (list) as root
final TreeItem institutions = this.widgetFactory.treeItemLocalized( final TreeItem institutions = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.INSTITUTION_VIEW_LIST.title); ActivityDefinition.INSTITUTION.displayName);
injectActivitySelection( injectActivitySelection(
institutions, institutions,
pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_LIST)); actionBuilder
.newAction(ActionDefinition.INSTITUTION_VIEW_LIST)
.create());
} else { } else {
// otherwise show the form of the institution for current user // otherwise show the form of the institution for current user
final TreeItem institutions = this.widgetFactory.treeItemLocalized( final TreeItem institutions = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.INSTITUTION_VIEW_FORM.title); ActivityDefinition.INSTITUTION.displayName);
injectActivitySelection( injectActivitySelection(
institutions, institutions,
pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_FORM) actionBuilder.newAction(ActionDefinition.INSTITUTION_VIEW_FORM)
.withEntityKey(userInfo.institutionId, EntityType.INSTITUTION) .withEntityKey(userInfo.institutionId, EntityType.INSTITUTION)
.withAttribute(AttributeKeys.READ_ONLY, "true")); .withAttribute(AttributeKeys.READ_ONLY, "true")
.create());
} }
// User Account // User Account
@ -101,30 +111,35 @@ public class ActivitiesPane implements TemplateComposer {
if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.USER)) { if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.USER)) {
final TreeItem userAccounts = this.widgetFactory.treeItemLocalized( final TreeItem userAccounts = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.USER_ACCOUNT_VIEW_LIST.title); ActivityDefinition.USER_ACCOUNT.displayName);
injectActivitySelection( injectActivitySelection(
userAccounts, userAccounts,
pageContext.createAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST)); actionBuilder
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST)
.create());
} else { } else {
// otherwise show the user account form for current user // otherwise show the user account form for current user
final TreeItem userAccounts = this.widgetFactory.treeItemLocalized( final TreeItem userAccounts = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.USER_ACCOUNT_VIEW_FORM.title); ActivityDefinition.USER_ACCOUNT.displayName);
injectActivitySelection( injectActivitySelection(
userAccounts, userAccounts,
pageContext.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FORM) actionBuilder.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FORM)
.withEntityKey(this.currentUser.get().getEntityKey()) .withEntityKey(this.currentUser.get().getEntityKey())
.withAttribute(AttributeKeys.READ_ONLY, "true")); .withAttribute(AttributeKeys.READ_ONLY, "true")
.create());
} }
// LMS Setup // LMS Setup
if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.LMS_SETUP)) { if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.LMS_SETUP)) {
final TreeItem lmsSetup = this.widgetFactory.treeItemLocalized( final TreeItem lmsSetup = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.LMS_SETUP_VIEW_LIST.title); ActivityDefinition.LMS_SETUP.displayName);
injectActivitySelection( injectActivitySelection(
lmsSetup, lmsSetup,
pageContext.createAction(ActionDefinition.LMS_SETUP_VIEW_LIST)); actionBuilder
.newAction(ActionDefinition.LMS_SETUP_VIEW_LIST)
.create());
} }
// Exam (Quiz Discovery) // Exam (Quiz Discovery)
@ -134,18 +149,22 @@ public class ActivitiesPane implements TemplateComposer {
// TODO discussion if this should be visible on Activity Pane or just over the Exam activity and Import action // TODO discussion if this should be visible on Activity Pane or just over the Exam activity and Import action
final TreeItem quizDiscovery = this.widgetFactory.treeItemLocalized( final TreeItem quizDiscovery = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST.title); ActivityDefinition.QUIZ_DISCOVERY.displayName);
injectActivitySelection( injectActivitySelection(
quizDiscovery, quizDiscovery,
pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST)); actionBuilder
.newAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST)
.create());
// Exam // Exam
final TreeItem exam = this.widgetFactory.treeItemLocalized( final TreeItem exam = this.widgetFactory.treeItemLocalized(
navigation, navigation,
ActionDefinition.EXAM_VIEW_LIST.title); ActivityDefinition.EXAM.displayName);
injectActivitySelection( injectActivitySelection(
exam, exam,
pageContext.createAction(ActionDefinition.EXAM_VIEW_LIST)); actionBuilder
.newAction(ActionDefinition.EXAM_VIEW_LIST)
.create());
} }
// TODO other activities // TODO other activities
@ -157,34 +176,42 @@ public class ActivitiesPane implements TemplateComposer {
new ActivitiesActionEventListener(navigation)); new ActivitiesActionEventListener(navigation));
// page-selection on (re)load // page-selection on (re)load
final MainPageState mainPageState = MainPageState.get(); final PageState state = this.pageService.getCurrentState();
if (state == null) {
if (mainPageState.action == null) { final TreeItem item = navigation.getItem(0);
mainPageState.action = getActivitySelection(navigation.getItem(0)); final PageAction activityAction = getActivitySelection(item);
this.pageService.executePageAction(activityAction);
} else {
final TreeItem item = findItemByActionDefinition(navigation.getItems(), state);
if (item != null) {
navigation.select(item);
}
} }
pageContext.firePageEvent(
new ActionEvent(mainPageState.action, false));
navigation.select(navigation.getItem(0));
} }
private void handleSelection(final PageContext composerCtx, final Event event) { private void handleSelection(final PageContext composerCtx, final Event event) {
final TreeItem treeItem = (TreeItem) event.item; final TreeItem treeItem = (TreeItem) event.item;
System.out.println("selected: " + treeItem);
final MainPageState mainPageState = MainPageState.get();
final PageAction action = getActivitySelection(treeItem); final PageAction action = getActivitySelection(treeItem);
if (mainPageState.action.definition != action.definition) { this.pageService.executePageAction(
mainPageState.action = action; action,
composerCtx.firePageEvent( result -> {
new ActionEvent(action, true)); if (result.hasError()) {
} final Tree tree = (Tree) event.widget;
tree.deselect(treeItem);
final PageState currentState = this.pageService.getCurrentState();
if (currentState != null) {
final TreeItem item = findItemByActionDefinition(tree.getItems(), currentState);
if (item != null) {
tree.select(item);
}
}
}
});
} }
static final TreeItem findItemByActionDefinition( private static final TreeItem findItemByActionDefinition(
final TreeItem[] items, final TreeItem[] items,
final ActionDefinition actionDefinition, final Activity activity,
final String modelId) { final String modelId) {
if (items == null) { if (items == null) {
@ -197,13 +224,14 @@ public class ActivitiesPane implements TemplateComposer {
continue; continue;
} }
final Activity activityAnchor = action.definition.targetState.activityAnchor();
final EntityKey entityKey = action.getEntityKey(); final EntityKey entityKey = action.getEntityKey();
if ((action.definition == actionDefinition || action.definition == actionDefinition.activityAlias) && if (activityAnchor.name().equals(activity.name()) &&
(entityKey == null || (modelId != null && modelId.equals(entityKey.modelId)))) { (entityKey == null || (modelId != null && modelId.equals(entityKey.modelId)))) {
return item; return item;
} }
final TreeItem _item = findItemByActionDefinition(item.getItems(), actionDefinition, modelId); final TreeItem _item = findItemByActionDefinition(item.getItems(), activity, modelId);
if (_item != null) { if (_item != null) {
return _item; return _item;
} }
@ -212,8 +240,8 @@ public class ActivitiesPane implements TemplateComposer {
return null; return null;
} }
static final TreeItem findItemByActionDefinition(final TreeItem[] items, final ActionDefinition actionDefinition) { static final TreeItem findItemByActionDefinition(final TreeItem[] items, final PageState pageState) {
return findItemByActionDefinition(items, actionDefinition, null); return findItemByActionDefinition(items, pageState.activityAnchor(), null);
} }
static final void expand(final TreeItem item) { static final void expand(final TreeItem item) {
@ -242,14 +270,15 @@ public class ActivitiesPane implements TemplateComposer {
@Override @Override
public void notify(final ActionEvent event) { public void notify(final ActionEvent event) {
final MainPageState mainPageState = MainPageState.get(); // TODO
mainPageState.action = event.action; // final MainPageState mainPageState = MainPageState.get();
// mainPageState.action = event.action;
if (!event.activity) { if (!event.activity) {
final EntityKey entityKey = event.action.getEntityKey(); final EntityKey entityKey = event.action.getEntityKey();
final String modelId = (entityKey != null) ? entityKey.modelId : null; final String modelId = (entityKey != null) ? entityKey.modelId : null;
final TreeItem item = findItemByActionDefinition( final TreeItem item = findItemByActionDefinition(
this.navigation.getItems(), this.navigation.getItems(),
event.action.definition, event.action.definition.targetState.activityAnchor(),
modelId); modelId);
if (item != null) { if (item != null) {
this.navigation.select(item); this.navigation.select(item);

View file

@ -0,0 +1,33 @@
/*
* 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.activity;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.Activity;
public enum ActivityDefinition implements Activity {
INSTITUTION(new LocTextKey("sebserver.institution.action.list")),
USER_ACCOUNT(new LocTextKey("sebserver.useraccount.action.list")),
LMS_SETUP(new LocTextKey("sebserver.lmssetup.action.list")),
QUIZ_DISCOVERY(new LocTextKey("sebserver.quizdiscovery.action.list")),
EXAM(new LocTextKey("sebserver.exam.action.list")),
;
public final LocTextKey displayName;
private ActivityDefinition(final LocTextKey displayName) {
this.displayName = displayName;
}
@Override
public LocTextKey displayName() {
return this.displayName;
}
}

View file

@ -0,0 +1,96 @@
/*
* 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.activity;
import ch.ethz.seb.sebserver.gui.content.ExamForm;
import ch.ethz.seb.sebserver.gui.content.ExamList;
import ch.ethz.seb.sebserver.gui.content.IndicatorForm;
import ch.ethz.seb.sebserver.gui.content.InstitutionForm;
import ch.ethz.seb.sebserver.gui.content.InstitutionList;
import ch.ethz.seb.sebserver.gui.content.LmsSetupForm;
import ch.ethz.seb.sebserver.gui.content.LmsSetupList;
import ch.ethz.seb.sebserver.gui.content.QuizDiscoveryList;
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
import ch.ethz.seb.sebserver.gui.content.action.ActionPane;
import ch.ethz.seb.sebserver.gui.service.page.Activity;
import ch.ethz.seb.sebserver.gui.service.page.PageState;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
public enum PageStateDefinition implements PageState {
INSTITUTION_LIST(Type.LIST_VIEW, InstitutionList.class, ActivityDefinition.INSTITUTION),
INSTITUTION_VIEW(Type.FORM_VIEW, InstitutionForm.class, ActivityDefinition.INSTITUTION),
INSTITUTION_EDIT(Type.FORM_EDIT, InstitutionForm.class, ActivityDefinition.INSTITUTION),
USER_ACCOUNT_LIST(Type.LIST_VIEW, UserAccountList.class, ActivityDefinition.USER_ACCOUNT),
USER_ACCOUNT_VIEW(Type.FORM_VIEW, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
USER_ACCOUNT_EDIT(Type.FORM_EDIT, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
USER_ACCOUNT_PASSWORD_CHANGE(Type.FORM_EDIT, UserAccountChangePasswordForm.class, ActivityDefinition.USER_ACCOUNT),
LMS_SETUP_LIST(Type.LIST_VIEW, LmsSetupList.class, ActivityDefinition.LMS_SETUP),
LMS_SETUP_VIEW(Type.FORM_VIEW, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
LMS_SETUP_EDIT(Type.FORM_EDIT, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
QUIZ_LIST(Type.LIST_VIEW, QuizDiscoveryList.class, ActivityDefinition.QUIZ_DISCOVERY),
EXAM_LIST(Type.LIST_VIEW, ExamList.class, ActivityDefinition.EXAM),
EXAM_VIEW(Type.FORM_VIEW, ExamForm.class, ActivityDefinition.EXAM),
EXAM_EDIT(Type.FORM_EDIT, ExamForm.class, ActivityDefinition.EXAM),
INDICATOR_EDIT(Type.FORM_EDIT, IndicatorForm.class, ActivityDefinition.EXAM),
;
public final Type type;
public final Class<? extends TemplateComposer> contentPaneComposer;
public final Class<? extends TemplateComposer> actionPaneComposer;
public final Activity activityAnchor;
private PageStateDefinition(
final Type type,
final Class<? extends TemplateComposer> contentPaneComposer,
final Activity activityAnchor) {
this(type, contentPaneComposer, ActionPane.class, activityAnchor);
}
private PageStateDefinition(
final Type type,
final Class<? extends TemplateComposer> contentPaneComposer,
final Class<? extends TemplateComposer> actionPaneComposer,
final Activity activityAnchor) {
this.type = type;
this.contentPaneComposer = contentPaneComposer;
this.actionPaneComposer = actionPaneComposer;
this.activityAnchor = activityAnchor;
}
@Override
public Type type() {
return this.type;
}
@Override
public Class<? extends TemplateComposer> contentPaneComposer() {
return this.contentPaneComposer;
}
@Override
public Class<? extends TemplateComposer> actionPaneComposer() {
return this.actionPaneComposer;
}
@Override
public Activity activityAnchor() {
return this.activityAnchor;
}
}

View file

@ -25,12 +25,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gbl.util.Tuple;
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.widget.Selection; import ch.ethz.seb.sebserver.gui.widget.Selection;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -40,9 +39,8 @@ public class FormBuilder {
private static final Logger log = LoggerFactory.getLogger(FormBuilder.class); private static final Logger log = LoggerFactory.getLogger(FormBuilder.class);
final PageService pageService;
final WidgetFactory widgetFactory; final WidgetFactory widgetFactory;
final JSONMapper jsonMapper;
private final PolyglotPageService polyglotPageService;
public final PageContext pageContext; public final PageContext pageContext;
public final Composite formParent; public final Composite formParent;
public final Form form; public final Form form;
@ -53,18 +51,15 @@ public class FormBuilder {
private int defaultSpanEmptyCell = 1; private int defaultSpanEmptyCell = 1;
private boolean emptyCellSeparation = true; private boolean emptyCellSeparation = true;
FormBuilder( public FormBuilder(
final JSONMapper jsonMapper, final PageService pageService,
final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService,
final PageContext pageContext, final PageContext pageContext,
final int rows) { final int rows) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.jsonMapper = jsonMapper; this.widgetFactory = pageService.getWidgetFactory();
this.polyglotPageService = polyglotPageService;
this.pageContext = pageContext; this.pageContext = pageContext;
this.form = new Form(jsonMapper); this.form = new Form(pageService.getJSONMapper());
this.formParent = new Composite(pageContext.getParent(), SWT.NONE); this.formParent = new Composite(pageContext.getParent(), SWT.NONE);
final GridLayout layout = new GridLayout(rows, true); final GridLayout layout = new GridLayout(rows, true);
@ -173,14 +168,12 @@ public class FormBuilder {
return buildFor(null); return buildFor(null);
} }
public <T extends Entity> FormHandle<T> buildFor( public <T extends Entity> FormHandle<T> buildFor(final RestCall<T> post) {
final RestCall<T> post) {
return new FormHandle<>( return new FormHandle<>(
this.pageService,
this.pageContext, this.pageContext,
this.form, this.form,
post, post);
this.polyglotPageService.getI18nSupport());
} }
private void empty(final Composite parent, final int hspan, final int vspan) { private void empty(final Composite parent, final int hspan, final int vspan) {

View file

@ -19,11 +19,10 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.form.Form.FormFieldAccessor; import ch.ethz.seb.sebserver.gui.form.Form.FormFieldAccessor;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError; import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; 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.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
@ -33,21 +32,23 @@ public class FormHandle<T extends Entity> {
public static final String FIELD_VALIDATION_LOCTEXT_PREFIX = "sebserver.form.validation.fieldError."; public static final String FIELD_VALIDATION_LOCTEXT_PREFIX = "sebserver.form.validation.fieldError.";
private final PageService pageService;
private final PageContext pageContext; private final PageContext pageContext;
private final Form form; private final Form form;
private final RestCall<T> post; private final RestCall<T> post;
private final I18nSupport i18nSupport; private final I18nSupport i18nSupport;
FormHandle( FormHandle(
final PageService pageService,
final PageContext pageContext, final PageContext pageContext,
final Form form, final Form form,
final RestCall<T> post, final RestCall<T> post) {
final I18nSupport i18nSupport) {
this.pageService = pageService;
this.pageContext = pageContext; this.pageContext = pageContext;
this.form = form; this.form = form;
this.post = post; this.post = post;
this.i18nSupport = i18nSupport; this.i18nSupport = pageService.getI18nSupport();
} }
/** Process an API post request to send and save the form field values /** Process an API post request to send and save the form field values
@ -89,12 +90,14 @@ public class FormHandle<T extends Entity> {
public PageAction handleFormPost(final Result<T> postResult, final PageAction action) { public PageAction handleFormPost(final Result<T> postResult, final PageAction action) {
return postResult return postResult
.map(result -> { .map(result -> {
PageAction resultAction = action.createNew()
.withAttribute(AttributeKeys.READ_ONLY, "true"); PageAction resultAction = this.pageService.pageActionBuilder(action.pageContext())
.newAction(action.definition)
.create();
if (resultAction.getEntityKey() == null) { if (resultAction.getEntityKey() == null) {
resultAction = resultAction.withEntityKey(result.getEntityKey()); resultAction = resultAction.withEntityKey(result.getEntityKey());
} }
action.pageContext().firePageEvent(new ActionEvent(resultAction, false));
return resultAction; return resultAction;
}) })
.onErrorDo(this::handleError) .onErrorDo(this::handleError)

View file

@ -1,59 +0,0 @@
/*
* Copyright (c) 2018 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.form;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@Lazy
@Component
@GuiProfile
public class PageFormService {
private final JSONMapper jsonMapper;
private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService;
public PageFormService(
final JSONMapper jsonMapper,
final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService) {
this.jsonMapper = jsonMapper;
this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService;
}
public FormBuilder getBuilder(
final PageContext pageContext,
final int rows) {
return new FormBuilder(
this.jsonMapper,
this.widgetFactory,
this.polyglotPageService,
pageContext,
rows);
}
public WidgetFactory getWidgetFactory() {
return this.widgetFactory;
}
public PolyglotPageService getPolyglotPageService() {
return this.polyglotPageService;
}
}

View file

@ -0,0 +1,19 @@
/*
* 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.page;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
public interface Activity {
String name();
LocTextKey displayName();
}

View file

@ -1,250 +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.service.page;
import java.util.Set;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
public final class PageAction implements Runnable {
private static final Logger log = LoggerFactory.getLogger(PageAction.class);
public final ActionDefinition definition;
Supplier<LocTextKey> confirm;
LocTextKey successMessage;
Supplier<Set<EntityKey>> selectionSupplier;
LocTextKey noSelectionMessage;
private final PageContext originalPageContext;
private PageContext pageContext;
private Function<PageAction, PageAction> exec = Function.identity();
private boolean fireActionEvent = true;
public PageAction(
final ActionDefinition definition,
final PageContext pageContext) {
this.definition = definition;
this.originalPageContext = pageContext;
final String readonly = pageContext.getAttribute(AttributeKeys.READ_ONLY, "true");
this.pageContext = pageContext.withAttribute(
AttributeKeys.READ_ONLY,
definition.readonly != null
? String.valueOf(definition.readonly)
: readonly);
}
@Override
public void run() {
if (this.confirm != null) {
final LocTextKey confirmMessage = this.confirm.get();
if (confirmMessage != null) {
this.pageContext.applyConfirmDialog(confirmMessage, () -> exec());
}
} else {
exec();
}
}
private void exec() {
try {
final PageAction executedAction = this.exec.apply(this);
if (this.fireActionEvent) {
this.pageContext.firePageEvent(new ActionEvent(executedAction, false));
}
} catch (final PageMessageException pme) {
PageAction.this.pageContext.publishPageMessage(pme);
} catch (final RestCallError restCallError) {
if (restCallError.isFieldValidationError()) {
PageAction.this.pageContext.publishPageMessage(
new LocTextKey("sebserver.form.validation.error.title"),
new LocTextKey("sebserver.form.validation.error.message"));
} else {
log.error("Failed to execute action: {}", PageAction.this, restCallError);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", restCallError);
}
} catch (final Throwable t) {
log.error("Failed to execute action: {}", PageAction.this, t);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", t);
}
}
public PageAction createNew() {
return this.pageContext.createAction(this.definition);
}
public PageAction withExec(final Function<PageAction, PageAction> exec) {
this.exec = exec;
return this;
}
public PageAction withSelectionSupplier(final Supplier<Set<EntityKey>> selectionSupplier) {
this.selectionSupplier = selectionSupplier;
return this;
}
public PageAction withSelect(
final Supplier<Set<EntityKey>> selectionSupplier,
final Function<PageAction, PageAction> exec,
final LocTextKey noSelectionMessage) {
this.selectionSupplier = selectionSupplier;
this.exec = exec;
this.noSelectionMessage = noSelectionMessage;
return this;
}
public PageAction withConfirm(final String confirmationMessageKey) {
this.confirm = () -> new LocTextKey(confirmationMessageKey);
return this;
}
public PageAction withConfirm(final Supplier<LocTextKey> confirm) {
this.confirm = confirm;
return this;
}
public PageAction withSuccess(final String successMessageKey) {
this.successMessage = new LocTextKey(successMessageKey);
return this;
}
public PageAction resetEntityKey() {
this.pageContext = this.pageContext.withEntityKey(null);
return this;
}
public PageAction noEventPropagation() {
this.fireActionEvent = false;
return this;
}
public PageAction resetParentEntityKey() {
this.pageContext = this.pageContext.withParentEntityKey(null);
return this;
}
public EntityKey getEntityKey() {
return this.pageContext.getEntityKey();
}
public PageContext pageContext() {
return this.pageContext;
}
public PageAction withEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withEntityKey(entityKey);
return this;
}
public PageAction withEntityKey(final Long modelId, final EntityType entityType) {
if (modelId != null) {
return withEntityKey(String.valueOf(modelId), entityType);
}
return this;
}
public PageAction withEntityKey(final String modelId, final EntityType entityType) {
if (modelId == null || entityType == null) {
return this;
}
this.pageContext = this.pageContext.withEntityKey(new EntityKey(modelId, entityType));
return this;
}
public PageAction withParentEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withParentEntityKey(entityKey);
return this;
}
public PageAction withAttribute(final String name, final String value) {
this.pageContext = this.pageContext.withAttribute(name, value);
return this;
}
public PageContext publish() {
this.pageContext.firePageEvent(new ActionPublishEvent(this));
return this.originalPageContext;
}
public PageContext publishIf(final BooleanSupplier condition) {
if (condition.getAsBoolean()) {
publish();
}
return this.originalPageContext;
}
public EntityKey getSingleSelection() {
final Set<EntityKey> selection = getMultiSelection();
if (selection != null) {
return selection.iterator().next();
}
return null;
}
public Set<EntityKey> getMultiSelection() {
if (this.selectionSupplier != null) {
final Set<EntityKey> selection = this.selectionSupplier.get();
if (selection.isEmpty()) {
if (this.noSelectionMessage != null) {
throw new PageMessageException(this.noSelectionMessage);
}
return null;
}
return selection;
}
if (this.noSelectionMessage != null) {
throw new PageMessageException(this.noSelectionMessage);
}
return null;
}
public static PageAction applySingleSelection(final PageAction action) {
return action.withEntityKey(action.getSingleSelection());
}
public static PageAction onEmptyEntityKeyGoToActivityHome(final PageAction action) {
if (action.getEntityKey() == null) {
final PageContext pageContext = action.pageContext();
final PageAction activityHomeAction = pageContext.createAction(action.definition.activityAlias);
action.pageContext.firePageEvent(new ActionEvent(activityHomeAction, false));
return activityHomeAction;
}
return action;
}
}

View file

@ -8,15 +8,15 @@
package ch.ethz.seb.sebserver.gui.service.page; package ch.ethz.seb.sebserver.gui.service.page;
import java.util.function.Consumer;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
/** Holds a page-context and defines some convenient functionality for page handling */ /** Holds a page-context and defines some convenient functionality for page handling */
public interface PageContext { public interface PageContext {
@ -149,21 +149,12 @@ public interface PageContext {
* @return a copy of this PageContext with the removed attribute */ * @return a copy of this PageContext with the removed attribute */
PageContext removeAttribute(String name); PageContext removeAttribute(String name);
/** Publishes a given PageEvent to the current page tree
* This goes through the page-tree and collects all listeners the are listen to
* the specified page event type.
*
* @param event the concrete PageEvent instance */
<T extends PageEvent> void firePageEvent(T event);
PageAction createAction(ActionDefinition actionDefinition);
/** Apply a confirm dialog with a specified confirm message and a callback code /** Apply a confirm dialog with a specified confirm message and a callback code
* block that will be executed on users OK selection. * block that will be executed on users OK selection.
* *
* @param confirmMessage the localized confirm message key * @param confirmMessage the localized confirm message key
* @param onOK callback code block that will be executed on users OK selection */ * @param onOK callback code block that will be called on users selection */
void applyConfirmDialog(LocTextKey confirmMessage, Runnable onOK); void applyConfirmDialog(LocTextKey confirmMessage, final Consumer<Boolean> callback);
/** This can be used to forward to a defined page. /** This can be used to forward to a defined page.
* *

View file

@ -0,0 +1,259 @@
/*
* 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.page;
import java.util.Set;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import ch.ethz.seb.sebserver.gbl.api.API;
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.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
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.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
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.RestService;
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
/** The main page service that provides functionality to build a page
* with forms and tables as well as dealing with page actions */
public interface PageService {
/** get the WidgetFactory service
*
* @return the WidgetFactory service */
WidgetFactory getWidgetFactory();
/** get the polyglotPageService service
*
* @return the polyglotPageService service */
PolyglotPageService getPolyglotPageService();
/** get the I18nSupport (internationalization support) service
*
* @return the I18nSupport (internationalization support) service */
I18nSupport getI18nSupport();
/** get the JSONMapper for parse, read and write JSON
*
* @return the JSONMapper for parse, read and write JSON */
JSONMapper getJSONMapper();
PageState initPageState(PageState initState);
PageState getCurrentState();
/** Publishes a given PageEvent to the current page tree
* This goes through the page-tree and collects all listeners the are listen to
* the specified page event type.
*
* @param event the concrete PageEvent instance */
<T extends PageEvent> void firePageEvent(T event, PageContext pageContext);
default void executePageAction(final PageAction pageAction) {
executePageAction(pageAction, result -> {
});
}
void executePageAction(PageAction pageAction, Consumer<Result<PageAction>> callback);
void publishAction(final PageAction pageAction);
FormBuilder formBuilder(final PageContext pageContext, final int rows);
<T extends Entity> TableBuilder<T> entityTableBuilder(final RestCall<Page<T>> apiCall);
void clear();
default PageActionBuilder pageActionBuilder(final PageContext pageContext) {
return new PageActionBuilder(this, pageContext);
}
default PageAction onEmptyEntityKeyGoTo(final PageAction action, final ActionDefinition gotoActionDef) {
if (action.getEntityKey() == null) {
final PageContext pageContext = action.pageContext();
final PageAction activityHomeAction = pageActionBuilder(pageContext)
.newAction(gotoActionDef)
.create();
firePageEvent(new ActionEvent(activityHomeAction), activityHomeAction.pageContext());
}
return action;
}
public class PageActionBuilder {
private final PageService pageService;
private final PageContext originalPageContext;
private PageContext pageContext;
private ActionDefinition definition;
private Supplier<LocTextKey> confirm;
private LocTextKey successMessage;
private Supplier<Set<EntityKey>> selectionSupplier;
private LocTextKey noSelectionMessage;
private Function<PageAction, PageAction> exec;
private boolean fireActionEvent = true;
private boolean ignoreMoveAwayFromEdit = false;
protected PageActionBuilder(final PageService pageService, final PageContext pageContext) {
this.pageService = pageService;
this.originalPageContext = pageContext;
}
public PageActionBuilder newAction(final ActionDefinition definition) {
pageContext = originalPageContext.copy();
this.definition = definition;
confirm = null;
successMessage = null;
selectionSupplier = null;
noSelectionMessage = null;
exec = null;
fireActionEvent = true;
ignoreMoveAwayFromEdit = false;
return this;
}
public PageAction create() {
return new PageAction(
definition,
confirm,
successMessage,
selectionSupplier,
noSelectionMessage,
pageContext,
exec,
fireActionEvent,
ignoreMoveAwayFromEdit);
}
public PageActionBuilder publish() {
pageService.publishAction(create());
return this;
}
public PageActionBuilder publishIf(final BooleanSupplier condition) {
if (!condition.getAsBoolean()) {
return this;
}
return this.publish();
}
public PageActionBuilder withExec(final Function<PageAction, PageAction> exec) {
this.exec = exec;
return this;
}
public PageActionBuilder withSelectionSupplier(final Supplier<Set<EntityKey>> selectionSupplier) {
this.selectionSupplier = selectionSupplier;
return this;
}
public PageActionBuilder withSelect(
final Supplier<Set<EntityKey>> selectionSupplier,
final Function<PageAction, PageAction> exec,
final LocTextKey noSelectionMessage) {
this.selectionSupplier = selectionSupplier;
this.exec = exec;
this.noSelectionMessage = noSelectionMessage;
return this;
}
public PageActionBuilder withSimpleRestCall(
final RestService restService,
final Class<? extends RestCall<?>> restCallType) {
this.exec = action -> {
restService.getBuilder(restCallType)
.withURIVariable(
API.PARAM_MODEL_ID,
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
.call()
.onErrorDo(t -> action.pageContext().notifyError(t));
return action;
};
return this;
}
public PageActionBuilder withConfirm(final String confirmationMessageKey) {
this.confirm = () -> new LocTextKey(confirmationMessageKey);
return this;
}
public PageActionBuilder withConfirm(final Supplier<LocTextKey> confirm) {
this.confirm = confirm;
return this;
}
public PageActionBuilder withSuccess(final String successMessageKey) {
this.successMessage = new LocTextKey(successMessageKey);
return this;
}
public PageActionBuilder noEventPropagation() {
this.fireActionEvent = false;
return this;
}
public PageActionBuilder withEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withEntityKey(entityKey);
return this;
}
public PageActionBuilder ignoreMoveAwayFromEdit() {
this.ignoreMoveAwayFromEdit = true;
return this;
}
public PageActionBuilder withEntityKey(final Long modelId, final EntityType entityType) {
if (modelId != null) {
return withEntityKey(String.valueOf(modelId), entityType);
}
return this;
}
public PageActionBuilder withEntityKey(final String modelId, final EntityType entityType) {
if (modelId == null || entityType == null) {
return this;
}
this.pageContext = this.pageContext.withEntityKey(new EntityKey(modelId, entityType));
return this;
}
public PageActionBuilder withParentEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withParentEntityKey(entityKey);
return this;
}
public PageActionBuilder withAttribute(final String name, final String value) {
this.pageContext = this.pageContext.withAttribute(name, value);
return this;
}
}
}

View file

@ -0,0 +1,29 @@
/*
* 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.page;
public interface PageState {
enum Type {
UNDEFINED,
LIST_VIEW,
FORM_VIEW,
FORM_EDIT
}
String name();
Type type();
public Class<? extends TemplateComposer> contentPaneComposer();
public Class<? extends TemplateComposer> actionPaneComposer();
Activity activityAnchor();
}

View file

@ -8,15 +8,23 @@
package ch.ethz.seb.sebserver.gui.service.page.event; package ch.ethz.seb.sebserver.gui.service.page.event;
import ch.ethz.seb.sebserver.gui.service.page.PageAction; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
/** This Event is used to propagate a user-action to the GUI system. /** This Event is used to propagate a user-action to the GUI system.
* Potentially every component can listen to an Event and react on the user-action */ * Potentially every component can listen to an Event and react on the user-action */
public final class ActionEvent implements PageEvent { public final class ActionEvent implements PageEvent {
public final PageAction action; public final PageAction action;
@Deprecated // use the ActionDefinition
public final boolean activity; public final boolean activity;
public ActionEvent(final PageAction action) {
super();
this.action = action;
this.activity = false;
}
@Deprecated
public ActionEvent(final PageAction action, final boolean activity) { public ActionEvent(final PageAction action, final boolean activity) {
super(); super();
this.action = action; this.action = action;

View file

@ -8,7 +8,7 @@
package ch.ethz.seb.sebserver.gui.service.page.event; package ch.ethz.seb.sebserver.gui.service.page.event;
import ch.ethz.seb.sebserver.gui.service.page.PageAction; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
/** This action is used to publish an Action to the Action-Pane for a specified context. /** This action is used to publish an Action to the Action-Pane for a specified context.
* The ActionPane is listening to this events and render specified actions on notify */ * The ActionPane is listening to this events and render specified actions on notify */

View file

@ -24,7 +24,6 @@ import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.page.ComposerService; import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition; import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;

View file

@ -30,10 +30,12 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService; import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
@ -50,6 +52,7 @@ public class DefaultPageLayout implements TemplateComposer {
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService; private final PolyglotPageService polyglotPageService;
private final AuthorizationContextHolder authorizationContextHolder; private final AuthorizationContextHolder authorizationContextHolder;
private final PageService pageStateService;
private final String sebServerVersion; private final String sebServerVersion;
private final boolean multilingual; private final boolean multilingual;
@ -57,12 +60,14 @@ public class DefaultPageLayout implements TemplateComposer {
final WidgetFactory widgetFactory, final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService, final PolyglotPageService polyglotPageService,
final AuthorizationContextHolder authorizationContextHolder, final AuthorizationContextHolder authorizationContextHolder,
final PageService pageStateService,
final Environment environment) { final Environment environment) {
this.widgetFactory = widgetFactory; this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService; this.polyglotPageService = polyglotPageService;
this.authorizationContextHolder = authorizationContextHolder; this.authorizationContextHolder = authorizationContextHolder;
this.sebServerVersion = environment.getProperty("sebserver.version", "--"); this.pageStateService = pageStateService;
this.sebServerVersion = environment.getProperty("sebserver.version", Constants.EMPTY_NOTE);
this.multilingual = BooleanUtils.toBoolean(environment.getProperty("sebserver.gui.multilingual", "false")); this.multilingual = BooleanUtils.toBoolean(environment.getProperty("sebserver.gui.multilingual", "false"));
} }
@ -135,7 +140,7 @@ public class DefaultPageLayout implements TemplateComposer {
// TODO error handling // TODO error handling
} }
MainPageState.clear(); this.pageStateService.clear();
// forward to login page with success message // forward to login page with success message
pageContext.forwardToLoginPage(); pageContext.forwardToLoginPage();

View file

@ -8,50 +8,52 @@
package ch.ethz.seb.sebserver.gui.service.page.impl; package ch.ethz.seb.sebserver.gui.service.page.impl;
import javax.servlet.http.HttpSession;
import org.eclipse.rap.rwt.RWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gui.content.MainPage;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
public final class MainPageState { public final class MainPageState {
private static final Logger log = LoggerFactory.getLogger(MainPageState.class); // private static final Logger log = LoggerFactory.getLogger(MainPageState.class);
//
public PageAction action = null; // private PageAction action = null;
//
private MainPageState() { // private MainPageState() {
} // }
//
public static MainPageState get() { // public action
try { //
// public boolean changeTo(final PageAction action) {
final HttpSession httpSession = RWT // if (this.action.definition != action.definition) {
.getUISession() // this.action = action;
.getHttpSession(); // return true;
// }
MainPageState mainPageState = (MainPageState) httpSession.getAttribute(MainPage.ATTR_MAIN_PAGE_STATE); //
if (mainPageState == null) { // return false;
mainPageState = new MainPageState(); // }
httpSession.setAttribute(MainPage.ATTR_MAIN_PAGE_STATE, mainPageState); //
} // public static MainPageState get() {
// try {
return mainPageState; //
// final HttpSession httpSession = RWT
} catch (final RuntimeException re) { // .getUISession()
throw re; // .getHttpSession();
} catch (final Exception e) { //
log.error("Unexpected error while trying to get MainPageState from user-session"); // MainPageState mainPageState = (MainPageState) httpSession.getAttribute(MainPage.ATTR_MAIN_PAGE_STATE);
} // if (mainPageState == null) {
// mainPageState = new MainPageState();
return null; // httpSession.setAttribute(MainPage.ATTR_MAIN_PAGE_STATE, mainPageState);
} // }
//
public static void clear() { // return mainPageState;
final MainPageState mainPageState = get(); //
mainPageState.action = null; // } catch (final RuntimeException re) {
} // throw re;
// } catch (final Exception e) {
// log.error("Unexpected error while trying to get MainPageState from user-session");
// }
//
// return null;
// }
//
// public static void clear() {
// final MainPageState mainPageState = get();
// mainPageState.action = null;
// }
} }

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
package ch.ethz.seb.sebserver.gui.service.page; package ch.ethz.seb.sebserver.gui.service.page.impl;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -22,6 +22,8 @@ import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;

View file

@ -0,0 +1,170 @@
/*
* 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.page.impl;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.PageState.Type;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
public final class PageAction {
private static final Logger log = LoggerFactory.getLogger(PageAction.class);
public final ActionDefinition definition;
private final Supplier<LocTextKey> confirm;
final LocTextKey successMessage;
private final Supplier<Set<EntityKey>> selectionSupplier;
private final LocTextKey noSelectionMessage;
private PageContext pageContext;
private final Function<PageAction, PageAction> exec;
final boolean fireActionEvent;
final boolean ignoreMoveAwayFromEdit;
public PageAction(
final ActionDefinition definition,
final Supplier<LocTextKey> confirm,
final LocTextKey successMessage,
final Supplier<Set<EntityKey>> selectionSupplier,
final LocTextKey noSelectionMessage,
final PageContext pageContext,
final Function<PageAction, PageAction> exec,
final boolean fireActionEvent,
final boolean ignoreMoveAwayFromEdit) {
this.definition = definition;
this.confirm = confirm;
this.successMessage = successMessage;
this.selectionSupplier = selectionSupplier;
this.noSelectionMessage = noSelectionMessage;
this.pageContext = pageContext;
this.exec = (exec != null) ? exec : Function.identity();
this.fireActionEvent = fireActionEvent;
this.ignoreMoveAwayFromEdit = ignoreMoveAwayFromEdit;
this.pageContext = pageContext.withAttribute(AttributeKeys.READ_ONLY, Constants.TRUE_STRING);
if (definition.targetState != null) {
final Type type = definition.targetState.type();
if (type.name().equals(Type.FORM_EDIT.name())) {
this.pageContext = pageContext.withAttribute(AttributeKeys.READ_ONLY, Constants.FALSE_STRING);
}
}
}
public EntityKey getEntityKey() {
return this.pageContext.getEntityKey();
}
public PageContext pageContext() {
return this.pageContext;
}
public EntityKey getSingleSelection() {
final Set<EntityKey> selection = getMultiSelection();
if (selection != null) {
return selection.iterator().next();
}
return null;
}
public Set<EntityKey> getMultiSelection() {
if (this.selectionSupplier != null) {
final Set<EntityKey> selection = this.selectionSupplier.get();
if (selection.isEmpty()) {
if (this.noSelectionMessage != null) {
throw new PageMessageException(this.noSelectionMessage);
}
return null;
}
return selection;
}
if (this.noSelectionMessage != null) {
throw new PageMessageException(this.noSelectionMessage);
}
return null;
}
void applyAction(final Consumer<Result<PageAction>> callback) {
if (this.confirm != null) {
final LocTextKey confirmMessage = this.confirm.get();
if (confirmMessage != null) {
this.pageContext.applyConfirmDialog(confirmMessage,
confirm -> callback.accept((confirm)
? exec()
: Result.ofRuntimeError("Confirm denied")));
}
} else {
callback.accept(exec());
}
}
private Result<PageAction> exec() {
try {
return Result.of(this.exec.apply(this));
} catch (final PageMessageException pme) {
PageAction.this.pageContext.publishPageMessage(pme);
return Result.ofError(pme);
} catch (final RestCallError restCallError) {
if (restCallError.isFieldValidationError()) {
PageAction.this.pageContext.publishPageMessage(
new LocTextKey("sebserver.form.validation.error.title"),
new LocTextKey("sebserver.form.validation.error.message"));
} else {
log.error("Failed to execute action: {}", PageAction.this, restCallError);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", restCallError);
}
return Result.ofError(restCallError);
} catch (final Throwable t) {
log.error("Failed to execute action: {}", PageAction.this, t);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", t);
return Result.ofError(t);
}
}
public PageAction withEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withEntityKey(entityKey);
return this;
}
public PageAction withParentEntityKey(final EntityKey parentEntityKey) {
this.pageContext = this.pageContext.withParentEntityKey(parentEntityKey);
return this;
}
public PageAction withAttribute(final String name, final String value) {
this.pageContext = this.pageContext.withAttribute(name, value);
return this;
}
public static PageAction applySingleSelection(final PageAction action) {
return action.withEntityKey(action.getSingleSelection());
}
}

View file

@ -8,12 +8,10 @@
package ch.ethz.seb.sebserver.gui.service.page.impl; package ch.ethz.seb.sebserver.gui.service.page.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.eclipse.rap.rwt.widgets.DialogCallback; import org.eclipse.rap.rwt.widgets.DialogCallback;
@ -29,24 +27,18 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessageError;
import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.ComposerService; import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition; import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.widget.Message; import ch.ethz.seb.sebserver.gui.widget.Message;
public class PageContextImpl implements PageContext { public class PageContextImpl implements PageContext {
private static final Logger log = LoggerFactory.getLogger(PageContextImpl.class); private static final Logger log = LoggerFactory.getLogger(PageContextImpl.class);
private static final ListenerComparator LIST_COMPARATOR = new ListenerComparator();
private final I18nSupport i18nSupport; private final I18nSupport i18nSupport;
private final ComposerService composerService; private final ComposerService composerService;
private final Composite root; private final Composite root;
@ -218,48 +210,14 @@ public class PageContextImpl implements PageContext {
} }
@Override @Override
@SuppressWarnings("unchecked") public void applyConfirmDialog(final LocTextKey confirmMessage, final Consumer<Boolean> callback) {
public <T extends PageEvent> void firePageEvent(final T event) {
final Class<? extends PageEvent> typeClass = event.getClass();
final List<PageEventListener<T>> listeners = new ArrayList<>();
ComposerService.traversePageTree(
this.root,
c -> {
final PageEventListener<?> listener =
(PageEventListener<?>) c.getData(PageEventListener.LISTENER_ATTRIBUTE_KEY);
return listener != null && listener.match(typeClass);
},
c -> listeners.add(((PageEventListener<T>) c.getData(PageEventListener.LISTENER_ATTRIBUTE_KEY))));
if (listeners.isEmpty()) {
return;
}
listeners.stream()
.sorted(LIST_COMPARATOR)
.forEach(listener -> {
try {
listener.notify(event);
} catch (final Exception e) {
log.error("Unexpected error while notify PageEventListener: ", e);
}
});
}
@Override
public PageAction createAction(final ActionDefinition actionDefinition) {
return new PageAction(actionDefinition, this);
}
@Override
public void applyConfirmDialog(final LocTextKey confirmMessage, final Runnable onOK) {
final Message messageBox = new Message( final Message messageBox = new Message(
this.root.getShell(), this.root.getShell(),
this.i18nSupport.getText("sebserver.dialog.confirm.title"), this.i18nSupport.getText("sebserver.dialog.confirm.title"),
this.i18nSupport.getText(confirmMessage), this.i18nSupport.getText(confirmMessage),
SWT.OK | SWT.CANCEL); SWT.OK | SWT.CANCEL);
messageBox.setMarkupEnabled(true); messageBox.setMarkupEnabled(true);
messageBox.open(new ConfirmDialogCallback(onOK)); messageBox.open(new ConfirmDialogCallback(callback));
} }
@Override @Override
@ -341,7 +299,6 @@ public class PageContextImpl implements PageContext {
log.info("Cleanup logout failed: {}", e.getMessage()); log.info("Cleanup logout failed: {}", e.getMessage());
} }
MainPageState.clear();
forwardToLoginPage(); forwardToLoginPage();
} }
@ -353,9 +310,9 @@ public class PageContextImpl implements PageContext {
private static final class ConfirmDialogCallback implements DialogCallback { private static final class ConfirmDialogCallback implements DialogCallback {
private static final long serialVersionUID = 1491270214433492441L; private static final long serialVersionUID = 1491270214433492441L;
private final Runnable onOK; private final Consumer<Boolean> onOK;
private ConfirmDialogCallback(final Runnable onOK) { private ConfirmDialogCallback(final Consumer<Boolean> onOK) {
this.onOK = onOK; this.onOK = onOK;
} }
@ -363,25 +320,15 @@ public class PageContextImpl implements PageContext {
public void dialogClosed(final int returnCode) { public void dialogClosed(final int returnCode) {
if (returnCode == SWT.OK) { if (returnCode == SWT.OK) {
try { try {
this.onOK.run(); this.onOK.accept(true);
} catch (final Throwable t) { } catch (final Throwable t) {
log.error( log.error(
"Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable", "Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable",
t); t);
this.onOK.accept(false);
} }
} }
} this.onOK.accept(false);
}
private static final class ListenerComparator implements Comparator<PageEventListener<?>>, Serializable {
private static final long serialVersionUID = 2571739214439340404L;
@Override
public int compare(final PageEventListener<?> o1, final PageEventListener<?> o2) {
final int x = o1.priority();
final int y = o2.priority();
return (x < y) ? -1 : ((x == y) ? 0 : 1);
} }
} }

View file

@ -0,0 +1,236 @@
/*
* 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.page.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import javax.servlet.http.HttpSession;
import org.eclipse.rap.rwt.RWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
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.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
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.PageState;
import ch.ethz.seb.sebserver.gui.service.page.PageState.Type;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@Lazy
@Service
@GuiProfile
public class PageServiceImpl implements PageService {
private static final Logger log = LoggerFactory.getLogger(PageServiceImpl.class);
private static final LocTextKey MSG_GO_AWAY_FROM_EDIT =
new LocTextKey("sebserver.overall.action.goAwayFromEditPageConfirm");
private static final String ATTR_PAGE_STATE = "PAGE_STATE";
private static final ListenerComparator LIST_COMPARATOR = new ListenerComparator();
private final JSONMapper jsonMapper;
private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService;
public PageServiceImpl(
final JSONMapper jsonMapper,
final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService) {
this.jsonMapper = jsonMapper;
this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService;
}
@Override
public WidgetFactory getWidgetFactory() {
return this.widgetFactory;
}
@Override
public PolyglotPageService getPolyglotPageService() {
return this.polyglotPageService;
}
@Override
public I18nSupport getI18nSupport() {
return this.widgetFactory.getI18nSupport();
}
@Override
public JSONMapper getJSONMapper() {
return this.jsonMapper;
}
@Override
public PageState initPageState(final PageState initState) {
// TODO Auto-generated method stub
return null;
}
@Override
public PageState getCurrentState() {
try {
final HttpSession httpSession = RWT
.getUISession()
.getHttpSession();
return (PageState) httpSession.getAttribute(ATTR_PAGE_STATE);
} catch (final Exception e) {
log.error("Failed to get current PageState: ", e);
return null;
}
}
@Override
@SuppressWarnings("unchecked")
public <T extends PageEvent> void firePageEvent(final T event, final PageContext pageContext) {
final Class<? extends PageEvent> typeClass = event.getClass();
final List<PageEventListener<T>> listeners = new ArrayList<>();
ComposerService.traversePageTree(
pageContext.getRoot(),
c -> {
final PageEventListener<?> listener =
(PageEventListener<?>) c.getData(PageEventListener.LISTENER_ATTRIBUTE_KEY);
return listener != null && listener.match(typeClass);
},
c -> listeners.add(((PageEventListener<T>) c.getData(PageEventListener.LISTENER_ATTRIBUTE_KEY))));
if (listeners.isEmpty()) {
return;
}
listeners.stream()
.sorted(LIST_COMPARATOR)
.forEach(listener -> {
try {
listener.notify(event);
} catch (final Exception e) {
log.error("Unexpected error while notify PageEventListener: ", e);
}
});
}
@Override
public void executePageAction(final PageAction pageAction, final Consumer<Result<PageAction>> callback) {
final PageState currentState = getCurrentState();
// TODO should there be a check to reload or not to reload the page if the state is the same?
if (!pageAction.ignoreMoveAwayFromEdit && currentState != null && currentState.type() == Type.FORM_EDIT) {
pageAction.pageContext().applyConfirmDialog(
MSG_GO_AWAY_FROM_EDIT,
confirm -> {
if (confirm) {
exec(pageAction, callback);
} else {
callback.accept(Result.ofRuntimeError("Confirm denied"));
}
});
} else {
exec(pageAction, callback);
}
}
private void exec(final PageAction pageAction, final Consumer<Result<PageAction>> callback) {
pageAction.applyAction(result -> {
if (!result.hasError()) {
final PageAction action = result.get();
if (pageAction.fireActionEvent) {
firePageEvent(new ActionEvent(action), action.pageContext());
}
try {
final HttpSession httpSession = RWT
.getUISession()
.getHttpSession();
log.debug("SET session PageState: {} : {}", pageAction.definition.targetState, httpSession.getId());
httpSession.setAttribute(ATTR_PAGE_STATE, pageAction.definition.targetState);
} catch (final Exception e) {
log.error("Failed to set current PageState: ", e);
}
}
callback.accept(result);
});
}
@Override
public void publishAction(final PageAction pageAction) {
this.firePageEvent(new ActionPublishEvent(pageAction), pageAction.pageContext());
}
@Override
public FormBuilder formBuilder(final PageContext pageContext, final int rows) {
return new FormBuilder(this, pageContext, rows);
}
@Override
public <T extends Entity> TableBuilder<T> entityTableBuilder(final RestCall<Page<T>> apiCall) {
return new TableBuilder<>(this, apiCall);
}
@Override
public void clear() {
try {
final HttpSession httpSession = RWT
.getUISession()
.getHttpSession();
log.debug("Clear session PageState: {}", httpSession.getId());
httpSession.removeAttribute(ATTR_PAGE_STATE);
} catch (final Exception e) {
log.error("Failed to clear current PageState: ", e);
}
}
private static final class ListenerComparator implements Comparator<PageEventListener<?>>, Serializable {
private static final long serialVersionUID = 2571739214439340404L;
@Override
public int compare(final PageEventListener<?> o1, final PageEventListener<?> o2) {
final int x = o1.priority();
final int y = o2.priority();
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
}

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
package ch.ethz.seb.sebserver.gui.service.page; package ch.ethz.seb.sebserver.gui.service.page.impl;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -28,18 +28,6 @@ public final class PageUtils {
private static final Logger log = LoggerFactory.getLogger(PageUtils.class); private static final Logger log = LoggerFactory.getLogger(PageUtils.class);
enum CommonTextKeys {
;
public LocTextKey textKey;
private CommonTextKeys(final LocTextKey textKey) {
this.textKey = textKey;
}
}
public static void clearComposite(final Composite parent) { public static void clearComposite(final Composite parent) {
if (parent == null) { if (parent == null) {
return; return;

View file

@ -12,7 +12,6 @@ import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
/** Interface to SEB Server webservice API thought RestCall's /** Interface to SEB Server webservice API thought RestCall's
@ -72,11 +71,11 @@ public interface RestService {
EntityType entityType, EntityType entityType,
CallType callType); CallType callType);
/** Performs an activation Action on RestCall specified within the given Action. // /** Performs an activation Action on RestCall specified within the given Action.
* The RestCall must be of CallType.ACTIVATION_ACTIVATE or CallType.ACTIVATION_DEACTIVATE // * The RestCall must be of CallType.ACTIVATION_ACTIVATE or CallType.ACTIVATION_DEACTIVATE
* // *
* @param action the Action that defines an entity activation // * @param action the Action that defines an entity activation
* @return the successfully executed Action */ // * @return the successfully executed Action */
<T> PageAction activation(PageAction action); // <T> PageAction activation(PageAction action);
} }

View file

@ -17,12 +17,9 @@ import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
@ -113,24 +110,24 @@ public class RestServiceImpl implements RestService {
return restCall.newBuilder(); return restCall.newBuilder();
} }
@Override // @Override
public <T> PageAction activation(final PageAction action) { // public <T> PageAction activation(final PageAction action) {
if (action.definition.restCallType == null) { // if (action.restCallType() == null) {
throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action"); // throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action");
} // }
//
@SuppressWarnings("unchecked") // @SuppressWarnings("unchecked")
final Class<? extends RestCall<T>> restCallType = // final Class<? extends RestCall<T>> restCallType =
(Class<? extends RestCall<T>>) action.definition.restCallType; // (Class<? extends RestCall<T>>) action.restCallType();
//
this.getBuilder(restCallType) // this.getBuilder(restCallType)
.withURIVariable( // .withURIVariable(
API.PARAM_MODEL_ID, // API.PARAM_MODEL_ID,
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID)) // action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
.call() // .call()
.onErrorDo(t -> action.pageContext().notifyError(t)); // .onErrorDo(t -> action.pageContext().notifyError(t));
//
return action; // return action;
} // }
} }

View file

@ -39,7 +39,8 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction; import ch.ethz.seb.sebserver.gui.service.page.PageService;
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.RestCall;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
@ -52,6 +53,7 @@ public class EntityTable<ROW extends Entity> {
static final String COLUMN_DEFINITION = "COLUMN_DEFINITION"; static final String COLUMN_DEFINITION = "COLUMN_DEFINITION";
static final String TABLE_ROW_DATA = "TABLE_ROW_DATA"; static final String TABLE_ROW_DATA = "TABLE_ROW_DATA";
final PageService pageService;
final WidgetFactory widgetFactory; final WidgetFactory widgetFactory;
final RestCall<Page<ROW>> restCall; final RestCall<Page<ROW>> restCall;
final I18nSupport i18nSupport; final I18nSupport i18nSupport;
@ -75,7 +77,7 @@ public class EntityTable<ROW extends Entity> {
final int type, final int type,
final Composite parent, final Composite parent,
final RestCall<Page<ROW>> restCall, final RestCall<Page<ROW>> restCall,
final WidgetFactory widgetFactory, final PageService pageService,
final List<ColumnDefinition<ROW>> columns, final List<ColumnDefinition<ROW>> columns,
final List<TableRowAction> actions, final List<TableRowAction> actions,
final int pageSize, final int pageSize,
@ -83,8 +85,9 @@ public class EntityTable<ROW extends Entity> {
final Function<EntityTable<ROW>, PageAction> defaultActionFunction) { final Function<EntityTable<ROW>, PageAction> defaultActionFunction) {
this.composite = new Composite(parent, type); this.composite = new Composite(parent, type);
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.i18nSupport = widgetFactory.getI18nSupport(); this.i18nSupport = pageService.getI18nSupport();
this.widgetFactory = pageService.getWidgetFactory();
this.restCall = restCall; this.restCall = restCall;
this.columns = Utils.immutableListOf(columns); this.columns = Utils.immutableListOf(columns);
this.actions = Utils.immutableListOf(actions); this.actions = Utils.immutableListOf(actions);
@ -110,7 +113,7 @@ public class EntityTable<ROW extends Entity> {
.findFirst() .findFirst()
.isPresent() ? new TableFilter<>(this) : null; .isPresent() ? new TableFilter<>(this) : null;
this.table = widgetFactory.tableLocalized(this.composite); this.table = this.widgetFactory.tableLocalized(this.composite);
final GridLayout gridLayout = new GridLayout(columns.size(), true); final GridLayout gridLayout = new GridLayout(columns.size(), true);
this.table.setLayout(gridLayout); this.table.setLayout(gridLayout);
gridData = new GridData(SWT.FILL, SWT.TOP, true, false); gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
@ -133,9 +136,8 @@ public class EntityTable<ROW extends Entity> {
this.table.addListener(SWT.MouseDoubleClick, event -> { this.table.addListener(SWT.MouseDoubleClick, event -> {
final EntityKey selection = getSingleSelection(); final EntityKey selection = getSingleSelection();
if (selection != null) { if (selection != null) {
defaultAction this.pageService.executePageAction(
.withEntityKey(selection) defaultAction.withEntityKey(selection));
.run();
} }
}); });
} }

View file

@ -19,9 +19,9 @@ import org.eclipse.swt.widgets.Composite;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction; import ch.ethz.seb.sebserver.gui.service.page.PageService;
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.RestCall;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
/** <code> /** <code>
* new TableBuilder<T>(RestCall) * new TableBuilder<T>(RestCall)
@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
* </code> */ * </code> */
public class TableBuilder<ROW extends Entity> { public class TableBuilder<ROW extends Entity> {
private final WidgetFactory widgetFactory; private final PageService pageService;
final RestCall<Page<ROW>> restCall; final RestCall<Page<ROW>> restCall;
final List<ColumnDefinition<ROW>> columns = new ArrayList<>(); final List<ColumnDefinition<ROW>> columns = new ArrayList<>();
final List<TableRowAction> actions = new ArrayList<>(); final List<TableRowAction> actions = new ArrayList<>();
@ -50,10 +50,10 @@ public class TableBuilder<ROW extends Entity> {
private int type = SWT.NONE; private int type = SWT.NONE;
public TableBuilder( public TableBuilder(
final WidgetFactory widgetFactory, final PageService pageService,
final RestCall<Page<ROW>> restCall) { final RestCall<Page<ROW>> restCall) {
this.widgetFactory = widgetFactory; this.pageService = pageService;
this.restCall = restCall; this.restCall = restCall;
} }
@ -107,7 +107,7 @@ public class TableBuilder<ROW extends Entity> {
this.type, this.type,
parent, parent,
this.restCall, this.restCall,
this.widgetFactory, this.pageService,
this.columns, this.columns,
this.actions, this.actions,
this.pageSize, this.pageSize,

View file

@ -17,7 +17,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
public class TableNavigator { public class TableNavigator {

View file

@ -23,7 +23,7 @@ import org.eclipse.swt.widgets.Label;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gbl.util.Tuple;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
public class MultiSelection extends Composite implements Selection { public class MultiSelection extends Composite implements Selection {

View file

@ -39,8 +39,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gbl.util.Tuple;
@ -50,8 +48,6 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService; import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.push.ServerPushService; import ch.ethz.seb.sebserver.gui.service.push.ServerPushService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
@Lazy @Lazy
@Service @Service
@ -310,10 +306,6 @@ public class WidgetFactory {
return item; return item;
} }
public <T extends Entity> TableBuilder<T> entityTableBuilder(final RestCall<Page<T>> apiCall) {
return new TableBuilder<>(this, apiCall);
}
public Table tableLocalized(final Composite parent) { public Table tableLocalized(final Composite parent) {
final Table table = new Table(parent, SWT.SINGLE | SWT.NO_SCROLL); final Table table = new Table(parent, SWT.SINGLE | SWT.NO_SCROLL);
this.injectI18n(table); this.injectI18n(table);

View file

@ -15,7 +15,7 @@ sebserver.overall.action.filter.clear=Clear Filter Criteria
sebserver.overall.action.ok=OK sebserver.overall.action.ok=OK
sebserver.overall.action.cancel=Cancel sebserver.overall.action.cancel=Cancel
sebserver.overall.action.close=Close sebserver.overall.action.close=Close
sebserver.overall.action.goAwayFromEditPageConfirm=Are you sure to leave this page? Any unsaved data will be lost.
sebserver.overall.action.category.varia=Varia sebserver.overall.action.category.varia=Varia
################################ ################################