added diverse activity action use cases (possibilities) to Institution
This commit is contained in:
parent
71fb39749b
commit
952e8ef12f
29 changed files with 237 additions and 108 deletions
|
@ -22,6 +22,9 @@
|
|||
<Match>
|
||||
<Package name="~ch\.ethz\.seb\.sebserver\.gui\..*" />
|
||||
<Bug pattern="SE_BAD_FIELD" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Package name="~ch\.ethz\.seb\.sebserver\.gui\..*" />
|
||||
<Bug pattern="REC_CATCH_EXCEPTION" />
|
||||
</Match>
|
||||
<Match>
|
||||
|
|
|
@ -14,11 +14,12 @@ import java.util.Set;
|
|||
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.Activatable;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
|
||||
|
||||
/** Defines a User-Account object */
|
||||
public interface UserAccount extends GrantEntity {
|
||||
public interface UserAccount extends GrantEntity, Activatable {
|
||||
|
||||
/** The model id of the User-Account (UUID) */
|
||||
@Override
|
||||
|
@ -42,6 +43,7 @@ public interface UserAccount extends GrantEntity {
|
|||
Boolean getActive();
|
||||
|
||||
/** Indicates whether the User-Account is active or not */
|
||||
@Override
|
||||
boolean isActive();
|
||||
|
||||
/** The language of the User-Account */
|
||||
|
|
|
@ -614,7 +614,7 @@ public class ExamForm implements TemplateComposer {
|
|||
.removeAttribute(AttributeKeys.IMPORT_FROM_QUIZ_DATA))
|
||||
.newAction(ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP)
|
||||
.withSelectionSupplier(() -> {
|
||||
final ExamConfigurationMap selectedROWData = table.getSelectedROWData();
|
||||
final ExamConfigurationMap selectedROWData = table.getSingleSelectedROWData();
|
||||
final HashSet<EntityKey> result = new HashSet<>();
|
||||
if (selectedROWData != null) {
|
||||
result.add(new EntityKey(
|
||||
|
|
|
@ -220,7 +220,7 @@ public class ExamList implements TemplateComposer {
|
|||
}
|
||||
|
||||
static final PageAction modifyExam(final PageAction action, final EntityTable<Exam> table) {
|
||||
final Exam exam = table.getSelectedROWData();
|
||||
final Exam exam = table.getSingleSelectedROWData();
|
||||
|
||||
if (exam == null) {
|
||||
throw new PageMessageException(EMPTY_SELECTION_TEXT_KEY);
|
||||
|
|
|
@ -26,7 +26,6 @@ import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultPageLayout;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
||||
|
@ -143,7 +142,7 @@ public class InstitutionForm implements TemplateComposer {
|
|||
.newAction(ActionDefinition.INSTITUTION_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withSimpleRestCall(this.restService, DeactivateInstitution.class)
|
||||
.withConfirm(PageUtils.confirmDeactivation(institution, this.restService))
|
||||
.withConfirm(this.pageService.confirmDeactivation(institution))
|
||||
.publishIf(() -> writeGrant && isReadonly && institution.isActive())
|
||||
|
||||
.newAction(ActionDefinition.INSTITUTION_ACTIVATE)
|
||||
|
@ -157,6 +156,12 @@ public class InstitutionForm implements TemplateComposer {
|
|||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> !isReadonly)
|
||||
|
||||
.newAction(ActionDefinition.INSTITUTION_SAVE_AND_ACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(formHandle::saveAndActivate)
|
||||
.ignoreMoveAwayFromEdit()
|
||||
.publishIf(() -> !isReadonly && !institution.isActive())
|
||||
|
||||
.newAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(this.pageService.backToCurrentFunction())
|
||||
|
|
|
@ -120,6 +120,11 @@ public class InstitutionList implements TemplateComposer {
|
|||
|
||||
.newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
|
||||
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
|
||||
.publishIf(() -> instGrant.m() && table.hasAnyContent())
|
||||
|
||||
.newAction(ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY)
|
||||
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
|
||||
.withConfirm(this.pageService.confirmDeactivation(table))
|
||||
.publishIf(() -> instGrant.m() && table.hasAnyContent());
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||
|
@ -266,7 +265,7 @@ public class LmsSetupForm implements TemplateComposer {
|
|||
.newAction(ActionDefinition.LMS_SETUP_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withSimpleRestCall(restService, DeactivateLmsSetup.class)
|
||||
.withConfirm(PageUtils.confirmDeactivation(lmsSetup, restService))
|
||||
.withConfirm(this.pageService.confirmDeactivation(lmsSetup))
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && lmsSetup.isActive())
|
||||
|
||||
.newAction(ActionDefinition.LMS_SETUP_ACTIVATE)
|
||||
|
|
|
@ -194,7 +194,7 @@ public class QuizDiscoveryList implements TemplateComposer {
|
|||
.newAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
|
||||
.withExec(action -> this.showDetails(
|
||||
action,
|
||||
t.getSelectedROWData(),
|
||||
t.getSingleSelectedROWData(),
|
||||
institutionNameFunction))
|
||||
.noEventPropagation()
|
||||
.create())
|
||||
|
@ -214,7 +214,7 @@ public class QuizDiscoveryList implements TemplateComposer {
|
|||
table::getSelection,
|
||||
action -> this.showDetails(
|
||||
action,
|
||||
table.getSelectedROWData(),
|
||||
table.getSingleSelectedROWData(),
|
||||
institutionNameFunction),
|
||||
EMPTY_SELECTION_TEXT)
|
||||
.noEventPropagation()
|
||||
|
@ -235,7 +235,7 @@ public class QuizDiscoveryList implements TemplateComposer {
|
|||
|
||||
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
|
||||
action.getSingleSelection();
|
||||
final QuizData selectedROWData = table.getSelectedROWData();
|
||||
final QuizData selectedROWData = table.getSingleSelectedROWData();
|
||||
|
||||
if (selectedROWData.endTime != null) {
|
||||
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||
|
|
|
@ -30,7 +30,6 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.download.SebClientConfigDownload;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
|
@ -183,7 +182,7 @@ public class SebClientConfigForm implements TemplateComposer {
|
|||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withSimpleRestCall(this.restService, DeactivateClientConfig.class)
|
||||
.withConfirm(PageUtils.confirmDeactivation(clientConfig, this.restService))
|
||||
.withConfirm(this.pageService.confirmDeactivation(clientConfig))
|
||||
.publishIf(() -> writeGrant && isReadonly && clientConfig.isActive())
|
||||
|
||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_ACTIVATE)
|
||||
|
|
|
@ -219,7 +219,7 @@ public class SebClientLogs implements TemplateComposer {
|
|||
|
||||
.withDefaultAction(t -> actionBuilder
|
||||
.newAction(ActionDefinition.LOGS_SEB_CLIENT_SHOW_DETAILS)
|
||||
.withExec(action -> this.showDetails(action, t.getSelectedROWData()))
|
||||
.withExec(action -> this.showDetails(action, t.getSingleSelectedROWData()))
|
||||
.noEventPropagation()
|
||||
.create())
|
||||
|
||||
|
@ -229,7 +229,7 @@ public class SebClientLogs implements TemplateComposer {
|
|||
.newAction(ActionDefinition.LOGS_SEB_CLIENT_SHOW_DETAILS)
|
||||
.withSelect(
|
||||
table::getSelection,
|
||||
action -> this.showDetails(action, table.getSelectedROWData()),
|
||||
action -> this.showDetails(action, table.getSingleSelectedROWData()),
|
||||
EMPTY_SELECTION_TEXT)
|
||||
.noEventPropagation()
|
||||
.publishIf(table::hasAnyContent);
|
||||
|
|
|
@ -347,7 +347,7 @@ public class SebExamConfigPropForm implements TemplateComposer {
|
|||
}
|
||||
|
||||
private ExamConfigurationMap getSelectedExamMapping(final EntityTable<ExamConfigurationMap> table) {
|
||||
final ExamConfigurationMap selectedROWData = table.getSelectedROWData();
|
||||
final ExamConfigurationMap selectedROWData = table.getSingleSelectedROWData();
|
||||
|
||||
if (selectedROWData == null) {
|
||||
throw new PageMessageException(ExamList.EMPTY_SELECTION_TEXT_KEY);
|
||||
|
|
|
@ -37,7 +37,6 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
|
||||
|
@ -225,7 +224,7 @@ public class UserAccountForm implements TemplateComposer {
|
|||
.newAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withSimpleRestCall(restService, DeactivateUserAccount.class)
|
||||
.withConfirm(PageUtils.confirmDeactivation(userAccount, restService))
|
||||
.withConfirm(this.pageService.confirmDeactivation(userAccount))
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive())
|
||||
|
||||
.newAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
|
||||
|
|
|
@ -191,7 +191,7 @@ public class UserActivityLogs implements TemplateComposer {
|
|||
|
||||
.withDefaultAction(t -> actionBuilder
|
||||
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
||||
.withExec(action -> this.showDetails(action, t.getSelectedROWData()))
|
||||
.withExec(action -> this.showDetails(action, t.getSingleSelectedROWData()))
|
||||
.noEventPropagation()
|
||||
.create())
|
||||
|
||||
|
@ -201,7 +201,7 @@ public class UserActivityLogs implements TemplateComposer {
|
|||
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
||||
.withSelect(
|
||||
table::getSelection,
|
||||
action -> this.showDetails(action, table.getSelectedROWData()),
|
||||
action -> this.showDetails(action, table.getSingleSelectedROWData()),
|
||||
EMPTY_SELECTION_TEXT)
|
||||
.noEventPropagation()
|
||||
.publishIf(table::hasAnyContent);
|
||||
|
|
|
@ -36,6 +36,11 @@ public enum ActionDefinition {
|
|||
ImageIcon.EDIT,
|
||||
PageStateDefinitionImpl.INSTITUTION_EDIT,
|
||||
ActionCategory.INSTITUTION_LIST),
|
||||
INSTITUTION_TOGGLE_ACTIVITY(
|
||||
new LocTextKey("sebserver.overall.action.toggle-activity"),
|
||||
ImageIcon.SWITCH,
|
||||
PageStateDefinitionImpl.INSTITUTION_LIST,
|
||||
ActionCategory.INSTITUTION_LIST),
|
||||
INSTITUTION_MODIFY(
|
||||
new LocTextKey("sebserver.institution.action.modify"),
|
||||
ImageIcon.EDIT,
|
||||
|
@ -51,6 +56,11 @@ public enum ActionDefinition {
|
|||
ImageIcon.SAVE,
|
||||
PageStateDefinitionImpl.INSTITUTION_VIEW,
|
||||
ActionCategory.FORM),
|
||||
INSTITUTION_SAVE_AND_ACTIVATE(
|
||||
new LocTextKey("sebserver.institution.action.activate"),
|
||||
ImageIcon.ACTIVE,
|
||||
PageStateDefinitionImpl.INSTITUTION_VIEW,
|
||||
ActionCategory.FORM),
|
||||
INSTITUTION_ACTIVATE(
|
||||
new LocTextKey("sebserver.institution.action.activate"),
|
||||
ImageIcon.TOGGLE_OFF,
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
|
@ -29,6 +30,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.FormBinding;
|
||||
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.RestCallError;
|
||||
|
||||
public class FormHandle<T extends Entity> {
|
||||
|
@ -79,6 +81,16 @@ public class FormHandle<T extends Entity> {
|
|||
return handleFormPost(doAPIPost(), action);
|
||||
}
|
||||
|
||||
public final PageAction saveAndActivate(final PageAction action) {
|
||||
final PageAction handleFormPost = handleFormPost(doAPIPost(), action);
|
||||
final EntityType entityType = this.post.getEntityType();
|
||||
this.pageService.getRestService().getBuilder(entityType, CallType.ACTIVATION_ACTIVATE)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, handleFormPost.getEntityKey().getModelId())
|
||||
.call()
|
||||
.getOrThrow();
|
||||
return handleFormPost;
|
||||
}
|
||||
|
||||
/** process a form post by first resetting all field validation errors (if there are some)
|
||||
* then collecting all input data from the form by form-binding to a either a JSON string in
|
||||
* HTTP PUT case or to an form-URL-encoded string on HTTP POST case. And PUT or POST the data
|
||||
|
@ -136,7 +148,7 @@ public class FormHandle<T extends Entity> {
|
|||
return true;
|
||||
} else {
|
||||
log.error("Unexpected error while trying to post form: {}", error.getMessage());
|
||||
final EntityType resultType = this.post.getResultType();
|
||||
final EntityType resultType = this.post.getEntityType();
|
||||
if (resultType != null) {
|
||||
this.pageContext.notifySaveError(resultType, error);
|
||||
} else {
|
||||
|
|
|
@ -8,23 +8,28 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.page;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.ScrolledComposite;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Activatable;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
|
@ -42,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.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
|
@ -99,6 +105,45 @@ public interface PageService {
|
|||
return action -> (currentState != null) ? currentState.gotoAction : action;
|
||||
}
|
||||
|
||||
/** Get a page action execution function for switching the activity of currently selected
|
||||
* entities from a given entity-table.
|
||||
*
|
||||
* @param table the entity table
|
||||
* @param noSelectionText LocTextKey for missing selection message
|
||||
* @return page action execution function for switching the activity */
|
||||
<T extends Entity & Activatable> Function<PageAction, PageAction> activationToggleActionFunction(
|
||||
EntityTable<T> table,
|
||||
LocTextKey noSelectionText);
|
||||
|
||||
/** Get a message supplier to notify deactivation dependencies to the user for all given entities
|
||||
*
|
||||
* @param entities Set of entities to collect the dependencies for
|
||||
* @return a message supplier to notify deactivation dependencies to the user */
|
||||
<T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(final Set<? extends T> entities);
|
||||
|
||||
/** Get a message supplier to notify deactivation dependencies to the user for given entity
|
||||
*
|
||||
* @param entity the entity instance
|
||||
* @return a message supplier to notify deactivation dependencies to the user */
|
||||
default <T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(final T entity) {
|
||||
return confirmDeactivation(new HashSet<>(Arrays.asList(entity)));
|
||||
}
|
||||
|
||||
/** Get a message supplier to notify deactivation dependencies to the user for given entity table selection
|
||||
*
|
||||
* @param table the entity table
|
||||
* @return a message supplier to notify deactivation dependencies to the user */
|
||||
default <T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(final EntityTable<T> table) {
|
||||
return () -> {
|
||||
return confirmDeactivation(table
|
||||
.getSelectedROWData()
|
||||
.stream()
|
||||
.filter(e -> e.isActive()) // NOTE: Activatable::isActive leads to an error here!?
|
||||
.collect(Collectors.toSet()))
|
||||
.get();
|
||||
};
|
||||
}
|
||||
|
||||
/** Publishes a given PageEvent to the current page tree
|
||||
* This goes through the page-tree and collects all listeners the are listen to
|
||||
* the specified page event type.
|
||||
|
@ -229,6 +274,16 @@ public interface PageService {
|
|||
}
|
||||
}
|
||||
|
||||
static void clearComposite(final Composite parent) {
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Control control : parent.getChildren()) {
|
||||
control.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public class PageActionBuilder {
|
||||
private final PageService pageService;
|
||||
private final PageContext originalPageContext;
|
||||
|
|
|
@ -115,7 +115,7 @@ public class ComposerServiceImpl implements ComposerService {
|
|||
|
||||
if (composer.validate(pageContext)) {
|
||||
|
||||
PageUtils.clearComposite(pageContext.getParent());
|
||||
PageService.clearComposite(pageContext.getParent());
|
||||
|
||||
try {
|
||||
composer.compose(pageContext);
|
||||
|
|
|
@ -10,9 +10,14 @@ package ch.ethz.seb.sebserver.gui.service.page.impl;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
@ -22,8 +27,13 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Activatable;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
@ -34,6 +44,7 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageStateDefinition.Type;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||
|
@ -41,8 +52,10 @@ import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
import ch.ethz.seb.sebserver.gui.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.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
|
@ -51,6 +64,11 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|||
@GuiProfile
|
||||
public class PageServiceImpl implements PageService {
|
||||
|
||||
private static final LocTextKey CONFIRM_DEACTIVATION_NO_DEP_KEY =
|
||||
new LocTextKey("sebserver.dialog.confirm.deactivation.noDependencies");
|
||||
|
||||
private static final String CONFIRM_DEACTIVATION_KEY = "sebserver.dialog.confirm.deactivation";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PageServiceImpl.class);
|
||||
|
||||
private static final LocTextKey MSG_GO_AWAY_FROM_EDIT =
|
||||
|
@ -183,6 +201,80 @@ public class PageServiceImpl implements PageService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(final Set<? extends T> entities) {
|
||||
final RestService restService = this.resourceService.getRestService();
|
||||
return () -> {
|
||||
if (entities == null || entities.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final int dependencies = entities.stream()
|
||||
.flatMap(entity -> {
|
||||
final RestCall<Set<EntityKey>>.RestCallBuilder builder =
|
||||
restService.<Set<EntityKey>> getBuilder(
|
||||
entity.entityType(),
|
||||
CallType.GET_DEPENDENCIES);
|
||||
|
||||
return builder
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(entity.getModelId()))
|
||||
.withQueryParam(API.PARAM_BULK_ACTION_TYPE, BulkActionType.DEACTIVATE.name())
|
||||
.call()
|
||||
.getOrThrow().stream();
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
.size();
|
||||
if (dependencies > 0) {
|
||||
return new LocTextKey(CONFIRM_DEACTIVATION_KEY, String.valueOf(dependencies));
|
||||
} else {
|
||||
return CONFIRM_DEACTIVATION_NO_DEP_KEY;
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to get dependencyies. Error: {}", e.getMessage());
|
||||
return new LocTextKey(CONFIRM_DEACTIVATION_KEY, "");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity & Activatable> Function<PageAction, PageAction> activationToggleActionFunction(
|
||||
final EntityTable<T> table,
|
||||
final LocTextKey noSelectionText) {
|
||||
|
||||
return action -> {
|
||||
final Set<T> selectedROWData = table.getSelectedROWData();
|
||||
if (selectedROWData == null || selectedROWData.isEmpty()) {
|
||||
throw new PageMessageException(noSelectionText);
|
||||
}
|
||||
|
||||
final RestService restService = this.resourceService.getRestService();
|
||||
final EntityType entityType = table.getEntityType();
|
||||
|
||||
final Collection<Exception> errors = new ArrayList<>();
|
||||
for (final T entity : selectedROWData) {
|
||||
if (entity.isActive()) {
|
||||
restService.getBuilder(entityType, CallType.ACTIVATION_DEACTIVATE)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entity.getModelId())
|
||||
.call()
|
||||
.onError(errors::add);
|
||||
} else {
|
||||
restService.getBuilder(entityType, CallType.ACTIVATION_ACTIVATE)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entity.getModelId())
|
||||
.call()
|
||||
.onError(errors::add);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
// TODO notify message for user
|
||||
}
|
||||
|
||||
return action;
|
||||
};
|
||||
}
|
||||
|
||||
private void exec(final PageAction pageAction, final Consumer<Result<PageAction>> callback) {
|
||||
pageAction.applyAction(result -> {
|
||||
if (!result.hasError()) {
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
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.RestService;
|
||||
|
||||
public final class PageUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PageUtils.class);
|
||||
|
||||
public static void clearComposite(final Composite parent) {
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Control control : parent.getChildren()) {
|
||||
control.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static final Supplier<LocTextKey> confirmDeactivation(
|
||||
final Entity entity,
|
||||
final RestService restService) {
|
||||
|
||||
return () -> {
|
||||
try {
|
||||
final RestCall<Set<EntityKey>>.RestCallBuilder builder =
|
||||
restService.<Set<EntityKey>> getBuilder(
|
||||
entity.entityType(),
|
||||
CallType.GET_DEPENDENCIES);
|
||||
|
||||
if (builder == null) {
|
||||
throw new RuntimeException("No RestCall builder found for entity type: " + entity.entityType());
|
||||
}
|
||||
|
||||
final Set<EntityKey> dependencies = builder
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(entity.getModelId()))
|
||||
.withQueryParam(API.PARAM_BULK_ACTION_TYPE, BulkActionType.DEACTIVATE.name())
|
||||
.call()
|
||||
.getOrThrow();
|
||||
final int size = dependencies.size();
|
||||
if (size > 0) {
|
||||
return new LocTextKey("sebserver.dialog.confirm.deactivation", String.valueOf(size));
|
||||
} else {
|
||||
return new LocTextKey("sebserver.dialog.confirm.deactivation.noDependencies");
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.info("Failed to get dependencyies for Entity: {} error: ", entity, e.getMessage());
|
||||
return new LocTextKey("sebserver.dialog.confirm.deactivation", "");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -94,7 +94,7 @@ public abstract class RestCall<T> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public EntityType getResultType() {
|
||||
public EntityType getEntityType() {
|
||||
if (this.typeKey != null) {
|
||||
return this.typeKey.entityType;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
|
||||
|
@ -203,6 +204,14 @@ public class EntityTable<ROW extends Entity> {
|
|||
this.sortOrder);
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
if (this.restCall != null) {
|
||||
return this.restCall.getEntityType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public PageContext getPageContext() {
|
||||
if (this.pageContext == null) {
|
||||
return null;
|
||||
|
@ -303,7 +312,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
return getRowData(item);
|
||||
}
|
||||
|
||||
public ROW getSelectedROWData() {
|
||||
public ROW getSingleSelectedROWData() {
|
||||
final TableItem[] selection = this.table.getSelection();
|
||||
if (selection == null || selection.length == 0) {
|
||||
return null;
|
||||
|
@ -312,6 +321,18 @@ public class EntityTable<ROW extends Entity> {
|
|||
return getRowData(selection[0]);
|
||||
}
|
||||
|
||||
public Set<ROW> getSelectedROWData() {
|
||||
final TableItem[] selection = this.table.getSelection();
|
||||
if (selection == null || selection.length == 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return Arrays.asList(selection)
|
||||
.stream()
|
||||
.map(this::getRowData)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<EntityKey> getSelection() {
|
||||
return getSelection(null);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.eclipse.swt.widgets.Composite;
|
|||
import org.eclipse.swt.widgets.Label;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||
|
||||
public class TableNavigator {
|
||||
|
@ -40,7 +40,7 @@ public class TableNavigator {
|
|||
|
||||
public Page<?> update(final Page<?> pageData) {
|
||||
// clear all
|
||||
PageUtils.clearComposite(this.composite);
|
||||
PageService.clearComposite(this.composite);
|
||||
|
||||
if (pageData.isEmpty()) {
|
||||
// show empty message
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.swt.widgets.Listener;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||
|
||||
public final class MultiSelection extends Composite implements Selection {
|
||||
|
@ -61,7 +61,7 @@ public final class MultiSelection extends Composite implements Selection {
|
|||
final String selectionValue = getSelectionValue();
|
||||
this.selected.clear();
|
||||
this.labels.clear();
|
||||
PageUtils.clearComposite(this);
|
||||
PageService.clearComposite(this);
|
||||
|
||||
for (final Tuple<String> tuple : mapping) {
|
||||
final Label label = new Label(this, SWT.NONE);
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.swt.widgets.Listener;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
|
||||
public final class MultiSelectionCheckbox extends Composite implements Selection {
|
||||
|
||||
|
@ -54,7 +54,7 @@ public final class MultiSelectionCheckbox extends Composite implements Selection
|
|||
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
||||
final String selectionValue = getSelectionValue();
|
||||
this.checkboxes.clear();
|
||||
PageUtils.clearComposite(this);
|
||||
PageService.clearComposite(this);
|
||||
|
||||
for (final Tuple<String> tuple : mapping) {
|
||||
final Button button = new Button(this, SWT.CHECK);
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.eclipse.swt.widgets.Composite;
|
|||
import org.eclipse.swt.widgets.Listener;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
|
||||
public final class RadioSelection extends Composite implements Selection {
|
||||
|
||||
|
@ -51,7 +51,7 @@ public final class RadioSelection extends Composite implements Selection {
|
|||
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
||||
final String selectionValue = getSelectionValue();
|
||||
this.radioButtons.clear();
|
||||
PageUtils.clearComposite(this);
|
||||
PageService.clearComposite(this);
|
||||
|
||||
for (final Tuple<String> tuple : mapping) {
|
||||
final Button button = new Button(this, SWT.RADIO);
|
||||
|
|
|
@ -82,6 +82,7 @@ public class WidgetFactory {
|
|||
INACTIVE("inactive.png"),
|
||||
TOGGLE_ON("toggle_on.png"),
|
||||
TOGGLE_OFF("toggle_off.png"),
|
||||
SWITCH("switch.png"),
|
||||
YES("yes.png"),
|
||||
NO("no.png"),
|
||||
SAVE("save.png"),
|
||||
|
@ -440,7 +441,7 @@ public class WidgetFactory {
|
|||
}
|
||||
|
||||
public Table tableLocalized(final Composite parent) {
|
||||
final Table table = new Table(parent, SWT.SINGLE | SWT.NO_SCROLL);
|
||||
final Table table = new Table(parent, SWT.MULTI | SWT.NO_SCROLL);
|
||||
this.polyglotPageService.injectI18n(table);
|
||||
return table;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ sebserver.gui.webservice.mock-lms-enabled=true
|
|||
|
||||
|
||||
sebserver.gui.theme=css/sebserver.css
|
||||
sebserver.gui.list.page.size=20
|
||||
sebserver.gui.list.page.size=15
|
||||
sebserver.gui.date.displayformat=MM/dd/yyyy HH:mm
|
||||
sebserver.gui.date.displayformat.timezone=|ZZ
|
||||
sebserver.gui.multilingual=true
|
||||
|
|
|
@ -28,6 +28,7 @@ sebserver.overall.date.to=To
|
|||
sebserver.overall.action.add=Add;
|
||||
sebserver.overall.action.remove=Remove
|
||||
sebserver.overall.action.select=Please Select
|
||||
sebserver.overall.action.toggle-activity=Switch Activity
|
||||
|
||||
sebserver.overall.types.activityType.CREATE=Create New
|
||||
sebserver.overall.types.activityType.IMPORT=Import
|
||||
|
|
BIN
src/main/resources/static/images/switch.png
Normal file
BIN
src/main/resources/static/images/switch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 205 B |
Loading…
Reference in a new issue