added SEBSever logo
added Institution show case added table attribute to user session
This commit is contained in:
parent
b27c79e1d8
commit
9f752bf145
23 changed files with 386 additions and 48 deletions
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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())
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue