diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java similarity index 92% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionForm.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java index c42ef299..3265f411 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.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.content; +package ch.ethz.seb.sebserver.gui.content; import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; @@ -20,21 +20,21 @@ import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.Institution; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.form.FormBuilder; -import ch.ethz.seb.sebserver.gui.service.form.FormHandle; -import ch.ethz.seb.sebserver.gui.service.form.PageFormService; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.content.action.InstitutionActions; +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.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.service.page.action.InstitutionActions; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java similarity index 89% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionList.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.java index 2958d3e8..9e3b063b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/InstitutionList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionList.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.content; +package ch.ethz.seb.sebserver.gui.content; import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; @@ -19,17 +19,17 @@ import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain; 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.content.action.InstitutionActions; 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.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.service.page.action.InstitutionActions; 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.table.ColumnDefinition; -import ch.ethz.seb.sebserver.gui.service.table.EntityTable; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +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 diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/LoginPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java similarity index 94% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/LoginPage.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java index 062b8962..342bf160 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/LoginPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.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.impl; +package ch.ethz.seb.sebserver.gui.content; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; @@ -28,8 +28,8 @@ import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext; -import ch.ethz.seb.sebserver.gui.service.widget.Message; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.Message; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java similarity index 93% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPage.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java index 0dd9f14e..19a188a0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.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.impl; +package ch.ethz.seb.sebserver.gui.content; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; @@ -21,15 +21,16 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; 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.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitiesPane; import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionEvent; import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionListener; import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon; +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; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java similarity index 86% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountForm.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java index 83745550..77b95048 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java @@ -6,41 +6,44 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.page.content; +package ch.ethz.seb.sebserver.gui.content; import java.util.UUID; import java.util.function.BooleanSupplier; +import org.apache.tomcat.util.buf.StringUtils; import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.user.UserAccount; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.model.user.UserMod; import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.form.FormBuilder; -import ch.ethz.seb.sebserver.gui.service.form.FormHandle; -import ch.ethz.seb.sebserver.gui.service.form.PageFormService; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions; +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.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.service.page.action.UserAccountActions; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; 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; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component @@ -120,9 +123,6 @@ public class UserAccountForm implements TemplateComposer { .putStaticValueIf(isNotNew, Domain.USER.ATTR_UUID, userAccount.getModelId()) - .putStaticValueIf(isNew, - Domain.USER.ATTR_TIMEZONE, - userAccount.getTimeZone().getID()) .addField(FormBuilder.singleSelection( Domain.USER.ATTR_INSTITUTION_ID, "sebserver.useraccount.form.institution", @@ -144,16 +144,18 @@ public class UserAccountForm implements TemplateComposer { .addField(FormBuilder.singleSelection( Domain.USER.ATTR_LOCALE, "sebserver.useraccount.form.language", - userAccount.getTimeZone().getID(), - () -> widgetFactory.getI18nSupport().getLanguageResources()) - .withLocalizationSupplied()) + userAccount.getLocale().getLanguage(), + widgetFactory.getI18nSupport().localizedLanguageResources())) .addField(FormBuilder.singleSelection( Domain.USER.ATTR_TIMEZONE, "sebserver.useraccount.form.timezone", userAccount.getTimeZone().getID(), - () -> widgetFactory.getI18nSupport().getTimeZoneResources()) - .withLocalizationSupplied()) - // TODO add role selection (create multi selector) + widgetFactory.getI18nSupport().localizedTimeZoneResources())) + .addField(FormBuilder.multiSelection( + USER_ROLE.REFERENCE_NAME, + "sebserver.useraccount.form.roles", + StringUtils.join(userAccount.getRoles(), Constants.LIST_SEPARATOR_CHAR), + widgetFactory.getI18nSupport().localizedUserRoleResources())) .addField(FormBuilder.text( UserMod.ATTR_NAME_NEW_PASSWORD, "sebserver.useraccount.form.password", diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java similarity index 89% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountList.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.java index 25e00b84..963efe34 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/content/UserAccountList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountList.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.content; +package ch.ethz.seb.sebserver.gui.content; import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; @@ -20,19 +20,19 @@ import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions; 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.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.service.page.action.UserAccountActions; 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; -import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition; -import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition.TableFilterAttribute; -import ch.ethz.seb.sebserver.gui.service.table.EntityTable; -import ch.ethz.seb.sebserver.gui.service.table.TableFilter.CriteriaType; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.table.ColumnDefinition; +import ch.ethz.seb.sebserver.gui.table.EntityTable; +import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute; +import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java similarity index 91% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionDefinition.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java index 0099d1fe..5c037877 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java @@ -6,9 +6,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.page.action; +package ch.ethz.seb.sebserver.gui.content.action; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; public enum ActionDefinition { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionPane.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java similarity index 91% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionPane.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.java index 0bf060da..f747827f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/ActionPane.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionPane.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.action; +package ch.ethz.seb.sebserver.gui.content.action; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.template.ImageCell; @@ -23,11 +23,12 @@ import org.springframework.stereotype.Component; 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.TemplateComposer; +import ch.ethz.seb.sebserver.gui.service.page.action.Action; 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.widget.WidgetFactory; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/InstitutionActions.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/InstitutionActions.java similarity index 86% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/InstitutionActions.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/action/InstitutionActions.java index 9ca3ec84..0f5e0335 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/InstitutionActions.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/InstitutionActions.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.action; +package ch.ethz.seb.sebserver.gui.content.action; import java.util.Collection; import java.util.function.Function; @@ -16,11 +16,12 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.Institution; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gui.content.activity.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.PageMessageException; +import ch.ethz.seb.sebserver.gui.service.page.action.Action; import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; -import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection.Activity; import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionEvent; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution; @@ -88,12 +89,14 @@ public final class InstitutionActions { } private static Result fromSelection(final Action action, final boolean edit) { - final Collection selection = action.selectionSupplier.get(); - if (selection.isEmpty()) { - return Result.ofError(new PageMessageException("sebserver.institution.info.pleaseSelect")); - } + return Result.tryCatch(() -> { + final Collection selection = action.getSelectionSupplier().get(); + if (selection.isEmpty()) { + throw new PageMessageException("sebserver.institution.info.pleaseSelect"); + } - return Result.of(goToInstitution(action.pageContext, selection.iterator().next(), edit)); + return goToInstitution(action.pageContext, selection.iterator().next(), edit); + }); } private static ActivitySelection goToInstitution( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/UserAccountActions.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/UserAccountActions.java similarity index 86% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/UserAccountActions.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/action/UserAccountActions.java index c87c8db8..5434f372 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/UserAccountActions.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/UserAccountActions.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.action; +package ch.ethz.seb.sebserver.gui.content.action; import java.util.Collection; import java.util.function.Function; @@ -16,11 +16,12 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gui.content.activity.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.PageMessageException; +import ch.ethz.seb.sebserver.gui.service.page.action.Action; import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; -import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection.Activity; import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionEvent; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount; @@ -87,12 +88,14 @@ public final class UserAccountActions { } private static Result fromSelection(final Action action, final boolean edit) { - final Collection selection = action.selectionSupplier.get(); - if (selection.isEmpty()) { - return Result.ofError(new PageMessageException("sebserver.useraccount.info.pleaseSelect")); - } + return Result.tryCatch(() -> { + final Collection selection = action.getSelectionSupplier().get(); + if (selection.isEmpty()) { + throw new PageMessageException("sebserver.useraccount.info.pleaseSelect"); + } - return Result.of(goToUserAccount(action.pageContext, selection.iterator().next(), edit)); + return goToUserAccount(action.pageContext, selection.iterator().next(), edit); + }); } private static ActivitySelection goToUserAccount( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitiesPane.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitiesPane.java rename to src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java index 53888cb0..046137a7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitiesPane.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.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.activity; +package ch.ethz.seb.sebserver.gui.content.activity; import java.util.Collection; import java.util.EnumMap; @@ -26,12 +26,13 @@ import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; 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.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; +import ch.ethz.seb.sebserver.gui.service.page.activity.ActivityActionHandler; +import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection.Activity; 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.ActivitySelectionEvent; @@ -39,8 +40,8 @@ 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.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @Lazy @Component @@ -192,7 +193,7 @@ public class ActivitiesPane implements TemplateComposer { final MainPageState mainPageState = MainPageState.get(); if (mainPageState.activitySelection == null || - mainPageState.activitySelection.activity == ActivitySelection.Activity.NONE) { + mainPageState.activitySelection.activity == Activity.NONE) { mainPageState.activitySelection = getActivitySelection(navigation.getItem(0)); } pageContext.publishPageEvent( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/Activity.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/Activity.java new file mode 100644 index 00000000..adbefcc7 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/Activity.java @@ -0,0 +1,81 @@ +/* + * 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.InstitutionForm; +import ch.ethz.seb.sebserver.gui.content.InstitutionList; +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.i18n.LocTextKey; +import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; +import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; +import ch.ethz.seb.sebserver.gui.service.page.impl.TODOTemplate; + +public enum Activity { + NONE(TODOTemplate.class, TODOTemplate.class), + INSTITUTION_LIST( + InstitutionList.class, + ActionPane.class, + new LocTextKey("sebserver.activities.institution")), + INSTITUTION_FORM( + InstitutionForm.class, + ActionPane.class, + new LocTextKey("sebserver.activities.institution")), + + USER_ACCOUNT_LIST( + UserAccountList.class, + ActionPane.class, + new LocTextKey("sebserver.activities.useraccount")), + + USER_ACCOUNT_FORM( + UserAccountForm.class, + ActionPane.class, + new LocTextKey("sebserver.activities.useraccount")), + +// USERS(UserAccountsForm.class, ActionPane.class), +// +// EXAMS(ExamsListPage.class, ActionPane.class), +// SEB_CONFIGS(SEBConfigurationForm.class, ActionPane.class), +// SEB_CONFIG(SEBConfigurationPage.class, ActionPane.class), +// SEB_CONFIG_TEMPLATES(TODOTemplate.class, ActionPane.class), +// MONITORING(MonitoringForm.class, ActionPane.class), +// RUNNING_EXAMS(RunningExamForm.class, ActionPane.class), +// RUNNING_EXAM(RunningExamPage.class, ActionPane.class, AttributeKeys.EXAM_ID), +// LOGS(TODOTemplate.class, ActionPane.class), + ; + + public final LocTextKey title; + public final Class contentPaneComposer; + public final Class actionPaneComposer; + //public final String modelIdAttribute; + + private Activity( + final Class objectPaneComposer, + final Class selectionPaneComposer, + final LocTextKey title) { + + this.title = title; + this.contentPaneComposer = objectPaneComposer; + this.actionPaneComposer = selectionPaneComposer; + } + + private Activity( + final Class objectPaneComposer, + final Class selectionPaneComposer) { + + this.title = null; + this.contentPaneComposer = objectPaneComposer; + this.actionPaneComposer = selectionPaneComposer; + } + + public final ActivitySelection createSelection() { + return new ActivitySelection(this); + } + } \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/FieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/FieldBuilder.java new file mode 100644 index 00000000..48ea7f47 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FieldBuilder.java @@ -0,0 +1,63 @@ +/* + * 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.form; + +import java.util.function.BooleanSupplier; + +abstract class FieldBuilder { + int spanLabel = -1; + int spanInput = -1; + int spanEmptyCell = -1; + boolean autoEmptyCellSeparation = false; + String group = null; + BooleanSupplier condition = null; + + final String name; + final String label; + final String value; + + protected FieldBuilder(final String name, final String label, final String value) { + this.name = name; + this.label = label; + this.value = value; + } + + public FieldBuilder withLabelSpan(final int span) { + this.spanLabel = span; + return this; + } + + public FieldBuilder withInputSpan(final int span) { + this.spanInput = span; + return this; + } + + public FieldBuilder withEmptyCellSpan(final int span) { + this.spanEmptyCell = span; + return this; + } + + public FieldBuilder withEmptyCellSeparation(final boolean separation) { + this.autoEmptyCellSeparation = separation; + return this; + } + + public FieldBuilder withGroup(final String group) { + this.group = group; + return this; + } + + public FieldBuilder withCondition(final BooleanSupplier condition) { + this.condition = condition; + return this; + } + + abstract void build(FormBuilder builder); + +} \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/Form.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/Form.java similarity index 69% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/form/Form.java rename to src/main/java/ch/ethz/seb/sebserver/gui/form/Form.java index 8029d5c1..e196745d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/Form.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/Form.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.form; +package ch.ethz.seb.sebserver.gui.form; import java.util.ArrayList; import java.util.HashSet; @@ -16,13 +16,15 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.eclipse.rap.rwt.RWT; -import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -31,8 +33,9 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.FormBinding; -import ch.ethz.seb.sebserver.gui.service.widget.ImageUpload; -import ch.ethz.seb.sebserver.gui.service.widget.SingleSelection; +import ch.ethz.seb.sebserver.gui.widget.ImageUpload; +import ch.ethz.seb.sebserver.gui.widget.MultiSelection; +import ch.ethz.seb.sebserver.gui.widget.SingleSelection; public final class Form implements FormBinding { @@ -40,7 +43,8 @@ public final class Form implements FormBinding { private final ObjectNode objectRoot; private final Map staticValues = new LinkedHashMap<>(); - private final Map formFields = new LinkedHashMap<>(); + private final MultiValueMap formFields = new LinkedMultiValueMap<>(); + //private final Map> formFields = new LinkedHashMap<>(); private final Map subForms = new LinkedHashMap<>(); private final Map> subLists = new LinkedHashMap<>(); private final Map> groups = new LinkedHashMap<>(); @@ -72,22 +76,26 @@ public final class Form implements FormBinding { public String getFormUrlEncoded() { final StringBuffer buffer = new StringBuffer(); for (final Map.Entry entry : this.staticValues.entrySet()) { - appendFormUrlEncoded(buffer, entry.getKey(), entry.getValue()); + appendFormUrlEncodedValue(buffer, entry.getKey(), entry.getValue()); } - for (final Map.Entry entry : this.formFields.entrySet()) { - appendFormUrlEncoded(buffer, entry.getKey(), entry.getValue().getValue()); + for (final Map.Entry> entry : this.formFields.entrySet()) { + entry.getValue() + .stream() + .forEach(ffa -> appendFormUrlEncodedValue(buffer, entry.getKey(), ffa.getValue())); } return buffer.toString(); } - public String getValue(final String name) { - final FormFieldAccessor formFieldAccessor = this.formFields.get(name); - if (formFieldAccessor != null) { - return formFieldAccessor.getValue(); + public List getValue(final String name) { + if (this.formFields.containsKey(name)) { + return this.formFields + .get(name) + .stream() + .map(ffa -> ffa.getValue()) + .collect(Collectors.toList()); } - return null; } @@ -109,23 +117,25 @@ public final class Form implements FormBinding { } public Form putField(final String name, final Label label, final Label field) { - this.formFields.put(name, createAccessor(label, field)); + this.formFields.add(name, createAccessor(label, field)); return this; } public Form putField(final String name, final Label label, final Text field) { - this.formFields.put(name, createAccessor(label, field)); + this.formFields.add(name, createAccessor(label, field)); return this; } - public void putField(final String name, final Label label, final Combo field) { - if (field instanceof SingleSelection) { - this.formFields.put(name, createAccessor(label, (SingleSelection) field)); - } + public void putField(final String name, final Label label, final SingleSelection field) { + this.formFields.add(name, createAccessor(label, field)); + } + + public void putField(final String name, final Label label, final MultiSelection field) { + this.formFields.add(name, createAccessor(label, field)); } public void putField(final String name, final Label label, final ImageUpload imageUpload) { - this.formFields.put(name, createAccessor(label, imageUpload)); + this.formFields.add(name, createAccessor(label, imageUpload)); } public void putSubForm(final String name, final Form form) { @@ -174,7 +184,7 @@ public final class Form implements FormBinding { this.formFields.entrySet() .stream() .filter(entity -> nameFilter.test(entity.getKey())) - .map(entity -> entity.getValue()) + .flatMap(entity -> entity.getValue().stream()) .forEach(processor); } @@ -183,11 +193,10 @@ public final class Form implements FormBinding { this.objectRoot.put(entry.getKey(), entry.getValue()); } - for (final Map.Entry entry : this.formFields.entrySet()) { - final FormFieldAccessor accessor = entry.getValue(); - if (accessor.control.isVisible()) { - this.objectRoot.put(entry.getKey(), accessor.getValue()); - } + for (final Map.Entry> entry : this.formFields.entrySet()) { + entry.getValue() + .stream() + .forEach(ffa -> this.objectRoot.put(entry.getKey(), ffa.getValue())); } for (final Map.Entry entry : this.subForms.entrySet()) { @@ -231,7 +240,15 @@ public final class Form implements FormBinding { @Override public void setValue(final String value) { singleSelection.select(value); } }; } + private FormFieldAccessor createAccessor( + final Label label, + final MultiSelection multiSelection) { + return new FormFieldAccessor(label, multiSelection) { + @Override public String getValue() { return multiSelection.getSelectionValue(); } + @Override public void setValue(final String value) { multiSelection.select(value); } + }; + } private FormFieldAccessor createAccessor(final Label label, final ImageUpload imageUpload) { return new FormFieldAccessor(label, imageUpload) { @Override public String getValue() { return imageUpload.getImageBase64(); } @@ -240,14 +257,24 @@ public final class Form implements FormBinding { } //@formatter:on - private void appendFormUrlEncoded(final StringBuffer buffer, final String name, final String value) { - if (StringUtils.isNoneBlank(value)) { - if (buffer.length() > 0) { - buffer.append(Constants.FORM_URL_ENCODED_SEPARATOR); + /* + * Adds the given name and value in from URL encoded format to the given StringBuffer. + * Checks first if the value String is a comma separated list. If true, splits values + * and adds every value within the same name mapping to the string buffer + */ + private void appendFormUrlEncodedValue(final StringBuffer buffer, final String name, final String value) { + final String[] split = StringUtils.split(value, Constants.LIST_SEPARATOR_CHAR); + if (split != null) { + for (int i = 0; i < split.length; i++) { + if (StringUtils.isNoneBlank(split[i])) { + if (buffer.length() > 0) { + buffer.append(Constants.FORM_URL_ENCODED_SEPARATOR); + } + buffer.append(name) + .append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR) + .append(split[i]); + } } - buffer.append(name) - .append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR) - .append(value); } } 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 new file mode 100644 index 00000000..a47e7e89 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java @@ -0,0 +1,223 @@ +/* + * 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 java.util.List; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabItem; +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.EntityKey; +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.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; + +public class FormBuilder { + + private static final Logger log = LoggerFactory.getLogger(FormBuilder.class); + + final WidgetFactory widgetFactory; + private final PolyglotPageService polyglotPageService; + public final PageContext pageContext; + public final Composite formParent; + public final Form form; + + boolean readonly = false; + private int defaultSpanLabel = 1; + private int defaultSpanInput = 2; + private int defaultSpanEmptyCell = 1; + private boolean emptyCellSeparation = true; + + FormBuilder( + final EntityKey entityKey, + final JSONMapper jsonMapper, + final WidgetFactory widgetFactory, + final PolyglotPageService polyglotPageService, + final PageContext pageContext, + final int rows) { + + this.widgetFactory = widgetFactory; + this.polyglotPageService = polyglotPageService; + this.pageContext = pageContext; + this.form = new Form(jsonMapper, entityKey); + + this.formParent = new Composite(pageContext.getParent(), SWT.NONE); + final GridLayout layout = new GridLayout(rows, true); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginLeft = 10; + layout.marginTop = 10; + this.formParent.setLayout(layout); + this.formParent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + public FormBuilder readonly(final boolean readonly) { + this.readonly = readonly; + return this; + } + + public FormBuilder setVisible(final boolean visible, final String group) { + this.form.setVisible(visible, group); + return this; + } + + public FormBuilder setControl(final TabItem instTab) { + instTab.setControl(this.formParent); + return this; + } + + public FormBuilder withDefaultSpanLabel(final int span) { + this.defaultSpanLabel = span; + return this; + } + + public FormBuilder withDefaultSpanInput(final int span) { + this.defaultSpanInput = span; + return this; + } + + public FormBuilder withDefaultSpanEmptyCell(final int span) { + this.defaultSpanEmptyCell = span; + return this; + } + + public FormBuilder withEmptyCellSeparation(final boolean separation) { + this.emptyCellSeparation = separation; + return this; + } + + public FormBuilder addEmptyCellIf(final BooleanSupplier condition) { + if (condition != null && condition.getAsBoolean()) { + return addEmptyCell(); + } + return this; + } + + public FormBuilder addEmptyCell() { + return addEmptyCell(1); + } + + public FormBuilder addEmptyCell(final int span) { + empty(this.formParent, span, 1); + return this; + } + + public FormBuilder putStaticValueIf(final BooleanSupplier condition, final String name, final String value) { + if (condition != null && condition.getAsBoolean()) { + return putStaticValue(name, value); + } + + return this; + } + + public FormBuilder putStaticValue(final String name, final String value) { + try { + this.form.putStatic(name, value); + } catch (final Exception e) { + log.error("Failed to put static field value to json object: ", e); + } + return this; + } + + public FormBuilder addField(final FieldBuilder template) { + if (template.condition == null || template.condition.getAsBoolean()) { + template.spanLabel = (template.spanLabel < 0) ? this.defaultSpanLabel : template.spanLabel; + template.spanInput = (template.spanInput < 0) ? this.defaultSpanInput : template.spanInput; + template.spanEmptyCell = (template.spanEmptyCell < 0) ? this.defaultSpanEmptyCell : template.spanEmptyCell; + template.autoEmptyCellSeparation = template.autoEmptyCellSeparation || this.emptyCellSeparation; + + if (template.autoEmptyCellSeparation && this.form.hasFields()) { + addEmptyCell(template.spanEmptyCell); + } + + template.build(this); + + if (StringUtils.isNoneBlank(template.group)) { + this.form.addToGroup(template.group, template.name); + } + } + return this; + } + + public FormHandle buildFor( + final RestCall post, + final Function postPostHandle) { + + return new FormHandle<>( + this.pageContext, + this.form, + post, + (postPostHandle == null) ? Function.identity() : postPostHandle, + this.polyglotPageService.getI18nSupport()); + } + + private void empty(final Composite parent, final int hspan, final int vspan) { + final Label empty = new Label(parent, SWT.LEFT); + empty.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, hspan, vspan)); + empty.setText(""); + } + + public static TextFieldBuilder text(final String name, final String label, final String value) { + return new TextFieldBuilder(name, label, value); + } + + public static SelectionFieldBuilder singleSelection( + final String name, + final String label, + final String value, + final Supplier>> itemsSupplier) { + + return new SelectionFieldBuilder(name, label, value, itemsSupplier); + } + + public static SelectionFieldBuilder multiSelection( + final String name, + final String label, + final String value, + final Supplier>> itemsSupplier) { + + return new SelectionFieldBuilder(name, label, value, itemsSupplier) + .asMultiSelection(); + } + + public static ImageUploadFieldBuilder imageUpload(final String name, final String label, final String value) { + return new ImageUploadFieldBuilder(name, label, value); + } + + Label labelLocalized(final Composite parent, final String locTextKey, final int hspan) { + final Label label = this.widgetFactory.labelLocalized(parent, locTextKey); + final GridData gridData = new GridData(SWT.RIGHT, SWT.TOP, true, false, hspan, 1); + gridData.verticalIndent = 5; + label.setLayoutData(gridData); + return label; + } + + Label valueLabel(final Composite parent, final String value, final int hspan) { + final Label label = new Label(parent, SWT.NONE); + label.setText((StringUtils.isNoneBlank(value)) ? value : Constants.EMPTY_NOTE); + final GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, true, false, hspan, 1); + label.setLayoutData(gridData); + return label; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormHandle.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java similarity index 92% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormHandle.java rename to src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java index a20a1317..359fd478 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormHandle.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/FormHandle.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.form; +package ch.ethz.seb.sebserver.gui.form; import java.util.function.Consumer; import java.util.function.Function; @@ -15,13 +15,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.ethz.seb.sebserver.gbl.util.Result; -import ch.ethz.seb.sebserver.gui.service.form.Form.FormFieldAccessor; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +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.FieldValidationError; import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.action.Action; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/ImageUploadFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/ImageUploadFieldBuilder.java new file mode 100644 index 00000000..5ea2aa24 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/ImageUploadFieldBuilder.java @@ -0,0 +1,37 @@ +/* + * 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.form; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Label; + +import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; +import ch.ethz.seb.sebserver.gui.widget.ImageUpload; + +public final class ImageUploadFieldBuilder extends FieldBuilder { + + ImageUploadFieldBuilder(final String name, final String label, final String value) { + super(name, label, value); + } + + @Override + void build(final FormBuilder builder) { + final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); + final ImageUpload imageUpload = builder.widgetFactory.imageUploadLocalized( + builder.formParent, + new LocTextKey("sebserver.overall.upload"), + builder.readonly); + final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1); + imageUpload.setLayoutData(gridData); + imageUpload.setImageBase64(this.value); + builder.form.putField(this.name, lab, imageUpload); + } + +} \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/PageFormService.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java similarity index 91% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/form/PageFormService.java rename to src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java index d967908f..04283bc0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/PageFormService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/PageFormService.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.form; +package ch.ethz.seb.sebserver.gui.form; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -16,7 +16,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; 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.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Component diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java new file mode 100644 index 00000000..47692f6c --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java @@ -0,0 +1,122 @@ +/* + * 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.form; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Control; +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.widget.MultiSelection; +import ch.ethz.seb.sebserver.gui.widget.Selection; +import ch.ethz.seb.sebserver.gui.widget.SingleSelection; + +public final class SelectionFieldBuilder extends FieldBuilder { + + final Supplier>> itemsSupplier; + Consumer
selectionListener = null; + boolean multi = false; + + SelectionFieldBuilder( + final String name, + final String label, + final String value, + final Supplier>> itemsSupplier) { + + super(name, label, value); + this.itemsSupplier = itemsSupplier; + } + + public SelectionFieldBuilder withSelectionListener(final Consumer selectionListener) { + this.selectionListener = selectionListener; + return this; + } + + public SelectionFieldBuilder asMultiSelection() { + this.multi = true; + return this; + } + + @Override + void build(final FormBuilder builder) { + final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); + if (builder.readonly) { + buildReadOnly(builder, lab); + } else { + buildInput(builder, lab); + } + } + + private void buildInput(final FormBuilder builder, final Label lab) { + final Selection selection = (this.multi) + ? builder.widgetFactory.multiSelectionLocalized(builder.formParent, this.itemsSupplier) + : builder.widgetFactory.singleSelectionLocalized(builder.formParent, this.itemsSupplier); + + final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1); + ((Control) selection).setLayoutData(gridData); + selection.select(this.value); + if (this.multi) { + builder.form.putField(this.name, lab, (MultiSelection) selection); + } else { + builder.form.putField(this.name, lab, (SingleSelection) selection); + } + if (this.selectionListener != null) { + ((Control) selection).addListener(SWT.Selection, e -> { + this.selectionListener.accept(builder.form); + }); + } + } + + /* Build the read-only representation of the selection field */ + private void buildReadOnly(final FormBuilder builder, final Label lab) { + builder.form.putField( + this.name, lab, + builder.valueLabel( + builder.formParent, + getSelectionValue(this.value, this.multi), + this.spanInput)); + } + + /* + * For Single selection just the selected value, for multi selection a comma + * separated list of values within a String value. + * + * @param key the key or keys, in case of multi selection a comma separated String of keys + * + * @param multi indicates multi seleciton + * + * @return selected value or comma separated String list of selected values + */ + private String getSelectionValue(final String key, final boolean multi) { + if (multi) { + final Collection keys = Arrays.asList(StringUtils.split(key, Constants.LIST_SEPARATOR)); + return StringUtils.join(this.itemsSupplier.get().stream() + .filter(tuple -> keys.contains(tuple._1)) + .map(tuple -> tuple._2) + .collect(Collectors.toList()), + Constants.LIST_SEPARATOR); + } else { + return this.itemsSupplier.get().stream() + .filter(tuple -> key.equals(tuple._1)) + .findFirst() + .map(tuple -> tuple._2) + .orElse(null); + } + } +} \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java new file mode 100644 index 00000000..197fb546 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/TextFieldBuilder.java @@ -0,0 +1,52 @@ +/* + * 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.form; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +public final class TextFieldBuilder extends FieldBuilder { + + boolean isPassword = false; + + TextFieldBuilder(final String name, final String label, final String value) { + super(name, label, value); + } + + public TextFieldBuilder asPasswordField() { + this.isPassword = true; + return this; + } + + @Override + void build(final FormBuilder builder) { + if (this.isPassword && builder.readonly) { + return; + } + + final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); + if (builder.readonly) { + builder.form.putField(this.name, lab, + builder.valueLabel(builder.formParent, this.value, this.spanInput)); + } else { + final Text textInput = new Text(builder.formParent, (this.isPassword) + ? SWT.LEFT | SWT.BORDER | SWT.PASSWORD + : SWT.LEFT | SWT.BORDER); + final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1); + gridData.heightHint = 15; + textInput.setLayoutData(gridData); + if (this.value != null) { + textInput.setText(this.value); + } + builder.form.putField(this.name, lab, textInput); + } + } +} \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormBuilder.java deleted file mode 100644 index d811f277..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/form/FormBuilder.java +++ /dev/null @@ -1,391 +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.service.form; - -import java.util.List; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.apache.commons.lang3.StringUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.TabItem; -import org.eclipse.swt.widgets.Text; -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.EntityKey; -import ch.ethz.seb.sebserver.gbl.util.Tuple; -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.remote.webservice.api.RestCall; -import ch.ethz.seb.sebserver.gui.service.widget.ImageUpload; -import ch.ethz.seb.sebserver.gui.service.widget.SingleSelection; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; - -public class FormBuilder { - - private static final Logger log = LoggerFactory.getLogger(FormBuilder.class); - - private final WidgetFactory widgetFactory; - private final PolyglotPageService polyglotPageService; - public final PageContext pageContext; - public final Composite formParent; - public final Form form; - - private boolean readonly = false; - private int defaultSpanLabel = 1; - private int defaultSpanInput = 2; - private int defaultSpanEmptyCell = 1; - private boolean emptyCellSeparation = true; - - FormBuilder( - final EntityKey entityKey, - final JSONMapper jsonMapper, - final WidgetFactory widgetFactory, - final PolyglotPageService polyglotPageService, - final PageContext pageContext, - final int rows) { - - this.widgetFactory = widgetFactory; - this.polyglotPageService = polyglotPageService; - this.pageContext = pageContext; - this.form = new Form(jsonMapper, entityKey); - - this.formParent = new Composite(pageContext.getParent(), SWT.NONE); - final GridLayout layout = new GridLayout(rows, true); - layout.horizontalSpacing = 10; - layout.verticalSpacing = 10; - layout.marginLeft = 10; - layout.marginTop = 10; - this.formParent.setLayout(layout); - this.formParent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - } - - public FormBuilder readonly(final boolean readonly) { - this.readonly = readonly; - return this; - } - - public FormBuilder setVisible(final boolean visible, final String group) { - this.form.setVisible(visible, group); - return this; - } - - public FormBuilder setControl(final TabItem instTab) { - instTab.setControl(this.formParent); - return this; - } - - public FormBuilder withDefaultSpanLabel(final int span) { - this.defaultSpanLabel = span; - return this; - } - - public FormBuilder withDefaultSpanInput(final int span) { - this.defaultSpanInput = span; - return this; - } - - public FormBuilder withDefaultSpanEmptyCell(final int span) { - this.defaultSpanEmptyCell = span; - return this; - } - - public FormBuilder withEmptyCellSeparation(final boolean separation) { - this.emptyCellSeparation = separation; - return this; - } - - public FormBuilder addEmptyCellIf(final BooleanSupplier condition) { - if (condition != null && condition.getAsBoolean()) { - return addEmptyCell(); - } - return this; - } - - public FormBuilder addEmptyCell() { - return addEmptyCell(1); - } - - public FormBuilder addEmptyCell(final int span) { - empty(this.formParent, span, 1); - return this; - } - - public FormBuilder putStaticValueIf(final BooleanSupplier condition, final String name, final String value) { - if (condition != null && condition.getAsBoolean()) { - return putStaticValue(name, value); - } - - return this; - } - - public FormBuilder putStaticValue(final String name, final String value) { - try { - this.form.putStatic(name, value); - } catch (final Exception e) { - log.error("Failed to put static field value to json object: ", e); - } - return this; - } - - public FormBuilder addField(final FieldTemplate template) { - if (template.condition == null || template.condition.getAsBoolean()) { - template.spanLabel = (template.spanLabel < 0) ? this.defaultSpanLabel : template.spanLabel; - template.spanInput = (template.spanInput < 0) ? this.defaultSpanInput : template.spanInput; - template.spanEmptyCell = (template.spanEmptyCell < 0) ? this.defaultSpanEmptyCell : template.spanEmptyCell; - template.autoEmptyCellSeparation = template.autoEmptyCellSeparation || this.emptyCellSeparation; - template.build(this); - } - return this; - } - - public FormHandle buildFor( - final RestCall post, - final Function postPostHandle) { - - return new FormHandle<>( - this.pageContext, - this.form, - post, - (postPostHandle == null) ? Function.identity() : postPostHandle, - this.polyglotPageService.getI18nSupport()); - } - - private void empty(final Composite parent, final int hspan, final int vspan) { - final Label empty = new Label(parent, SWT.LEFT); - empty.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, hspan, vspan)); - empty.setText(""); - } - - public static TextField text(final String name, final String label, final String value) { - return new TextField(name, label, value); - } - - public static SingleSelectionField singleSelection( - final String name, - final String label, - final String value, - final Supplier>> itemsSupplier) { - return new SingleSelectionField(name, label, value, itemsSupplier); - } - - public static ImageUploadField imageUpload(final String name, final String label, final String value) { - return new ImageUploadField(name, label, value); - } - - abstract static class FieldTemplate { - int spanLabel = -1; - int spanInput = -1; - int spanEmptyCell = -1; - boolean autoEmptyCellSeparation = false; - String group = null; - BooleanSupplier condition = null; - - final String name; - final String label; - final String value; - - protected FieldTemplate(final String name, final String label, final String value) { - this.name = name; - this.label = label; - this.value = value; - } - - public FieldTemplate withLabelSpan(final int span) { - this.spanLabel = span; - return this; - } - - public FieldTemplate withInputSpan(final int span) { - this.spanInput = span; - return this; - } - - public FieldTemplate withEmptyCellSpan(final int span) { - this.spanEmptyCell = span; - return this; - } - - public FieldTemplate withEmptyCellSeparation(final boolean separation) { - this.autoEmptyCellSeparation = separation; - return this; - } - - public FieldTemplate withGroup(final String group) { - this.group = group; - return this; - } - - public FieldTemplate withCondition(final BooleanSupplier condition) { - this.condition = condition; - return this; - } - - abstract void build(FormBuilder builder); - - } - - public static final class TextField extends FieldTemplate { - - boolean isPassword = false; - - TextField(final String name, final String label, final String value) { - super(name, label, value); - } - - public TextField asPasswordField() { - this.isPassword = true; - return this; - } - - @Override - void build(final FormBuilder builder) { - if (this.isPassword && builder.readonly) { - return; - } - - if (this.autoEmptyCellSeparation && builder.form.hasFields()) { - builder.addEmptyCell(this.spanEmptyCell); - } - - final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); - if (builder.readonly) { - builder.form.putField(this.name, lab, - builder.valueLabel(builder.formParent, this.value, this.spanInput)); - } else { - final Text textInput = new Text(builder.formParent, (this.isPassword) - ? SWT.LEFT | SWT.BORDER | SWT.PASSWORD - : SWT.LEFT | SWT.BORDER); - final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1); - gridData.heightHint = 15; - textInput.setLayoutData(gridData); - if (this.value != null) { - textInput.setText(this.value); - } - builder.form.putField(this.name, lab, textInput); - } - if (StringUtils.isNoneBlank(this.group)) { - builder.form.addToGroup(this.group, this.name); - } - } - } - - public static final class SingleSelectionField extends FieldTemplate { - - final Supplier>> itemsSupplier; - boolean isLocalizationSupplied = false; - Consumer selectionListener = null; - - SingleSelectionField( - final String name, - final String label, - final String value, - final Supplier>> itemsSupplier) { - - super(name, label, value); - this.itemsSupplier = itemsSupplier; - } - - public SingleSelectionField withLocalizationSupplied() { - this.isLocalizationSupplied = true; - return this; - } - - public SingleSelectionField withSelectionListener(final Consumer selectionListener) { - this.selectionListener = selectionListener; - return this; - } - - @Override - void build(final FormBuilder builder) { - - if (this.autoEmptyCellSeparation && builder.form.hasFields()) { - builder.addEmptyCell(this.spanEmptyCell); - } - - final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); - if (builder.readonly) { - builder.form.putField( - this.name, lab, - builder.valueLabel(builder.formParent, this.value, this.spanInput)); - } else { - final SingleSelection selection = (this.isLocalizationSupplied) - ? builder.widgetFactory.singleSelectionLocalizedSupplier( - builder.formParent, - this.itemsSupplier) - : builder.widgetFactory.singleSelectionLocalized( - builder.formParent, - this.itemsSupplier.get()); - final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1); - gridData.heightHint = 25; - selection.setLayoutData(gridData); - selection.select(this.value); - builder.form.putField(this.name, lab, selection); - if (this.selectionListener != null) { - selection.addListener(SWT.Selection, e -> { - this.selectionListener.accept(builder.form); - }); - } - } - if (StringUtils.isNoneBlank(this.group)) { - builder.form.addToGroup(this.group, this.name); - } - } - } - - public static final class ImageUploadField extends FieldTemplate { - - ImageUploadField(final String name, final String label, final String value) { - super(name, label, value); - } - - @Override - void build(final FormBuilder builder) { - - if (this.autoEmptyCellSeparation && builder.form.hasFields()) { - builder.addEmptyCell(this.spanEmptyCell); - } - - final Label lab = builder.labelLocalized(builder.formParent, this.label, this.spanLabel); - final ImageUpload imageUpload = builder.widgetFactory.formImageUpload( - builder.formParent, - this.value, - new LocTextKey("sebserver.overall.upload"), - this.spanInput, 1, builder.readonly); - builder.form.putField(this.name, lab, imageUpload); - } - - } - - private Label labelLocalized(final Composite parent, final String locTextKey, final int hspan) { - final Label label = this.widgetFactory.labelLocalized(parent, locTextKey); - final GridData gridData = new GridData(SWT.RIGHT, SWT.CENTER, true, false, hspan, 1); - label.setLayoutData(gridData); - return label; - } - - private Label valueLabel(final Composite parent, final String value, final int hspan) { - final Label label = new Label(parent, SWT.NONE); - label.setText((StringUtils.isNoneBlank(value)) ? value : Constants.EMPTY_NOTE); - final GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, true, false, hspan, 1); - label.setLayoutData(gridData); - return label; - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/I18nSupport.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/I18nSupport.java index b2e3023d..91cabd41 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/I18nSupport.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/I18nSupport.java @@ -8,15 +8,19 @@ package ch.ethz.seb.sebserver.gui.service.i18n; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.util.Tuple; public interface I18nSupport { @@ -78,14 +82,30 @@ public interface I18nSupport { * @return the text in current language parsed from localized text */ String getText(String key, Locale locale, String def, Object... args); - default List> getLanguageResources() { - return getLanguageResources(this); + default Supplier>> localizedResourceSupplier(final List> source) { + return () -> source.stream() + .map(tuple -> new Tuple<>(tuple._1, getText(tuple._2))) + .collect(Collectors.toList()); } - default List> getTimeZoneResources() { - return getTimeZoneResources(this); + default Supplier>> localizedLanguageResources() { + return () -> getLanguageResources(this); } + default Supplier>> localizedTimeZoneResources() { + return () -> getTimeZoneResources(this); + } + + default Supplier>> localizedUserRoleResources() { + return localizedResourceSupplier(USER_ROLE_RESOURCES); + } + + final List> USER_ROLE_RESOURCES = Collections.unmodifiableList( + Arrays.asList(UserRole.values()) + .stream() + .map(ur -> new Tuple<>(ur.name(), "sebserver.useraccount.role." + ur.name())) + .collect(Collectors.toList())); + /** Get a list of language key/name tuples for all supported languages in the * language of the current users locale. * 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 7f09b41f..cc00a230 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 @@ -12,9 +12,9 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; 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.action.Action; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/Action.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/Action.java index 63340c1e..fb21cb68 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/Action.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/action/Action.java @@ -17,6 +17,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.PageMessageException; @@ -29,16 +30,17 @@ public final class Action implements Runnable { private static final Logger log = LoggerFactory.getLogger(Action.class); + public final RestService restService; + public final PageContext pageContext; public final ActionDefinition definition; Supplier confirm; LocTextKey successMessage; boolean updateOnSelection; - final RestService restService; - final PageContext pageContext; - Function> exec; Supplier> selectionSupplier; + private Function> exec; + public Action( final ActionDefinition definition, final PageContext pageContext, @@ -90,6 +92,10 @@ public final class Action implements Runnable { } } + public Supplier> getSelectionSupplier() { + return this.selectionSupplier; + } + public Action withExec(final Function> exec) { this.exec = exec; return this; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivityActionHandler.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivityActionHandler.java index 8a125d5e..66eab226 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivityActionHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivityActionHandler.java @@ -10,8 +10,8 @@ package ch.ethz.seb.sebserver.gui.service.page.activity; import org.eclipse.swt.widgets.Tree; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.page.PageContext; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; public interface ActivityActionHandler { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitySelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitySelection.java index 9b15a06f..1c4c19f9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitySelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/activity/ActivitySelection.java @@ -16,15 +16,8 @@ import java.util.function.Consumer; import org.eclipse.swt.widgets.TreeItem; import ch.ethz.seb.sebserver.gbl.model.EntityKey; -import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; +import ch.ethz.seb.sebserver.gui.content.activity.Activity; import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys; -import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionPane; -import ch.ethz.seb.sebserver.gui.service.page.content.InstitutionForm; -import ch.ethz.seb.sebserver.gui.service.page.content.InstitutionList; -import ch.ethz.seb.sebserver.gui.service.page.content.UserAccountForm; -import ch.ethz.seb.sebserver.gui.service.page.content.UserAccountList; -import ch.ethz.seb.sebserver.gui.service.page.impl.TODOTemplate; public class ActivitySelection { @@ -35,73 +28,11 @@ public class ActivitySelection { ti.setItemCount(1); }; - public enum Activity { - NONE(TODOTemplate.class, TODOTemplate.class), - INSTITUTION_LIST( - InstitutionList.class, - ActionPane.class, - new LocTextKey("sebserver.activities.institution")), - INSTITUTION_FORM( - InstitutionForm.class, - ActionPane.class, - new LocTextKey("sebserver.activities.institution")), - - USER_ACCOUNT_LIST( - UserAccountList.class, - ActionPane.class, - new LocTextKey("sebserver.activities.useraccount")), - - USER_ACCOUNT_FORM( - UserAccountForm.class, - ActionPane.class, - new LocTextKey("sebserver.activities.useraccount")), - -// USERS(UserAccountsForm.class, ActionPane.class), -// -// EXAMS(ExamsListPage.class, ActionPane.class), -// SEB_CONFIGS(SEBConfigurationForm.class, ActionPane.class), -// SEB_CONFIG(SEBConfigurationPage.class, ActionPane.class), -// SEB_CONFIG_TEMPLATES(TODOTemplate.class, ActionPane.class), -// MONITORING(MonitoringForm.class, ActionPane.class), -// RUNNING_EXAMS(RunningExamForm.class, ActionPane.class), -// RUNNING_EXAM(RunningExamPage.class, ActionPane.class, AttributeKeys.EXAM_ID), -// LOGS(TODOTemplate.class, ActionPane.class), - ; - - public final LocTextKey title; - public final Class contentPaneComposer; - public final Class actionPaneComposer; - //public final String modelIdAttribute; - - private Activity( - final Class objectPaneComposer, - final Class selectionPaneComposer, - final LocTextKey title) { - - this.title = title; - this.contentPaneComposer = objectPaneComposer; - this.actionPaneComposer = selectionPaneComposer; - } - - private Activity( - final Class objectPaneComposer, - final Class selectionPaneComposer) { - - this.title = null; - this.contentPaneComposer = objectPaneComposer; - this.actionPaneComposer = selectionPaneComposer; - } - - public final ActivitySelection createSelection() { - return new ActivitySelection(this); - } - } - public final Activity activity; final Map attributes; Consumer expandFunction = EMPTY_FUNCTION; - ActivitySelection(final Activity activity) { + public ActivitySelection(final Activity activity) { this.activity = activity; this.attributes = new HashMap<>(); } 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 41347606..8000f156 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,7 +8,7 @@ package ch.ethz.seb.sebserver.gui.service.page.event; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; /** 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 */ diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java index b018c425..ac4844ad 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java @@ -13,7 +13,7 @@ import java.util.function.Predicate; import org.eclipse.swt.widgets.Widget; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; public interface ActionEventListener extends PageEventListener { 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 c3033bb8..32b71068 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 @@ -27,7 +27,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageDefinition; 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.auth.AuthorizationContextHolder; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @Service diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultLoginPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultLoginPage.java index d7e29da8..588759cc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultLoginPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultLoginPage.java @@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.page.impl; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import ch.ethz.seb.sebserver.gui.content.LoginPage; 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.PageDefinition; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultMainPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultMainPage.java index a7c92fd0..f34165f9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultMainPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/DefaultMainPage.java @@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.page.impl; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import ch.ethz.seb.sebserver.gui.content.MainPage; 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.PageDefinition; 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 d9ede401..25c128a6 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 @@ -36,9 +36,9 @@ 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.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder; -import ch.ethz.seb.sebserver.gui.service.widget.Message; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant; +import ch.ethz.seb.sebserver.gui.widget.Message; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @Lazy @Component 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 665a8f00..5bb33174 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 @@ -1,6 +1,6 @@ /* * 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/. @@ -11,12 +11,17 @@ 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.content.activity.Activity; import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; -import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection.Activity; public final class MainPageState { + private static final Logger log = LoggerFactory.getLogger(MainPageState.class); + public ActivitySelection activitySelection = Activity.NONE.createSelection(); private MainPageState() { @@ -36,7 +41,7 @@ public final class MainPageState { return mainPageState; } catch (final Exception e) { - MainPage.log.error("Unexpected error while trying to get MainPageState from user-session"); + log.error("Unexpected error while trying to get MainPageState from user-session"); } return null; 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 36ab1216..d191f9a8 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 @@ -28,6 +28,7 @@ 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.ComposerService; @@ -35,12 +36,11 @@ 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.action.Action; -import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection; 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.RestService; -import ch.ethz.seb.sebserver.gui.service.widget.Message; +import ch.ethz.seb.sebserver.gui.widget.Message; public class PageContextImpl implements PageContext { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/ColumnDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/ColumnDefinition.java similarity index 94% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/ColumnDefinition.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/ColumnDefinition.java index 72dbb973..3cb05099 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/ColumnDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/ColumnDefinition.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; import java.util.List; import java.util.function.Function; @@ -14,7 +14,7 @@ import java.util.function.Function; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; -import ch.ethz.seb.sebserver.gui.service.table.TableFilter.CriteriaType; +import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType; public final class ColumnDefinition { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/EntityTable.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/EntityTable.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java index 3d1536f7..fe305a10 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/EntityTable.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/EntityTable.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; import static ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService.POLYGLOT_WIDGET_FUNCTION_KEY; @@ -35,8 +35,8 @@ import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService.SortOrder; public class EntityTable extends Composite { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java similarity index 92% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableBuilder.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java index 002fbf21..fc33e526 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableBuilder.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; import java.util.ArrayList; import java.util.List; @@ -17,7 +17,7 @@ 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.remote.webservice.api.RestCall; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; /** * new TableBuilder(RestCall) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableFilter.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableFilter.java similarity index 91% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableFilter.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/TableFilter.java index 673d67eb..c1fa211f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableFilter.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableFilter.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; import java.util.Arrays; import java.util.List; @@ -25,9 +25,9 @@ import org.springframework.util.MultiValueMap; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; -import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition.TableFilterAttribute; -import ch.ethz.seb.sebserver.gui.service.widget.SingleSelection; -import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon; +import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute; +import ch.ethz.seb.sebserver.gui.widget.SingleSelection; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; public class TableFilter extends Composite { @@ -241,11 +241,11 @@ public class TableFilter extends Composite { @Override FilterComponent build(final Composite parent) { this.selector = TableFilter.this.entityTable.widgetFactory - .singleSelectionLocalizedSupplier( + .singleSelectionLocalized( parent, - () -> TableFilter.this.entityTable.widgetFactory + TableFilter.this.entityTable.widgetFactory .getI18nSupport() - .getLanguageResources()); + .localizedLanguageResources()); this.selector.setLayoutData(this.rowData); return this; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableNavigator.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java similarity index 94% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableNavigator.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java index 6ea0aff2..b8b1be58 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableNavigator.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; @@ -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.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; public class TableNavigator extends Composite { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableRowAction.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableRowAction.java similarity index 84% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableRowAction.java rename to src/main/java/ch/ethz/seb/sebserver/gui/table/TableRowAction.java index d1c669cc..af86b255 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/table/TableRowAction.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableRowAction.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.table; +package ch.ethz.seb.sebserver.gui.table; public class TableRowAction { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/widget/ImageUpload.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java similarity index 96% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/widget/ImageUpload.java rename to src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java index 8f6e3169..3682b802 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/widget/ImageUpload.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.widget; +package ch.ethz.seb.sebserver.gui.widget; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/widget/Message.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java similarity index 93% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/widget/Message.java rename to src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java index 2a2c4c3e..dc874982 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/widget/Message.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.widget; +package ch.ethz.seb.sebserver.gui.widget; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.graphics.Rectangle; 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 new file mode 100644 index 00000000..2335fbf3 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java @@ -0,0 +1,128 @@ +/* + * 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.widget; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.util.Tuple; + +public class MultiSelection extends Composite implements Selection { + + private static final long serialVersionUID = 2730206903047681378L; + private static final String OPTION_VALUE = "OPTION_VALUE"; + + private final List