SEBSERV-27 User Account multi selection
This commit is contained in:
parent
422d816093
commit
f760eba750
48 changed files with 1027 additions and 733 deletions
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.Logger;
|
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.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.content.action.InstitutionActions;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.PageFormService;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
|
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.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.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.Logger;
|
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.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.InstitutionActions;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
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.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
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.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
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.widget.Message;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
|
@ -21,15 +21,16 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
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.ActivitySelectionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionListener;
|
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.page.event.PageEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.MainPageState;
|
||||||
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;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,41 +6,44 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
import org.apache.tomcat.util.buf.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
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.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
|
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.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||||
import ch.ethz.seb.sebserver.gui.service.form.PageFormService;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
|
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.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.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
@ -120,9 +123,6 @@ public class UserAccountForm implements TemplateComposer {
|
||||||
.putStaticValueIf(isNotNew,
|
.putStaticValueIf(isNotNew,
|
||||||
Domain.USER.ATTR_UUID,
|
Domain.USER.ATTR_UUID,
|
||||||
userAccount.getModelId())
|
userAccount.getModelId())
|
||||||
.putStaticValueIf(isNew,
|
|
||||||
Domain.USER.ATTR_TIMEZONE,
|
|
||||||
userAccount.getTimeZone().getID())
|
|
||||||
.addField(FormBuilder.singleSelection(
|
.addField(FormBuilder.singleSelection(
|
||||||
Domain.USER.ATTR_INSTITUTION_ID,
|
Domain.USER.ATTR_INSTITUTION_ID,
|
||||||
"sebserver.useraccount.form.institution",
|
"sebserver.useraccount.form.institution",
|
||||||
|
@ -144,16 +144,18 @@ public class UserAccountForm implements TemplateComposer {
|
||||||
.addField(FormBuilder.singleSelection(
|
.addField(FormBuilder.singleSelection(
|
||||||
Domain.USER.ATTR_LOCALE,
|
Domain.USER.ATTR_LOCALE,
|
||||||
"sebserver.useraccount.form.language",
|
"sebserver.useraccount.form.language",
|
||||||
userAccount.getTimeZone().getID(),
|
userAccount.getLocale().getLanguage(),
|
||||||
() -> widgetFactory.getI18nSupport().getLanguageResources())
|
widgetFactory.getI18nSupport().localizedLanguageResources()))
|
||||||
.withLocalizationSupplied())
|
|
||||||
.addField(FormBuilder.singleSelection(
|
.addField(FormBuilder.singleSelection(
|
||||||
Domain.USER.ATTR_TIMEZONE,
|
Domain.USER.ATTR_TIMEZONE,
|
||||||
"sebserver.useraccount.form.timezone",
|
"sebserver.useraccount.form.timezone",
|
||||||
userAccount.getTimeZone().getID(),
|
userAccount.getTimeZone().getID(),
|
||||||
() -> widgetFactory.getI18nSupport().getTimeZoneResources())
|
widgetFactory.getI18nSupport().localizedTimeZoneResources()))
|
||||||
.withLocalizationSupplied())
|
.addField(FormBuilder.multiSelection(
|
||||||
// TODO add role selection (create multi selector)
|
USER_ROLE.REFERENCE_NAME,
|
||||||
|
"sebserver.useraccount.form.roles",
|
||||||
|
StringUtils.join(userAccount.getRoles(), Constants.LIST_SEPARATOR_CHAR),
|
||||||
|
widgetFactory.getI18nSupport().localizedUserRoleResources()))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
UserMod.ATTR_NAME_NEW_PASSWORD,
|
UserMod.ATTR_NAME_NEW_PASSWORD,
|
||||||
"sebserver.useraccount.form.password",
|
"sebserver.useraccount.form.password",
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.Logger;
|
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.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
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.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,9 +6,9 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.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 {
|
public enum ActionDefinition {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.rap.rwt.template.ImageCell;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
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.ActionPublishEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Function;
|
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.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
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;
|
||||||
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.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.ActivateInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
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) {
|
private static Result<?> fromSelection(final Action action, final boolean edit) {
|
||||||
final Collection<String> selection = action.selectionSupplier.get();
|
return Result.tryCatch(() -> {
|
||||||
if (selection.isEmpty()) {
|
final Collection<String> selection = action.getSelectionSupplier().get();
|
||||||
return Result.ofError(new PageMessageException("sebserver.institution.info.pleaseSelect"));
|
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(
|
private static ActivitySelection goToInstitution(
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Function;
|
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.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
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;
|
||||||
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.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.ActivateUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
|
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) {
|
private static Result<?> fromSelection(final Action action, final boolean edit) {
|
||||||
final Collection<String> selection = action.selectionSupplier.get();
|
return Result.tryCatch(() -> {
|
||||||
if (selection.isEmpty()) {
|
final Collection<String> selection = action.getSelectionSupplier().get();
|
||||||
return Result.ofError(new PageMessageException("sebserver.useraccount.info.pleaseSelect"));
|
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(
|
private static ActivitySelection goToUserAccount(
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.activity;
|
package ch.ethz.seb.sebserver.gui.content.activity;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EnumMap;
|
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.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
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.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.ActionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActivitySelectionEvent;
|
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.page.impl.MainPageState;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
@ -192,7 +193,7 @@ public class ActivitiesPane implements TemplateComposer {
|
||||||
final MainPageState mainPageState = MainPageState.get();
|
final MainPageState mainPageState = MainPageState.get();
|
||||||
|
|
||||||
if (mainPageState.activitySelection == null ||
|
if (mainPageState.activitySelection == null ||
|
||||||
mainPageState.activitySelection.activity == ActivitySelection.Activity.NONE) {
|
mainPageState.activitySelection.activity == Activity.NONE) {
|
||||||
mainPageState.activitySelection = getActivitySelection(navigation.getItem(0));
|
mainPageState.activitySelection = getActivitySelection(navigation.getItem(0));
|
||||||
}
|
}
|
||||||
pageContext.publishPageEvent(
|
pageContext.publishPageEvent(
|
|
@ -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<? extends TemplateComposer> contentPaneComposer;
|
||||||
|
public final Class<? extends TemplateComposer> actionPaneComposer;
|
||||||
|
//public final String modelIdAttribute;
|
||||||
|
|
||||||
|
private Activity(
|
||||||
|
final Class<? extends TemplateComposer> objectPaneComposer,
|
||||||
|
final Class<? extends TemplateComposer> selectionPaneComposer,
|
||||||
|
final LocTextKey title) {
|
||||||
|
|
||||||
|
this.title = title;
|
||||||
|
this.contentPaneComposer = objectPaneComposer;
|
||||||
|
this.actionPaneComposer = selectionPaneComposer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Activity(
|
||||||
|
final Class<? extends TemplateComposer> objectPaneComposer,
|
||||||
|
final Class<? extends TemplateComposer> selectionPaneComposer) {
|
||||||
|
|
||||||
|
this.title = null;
|
||||||
|
this.contentPaneComposer = objectPaneComposer;
|
||||||
|
this.actionPaneComposer = selectionPaneComposer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ActivitySelection createSelection() {
|
||||||
|
return new ActivitySelection(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.form;
|
package ch.ethz.seb.sebserver.gui.form;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -16,13 +16,15 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.widgets.Combo;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.Text;
|
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.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
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.api.JSONMapper;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
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.remote.webservice.api.FormBinding;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.ImageUpload;
|
import ch.ethz.seb.sebserver.gui.widget.ImageUpload;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.SingleSelection;
|
import ch.ethz.seb.sebserver.gui.widget.MultiSelection;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.SingleSelection;
|
||||||
|
|
||||||
public final class Form implements FormBinding {
|
public final class Form implements FormBinding {
|
||||||
|
|
||||||
|
@ -40,7 +43,8 @@ public final class Form implements FormBinding {
|
||||||
private final ObjectNode objectRoot;
|
private final ObjectNode objectRoot;
|
||||||
|
|
||||||
private final Map<String, String> staticValues = new LinkedHashMap<>();
|
private final Map<String, String> staticValues = new LinkedHashMap<>();
|
||||||
private final Map<String, FormFieldAccessor> formFields = new LinkedHashMap<>();
|
private final MultiValueMap<String, FormFieldAccessor> formFields = new LinkedMultiValueMap<>();
|
||||||
|
//private final Map<String, List<FormFieldAccessor>> formFields = new LinkedHashMap<>();
|
||||||
private final Map<String, Form> subForms = new LinkedHashMap<>();
|
private final Map<String, Form> subForms = new LinkedHashMap<>();
|
||||||
private final Map<String, List<Form>> subLists = new LinkedHashMap<>();
|
private final Map<String, List<Form>> subLists = new LinkedHashMap<>();
|
||||||
private final Map<String, Set<String>> groups = new LinkedHashMap<>();
|
private final Map<String, Set<String>> groups = new LinkedHashMap<>();
|
||||||
|
@ -72,22 +76,26 @@ public final class Form implements FormBinding {
|
||||||
public String getFormUrlEncoded() {
|
public String getFormUrlEncoded() {
|
||||||
final StringBuffer buffer = new StringBuffer();
|
final StringBuffer buffer = new StringBuffer();
|
||||||
for (final Map.Entry<String, String> entry : this.staticValues.entrySet()) {
|
for (final Map.Entry<String, String> entry : this.staticValues.entrySet()) {
|
||||||
appendFormUrlEncoded(buffer, entry.getKey(), entry.getValue());
|
appendFormUrlEncodedValue(buffer, entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Map.Entry<String, FormFieldAccessor> entry : this.formFields.entrySet()) {
|
for (final Map.Entry<String, List<FormFieldAccessor>> entry : this.formFields.entrySet()) {
|
||||||
appendFormUrlEncoded(buffer, entry.getKey(), entry.getValue().getValue());
|
entry.getValue()
|
||||||
|
.stream()
|
||||||
|
.forEach(ffa -> appendFormUrlEncodedValue(buffer, entry.getKey(), ffa.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue(final String name) {
|
public List<String> getValue(final String name) {
|
||||||
final FormFieldAccessor formFieldAccessor = this.formFields.get(name);
|
if (this.formFields.containsKey(name)) {
|
||||||
if (formFieldAccessor != null) {
|
return this.formFields
|
||||||
return formFieldAccessor.getValue();
|
.get(name)
|
||||||
|
.stream()
|
||||||
|
.map(ffa -> ffa.getValue())
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,23 +117,25 @@ public final class Form implements FormBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Form putField(final String name, final Label label, final Label field) {
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Form putField(final String name, final Label label, final Text field) {
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putField(final String name, final Label label, final Combo field) {
|
public void putField(final String name, final Label label, final SingleSelection field) {
|
||||||
if (field instanceof SingleSelection) {
|
this.formFields.add(name, createAccessor(label, field));
|
||||||
this.formFields.put(name, createAccessor(label, (SingleSelection) 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) {
|
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) {
|
public void putSubForm(final String name, final Form form) {
|
||||||
|
@ -174,7 +184,7 @@ public final class Form implements FormBinding {
|
||||||
this.formFields.entrySet()
|
this.formFields.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(entity -> nameFilter.test(entity.getKey()))
|
.filter(entity -> nameFilter.test(entity.getKey()))
|
||||||
.map(entity -> entity.getValue())
|
.flatMap(entity -> entity.getValue().stream())
|
||||||
.forEach(processor);
|
.forEach(processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,11 +193,10 @@ public final class Form implements FormBinding {
|
||||||
this.objectRoot.put(entry.getKey(), entry.getValue());
|
this.objectRoot.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Map.Entry<String, FormFieldAccessor> entry : this.formFields.entrySet()) {
|
for (final Map.Entry<String, List<FormFieldAccessor>> entry : this.formFields.entrySet()) {
|
||||||
final FormFieldAccessor accessor = entry.getValue();
|
entry.getValue()
|
||||||
if (accessor.control.isVisible()) {
|
.stream()
|
||||||
this.objectRoot.put(entry.getKey(), accessor.getValue());
|
.forEach(ffa -> this.objectRoot.put(entry.getKey(), ffa.getValue()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Map.Entry<String, Form> entry : this.subForms.entrySet()) {
|
for (final Map.Entry<String, Form> entry : this.subForms.entrySet()) {
|
||||||
|
@ -231,7 +240,15 @@ public final class Form implements FormBinding {
|
||||||
@Override public void setValue(final String value) { singleSelection.select(value); }
|
@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) {
|
private FormFieldAccessor createAccessor(final Label label, final ImageUpload imageUpload) {
|
||||||
return new FormFieldAccessor(label, imageUpload) {
|
return new FormFieldAccessor(label, imageUpload) {
|
||||||
@Override public String getValue() { return imageUpload.getImageBase64(); }
|
@Override public String getValue() { return imageUpload.getImageBase64(); }
|
||||||
|
@ -240,14 +257,24 @@ public final class Form implements FormBinding {
|
||||||
}
|
}
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
private void appendFormUrlEncoded(final StringBuffer buffer, final String name, final String value) {
|
/*
|
||||||
if (StringUtils.isNoneBlank(value)) {
|
* Adds the given name and value in from URL encoded format to the given StringBuffer.
|
||||||
if (buffer.length() > 0) {
|
* Checks first if the value String is a comma separated list. If true, splits values
|
||||||
buffer.append(Constants.FORM_URL_ENCODED_SEPARATOR);
|
* 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
223
src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java
Normal file
223
src/main/java/ch/ethz/seb/sebserver/gui/form/FormBuilder.java
Normal file
|
@ -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 <T> FormHandle<T> buildFor(
|
||||||
|
final RestCall<T> post,
|
||||||
|
final Function<T, T> 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<List<Tuple<String>>> itemsSupplier) {
|
||||||
|
|
||||||
|
return new SelectionFieldBuilder(name, label, value, itemsSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SelectionFieldBuilder multiSelection(
|
||||||
|
final String name,
|
||||||
|
final String label,
|
||||||
|
final String value,
|
||||||
|
final Supplier<List<Tuple<String>>> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.form;
|
package ch.ethz.seb.sebserver.gui.form;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -15,13 +15,13 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
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.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError;
|
import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
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.page.event.ActionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.form;
|
package ch.ethz.seb.sebserver.gui.form;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
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.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
|
@ -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<List<Tuple<String>>> itemsSupplier;
|
||||||
|
Consumer<Form> selectionListener = null;
|
||||||
|
boolean multi = false;
|
||||||
|
|
||||||
|
SelectionFieldBuilder(
|
||||||
|
final String name,
|
||||||
|
final String label,
|
||||||
|
final String value,
|
||||||
|
final Supplier<List<Tuple<String>>> itemsSupplier) {
|
||||||
|
|
||||||
|
super(name, label, value);
|
||||||
|
this.itemsSupplier = itemsSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectionFieldBuilder withSelectionListener(final Consumer<Form> 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<String> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <T> FormHandle<T> buildFor(
|
|
||||||
final RestCall<T> post,
|
|
||||||
final Function<T, T> 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<List<Tuple<String>>> 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<List<Tuple<String>>> itemsSupplier;
|
|
||||||
boolean isLocalizationSupplied = false;
|
|
||||||
Consumer<Form> selectionListener = null;
|
|
||||||
|
|
||||||
SingleSelectionField(
|
|
||||||
final String name,
|
|
||||||
final String label,
|
|
||||||
final String value,
|
|
||||||
final Supplier<List<Tuple<String>>> itemsSupplier) {
|
|
||||||
|
|
||||||
super(name, label, value);
|
|
||||||
this.itemsSupplier = itemsSupplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SingleSelectionField withLocalizationSupplied() {
|
|
||||||
this.isLocalizationSupplied = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SingleSelectionField withSelectionListener(final Consumer<Form> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -8,15 +8,19 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.i18n;
|
package ch.ethz.seb.sebserver.gui.service.i18n;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
|
||||||
public interface I18nSupport {
|
public interface I18nSupport {
|
||||||
|
@ -78,14 +82,30 @@ public interface I18nSupport {
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
String getText(String key, Locale locale, String def, Object... args);
|
String getText(String key, Locale locale, String def, Object... args);
|
||||||
|
|
||||||
default List<Tuple<String>> getLanguageResources() {
|
default Supplier<List<Tuple<String>>> localizedResourceSupplier(final List<Tuple<String>> source) {
|
||||||
return getLanguageResources(this);
|
return () -> source.stream()
|
||||||
|
.map(tuple -> new Tuple<>(tuple._1, getText(tuple._2)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<Tuple<String>> getTimeZoneResources() {
|
default Supplier<List<Tuple<String>>> localizedLanguageResources() {
|
||||||
return getTimeZoneResources(this);
|
return () -> getLanguageResources(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Supplier<List<Tuple<String>>> localizedTimeZoneResources() {
|
||||||
|
return () -> getTimeZoneResources(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Supplier<List<Tuple<String>>> localizedUserRoleResources() {
|
||||||
|
return localizedResourceSupplier(USER_ROLE_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Tuple<String>> 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
|
/** Get a list of language key/name tuples for all supported languages in the
|
||||||
* language of the current users locale.
|
* language of the current users locale.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,9 +12,9 @@ import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
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.activity.ActivitySelection;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
|
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
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);
|
private static final Logger log = LoggerFactory.getLogger(Action.class);
|
||||||
|
|
||||||
|
public final RestService restService;
|
||||||
|
public final PageContext pageContext;
|
||||||
public final ActionDefinition definition;
|
public final ActionDefinition definition;
|
||||||
Supplier<LocTextKey> confirm;
|
Supplier<LocTextKey> confirm;
|
||||||
LocTextKey successMessage;
|
LocTextKey successMessage;
|
||||||
boolean updateOnSelection;
|
boolean updateOnSelection;
|
||||||
|
|
||||||
final RestService restService;
|
|
||||||
final PageContext pageContext;
|
|
||||||
Function<Action, Result<?>> exec;
|
|
||||||
Supplier<Set<String>> selectionSupplier;
|
Supplier<Set<String>> selectionSupplier;
|
||||||
|
|
||||||
|
private Function<Action, Result<?>> exec;
|
||||||
|
|
||||||
public Action(
|
public Action(
|
||||||
final ActionDefinition definition,
|
final ActionDefinition definition,
|
||||||
final PageContext pageContext,
|
final PageContext pageContext,
|
||||||
|
@ -90,6 +92,10 @@ public final class Action implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Supplier<Set<String>> getSelectionSupplier() {
|
||||||
|
return this.selectionSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
public Action withExec(final Function<Action, Result<?>> exec) {
|
public Action withExec(final Function<Action, Result<?>> exec) {
|
||||||
this.exec = exec;
|
this.exec = exec;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -10,8 +10,8 @@ package ch.ethz.seb.sebserver.gui.service.page.activity;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Tree;
|
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.PageContext;
|
||||||
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.page.event.ActionEvent;
|
||||||
|
|
||||||
public interface ActivityActionHandler {
|
public interface ActivityActionHandler {
|
||||||
|
|
|
@ -16,15 +16,8 @@ import java.util.function.Consumer;
|
||||||
import org.eclipse.swt.widgets.TreeItem;
|
import org.eclipse.swt.widgets.TreeItem;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
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.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 {
|
public class ActivitySelection {
|
||||||
|
|
||||||
|
@ -35,73 +28,11 @@ public class ActivitySelection {
|
||||||
ti.setItemCount(1);
|
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<? extends TemplateComposer> contentPaneComposer;
|
|
||||||
public final Class<? extends TemplateComposer> actionPaneComposer;
|
|
||||||
//public final String modelIdAttribute;
|
|
||||||
|
|
||||||
private Activity(
|
|
||||||
final Class<? extends TemplateComposer> objectPaneComposer,
|
|
||||||
final Class<? extends TemplateComposer> selectionPaneComposer,
|
|
||||||
final LocTextKey title) {
|
|
||||||
|
|
||||||
this.title = title;
|
|
||||||
this.contentPaneComposer = objectPaneComposer;
|
|
||||||
this.actionPaneComposer = selectionPaneComposer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Activity(
|
|
||||||
final Class<? extends TemplateComposer> objectPaneComposer,
|
|
||||||
final Class<? extends TemplateComposer> selectionPaneComposer) {
|
|
||||||
|
|
||||||
this.title = null;
|
|
||||||
this.contentPaneComposer = objectPaneComposer;
|
|
||||||
this.actionPaneComposer = selectionPaneComposer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final ActivitySelection createSelection() {
|
|
||||||
return new ActivitySelection(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Activity activity;
|
public final Activity activity;
|
||||||
final Map<String, String> attributes;
|
final Map<String, String> attributes;
|
||||||
Consumer<TreeItem> expandFunction = EMPTY_FUNCTION;
|
Consumer<TreeItem> expandFunction = EMPTY_FUNCTION;
|
||||||
|
|
||||||
ActivitySelection(final Activity activity) {
|
public ActivitySelection(final Activity activity) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
this.attributes = new HashMap<>();
|
this.attributes = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.event;
|
package ch.ethz.seb.sebserver.gui.service.page.event;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
|
|
||||||
/** This Event is used to propagate a user-action to the GUI system.
|
/** This Event is used to propagate a user-action to the GUI system.
|
||||||
* Potentially every component can listen to an Event and react on the user-action */
|
* Potentially every component can listen to an Event and react on the user-action */
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Widget;
|
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<ActionEvent> {
|
public interface ActionEventListener extends PageEventListener<ActionEvent> {
|
||||||
|
|
||||||
|
|
|
@ -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.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
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
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
||||||
|
|
|
@ -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.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.Message;
|
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
|
|
@ -11,12 +11,17 @@ package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.activity.ActivitySelection.Activity;
|
|
||||||
|
|
||||||
public final class MainPageState {
|
public final class MainPageState {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MainPageState.class);
|
||||||
|
|
||||||
public ActivitySelection activitySelection = Activity.NONE.createSelection();
|
public ActivitySelection activitySelection = Activity.NONE.createSelection();
|
||||||
|
|
||||||
private MainPageState() {
|
private MainPageState() {
|
||||||
|
@ -36,7 +41,7 @@ public final class MainPageState {
|
||||||
|
|
||||||
return mainPageState;
|
return mainPageState;
|
||||||
} catch (final Exception e) {
|
} 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;
|
return null;
|
||||||
|
|
|
@ -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.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
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.PageDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
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.activity.ActivitySelection;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
|
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.page.event.PageEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.Message;
|
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||||
|
|
||||||
public class PageContextImpl implements PageContext {
|
public class PageContextImpl implements PageContext {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
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.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
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.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
|
|
||||||
public final class ColumnDefinition<ROW extends Entity> {
|
public final class ColumnDefinition<ROW extends Entity> {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
import static ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService.POLYGLOT_WIDGET_FUNCTION_KEY;
|
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.model.Page;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
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;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService.SortOrder;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService.SortOrder;
|
||||||
|
|
||||||
public class EntityTable<ROW extends Entity> extends Composite {
|
public class EntityTable<ROW extends Entity> extends Composite {
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
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.remote.webservice.api.RestCall;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
/** <code>
|
/** <code>
|
||||||
* new TableBuilder<T>(RestCall)
|
* new TableBuilder<T>(RestCall)
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
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.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.SingleSelection;
|
import ch.ethz.seb.sebserver.gui.widget.SingleSelection;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.ImageIcon;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
|
|
||||||
public class TableFilter<ROW extends Entity> extends Composite {
|
public class TableFilter<ROW extends Entity> extends Composite {
|
||||||
|
|
||||||
|
@ -241,11 +241,11 @@ public class TableFilter<ROW extends Entity> extends Composite {
|
||||||
@Override
|
@Override
|
||||||
FilterComponent build(final Composite parent) {
|
FilterComponent build(final Composite parent) {
|
||||||
this.selector = TableFilter.this.entityTable.widgetFactory
|
this.selector = TableFilter.this.entityTable.widgetFactory
|
||||||
.singleSelectionLocalizedSupplier(
|
.singleSelectionLocalized(
|
||||||
parent,
|
parent,
|
||||||
() -> TableFilter.this.entityTable.widgetFactory
|
TableFilter.this.entityTable.widgetFactory
|
||||||
.getI18nSupport()
|
.getI18nSupport()
|
||||||
.getLanguageResources());
|
.localizedLanguageResources());
|
||||||
this.selector.setLayoutData(this.rowData);
|
this.selector.setLayoutData(this.rowData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
|
@ -17,7 +17,7 @@ import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
public class TableNavigator extends Composite {
|
public class TableNavigator extends Composite {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.table;
|
package ch.ethz.seb.sebserver.gui.table;
|
||||||
|
|
||||||
public class TableRowAction {
|
public class TableRowAction {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.widget;
|
package ch.ethz.seb.sebserver.gui.widget;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.widget;
|
package ch.ethz.seb.sebserver.gui.widget;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
import org.eclipse.swt.graphics.Rectangle;
|
|
@ -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<Label> labels = new ArrayList<>();
|
||||||
|
private final List<Label> selected = new ArrayList<>();
|
||||||
|
|
||||||
|
public MultiSelection(final Composite parent) {
|
||||||
|
super(parent, SWT.NONE);
|
||||||
|
final GridLayout gridLayout = new GridLayout(1, true);
|
||||||
|
gridLayout.verticalSpacing = 1;
|
||||||
|
gridLayout.marginLeft = 0;
|
||||||
|
setLayout(gridLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
||||||
|
final String selectionValue = getSelectionValue();
|
||||||
|
this.selected.clear();
|
||||||
|
for (final Tuple<String> tuple : mapping) {
|
||||||
|
final Label label = new Label(this, SWT.NONE);
|
||||||
|
final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
||||||
|
label.setLayoutData(gridData);
|
||||||
|
label.setData(OPTION_VALUE, tuple._1);
|
||||||
|
label.setData(RWT.CUSTOM_VARIANT, "selection");
|
||||||
|
label.setText(" " + tuple._2);
|
||||||
|
label.addListener(SWT.MouseDown, event -> {
|
||||||
|
final Label l = (Label) event.widget;
|
||||||
|
if (this.selected.contains(l)) {
|
||||||
|
l.setData(RWT.CUSTOM_VARIANT, "selection");
|
||||||
|
this.selected.remove(l);
|
||||||
|
} else {
|
||||||
|
l.setData(RWT.CUSTOM_VARIANT, "selected");
|
||||||
|
this.selected.add(l);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
select(selectionValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectOne(final String key) {
|
||||||
|
this.labels.stream()
|
||||||
|
.filter(label -> key.equals(label.getData(OPTION_VALUE)))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(label -> {
|
||||||
|
label.setData(RWT.CUSTOM_VARIANT, "selected");
|
||||||
|
this.selected.add(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselect(final String key) {
|
||||||
|
this.selected.stream()
|
||||||
|
.filter(label -> key.equals(label.getData(OPTION_VALUE)))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(label -> {
|
||||||
|
label.setData(RWT.CUSTOM_VARIANT, "selection");
|
||||||
|
this.selected.remove(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselectAll() {
|
||||||
|
for (final Label label : this.selected) {
|
||||||
|
label.setData(RWT.CUSTOM_VARIANT, "selection");
|
||||||
|
}
|
||||||
|
this.selected.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void select(final String keys) {
|
||||||
|
this.selected.clear();
|
||||||
|
if (StringUtils.isNotBlank(keys)) {
|
||||||
|
final List<String> split = Arrays.asList(keys.split(keys, Constants.LIST_SEPARATOR_CHAR));
|
||||||
|
for (final Label label : this.labels) {
|
||||||
|
if (split.contains(label.getData(OPTION_VALUE))) {
|
||||||
|
label.setData(RWT.CUSTOM_VARIANT, "selected");
|
||||||
|
this.selected.add(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSelectionValue() {
|
||||||
|
if (this.selected.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.join(
|
||||||
|
this.selected
|
||||||
|
.stream()
|
||||||
|
.map(label -> (String) label.getData(OPTION_VALUE))
|
||||||
|
.collect(Collectors.toList()),
|
||||||
|
Constants.LIST_SEPARATOR_CHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
deselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.List;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
|
||||||
|
public interface Selection {
|
||||||
|
|
||||||
|
void applyNewMapping(final List<Tuple<String>> mapping);
|
||||||
|
|
||||||
|
void select(final String keys);
|
||||||
|
|
||||||
|
String getSelectionValue();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.widget;
|
package ch.ethz.seb.sebserver.gui.widget;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -18,21 +18,21 @@ import org.eclipse.swt.widgets.Composite;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
|
||||||
public class SingleSelection extends Combo {
|
public class SingleSelection extends Combo implements Selection {
|
||||||
|
|
||||||
private static final long serialVersionUID = 6522063655406404279L;
|
private static final long serialVersionUID = 6522063655406404279L;
|
||||||
|
|
||||||
final List<String> valueMapping;
|
final List<String> valueMapping;
|
||||||
final List<String> keyMapping;
|
final List<String> keyMapping;
|
||||||
|
|
||||||
public SingleSelection(final Composite parent, final List<Tuple<String>> mapping) {
|
public SingleSelection(final Composite parent) {
|
||||||
super(parent, SWT.READ_ONLY);
|
super(parent, SWT.READ_ONLY);
|
||||||
this.valueMapping = new ArrayList<>();
|
this.valueMapping = new ArrayList<>();
|
||||||
this.keyMapping = new ArrayList<>();
|
this.keyMapping = new ArrayList<>();
|
||||||
applyNewMapping(mapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyNewMapping(final List<Tuple<String>> mapping) {
|
@Override
|
||||||
|
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
||||||
final String selectionValue = getSelectionValue();
|
final String selectionValue = getSelectionValue();
|
||||||
this.valueMapping.clear();
|
this.valueMapping.clear();
|
||||||
this.keyMapping.clear();
|
this.keyMapping.clear();
|
||||||
|
@ -46,6 +46,7 @@ public class SingleSelection extends Combo {
|
||||||
select(selectionValue);
|
select(selectionValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void select(final String key) {
|
public void select(final String key) {
|
||||||
final int selectionindex = this.keyMapping.indexOf(key);
|
final int selectionindex = this.keyMapping.indexOf(key);
|
||||||
if (selectionindex < 0) {
|
if (selectionindex < 0) {
|
||||||
|
@ -55,6 +56,7 @@ public class SingleSelection extends Combo {
|
||||||
super.select(selectionindex);
|
super.select(selectionindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getSelectionValue() {
|
public String getSelectionValue() {
|
||||||
final int selectionindex = super.getSelectionIndex();
|
final int selectionindex = super.getSelectionIndex();
|
||||||
if (selectionindex < 0) {
|
if (selectionindex < 0) {
|
||||||
|
@ -64,6 +66,7 @@ public class SingleSelection extends Combo {
|
||||||
return this.keyMapping.get(selectionindex);
|
return this.keyMapping.get(selectionindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
super.clearSelection();
|
super.clearSelection();
|
||||||
super.setItems(this.valueMapping.toArray(new String[this.valueMapping.size()]));
|
super.setItems(this.valueMapping.toArray(new String[this.valueMapping.size()]));
|
|
@ -6,12 +6,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.widget;
|
package ch.ethz.seb.sebserver.gui.widget;
|
||||||
|
|
||||||
import static ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService.*;
|
import static ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService.*;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -26,7 +25,6 @@ import org.eclipse.swt.graphics.ImageData;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Combo;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
@ -45,16 +43,16 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.action.ActionDefinition;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.push.ServerPushService;
|
import ch.ethz.seb.sebserver.gui.service.push.ServerPushService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
import ch.ethz.seb.sebserver.gui.service.table.TableBuilder;
|
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
|
@ -311,45 +309,24 @@ public class WidgetFactory {
|
||||||
|
|
||||||
public SingleSelection singleSelectionLocalized(
|
public SingleSelection singleSelectionLocalized(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final List<Tuple<String>> items) {
|
final Supplier<List<Tuple<String>>> itemsSupplier) {
|
||||||
|
|
||||||
final SingleSelection combo = new SingleSelection(parent, items);
|
final SingleSelection singleSelection = new SingleSelection(parent);
|
||||||
this.injectI18n(combo, combo.valueMapping);
|
final Consumer<SingleSelection> updateFunction = ss -> ss.applyNewMapping(itemsSupplier.get());
|
||||||
return combo;
|
singleSelection.setData(POLYGLOT_WIDGET_FUNCTION_KEY, updateFunction);
|
||||||
|
updateFunction.accept(singleSelection);
|
||||||
|
return singleSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingleSelection singleSelectionLocalizedSupplier(
|
public MultiSelection multiSelectionLocalized(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final Supplier<List<Tuple<String>>> itemsSupplier) {
|
final Supplier<List<Tuple<String>>> itemsSupplier) {
|
||||||
|
|
||||||
final Consumer<SingleSelection> updateFunction =
|
final MultiSelection multiSelection = new MultiSelection(parent);
|
||||||
selection -> selection.applyNewMapping(itemsSupplier.get());
|
final Consumer<MultiSelection> updateFunction = ss -> ss.applyNewMapping(itemsSupplier.get());
|
||||||
final SingleSelection selection = new SingleSelection(parent, itemsSupplier.get());
|
multiSelection.setData(POLYGLOT_WIDGET_FUNCTION_KEY, updateFunction);
|
||||||
selection.setData(POLYGLOT_WIDGET_FUNCTION_KEY, updateFunction);
|
updateFunction.accept(multiSelection);
|
||||||
return selection;
|
return multiSelection;
|
||||||
}
|
|
||||||
|
|
||||||
// public SingleSelection languageSelector(final Composite parent) {
|
|
||||||
// final Consumer<SingleSelection> updateFunction =
|
|
||||||
// selection -> selection.applyNewMapping(this.i18nSupport.getLanguageResources());
|
|
||||||
// final SingleSelection selection = new SingleSelection(parent, this.i18nSupport.getLanguageResources());
|
|
||||||
// selection.setData(POLYGLOT_WIDGET_FUNCTION_KEY, updateFunction);
|
|
||||||
// return selection;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public ImageUpload formImageUpload(
|
|
||||||
final Composite parent,
|
|
||||||
final String value,
|
|
||||||
final LocTextKey locTextKey,
|
|
||||||
final int hspan,
|
|
||||||
final int vspan,
|
|
||||||
final boolean readonly) {
|
|
||||||
|
|
||||||
final ImageUpload imageUpload = imageUploadLocalized(parent, locTextKey, readonly);
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, hspan, vspan);
|
|
||||||
imageUpload.setLayoutData(gridData);
|
|
||||||
imageUpload.setImageBase64(value);
|
|
||||||
return imageUpload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageUpload imageUploadLocalized(
|
public ImageUpload imageUploadLocalized(
|
||||||
|
@ -363,7 +340,11 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final ImageUpload imageUpload, final LocTextKey locTextKey) {
|
public void injectI18n(final ImageUpload imageUpload, final LocTextKey locTextKey) {
|
||||||
final Consumer<ImageUpload> imageUploadFunction = imageUploadFunction(locTextKey, this.i18nSupport);
|
final Consumer<ImageUpload> imageUploadFunction = iu -> {
|
||||||
|
if (locTextKey != null) {
|
||||||
|
iu.setSelectionText(this.i18nSupport.getText(locTextKey));
|
||||||
|
}
|
||||||
|
};
|
||||||
imageUpload.setData(POLYGLOT_WIDGET_FUNCTION_KEY, imageUploadFunction);
|
imageUpload.setData(POLYGLOT_WIDGET_FUNCTION_KEY, imageUploadFunction);
|
||||||
imageUploadFunction.accept(imageUpload);
|
imageUploadFunction.accept(imageUpload);
|
||||||
}
|
}
|
||||||
|
@ -383,13 +364,22 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final Button button, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
public void injectI18n(final Button button, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
||||||
final Consumer<Button> buttonFunction = buttonFunction(locTextKey, locToolTipKey, this.i18nSupport);
|
final Consumer<Button> buttonFunction = b -> {
|
||||||
|
if (locTextKey != null) {
|
||||||
|
b.setText(this.i18nSupport.getText(locTextKey));
|
||||||
|
}
|
||||||
|
if (locToolTipKey != null) {
|
||||||
|
b.setToolTipText(this.i18nSupport.getText(locToolTipKey));
|
||||||
|
}
|
||||||
|
};
|
||||||
button.setData(POLYGLOT_WIDGET_FUNCTION_KEY, buttonFunction);
|
button.setData(POLYGLOT_WIDGET_FUNCTION_KEY, buttonFunction);
|
||||||
buttonFunction.accept(button);
|
buttonFunction.accept(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final Tree tree) {
|
public void injectI18n(final Tree tree) {
|
||||||
tree.setData(POLYGLOT_WIDGET_FUNCTION_KEY, treeFunction(this.i18nSupport));
|
tree.setData(
|
||||||
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
|
(Consumer<Tree>) t -> updateLocale(t.getItems(), this.i18nSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final TreeItem treeItem, final LocTextKey locTextKey) {
|
public void injectI18n(final TreeItem treeItem, final LocTextKey locTextKey) {
|
||||||
|
@ -398,7 +388,12 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final Table table) {
|
public void injectI18n(final Table table) {
|
||||||
table.setData(POLYGLOT_WIDGET_FUNCTION_KEY, tableFunction(this.i18nSupport));
|
table.setData(
|
||||||
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
|
(Consumer<Table>) t -> {
|
||||||
|
updateLocale(t.getColumns(), this.i18nSupport);
|
||||||
|
updateLocale(t.getItems(), this.i18nSupport);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final TableColumn tableColumn, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
public void injectI18n(final TableColumn tableColumn, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||||
|
@ -422,17 +417,15 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectI18n(final Combo combo, final List<String> items) {
|
|
||||||
final Consumer<Combo> comboFunction = comboFunction(items, this.i18nSupport);
|
|
||||||
combo.setData(POLYGLOT_WIDGET_FUNCTION_KEY, comboFunction);
|
|
||||||
comboFunction.accept(combo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createLanguageSelector(final PageContext composerCtx) {
|
public void createLanguageSelector(final PageContext composerCtx) {
|
||||||
for (final Locale locale : this.i18nSupport.supportedLanguages()) {
|
for (final Locale locale : this.i18nSupport.supportedLanguages()) {
|
||||||
final Label languageSelection = new Label(composerCtx.getParent(), SWT.NONE);
|
final Label languageSelection = new Label(composerCtx.getParent(), SWT.NONE);
|
||||||
languageSelection.setData(POLYGLOT_WIDGET_FUNCTION_KEY,
|
languageSelection.setData(
|
||||||
langSelectionLabelFunction(locale, this.i18nSupport));
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
|
(Consumer<Label>) label -> label.setVisible(
|
||||||
|
!this.i18nSupport.getCurrentLocale()
|
||||||
|
.getLanguage()
|
||||||
|
.equals(locale.getLanguage())));
|
||||||
languageSelection.setData(RWT.CUSTOM_VARIANT, "header");
|
languageSelection.setData(RWT.CUSTOM_VARIANT, "header");
|
||||||
languageSelection.setText("| " + locale.getLanguage().toUpperCase());
|
languageSelection.setText("| " + locale.getLanguage().toUpperCase());
|
||||||
//languageSelection.updateLocale(this.i18nSupport);
|
//languageSelection.updateLocale(this.i18nSupport);
|
||||||
|
@ -452,38 +445,6 @@ public class WidgetFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Consumer<ImageUpload> imageUploadFunction(
|
|
||||||
final LocTextKey locTextKey,
|
|
||||||
final I18nSupport i18nSupport) {
|
|
||||||
|
|
||||||
return imageUpload -> {
|
|
||||||
if (locTextKey != null) {
|
|
||||||
imageUpload.setSelectionText(i18nSupport.getText(locTextKey));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Consumer<Tree> treeFunction(final I18nSupport i18nSupport) {
|
|
||||||
return tree -> updateLocale(tree.getItems(), i18nSupport);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Consumer<Table> tableFunction(final I18nSupport i18nSupport) {
|
|
||||||
return table -> {
|
|
||||||
updateLocale(table.getColumns(), i18nSupport);
|
|
||||||
updateLocale(table.getItems(), i18nSupport);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Consumer<Label> langSelectionLabelFunction(
|
|
||||||
final Locale locale,
|
|
||||||
final I18nSupport i18nSupport) {
|
|
||||||
|
|
||||||
return label -> label.setVisible(
|
|
||||||
!i18nSupport.getCurrentLocale()
|
|
||||||
.getLanguage()
|
|
||||||
.equals(locale.getLanguage()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Consumer<Label> labelFunction(
|
private static final Consumer<Label> labelFunction(
|
||||||
final LocTextKey locTextKey,
|
final LocTextKey locTextKey,
|
||||||
final LocTextKey locToolTipKey,
|
final LocTextKey locToolTipKey,
|
||||||
|
@ -511,35 +472,6 @@ public class WidgetFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Consumer<Combo> comboFunction(
|
|
||||||
final List<String> items,
|
|
||||||
final I18nSupport i18nSupport) {
|
|
||||||
|
|
||||||
return combo -> {
|
|
||||||
int i = 0;
|
|
||||||
final Iterator<String> iterator = items.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
combo.setItem(i, i18nSupport.getText(iterator.next()));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Consumer<Button> buttonFunction(
|
|
||||||
final LocTextKey locTextKey,
|
|
||||||
final LocTextKey locToolTipKey,
|
|
||||||
final I18nSupport i18nSupport) {
|
|
||||||
|
|
||||||
return button -> {
|
|
||||||
if (locTextKey != null) {
|
|
||||||
button.setText(i18nSupport.getText(locTextKey));
|
|
||||||
}
|
|
||||||
if (locToolTipKey != null) {
|
|
||||||
button.setToolTipText(i18nSupport.getText(locToolTipKey));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final void updateLocale(final TreeItem[] items, final I18nSupport i18nSupport) {
|
private static final void updateLocale(final TreeItem[] items, final I18nSupport i18nSupport) {
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
return;
|
return;
|
|
@ -89,6 +89,11 @@ sebserver.institution.form.logoImage=Logo Image
|
||||||
# User Account
|
# User Account
|
||||||
################################
|
################################
|
||||||
|
|
||||||
|
sebserver.useraccount.role.SEB_SERVER_ADMIN=SEB Server Administrator
|
||||||
|
sebserver.useraccount.role.INSTITUTIONAL_ADMIN=Institutional Administrator
|
||||||
|
sebserver.useraccount.role.EXAM_ADMIN=Exam Administrator
|
||||||
|
sebserver.useraccount.role.EXAM_SUPPORTER=Exam Supporter
|
||||||
|
|
||||||
sebserver.useraccount.list.title=User Accounts
|
sebserver.useraccount.list.title=User Accounts
|
||||||
sebserver.useraccount.list.column.name=Name
|
sebserver.useraccount.list.column.name=Name
|
||||||
sebserver.useraccount.list.column.username=User Name
|
sebserver.useraccount.list.column.username=User Name
|
||||||
|
@ -114,6 +119,7 @@ sebserver.useraccount.form.username=Username
|
||||||
sebserver.useraccount.form.mail=E-Mail
|
sebserver.useraccount.form.mail=E-Mail
|
||||||
sebserver.useraccount.form.language=Language
|
sebserver.useraccount.form.language=Language
|
||||||
sebserver.useraccount.form.timezone=Time Zone
|
sebserver.useraccount.form.timezone=Time Zone
|
||||||
|
sebserver.useraccount.form.roles=User Roles
|
||||||
sebserver.useraccount.form.password=Password
|
sebserver.useraccount.form.password=Password
|
||||||
sebserver.useraccount.form.password.retyped=Retyped Password
|
sebserver.useraccount.form.password.retyped=Retyped Password
|
||||||
|
|
||||||
|
|
|
@ -62,18 +62,29 @@ Label.h3 {
|
||||||
color: #1f407a;
|
color: #1f407a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Label:hover.imageButton {
|
|
||||||
background-color: #82BE1E;
|
|
||||||
background-gradient-color: #82BE1E;
|
|
||||||
background-image: gradient( linear, left top, left bottom, from( #82BE1E ), to( #82BE1E ) );
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Label:hover.imageButton {
|
Label:hover.imageButton {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label.selection {
|
||||||
|
padding: 4px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label:hover.selection {
|
||||||
|
color: #4a4a4a;
|
||||||
|
background-color: #b5b5b5;
|
||||||
|
background-image: gradient(linear, left top, left bottom, from(#b5b5b5),to(#b5b5b5));
|
||||||
|
padding: 4px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label.selected {
|
||||||
|
color: #4a4a4a;
|
||||||
|
background-color: #b5b5b5;
|
||||||
|
background-image: gradient(linear, left top, left bottom, from(#b5b5b5),to(#b5b5b5));
|
||||||
|
padding: 4px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
Composite.bordered {
|
Composite.bordered {
|
||||||
border: 2px;
|
border: 2px;
|
||||||
}
|
}
|
||||||
|
@ -391,12 +402,12 @@ Tree-RowOverlay:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree-RowOverlay:selected {
|
Tree-RowOverlay:selected {
|
||||||
background-color: #D3D9DB;
|
background-color: #b5b5b5;
|
||||||
color: #1F407A;
|
color: #1F407A;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree-RowOverlay:selected:unfocused {
|
Tree-RowOverlay:selected:unfocused {
|
||||||
background-color: #D3D9DB;
|
background-color: #b5b5b5;
|
||||||
color: #1f407a;
|
color: #1f407a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue