added SEBSever logo

added Institution show case
added table attribute to user session
This commit is contained in:
anhefti 2019-12-10 13:33:15 +01:00
parent b27c79e1d8
commit 9f752bf145
23 changed files with 386 additions and 48 deletions

View file

@ -19,6 +19,7 @@ public interface Entity extends ModelIdAware {
public static final String FILTER_ATTR_INSTITUTION = API.PARAM_INSTITUTION_ID; public static final String FILTER_ATTR_INSTITUTION = API.PARAM_INSTITUTION_ID;
public static final String FILTER_ATTR_ACTIVE = "active"; public static final String FILTER_ATTR_ACTIVE = "active";
public static final String FILTER_ATTR_NAME = "name"; public static final String FILTER_ATTR_NAME = "name";
public static final String FILTER_ATTR_URL_SUFFIX = "urlsuffix";
/** Get the type of the entity. /** Get the type of the entity.
* *

View file

@ -185,7 +185,9 @@ public class ConfigTemplateForm implements TemplateComposer {
() -> this.resourceService.getAttributeTypeResources()); () -> this.resourceService.getAttributeTypeResources());
final EntityTable<TemplateAttribute> attrTable = final EntityTable<TemplateAttribute> attrTable =
this.pageService.entityTableBuilder(this.restService.getRestCall(GetTemplateAttributePage.class)) this.pageService.entityTableBuilder(
Domain.CONFIGURATION_NODE.TYPE_NAME + "_Template",
this.restService.getRestCall(GetTemplateAttributePage.class))
.withRestCallAdapter(restCall -> restCall.withURIVariable( .withRestCallAdapter(restCall -> restCall.withURIVariable(
API.PARAM_PARENT_MODEL_ID, API.PARAM_PARENT_MODEL_ID,
entityKey.modelId)) entityKey.modelId))
@ -226,7 +228,7 @@ public class ConfigTemplateForm implements TemplateComposer {
.withParentEntityKey(entityKey) .withParentEntityKey(entityKey)
.withSelect( .withSelect(
attrTable::getSelection, attrTable::getSelection,
PageAction::applySingleSelection, PageAction::applySingleSelectionAsEntityKey,
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY) EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
.publishIf(() -> attrTable.hasAnyContent()) .publishIf(() -> attrTable.hasAnyContent())

View file

@ -519,7 +519,7 @@ public class ExamForm implements TemplateComposer {
.withParentEntityKey(entityKey) .withParentEntityKey(entityKey)
.withSelect( .withSelect(
indicatorTable::getSelection, indicatorTable::getSelection,
PageAction::applySingleSelection, PageAction::applySingleSelectionAsEntityKey,
INDICATOR_EMPTY_SELECTION_TEXT_KEY) INDICATOR_EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent() && editable) .publishIf(() -> modifyGrant && indicatorTable.hasAnyContent() && editable)

View file

@ -207,7 +207,7 @@ public class ExamList implements TemplateComposer {
.publishIf(userGrant::im) .publishIf(userGrant::im)
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST) .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(table::hasAnyContent) .publishIf(table::hasAnyContent)
.newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST) .newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)

View file

@ -13,8 +13,10 @@ import org.springframework.beans.factory.annotation.Value;
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.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.Entity;
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.ActionDefinition;
@ -29,7 +31,9 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetIn
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition; import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
import ch.ethz.seb.sebserver.gui.table.EntityTable; import ch.ethz.seb.sebserver.gui.table.EntityTable;
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
@Lazy @Lazy
@Component @Component
@ -49,6 +53,12 @@ public class InstitutionList implements TemplateComposer {
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY = private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.institution.info.pleaseSelect"); new LocTextKey("sebserver.institution.info.pleaseSelect");
private final TableFilterAttribute nameFilter =
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
private final TableFilterAttribute urlSuffixFilter =
new TableFilterAttribute(CriteriaType.TEXT, Institution.FILTER_ATTR_URL_SUFFIX);
private final TableFilterAttribute activityFilter;
private final PageService pageService; private final PageService pageService;
private final RestService restService; private final RestService restService;
private final CurrentUser currentUser; private final CurrentUser currentUser;
@ -64,6 +74,12 @@ public class InstitutionList implements TemplateComposer {
this.restService = restService; this.restService = restService;
this.currentUser = currentUser; this.currentUser = currentUser;
this.pageSize = pageSize; this.pageSize = pageSize;
this.activityFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Institution.FILTER_ATTR_ACTIVE,
Constants.TRUE_STRING,
this.pageService.getResourceService()::activityResources);
} }
@Override @Override
@ -84,19 +100,22 @@ public class InstitutionList implements TemplateComposer {
Domain.INSTITUTION.ATTR_NAME, Domain.INSTITUTION.ATTR_NAME,
NAME_TEXT_KEY, NAME_TEXT_KEY,
Institution::getName) Institution::getName)
.sortable()) .sortable()
.withFilter(this.nameFilter))
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
Domain.INSTITUTION.ATTR_URL_SUFFIX, Domain.INSTITUTION.ATTR_URL_SUFFIX,
URL_TEXT_KEY, URL_TEXT_KEY,
Institution::getUrlSuffix) Institution::getUrlSuffix)
.sortable()) .sortable()
.withFilter(this.urlSuffixFilter))
.withColumn(new ColumnDefinition<Institution>( .withColumn(new ColumnDefinition<Institution>(
Domain.INSTITUTION.ATTR_ACTIVE, Domain.INSTITUTION.ATTR_ACTIVE,
ACTIVE_TEXT_KEY, ACTIVE_TEXT_KEY,
entity -> this.pageService entity -> this.pageService
.getResourceService() .getResourceService()
.localizedActivityResource().apply(entity.active)) .localizedActivityResource().apply(entity.active))
.sortable()) .sortable()
.withFilter(this.activityFilter))
.withDefaultAction(pageActionBuilder .withDefaultAction(pageActionBuilder
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
.create()) .create())
@ -111,21 +130,31 @@ public class InstitutionList implements TemplateComposer {
.newAction(ActionDefinition.INSTITUTION_NEW) .newAction(ActionDefinition.INSTITUTION_NEW)
.publishIf(instGrant::w) .publishIf(instGrant::w)
.newAction(ActionDefinition.USER_ACCOUNT_NEW)
.publishIf(userGrant::w)
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST) .newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table::getSelection,
PageAction::applySingleSelectionAsEntityKey,
EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST) .newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table::getSelection,
PageAction::applySingleSelectionAsEntityKey,
EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> instGrant.m() && table.hasAnyContent()) .publishIf(() -> instGrant.m() && table.hasAnyContent())
.newAction(ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY) .newAction(ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY)
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY)) .withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
.withConfirm(this.pageService.confirmDeactivation(table)) .withConfirm(this.pageService.confirmDeactivation(table))
.publishIf(() -> instGrant.m() && table.hasAnyContent()); .publishIf(() -> instGrant.m() && table.hasAnyContent())
.newAction(ActionDefinition.INSTITUTION_USER_ACCOUNT_NEW)
.withSelect(
table::getSelection,
PageAction::applySingleSelectionAsParentEntityKey,
EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent() && userGrant.w());
} }
} }

View file

@ -157,13 +157,13 @@ public class LmsSetupList implements TemplateComposer {
.publishIf(userGrant::iw) .publishIf(userGrant::iw)
.newAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST) .newAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST) .newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
.withSelect( .withSelect(
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION), table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());
} }

View file

@ -136,7 +136,7 @@ public class MonitoringRunningExamList implements TemplateComposer {
actionBuilder actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_FROM_LIST) .newAction(ActionDefinition.MONITOR_EXAM_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER)); .publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER));
} }

View file

@ -161,13 +161,13 @@ public class SebClientConfigList implements TemplateComposer {
.publishIf(clientConfigGrant::iw) .publishIf(clientConfigGrant::iw)
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST) .newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST) .newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
.withSelect( .withSelect(
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION), table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent()); .publishIf(() -> clientConfigGrant.im() && table.hasAnyContent());
} }

View file

@ -192,19 +192,19 @@ public class SebExamConfigList implements TemplateComposer {
.publishIf(examConfigGrant::iw) .publishIf(examConfigGrant::iw)
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
.withSelect(configTable::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(configTable::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> configTable.hasAnyContent()) .publishIf(() -> configTable.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
.withSelect( .withSelect(
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION), configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent()) .publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST)
.withSelect( .withSelect(
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION), configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent()) .publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG) .newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
@ -217,14 +217,14 @@ public class SebExamConfigList implements TemplateComposer {
.publishIf(examConfigGrant::iw) .publishIf(examConfigGrant::iw)
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST)
.withSelect(templateTable::getSelection, PageAction::applySingleSelection, .withSelect(templateTable::getSelection, PageAction::applySingleSelectionAsEntityKey,
EMPTY_TEMPLATE_SELECTION_TEXT_KEY) EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
.publishIf(() -> templateTable.hasAnyContent()) .publishIf(() -> templateTable.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY_FROM_LIST)
.withSelect( .withSelect(
templateTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION), templateTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_TEMPLATE_SELECTION_TEXT_KEY) PageAction::applySingleSelectionAsEntityKey, EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
.publishIf(() -> examConfigGrant.im() && templateTable.hasAnyContent()); .publishIf(() -> examConfigGrant.im() && templateTable.hasAnyContent());
} }

View file

@ -342,7 +342,7 @@ public class SebExamConfigPropForm implements TemplateComposer {
final ExamConfigurationMap selectedROWData = getSelectedExamMapping(table); final ExamConfigurationMap selectedROWData = getSelectedExamMapping(table);
return new HashSet<>(Arrays.asList(new EntityKey(selectedROWData.examId, EntityType.EXAM))); return new HashSet<>(Arrays.asList(new EntityKey(selectedROWData.examId, EntityType.EXAM)));
}) })
.withExec(PageAction::applySingleSelection) .withExec(PageAction::applySingleSelectionAsEntityKey)
.create(); .create();
} }

View file

@ -195,7 +195,7 @@ public class UserAccountList implements TemplateComposer {
.publishIf(userGrant::iw) .publishIf(userGrant::iw)
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST) .newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST) .newAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
@ -214,7 +214,7 @@ public class UserAccountList implements TemplateComposer {
throw new PageMessageException(NO_EDIT_RIGHT_MESSAGE); throw new PageMessageException(NO_EDIT_RIGHT_MESSAGE);
} }
return PageAction.applySingleSelection(pageAction); return PageAction.applySingleSelectionAsEntityKey(pageAction);
} }
private String getLocaleDisplayText(final UserInfo userInfo) { private String getLocaleDisplayText(final UserInfo userInfo) {

View file

@ -25,7 +25,8 @@ public enum ActionDefinition {
INSTITUTION_NEW( INSTITUTION_NEW(
new LocTextKey("sebserver.institution.action.new"), new LocTextKey("sebserver.institution.action.new"),
ImageIcon.INSTITUTION, ImageIcon.INSTITUTION,
PageStateDefinitionImpl.INSTITUTION_EDIT), PageStateDefinitionImpl.INSTITUTION_EDIT,
ActionCategory.FORM),
INSTITUTION_VIEW_FROM_LIST( INSTITUTION_VIEW_FROM_LIST(
new LocTextKey("sebserver.institution.action.list.view"), new LocTextKey("sebserver.institution.action.list.view"),
ImageIcon.SHOW, ImageIcon.SHOW,
@ -71,6 +72,11 @@ public enum ActionDefinition {
ImageIcon.TOGGLE_ON, ImageIcon.TOGGLE_ON,
PageStateDefinitionImpl.INSTITUTION_VIEW, PageStateDefinitionImpl.INSTITUTION_VIEW,
ActionCategory.FORM), ActionCategory.FORM),
INSTITUTION_USER_ACCOUNT_NEW(
new LocTextKey("sebserver.useraccount.action.new"),
ImageIcon.USER,
PageStateDefinitionImpl.USER_ACCOUNT_EDIT,
ActionCategory.INSTITUTION_LIST),
USER_ACCOUNT_VIEW_LIST( USER_ACCOUNT_VIEW_LIST(
new LocTextKey("sebserver.useraccount.action.list"), new LocTextKey("sebserver.useraccount.action.list"),

View file

@ -147,8 +147,9 @@ public class ResourceService {
public List<Tuple<String>> activityResources() { public List<Tuple<String>> activityResources() {
final List<Tuple<String>> result = new ArrayList<>(); final List<Tuple<String>> result = new ArrayList<>();
result.add(new Tuple<>("true", this.i18nSupport.getText("sebserver.overall.status.active"))); result.add(new Tuple<>(Constants.TRUE_STRING, this.i18nSupport.getText("sebserver.overall.status.active")));
result.add(new Tuple<>("false", this.i18nSupport.getText("sebserver.overall.status.inactive"))); result.add(new Tuple<>(Constants.FALSE_STRING, this.i18nSupport.getText("sebserver.overall.status.inactive")));
result.add(new Tuple<>(StringUtils.EMPTY, StringUtils.EMPTY));
return result; return result;
} }

View file

@ -47,6 +47,7 @@ import ch.ethz.seb.sebserver.gui.service.page.impl.PageState;
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.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.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.table.EntityTable; import ch.ethz.seb.sebserver.gui.table.EntityTable;
import ch.ethz.seb.sebserver.gui.table.TableBuilder; import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -92,6 +93,11 @@ public interface PageService {
* @return the RestService bean */ * @return the RestService bean */
RestService getRestService(); RestService getRestService();
/** Use this to get the CurrentUser facade
*
* @return the CurrentUser facade */
CurrentUser getCurrentUser();
/** Get the PageState of the current user. /** Get the PageState of the current user.
* *
* @return PageState of the current user. */ * @return PageState of the current user. */
@ -187,7 +193,19 @@ public interface PageService {
* @param apiCall the SEB Server API RestCall that feeds the table with data * @param apiCall the SEB Server API RestCall that feeds the table with data
* @param <T> the type of the Entity of the table * @param <T> the type of the Entity of the table
* @return TableBuilder of specified type */ * @return TableBuilder of specified type */
<T extends Entity> TableBuilder<T> entityTableBuilder(RestCall<Page<T>> apiCall); default <T extends Entity> TableBuilder<T> entityTableBuilder(final RestCall<Page<T>> apiCall) {
return entityTableBuilder(apiCall.getEntityType().name(), apiCall);
}
/** Get an new TableBuilder for specified page based RestCall.
*
* @param The name of the table to build
* @param apiCall the SEB Server API RestCall that feeds the table with data
* @param <T> the type of the Entity of the table
* @return TableBuilder of specified type */
<T extends Entity> TableBuilder<T> entityTableBuilder(
String name,
RestCall<Page<T>> apiCall);
/** Get a new PageActionBuilder for a given PageContext. /** Get a new PageActionBuilder for a given PageContext.
* *

View file

@ -231,10 +231,14 @@ public final class PageAction {
return builder.toString(); return builder.toString();
} }
public static PageAction applySingleSelection(final PageAction action) { public static PageAction applySingleSelectionAsEntityKey(final PageAction action) {
return action.withEntityKey(action.getSingleSelection()); return action.withEntityKey(action.getSingleSelection());
} }
public static PageAction applySingleSelectionAsParentEntityKey(final PageAction action) {
return action.withParentEntityKey(action.getSingleSelection());
}
public static PageAction copyOf(final PageAction source) { public static PageAction copyOf(final PageAction source) {
return new PageAction( return new PageAction(
source.definition, source.definition,

View file

@ -56,6 +56,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.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.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.table.EntityTable; import ch.ethz.seb.sebserver.gui.table.EntityTable;
import ch.ethz.seb.sebserver.gui.table.TableBuilder; import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -84,20 +85,20 @@ public class PageServiceImpl implements PageService {
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService; private final PolyglotPageService polyglotPageService;
private final ResourceService resourceService; private final ResourceService resourceService;
private final AuthorizationContextHolder authorizationContextHolder; private final CurrentUser currentUser;
public PageServiceImpl( public PageServiceImpl(
final JSONMapper jsonMapper, final JSONMapper jsonMapper,
final WidgetFactory widgetFactory, final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService, final PolyglotPageService polyglotPageService,
final ResourceService resourceService, final ResourceService resourceService,
final AuthorizationContextHolder authorizationContextHolder) { final CurrentUser currentUser) {
this.jsonMapper = jsonMapper; this.jsonMapper = jsonMapper;
this.widgetFactory = widgetFactory; this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService; this.polyglotPageService = polyglotPageService;
this.resourceService = resourceService; this.resourceService = resourceService;
this.authorizationContextHolder = authorizationContextHolder; this.currentUser = currentUser;
} }
@Override @Override
@ -112,7 +113,7 @@ public class PageServiceImpl implements PageService {
@Override @Override
public AuthorizationContextHolder getAuthorizationContextHolder() { public AuthorizationContextHolder getAuthorizationContextHolder() {
return this.authorizationContextHolder; return this.currentUser.getAuthorizationContextHolder();
} }
@Override @Override
@ -139,6 +140,11 @@ public class PageServiceImpl implements PageService {
return this.resourceService.getRestService(); return this.resourceService.getRestService();
} }
@Override
public CurrentUser getCurrentUser() {
return this.currentUser;
}
@Override @Override
public PageState getCurrentState() { public PageState getCurrentState() {
try { try {
@ -317,8 +323,11 @@ public class PageServiceImpl implements PageService {
} }
@Override @Override
public <T extends Entity> TableBuilder<T> entityTableBuilder(final RestCall<Page<T>> apiCall) { public <T extends Entity> TableBuilder<T> entityTableBuilder(
return new TableBuilder<>(this, apiCall); final String name,
final RestCall<Page<T>> apiCall) {
return new TableBuilder<>(name, this, apiCall);
} }
@Override @Override
@ -326,9 +335,7 @@ public class PageServiceImpl implements PageService {
this.clearState(); this.clearState();
try { try {
final boolean logoutSuccessful = this.authorizationContextHolder final boolean logoutSuccessful = this.currentUser.logout();
.getAuthorizationContext()
.logout();
if (!logoutSuccessful) { if (!logoutSuccessful) {
log.error("Failed to logout. See logfiles for more information"); log.error("Failed to logout. See logfiles for more information");

View file

@ -45,9 +45,23 @@ public class CurrentUser {
private final AuthorizationContextHolder authorizationContextHolder; private final AuthorizationContextHolder authorizationContextHolder;
private SEBServerAuthorizationContext authContext = null; private SEBServerAuthorizationContext authContext = null;
private Map<RoleTypeKey, Privilege> privileges = null; private Map<RoleTypeKey, Privilege> privileges = null;
private final Map<String, String> attributes;
public CurrentUser(final AuthorizationContextHolder authorizationContextHolder) { public CurrentUser(final AuthorizationContextHolder authorizationContextHolder) {
this.authorizationContextHolder = authorizationContextHolder; this.authorizationContextHolder = authorizationContextHolder;
this.attributes = new HashMap<>();
}
public void putAttribute(final String name, final String value) {
this.attributes.put(name, value);
}
public String getAttribute(final String name) {
return this.attributes.get(name);
}
public AuthorizationContextHolder getAuthorizationContextHolder() {
return this.authorizationContextHolder;
} }
public UserInfo get() { public UserInfo get() {
@ -161,6 +175,19 @@ public class CurrentUser {
this.authContext.refreshUser(userInfo); this.authContext.refreshUser(userInfo);
} }
public boolean logout() {
if (isAvailable()) {
if (this.authContext.logout()) {
this.authContext = null;
return true;
} else {
return false;
}
} else {
return this.authorizationContextHolder.getAuthorizationContext().logout();
}
}
private void updateContext() { private void updateContext() {
if (this.authContext == null || !this.authContext.isValid()) { if (this.authContext == null || !this.authContext.isValid()) {
this.authContext = this.authorizationContextHolder.getAuthorizationContext(); this.authContext = this.authorizationContextHolder.getAuthorizationContext();

View file

@ -57,6 +57,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
import io.micrometer.core.instrument.util.StringUtils;
public class EntityTable<ROW extends Entity> { public class EntityTable<ROW extends Entity> {
@ -67,6 +68,12 @@ public class EntityTable<ROW extends Entity> {
private static final int HEADER_HEIGHT = 40; private static final int HEADER_HEIGHT = 40;
private static final int ROW_HEIGHT = 25; private static final int ROW_HEIGHT = 25;
private final String name;
private final String filterAttrName;
private final String sortAttrName;
private final String sortOrderAttrName;
private final String currentPageAttrName;
final PageService pageService; final PageService pageService;
final WidgetFactory widgetFactory; final WidgetFactory widgetFactory;
final RestCall<Page<ROW>> restCall; final RestCall<Page<ROW>> restCall;
@ -92,6 +99,7 @@ public class EntityTable<ROW extends Entity> {
boolean hideNavigation = false; boolean hideNavigation = false;
EntityTable( EntityTable(
final String name,
final int type, final int type,
final PageContext pageContext, final PageContext pageContext,
final RestCall<Page<ROW>> restCall, final RestCall<Page<ROW>> restCall,
@ -105,6 +113,12 @@ public class EntityTable<ROW extends Entity> {
final MultiValueMap<String, String> staticQueryParams, final MultiValueMap<String, String> staticQueryParams,
final BiConsumer<TableItem, ROW> rowDecorator) { final BiConsumer<TableItem, ROW> rowDecorator) {
this.name = name;
this.filterAttrName = name + "_filter";
this.sortAttrName = name + "_sort";
this.sortOrderAttrName = name + "_sortOrder";
this.currentPageAttrName = name + "_currentPage";
this.composite = new Composite(pageContext.getParent(), type); this.composite = new Composite(pageContext.getParent(), type);
this.pageService = pageService; this.pageService = pageService;
this.i18nSupport = pageService.getI18nSupport(); this.i18nSupport = pageService.getI18nSupport();
@ -125,10 +139,6 @@ public class EntityTable<ROW extends Entity> {
this.composite.setLayoutData(gridData); this.composite.setLayoutData(gridData);
this.staticQueryParams = staticQueryParams; this.staticQueryParams = staticQueryParams;
this.rowDecorator = rowDecorator; this.rowDecorator = rowDecorator;
// TODO just for debugging, remove when tested
// this.composite.setBackground(new Color(parent.getDisplay(), new RGB(0, 200, 0)));
this.pageSize = pageSize; this.pageSize = pageSize;
this.filter = this.filter =
columns columns
@ -197,6 +207,9 @@ public class EntityTable<ROW extends Entity> {
this.navigator = new TableNavigator(this); this.navigator = new TableNavigator(this);
createTableColumns(); createTableColumns();
initCurrentPageFromUserAttr();
initFilterFromUserAttrs();
initSortFromUserAttr();
updateTableRows( updateTableRows(
this.pageNumber, this.pageNumber,
this.pageSize, this.pageSize,
@ -204,6 +217,10 @@ public class EntityTable<ROW extends Entity> {
this.sortOrder); this.sortOrder);
} }
public String getName() {
return this.name;
}
public EntityType getEntityType() { public EntityType getEntityType() {
if (this.restCall != null) { if (this.restCall != null) {
return this.restCall.getEntityType(); return this.restCall.getEntityType();
@ -245,15 +262,29 @@ public class EntityTable<ROW extends Entity> {
this.pageSize, this.pageSize,
this.sortColumn, this.sortColumn,
this.sortOrder); this.sortOrder);
updateCurrentPageAttr(pageSelection);
}
public void reset() {
this.applySort(null);
this.table.setSortColumn(null);
this.table.setSortDirection(SWT.NONE);
applyFilter();
} }
public void applyFilter() { public void applyFilter() {
try { try {
updateTableRows( updateTableRows(
this.pageNumber, this.pageNumber,
this.pageSize, this.pageSize,
this.sortColumn, this.sortColumn,
this.sortOrder); this.sortOrder);
updateFilterUserAttrs();
this.selectPage(0);
} catch (final Exception e) { } catch (final Exception e) {
log.error("Unexpected error while trying to apply filter: ", e); log.error("Unexpected error while trying to apply filter: ", e);
} }
@ -269,6 +300,9 @@ public class EntityTable<ROW extends Entity> {
this.pageSize, this.pageSize,
this.sortColumn, this.sortColumn,
this.sortOrder); this.sortOrder);
updateSortUserAttr();
} catch (final Exception e) { } catch (final Exception e) {
log.error("Unexpected error while trying to apply sort: ", e); log.error("Unexpected error while trying to apply sort: ", e);
} }
@ -285,6 +319,9 @@ public class EntityTable<ROW extends Entity> {
this.pageSize, this.pageSize,
this.sortColumn, this.sortColumn,
this.sortOrder); this.sortOrder);
updateSortUserAttr();
} catch (final Exception e) { } catch (final Exception e) {
log.error("Unexpected error while trying to apply sort: ", e); log.error("Unexpected error while trying to apply sort: ", e);
} }
@ -366,6 +403,18 @@ public class EntityTable<ROW extends Entity> {
}); });
} }
private TableColumn getTableColumn(final String name) {
return Arrays.asList(this.table.getColumns())
.stream()
.filter(col -> {
@SuppressWarnings("unchecked")
final ColumnDefinition<ROW> def = (ColumnDefinition<ROW>) col.getData(COLUMN_DEFINITION);
return name.equals(def.columnName);
})
.findFirst()
.orElse(null);
}
private void createTableColumns() { private void createTableColumns() {
for (final ColumnDefinition<ROW> column : this.columns) { for (final ColumnDefinition<ROW> column : this.columns) {
final TableColumn tableColumn = this.widgetFactory.tableColumnLocalized( final TableColumn tableColumn = this.widgetFactory.tableColumnLocalized(
@ -558,4 +607,91 @@ public class EntityTable<ROW extends Entity> {
// TODO handle selection tool-tips on cell level // TODO handle selection tool-tips on cell level
} }
private void updateCurrentPageAttr(final int page) {
try {
this.pageService
.getCurrentUser()
.putAttribute(this.currentPageAttrName, String.valueOf(page));
} catch (final Exception e) {
log.error("Failed to put current page attribute to current user attributes", e);
}
}
private void initCurrentPageFromUserAttr() {
try {
final String currentPage = this.pageService
.getCurrentUser()
.getAttribute(this.currentPageAttrName);
if (StringUtils.isNotBlank(currentPage)) {
this.selectPage(Integer.parseInt(currentPage));
}
} catch (final Exception e) {
log.error("Failed to get sort attribute form current user attributes", e);
}
}
private void updateSortUserAttr() {
try {
this.pageService
.getCurrentUser()
.putAttribute(this.sortAttrName, this.sortColumn);
this.pageService
.getCurrentUser()
.putAttribute(this.sortOrderAttrName, this.sortOrder.name());
} catch (final Exception e) {
log.error("Failed to put sort attribute to current user attributes", e);
}
}
private void initSortFromUserAttr() {
try {
final String sort = this.pageService
.getCurrentUser()
.getAttribute(this.sortAttrName);
if (StringUtils.isNotBlank(sort)) {
this.sortColumn = sort;
final TableColumn tableColumn = getTableColumn(sort);
if (tableColumn != null) {
this.table.setSortColumn(tableColumn);
}
}
final String sortOrder = this.pageService
.getCurrentUser()
.getAttribute(this.sortOrderAttrName);
if (StringUtils.isNotBlank(sortOrder)) {
this.sortOrder = PageSortOrder.valueOf(sortOrder);
this.table.setSortDirection(this.sortOrder == PageSortOrder.ASCENDING ? SWT.UP : SWT.DOWN);
}
} catch (final Exception e) {
log.error("Failed to get sort attribute form current user attributes", e);
}
}
private void updateFilterUserAttrs() {
if (this.filter != null) {
try {
this.pageService
.getCurrentUser()
.putAttribute(this.filterAttrName, this.filter.getFilterAttributes());
} catch (final Exception e) {
log.error("Failed to put filter attributes to current user attributes", e);
}
}
}
private void initFilterFromUserAttrs() {
if (this.filter != null) {
try {
this.filter.setFilterAttributes(
this.pageService
.getCurrentUser()
.getAttribute(this.filterAttrName));
} catch (final Exception e) {
log.error("Failed to get filter attributes form current user attributes", e);
}
}
}
} }

View file

@ -30,6 +30,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
public class TableBuilder<ROW extends Entity> { public class TableBuilder<ROW extends Entity> {
private final String name;
private final PageService pageService; private final PageService pageService;
final RestCall<Page<ROW>> restCall; final RestCall<Page<ROW>> restCall;
private final MultiValueMap<String, String> staticQueryParams; private final MultiValueMap<String, String> staticQueryParams;
@ -43,9 +44,11 @@ public class TableBuilder<ROW extends Entity> {
private BiConsumer<TableItem, ROW> rowDecorator; private BiConsumer<TableItem, ROW> rowDecorator;
public TableBuilder( public TableBuilder(
final String name,
final PageService pageService, final PageService pageService,
final RestCall<Page<ROW>> restCall) { final RestCall<Page<ROW>> restCall) {
this.name = name;
this.pageService = pageService; this.pageService = pageService;
this.restCall = restCall; this.restCall = restCall;
this.staticQueryParams = new LinkedMultiValueMap<>(); this.staticQueryParams = new LinkedMultiValueMap<>();
@ -136,6 +139,7 @@ public class TableBuilder<ROW extends Entity> {
public EntityTable<ROW> compose(final PageContext pageContext) { public EntityTable<ROW> compose(final PageContext pageContext) {
return new EntityTable<>( return new EntityTable<>(
this.name,
this.type, this.type,
pageContext, pageContext,
this.restCall, this.restCall,

View file

@ -25,12 +25,15 @@ import org.eclipse.swt.widgets.DateTime;
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.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
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.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute; import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
import ch.ethz.seb.sebserver.gui.widget.Selection; import ch.ethz.seb.sebserver.gui.widget.Selection;
@ -38,6 +41,8 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
public class TableFilter<ROW extends Entity> { public class TableFilter<ROW extends Entity> {
private static final Logger log = LoggerFactory.getLogger(TableFilter.class);
private static final LocTextKey DATE_FROM_TEXT = new LocTextKey("sebserver.overall.date.from"); private static final LocTextKey DATE_FROM_TEXT = new LocTextKey("sebserver.overall.date.from");
private static final LocTextKey DATE_TO_TEXT = new LocTextKey("sebserver.overall.date.to"); private static final LocTextKey DATE_TO_TEXT = new LocTextKey("sebserver.overall.date.to");
@ -137,6 +142,50 @@ public class TableFilter<ROW extends Entity> {
return false; return false;
} }
String getFilterAttributes() {
final StringBuilder builder = this.components
.stream()
.reduce(
new StringBuilder(),
(sb, filter) -> sb
.append(filter.attribute.columnName)
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
.append(filter.getValue())
.append(Constants.LIST_SEPARATOR),
(sb1, sb2) -> sb1.append(sb2));
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
void setFilterAttributes(final String attribute) {
if (StringUtils.isBlank(attribute)) {
return;
}
try {
Arrays.asList(StringUtils.split(
attribute,
Constants.LIST_SEPARATOR_CHAR))
.stream()
.map(nameValue -> StringUtils.split(
nameValue,
Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR))
.forEach(nameValue -> {
this.components
.stream()
.filter(filter -> nameValue[0].equals(filter.attribute.columnName))
.findFirst()
.ifPresent(filter -> filter.setValue((nameValue.length > 1)
? nameValue[1]
: StringUtils.EMPTY));
});
} catch (final Exception e) {
log.error("Failed to set filter attributes: ", e);
}
}
private void addActions() { private void addActions() {
final Composite inner = new Composite(this.composite, SWT.NONE); final Composite inner = new Composite(this.composite, SWT.NONE);
final GridLayout gridLayout = new GridLayout(2, true); final GridLayout gridLayout = new GridLayout(2, true);
@ -163,7 +212,7 @@ public class TableFilter<ROW extends Entity> {
new LocTextKey("sebserver.overall.action.filter.clear"), new LocTextKey("sebserver.overall.action.filter.clear"),
event -> { event -> {
reset(); reset();
this.entityTable.applyFilter(); this.entityTable.reset();
}); });
imageButton2.setLayoutData(gridData); imageButton2.setLayoutData(gridData);
} }
@ -196,6 +245,8 @@ public class TableFilter<ROW extends Entity> {
abstract String getValue(); abstract String getValue();
abstract void setValue(String value);
boolean adaptWidth(final int width) { boolean adaptWidth(final int width) {
final int _width = width + CELL_WIDTH_ADJUSTMENT; final int _width = width + CELL_WIDTH_ADJUSTMENT;
if (_width != this.rowData.width) { if (_width != this.rowData.width) {
@ -244,6 +295,10 @@ public class TableFilter<ROW extends Entity> {
return null; return null;
} }
@Override
void setValue(final String value) {
}
} }
private class TextFilter extends FilterComponent { private class TextFilter extends FilterComponent {
@ -281,6 +336,13 @@ public class TableFilter<ROW extends Entity> {
return null; return null;
} }
@Override
void setValue(final String value) {
if (this.textInput != null) {
this.textInput.setText(value);
}
}
} }
private class SelectionFilter extends FilterComponent { private class SelectionFilter extends FilterComponent {
@ -317,6 +379,9 @@ public class TableFilter<ROW extends Entity> {
FilterComponent reset() { FilterComponent reset() {
if (this.selector != null) { if (this.selector != null) {
this.selector.clear(); this.selector.clear();
if (StringUtils.isNotBlank(this.attribute.initValue)) {
this.selector.select(this.attribute.initValue);
}
} }
return this; return this;
} }
@ -329,6 +394,13 @@ public class TableFilter<ROW extends Entity> {
return null; return null;
} }
@Override
void setValue(final String value) {
if (this.selector != null) {
this.selector.select(value);
}
}
} }
// NOTE: SWT DateTime month-number starting with 0 and joda DateTime with 1! // NOTE: SWT DateTime month-number starting with 0 and joda DateTime with 1!
@ -379,13 +451,24 @@ public class TableFilter<ROW extends Entity> {
} }
} }
@Override
void setValue(final String value) {
if (this.selector != null) {
try {
final org.joda.time.DateTime date = Utils.toDateTime(value);
this.selector.setDate(date.getYear(), date.getMonthOfYear() - 1, date.getDayOfMonth());
} catch (final Exception e) {
log.error("Failed to set date filter attribute: ", e);
}
}
}
@Override @Override
boolean adaptWidth(final int width) { boolean adaptWidth(final int width) {
// NOTE: for some unknown reason RWT acts differently on width-property for date selector // NOTE: for some unknown reason RWT acts differently on width-property for date selector
// this is to adjust date filter criteria to the list column width // this is to adjust date filter criteria to the list column width
return super.adaptWidth(width - 5); return super.adaptWidth(width - 5);
} }
} }
// NOTE: SWT DateTime month-number starting with 0 and joda DateTime with 1! // NOTE: SWT DateTime month-number starting with 0 and joda DateTime with 1!
@ -473,6 +556,23 @@ public class TableFilter<ROW extends Entity> {
return null; return null;
} }
} }
@Override
void setValue(final String value) {
if (this.fromSelector != null && this.toSelector != null) {
try {
final String[] split = StringUtils.split(value, Constants.EMBEDDED_LIST_SEPARATOR);
final org.joda.time.DateTime fromDate = Utils.toDateTime(split[0]);
final org.joda.time.DateTime toDate = Utils.toDateTime(split[1]);
this.fromSelector.setDate(fromDate.getYear(), fromDate.getMonthOfYear() - 1,
fromDate.getDayOfMonth());
this.toSelector.setDate(toDate.getYear(), toDate.getMonthOfYear() - 1, toDate.getDayOfMonth());
} catch (final Exception e) {
log.error("Failed to set date range filter attribute: ", e);
}
}
}
} }
} }

View file

@ -106,6 +106,9 @@ public class InstitutionDAOImpl implements InstitutionDAO {
.and( .and(
InstitutionRecordDynamicSqlSupport.name, InstitutionRecordDynamicSqlSupport.name,
SqlBuilder.isLikeWhenPresent(filterMap.getName())) SqlBuilder.isLikeWhenPresent(filterMap.getName()))
.and(
InstitutionRecordDynamicSqlSupport.urlSuffix,
SqlBuilder.isLikeWhenPresent(filterMap.getSQLWildcard(Institution.FILTER_ATTR_URL_SUFFIX)))
.build() .build()
.execute() .execute()
.stream() .stream()

View file

@ -19,7 +19,7 @@ sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=15 sebserver.gui.list.page.size=15
sebserver.gui.date.displayformat=yyyy-MM-dd HH:mm sebserver.gui.date.displayformat=yyyy-MM-dd HH:mm
sebserver.gui.date.displayformat.timezone=|ZZ sebserver.gui.date.displayformat.timezone=|ZZ
sebserver.gui.multilingual=true sebserver.gui.multilingual=false
sebserver.gui.languages=en,de sebserver.gui.languages=en,de
sebserver.gui.seb.client.config.download.filename=SEBClientSettings.seb sebserver.gui.seb.client.config.download.filename=SEBClientSettings.seb

View file

@ -4,7 +4,7 @@
sebserver.overall.version=SEB Server Version : {0} sebserver.overall.version=SEB Server Version : {0}
sebserver.overall.help=Documentation sebserver.overall.help=Documentation
sebserver.overall.help.link=https://www.safeexambrowser.org/news_en.html sebserver.overall.help.link=https://seb-server.readthedocs.io/en/latest/#
sebserver.overall.message.leave.without.save=You have unsaved changes!\nAre you sure you want to leave the page?\The changes will be lost. sebserver.overall.message.leave.without.save=You have unsaved changes!\nAre you sure you want to leave the page?\The changes will be lost.
sebserver.overall.upload=Please select a file sebserver.overall.upload=Please select a file