You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/05/26 11:55:09 UTC
[syncope] 04/04: Further Console extendability improvements
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 382738527a32c01907f01982097c996dd672f14d
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Thu May 26 13:22:41 2022 +0200
Further Console extendability improvements
---
.../client/console/panels/RealmChoicePanel.java | 72 ++++++++----
.../client/console/widgets/NumberWidget.java | 22 ++--
.../syncope/client/console/wizards/any/Groups.java | 70 ++++++------
.../client/console/wizards/any/Relationships.java | 123 ++++++++++++---------
.../client/console/panels/RealmChoicePanel.html | 6 +-
.../apache/syncope/fit/console/RealmsITCase.java | 14 ++-
.../reference-guide/usage/customization.adoc | 4 +-
7 files changed, 182 insertions(+), 129 deletions(-)
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index 9313bacd1e..07d30b2ff6 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -47,6 +47,7 @@ import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AbstractAutoCompleteRenderer;
@@ -55,11 +56,11 @@ import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSe
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer;
import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
@@ -91,9 +92,7 @@ public class RealmChoicePanel extends Panel {
protected final boolean isSearchEnabled;
- protected final Label realmDisplayKey;
-
- protected final Label realmDisplayValue;
+ protected final ListView<String> breadcrumb;
public RealmChoicePanel(final String id, final String initialRealm, final PageReference pageRef) {
super(id);
@@ -169,33 +168,60 @@ public class RealmChoicePanel extends Panel {
container = new WebMarkupContainerNoVeil("container", realmTree);
add(container.setOutputMarkupId(true));
- realmDisplayKey = new Label("realmDisplayKey", realmDisplayKeyModel(null));
- container.addOrReplace(realmDisplayKey.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
- realmDisplayValue = new Label("realmDisplayValue", realmDisplayValueText());
- container.addOrReplace(realmDisplayValue.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
+ breadcrumb = new ListView<String>("breadcrumb") {
+
+ private static final long serialVersionUID = -8746795666847966508L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ AjaxLink<Void> bcitem = new AjaxLink<>("bcitem") {
+
+ private static final long serialVersionUID = -817438685948164787L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ RealmRestClient.list(item.getModelObject()).stream().
+ filter(r -> item.getModelObject().equals(r.getFullPath())).
+ findFirst().ifPresent(t -> chooseRealm(t, target));
+ }
+ };
+ bcitem.setBody(Model.of(SyncopeConstants.ROOT_REALM.equals(item.getModelObject())
+ ? SyncopeConstants.ROOT_REALM
+ : StringUtils.substringAfterLast(item.getModelObject(), "/")));
+ bcitem.setEnabled(!model.getObject().getFullPath().equals(item.getModelObject()));
+ item.add(bcitem);
+ }
+ };
+ container.addOrReplace(breadcrumb.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
+ setBreadcrumb(model.getObject());
reloadRealmTree();
}
- protected IModel<String> realmDisplayKeyModel(final Boolean dynamic) {
- return dynamic == null
- ? model.getObject().getFullPath().startsWith(SyncopeConstants.ROOT_REALM)
- ? new ResourceModel("realmDisplayKey", "Realm")
- : new ResourceModel("dynRealmLabel", "Dynamic Realm")
- : dynamic
- ? new ResourceModel("dynRealmLabel", "Dynamic Realm")
- : new ResourceModel("realmDisplayKey", "Realm");
- }
+ protected void setBreadcrumb(final RealmTO realm) {
+ if (SyncopeConstants.ROOT_REALM.equals(realm.getFullPath())) {
+ breadcrumb.setList(List.of(realm.getFullPath()));
+ } else {
+ List<String> bcitems = new ArrayList<>();
+ bcitems.add(SyncopeConstants.ROOT_REALM);
+
+ String[] split = realm.getFullPath().split("/");
+ for (int i = 1; i < split.length; i++) {
+ StringBuilder bcitem = new StringBuilder();
+ for (int j = 1; j <= i; j++) {
+ bcitem.append('/').append(split[j]);
+ }
+ bcitems.add(bcitem.toString());
+ }
- protected String realmDisplayValueText() {
- return RealmsUtils.getFullPath(model.getObject().getFullPath());
+ breadcrumb.setList(bcitems);
+ }
}
protected void chooseRealm(final RealmTO realm, final AjaxRequestTarget target) {
model.setObject(realm);
- realmDisplayValue.setDefaultModelObject(realmDisplayValueText());
- realmDisplayKey.setDefaultModel(realmDisplayKeyModel(false));
- target.add(realmDisplayValue);
+ setBreadcrumb(realm);
+ target.add(container);
send(pageRef.getPage(), Broadcast.EXACT, new ChosenRealm<>(realm, target));
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/NumberWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/NumberWidget.java
index 1f720a6f32..dd6933301d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/NumberWidget.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/NumberWidget.java
@@ -20,6 +20,8 @@ package org.apache.syncope.client.console.widgets;
import java.util.List;
import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.SyncopeWebApplication;
+import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -29,7 +31,6 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.syncope.client.console.pages.Realms;
import org.apache.syncope.client.console.pages.Security;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
-import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.mapper.parameter.PageParameters;
public class NumberWidget extends BaseWidget {
@@ -48,20 +49,27 @@ public class NumberWidget extends BaseWidget {
WebMarkupContainer box = new WebMarkupContainer("card");
box.add(new AttributeAppender("class", ' ' + bg));
+ @SuppressWarnings("unchecked")
+ Class<? extends BasePage> realmsPage =
+ (Class<? extends BasePage>) SyncopeWebApplication.get().getPageClass("realms");
+ if (realmsPage == null) {
+ realmsPage = Realms.class;
+ }
+
boolean isAuthorized = true;
PageParameters pageParameters = new PageParameters();
- Class<? extends IRequestablePage> responsePage;
+ Class<? extends BasePage> responsePage;
List<String> anyTypes = AnyTypeRestClient.list();
switch (id) {
case "totalUsers":
pageParameters.add(Realms.SELECTED_INDEX, 1);
- responsePage = Realms.class;
+ responsePage = realmsPage;
isAuthorized = SyncopeConsoleSession.get().owns(IdRepoEntitlement.USER_SEARCH);
break;
case "totalGroups":
pageParameters.add(Realms.SELECTED_INDEX, 2);
- responsePage = Realms.class;
+ responsePage = realmsPage;
isAuthorized = SyncopeConsoleSession.get().owns(IdRepoEntitlement.GROUP_SEARCH);
break;
@@ -74,7 +82,7 @@ public class NumberWidget extends BaseWidget {
pageParameters.add(Realms.SELECTED_INDEX, selectedIndex);
}
}
- responsePage = Realms.class;
+ responsePage = realmsPage;
isAuthorized = SyncopeConsoleSession.get().owns(label + "_SEARCH");
} else {
responsePage = Security.class;
@@ -90,13 +98,13 @@ public class NumberWidget extends BaseWidget {
pageParameters.add(Realms.SELECTED_INDEX, selectedIndex);
}
}
- responsePage = Realms.class;
+ responsePage = realmsPage;
isAuthorized = SyncopeConsoleSession.get().owns(label + "_SEARCH");
break;
default:
pageParameters.add(Realms.SELECTED_INDEX, 0);
- responsePage = Realms.class;
+ responsePage = realmsPage;
}
AjaxEventBehavior clickToRealms = new AjaxEventBehavior("mousedown") {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
index e1a0c2988a..b4d88faf04 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
@@ -86,6 +86,10 @@ public class Groups extends AbstractGroups {
addDynamicRealmsContainer();
}
+ protected List<GroupTO> searchAssignable(final String realm, final String term) {
+ return SyncopeRestClient.searchAssignableGroups(realm, term, 1, Constants.MAX_GROUP_LIST_SIZE);
+ }
+
@Override
protected void addDynamicRealmsContainer() {
dynrealmsContainer = new WebMarkupContainer("dynrealmsContainer");
@@ -123,53 +127,49 @@ public class Groups extends AbstractGroups {
@Override
public MembershipTO getObject(
- final String id, final IModel<? extends List<? extends MembershipTO>> choices) {
+ final String id, final IModel<? extends List<? extends MembershipTO>> choices) {
return choices.getObject().stream().
- filter(object -> id.equalsIgnoreCase(object.getGroupName())).findAny().orElse(null);
+ filter(object -> id.equalsIgnoreCase(object.getGroupName())).findAny().orElse(null);
}
});
- groupsContainer.add(builder.setAllowOrder(true).withFilter("*").build("groups",
- new ListModel<>() {
+ groupsContainer.add(builder.setAllowOrder(true).withFilter("*").build("groups", new ListModel<>() {
- private static final long serialVersionUID = -2583290457773357445L;
+ private static final long serialVersionUID = -2583290457773357445L;
- @Override
- public List<MembershipTO> getObject() {
- return Groups.this.groupsModel.getMemberships();
- }
-
- }, new AjaxPalettePanel.Builder.Query<>() {
+ @Override
+ public List<MembershipTO> getObject() {
+ return Groups.this.groupsModel.getMemberships();
+ }
+ }, new AjaxPalettePanel.Builder.Query<>() {
- private static final long serialVersionUID = -7223078772249308813L;
+ private static final long serialVersionUID = -7223078772249308813L;
- @Override
- public List<MembershipTO> execute(final String filter) {
- return StringUtils.isEmpty(filter)
+ @Override
+ public List<MembershipTO> execute(final String filter) {
+ return StringUtils.isEmpty(filter)
? List.of()
: ("*".equals(filter)
- ? groupsModel.getObject()
- : SyncopeRestClient.searchAssignableGroups(
- anyTO.getRealm(), filter, 1, Constants.MAX_GROUP_LIST_SIZE)).stream().
- map(group -> new MembershipTO.Builder(group.getKey()).
- groupName(group.getName()).build()).
- collect(Collectors.toList());
- }
- }).hideLabel().setOutputMarkupId(true));
+ ? groupsModel.getObject()
+ : searchAssignable(anyTO.getRealm(), filter)).stream().
+ map(group -> new MembershipTO.Builder(group.getKey()).
+ groupName(group.getName()).build()).
+ collect(Collectors.toList());
+ }
+ }).hideLabel().setOutputMarkupId(true));
dyngroupsContainer.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("dyngroups",
- new ListModel<>() {
-
- private static final long serialVersionUID = -2583290457773357445L;
+ new ListModel<>() {
- @Override
- public List<String> getObject() {
- return Groups.this.groupsModel.getDynMemberships();
- }
+ private static final long serialVersionUID = -2583290457773357445L;
- }, new ListModel<>(groupsModel.getObject().stream().
- map(GroupTO::getName).collect(Collectors.toList()))).
+ @Override
+ public List<String> getObject() {
+ return Groups.this.groupsModel.getDynMemberships();
+ }
+ }, new ListModel<>(groupsModel.getObject().stream().
+ map(GroupTO::getName).collect(Collectors.toList()))).
hideLabel().setEnabled(false).setOutputMarkupId(true));
}
}
@@ -214,11 +214,7 @@ public class Groups extends AbstractGroups {
*/
@Override
protected void reloadObject() {
- groupsObj = SyncopeRestClient.searchAssignableGroups(
- realmObj,
- null,
- 1,
- Constants.MAX_GROUP_LIST_SIZE);
+ groupsObj = searchAssignable(realmObj, null);
}
@Override
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 159d3a9296..91b84b4e38 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -82,9 +82,11 @@ public class Relationships extends WizardStep implements ICondition {
private static final long serialVersionUID = 855618618337931784L;
- private final PageReference pageRef;
+ protected final AnyTO anyTO;
- private final AnyTO anyTO;
+ protected final Specification specification;
+
+ protected final PageReference pageRef;
public Relationships(final AnyWrapper<?> modelObject, final PageReference pageRef) {
super();
@@ -101,6 +103,7 @@ public class Relationships extends WizardStep implements ICondition {
}
this.anyTO = modelObject.getInnerObject();
+ this.specification = new Specification();
this.pageRef = pageRef;
// ------------------------
@@ -115,11 +118,11 @@ public class Relationships extends WizardStep implements ICondition {
return super.getHeader(id, parent, wizard).setVisible(false);
}
- private Fragment getViewFragment() {
- final Map<String, List<RelationshipTO>> relationships = new HashMap<>();
+ protected Fragment getViewFragment() {
+ Map<String, List<RelationshipTO>> relationships = new HashMap<>();
addRelationship(relationships, getCurrentRelationships().toArray(RelationshipTO[]::new));
- final Fragment viewFragment = new Fragment("relationships", "viewFragment", this);
+ Fragment viewFragment = new Fragment("relationships", "viewFragment", this);
viewFragment.setOutputMarkupId(true);
viewFragment.add(new Accordion("relationships", relationships.keySet().stream().
@@ -158,7 +161,7 @@ public class Relationships extends WizardStep implements ICondition {
}
});
- final ActionsPanel<RelationshipTO> panel = new ActionsPanel<>("actions", null);
+ ActionsPanel<RelationshipTO> panel = new ActionsPanel<>("actions", null);
viewFragment.add(panel);
panel.add(new ActionLink<>() {
@@ -169,7 +172,7 @@ public class Relationships extends WizardStep implements ICondition {
public void onClick(final AjaxRequestTarget target, final RelationshipTO ignore) {
Fragment addFragment = new Fragment("relationships", "addFragment", Relationships.this);
addOrReplace(addFragment);
- addFragment.add(new Specification().setRenderBodyOnly(true));
+ addFragment.add(specification.setRenderBodyOnly(true));
target.add(Relationships.this);
}
}, ActionType.CREATE, AnyEntitlement.UPDATE.getFor(anyTO.getType())).hideLabel();
@@ -177,18 +180,18 @@ public class Relationships extends WizardStep implements ICondition {
return viewFragment;
}
- private List<RelationshipTO> getCurrentRelationships() {
+ protected List<RelationshipTO> getCurrentRelationships() {
return anyTO instanceof GroupableRelatableTO
? GroupableRelatableTO.class.cast(anyTO).getRelationships()
: List.of();
}
- private static void addRelationship(
+ protected void addRelationship(
final Map<String, List<RelationshipTO>> relationships,
final RelationshipTO... rels) {
for (RelationshipTO relationship : rels) {
- final List<RelationshipTO> listrels;
+ List<RelationshipTO> listrels;
if (relationships.containsKey(relationship.getType())) {
listrels = relationships.get(relationship.getType());
} else {
@@ -199,17 +202,18 @@ public class Relationships extends WizardStep implements ICondition {
}
}
- private void addNewRelationships(final RelationshipTO... rels) {
+ protected void addNewRelationships(final RelationshipTO... rels) {
getCurrentRelationships().addAll(List.of(rels));
}
- private void removeRelationships(
+ protected void removeRelationships(
final Map<String, List<RelationshipTO>> relationships, final RelationshipTO... rels) {
- final List<RelationshipTO> currentRels = getCurrentRelationships();
+
+ List<RelationshipTO> currentRels = getCurrentRelationships();
for (RelationshipTO relationship : rels) {
currentRels.remove(relationship);
if (relationships.containsKey(relationship.getType())) {
- final List<RelationshipTO> rellist = relationships.get(relationship.getType());
+ List<RelationshipTO> rellist = relationships.get(relationship.getType());
rellist.remove(relationship);
if (rellist.isEmpty()) {
relationships.remove(relationship.getType());
@@ -228,30 +232,38 @@ public class Relationships extends WizardStep implements ICondition {
private static final long serialVersionUID = 6199050589175839467L;
- private final RelationshipTO rel;
+ protected final RelationshipTO rel;
+
+ protected final AjaxDropDownChoicePanel<String> type;
+
+ protected final AjaxDropDownChoicePanel<AnyTypeTO> otherType;
+
+ protected final WebMarkupContainer container;
+
+ protected final Fragment emptyFragment;
- private AnyObjectSearchPanel anyObjectSearchPanel;
+ protected final Fragment fragment;
- private WizardMgtPanel<AnyWrapper<AnyObjectTO>> anyObjectDirectoryPanel;
+ protected AnyObjectSearchPanel anyObjectSearchPanel;
+
+ protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> anyObjectDirectoryPanel;
public Specification() {
super("specification");
rel = new RelationshipTO();
- final List<String> availableRels = RelationshipTypeRestClient.list().stream().
+ List<String> availableRels = RelationshipTypeRestClient.list().stream().
map(EntityTO::getKey).collect(Collectors.toList());
- final AjaxDropDownChoicePanel<String> type = new AjaxDropDownChoicePanel<>(
- "type", "type", new PropertyModel<>(rel, "type"));
+ type = new AjaxDropDownChoicePanel<>("type", "type", new PropertyModel<>(rel, "type"));
type.setChoices(availableRels);
- add(type.setRenderBodyOnly(true));
+ add(type.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true).setRenderBodyOnly(true));
- final List<AnyTypeTO> availableTypes = AnyTypeRestClient.listAnyTypes().stream().
+ List<AnyTypeTO> availableTypes = AnyTypeRestClient.listAnyTypes().stream().
filter(anyType -> anyType.getKind() != AnyTypeKind.GROUP
&& anyType.getKind() != AnyTypeKind.USER).collect(Collectors.toList());
- final AjaxDropDownChoicePanel<AnyTypeTO> otherType = new AjaxDropDownChoicePanel<>(
- "otherType", "otherType", new PropertyModel<>(rel, "otherType") {
+ otherType = new AjaxDropDownChoicePanel<>("otherType", "otherType", new PropertyModel<>(rel, "otherType") {
private static final long serialVersionUID = -5861057041758169508L;
@@ -288,27 +300,27 @@ public class Relationships extends WizardStep implements ICondition {
@Override
public AnyTypeTO getObject(final String id, final IModel<? extends List<? extends AnyTypeTO>> choices) {
return choices.getObject().stream().
- filter(anyTypeTO -> id.equals(anyTypeTO.getKey())).findAny().orElse(null);
+ filter(anyTypeTO -> id.equals(anyTypeTO.getKey())).findAny().orElse(null);
}
});
// enable "otherType" dropdown only if "type" option is selected - SYNCOPE-1140
otherType.setEnabled(false);
- add(otherType);
+ add(otherType.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
- final WebMarkupContainer container = new WebMarkupContainer("searchPanelContainer");
- container.setOutputMarkupId(true);
- add(container);
+ container = new WebMarkupContainer("searchPanelContainer");
+ add(container.setOutputMarkupId(true));
- Fragment emptyFragment = new Fragment("searchPanel", "emptyFragment", this);
+ emptyFragment = new Fragment("searchPanel", "emptyFragment", this);
container.add(emptyFragment.setRenderBodyOnly(true));
+ fragment = new Fragment("searchPanel", "searchFragment", Specification.this);
+
type.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
private static final long serialVersionUID = -1107858522700306810L;
@Override
protected void onUpdate(final AjaxRequestTarget target) {
- Fragment emptyFragment = new Fragment("searchPanel", "emptyFragment", Specification.this);
container.addOrReplace(emptyFragment.setRenderBodyOnly(true));
otherType.setModelObject(null);
// enable "otherType" dropdown only if "type" option is selected - SYNCOPE-1140
@@ -324,46 +336,47 @@ public class Relationships extends WizardStep implements ICondition {
@Override
protected void onUpdate(final AjaxRequestTarget target) {
- final AnyTypeTO anyType = otherType.getModelObject();
+ AnyTypeTO anyType = otherType.getModelObject();
if (anyType == null) {
- Fragment emptyFragment = new Fragment("searchPanel", "emptyFragment", Specification.this);
container.addOrReplace(emptyFragment.setRenderBodyOnly(true));
} else {
- final Fragment fragment = new Fragment("searchPanel", "searchFragment", Specification.this);
+ setupFragment(anyType);
container.addOrReplace(fragment.setRenderBodyOnly(true));
-
- anyObjectSearchPanel = new AnyObjectSearchPanel.Builder(
- anyType.getKey(),
- new ListModel<>(new ArrayList<>())).
- enableSearch(Specification.this).
- build("searchPanel");
- fragment.add(anyObjectSearchPanel.setRenderBodyOnly(true));
-
- anyObjectDirectoryPanel = new AnyObjectSelectionDirectoryPanel.Builder(
- AnyTypeClassRestClient.list(anyType.getClasses()),
- anyType.getKey(),
- pageRef).
- setFiql(SyncopeClient.getAnyObjectSearchConditionBuilder(anyType.getKey()).
- is(Constants.KEY_FIELD_NAME).notNullValue().query()).
- setWizardInModal(true).build("searchResultPanel");
- fragment.add(anyObjectDirectoryPanel.setRenderBodyOnly(true));
}
target.add(container);
}
});
}
+ protected void setupFragment(final AnyTypeTO anyType) {
+ anyObjectSearchPanel = new AnyObjectSearchPanel.Builder(
+ anyType.getKey(),
+ new ListModel<>(new ArrayList<>())).
+ enableSearch(Specification.this).
+ build("searchPanel");
+ fragment.addOrReplace(anyObjectSearchPanel.setRenderBodyOnly(true));
+
+ anyObjectDirectoryPanel = new AnyObjectSelectionDirectoryPanel.Builder(
+ AnyTypeClassRestClient.list(anyType.getClasses()),
+ anyType.getKey(),
+ pageRef).
+ setFiql(SyncopeClient.getAnyObjectSearchConditionBuilder(anyType.getKey()).
+ is(Constants.KEY_FIELD_NAME).notNullValue().query()).
+ setWizardInModal(true).build("searchResultPanel");
+ fragment.addOrReplace(anyObjectDirectoryPanel.setRenderBodyOnly(true));
+ }
+
@Override
public void onEvent(final IEvent<?> event) {
if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
- final AjaxRequestTarget target = SearchClausePanel.SearchEvent.class.cast(event.getPayload()).
- getTarget();
- final String fiql = SearchUtils.buildFIQL(anyObjectSearchPanel.getModel().getObject(),
+ AjaxRequestTarget target =
+ SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
+ String fiql = SearchUtils.buildFIQL(anyObjectSearchPanel.getModel().getObject(),
SyncopeClient.getAnyObjectSearchConditionBuilder(anyObjectSearchPanel.getBackObjectType()));
AnyDirectoryPanel.class.cast(Specification.this.anyObjectDirectoryPanel).search(fiql, target);
} else if (event.getPayload() instanceof AnySelectionDirectoryPanel.ItemSelection) {
- final AjaxRequestTarget target = AnySelectionDirectoryPanel.ItemSelection.class.cast(event.
- getPayload()).getTarget();
+ AjaxRequestTarget target =
+ AnySelectionDirectoryPanel.ItemSelection.class.cast(event.getPayload()).getTarget();
AnyTO right = AnySelectionDirectoryPanel.ItemSelection.class.cast(event.getPayload()).getSelection();
rel.setOtherEndKey(right.getKey());
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
index 0691389902..b250636658 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
@@ -20,7 +20,11 @@ under the License.
<wicket:panel>
<div wicket:id="container" class="realm-header">
<div class="realm-label">
- <label wicket:id="realmDisplayKey"/>: <label wicket:id="realmDisplayValue"/>
+ <nav aria-label="breadcrumb">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item" wicket:id="breadcrumb"><a wicket:id="bcitem"/></li>
+ </ol>
+ </nav>
</div>
<span wicket:id="realmsFragment"></span>
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index 47ee9853ab..8f2b63b0aa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -18,7 +18,9 @@
*/
package org.apache.syncope.fit.console;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import org.apache.syncope.client.ui.commons.Constants;
@@ -73,7 +75,8 @@ public class RealmsITCase extends AbstractConsoleITCase {
"body:content:realmChoicePanel:container:realmsFragment:realms:dropdown-menu:buttons:5:button",
Constants.ON_CLICK);
- TESTER.assertLabel("body:content:realmChoicePanel:container:realmDisplayValue", "/testRealm");
+ assertTrue(TESTER.getLastResponseAsString().contains(">/</a>"));
+ assertTrue(TESTER.getLastResponseAsString().contains(">testRealm</a>"));
TESTER.getRequest().addParameter("confirm", "true");
TESTER.clickLink(
@@ -86,7 +89,8 @@ public class RealmsITCase extends AbstractConsoleITCase {
"body:content:body:container:content:tabbedPanel:panel:container:policies:1:field-label",
"Account Policy");
- TESTER.assertLabel("body:content:realmChoicePanel:container:realmDisplayValue", "/");
+ assertTrue(TESTER.getLastResponseAsString().contains(">/</a>"));
+ assertFalse(TESTER.getLastResponseAsString().contains(">testRealm</a>"));
}
@Test
@@ -116,7 +120,8 @@ public class RealmsITCase extends AbstractConsoleITCase {
"body:content:realmChoicePanel:container:realmsFragment:realms:dropdown-menu:buttons:4:button",
Constants.ON_CLICK);
- TESTER.assertLabel("body:content:realmChoicePanel:container:realmDisplayValue", "/odd");
+ assertTrue(TESTER.getLastResponseAsString().contains(">/</a>"));
+ assertTrue(TESTER.getLastResponseAsString().contains(">odd</a>"));
TESTER.clickLink(
"body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:2:action:action");
@@ -136,7 +141,8 @@ public class RealmsITCase extends AbstractConsoleITCase {
assertSuccessMessage();
TESTER.cleanupFeedbackMessages();
- TESTER.assertLabel("body:content:realmChoicePanel:container:realmDisplayValue", "/odd");
+ assertTrue(TESTER.getLastResponseAsString().contains(">/</a>"));
+ assertTrue(TESTER.getLastResponseAsString().contains(">odd</a>"));
TESTER.clickLink(
"body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:2:action:action");
diff --git a/src/main/asciidoc/reference-guide/usage/customization.adoc b/src/main/asciidoc/reference-guide/usage/customization.adoc
index 4e54b98ac5..6ced0aaef9 100644
--- a/src/main/asciidoc/reference-guide/usage/customization.adoc
+++ b/src/main/asciidoc/reference-guide/usage/customization.adoc
@@ -120,11 +120,11 @@ At this point your favourite IDE can be attached to the port `8000`.
===== Override behavior
As a rule of thumb, any file of the local project will take precedence over a file with the same name in the same
-directory of the standard Apache Syncope release.
+package directory of the standard Apache Syncope release.
For example, if you place
- core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
+ core/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
in the local project, this file will be picked up instead of
ifeval::["{snapshotOrRelease}" == "release"]