diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java index ac72efe3..cde95596 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamForm.java @@ -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.form.FormBuilder; 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.i18n.I18nSupport; 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.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.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.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.GetExam; 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 final PageFormService pageFormService; + private final PageService pageService; private final ResourceService resourceService; private final static LocTextKey listTitleKey = @@ -77,10 +80,10 @@ public class ExamForm implements TemplateComposer { new LocTextKey("sebserver.exam.indicator.list.pleaseSelect"); protected ExamForm( - final PageFormService pageFormService, + final PageService pageService, final ResourceService resourceService) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.resourceService = resourceService; } @@ -88,7 +91,7 @@ public class ExamForm implements TemplateComposer { public void compose(final PageContext pageContext) { final CurrentUser currentUser = this.resourceService.getCurrentUser(); 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 UserInfo user = currentUser.get(); @@ -131,7 +134,7 @@ public class ExamForm implements TemplateComposer { final boolean modifyGrant = userGrantCheck.m(); // The Exam form - final FormHandle<Exam> formHandle = this.pageFormService.getBuilder( + final FormHandle<Exam> formHandle = this.pageService.formBuilder( formContext.copyOf(content), 4) .readonly(readonly) .putStaticValueIf(isNotNew, @@ -204,34 +207,36 @@ public class ExamForm implements TemplateComposer { ? restService.getRestCall(ImportAsExam.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 - formContext.clearEntityKeys() - .removeAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA) + actionBuilder - .createAction(ActionDefinition.EXAM_MODIFY) + .newAction(ActionDefinition.EXAM_MODIFY) .withEntityKey(entityKey) .publishIf(() -> modifyGrant && readonly) - .createAction(ActionDefinition.EXAM_SAVE) + .newAction(ActionDefinition.EXAM_SAVE) .withExec(formHandle::processFormSave) + .ignoreMoveAwayFromEdit() .publishIf(() -> !readonly && modifyGrant) - .createAction(ActionDefinition.EXAM_CANCEL_MODIFY) + .newAction(ActionDefinition.EXAM_CANCEL_MODIFY) .withEntityKey(entityKey) .withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, String.valueOf(importFromQuizData)) - .withExec(ExamForm::cancelModify) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + .withExec(this::cancelModify) .publishIf(() -> !readonly) - .createAction(ActionDefinition.EXAM_DEACTIVATE) + .newAction(ActionDefinition.EXAM_DEACTIVATE) .withEntityKey(entityKey) - .withExec(restService::activation) + .withSimpleRestCall(restService, DeactivateExam.class) .withConfirm(PageUtils.confirmDeactivation(exam, restService)) .publishIf(() -> writeGrant && readonly && exam.isActive()) - .createAction(ActionDefinition.EXAM_ACTIVATE) + .newAction(ActionDefinition.EXAM_ACTIVATE) .withEntityKey(entityKey) - .withExec(restService::activation) + .withSimpleRestCall(restService, ActivateExam.class) .publishIf(() -> writeGrant && readonly && !exam.isActive()); // additional data in read-only view @@ -244,7 +249,7 @@ public class ExamForm implements TemplateComposer { listTitleKey); 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")) .withPaging(3) .withColumn(new ColumnDefinition<>( @@ -265,19 +270,18 @@ public class ExamForm implements TemplateComposer { .compose(content); - formContext.clearEntityKeys() - .removeAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA) + actionBuilder - .createAction(ActionDefinition.EXAM_INDICATOR_NEW) + .newAction(ActionDefinition.EXAM_INDICATOR_NEW) .withParentEntityKey(entityKey) .publishIf(() -> modifyGrant) - .createAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST) + .newAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST) .withParentEntityKey(entityKey) .withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .publishIf(() -> modifyGrant && indicatorTable.hasAnyContent()) - .createAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST) + .newAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST) .withEntityKey(entityKey) .withSelect(indicatorTable::getSelection, this::deleteSelectedIndicator, emptySelectionTextKey) .publishIf(() -> modifyGrant && indicatorTable.hasAnyContent()); @@ -338,17 +342,20 @@ public class ExamForm implements TemplateComposer { .toString(); } - public static PageAction cancelModify(final PageAction action) { + private PageAction cancelModify(final PageAction action) { final boolean importFromQuizData = BooleanUtils.toBoolean( action.pageContext().getAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA)); if (importFromQuizData) { - final PageContext pageContext = action.pageContext(); - final PageAction activityHomeAction = pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST); - action.pageContext().firePageEvent(new ActionEvent(activityHomeAction, false)); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(action.pageContext()); + final PageAction activityHomeAction = actionBuilder + .newAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST) + .create(); + this.pageService.firePageEvent(new ActionEvent(activityHomeAction), action.pageContext()); return activityHomeAction; } - return PageAction.onEmptyEntityKeyGoToActivityHome(action); + this.pageService.onEmptyEntityKeyGoTo(action, ActionDefinition.EXAM_VIEW_LIST); + return action; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamList.java index 6b8bd199..6d0de6f7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamList.java @@ -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.i18n.I18nSupport; 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.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.impl.PageAction; 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.auth.CurrentUser; @@ -46,7 +48,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @GuiProfile public class ExamList implements TemplateComposer { - private final WidgetFactory widgetFactory; + private final PageService pageService; private final ResourceService resourceService; private final int pageSize; @@ -67,11 +69,11 @@ public class ExamList implements TemplateComposer { new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME); protected ExamList( - final WidgetFactory widgetFactory, + final PageService pageService, final ResourceService resourceService, @Value("${sebserver.gui.list.page.size}") final Integer pageSize) { - this.widgetFactory = widgetFactory; + this.pageService = pageService; this.resourceService = resourceService; this.pageSize = (pageSize != null) ? pageSize : 20; @@ -88,20 +90,23 @@ public class ExamList implements TemplateComposer { @Override public void compose(final PageContext pageContext) { + + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final CurrentUser currentUser = this.resourceService.getCurrentUser(); final RestService restService = this.resourceService.getRestService(); final I18nSupport i18nSupport = this.resourceService.getI18nSupport(); // content page layout with title - final Composite content = this.widgetFactory.defaultPageLayout( + final Composite content = widgetFactory.defaultPageLayout( pageContext.getParent(), new LocTextKey("sebserver.exam.list.title")); final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys()); // 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")) .withPaging(this.pageSize) .withColumnIf(() -> isSEBAdmin, @@ -136,23 +141,23 @@ public class ExamList implements TemplateComposer { columnTitleTypeKey, this::examTypeName, true)) - .withDefaultAction(pageContext - .clearEntityKeys() - .createAction(ActionDefinition.EXAM_VIEW_FROM_LIST)) + .withDefaultAction(actionBuilder + .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST) + .create()) .compose(content); // propagate content actions to action-pane final GrantCheck userGrant = currentUser.grantCheck(EntityType.EXAM); - pageContext.clearEntityKeys() + actionBuilder - .createAction(ActionDefinition.EXAM_IMPORT) + .newAction(ActionDefinition.EXAM_IMPORT) .publishIf(userGrant::im) - .createAction(ActionDefinition.EXAM_VIEW_FROM_LIST) + .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .publishIf(table::hasAnyContent) - .createAction(ActionDefinition.EXAM_MODIFY_FROM_LIST) + .newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .publishIf(() -> userGrant.im() && table.hasAnyContent()); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/IndicatorForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/IndicatorForm.java index e8ca555f..43653236 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/IndicatorForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/IndicatorForm.java @@ -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.form.FormBuilder; 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.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.PageService; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; @@ -43,21 +42,21 @@ public class IndicatorForm implements TemplateComposer { private static final Logger log = LoggerFactory.getLogger(IndicatorForm.class); - private final PageFormService pageFormService; + private final PageService pageService; private final ResourceService resourceService; protected IndicatorForm( - final PageFormService pageFormService, + final PageService pageService, final ResourceService resourceService) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.resourceService = resourceService; } @Override public void compose(final PageContext pageContext) { 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 parentEntityKey = pageContext.getParentEntityKey(); final boolean isNew = entityKey == null; @@ -97,7 +96,7 @@ public class IndicatorForm implements TemplateComposer { formContext.getParent(), titleKey); - final FormHandle<Indicator> formHandle = this.pageFormService.getBuilder( + final FormHandle<Indicator> formHandle = this.pageService.formBuilder( formContext.copyOf(content), 4) .readonly(isReadonly) .putStaticValueIf(() -> !isNew, @@ -136,16 +135,19 @@ public class IndicatorForm implements TemplateComposer { : restService.getRestCall(SaveIndicator.class)); // propagate content actions to action-pane - formContext.clearEntityKeys() - .createAction(ActionDefinition.EXAM_INDICATOR_SAVE) + this.pageService.pageActionBuilder(formContext.clearEntityKeys()) + + .newAction(ActionDefinition.EXAM_INDICATOR_SAVE) .withEntityKey(parentEntityKey) .withExec(formHandle::processFormSave) + .ignoreMoveAwayFromEdit() .publishIf(() -> !isReadonly) - .createAction(ActionDefinition.EXAM_INDICATOR_CANCEL_MODIFY) + .newAction(ActionDefinition.EXAM_INDICATOR_CANCEL_MODIFY) .withEntityKey(parentEntityKey) - .withExec(PageAction::onEmptyEntityKeyGoToActivityHome) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.EXAM_VIEW_LIST)) .publishIf(() -> !isReadonly); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java index 68b9d8a6..340af3b1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java @@ -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.form.FormBuilder; 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.page.PageAction; 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.impl.PageUtils; 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.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.NewInstitution; 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 final PageFormService pageFormService; + private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; private final SebClientConfigDownload sebClientConfigDownload; protected InstitutionForm( - final PageFormService pageFormService, + final PageService pageService, final RestService restService, final CurrentUser currentUser, final SebClientConfigDownload sebClientConfigDownload) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; this.sebClientConfigDownload = sebClientConfigDownload; @@ -68,7 +69,7 @@ public class InstitutionForm implements TemplateComposer { @Override public void compose(final PageContext pageContext) { - final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final EntityKey entityKey = pageContext.getEntityKey(); final boolean isNew = entityKey == null; // get data or create new. Handle error if happen @@ -114,7 +115,7 @@ public class InstitutionForm implements TemplateComposer { titleKey); // The Institution form - final FormHandle<Institution> formHandle = this.pageFormService.getBuilder( + final FormHandle<Institution> formHandle = this.pageService.formBuilder( formContext.copyOf(content), 4) .readonly(isReadonly) .putStaticValueIf(() -> !isNew, @@ -139,20 +140,20 @@ public class InstitutionForm implements TemplateComposer { // propagate content actions to action-pane 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) - .createAction(ActionDefinition.USER_ACCOUNT_NEW) + .newAction(ActionDefinition.USER_ACCOUNT_NEW) .withParentEntityKey(entityKey) .publishIf(() -> userWriteGrant && isReadonly && institution.isActive()) - .createAction(ActionDefinition.INSTITUTION_MODIFY) + .newAction(ActionDefinition.INSTITUTION_MODIFY) .withEntityKey(entityKey) .publishIf(() -> modifyGrant && isReadonly) - .createAction(ActionDefinition.INSTITUTION_EXPORT_SEB_CONFIG) + .newAction(ActionDefinition.INSTITUTION_EXPORT_SEB_CONFIG) .withEntityKey(entityKey) .withExec(action -> { final String downloadURL = this.sebClientConfigDownload.downloadSEBClientConfigURL( @@ -162,26 +163,28 @@ public class InstitutionForm implements TemplateComposer { }) .publishIf(() -> sebConfigWriteGrant && isReadonly && institution.isActive()) - .createAction(ActionDefinition.INSTITUTION_DEACTIVATE) + .newAction(ActionDefinition.INSTITUTION_DEACTIVATE) .withEntityKey(entityKey) - .withExec(this.restService::activation) + .withSimpleRestCall(this.restService, DeactivateInstitution.class) .withConfirm(PageUtils.confirmDeactivation(institution, this.restService)) .publishIf(() -> writeGrant && isReadonly && institution.isActive()) - .createAction(ActionDefinition.INSTITUTION_ACTIVATE) + .newAction(ActionDefinition.INSTITUTION_ACTIVATE) .withEntityKey(entityKey) - .withExec(this.restService::activation) + .withSimpleRestCall(this.restService, ActivateInstitution.class) .publishIf(() -> writeGrant && isReadonly && !institution.isActive()) - .createAction(ActionDefinition.INSTITUTION_SAVE) + .newAction(ActionDefinition.INSTITUTION_SAVE) .withEntityKey(entityKey) .withExec(formHandle::processFormSave) + .ignoreMoveAwayFromEdit() .publishIf(() -> !isReadonly) - .createAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY) + .newAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY) .withEntityKey(entityKey) - .withExec(PageAction::onEmptyEntityKeyGoToActivityHome) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.INSTITUTION_VIEW_LIST)) .publishIf(() -> !isReadonly); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java index bef5ba1e..2a74e35f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java @@ -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.gui.content.action.ActionDefinition; 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.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.impl.PageAction; 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.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck; import ch.ethz.seb.sebserver.gui.table.ColumnDefinition; import ch.ethz.seb.sebserver.gui.table.EntityTable; -import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component @@ -47,29 +48,32 @@ public class InstitutionList implements TemplateComposer { private static final LocTextKey EMPTY_SELECTION_TEXT_KEY = new LocTextKey("sebserver.institution.info.pleaseSelect"); - private final WidgetFactory widgetFactory; + private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; protected InstitutionList( - final WidgetFactory widgetFactory, + final PageService pageService, final RestService restService, final CurrentUser currentUser) { - this.widgetFactory = widgetFactory; + this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; } @Override public void compose(final PageContext pageContext) { - final Composite content = this.widgetFactory.defaultPageLayout( + final Composite content = this.pageService.getWidgetFactory().defaultPageLayout( pageContext.getParent(), TITLE_TEXT_KEY); + final PageActionBuilder pageActionBuilder = + this.pageService.pageActionBuilder(pageContext.clearEntityKeys()); + // 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) .withPaging(3) .withColumn(new ColumnDefinition<>( @@ -87,27 +91,28 @@ public class InstitutionList implements TemplateComposer { ACTIVE_TEXT_KEY, entity -> entity.active, true)) - .withDefaultAction(pageContext - .clearEntityKeys() - .createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)) + .withDefaultAction(pageActionBuilder + .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) + .create()) .compose(content); // propagate content actions to action-pane final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION); final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER); - pageContext.clearEntityKeys() - .createAction(ActionDefinition.INSTITUTION_NEW) + pageActionBuilder + + .newAction(ActionDefinition.INSTITUTION_NEW) .publishIf(instGrant::w) - .createAction(ActionDefinition.USER_ACCOUNT_NEW) + .newAction(ActionDefinition.USER_ACCOUNT_NEW) .publishIf(userGrant::w) - .createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) + .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .publishIf(() -> table.hasAnyContent()) - .createAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST) + .newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .publishIf(() -> instGrant.m() && table.hasAnyContent()); ; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java index b7640ef7..040d70b7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java @@ -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.form.FormBuilder; 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.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.AttributeKeys; 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.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.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.NewLmsSetup; 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 final PageFormService pageFormService; + private final PageService pageService; private final ResourceService resourceService; protected LmsSetupForm( - final PageFormService pageFormService, + final PageService pageService, final ResourceService resourceService) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.resourceService = resourceService; } @@ -70,7 +73,7 @@ public class LmsSetupForm implements TemplateComposer { public void compose(final PageContext pageContext) { final CurrentUser currentUser = this.resourceService.getCurrentUser(); final RestService restService = this.resourceService.getRestService(); - final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final UserInfo user = currentUser.get(); final EntityKey entityKey = pageContext.getEntityKey(); @@ -122,7 +125,7 @@ public class LmsSetupForm implements TemplateComposer { // The LMS Setup form final LmsType lmsType = lmsSetup.getLmsType(); - final FormHandle<LmsSetup> formHandle = this.pageFormService.getBuilder( + final FormHandle<LmsSetup> formHandle = this.pageService.formBuilder( formContext.copyOf(content), 4) .readonly(readonly) .putStaticValueIf(isNotNew, @@ -174,49 +177,58 @@ public class LmsSetupForm implements TemplateComposer { ; // 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) - .createAction(ActionDefinition.LMS_SETUP_MODIFY) + .newAction(ActionDefinition.LMS_SETUP_MODIFY) .withEntityKey(entityKey) .publishIf(() -> modifyGrant && readonly && institutionActive) - .createAction(ActionDefinition.LMS_SETUP_TEST) + .newAction(ActionDefinition.LMS_SETUP_TEST) .withEntityKey(entityKey) .withExec(action -> this.testLmsSetup(action, formHandle)) .publishIf(() -> modifyGrant && isNotNew.getAsBoolean() && institutionActive) - .createAction(ActionDefinition.LMS_SETUP_DEACTIVATE) + .newAction(ActionDefinition.LMS_SETUP_DEACTIVATE) .withEntityKey(entityKey) - .withExec(restService::activation) + .withSimpleRestCall(restService, DeactivateLmsSetup.class) .withConfirm(PageUtils.confirmDeactivation(lmsSetup, restService)) .publishIf(() -> writeGrant && readonly && institutionActive && lmsSetup.isActive()) - .createAction(ActionDefinition.LMS_SETUP_ACTIVATE) + .newAction(ActionDefinition.LMS_SETUP_ACTIVATE) .withEntityKey(entityKey) .withExec(action -> activate(action, formHandle)) .publishIf(() -> writeGrant && readonly && institutionActive && !lmsSetup.isActive()) - .createAction(ActionDefinition.LMS_SETUP_SAVE) + .newAction(ActionDefinition.LMS_SETUP_SAVE) .withEntityKey(entityKey) .withExec(formHandle::processFormSave) + .ignoreMoveAwayFromEdit() .publishIf(() -> !readonly) - .createAction(ActionDefinition.LMS_SETUP_CANCEL_MODIFY) + .newAction(ActionDefinition.LMS_SETUP_CANCEL_MODIFY) .withEntityKey(entityKey) - .withExec(PageAction::onEmptyEntityKeyGoToActivityHome) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.LMS_SETUP_VIEW_LIST)) .publishIf(() -> !readonly); } /** Save and test connection before activation */ 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 activation = restService.activation(testLmsSetup); - return activation; + // if LMS Setup test was successful, the activation action applies + 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 */ diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupList.java index db066f6b..f64d6bcd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupList.java @@ -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.service.ResourceService; 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.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.impl.PageAction; 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.auth.CurrentUser; @@ -63,16 +65,16 @@ public class LmsSetupList implements TemplateComposer { new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME); private final TableFilterAttribute typeFilter; - private final WidgetFactory widgetFactory; + private final PageService pageService; private final ResourceService resourceService; private final int pageSize; protected LmsSetupList( - final WidgetFactory widgetFactory, + final PageService pageService, final ResourceService resourceService, @Value("${sebserver.gui.list.page.size}") final Integer pageSize) { - this.widgetFactory = widgetFactory; + this.pageService = pageService; this.resourceService = resourceService; this.pageSize = (pageSize != null) ? pageSize : 20; @@ -89,20 +91,21 @@ public class LmsSetupList implements TemplateComposer { @Override public void compose(final PageContext pageContext) { + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final CurrentUser currentUser = this.resourceService.getCurrentUser(); final RestService restService = this.resourceService.getRestService(); // content page layout with title - final Composite content = this.widgetFactory.defaultPageLayout( + final Composite content = widgetFactory.defaultPageLayout( pageContext.getParent(), TITLE_TEXT_KEY); final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys()); // table - final EntityTable<LmsSetup> table = - this.widgetFactory.entityTableBuilder(restService.getRestCall(GetLmsSetups.class)) + this.pageService.entityTableBuilder(restService.getRestCall(GetLmsSetups.class)) .withEmptyMessage(EMPTY_LIST_TEXT_KEY) .withPaging(this.pageSize) .withColumnIf(() -> isSEBAdmin, @@ -129,23 +132,23 @@ public class LmsSetupList implements TemplateComposer { ACTIVITY_TEXT_KEY, entity -> entity.active, true)) - .withDefaultAction(pageContext - .clearEntityKeys() - .createAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)) + .withDefaultAction(actionBuilder + .newAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST) + .create()) .compose(content); // propagate content actions to action-pane final GrantCheck userGrant = currentUser.grantCheck(EntityType.LMS_SETUP); - pageContext.clearEntityKeys() + actionBuilder - .createAction(ActionDefinition.LMS_SETUP_NEW) + .newAction(ActionDefinition.LMS_SETUP_NEW) .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) .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) .publishIf(() -> userGrant.im() && table.hasAnyContent()); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java index 654bfe45..9f70bad2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java @@ -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.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.PageContext; +import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; 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.impl.MainPageState; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; 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); - public static final String ATTR_MAIN_PAGE_STATE = "MAIN_PAGE_STATE"; - private static final int ACTIVITY_PANE_WEIGHT = 15; private static final int CONTENT_PANE_WEIGHT = 65; 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 final WidgetFactory widgetFactory; + private final PageService pageStateService; + + public MainPage( + final WidgetFactory widgetFactory, + final PageService pageStateService) { - public MainPage(final WidgetFactory widgetFactory) { this.widgetFactory = widgetFactory; + this.pageStateService = pageStateService; } @Override public void compose(final PageContext pageContext) { - MainPageState.clear(); + this.pageStateService.clear(); final Composite parent = pageContext.getParent(); parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); @@ -123,7 +126,7 @@ public class MainPage implements TemplateComposer { contentObjects.setData( PageEventListener.LISTENER_ATTRIBUTE_KEY, new ContentActionEventListener(event -> pageContext.composerService().compose( - event.action.definition.contentPaneComposer, + event.action.definition.targetState.contentPaneComposer(), event.action.pageContext().copyOf(contentObjects)), 2)); final Composite actionPane = new Composite(mainSash, SWT.NONE); @@ -134,7 +137,7 @@ public class MainPage implements TemplateComposer { actionPane.setData( PageEventListener.LISTENER_ATTRIBUTE_KEY, new ContentActionEventListener(event -> pageContext.composerService().compose( - event.action.definition.actionPaneComposer, + event.action.definition.targetState.actionPaneComposer(), event.action.pageContext().copyOf(actionPane)), 1)); pageContext.composerService().compose( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java index 05713140..91ecbe44 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/QuizDiscoveryList.java @@ -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.gui.content.action.ActionDefinition; 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.i18n.I18nSupport; 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.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.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.quiz.GetQuizzes; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; @@ -70,17 +71,16 @@ public class QuizDiscoveryList implements TemplateComposer { // dependencies private final WidgetFactory widgetFactory; private final ResourceService resourceService; - private final PageFormService pageFormService; + private final PageService pageService; private final int pageSize; protected QuizDiscoveryList( - final PageFormService pageFormService, - final WidgetFactory widgetFactory, + final PageService pageService, final ResourceService resourceService, @Value("${sebserver.gui.list.page.size}") final Integer pageSize) { - this.pageFormService = pageFormService; - this.widgetFactory = widgetFactory; + this.pageService = pageService; + this.widgetFactory = pageService.getWidgetFactory(); this.resourceService = resourceService; this.pageSize = (pageSize != null) ? pageSize : 20; @@ -101,9 +101,11 @@ public class QuizDiscoveryList implements TemplateComposer { pageContext.getParent(), TITLE_TEXT_KEY); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys()); + // table final EntityTable<QuizData> table = - this.widgetFactory.entityTableBuilder(restService.getRestCall(GetQuizzes.class)) + this.pageService.entityTableBuilder(restService.getRestCall(GetQuizzes.class)) .withEmptyMessage(EMPTY_LIST_TEXT_KEY) .withPaging(this.pageSize) .withColumn(new ColumnDefinition<>( @@ -133,22 +135,22 @@ public class QuizDiscoveryList implements TemplateComposer { i18nSupport.getUsersTimeZoneTitleSuffix()), quizData -> quizData.endTime, true)) - .withDefaultAction(t -> pageContext - .clearEntityKeys() - .createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS) + .withDefaultAction(t -> actionBuilder + .newAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS) .withExec(action -> this.showDetails(action, t.getSelectedROWData())) - .noEventPropagation()) + .noEventPropagation() + .create()) .compose(content); // propagate content actions to action-pane final GrantCheck lmsSetupGrant = currentUser.grantCheck(EntityType.LMS_SETUP); final GrantCheck examGrant = currentUser.grantCheck(EntityType.EXAM); - pageContext.clearEntityKeys() + actionBuilder - .createAction(ActionDefinition.LMS_SETUP_NEW) + .newAction(ActionDefinition.LMS_SETUP_NEW) .publishIf(lmsSetupGrant::iw) - .createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS) + .newAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS) .withSelect( table::getSelection, action -> this.showDetails(action, table.getSelectedROWData()), @@ -156,7 +158,7 @@ public class QuizDiscoveryList implements TemplateComposer { .noEventPropagation() .publishIf(table::hasAnyContent) - .createAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT) + .newAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT) .withSelect( table::getSelection, action -> this.importQuizData(action, table), @@ -195,7 +197,7 @@ public class QuizDiscoveryList implements TemplateComposer { private void createDetailsForm(final QuizData quizData, final PageContext pc) { this.widgetFactory.labelSeparator(pc.getParent()); - this.pageFormService.getBuilder(pc, 4) + this.pageService.formBuilder(pc, 4) .readonly(true) .addField(FormBuilder.singleSelection( QuizData.QUIZ_ATTR_LMS_SETUP_ID, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountChangePasswordForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountChangePasswordForm.java index dd3bb323..1c46e2c9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountChangePasswordForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountChangePasswordForm.java @@ -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.form.FormBuilder; 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.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.PageService; 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.useraccount.ChangePassword; 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. */ public class UserAccountChangePasswordForm implements TemplateComposer { - private final PageFormService pageFormService; + private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; private final I18nSupport i18nSupport; protected UserAccountChangePasswordForm( - final PageFormService pageFormService, + final PageService pageService, final RestService restService, - final CurrentUser currentUser, - final I18nSupport i18nSupport) { + final CurrentUser currentUser) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; - this.i18nSupport = i18nSupport; + this.i18nSupport = pageService.getI18nSupport(); } @Override public void compose(final PageContext pageContext) { - final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final EntityKey entityKey = pageContext.getEntityKey(); final UserInfo userInfo = this.restService @@ -82,7 +81,7 @@ public class UserAccountChangePasswordForm implements TemplateComposer { final boolean ownAccount = this.currentUser.get().uuid.equals(entityKey.getModelId()); // The Password Change form - final FormHandle<UserInfo> formHandle = this.pageFormService.getBuilder( + final FormHandle<UserInfo> formHandle = this.pageService.formBuilder( pageContext.copyOf(content), 4) .readonly(false) .putStaticValueIf(() -> entityKey != null, @@ -103,9 +102,11 @@ public class UserAccountChangePasswordForm implements TemplateComposer { .withCondition(() -> entityKey != null)) .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 -> { - formHandle.processFormSave(action); + final PageAction saveAction = formHandle.processFormSave(action); if (ownAccount) { // NOTE: in this case the user changed the password of the own account // this should cause an logout with specified message that password change @@ -118,12 +119,15 @@ public class UserAccountChangePasswordForm implements TemplateComposer { SWT.ERROR); error.open(null); } - return null; + return saveAction; }) + .ignoreMoveAwayFromEdit() .publish() - .createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY) - .withExec(PageAction::onEmptyEntityKeyGoToActivityHome) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + + .newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY) + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.USER_ACCOUNT_VIEW_LIST)) .publish(); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java index 51c5977f..b98fa088 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java @@ -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.form.FormBuilder; 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.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.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.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.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.NewUserAccount; 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 final PageFormService pageFormService; + private final PageService pageService; private final ResourceService resourceService; protected UserAccountForm( - final PageFormService pageFormService, + final PageService pageService, final ResourceService resourceService) { - this.pageFormService = pageFormService; + this.pageService = pageService; this.resourceService = resourceService; } @@ -69,7 +71,7 @@ public class UserAccountForm implements TemplateComposer { public void compose(final PageContext pageContext) { final CurrentUser currentUser = this.resourceService.getCurrentUser(); final RestService restService = this.resourceService.getRestService(); - final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory(); + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final UserInfo user = currentUser.get(); final EntityKey entityKey = pageContext.getEntityKey(); @@ -127,7 +129,7 @@ public class UserAccountForm implements TemplateComposer { titleKey); // The UserAccount form - final FormHandle<UserInfo> formHandle = this.pageFormService.getBuilder( + final FormHandle<UserInfo> formHandle = this.pageService.formBuilder( formContext.copyOf(content), 4) .readonly(readonly) .putStaticValueIf(isNotNew, @@ -187,46 +189,48 @@ public class UserAccountForm implements TemplateComposer { : restService.getRestCall(SaveUserAccount.class)); // 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) - .createAction(ActionDefinition.USER_ACCOUNT_MODIFY) + .newAction(ActionDefinition.USER_ACCOUNT_MODIFY) .withEntityKey(entityKey) .publishIf(() -> modifyGrant && readonly && institutionActive) - .createAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD) + .newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD) .withEntityKey(entityKey) .publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive()) - .createAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE) + .newAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE) .withEntityKey(entityKey) - .withExec(restService::activation) + .withSimpleRestCall(restService, DeactivateUserAccount.class) .withConfirm(PageUtils.confirmDeactivation(userAccount, restService)) .publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive()) - .createAction(ActionDefinition.USER_ACCOUNT_ACTIVATE) + .newAction(ActionDefinition.USER_ACCOUNT_ACTIVATE) .withEntityKey(entityKey) - .withExec(restService::activation) + .withSimpleRestCall(restService, ActivateUserAccount.class) .publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive()) - .createAction(ActionDefinition.USER_ACCOUNT_SAVE) + .newAction(ActionDefinition.USER_ACCOUNT_SAVE) .withEntityKey(entityKey) .withExec(action -> { - final PageAction postChanges = formHandle.processFormSave(action); + final PageAction saveAction = formHandle.processFormSave(action); if (ownAccount) { currentUser.refresh(); pageContext.forwardToMainPage(); } - return postChanges; + return saveAction; }) + .ignoreMoveAwayFromEdit() .publishIf(() -> !readonly) - .createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY) + .newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY) .withEntityKey(entityKey) - .withExec(PageAction::onEmptyEntityKeyGoToActivityHome) - .withConfirm("sebserver.overall.action.modify.cancel.confirm") + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.USER_ACCOUNT_VIEW_LIST)) .publishIf(() -> !readonly); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java index b949df49..2b835e9b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java @@ -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.service.ResourceService; 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.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.impl.PageAction; 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.auth.CurrentUser; @@ -73,16 +75,16 @@ public class UserAccountList implements TemplateComposer { private final TableFilterAttribute languageFilter; // dependencies - private final WidgetFactory widgetFactory; + private final PageService pageService; private final ResourceService resourceService; private final int pageSize; protected UserAccountList( - final WidgetFactory widgetFactory, + final PageService pageService, final ResourceService resourceService, @Value("${sebserver.gui.list.page.size}") final Integer pageSize) { - this.widgetFactory = widgetFactory; + this.pageService = pageService; this.resourceService = resourceService; this.pageSize = (pageSize != null) ? pageSize : 20; @@ -99,17 +101,19 @@ public class UserAccountList implements TemplateComposer { @Override public void compose(final PageContext pageContext) { + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); final CurrentUser currentUser = this.resourceService.getCurrentUser(); final RestService restService = this.resourceService.getRestService(); // content page layout with title - final Composite content = this.widgetFactory.defaultPageLayout( + final Composite content = widgetFactory.defaultPageLayout( pageContext.getParent(), TITLE_TEXT_KEY); final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys()); // table - final EntityTable<UserInfo> table = this.widgetFactory.entityTableBuilder( + final EntityTable<UserInfo> table = this.pageService.entityTableBuilder( restService.getRestCall(GetUserAccounts.class)) .withEmptyMessage(new LocTextKey("sebserver.useraccount.list.empty")) @@ -150,30 +154,30 @@ public class UserAccountList implements TemplateComposer { ACTIVE_TEXT_KEY, entity -> entity.active, true)) - .withDefaultAction(pageContext - .clearEntityKeys() - .createAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)) + .withDefaultAction(actionBuilder + .newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST) + .create()) .compose(content); // propagate content actions to action-pane final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER); - pageContext.clearEntityKeys() + actionBuilder - .createAction(ActionDefinition.USER_ACCOUNT_NEW) + .newAction(ActionDefinition.USER_ACCOUNT_NEW) .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) .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) .publishIf(() -> userGrant.im() && table.hasAnyContent()); } private String getLocaleDisplayText(final UserInfo userInfo) { return (userInfo.language != null) - ? userInfo.language.getDisplayLanguage(this.widgetFactory.getI18nSupport().getCurrentLocale()) + ? userInfo.language.getDisplayLanguage(this.pageService.getI18nSupport().getCurrentLocale()) : Constants.EMPTY_NOTE; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java index e2393c67..ceef7e10 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java @@ -8,471 +8,276 @@ package ch.ethz.seb.sebserver.gui.content.action; -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.activity.PageStateDefinition; 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.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.service.page.PageState; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; /** 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 { INSTITUTION_VIEW_LIST( new LocTextKey("sebserver.institution.action.list"), - InstitutionList.class), + PageStateDefinition.INSTITUTION_LIST), INSTITUTION_VIEW_FORM( new LocTextKey("sebserver.institution.action.form"), - InstitutionForm.class, - INSTITUTION_VIEW_LIST), + PageStateDefinition.INSTITUTION_VIEW), INSTITUTION_NEW( new LocTextKey("sebserver.institution.action.new"), ImageIcon.NEW, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, - false), + PageStateDefinition.INSTITUTION_EDIT), INSTITUTION_VIEW_FROM_LIST( new LocTextKey("sebserver.institution.action.list.view"), ImageIcon.SHOW, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, + PageStateDefinition.INSTITUTION_VIEW, ActionCategory.INSTITUTION_LIST), INSTITUTION_MODIFY_FROM_LIST( new LocTextKey("sebserver.institution.action.list.modify"), ImageIcon.EDIT, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, - ActionCategory.INSTITUTION_LIST, - false), + PageStateDefinition.INSTITUTION_EDIT, + ActionCategory.INSTITUTION_LIST), INSTITUTION_MODIFY( new LocTextKey("sebserver.institution.action.modify"), ImageIcon.EDIT, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, - ActionCategory.FORM, - false), + PageStateDefinition.INSTITUTION_EDIT, + ActionCategory.FORM), INSTITUTION_CANCEL_MODIFY( new LocTextKey("sebserver.overall.action.modify.cancel"), ImageIcon.CANCEL, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, - ActionCategory.FORM, - true), + PageStateDefinition.INSTITUTION_VIEW, + ActionCategory.FORM), INSTITUTION_SAVE( new LocTextKey("sebserver.institution.action.save"), ImageIcon.SAVE, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, + PageStateDefinition.INSTITUTION_VIEW, ActionCategory.FORM), INSTITUTION_ACTIVATE( new LocTextKey("sebserver.institution.action.activate"), ImageIcon.INACTIVE, - InstitutionForm.class, - ActivateInstitution.class, - INSTITUTION_VIEW_LIST, + PageStateDefinition.INSTITUTION_VIEW, ActionCategory.FORM), INSTITUTION_DEACTIVATE( new LocTextKey("sebserver.institution.action.deactivate"), ImageIcon.ACTIVE, - InstitutionForm.class, - DeactivateInstitution.class, - INSTITUTION_VIEW_LIST, + PageStateDefinition.INSTITUTION_VIEW, ActionCategory.FORM), - INSTITUTION_DELETE( - new LocTextKey("sebserver.institution.action.modify"), - ImageIcon.DELETE, - InstitutionList.class, - INSTITUTION_VIEW_LIST), INSTITUTION_EXPORT_SEB_CONFIG( new LocTextKey("sebserver.institution.action.export.sebconfig"), ImageIcon.SAVE, - InstitutionForm.class, - INSTITUTION_VIEW_LIST, + PageStateDefinition.INSTITUTION_VIEW, ActionCategory.FORM), USER_ACCOUNT_VIEW_LIST( new LocTextKey("sebserver.useraccount.action.list"), - UserAccountList.class), + PageStateDefinition.USER_ACCOUNT_LIST), USER_ACCOUNT_VIEW_FORM( new LocTextKey("sebserver.useraccount.action.form"), - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST), + PageStateDefinition.USER_ACCOUNT_VIEW), USER_ACCOUNT_NEW( new LocTextKey("sebserver.useraccount.action.new"), ImageIcon.NEW, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, false), + PageStateDefinition.USER_ACCOUNT_EDIT), USER_ACCOUNT_VIEW_FROM_LIST( new LocTextKey("sebserver.useraccount.action.view"), ImageIcon.SHOW, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, + PageStateDefinition.USER_ACCOUNT_VIEW, ActionCategory.USER_ACCOUNT_LIST), USER_ACCOUNT_MODIFY_FROM_LIST( new LocTextKey("sebserver.useraccount.action.list.modify"), ImageIcon.EDIT, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, - ActionCategory.USER_ACCOUNT_LIST, - false), + PageStateDefinition.USER_ACCOUNT_EDIT, + ActionCategory.USER_ACCOUNT_LIST), USER_ACCOUNT_MODIFY( new LocTextKey("sebserver.useraccount.action.modify"), ImageIcon.EDIT, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, - ActionCategory.FORM, - false), + PageStateDefinition.USER_ACCOUNT_EDIT, + ActionCategory.FORM), USER_ACCOUNT_CANCEL_MODIFY( new LocTextKey("sebserver.overall.action.modify.cancel"), ImageIcon.CANCEL, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, - ActionCategory.FORM, - true), + PageStateDefinition.USER_ACCOUNT_VIEW, + ActionCategory.FORM), USER_ACCOUNT_SAVE( new LocTextKey("sebserver.useraccount.action.save"), ImageIcon.SAVE, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, + PageStateDefinition.USER_ACCOUNT_VIEW, ActionCategory.FORM), USER_ACCOUNT_ACTIVATE( new LocTextKey("sebserver.useraccount.action.activate"), ImageIcon.INACTIVE, - UserAccountForm.class, - ActivateUserAccount.class, - USER_ACCOUNT_VIEW_LIST, + PageStateDefinition.USER_ACCOUNT_VIEW, ActionCategory.FORM), USER_ACCOUNT_DEACTIVATE( new LocTextKey("sebserver.useraccount.action.deactivate"), ImageIcon.ACTIVE, - UserAccountForm.class, - DeactivateUserAccount.class, - USER_ACCOUNT_VIEW_LIST, + PageStateDefinition.USER_ACCOUNT_VIEW, ActionCategory.FORM), - USER_ACCOUNT_DELETE( - new LocTextKey("sebserver.useraccount.action.modify"), - ImageIcon.DELETE, - UserAccountList.class, - USER_ACCOUNT_VIEW_LIST), USER_ACCOUNT_CHANGE_PASSOWRD( new LocTextKey("sebserver.useraccount.action.change.password"), ImageIcon.EDIT, - UserAccountChangePasswordForm.class, - USER_ACCOUNT_VIEW_LIST, - ActionCategory.FORM, - false), + PageStateDefinition.USER_ACCOUNT_PASSWORD_CHANGE, + ActionCategory.FORM), USER_ACCOUNT_CHANGE_PASSOWRD_SAVE( new LocTextKey("sebserver.useraccount.action.change.password.save"), ImageIcon.SAVE, - UserAccountForm.class, - USER_ACCOUNT_VIEW_LIST, + PageStateDefinition.USER_ACCOUNT_VIEW, ActionCategory.FORM), LMS_SETUP_VIEW_LIST( new LocTextKey("sebserver.lmssetup.action.list"), - LmsSetupList.class), + PageStateDefinition.LMS_SETUP_LIST), LMS_SETUP_NEW( new LocTextKey("sebserver.lmssetup.action.new"), ImageIcon.NEW, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, false), + PageStateDefinition.LMS_SETUP_EDIT), LMS_SETUP_VIEW_FROM_LIST( new LocTextKey("sebserver.lmssetup.action.list.view"), ImageIcon.SHOW, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, + PageStateDefinition.LMS_SETUP_VIEW, ActionCategory.LMS_SETUP_LIST), LMS_SETUP_MODIFY_FROM_LIST( new LocTextKey("sebserver.lmssetup.action.list.modify"), ImageIcon.EDIT, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, - ActionCategory.LMS_SETUP_LIST, - false), + PageStateDefinition.LMS_SETUP_EDIT, + ActionCategory.LMS_SETUP_LIST), LMS_SETUP_MODIFY( new LocTextKey("sebserver.lmssetup.action.modify"), ImageIcon.EDIT, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, - ActionCategory.FORM, - false), + PageStateDefinition.LMS_SETUP_EDIT, + ActionCategory.FORM), LMS_SETUP_TEST( new LocTextKey("sebserver.lmssetup.action.test"), ImageIcon.TEST, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, + PageStateDefinition.LMS_SETUP_VIEW, ActionCategory.FORM), LMS_SETUP_CANCEL_MODIFY( new LocTextKey("sebserver.overall.action.modify.cancel"), ImageIcon.CANCEL, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, - ActionCategory.FORM, - true), + PageStateDefinition.LMS_SETUP_VIEW, + ActionCategory.FORM), LMS_SETUP_SAVE( new LocTextKey("sebserver.lmssetup.action.save"), ImageIcon.SAVE, - LmsSetupForm.class, - LMS_SETUP_VIEW_LIST, + PageStateDefinition.LMS_SETUP_VIEW, ActionCategory.FORM), LMS_SETUP_ACTIVATE( new LocTextKey("sebserver.lmssetup.action.activate"), ImageIcon.INACTIVE, - LmsSetupForm.class, - ActivateLmsSetup.class, - LMS_SETUP_VIEW_LIST, + PageStateDefinition.LMS_SETUP_VIEW, ActionCategory.FORM), LMS_SETUP_DEACTIVATE( new LocTextKey("sebserver.lmssetup.action.deactivate"), ImageIcon.ACTIVE, - LmsSetupForm.class, - DeactivateLmsSetup.class, - LMS_SETUP_VIEW_LIST, + PageStateDefinition.LMS_SETUP_VIEW, ActionCategory.FORM), QUIZ_DISCOVERY_VIEW_LIST( new LocTextKey("sebserver.quizdiscovery.action.list"), - QuizDiscoveryList.class), + PageStateDefinition.QUIZ_LIST), QUIZ_DISCOVERY_SHOW_DETAILS( new LocTextKey("sebserver.quizdiscovery.action.details"), ImageIcon.SHOW, + null, ActionCategory.QUIZ_LIST), QUIZ_DISCOVERY_EXAM_IMPORT( new LocTextKey("sebserver.quizdiscovery.action.import"), ImageIcon.IMPORT, - ExamForm.class, - QUIZ_DISCOVERY_VIEW_LIST, - ActionCategory.QUIZ_LIST, - false), + PageStateDefinition.EXAM_EDIT, + ActionCategory.QUIZ_LIST), EXAM_VIEW_LIST( new LocTextKey("sebserver.exam.action.list"), - ExamList.class), + PageStateDefinition.EXAM_LIST), EXAM_IMPORT( new LocTextKey("sebserver.exam.action.import"), ImageIcon.IMPORT, - QuizDiscoveryList.class, - QUIZ_DISCOVERY_VIEW_LIST, - false), + PageStateDefinition.QUIZ_LIST), EXAM_VIEW_FROM_LIST( new LocTextKey("sebserver.exam.action.list.view"), ImageIcon.SHOW, - ExamForm.class, - EXAM_VIEW_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.EXAM_LIST), EXAM_MODIFY_FROM_LIST( new LocTextKey("sebserver.exam.action.list.modify"), ImageIcon.EDIT, - ExamForm.class, - EXAM_VIEW_LIST, - ActionCategory.EXAM_LIST, - false), + PageStateDefinition.EXAM_EDIT, + ActionCategory.EXAM_LIST), EXAM_MODIFY( new LocTextKey("sebserver.exam.action.modify"), ImageIcon.EDIT, - ExamForm.class, - EXAM_VIEW_LIST, - ActionCategory.FORM, - false), + PageStateDefinition.EXAM_EDIT, + ActionCategory.FORM), EXAM_CANCEL_MODIFY( new LocTextKey("sebserver.overall.action.modify.cancel"), ImageIcon.CANCEL, - ExamForm.class, - EXAM_VIEW_LIST, - ActionCategory.FORM, - true), + PageStateDefinition.EXAM_VIEW, + ActionCategory.FORM), EXAM_SAVE( new LocTextKey("sebserver.exam.action.save"), ImageIcon.SAVE, - ExamForm.class, - EXAM_VIEW_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.FORM), EXAM_ACTIVATE( new LocTextKey("sebserver.exam.action.activate"), ImageIcon.INACTIVE, - ExamForm.class, - ActivateExam.class, - EXAM_VIEW_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.FORM), EXAM_DEACTIVATE( new LocTextKey("sebserver.exam.action.deactivate"), ImageIcon.ACTIVE, - ExamForm.class, - DeactivateExam.class, - EXAM_VIEW_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.FORM), EXAM_INDICATOR_NEW( new LocTextKey("sebserver.exam.indicator.action.list.new"), ImageIcon.NEW, - IndicatorForm.class, - EXAM_VIEW_FROM_LIST, - false), + PageStateDefinition.INDICATOR_EDIT), EXAM_INDICATOR_MODIFY_FROM_LIST( new LocTextKey("sebserver.exam.indicator.action.list.modify"), ImageIcon.EDIT, - IndicatorForm.class, - EXAM_VIEW_FROM_LIST, - ActionCategory.INDICATOR_LIST, - false), + PageStateDefinition.INDICATOR_EDIT, + ActionCategory.INDICATOR_LIST), EXAM_INDICATOR_DELETE_FROM_LIST( new LocTextKey("sebserver.exam.indicator.action.list.delete"), ImageIcon.DELETE, - ExamForm.class, - EXAM_VIEW_FROM_LIST, - ActionCategory.INDICATOR_LIST, - true), + PageStateDefinition.EXAM_VIEW, + ActionCategory.INDICATOR_LIST), EXAM_INDICATOR_SAVE( new LocTextKey("sebserver.exam.indicator.action.save"), ImageIcon.SAVE, - ExamForm.class, - EXAM_VIEW_FROM_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.FORM), EXAM_INDICATOR_CANCEL_MODIFY( new LocTextKey("sebserver.overall.action.modify.cancel"), ImageIcon.CANCEL, - ExamForm.class, - EXAM_VIEW_FROM_LIST, - ActionCategory.FORM, - true), - TEST_ACTION( - new LocTextKey("TEST"), - ImageIcon.TEST, - ExamList.class, - EXAM_VIEW_LIST, + PageStateDefinition.EXAM_VIEW, ActionCategory.FORM), ; public final LocTextKey title; public final ImageIcon icon; - public final Class<? extends TemplateComposer> contentPaneComposer; - public final Class<? extends TemplateComposer> actionPaneComposer; - public final Class<? extends RestCall<?>> restCallType; - public final ActionDefinition activityAlias; + public final PageState targetState; public final ActionCategory category; - public final Boolean readonly; - private ActionDefinition( - final LocTextKey title, - final Class<? extends TemplateComposer> contentPaneComposer) { - - this(title, null, contentPaneComposer, ActionPane.class, null, null, null, null); + private ActionDefinition(final LocTextKey title, final PageState targetState) { + this(title, null, targetState, ActionCategory.VARIA); } - private ActionDefinition( - final LocTextKey title, - final Class<? extends TemplateComposer> contentPaneComposer, - final ActionDefinition activityAlias) { - - this(title, null, contentPaneComposer, ActionPane.class, null, activityAlias, null, null); + private ActionDefinition(final LocTextKey title, final ImageIcon icon, final PageState targetState) { + this(title, icon, targetState, ActionCategory.VARIA); } private ActionDefinition( final LocTextKey title, final ImageIcon icon, + final PageState targetState, 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.icon = icon; - this.contentPaneComposer = contentPaneComposer; - this.actionPaneComposer = actionPaneComposer; - this.restCallType = restCallType; - this.activityAlias = activityAlias; - this.category = (category != null) ? category : ActionCategory.VARIA; - this.readonly = readonly; + this.targetState = targetState; + this.category = category; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java index 96b9e009..bb6e3828 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java @@ -28,12 +28,13 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; 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.PageService; 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.ActionPublishEventListener; 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.CustomVariant; @@ -43,13 +44,14 @@ public class ActionPane implements TemplateComposer { private static final String ACTION_EVENT_CALL_KEY = "ACTION_EVENT_CALL"; + private final PageService pageService; private final WidgetFactory widgetFactory; private final Map<String, Tree> actionTrees = new HashMap<>(); - public ActionPane(final WidgetFactory widgetFactory) { - super(); - this.widgetFactory = widgetFactory; + protected ActionPane(final PageService pageService) { + this.pageService = pageService; + this.widgetFactory = pageService.getWidgetFactory(); } @Override @@ -161,7 +163,7 @@ public class ActionPane implements TemplateComposer { final TreeItem treeItem = (TreeItem) event.item; final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY); - action.run(); + this.pageService.executePageAction(action); if (!treeItem.isDisposed()) { treeItem.getParent().deselectAll(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java index bee8f085..65e9d8fb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java @@ -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.gui.content.action.ActionDefinition; 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.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.event.ActionEvent; 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.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.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @@ -44,13 +47,15 @@ public class ActivitiesPane implements TemplateComposer { private final WidgetFactory widgetFactory; private final CurrentUser currentUser; + private final PageService pageService; 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.pageService = pageService; } @Override @@ -73,27 +78,32 @@ public class ActivitiesPane implements TemplateComposer { //navigationGridData.horizontalIndent = 10; navigation.setLayoutData(navigationGridData); + final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext); + // Institution // If current user has SEB Server Admin role, show the Institution list if (userInfo.hasRole(UserRole.SEB_SERVER_ADMIN)) { // institutions (list) as root final TreeItem institutions = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.INSTITUTION_VIEW_LIST.title); + ActivityDefinition.INSTITUTION.displayName); injectActivitySelection( institutions, - pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_LIST)); + actionBuilder + .newAction(ActionDefinition.INSTITUTION_VIEW_LIST) + .create()); } else { // otherwise show the form of the institution for current user final TreeItem institutions = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.INSTITUTION_VIEW_FORM.title); + ActivityDefinition.INSTITUTION.displayName); injectActivitySelection( institutions, - pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_FORM) + actionBuilder.newAction(ActionDefinition.INSTITUTION_VIEW_FORM) .withEntityKey(userInfo.institutionId, EntityType.INSTITUTION) - .withAttribute(AttributeKeys.READ_ONLY, "true")); + .withAttribute(AttributeKeys.READ_ONLY, "true") + .create()); } // User Account @@ -101,30 +111,35 @@ public class ActivitiesPane implements TemplateComposer { if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.USER)) { final TreeItem userAccounts = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.USER_ACCOUNT_VIEW_LIST.title); + ActivityDefinition.USER_ACCOUNT.displayName); injectActivitySelection( userAccounts, - pageContext.createAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST)); + actionBuilder + .newAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST) + .create()); } else { // otherwise show the user account form for current user final TreeItem userAccounts = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.USER_ACCOUNT_VIEW_FORM.title); + ActivityDefinition.USER_ACCOUNT.displayName); injectActivitySelection( userAccounts, - pageContext.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FORM) + actionBuilder.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FORM) .withEntityKey(this.currentUser.get().getEntityKey()) - .withAttribute(AttributeKeys.READ_ONLY, "true")); + .withAttribute(AttributeKeys.READ_ONLY, "true") + .create()); } // LMS Setup if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, EntityType.LMS_SETUP)) { final TreeItem lmsSetup = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.LMS_SETUP_VIEW_LIST.title); + ActivityDefinition.LMS_SETUP.displayName); injectActivitySelection( lmsSetup, - pageContext.createAction(ActionDefinition.LMS_SETUP_VIEW_LIST)); + actionBuilder + .newAction(ActionDefinition.LMS_SETUP_VIEW_LIST) + .create()); } // 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 final TreeItem quizDiscovery = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST.title); + ActivityDefinition.QUIZ_DISCOVERY.displayName); injectActivitySelection( quizDiscovery, - pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST)); + actionBuilder + .newAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST) + .create()); // Exam final TreeItem exam = this.widgetFactory.treeItemLocalized( navigation, - ActionDefinition.EXAM_VIEW_LIST.title); + ActivityDefinition.EXAM.displayName); injectActivitySelection( exam, - pageContext.createAction(ActionDefinition.EXAM_VIEW_LIST)); + actionBuilder + .newAction(ActionDefinition.EXAM_VIEW_LIST) + .create()); } // TODO other activities @@ -157,34 +176,42 @@ public class ActivitiesPane implements TemplateComposer { new ActivitiesActionEventListener(navigation)); // page-selection on (re)load - final MainPageState mainPageState = MainPageState.get(); - - if (mainPageState.action == null) { - mainPageState.action = getActivitySelection(navigation.getItem(0)); + final PageState state = this.pageService.getCurrentState(); + if (state == null) { + final TreeItem item = 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) { final TreeItem treeItem = (TreeItem) event.item; - - System.out.println("selected: " + treeItem); - - final MainPageState mainPageState = MainPageState.get(); final PageAction action = getActivitySelection(treeItem); - if (mainPageState.action.definition != action.definition) { - mainPageState.action = action; - composerCtx.firePageEvent( - new ActionEvent(action, true)); - } + this.pageService.executePageAction( + action, + result -> { + 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 ActionDefinition actionDefinition, + final Activity activity, final String modelId) { if (items == null) { @@ -197,13 +224,14 @@ public class ActivitiesPane implements TemplateComposer { continue; } + final Activity activityAnchor = action.definition.targetState.activityAnchor(); 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)))) { return item; } - final TreeItem _item = findItemByActionDefinition(item.getItems(), actionDefinition, modelId); + final TreeItem _item = findItemByActionDefinition(item.getItems(), activity, modelId); if (_item != null) { return _item; } @@ -212,8 +240,8 @@ public class ActivitiesPane implements TemplateComposer { return null; } - static final TreeItem findItemByActionDefinition(final TreeItem[] items, final ActionDefinition actionDefinition) { - return findItemByActionDefinition(items, actionDefinition, null); + static final TreeItem findItemByActionDefinition(final TreeItem[] items, final PageState pageState) { + return findItemByActionDefinition(items, pageState.activityAnchor(), null); } static final void expand(final TreeItem item) { @@ -242,14 +270,15 @@ public class ActivitiesPane implements TemplateComposer { @Override public void notify(final ActionEvent event) { - final MainPageState mainPageState = MainPageState.get(); - mainPageState.action = event.action; + // TODO +// final MainPageState mainPageState = MainPageState.get(); +// mainPageState.action = event.action; if (!event.activity) { final EntityKey entityKey = event.action.getEntityKey(); final String modelId = (entityKey != null) ? entityKey.modelId : null; final TreeItem item = findItemByActionDefinition( this.navigation.getItems(), - event.action.definition, + event.action.definition.targetState.activityAnchor(), modelId); if (item != null) { this.navigation.select(item); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivityDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivityDefinition.java new file mode 100644 index 00000000..5423bf8d --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivityDefinition.java @@ -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; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java new file mode 100644 index 00000000..81cba0a8 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java @@ -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; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java index 25a2a0c2..62a69aab 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java @@ -25,12 +25,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.exam.Indicator.Threshold; 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.PageService; 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.WidgetFactory; @@ -40,9 +39,8 @@ public class FormBuilder { private static final Logger log = LoggerFactory.getLogger(FormBuilder.class); + final PageService pageService; final WidgetFactory widgetFactory; - final JSONMapper jsonMapper; - private final PolyglotPageService polyglotPageService; public final PageContext pageContext; public final Composite formParent; public final Form form; @@ -53,18 +51,15 @@ public class FormBuilder { private int defaultSpanEmptyCell = 1; private boolean emptyCellSeparation = true; - FormBuilder( - final JSONMapper jsonMapper, - final WidgetFactory widgetFactory, - final PolyglotPageService polyglotPageService, + public FormBuilder( + final PageService pageService, final PageContext pageContext, final int rows) { - this.widgetFactory = widgetFactory; - this.jsonMapper = jsonMapper; - this.polyglotPageService = polyglotPageService; + this.pageService = pageService; + this.widgetFactory = pageService.getWidgetFactory(); this.pageContext = pageContext; - this.form = new Form(jsonMapper); + this.form = new Form(pageService.getJSONMapper()); this.formParent = new Composite(pageContext.getParent(), SWT.NONE); final GridLayout layout = new GridLayout(rows, true); @@ -173,14 +168,12 @@ public class FormBuilder { return buildFor(null); } - public <T extends Entity> FormHandle<T> buildFor( - final RestCall<T> post) { - + public <T extends Entity> FormHandle<T> buildFor(final RestCall<T> post) { return new FormHandle<>( + this.pageService, this.pageContext, this.form, - post, - this.polyglotPageService.getI18nSupport()); + post); } private void empty(final Composite parent, final int hspan, final int vspan) { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java index 3d70cadd..ec1890cd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java @@ -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.service.i18n.I18nSupport; 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.PageContext; -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.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.RestCallError; @@ -33,21 +32,23 @@ public class FormHandle<T extends Entity> { public static final String FIELD_VALIDATION_LOCTEXT_PREFIX = "sebserver.form.validation.fieldError."; + private final PageService pageService; private final PageContext pageContext; private final Form form; private final RestCall<T> post; private final I18nSupport i18nSupport; FormHandle( + final PageService pageService, final PageContext pageContext, final Form form, - final RestCall<T> post, - final I18nSupport i18nSupport) { + final RestCall<T> post) { + this.pageService = pageService; this.pageContext = pageContext; this.form = form; this.post = post; - this.i18nSupport = i18nSupport; + this.i18nSupport = pageService.getI18nSupport(); } /** 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) { return postResult .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) { resultAction = resultAction.withEntityKey(result.getEntityKey()); } - action.pageContext().firePageEvent(new ActionEvent(resultAction, false)); + return resultAction; }) .onErrorDo(this::handleError) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java deleted file mode 100644 index e59d05c5..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/Activity.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/Activity.java new file mode 100644 index 00000000..11c7867e --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/Activity.java @@ -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(); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageAction.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageAction.java deleted file mode 100644 index c18f260a..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageAction.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java index bac0cabe..9ad6fa02 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageContext.java @@ -8,15 +8,15 @@ package ch.ethz.seb.sebserver.gui.service.page; +import java.util.function.Consumer; + import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.event.PageEvent; /** Holds a page-context and defines some convenient functionality for page handling */ public interface PageContext { @@ -149,21 +149,12 @@ public interface PageContext { * @return a copy of this PageContext with the removed attribute */ 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 * block that will be executed on users OK selection. * * @param confirmMessage the localized confirm message key - * @param onOK callback code block that will be executed on users OK selection */ - void applyConfirmDialog(LocTextKey confirmMessage, Runnable onOK); + * @param onOK callback code block that will be called on users selection */ + void applyConfirmDialog(LocTextKey confirmMessage, final Consumer<Boolean> callback); /** This can be used to forward to a defined page. * diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java new file mode 100644 index 00000000..84ac7d26 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageService.java @@ -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; + } + + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageState.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageState.java new file mode 100644 index 00000000..ca743d22 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageState.java @@ -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(); +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEvent.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEvent.java index 03b8c709..d2ccff06 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEvent.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEvent.java @@ -8,15 +8,23 @@ 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. * Potentially every component can listen to an Event and react on the user-action */ public final class ActionEvent implements PageEvent { public final PageAction action; + @Deprecated // use the ActionDefinition 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) { super(); this.action = action; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionPublishEvent.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionPublishEvent.java index fe130a14..c5b487e3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionPublishEvent.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionPublishEvent.java @@ -8,7 +8,7 @@ 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. * The ActionPane is listening to this events and render specified actions on notify */ diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ComposerServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ComposerServiceImpl.java index dae9808b..8b5733d5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ComposerServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ComposerServiceImpl.java @@ -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.PageContext; 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.remote.webservice.auth.AuthorizationContextHolder; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultPageLayout.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultPageLayout.java index 79f98e54..f986be85 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultPageLayout.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultPageLayout.java @@ -30,10 +30,12 @@ import org.springframework.context.annotation.Lazy; import org.springframework.core.env.Environment; 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.gui.service.i18n.LocTextKey; 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.PageService; 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.remote.webservice.auth.AuthorizationContextHolder; @@ -50,6 +52,7 @@ public class DefaultPageLayout implements TemplateComposer { private final WidgetFactory widgetFactory; private final PolyglotPageService polyglotPageService; private final AuthorizationContextHolder authorizationContextHolder; + private final PageService pageStateService; private final String sebServerVersion; private final boolean multilingual; @@ -57,12 +60,14 @@ public class DefaultPageLayout implements TemplateComposer { final WidgetFactory widgetFactory, final PolyglotPageService polyglotPageService, final AuthorizationContextHolder authorizationContextHolder, + final PageService pageStateService, final Environment environment) { this.widgetFactory = widgetFactory; this.polyglotPageService = polyglotPageService; 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")); } @@ -135,7 +140,7 @@ public class DefaultPageLayout implements TemplateComposer { // TODO error handling } - MainPageState.clear(); + this.pageStateService.clear(); // forward to login page with success message pageContext.forwardToLoginPage(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java index e505bc6a..78a4115a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java @@ -8,50 +8,52 @@ 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 { - private static final Logger log = LoggerFactory.getLogger(MainPageState.class); - - public PageAction action = null; - - private MainPageState() { - } - - public static MainPageState get() { - try { - - final HttpSession httpSession = RWT - .getUISession() - .getHttpSession(); - - MainPageState mainPageState = (MainPageState) httpSession.getAttribute(MainPage.ATTR_MAIN_PAGE_STATE); - if (mainPageState == null) { - mainPageState = new MainPageState(); - httpSession.setAttribute(MainPage.ATTR_MAIN_PAGE_STATE, mainPageState); - } - - return mainPageState; - - } 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; - } +// private static final Logger log = LoggerFactory.getLogger(MainPageState.class); +// +// private PageAction action = null; +// +// private MainPageState() { +// } +// +// public action +// +// public boolean changeTo(final PageAction action) { +// if (this.action.definition != action.definition) { +// this.action = action; +// return true; +// } +// +// return false; +// } +// +// public static MainPageState get() { +// try { +// +// final HttpSession httpSession = RWT +// .getUISession() +// .getHttpSession(); +// +// MainPageState mainPageState = (MainPageState) httpSession.getAttribute(MainPage.ATTR_MAIN_PAGE_STATE); +// if (mainPageState == null) { +// mainPageState = new MainPageState(); +// httpSession.setAttribute(MainPage.ATTR_MAIN_PAGE_STATE, mainPageState); +// } +// +// return mainPageState; +// +// } 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; +// } } \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/ModalInputDialog.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java similarity index 94% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/ModalInputDialog.java rename to src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java index f7f88d36..63bf0381 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/ModalInputDialog.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java @@ -6,7 +6,7 @@ * 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.Supplier; @@ -22,6 +22,8 @@ import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Shell; 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.CustomVariant; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java new file mode 100644 index 00000000..ddd7775c --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageAction.java @@ -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()); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java index 3ed27dad..76dfcf72 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java @@ -8,12 +8,10 @@ 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.List; import java.util.Map; +import java.util.function.Consumer; import org.apache.commons.lang3.BooleanUtils; 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.model.EntityKey; 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.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.PageContext; 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.event.PageEvent; -import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener; import ch.ethz.seb.sebserver.gui.widget.Message; public class PageContextImpl implements PageContext { private static final Logger log = LoggerFactory.getLogger(PageContextImpl.class); - private static final ListenerComparator LIST_COMPARATOR = new ListenerComparator(); - private final I18nSupport i18nSupport; private final ComposerService composerService; private final Composite root; @@ -218,48 +210,14 @@ public class PageContextImpl implements PageContext { } @Override - @SuppressWarnings("unchecked") - 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) { + public void applyConfirmDialog(final LocTextKey confirmMessage, final Consumer<Boolean> callback) { final Message messageBox = new Message( this.root.getShell(), this.i18nSupport.getText("sebserver.dialog.confirm.title"), this.i18nSupport.getText(confirmMessage), SWT.OK | SWT.CANCEL); messageBox.setMarkupEnabled(true); - messageBox.open(new ConfirmDialogCallback(onOK)); + messageBox.open(new ConfirmDialogCallback(callback)); } @Override @@ -341,7 +299,6 @@ public class PageContextImpl implements PageContext { log.info("Cleanup logout failed: {}", e.getMessage()); } - MainPageState.clear(); forwardToLoginPage(); } @@ -353,9 +310,9 @@ public class PageContextImpl implements PageContext { private static final class ConfirmDialogCallback implements DialogCallback { 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; } @@ -363,25 +320,15 @@ public class PageContextImpl implements PageContext { public void dialogClosed(final int returnCode) { if (returnCode == SWT.OK) { try { - this.onOK.run(); + this.onOK.accept(true); } catch (final Throwable t) { log.error( "Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable", t); + 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); + this.onOK.accept(false); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageServiceImpl.java new file mode 100644 index 00000000..c182a45d --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageServiceImpl.java @@ -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); + } + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageUtils.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageUtils.java similarity index 88% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageUtils.java rename to src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageUtils.java index 9634f330..4a467589 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/PageUtils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageUtils.java @@ -6,7 +6,7 @@ * 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.function.Supplier; @@ -28,18 +28,6 @@ public final class PageUtils { 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) { if (parent == null) { return; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestService.java index 57217193..f79f6ea2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestService.java @@ -12,7 +12,6 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; 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; /** Interface to SEB Server webservice API thought RestCall's @@ -72,11 +71,11 @@ public interface RestService { EntityType entityType, CallType callType); - /** Performs an activation Action on RestCall specified within the given Action. - * The RestCall must be of CallType.ACTIVATION_ACTIVATE or CallType.ACTIVATION_DEACTIVATE - * - * @param action the Action that defines an entity activation - * @return the successfully executed Action */ - <T> PageAction activation(PageAction action); +// /** Performs an activation Action on RestCall specified within the given Action. +// * The RestCall must be of CallType.ACTIVATION_ACTIVATE or CallType.ACTIVATION_DEACTIVATE +// * +// * @param action the Action that defines an entity activation +// * @return the successfully executed Action */ +// <T> PageAction activation(PageAction action); } \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestServiceImpl.java index 9b74a6e7..72140f52 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestServiceImpl.java @@ -17,12 +17,9 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; 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.JSONMapper; 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.auth.AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService; @@ -113,24 +110,24 @@ public class RestServiceImpl implements RestService { return restCall.newBuilder(); } - @Override - public <T> PageAction activation(final PageAction action) { - if (action.definition.restCallType == null) { - throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action"); - } - - @SuppressWarnings("unchecked") - final Class<? extends RestCall<T>> restCallType = - (Class<? extends RestCall<T>>) action.definition.restCallType; - - this.getBuilder(restCallType) - .withURIVariable( - API.PARAM_MODEL_ID, - action.pageContext().getAttribute(AttributeKeys.ENTITY_ID)) - .call() - .onErrorDo(t -> action.pageContext().notifyError(t)); - - return action; - } +// @Override +// public <T> PageAction activation(final PageAction action) { +// if (action.restCallType() == null) { +// throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action"); +// } +// +// @SuppressWarnings("unchecked") +// final Class<? extends RestCall<T>> restCallType = +// (Class<? extends RestCall<T>>) action.restCallType(); +// +// this.getBuilder(restCallType) +// .withURIVariable( +// API.PARAM_MODEL_ID, +// action.pageContext().getAttribute(AttributeKeys.ENTITY_ID)) +// .call() +// .onErrorDo(t -> action.pageContext().notifyError(t)); +// +// return action; +// } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java index 77684c56..b01bd40c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java @@ -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.gui.service.i18n.I18nSupport; 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.widget.WidgetFactory; 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 TABLE_ROW_DATA = "TABLE_ROW_DATA"; + final PageService pageService; final WidgetFactory widgetFactory; final RestCall<Page<ROW>> restCall; final I18nSupport i18nSupport; @@ -75,7 +77,7 @@ public class EntityTable<ROW extends Entity> { final int type, final Composite parent, final RestCall<Page<ROW>> restCall, - final WidgetFactory widgetFactory, + final PageService pageService, final List<ColumnDefinition<ROW>> columns, final List<TableRowAction> actions, final int pageSize, @@ -83,8 +85,9 @@ public class EntityTable<ROW extends Entity> { final Function<EntityTable<ROW>, PageAction> defaultActionFunction) { this.composite = new Composite(parent, type); - this.widgetFactory = widgetFactory; - this.i18nSupport = widgetFactory.getI18nSupport(); + this.pageService = pageService; + this.i18nSupport = pageService.getI18nSupport(); + this.widgetFactory = pageService.getWidgetFactory(); this.restCall = restCall; this.columns = Utils.immutableListOf(columns); this.actions = Utils.immutableListOf(actions); @@ -110,7 +113,7 @@ public class EntityTable<ROW extends Entity> { .findFirst() .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); this.table.setLayout(gridLayout); 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 -> { final EntityKey selection = getSingleSelection(); if (selection != null) { - defaultAction - .withEntityKey(selection) - .run(); + this.pageService.executePageAction( + defaultAction.withEntityKey(selection)); } }); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java index 062322c5..365206ed 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java @@ -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.Page; 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.widget.WidgetFactory; /** <code> * new TableBuilder<T>(RestCall) @@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; * </code> */ public class TableBuilder<ROW extends Entity> { - private final WidgetFactory widgetFactory; + private final PageService pageService; final RestCall<Page<ROW>> restCall; final List<ColumnDefinition<ROW>> columns = new ArrayList<>(); final List<TableRowAction> actions = new ArrayList<>(); @@ -50,10 +50,10 @@ public class TableBuilder<ROW extends Entity> { private int type = SWT.NONE; public TableBuilder( - final WidgetFactory widgetFactory, + final PageService pageService, final RestCall<Page<ROW>> restCall) { - this.widgetFactory = widgetFactory; + this.pageService = pageService; this.restCall = restCall; } @@ -107,7 +107,7 @@ public class TableBuilder<ROW extends Entity> { this.type, parent, this.restCall, - this.widgetFactory, + this.pageService, this.columns, this.actions, this.pageSize, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java index 39848c9e..fbe87cb9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java @@ -17,7 +17,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; 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; public class TableNavigator { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java index 1aee259a..c7300066 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java @@ -23,7 +23,7 @@ import org.eclipse.swt.widgets.Label; import ch.ethz.seb.sebserver.gbl.Constants; 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; public class MultiSelection extends Composite implements Selection { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java index ef4a2fb5..e1145719 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java @@ -39,8 +39,6 @@ import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; 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.profile.GuiProfile; 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.page.PageContext; 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 @Service @@ -310,10 +306,6 @@ public class WidgetFactory { 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) { final Table table = new Table(parent, SWT.SINGLE | SWT.NO_SCROLL); this.injectI18n(table); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 7b5e428d..c9805e61 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -15,7 +15,7 @@ sebserver.overall.action.filter.clear=Clear Filter Criteria sebserver.overall.action.ok=OK sebserver.overall.action.cancel=Cancel 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 ################################