code cleanup
This commit is contained in:
parent
2e13bf4ca2
commit
d2cfa615a1
20 changed files with 387 additions and 302 deletions
|
@ -16,14 +16,11 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.InstitutionActions;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||
import ch.ethz.seb.sebserver.gui.form.PageFormService;
|
||||
|
@ -31,11 +28,13 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
@Lazy
|
||||
|
@ -81,9 +80,10 @@ public class InstitutionForm implements TemplateComposer {
|
|||
return;
|
||||
}
|
||||
|
||||
final boolean writeGrant = this.currentUser.hasPrivilege(PrivilegeType.WRITE, institution);
|
||||
final boolean modifyGrant = this.currentUser.hasPrivilege(PrivilegeType.MODIFY, institution);
|
||||
final boolean userWriteGrant = this.currentUser.hasBasePrivilege(PrivilegeType.WRITE, EntityType.USER);
|
||||
final EntityGrantCheck instGrant = this.currentUser.entityGrantCheck(institution);
|
||||
final boolean writeGrant = instGrant.w();
|
||||
final boolean modifyGrant = instGrant.m();
|
||||
final boolean userWriteGrant = this.currentUser.grantCheck(EntityType.USER).w();
|
||||
final boolean isReadonly = pageContext.isReadonly();
|
||||
|
||||
// new PageContext with actual EntityKey
|
||||
|
@ -128,34 +128,37 @@ public class InstitutionForm implements TemplateComposer {
|
|||
: this.restService.getRestCall(SaveInstitution.class));
|
||||
|
||||
// propagate content actions to action-pane
|
||||
formContext.createAction(ActionDefinition.INSTITUTION_NEW)
|
||||
.readonly(false)
|
||||
formContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_NEW)
|
||||
.publishIf(() -> writeGrant && isReadonly)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.withExec(UserAccountActions::newUserAccount)
|
||||
.resetEntity()
|
||||
.withParentEntity(entityKey)
|
||||
.withParentEntityKey(entityKey)
|
||||
.publishIf(() -> userWriteGrant && isReadonly && institution.isActive())
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_MODIFY)
|
||||
.withExec(InstitutionActions::editInstitution)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && isReadonly)
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_DEACTIVATE)
|
||||
.withExec(InstitutionActions::deactivateInstitution)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(Action.activation(this.restService, false))
|
||||
.withConfirm(PageUtils.confirmDeactivation(institution, this.restService))
|
||||
.publishIf(() -> writeGrant && isReadonly && institution.isActive())
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_ACTIVATE)
|
||||
.withExec(InstitutionActions::activateInstitution)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(Action.activation(this.restService, true))
|
||||
.publishIf(() -> writeGrant && isReadonly && !institution.isActive())
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_SAVE)
|
||||
.withExec(formHandle::postChanges)
|
||||
.publishIf(() -> !isReadonly)
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
|
||||
.withExec(InstitutionActions::cancelEditInstitution)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
|
||||
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
||||
.publishIf(() -> !isReadonly);
|
||||
}
|
||||
|
|
|
@ -13,19 +13,18 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.InstitutionActions;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
@ -77,21 +76,23 @@ public class InstitutionList implements TemplateComposer {
|
|||
.compose(content);
|
||||
|
||||
// propagate content actions to action-pane
|
||||
pageContext.createAction(ActionDefinition.INSTITUTION_NEW)
|
||||
.readonly(false)
|
||||
.publishIf(() -> this.currentUser.hasBasePrivilege(PrivilegeType.WRITE, EntityType.INSTITUTION))
|
||||
final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION);
|
||||
final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER);
|
||||
pageContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_NEW)
|
||||
.publishIf(instGrant::w)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.withExec(UserAccountActions::newUserAccount)
|
||||
.publishIf(() -> this.currentUser.hasBasePrivilege(PrivilegeType.WRITE, EntityType.USER))
|
||||
.publishIf(userGrant::w)
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
|
||||
.withSelectionSupplier(table::getSelection)
|
||||
.withExec(InstitutionActions::viewInstitutionFromList)
|
||||
.withSelect(table::getSelection, Action.applySingleSelection("sebserver.institution.info.pleaseSelect"))
|
||||
.publish()
|
||||
|
||||
.createAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
|
||||
.withSelectionSupplier(table::getSelection)
|
||||
.withExec(InstitutionActions::editInstitutionFromList)
|
||||
.readonly(false)
|
||||
.publishIf(() -> this.currentUser.hasBasePrivilege(PrivilegeType.MODIFY, EntityType.INSTITUTION));
|
||||
.withSelect(table::getSelection, Action.applySingleSelection("sebserver.institution.info.pleaseSelect"))
|
||||
.publishIf(instGrant::m);
|
||||
;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
|||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||
import ch.ethz.seb.sebserver.gui.form.PageFormService;
|
||||
|
@ -29,6 +28,7 @@ import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
|||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||
|
@ -115,7 +115,7 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
|
|||
})
|
||||
.publish()
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
||||
.withExec(UserAccountActions::cancelEditUserAccount)
|
||||
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
|
||||
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
||||
.publish();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
|
@ -31,7 +30,6 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
|||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||
import ch.ethz.seb.sebserver.gui.form.PageFormService;
|
||||
|
@ -46,6 +44,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUs
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
@Lazy
|
||||
|
@ -72,13 +71,13 @@ public class UserAccountForm implements TemplateComposer {
|
|||
@Override
|
||||
public void compose(final PageContext pageContext) {
|
||||
|
||||
final UserInfo currentUser = this.currentUser.get();
|
||||
final UserInfo user = this.currentUser.get();
|
||||
final WidgetFactory widgetFactory = this.pageFormService.getWidgetFactory();
|
||||
final EntityKey entityKey = pageContext.getEntityKey();
|
||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||
final BooleanSupplier isNew = () -> entityKey == null;
|
||||
final BooleanSupplier isNotNew = () -> !isNew.getAsBoolean();
|
||||
final BooleanSupplier isSEBAdmin = () -> currentUser.hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||
final BooleanSupplier isSEBAdmin = () -> user.hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||
final boolean readonly = pageContext.isReadonly();
|
||||
// get data or create new. handle error if happen
|
||||
final UserAccount userAccount = isNew.getAsBoolean()
|
||||
|
@ -86,7 +85,7 @@ public class UserAccountForm implements TemplateComposer {
|
|||
UUID.randomUUID().toString(),
|
||||
(parentEntityKey != null)
|
||||
? Long.valueOf(parentEntityKey.modelId)
|
||||
: currentUser.institutionId)
|
||||
: user.institutionId)
|
||||
: this.restService
|
||||
.getBuilder(GetUserAccount.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||
|
@ -101,9 +100,10 @@ public class UserAccountForm implements TemplateComposer {
|
|||
return;
|
||||
}
|
||||
|
||||
final boolean ownAccount = currentUser.uuid.equals(userAccount.getModelId());
|
||||
final boolean writeGrant = this.currentUser.hasPrivilege(PrivilegeType.WRITE, userAccount);
|
||||
final boolean modifyGrant = this.currentUser.hasPrivilege(PrivilegeType.MODIFY, userAccount);
|
||||
final boolean ownAccount = user.uuid.equals(userAccount.getModelId());
|
||||
final EntityGrantCheck userGrantCheck = this.currentUser.entityGrantCheck(userAccount);
|
||||
final boolean writeGrant = userGrantCheck.w();
|
||||
final boolean modifyGrant = userGrantCheck.m();
|
||||
// modifying an UserAccount is not possible if the root institution is inactive
|
||||
final boolean istitutionActive = this.restService.getBuilder(GetInstitution.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(userAccount.getInstitutionId()))
|
||||
|
@ -190,26 +190,26 @@ public class UserAccountForm implements TemplateComposer {
|
|||
|
||||
// propagate content actions to action-pane
|
||||
|
||||
formContext.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.resetEntity()
|
||||
.withExec(UserAccountActions::newUserAccount)
|
||||
formContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY)
|
||||
.withExec(UserAccountActions::editUserAccount)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && readonly && istitutionActive)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD)
|
||||
.withEntity(userAccount.getEntityKey())
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && readonly && istitutionActive && userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
|
||||
.withExec(UserAccountActions::deactivateUserAccount)
|
||||
.withExec(Action.activation(this.restService, false))
|
||||
.withConfirm(PageUtils.confirmDeactivation(userAccount, this.restService))
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
|
||||
.withExec(UserAccountActions::activateUserAccount)
|
||||
.withExec(Action.activation(this.restService, true))
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && !userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_SAVE)
|
||||
|
@ -224,7 +224,7 @@ public class UserAccountForm implements TemplateComposer {
|
|||
.publishIf(() -> !readonly)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
||||
.withExec(UserAccountActions::cancelEditUserAccount)
|
||||
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
|
||||
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
||||
.publishIf(() -> !readonly);
|
||||
}
|
||||
|
|
|
@ -14,18 +14,18 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.UserAccountActions;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||
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;
|
||||
|
@ -97,17 +97,19 @@ public class UserAccountList implements TemplateComposer {
|
|||
.compose(content);
|
||||
|
||||
// propagate content actions to action-pane
|
||||
pageContext.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.withExec(UserAccountActions::newUserAccount)
|
||||
.publishIf(() -> this.currentUser.hasInstitutionalPrivilege(PrivilegeType.WRITE, EntityType.USER))
|
||||
final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER);
|
||||
pageContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.publishIf(userGrant::w)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_VIEW)
|
||||
.withSelectionSupplier(table::getSelection)
|
||||
.withExec(UserAccountActions::viewUserAccountFromList)
|
||||
.withSelect(table::getSelection, Action.applySingleSelection("sebserver.useraccount.info.pleaseSelect"))
|
||||
.publish()
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
|
||||
.withSelectionSupplier(table::getSelection)
|
||||
.withExec(UserAccountActions::editUserAccountFromList)
|
||||
.publishIf(() -> this.currentUser.hasInstitutionalPrivilege(PrivilegeType.MODIFY, EntityType.USER));
|
||||
.withSelect(table::getSelection, Action.applySingleSelection("sebserver.useraccount.info.pleaseSelect"))
|
||||
.publishIf(userGrant::m);
|
||||
}
|
||||
|
||||
private String getLocaleDisplayText(final UserInfo userInfo) {
|
||||
|
|
|
@ -30,7 +30,7 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.institution.action.new"),
|
||||
ImageIcon.NEW,
|
||||
InstitutionForm.class,
|
||||
INSTITUTION_VIEW_LIST),
|
||||
INSTITUTION_VIEW_LIST, false),
|
||||
INSTITUTION_VIEW_FROM_LIST(
|
||||
new LocTextKey("sebserver.institution.action.list.view"),
|
||||
ImageIcon.SHOW,
|
||||
|
@ -41,13 +41,13 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.institution.action.list.modify"),
|
||||
ImageIcon.EDIT,
|
||||
InstitutionForm.class,
|
||||
INSTITUTION_VIEW_LIST),
|
||||
INSTITUTION_VIEW_LIST, false),
|
||||
|
||||
INSTITUTION_MODIFY(
|
||||
new LocTextKey("sebserver.institution.action.modify"),
|
||||
ImageIcon.EDIT,
|
||||
InstitutionForm.class,
|
||||
INSTITUTION_VIEW_LIST),
|
||||
INSTITUTION_VIEW_LIST, false),
|
||||
|
||||
INSTITUTION_CANCEL_MODIFY(
|
||||
new LocTextKey("sebserver.overall.action.modify.cancel"),
|
||||
|
@ -90,7 +90,7 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.useraccount.action.new"),
|
||||
ImageIcon.NEW,
|
||||
UserAccountForm.class,
|
||||
USER_ACCOUNT_VIEW_LIST),
|
||||
USER_ACCOUNT_VIEW_LIST, false),
|
||||
|
||||
USER_ACCOUNT_VIEW(
|
||||
new LocTextKey("sebserver.useraccount.action.view"),
|
||||
|
@ -102,13 +102,13 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.useraccount.action.list.modify"),
|
||||
ImageIcon.EDIT,
|
||||
UserAccountForm.class,
|
||||
USER_ACCOUNT_VIEW_LIST),
|
||||
USER_ACCOUNT_VIEW_LIST, false),
|
||||
|
||||
USER_ACCOUNT_MODIFY(
|
||||
new LocTextKey("sebserver.useraccount.action.modify"),
|
||||
ImageIcon.EDIT,
|
||||
UserAccountForm.class,
|
||||
USER_ACCOUNT_VIEW_LIST),
|
||||
USER_ACCOUNT_VIEW_LIST, false),
|
||||
|
||||
USER_ACCOUNT_CANCEL_MODIFY(
|
||||
new LocTextKey("sebserver.overall.action.modify.cancel"),
|
||||
|
@ -144,7 +144,7 @@ public enum ActionDefinition {
|
|||
new LocTextKey("sebserver.useraccount.action.change.password"),
|
||||
ImageIcon.EDIT,
|
||||
UserAccountChangePasswordForm.class,
|
||||
USER_ACCOUNT_VIEW_LIST),
|
||||
USER_ACCOUNT_VIEW_LIST, false),
|
||||
USER_ACCOUNT_CHANGE_PASSOWRD_SAVE(
|
||||
new LocTextKey("sebserver.useraccount.action.change.password.save"),
|
||||
ImageIcon.SAVE,
|
||||
|
@ -158,6 +158,7 @@ public enum ActionDefinition {
|
|||
public final Class<? extends TemplateComposer> contentPaneComposer;
|
||||
public final Class<? extends TemplateComposer> actionPaneComposer;
|
||||
public final ActionDefinition activityAlias;
|
||||
public final boolean readonly;
|
||||
|
||||
private ActionDefinition(
|
||||
final LocTextKey title,
|
||||
|
@ -168,6 +169,7 @@ public enum ActionDefinition {
|
|||
this.contentPaneComposer = contentPaneComposer;
|
||||
this.actionPaneComposer = ActionPane.class;
|
||||
this.activityAlias = null;
|
||||
this.readonly = true;
|
||||
}
|
||||
|
||||
private ActionDefinition(
|
||||
|
@ -180,6 +182,7 @@ public enum ActionDefinition {
|
|||
this.contentPaneComposer = contentPaneComposer;
|
||||
this.actionPaneComposer = ActionPane.class;
|
||||
this.activityAlias = activityAlias;
|
||||
this.readonly = true;
|
||||
}
|
||||
|
||||
private ActionDefinition(
|
||||
|
@ -193,20 +196,22 @@ public enum ActionDefinition {
|
|||
this.contentPaneComposer = contentPaneComposer;
|
||||
this.actionPaneComposer = ActionPane.class;
|
||||
this.activityAlias = activityAlias;
|
||||
this.readonly = true;
|
||||
}
|
||||
|
||||
private ActionDefinition(
|
||||
final LocTextKey title,
|
||||
final ImageIcon icon,
|
||||
final Class<? extends TemplateComposer> contentPaneComposer,
|
||||
final Class<? extends TemplateComposer> actionPaneComposer,
|
||||
final ActionDefinition activityAlias) {
|
||||
final ActionDefinition activityAlias,
|
||||
final boolean readonly) {
|
||||
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.contentPaneComposer = contentPaneComposer;
|
||||
this.actionPaneComposer = actionPaneComposer;
|
||||
this.actionPaneComposer = ActionPane.class;
|
||||
this.activityAlias = activityAlias;
|
||||
this.readonly = readonly;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gui.content.action;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
||||
|
||||
/** Defines the action execution functions for all Institution action. */
|
||||
public final class InstitutionActions {
|
||||
|
||||
public static Action viewInstitutionFromList(final Action action) {
|
||||
return fromSelection(action, false);
|
||||
}
|
||||
|
||||
public static Action editInstitutionFromList(final Action action) {
|
||||
return fromSelection(action, true);
|
||||
}
|
||||
|
||||
public static Action editInstitution(final Action action) {
|
||||
return goToInstitution(action, null, true);
|
||||
}
|
||||
|
||||
public static Action cancelEditInstitution(final Action action) {
|
||||
if (action.getEntityKey() == null) {
|
||||
final PageContext pageContext = action.pageContext();
|
||||
final Action toList = pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_LIST);
|
||||
pageContext.publishPageEvent(new ActionEvent(toList, false));
|
||||
return toList;
|
||||
} else {
|
||||
return goToInstitution(action, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static Action activateInstitution(final Action action) {
|
||||
return action.restService
|
||||
.getBuilder(ActivateInstitution.class)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.map(report -> goToInstitution(action, report.getSingleSource().modelId, false))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
public static Action deactivateInstitution(final Action action) {
|
||||
return action.restService
|
||||
.getBuilder(DeactivateInstitution.class)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.map(report -> goToInstitution(action, report.getSingleSource().modelId, false))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private static Action fromSelection(final Action action, final boolean edit) {
|
||||
final Collection<String> selection = action.getSelectionSupplier().get();
|
||||
if (selection.isEmpty()) {
|
||||
throw new PageMessageException("sebserver.institution.info.pleaseSelect");
|
||||
}
|
||||
|
||||
return goToInstitution(action, selection.iterator().next(), edit);
|
||||
}
|
||||
|
||||
private static Action goToInstitution(
|
||||
final Action action,
|
||||
final String modelId,
|
||||
final boolean edit) {
|
||||
|
||||
action.withAttribute(AttributeKeys.READ_ONLY, String.valueOf(!edit));
|
||||
if (modelId != null) {
|
||||
action.withEntity(new EntityKey(modelId, EntityType.INSTITUTION));
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,88 +8,54 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.content.action;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
|
||||
|
||||
public final class UserAccountActions {
|
||||
|
||||
public static Action newUserAccount(final Action action) {
|
||||
return goToUserAccount(action, null, true);
|
||||
}
|
||||
|
||||
public static Action viewUserAccountFromList(final Action action) {
|
||||
return fromSelection(action, false);
|
||||
}
|
||||
|
||||
public static Action editUserAccountFromList(final Action action) {
|
||||
return fromSelection(action, true);
|
||||
}
|
||||
|
||||
public static Action editUserAccount(final Action action) {
|
||||
return goToUserAccount(action, null, true);
|
||||
}
|
||||
|
||||
public static Action cancelEditUserAccount(final Action action) {
|
||||
if (action.pageContext().getEntityKey() == null) {
|
||||
final Action toList = action.pageContext().createAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST);
|
||||
action.pageContext().publishPageEvent(new ActionEvent(toList, false));
|
||||
return toList;
|
||||
} else {
|
||||
return goToUserAccount(action, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static Action activateUserAccount(final Action action) {
|
||||
return action.restService
|
||||
.getBuilder(ActivateUserAccount.class)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.map(report -> goToUserAccount(action, report.getSingleSource().modelId, false))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
public static Action deactivateUserAccount(final Action action) {
|
||||
return action.restService
|
||||
.getBuilder(DeactivateUserAccount.class)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.map(report -> goToUserAccount(action, report.getSingleSource().modelId, false))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private static Action fromSelection(final Action action, final boolean edit) {
|
||||
final Collection<String> selection = action.getSelectionSupplier().get();
|
||||
if (selection.isEmpty()) {
|
||||
throw new PageMessageException("sebserver.useraccount.info.pleaseSelect");
|
||||
}
|
||||
|
||||
return goToUserAccount(action, selection.iterator().next(), edit);
|
||||
}
|
||||
|
||||
private static Action goToUserAccount(
|
||||
final Action action,
|
||||
final String modelId,
|
||||
final boolean edit) {
|
||||
|
||||
action.withAttribute(AttributeKeys.READ_ONLY, String.valueOf(!edit));
|
||||
if (modelId != null) {
|
||||
action.withEntity(new EntityKey(modelId, EntityType.USER));
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
// public static Action newUserAccount(final Action action) {
|
||||
// return goToUserAccount(action, null, true);
|
||||
// }
|
||||
//
|
||||
// public static Action viewUserAccountFromList(final Action action) {
|
||||
// return fromSelection(action, false);
|
||||
// }
|
||||
//
|
||||
// public static Action editUserAccountFromList(final Action action) {
|
||||
// return fromSelection(action, true);
|
||||
// }
|
||||
//
|
||||
// public static Action editUserAccount(final Action action) {
|
||||
// return goToUserAccount(action, null, true);
|
||||
// }
|
||||
//
|
||||
// public static Action cancelEditUserAccount(final Action action) {
|
||||
// if (action.pageContext().getEntityKey() == null) {
|
||||
// final Action toList = action.pageContext().createAction(ActionDefinition.USER_ACCOUNT_VIEW_LIST);
|
||||
// action.pageContext().publishPageEvent(new ActionEvent(toList, false));
|
||||
// return toList;
|
||||
// } else {
|
||||
// return goToUserAccount(action, null, false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static Action fromSelection(final Action action, final boolean edit) {
|
||||
// final Collection<String> selection = action.getSelectionSupplier().get();
|
||||
// if (selection.isEmpty()) {
|
||||
// throw new PageMessageException("sebserver.useraccount.info.pleaseSelect");
|
||||
// }
|
||||
//
|
||||
// return goToUserAccount(action, selection.iterator().next(), edit);
|
||||
// }
|
||||
//
|
||||
// private static Action goToUserAccount(
|
||||
// final Action action,
|
||||
// final String modelId,
|
||||
// final boolean edit) {
|
||||
//
|
||||
// action.withAttribute(AttributeKeys.READ_ONLY, String.valueOf(!edit));
|
||||
// if (modelId != null) {
|
||||
// action.withEntity(new EntityKey(modelId, EntityType.USER));
|
||||
// }
|
||||
//
|
||||
// return action;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class ActivitiesPane implements TemplateComposer {
|
|||
injectActivitySelection(
|
||||
institutions,
|
||||
pageContext.createAction(ActionDefinition.INSTITUTION_VIEW_FORM)
|
||||
.withEntity(userInfo.institutionId, EntityType.INSTITUTION)
|
||||
.withEntityKey(userInfo.institutionId, EntityType.INSTITUTION)
|
||||
.withAttribute(AttributeKeys.READ_ONLY, "true"));
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class ActivitiesPane implements TemplateComposer {
|
|||
injectActivitySelection(
|
||||
userAccounts,
|
||||
pageContext.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FORM)
|
||||
.withEntity(this.currentUser.get().getEntityKey())
|
||||
.withEntityKey(this.currentUser.get().getEntityKey())
|
||||
.withAttribute(AttributeKeys.READ_ONLY, "true"));
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public class FormHandle<T extends Entity> {
|
|||
.map(result -> {
|
||||
final Action action = this.pageContext.createAction(actionDefinition)
|
||||
.withAttribute(AttributeKeys.READ_ONLY, "true")
|
||||
.withEntity(result.getEntityKey());
|
||||
.withEntityKey(result.getEntityKey());
|
||||
this.pageContext.publishPageEvent(new ActionEvent(action, false));
|
||||
return action;
|
||||
})
|
||||
|
|
|
@ -131,6 +131,11 @@ public interface PageContext {
|
|||
* @return the new PageContext with the EntityKey added */
|
||||
PageContext withParentEntityKey(EntityKey entityKey);
|
||||
|
||||
/** Create a copy of this PageContext and resets both entity keys attributes, the base and the parent EntityKey
|
||||
*
|
||||
* @return copy of this PageContext with reseted EntityKey attributes (base and parent) */
|
||||
PageContext clearEntityKeys();
|
||||
|
||||
/** Indicates if an attribute with the specified name exists within this PageContext
|
||||
*
|
||||
* @param name the name of the attribute
|
||||
|
@ -205,4 +210,5 @@ public interface PageContext {
|
|||
*
|
||||
* @param pme the PageMessageException */
|
||||
void publishPageMessage(PageMessageException pme);
|
||||
|
||||
}
|
||||
|
|
|
@ -13,9 +13,11 @@ import java.util.function.BooleanSupplier;
|
|||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
|
@ -27,18 +29,19 @@ import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
|
||||
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.ActivateInstitution;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
||||
|
||||
public final class Action implements Runnable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Action.class);
|
||||
|
||||
public final RestService restService;
|
||||
public final ActionDefinition definition;
|
||||
Supplier<LocTextKey> confirm;
|
||||
LocTextKey successMessage;
|
||||
boolean updateOnSelection;
|
||||
|
||||
Supplier<Set<String>> selectionSupplier;
|
||||
Supplier<Set<EntityKey>> selectionSupplier;
|
||||
|
||||
private final PageContext originalPageContext;
|
||||
private PageContext pageContext;
|
||||
|
@ -46,13 +49,13 @@ public final class Action implements Runnable {
|
|||
|
||||
public Action(
|
||||
final ActionDefinition definition,
|
||||
final PageContext pageContext,
|
||||
final RestService restService) {
|
||||
final PageContext pageContext) {
|
||||
|
||||
this.definition = definition;
|
||||
this.originalPageContext = pageContext;
|
||||
this.pageContext = pageContext;
|
||||
this.restService = restService;
|
||||
this.pageContext = pageContext.withAttribute(
|
||||
AttributeKeys.READ_ONLY,
|
||||
String.valueOf(definition.readonly));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,7 +73,8 @@ public final class Action implements Runnable {
|
|||
private void exec() {
|
||||
try {
|
||||
|
||||
this.pageContext.publishPageEvent(new ActionEvent(this.exec.apply(this), false));
|
||||
final Action executedAction = this.exec.apply(this);
|
||||
this.pageContext.publishPageEvent(new ActionEvent(executedAction, false));
|
||||
|
||||
} catch (final PageMessageException pme) {
|
||||
Action.this.pageContext.publishPageMessage(pme);
|
||||
|
@ -90,20 +94,22 @@ public final class Action implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
public Supplier<Set<String>> getSelectionSupplier() {
|
||||
return this.selectionSupplier;
|
||||
}
|
||||
|
||||
public Action withExec(final Function<Action, Action> exec) {
|
||||
this.exec = exec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action withSelectionSupplier(final Supplier<Set<String>> selectionSupplier) {
|
||||
public Action withSelectionSupplier(final Supplier<Set<EntityKey>> selectionSupplier) {
|
||||
this.selectionSupplier = selectionSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action withSelect(final Supplier<Set<EntityKey>> selectionSupplier, final Function<Action, Action> exec) {
|
||||
this.selectionSupplier = selectionSupplier;
|
||||
this.exec = exec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action withConfirm(final String confirmationMessageKey) {
|
||||
this.confirm = () -> new LocTextKey(confirmationMessageKey);
|
||||
return this;
|
||||
|
@ -124,12 +130,12 @@ public final class Action implements Runnable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Action resetEntity() {
|
||||
public Action resetEntityKey() {
|
||||
this.pageContext = this.pageContext.withEntityKey(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action resetParentEntity() {
|
||||
public Action resetParentEntityKey() {
|
||||
this.pageContext = this.pageContext.withParentEntityKey(null);
|
||||
return this;
|
||||
}
|
||||
|
@ -142,20 +148,20 @@ public final class Action implements Runnable {
|
|||
return this.pageContext;
|
||||
}
|
||||
|
||||
public Action withEntity(final EntityKey entityKey) {
|
||||
public Action withEntityKey(final EntityKey entityKey) {
|
||||
this.pageContext = this.pageContext.withEntityKey(entityKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action withEntity(final Long modelId, final EntityType entityType) {
|
||||
public Action withEntityKey(final Long modelId, final EntityType entityType) {
|
||||
if (modelId != null) {
|
||||
return withEntity(String.valueOf(modelId), entityType);
|
||||
return withEntityKey(String.valueOf(modelId), entityType);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Action withEntity(final String modelId, final EntityType entityType) {
|
||||
public Action withEntityKey(final String modelId, final EntityType entityType) {
|
||||
if (modelId == null || entityType == null) {
|
||||
return this;
|
||||
}
|
||||
|
@ -164,7 +170,7 @@ public final class Action implements Runnable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Action withParentEntity(final EntityKey entityKey) {
|
||||
public Action withParentEntityKey(final EntityKey entityKey) {
|
||||
this.pageContext = this.pageContext.withParentEntityKey(entityKey);
|
||||
return this;
|
||||
}
|
||||
|
@ -187,8 +193,60 @@ public final class Action implements Runnable {
|
|||
return this.originalPageContext;
|
||||
}
|
||||
|
||||
public Action readonly(final boolean b) {
|
||||
return this.withAttribute(AttributeKeys.READ_ONLY, "false");
|
||||
public EntityKey getSingleSelection(final String messageOnEmptySelection) {
|
||||
final Set<EntityKey> selection = getMultiSelection(messageOnEmptySelection);
|
||||
if (selection != null) {
|
||||
return selection.iterator().next();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<EntityKey> getMultiSelection(final String messageOnEmptySelection) {
|
||||
if (this.selectionSupplier != null) {
|
||||
final Set<EntityKey> selection = this.selectionSupplier.get();
|
||||
if (selection.isEmpty()) {
|
||||
if (StringUtils.isNoneBlank(messageOnEmptySelection)) {
|
||||
throw new PageMessageException(messageOnEmptySelection);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
if (StringUtils.isNoneBlank(messageOnEmptySelection)) {
|
||||
throw new PageMessageException(messageOnEmptySelection);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Function<Action, Action> applySingleSelection(final String messageOnEmptySelection) {
|
||||
return action -> action.withEntityKey(action.getSingleSelection(messageOnEmptySelection));
|
||||
}
|
||||
|
||||
public static Function<Action, Action> activation(final RestService restService, final boolean activate) {
|
||||
return action -> restService
|
||||
.getBuilder((activate) ? ActivateInstitution.class : DeactivateInstitution.class)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.map(report -> action)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
public static Action onEmptyEntityKeyGoToActivityHome(final Action action) {
|
||||
if (action.getEntityKey() == null) {
|
||||
final PageContext pageContext = action.pageContext();
|
||||
final Action activityHomeAction = pageContext.createAction(action.definition.activityAlias);
|
||||
action.pageContext.publishPageEvent(new ActionEvent(activityHomeAction, false));
|
||||
return activityHomeAction;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ 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.PageDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
|
@ -41,20 +40,17 @@ public class ComposerServiceImpl implements ComposerService {
|
|||
private final Class<? extends PageDefinition> mainPageType = DefaultMainPage.class;
|
||||
|
||||
final AuthorizationContextHolder authorizationContextHolder;
|
||||
private final RestService restService;
|
||||
private final I18nSupport i18nSupport;
|
||||
private final Map<String, TemplateComposer> composer;
|
||||
private final Map<String, PageDefinition> pages;
|
||||
|
||||
public ComposerServiceImpl(
|
||||
final AuthorizationContextHolder authorizationContextHolder,
|
||||
final RestService restService,
|
||||
final I18nSupport i18nSupport,
|
||||
final Collection<TemplateComposer> composer,
|
||||
final Collection<PageDefinition> pageDefinitions) {
|
||||
|
||||
this.authorizationContextHolder = authorizationContextHolder;
|
||||
this.restService = restService;
|
||||
this.i18nSupport = i18nSupport;
|
||||
this.composer = composer
|
||||
.stream()
|
||||
|
@ -178,7 +174,7 @@ public class ComposerServiceImpl implements ComposerService {
|
|||
}
|
||||
|
||||
private PageContext createPageContext(final Composite root) {
|
||||
return new PageContextImpl(this.restService, this.i18nSupport, this, root, root, null);
|
||||
return new PageContextImpl(this.i18nSupport, this, root, root, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
|||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||
|
||||
public class PageContextImpl implements PageContext {
|
||||
|
@ -47,7 +46,6 @@ public class PageContextImpl implements PageContext {
|
|||
|
||||
private static final ListenerComparator LIST_COMPARATOR = new ListenerComparator();
|
||||
|
||||
private final RestService restService;
|
||||
private final I18nSupport i18nSupport;
|
||||
private final ComposerService composerService;
|
||||
private final Composite root;
|
||||
|
@ -55,14 +53,12 @@ public class PageContextImpl implements PageContext {
|
|||
private final Map<String, String> attributes;
|
||||
|
||||
PageContextImpl(
|
||||
final RestService restService,
|
||||
final I18nSupport i18nSupport,
|
||||
final ComposerService composerService,
|
||||
final Composite root,
|
||||
final Composite parent,
|
||||
final Map<String, String> attributes) {
|
||||
|
||||
this.restService = restService;
|
||||
this.i18nSupport = i18nSupport;
|
||||
this.composerService = composerService;
|
||||
this.root = root;
|
||||
|
@ -102,7 +98,6 @@ public class PageContextImpl implements PageContext {
|
|||
@Override
|
||||
public PageContext copyOf(final Composite parent) {
|
||||
return new PageContextImpl(
|
||||
this.restService,
|
||||
this.i18nSupport,
|
||||
this.composerService,
|
||||
this.root,
|
||||
|
@ -116,7 +111,6 @@ public class PageContextImpl implements PageContext {
|
|||
attrs.putAll(this.attributes);
|
||||
attrs.putAll(((PageContextImpl) otherContext).attributes);
|
||||
return new PageContextImpl(
|
||||
this.restService,
|
||||
this.i18nSupport,
|
||||
this.composerService,
|
||||
this.root,
|
||||
|
@ -130,7 +124,6 @@ public class PageContextImpl implements PageContext {
|
|||
attrs.putAll(this.attributes);
|
||||
attrs.put(key, value);
|
||||
return new PageContextImpl(
|
||||
this.restService,
|
||||
this.i18nSupport,
|
||||
this.composerService,
|
||||
this.root,
|
||||
|
@ -199,6 +192,12 @@ public class PageContextImpl implements PageContext {
|
|||
.withAttribute(AttributeKeys.PARENT_ENTITY_TYPE, entityKey.entityType.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageContext clearEntityKeys() {
|
||||
return withEntityKey(null)
|
||||
.withParentEntityKey(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttribute(final String name) {
|
||||
return this.attributes.containsKey(name);
|
||||
|
@ -210,7 +209,6 @@ public class PageContextImpl implements PageContext {
|
|||
attrs.putAll(this.attributes);
|
||||
attrs.remove(name);
|
||||
return new PageContextImpl(
|
||||
this.restService,
|
||||
this.i18nSupport,
|
||||
this.composerService,
|
||||
this.root,
|
||||
|
@ -243,7 +241,7 @@ public class PageContextImpl implements PageContext {
|
|||
|
||||
@Override
|
||||
public Action createAction(final ActionDefinition actionDefinition) {
|
||||
return new Action(actionDefinition, this, this.restService);
|
||||
return new Action(actionDefinition, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,6 +74,14 @@ public class CurrentUser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public GrantCheck grantCheck(final EntityType entityType) {
|
||||
return new GrantCheck(entityType);
|
||||
}
|
||||
|
||||
public EntityGrantCheck entityGrantCheck(final GrantEntity grantEntity) {
|
||||
return new EntityGrantCheck(grantEntity);
|
||||
}
|
||||
|
||||
public boolean hasBasePrivilege(final PrivilegeType privilegeType, final EntityType entityType) {
|
||||
return hasPrivilege(privilegeType, entityType, null, null);
|
||||
}
|
||||
|
@ -206,4 +214,85 @@ public class CurrentUser {
|
|||
}
|
||||
}
|
||||
|
||||
/** Wrapper can be used for base and institutional grant checks for a specified EntityType */
|
||||
public class GrantCheck {
|
||||
private final EntityType entityType;
|
||||
|
||||
protected GrantCheck(final EntityType entityType) {
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
/** Checks the base read-only privilege grant
|
||||
*
|
||||
* @return true on read-only privilege grant on wrapped EntityType */
|
||||
public boolean r() {
|
||||
return hasBasePrivilege(PrivilegeType.READ_ONLY, this.entityType);
|
||||
}
|
||||
|
||||
/** Checks the base modify privilege grant
|
||||
*
|
||||
* @return true on modify privilege grant on wrapped EntityType */
|
||||
public boolean m() {
|
||||
return hasBasePrivilege(PrivilegeType.MODIFY, this.entityType);
|
||||
}
|
||||
|
||||
/** Checks the base write privilege grant
|
||||
*
|
||||
* @return true on write privilege grant on wrapped EntityType */
|
||||
public boolean w() {
|
||||
return hasBasePrivilege(PrivilegeType.WRITE, this.entityType);
|
||||
}
|
||||
|
||||
/** Checks the institutional read-only privilege grant
|
||||
*
|
||||
* @return true institutional read-only privilege grant on wrapped EntityType */
|
||||
public boolean ir() {
|
||||
return hasInstitutionalPrivilege(PrivilegeType.READ_ONLY, this.entityType);
|
||||
}
|
||||
|
||||
/** Checks the institutional modify privilege grant
|
||||
*
|
||||
* @return true institutional modify privilege grant on wrapped EntityType */
|
||||
public boolean im() {
|
||||
return hasInstitutionalPrivilege(PrivilegeType.MODIFY, this.entityType);
|
||||
}
|
||||
|
||||
/** Checks the institutional write privilege grant
|
||||
*
|
||||
* @return true institutional write privilege grant on wrapped EntityType */
|
||||
public boolean iw() {
|
||||
return hasInstitutionalPrivilege(PrivilegeType.WRITE, this.entityType);
|
||||
}
|
||||
}
|
||||
|
||||
/** Wrapper can be used for Entity based grant checks */
|
||||
public class EntityGrantCheck {
|
||||
private final GrantEntity grantEntity;
|
||||
|
||||
protected EntityGrantCheck(final GrantEntity grantEntity) {
|
||||
this.grantEntity = grantEntity;
|
||||
}
|
||||
|
||||
/** Checks the read-only privilege grant for wrapped grantEntity
|
||||
*
|
||||
* @return true on read-only privilege grant for wrapped grantEntity */
|
||||
public boolean r() {
|
||||
return hasPrivilege(PrivilegeType.READ_ONLY, this.grantEntity);
|
||||
}
|
||||
|
||||
/** Checks the modify privilege grant for wrapped grantEntity
|
||||
*
|
||||
* @return true on modify privilege grant for wrapped grantEntity */
|
||||
public boolean m() {
|
||||
return hasPrivilege(PrivilegeType.MODIFY, this.grantEntity);
|
||||
}
|
||||
|
||||
/** Checks the write privilege grant for wrapped grantEntity
|
||||
*
|
||||
* @return true on write privilege grant for wrapped grantEntity */
|
||||
public boolean w() {
|
||||
return hasPrivilege(PrivilegeType.WRITE, this.grantEntity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
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.util.Utils;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
@ -174,7 +175,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
this.sortOrder);
|
||||
}
|
||||
|
||||
public String getSingleSelection() {
|
||||
public EntityKey getSingleSelection() {
|
||||
final TableItem[] selection = this.table.getSelection();
|
||||
if (selection == null || selection.length == 0) {
|
||||
return null;
|
||||
|
@ -183,7 +184,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
return getRowDataId(selection[0]);
|
||||
}
|
||||
|
||||
public Set<String> getSelection() {
|
||||
public Set<EntityKey> getSelection() {
|
||||
final TableItem[] selection = this.table.getSelection();
|
||||
if (selection == null) {
|
||||
return Collections.emptySet();
|
||||
|
@ -348,8 +349,8 @@ public class EntityTable<ROW extends Entity> {
|
|||
return (ROW) item.getData(TABLE_ROW_DATA);
|
||||
}
|
||||
|
||||
private String getRowDataId(final TableItem item) {
|
||||
return getRowData(item).getModelId();
|
||||
private EntityKey getRowDataId(final TableItem item) {
|
||||
return getRowData(item).getEntityKey();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ public class TableBuilder<ROW extends Entity> {
|
|||
|
||||
private final WidgetFactory widgetFactory;
|
||||
final RestCall<Page<ROW>> restCall;
|
||||
// final List<TableFilterAttribute> filter = new ArrayList<>();
|
||||
final List<ColumnDefinition<ROW>> columns = new ArrayList<>();
|
||||
final List<TableRowAction> actions = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.io.InputStream;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
|
@ -48,7 +47,6 @@ import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
|||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||
import ch.ethz.seb.sebserver.gui.service.push.ServerPushService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
|
||||
|
@ -155,16 +153,11 @@ public class WidgetFactory {
|
|||
public Composite defaultPageLayout(
|
||||
final Composite parent,
|
||||
final LocTextKey title,
|
||||
final ActionDefinition actionDefinition,
|
||||
final Function<Label, Consumer<ActionEvent>> eventFunction) {
|
||||
final ActionDefinition actionDefinition) {
|
||||
|
||||
final Composite defaultPageLayout = defaultPageLayout(parent);
|
||||
final Label labelLocalizedTitle = labelLocalizedTitle(defaultPageLayout, title);
|
||||
labelLocalizedTitle.setLayoutData(new GridData(SWT.TOP, SWT.LEFT, true, false));
|
||||
// ActionEventListener.injectListener(
|
||||
// labelLocalizedTitle,
|
||||
// actionDefinition,
|
||||
// eventFunction.apply(labelLocalizedTitle));
|
||||
return defaultPageLayout;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Page<T> getAll(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
|
@ -126,7 +126,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
path = API.NAMES_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Collection<EntityName> getNames(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
|
@ -160,7 +160,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
path = API.MODEL_ID_VAR_PATH_SEGMENT + API.DEPENDENCY_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Collection<EntityKey> getDependencies(
|
||||
@PathVariable final String modelId,
|
||||
@RequestParam(API.PARAM_BULK_ACTION_TYPE) final BulkActionType bulkActionType) {
|
||||
|
@ -186,7 +186,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
path = API.MODEL_ID_VAR_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public T getBy(@PathVariable final String modelId) {
|
||||
|
||||
return this.entityDAO
|
||||
|
@ -203,7 +203,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
path = API.LIST_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Collection<T> getForIds(@RequestParam(name = "ids", required = true) final String ids) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
|
@ -228,7 +228,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
@RequestMapping(
|
||||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public T create(
|
||||
@RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||
@RequestParam(
|
||||
|
@ -261,8 +261,8 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.PUT,
|
||||
consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public T savePut(@Valid @RequestBody final T modifyData) {
|
||||
|
||||
return this.authorization.checkModify(modifyData)
|
||||
|
@ -309,7 +309,7 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
@RequestMapping(
|
||||
path = "/{modelId}",
|
||||
method = RequestMethod.DELETE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public EntityProcessingReport hardDelete(@PathVariable final String modelId) {
|
||||
final EntityType entityType = this.entityDAO.entityType();
|
||||
final BulkAction bulkAction = new BulkAction(
|
||||
|
|
|
@ -12,13 +12,19 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
|
||||
public class InstitutionTest {
|
||||
|
||||
|
@ -33,4 +39,60 @@ public class InstitutionTest {
|
|||
assertEquals("ETH Zürich", inst.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pageOfInstituions() throws Exception {
|
||||
final Page<Institution> page = new Page<>(2, 1, "name", Arrays.asList(
|
||||
new Institution(1L, "InstOne", "one", "", true),
|
||||
new Institution(2L, "InstTwo", "two", "", true),
|
||||
new Institution(3L, "InstThree", "three", "", true)));
|
||||
|
||||
final JSONMapper jsonMapper = new JSONMapper();
|
||||
final ObjectWriter writerWithDefaultPrettyPrinter = jsonMapper.writerWithDefaultPrettyPrinter();
|
||||
String json = writerWithDefaultPrettyPrinter.writeValueAsString(page);
|
||||
assertEquals("{\r\n" +
|
||||
" \"number_of_pages\" : 2,\r\n" +
|
||||
" \"page_number\" : 1,\r\n" +
|
||||
" \"sort\" : \"name\",\r\n" +
|
||||
" \"content\" : [ {\r\n" +
|
||||
" \"id\" : 1,\r\n" +
|
||||
" \"name\" : \"InstOne\",\r\n" +
|
||||
" \"urlSuffix\" : \"one\",\r\n" +
|
||||
" \"logoImage\" : \"\",\r\n" +
|
||||
" \"active\" : true\r\n" +
|
||||
" }, {\r\n" +
|
||||
" \"id\" : 2,\r\n" +
|
||||
" \"name\" : \"InstTwo\",\r\n" +
|
||||
" \"urlSuffix\" : \"two\",\r\n" +
|
||||
" \"logoImage\" : \"\",\r\n" +
|
||||
" \"active\" : true\r\n" +
|
||||
" }, {\r\n" +
|
||||
" \"id\" : 3,\r\n" +
|
||||
" \"name\" : \"InstThree\",\r\n" +
|
||||
" \"urlSuffix\" : \"three\",\r\n" +
|
||||
" \"logoImage\" : \"\",\r\n" +
|
||||
" \"active\" : true\r\n" +
|
||||
" } ],\r\n" +
|
||||
" \"page_size\" : 3\r\n" +
|
||||
"}", json);
|
||||
|
||||
final List<EntityName> namesList = page.content.stream()
|
||||
.map(inst -> new EntityName(inst.getEntityKey(), inst.name))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
json = writerWithDefaultPrettyPrinter.writeValueAsString(namesList);
|
||||
assertEquals("[ {\r\n" +
|
||||
" \"entityType\" : \"INSTITUTION\",\r\n" +
|
||||
" \"modelId\" : \"1\",\r\n" +
|
||||
" \"name\" : \"InstOne\"\r\n" +
|
||||
"}, {\r\n" +
|
||||
" \"entityType\" : \"INSTITUTION\",\r\n" +
|
||||
" \"modelId\" : \"2\",\r\n" +
|
||||
" \"name\" : \"InstTwo\"\r\n" +
|
||||
"}, {\r\n" +
|
||||
" \"entityType\" : \"INSTITUTION\",\r\n" +
|
||||
" \"modelId\" : \"3\",\r\n" +
|
||||
" \"name\" : \"InstThree\"\r\n" +
|
||||
"} ]", json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue