diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties
index 85c330fe1d9..c0e32fc8bd4 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties
@@ -22,7 +22,7 @@ resource.edit=Edit resource {0}
resource.menu.add=Add new resource
resource.menu.remove=Remove resource
resource.menu.edit=Edit resource
-resource.menu.provision=Edit provision rules
+resource.menu.provision=Provision rules
resource.menu.explore=Explore resource
resource.menu.history=Configuration history
resource.menu.clone=Clone resource
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties
index ab162bba115..0f05abbd443 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties
@@ -22,17 +22,17 @@ resource.edit=Modifier la ressource {0}
resource.menu.add=Ajouter une nouvelle ressource
resource.menu.remove=Supprimer la ressource
resource.menu.edit=Modifier la ressource
-resource.menu.provision=Modifier les r\u00e8gles de mise \u00e0 disposition
+resource.menu.provision=R\u00e8gles de mise \u00e0 disposition
resource.menu.explore=Explorer la ressource
resource.menu.history=Historique des configurations
resource.menu.clone=Cloner la ressource
task.propagation.list=T\u00e2ches de propagation {0}
-task.pull.list=T\u00e2ches d\u0027extraction {0}
+task.pull.list=T\u00e2ches d'extraction {0}
task.push.list=Pousser les t\u00e2ches {0}
resource.explore.list=Explorer ${key}
resource.reconciliation=R\u00e9conciliation {0}
resource.menu.reconciliation=R\u00e9conciliation
resource.menu.push.list=Pousser les t\u00e2ches
-resource.menu.pull.list=T\u00e2ches d\u0027extraction
+resource.menu.pull.list=T\u00e2ches d'extraction
resource.menu.propagation.list=T\u00e2ches de propagation
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties
index 860655d89f5..b2d92e0dc3b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties
@@ -22,7 +22,7 @@ resource.edit=Modifica risorsa {0}
resource.menu.add=Aggiungi nuova risorsa
resource.menu.remove=Rimuovi risorsa
resource.menu.edit=Modifica risorsa
-resource.menu.provision=Modifica regole di provisioning
+resource.menu.provision=Regole di provisioning
resource.menu.explore=Esplora risorsa
resource.menu.history=Storico delle configurazioni
resource.menu.clone=Duplica risorsa
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties
index 1600a2c4376..1175e6024c6 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties
@@ -22,7 +22,7 @@ resource.edit=Editar recurso {0}
resource.menu.add=Adicionar novo recurso
resource.menu.remove=Remover recurso
resource.menu.edit=Editar recurso
-resource.menu.provision=Editar regras de provis\u00e3o
+resource.menu.provision=Regras de provis\u00e3o
resource.menu.explore=Explorar recurso
resource.menu.history=Hist\u00f3rico de Configura\u00e7\u00e3o
resource.menu.clone=Clonar recurso
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
index c6d63eec6e7..82cf506d607 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
@@ -27,7 +27,7 @@ resource.clone=Clone resource {0}
resource.menu.add=Add new resource
resource.menu.remove=Remove resource
resource.menu.edit=Edit resource
-resource.menu.provision=Edit provision rules
+resource.menu.provision=Provision rules
resource.menu.explore=Explore resource
resource.menu.history=Configuration history
resource.menu.clone=Clone resource
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
index cffa797da47..c3d0a5fe589 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
@@ -27,7 +27,7 @@ resource.clone=Cloner la ressource {0}
resource.menu.add=Ajouter une nouvelle ressource
resource.menu.remove=Supprimer une ressource
resource.menu.edit=Modifier la ressource
-resource.menu.provision=Modifier les r\u00e8gles de provision
+resource.menu.provision=R\u00e8gles de provision
resource.menu.explore=Explorer la ressource
resource.menu.history=Historique de configuration
resource.menu.clone=Cloner la ressource
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
index 8126fd268f8..6e7d8d010be 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
@@ -27,7 +27,7 @@ resource.clone=Duplica risorsa {0}
resource.menu.add=Aggiungi nuova risorsa
resource.menu.remove=Rimuovi risorsa
resource.menu.edit=Modifica risorsa
-resource.menu.provision=Modifica regole di provisioning
+resource.menu.provision=Regole di provisioning
resource.menu.explore=Esplora risorsa
resource.menu.history=Storico delle configurazioni
resource.menu.clone=Duplica risorsa
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
index 2c39dc5d858..04125188afd 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
@@ -27,7 +27,7 @@ resource.clone=Clone recurso {0}
resource.menu.add=Adicionar novo recurso
resource.menu.remove=Retire recurso
resource.menu.edit=Alterar recurso
-resource.menu.provision=Alterar regras de provision
+resource.menu.provision=Regras de provision
resource.menu.explore=Explorar recurso
resource.menu.history=Hist\u00f3rico de configura\u00e7\u00e3o
resource.menu.clone=Clone recurso
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java
index b58288c48eb..8ea9290e2f5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java
@@ -363,11 +363,11 @@ public Recipients(final NotificationWrapper modelObject) {
recipientAttrName.setChoices(getSchemas());
recipientAttrName.addRequiredLabel();
recipientAttrName.setTitle(getString("intAttrNameInfo.help")
- + "groups[groupName].attribute, "
+ + " groups[groupName].attribute, "
+ "users[userName].attribute, "
+ "anyObjects[anyObjectName].attribute, "
- + "relationships[relationshipType][anyType].attribute or "
- + "memberships[groupName].attribute", true);
+ + "memberships[groupName].attribute, "
+ + "relationships[relationshipType][anyObjectName].attribute", true);
add(recipientAttrName);
AjaxTextFieldPanel staticRecipientsFieldPanel =
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 7839d160b9e..89b187f0c28 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -150,28 +150,31 @@ public RealmChoicePanel getRealmChoicePanel() {
public void onEvent(final IEvent> event) {
super.onEvent(event);
- if (event.getPayload() instanceof ChosenRealm) {
- @SuppressWarnings("unchecked")
- ChosenRealm choosenRealm = ChosenRealm.class.cast(event.getPayload());
- updateRealmContent(choosenRealm.getObj(), 0);
- choosenRealm.getTarget().add(content);
- } else if (event.getPayload() instanceof AjaxWizard.NewItemEvent> newItemEvent) {
- WizardModalPanel> modalPanel = newItemEvent.getModalPanel();
-
- if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
- final IModel model = new CompoundPropertyModel<>(modalPanel.getItem());
- templateModal.setFormModel(model);
- templateModal.header(newItemEvent.getTitleModel());
- newItemEvent.getTarget().ifPresent(t -> t.add(templateModal.setContent(modalPanel)));
- templateModal.show(true);
- } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
- newItemEvent.getTarget().ifPresent(templateModal::close);
- } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
- SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
- newItemEvent.getTarget().ifPresent(t -> {
- ((BasePage) getPage()).getNotificationPanel().refresh(t);
- templateModal.close(t);
- });
+ switch (event.getPayload()) {
+ case ChosenRealm chosenRealm -> {
+ updateRealmContent(chosenRealm.obj(), 0);
+ chosenRealm.target().add(content);
+ }
+ case AjaxWizard.NewItemEvent> newItemEvent -> {
+ WizardModalPanel> modalPanel = newItemEvent.getModalPanel();
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+ final IModel model = new CompoundPropertyModel<>(modalPanel.getItem());
+ templateModal.setFormModel(model);
+ templateModal.header(newItemEvent.getTitleModel());
+ newItemEvent.getTarget().ifPresent(t -> t.add(templateModal.setContent(modalPanel)));
+ templateModal.show(true);
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
+ newItemEvent.getTarget().ifPresent(templateModal::close);
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ newItemEvent.getTarget().ifPresent(t -> {
+ ((BasePage) getPage()).getNotificationPanel().refresh(t);
+ templateModal.close(t);
+ });
+ }
+ }
+ default -> {
}
}
}
@@ -200,12 +203,12 @@ protected void onClickTemplate(final AjaxRequestTarget target) {
@Override
protected void setWindowClosedReloadCallback(final BaseModal> modal) {
modal.setWindowClosedCallback(target -> {
- if (modal.getContent() instanceof ResultPanel, ?> rp) {
+ if (modal.getContent() instanceof final ResultPanel, ?> rp) {
RealmTO newRealmTO = RealmTO.class.cast(ProvisioningResult.class.cast(rp.getResult()).getEntity());
// reload realmChoicePanel label too - SYNCOPE-1151
target.add(realmChoicePanel.reloadRealmTree(target, Model.of(newRealmTO)));
realmChoicePanel.setCurrentRealm(newRealmTO);
- send(Realms.this, Broadcast.DEPTH, new ChosenRealm<>(newRealmTO, target));
+ send(Realms.this, Broadcast.DEPTH, new ChosenRealm(newRealmTO, target));
} else {
target.add(realmChoicePanel.reloadRealmTree(target));
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index 79afc603d77..c8b2acbb8f8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -260,7 +260,30 @@ public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
@Override
public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
target.add(typeExtensionsModal.setContent(new TypeExtensionDirectoryPanel(
- typeExtensionsModal, model.getObject(), pageRef)));
+ typeExtensionsModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = -2603789363348077538L;
+
+ @Override
+ public void onSubmit(final AjaxRequestTarget target) {
+ GroupUR req = new GroupUR();
+ req.setKey(model.getObject().getKey());
+ req.getTypeExtensions().addAll(typeExtensionHolder.getTypeExtensions());
+
+ try {
+ groupRestClient.update(model.getObject().getETagValue(), req);
+
+ baseModal.show(false);
+ baseModal.close(target);
+
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("Group update failure", e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }));
typeExtensionsModal.header(new StringResourceModel("typeExtensions", model));
typeExtensionsModal.show(true);
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 3dace52aa6a..d3b2e08e748 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -120,7 +120,7 @@ protected List buildTabList(final PageReference pageRef) {
tabs.add(new RealmDetailsTabPanel());
AnyLayout anyLayout = AnyLayoutUtils.fetch(roleRestClient, anyTypes.stream().map(AnyTypeTO::getKey).toList());
- for (AnyTypeTO anyType : anyTypes) {
+ anyTypes.forEach(anyType -> {
tabs.add(new ITabComponent(
new ResourceModel("anyType." + anyType.getKey(), anyType.getKey()),
String.format("%s_SEARCH", anyType.getKey())) {
@@ -139,7 +139,7 @@ public boolean isVisible() {
isActionAuthorized(this, RENDER);
}
});
- }
+ });
return tabs;
}
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 401fe876772..48b79686d92 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
@@ -73,6 +73,10 @@
public class RealmChoicePanel extends Panel {
+ public record ChosenRealm(RealmTO obj, AjaxRequestTarget target) {
+
+ }
+
private static final long serialVersionUID = -1100228004207271270L;
protected static final String SEARCH_REALMS = "searchRealms";
@@ -124,8 +128,7 @@ protected List> load() {
Stream> full;
if (fullRealmsTree) {
full = map.values().stream().
- map(realmTOListPair ->
- Pair.of(realmTOListPair.getLeft().getFullPath(), realmTOListPair.getKey())).
+ map(pair -> Pair.of(pair.getLeft().getFullPath(), pair.getLeft())).
sorted(Comparator.comparing(Pair::getLeft));
} else {
full = map.entrySet().stream().
@@ -250,7 +253,7 @@ protected void chooseRealm(final RealmTO realm, final AjaxRequestTarget target)
model.setObject(realm);
setBreadcrumb(realm);
target.add(container);
- send(pageRef.getPage(), Broadcast.EXACT, new ChosenRealm<>(realm, target));
+ send(pageRef.getPage(), Broadcast.EXACT, new ChosenRealm(realm, target));
}
public void reloadRealmsTree() {
@@ -512,26 +515,6 @@ public RealmTO moveToParentRealm(final String key) {
return null;
}
- public static class ChosenRealm {
-
- protected final AjaxRequestTarget target;
-
- protected final T obj;
-
- public ChosenRealm(final T obj, final AjaxRequestTarget target) {
- this.obj = obj;
- this.target = target;
- }
-
- public T getObj() {
- return obj;
- }
-
- public AjaxRequestTarget getTarget() {
- return target;
- }
- }
-
public List getLinks() {
return links;
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
index 023c09b139f..00058b6aae7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
@@ -18,13 +18,12 @@
*/
package org.apache.syncope.client.console.panels;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.DirectoryDataProvider;
@@ -33,8 +32,9 @@
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.RelationshipTypesPanel.RelationshipTypeProvider;
import org.apache.syncope.client.console.rest.RelationshipTypeRestClient;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
@@ -51,12 +51,15 @@
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
public class RelationshipTypesPanel extends TypesDirectoryPanel<
RelationshipTypeTO, RelationshipTypeProvider, RelationshipTypeRestClient> {
private static final long serialVersionUID = -3731778000138547357L;
+ protected final BaseModal typeExtensionsModal = new BaseModal<>(Constants.OUTER);
+
public RelationshipTypesPanel(
final String id,
final RelationshipTypeRestClient restClient,
@@ -65,6 +68,11 @@ public RelationshipTypesPanel(
super(id, restClient, false, pageRef);
disableCheckBoxes();
+ typeExtensionsModal.size(Modal.Size.Large);
+ typeExtensionsModal.addSubmitButton();
+ setWindowClosedReloadCallback(typeExtensionsModal);
+ addOuterObject(typeExtensionsModal);
+
this.addNewItemPanelBuilder(
new AbstractModalPanelBuilder(new RelationshipTypeTO(), pageRef) {
@@ -121,41 +129,18 @@ protected Collection getBatches() {
@Override
protected List> getColumns() {
-
- final List> columns = new ArrayList<>();
-
- for (Field field : RelationshipTypeTO.class.getDeclaredFields()) {
- if (!field.isSynthetic() && !Modifier.isStatic(field.getModifiers())) {
- final String fieldName = field.getName();
- if (field.getType().isArray()
- || Collection.class.isAssignableFrom(field.getType())
- || Map.class.isAssignableFrom(field.getType())) {
-
- columns.add(new PropertyColumn<>(
- new ResourceModel(field.getName()), field.getName()));
- } else if (field.getType().equals(boolean.class) || field.getType().equals(Boolean.class)) {
- columns.add(new BooleanPropertyColumn<>(
- new ResourceModel(field.getName()), field.getName(), field.getName()));
- } else {
- columns.add(new PropertyColumn<>(
- new ResourceModel(field.getName()), field.getName(), field.getName()) {
-
- private static final long serialVersionUID = -6902459669035442212L;
-
- @Override
- public String getCssClass() {
- String css = super.getCssClass();
- if (Constants.KEY_FIELD_NAME.equals(fieldName)) {
- css = StringUtils.isBlank(css)
- ? "col-xs-1"
- : css + " col-xs-1";
- }
- return css;
- }
- });
- }
- }
- }
+ List> columns = new ArrayList<>();
+
+ columns.add(new PropertyColumn<>(
+ new ResourceModel(Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME));
+ columns.add(new PropertyColumn<>(
+ new ResourceModel(Constants.DESCRIPTION_FIELD_NAME),
+ Constants.DESCRIPTION_FIELD_NAME,
+ Constants.DESCRIPTION_FIELD_NAME));
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("leftEndAnyType"), "leftEndAnyType", "leftEndAnyType"));
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("rightEndAnyType"), "rightEndAnyType", "rightEndAnyType"));
return columns;
}
@@ -174,6 +159,37 @@ public void onClick(final AjaxRequestTarget target, final RelationshipTypeTO ign
new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.RELATIONSHIPTYPE_UPDATE);
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 6242834621660352855L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final RelationshipTypeTO ignore) {
+ target.add(typeExtensionsModal.setContent(new TypeExtensionDirectoryPanel(
+ typeExtensionsModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = -2603789363348077538L;
+
+ @Override
+ public void onSubmit(final AjaxRequestTarget target) {
+ try {
+ RelationshipTypesPanel.this.restClient.update(model.getObject());
+
+ baseModal.show(false);
+ baseModal.close(target);
+
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("RelationshipType update failure", e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }));
+ typeExtensionsModal.header(new StringResourceModel("typeExtensions", model));
+ typeExtensionsModal.show(true);
+ }
+ }, ActionType.TYPE_EXTENSIONS, IdRepoEntitlement.RELATIONSHIPTYPE_UPDATE);
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
index 01aeeefe02e..d5c0ceb8e49 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
@@ -32,7 +32,6 @@
import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.BaseRestClient;
-import org.apache.syncope.client.console.rest.GroupRestClient;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
@@ -40,8 +39,7 @@
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.panels.SubmitableModalPanel;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
-import org.apache.syncope.common.lib.request.GroupUR;
-import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.TypeExtensionHolderTO;
import org.apache.syncope.common.lib.to.TypeExtensionTO;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -55,15 +53,12 @@
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
-public class TypeExtensionDirectoryPanel
+public abstract class TypeExtensionDirectoryPanel
extends DirectoryPanel
implements SubmitableModalPanel {
private static final long serialVersionUID = -4117015319209624858L;
- @SpringBean
- protected GroupRestClient groupRestClient;
-
@SpringBean
protected AnyTypeRestClient anyTypeRestClient;
@@ -72,20 +67,20 @@ public class TypeExtensionDirectoryPanel
protected final BaseModal baseModal;
- protected final GroupTO groupTO;
+ protected final TypeExtensionHolderTO typeExtensionHolder;
protected TypeExtensionDirectoryPanel(
final BaseModal baseModal,
- final GroupTO groupTO,
+ final TypeExtensionHolderTO typeExtensionHolder,
final PageReference pageRef) {
super(BaseModal.CONTENT_ID, null, pageRef, false);
this.baseModal = baseModal;
- this.groupTO = groupTO;
+ this.typeExtensionHolder = typeExtensionHolder;
TypeExtensionWizardBuilder builder = new TypeExtensionWizardBuilder(
- groupTO,
+ typeExtensionHolder,
new TypeExtensionTO(),
new StringResourceModel("anyType", this).getObject(),
new StringResourceModel("auxClasses", this).getObject(),
@@ -98,26 +93,6 @@ protected TypeExtensionDirectoryPanel(
initResultTable();
}
- @Override
- public void onSubmit(final AjaxRequestTarget target) {
- GroupUR req = new GroupUR();
- req.setKey(groupTO.getKey());
- req.getTypeExtensions().addAll(groupTO.getTypeExtensions());
-
- try {
- groupRestClient.update(groupTO.getETagValue(), req);
-
- this.baseModal.show(false);
- this.baseModal.close(target);
-
- SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
- } catch (Exception e) {
- LOG.error("Group update failure", e);
- SyncopeConsoleSession.get().onException(e);
- }
- ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
- }
-
@Override
public void onError(final AjaxRequestTarget target) {
SyncopeConsoleSession.get().error(getString(Constants.OPERATION_ERROR));
@@ -167,8 +142,8 @@ public void onClick(final AjaxRequestTarget target, final TypeExtensionTO ignore
@Override
public void onClick(final AjaxRequestTarget target, final TypeExtensionTO ignore) {
- groupTO.getTypeExtension(typeExtension.getAnyType()).ifPresent(typeExt -> {
- groupTO.getTypeExtensions().remove(typeExt);
+ typeExtensionHolder.getTypeExtension(typeExtension.getAnyType()).ifPresent(typeExt -> {
+ typeExtensionHolder.getTypeExtensions().remove(typeExt);
target.add(container);
});
}
@@ -193,36 +168,17 @@ public TypeExtensionDataProvider(final int paginatorRows) {
@Override
public Iterator extends TypeExtensionTO> iterator(final long first, final long count) {
- return groupTO.getTypeExtensions().subList((int) first, (int) (first + count)).iterator();
+ return typeExtensionHolder.getTypeExtensions().subList((int) first, (int) (first + count)).iterator();
}
@Override
public long size() {
- return groupTO.getTypeExtensions().size();
+ return typeExtensionHolder.getTypeExtensions().size();
}
@Override
public IModel model(final TypeExtensionTO object) {
return new CompoundPropertyModel<>(object);
}
-
- }
-
- @Override
- protected void customActionCallback(final AjaxRequestTarget target) {
- // change modal footer visibility
- send(TypeExtensionDirectoryPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
- }
-
- @Override
- protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
- // change modal footer visibility
- send(TypeExtensionDirectoryPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
- }
-
- @Override
- protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
- // change modal footer visibility
- send(TypeExtensionDirectoryPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
index 698514d48e0..ce63c083c60 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
@@ -24,18 +24,22 @@
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.rest.GroupRestClient;
+import org.apache.syncope.client.console.rest.RelationshipTypeRestClient;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelatableTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
import org.apache.syncope.common.lib.to.SchemaTO;
import org.apache.syncope.common.lib.to.TypeExtensionTO;
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.core.util.lang.PropertyResolver;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.model.IModel;
@@ -49,10 +53,17 @@ public abstract class AbstractAttrs extends AbstractAttrsWiz
@SpringBean
protected GroupRestClient groupRestClient;
+ @SpringBean
+ protected RelationshipTypeRestClient relationshipTypeRestClient;
+
protected final IModel> memberships;
+ protected final IModel> relationships;
+
protected final Map> membershipSchemas = new LinkedHashMap<>();
+ protected final Map, Map> relationshipSchemas = new LinkedHashMap<>();
+
public AbstractAttrs(
final AnyWrapper> modelObject,
final AjaxWizard.Mode mode,
@@ -62,33 +73,29 @@ public AbstractAttrs(
super(modelObject.getInnerObject(), mode, anyTypeClasses, whichAttrs);
this.memberships = new ListModel<>(List.of());
+ this.relationships = new ListModel<>(List.of());
this.setOutputMarkupId(true);
}
- @SuppressWarnings("unchecked")
private List loadMemberships() {
- if (attributable instanceof AnyTO anyTO) {
+ if (attributable instanceof GroupableRelatableTO anyTO) {
membershipSchemas.clear();
List membs = new ArrayList<>();
- try {
- ((Iterable) PropertyResolver.getPropertyField("memberships", anyTO).get(anyTO)).
- forEach(memb -> {
- setSchemas(memb.getGroupKey(),
- anyTypeClassRestClient.list(getMembershipAuxClasses(memb, anyTO.getType())).
- stream().map(AnyTypeClassTO::getKey).collect(Collectors.toList()));
- setAttrs(memb);
-
- if (this instanceof PlainAttrs && !memb.getPlainAttrs().isEmpty()) {
- membs.add(memb);
- } else if (this instanceof DerAttrs && !memb.getDerAttrs().isEmpty()) {
- membs.add(memb);
- }
- });
- } catch (WicketRuntimeException | IllegalArgumentException | IllegalAccessException ex) {
- // ignore
- }
+ anyTO.getMemberships().forEach(memb -> {
+ setSchemas(memb.getGroupKey(),
+ anyTypeClassRestClient.list(getMembershipAuxClasses(
+ memb.getGroupKey(), ((AnyTO) anyTO).getType())).stream().
+ map(AnyTypeClassTO::getKey).collect(Collectors.toList()));
+ setAttrs(memb);
+
+ if (this instanceof PlainAttrs && !memb.getPlainAttrs().isEmpty()) {
+ membs.add(memb);
+ } else if (this instanceof DerAttrs && !memb.getDerAttrs().isEmpty()) {
+ membs.add(memb);
+ }
+ });
return membs;
}
@@ -96,6 +103,31 @@ private List loadMemberships() {
return List.of();
}
+ private List loadRelationships() {
+ if (attributable instanceof RelatableTO anyTO) {
+ relationshipSchemas.clear();
+
+ List rels = new ArrayList<>();
+ anyTO.getRelationships().forEach(rel -> {
+ setSchemas(Pair.of(rel.getType(), rel.getOtherEndKey()),
+ anyTypeClassRestClient.list(getRelationshipAuxClasses(
+ rel.getType(), ((AnyTO) anyTO).getType())).stream().
+ map(AnyTypeClassTO::getKey).collect(Collectors.toList()));
+ setAttrs(rel);
+
+ if (this instanceof PlainAttrs && !rel.getPlainAttrs().isEmpty()) {
+ rels.add(rel);
+ } else if (this instanceof DerAttrs && !rel.getDerAttrs().isEmpty()) {
+ rels.add(rel);
+ }
+ });
+
+ return rels;
+ }
+
+ return List.of();
+ }
+
private void setSchemas(final String membership, final List anyTypeClasses) {
final Map mscs;
@@ -108,12 +140,31 @@ private void setSchemas(final String membership, final List anyTypeClass
setSchemas(anyTypeClasses, mscs);
}
- protected List getMembershipAuxClasses(final MembershipTO membershipTO, final String anyType) {
+ private void setSchemas(final Pair relationship, final List anyTypeClasses) {
+ final Map mscs;
+
+ if (relationshipSchemas.containsKey(relationship)) {
+ mscs = relationshipSchemas.get(relationship);
+ } else {
+ mscs = new LinkedHashMap<>();
+ relationshipSchemas.put(relationship, mscs);
+ }
+ setSchemas(anyTypeClasses, mscs);
+ }
+
+ protected List getMembershipAuxClasses(final String group, final String anyType) {
try {
- GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey());
- return groupTO.getTypeExtension(anyType).
- map(TypeExtensionTO::getAuxClasses).
- orElseGet(List::of);
+ GroupTO groupTO = groupRestClient.read(group);
+ return groupTO.getTypeExtension(anyType).map(TypeExtensionTO::getAuxClasses).orElseGet(List::of);
+ } catch (Exception e) {
+ return List.of();
+ }
+ }
+
+ protected List getRelationshipAuxClasses(final String relationshipType, final String anyType) {
+ try {
+ RelationshipTypeTO typeTO = relationshipTypeRestClient.read(relationshipType);
+ return typeTO.getTypeExtension(anyType).map(TypeExtensionTO::getAuxClasses).orElseGet(List::of);
} catch (Exception e) {
return List.of();
}
@@ -121,12 +172,19 @@ protected List getMembershipAuxClasses(final MembershipTO membershipTO,
protected abstract void setAttrs(MembershipTO membershipTO);
+ protected abstract void setAttrs(RelationshipTO relationshipTO);
+
protected abstract List getAttrsFromTO(MembershipTO membershipTO);
+ protected abstract List getAttrsFromTO(RelationshipTO relationshipTO);
+
@Override
public void renderHead(final IHeaderResponse response) {
super.renderHead(response);
- if (CollectionUtils.isEmpty(attrs.getObject()) && CollectionUtils.isEmpty(memberships.getObject())) {
+ if (CollectionUtils.isEmpty(attrs.getObject())
+ && CollectionUtils.isEmpty(memberships.getObject())
+ && CollectionUtils.isEmpty(relationships.getObject())) {
+
response.render(OnDomReadyHeaderItem.forScript(
String.format("$('#emptyPlaceholder').append(\"%s\"); $('#attributes').hide();",
getString("attribute.empty.list"))));
@@ -137,6 +195,9 @@ public void renderHead(final IHeaderResponse response) {
public boolean evaluate() {
this.attrs.setObject(loadAttrs());
this.memberships.setObject(loadMemberships());
- return !attrs.getObject().isEmpty() || !memberships.getObject().isEmpty();
+ this.relationships.setObject(loadRelationships());
+ return !attrs.getObject().isEmpty()
+ || !memberships.getObject().isEmpty()
+ || !relationships.getObject().isEmpty();
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index f62a8870de3..d00eb16db43 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -23,6 +23,7 @@
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.SyncopeWebApplication;
@@ -47,6 +48,8 @@ public abstract class AnyWizardBuilder extends AbstractAnyWizar
private static final long serialVersionUID = -2480279868319546243L;
+ private static final List NO_VALUES = List.of(StringUtils.EMPTY);
+
@SuppressWarnings("unchecked")
protected static AnyWrapper wrapper(final T anyTO) {
return (AnyWrapper) (anyTO instanceof UserTO userTO
@@ -123,6 +126,10 @@ protected WizardModel buildModelSteps(final AnyWrapper modelObject, final Wiz
wizardModel.add(new Groups(modelObject, mode == AjaxWizard.Mode.TEMPLATE));
}
+ if (formLayoutInfo.isRelationships()) {
+ wizardModel.add(new Relationships(modelObject, pageRef));
+ }
+
// attributes panel steps
if (formLayoutInfo.isPlainAttrs()) {
wizardModel.add(new PlainAttrs(modelObject, mode, anyTypeClasses, formLayoutInfo.getWhichPlainAttrs()) {
@@ -148,10 +155,6 @@ public PageReference getPageReference() {
wizardModel.add(new Roles(userWrapper));
}
- if (formLayoutInfo.isRelationships()) {
- wizardModel.add(new Relationships(modelObject, pageRef));
- }
-
SyncopeWebApplication.get().getAnyWizardBuilderAdditionalSteps().
buildModelSteps(modelObject, wizardModel, formLayoutInfo);
@@ -182,14 +185,23 @@ protected void fixPlainAttrs(final AnyTO updated, final AnyTO original) {
ifPresent(uMemb -> oMemb.getPlainAttrs().stream().
filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()).
forEach(attr -> uMemb.getPlainAttrs().add(attr))));
+ originalTO.getRelationships().
+ forEach(oRel -> updatedTO.getRelationship(oRel.getType(), oRel.getOtherEndKey()).
+ ifPresent(uRel -> oRel.getPlainAttrs().stream().
+ filter(attr -> uRel.getPlainAttr(attr.getSchema()).isEmpty()).
+ forEach(attr -> uRel.getPlainAttrs().add(attr))));
}
// remove from the updated object any plain attribute without values, thus triggering for removal in
// the generated patch
- updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty());
+ updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty() || NO_VALUES.equals(attr.getValues()));
if (updated instanceof GroupableRelatableTO updatedTO) {
updatedTO.getMemberships().
- forEach(memb -> memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()));
+ forEach(memb -> memb.getPlainAttrs().
+ removeIf(attr -> attr.getValues().isEmpty() || NO_VALUES.equals(attr.getValues())));
+ updatedTO.getRelationships().
+ forEach(rel -> rel.getPlainAttrs().
+ removeIf(attr -> attr.getValues().isEmpty() || NO_VALUES.equals(attr.getValues())));
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
index 0f8295c8a88..e41ab711d9a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
@@ -24,6 +24,7 @@
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
@@ -35,6 +36,7 @@
import org.apache.syncope.common.lib.to.DerSchemaTO;
import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.markup.ComponentTag;
@@ -113,6 +115,11 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) {
return membershipTO.getDerAttrs().stream().sorted(attrComparator).collect(Collectors.toList());
}
+ @Override
+ protected List getAttrsFromTO(final RelationshipTO relationshipTO) {
+ return relationshipTO.getDerAttrs().stream().sorted(attrComparator).collect(Collectors.toList());
+ }
+
@Override
protected void setAttrs() {
List derAttrs = new ArrayList<>();
@@ -154,6 +161,29 @@ protected void setAttrs(final MembershipTO membershipTO) {
membershipTO.getDerAttrs().addAll(derAttrs);
}
+ @Override
+ protected void setAttrs(final RelationshipTO relationshipTO) {
+ Map attrMap = GroupableRelatableTO.class.cast(attributable).
+ getRelationship(relationshipTO.getType(), relationshipTO.getOtherEndKey()).
+ map(gr -> EntityTOUtils.buildAttrMap(gr.getDerAttrs())).
+ orElseGet(HashMap::new);
+
+ List derAttrs = relationshipSchemas.get(
+ Pair.of(relationshipTO.getType(), relationshipTO.getOtherEndKey())).values().stream().map(schema -> {
+
+ Attr attr = new Attr();
+ attr.setSchema(schema.getKey());
+ if (attrMap.containsKey(schema.getKey())) {
+ attr.getValues().addAll(attrMap.get(schema.getKey()).getValues());
+ }
+
+ return attr;
+ }).toList();
+
+ relationshipTO.getDerAttrs().clear();
+ relationshipTO.getDerAttrs().addAll(derAttrs);
+ }
+
public static class DerSchemas extends Schemas {
private static final long serialVersionUID = -4730563859116024676L;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index bb000382812..f44a5e02349 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -23,6 +23,7 @@
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
@@ -35,6 +36,7 @@
import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.SchemaType;
@@ -90,7 +92,7 @@ public WebMarkupContainer getPanel(final String panelId) {
@Override
protected void populateItem(final ListItem item) {
- final MembershipTO membershipTO = item.getModelObject();
+ MembershipTO membershipTO = item.getModelObject();
item.add(new Accordion("membershipPlainSchemas", List.of(new AbstractTab(
new StringResourceModel(
"attributes.membership.accordion",
@@ -101,7 +103,7 @@ protected void populateItem(final ListItem item) {
@Override
public WebMarkupContainer getPanel(final String panelId) {
- return new PlainSchemasMemberships(
+ return new PlainSchemasAttributable(
panelId,
membershipSchemas.get(membershipTO.getGroupKey()),
new LoadableDetachableModel<>() {
@@ -117,6 +119,41 @@ protected AttributableTO load() {
}), Model.of(-1)).setOutputMarkupId(true));
}
});
+
+ add(new ListView<>("relationshipsPlainSchemas", relationships) {
+
+ private static final long serialVersionUID = 6741044372185745296L;
+
+ @Override
+ protected void populateItem(final ListItem item) {
+ RelationshipTO relationshipTO = item.getModelObject();
+ item.add(new Accordion("relationshipPlainSchemas", List.of(new AbstractTab(
+ new StringResourceModel(
+ "attributes.relationship.accordion",
+ PlainAttrs.this,
+ Model.of(relationshipTO))) {
+
+ private static final long serialVersionUID = 1037272333056449378L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new PlainSchemasAttributable(
+ panelId,
+ relationshipSchemas.get(Pair.of(
+ relationshipTO.getType(), relationshipTO.getOtherEndKey())),
+ new LoadableDetachableModel<>() {
+
+ private static final long serialVersionUID = 526768546610546553L;
+
+ @Override
+ protected AttributableTO load() {
+ return relationshipTO;
+ }
+ });
+ }
+ }), Model.of(-1)).setOutputMarkupId(true));
+ }
+ });
}
@Override
@@ -139,6 +176,11 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) {
return membershipTO.getPlainAttrs().stream().sorted(attrComparator).collect(Collectors.toList());
}
+ @Override
+ protected List getAttrsFromTO(final RelationshipTO relationshipTO) {
+ return relationshipTO.getPlainAttrs().stream().sorted(attrComparator).collect(Collectors.toList());
+ }
+
@Override
protected void setAttrs() {
Map attrMap = EntityTOUtils.buildAttrMap(attributable.getPlainAttrs());
@@ -184,6 +226,32 @@ protected void setAttrs(final MembershipTO membershipTO) {
membershipTO.getPlainAttrs().addAll(plainAttrs);
}
+ @Override
+ protected void setAttrs(final RelationshipTO relationshipTO) {
+ Map attrMap = GroupableRelatableTO.class.cast(attributable).
+ getRelationship(relationshipTO.getType(), relationshipTO.getOtherEndKey()).
+ map(gr -> EntityTOUtils.buildAttrMap(gr.getPlainAttrs())).
+ orElseGet(HashMap::new);
+
+ List plainAttrs = relationshipSchemas.get(
+ Pair.of(relationshipTO.getType(), relationshipTO.getOtherEndKey())).values().stream().map(schema -> {
+
+ Attr attr = new Attr();
+ attr.setSchema(schema.getKey());
+ if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
+ if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) {
+ attr.getValues().add(StringUtils.EMPTY);
+ }
+ } else {
+ attr.getValues().addAll(attrMap.get(schema.getKey()).getValues());
+ }
+ return attr;
+ }).toList();
+
+ relationshipTO.getPlainAttrs().clear();
+ relationshipTO.getPlainAttrs().addAll(plainAttrs);
+ }
+
protected class PlainSchemasOwn extends PlainSchemas> {
private static final long serialVersionUID = -4730563859116024676L;
@@ -208,11 +276,11 @@ protected void populateItem(final ListItem item) {
}
}
- protected class PlainSchemasMemberships extends PlainSchemas {
+ protected class PlainSchemasAttributable extends PlainSchemas {
private static final long serialVersionUID = 456754923340249215L;
- public PlainSchemasMemberships(
+ public PlainSchemasAttributable(
final String id,
final Map schemas,
final IModel attributableTO) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
index 223dec574d6..43512a77334 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
@@ -29,6 +29,7 @@
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.TypeExtensionHolderTO;
import org.apache.syncope.common.lib.to.TypeExtensionTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.wicket.PageReference;
@@ -42,7 +43,7 @@ public class TypeExtensionWizardBuilder extends BaseAjaxWizardBuilder typeExtensions = groupTO.getTypeExtensions().stream().
+ List typeExtensions = typeExtensionHolder.getTypeExtensions().stream().
filter(typeExt -> !typeExt.getAnyType().equals(modelObject.getAnyType())).collect(Collectors.toList());
typeExtensions.add(modelObject);
- groupTO.getTypeExtensions().clear();
- groupTO.getTypeExtensions().addAll(typeExtensions);
- return groupTO;
+ typeExtensionHolder.getTypeExtensions().clear();
+ typeExtensionHolder.getTypeExtensions().addAll(typeExtensions);
+ return typeExtensionHolder;
}
public class Details extends WizardStep {
@@ -98,9 +99,11 @@ public Details(final TypeExtensionTO typeExtensionTO) {
if (typeExtensionTO.getAnyType() == null) {
List anyTypes = anyTypeRestClient.list();
- anyTypes.remove(AnyTypeKind.GROUP.name());
+ if (typeExtensionHolder instanceof GroupTO) {
+ anyTypes.remove(AnyTypeKind.GROUP.name());
+ }
anyTypes.removeAll(anyTypes.stream().
- filter(anyType -> groupTO.getTypeExtension(anyType).isPresent()).toList());
+ filter(anyType -> typeExtensionHolder.getTypeExtension(anyType).isPresent()).toList());
AjaxDropDownChoicePanel anyTypeComponent = new AjaxDropDownChoicePanel<>(
"anyType.component", "anyType", new PropertyModel<>(typeExtensionTO, "anyType"));
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
index 5c79d616eef..1b1bc84840f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
@@ -149,11 +149,11 @@ public AbstractMappingPanel(
intAttrNameInfo.add(new PopoverBehavior(
Model.of(),
Model.of(getString("intAttrNameInfo.help")
- + "groups[groupName].attribute, "
+ + " groups[groupName].attribute, "
+ "users[userName].attribute, "
+ "anyObjects[anyObjectName].attribute, "
- + "relationships[relationshipType][anyType].attribute or "
- + "memberships[groupName].attribute"),
+ + "memberships[groupName].attribute, "
+ + "relationships[relationshipType][anyObjectName].attribute"),
new PopoverConfig().withHtml(true).withPlacement(TooltipConfig.Placement.right)) {
private static final long serialVersionUID = -7867802555691605021L;
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel.properties
index 9c394fc9553..44c8e2a4ad1 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel.properties
@@ -39,8 +39,6 @@ batch=Batch
any.propagation.tasks=Propagation tasks for ${type} ${name}
any.notification.tasks=Notification tasks for ${type} ${name}
notification.tasks=Tasks about notification ${key}
-
-typeExtensions=Type extensions for GROUP ${name}
creator=Creator
creationContext=Creation Context
lastChangeContext=Last Change Context
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_fr_CA.properties
index 2b04856ffce..c69bd48cf58 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_fr_CA.properties
@@ -36,7 +36,6 @@ batch=Lot
any.propagation.tasks=T\u00e2ches de propagation pour ${type} ${name}
any.notification.tasks=T\u00e2ches de notification pour ${type} ${name}
notification.tasks=T\u00e2ches \u00e0 propos de la notification ${key}
-typeExtensions=Taper les extensions pour GROUPE ${name}
creator=Cr\u00e9ateur
creationContext=Creation Context
lastChangeContext=Last Change Context
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_it.properties
index e36a31d674b..118ddc7d7c2 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_it.properties
@@ -39,7 +39,6 @@ batch=Batch
any.propagation.tasks=Task di Propagazione per ${type} ${name}
any.notification.tasks=Task di Notifica per ${type} ${name}
notification.tasks=Task relativi alla notifica ${key}
-typeExtensions=Type extensions per GROUP ${name}
creator=Creatore
creationContext=Contesto Di Crezione
lastChangeContext=Contesto Di Ultima Modifica
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ja.properties
index a62d3a840f7..29e4faf648c 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ja.properties
@@ -39,8 +39,6 @@ batch=\u30d0\u30c3\u30c1
any.propagation.tasks=${type} ${name} \u306e\u4f1d\u64ad\u30bf\u30b9\u30af
any.notification.tasks=${type} ${name} \u306e\u901a\u77e5\u30bf\u30b9\u30af
notification.tasks=\u901a\u77e5 ${key} \u306b\u95a2\u3059\u308b\u30bf\u30b9\u30af
-
-typeExtensions=\u30b0\u30eb\u30fc\u30d7 ${name} \u306e\u30bf\u30a4\u30d7\u62e1\u5f35
creator=\u4f5c\u6210\u8005
creationContext=Creation Context
lastChangeContext=Last Change Context
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_pt_BR.properties
index bd1d7260a33..b285a4911ba 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_pt_BR.properties
@@ -39,7 +39,6 @@ batch=Batch
any.propagation.tasks=Propagation tasks for ${type} ${name}
any.notification.tasks=Notification tasks for ${type} ${name}
notification.tasks=Tasks about notification ${key}
-typeExtensions=Type extensions for GROUP ${name}
creator=Criador
creationContext=Creation Context
lastChangeContext=Last Change Context
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ru.properties
index 26076067753..dd31e40e7fe 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DirectoryPanel_ru.properties
@@ -40,7 +40,6 @@ batch=Batch
any.propagation.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f ${type} ${name}
any.notification.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f ${type} ${name}
notification.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 ${key}
-typeExtensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0413\u0440\u0443\u043f\u043f\u044b ${name}
creator=\u0421\u043e\u0437\u0434\u0430\u043b
creationContext=Creation Context
lastChangeContext=Last Change Context
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties
index 7c1cb8cdc53..9b6c4d16a11 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties
@@ -17,3 +17,4 @@
any.edit=Edit ${anyTO.type} ${anyTO.name}
group.members=${right} members of ${left.name}
auditHistory.title=${anyTO.type} ${anyTO.name} history
+typeExtensions=Type extensions for GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_fr_CA.properties
index f2b1ceff00b..963b8c912f2 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_fr_CA.properties
@@ -17,3 +17,4 @@
any.edit=Modifier ${anyTO.type} ${anyTO.name}
group.members=${right} membres de ${left.name}
auditHistory.title=${anyTO.type} ${anyTO.name} histoire
+typeExtensions=Type extensions for GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties
index 8566276c489..9912ea63529 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties
@@ -17,3 +17,4 @@
any.edit=Modifica ${anyTO.type} ${anyTO.name}
group.members=Membri ${right} di '${left.name}'
auditHistory.title=${anyTO.type} ${anyTO.name} history
+typeExtensions=Type extensions per GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties
index 2f0982a197f..c91f74dbebd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties
@@ -17,3 +17,4 @@
any.edit=${anyTO.type} ${anyTO.name} \u3092\u7de8\u96c6
group.members=${left.name} \u306e ${right} \u30e1\u30f3\u30d0\u30fc
auditHistory.title=${anyTO.type} ${anyTO.name} history
+typeExtensions=Type extensions for GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties
index b5730e23ccb..f3ee5f48f36 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties
@@ -17,3 +17,4 @@
any.edit=Alterar ${anyTO.type} ${anyTO.name}
group.members=${right} members of ${left.name}
auditHistory.title=${anyTO.type} ${anyTO.name} history
+typeExtensions=Type extensions for GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties
index 84e3f7b4ecd..4a868f43aed 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties
@@ -18,3 +18,4 @@
any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${anyTO.type} ${anyTO.name}
group.members=${right} \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 ${left.name}
auditHistory.title=${anyTO.type} ${anyTO.name} history
+typeExtensions=Type extensions for GROUP ${name}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel.properties
index c41e4711bfa..368d855bafd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel.properties
@@ -19,3 +19,4 @@ any.new=New RelationshipType
leftEndAnyType=Left End AnyType
rightEndAnyType=Right End AnyType
description=Description
+typeExtensions=Type extensions for RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_fr_CA.properties
index 89e67c8b236..88163315ddb 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_fr_CA.properties
@@ -19,3 +19,4 @@ any.new=Nouveau type de relation
leftEndAnyType=Left End AnyType
rightEndAnyType=Right End AnyType
description=Description
+typeExtensions=Type extensions for RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_it.properties
index e9ec8689ef7..339684e7b85 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_it.properties
@@ -19,3 +19,4 @@ any.new=Nuovo RelationshipType
leftEndAnyType=AnyType lato sinistro
rightEndAnyType=AnyType lato destro
description=Descrizione
+typeExtensions=Type extensions per RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ja.properties
index 376289e60f2..6b38da5a1d3 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ja.properties
@@ -19,3 +19,4 @@ any.new=\u65b0\u3057\u3044\u95a2\u4fc2\u30bf\u30a4\u30d7
leftEndAnyType=Left End AnyType
rightEndAnyType=Right End AnyType
description=Description
+typeExtensions=Type extensions for RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_pt_BR.properties
index bf5e41f9634..825bb27c712 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_pt_BR.properties
@@ -19,3 +19,4 @@ any.new=Novo RelationshipType
leftEndAnyType=Left End AnyType
rightEndAnyType=Right End AnyType
description=Description
+typeExtensions=Type extensions for RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ru.properties
index bf61f42a917..52b2f48b7b8 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RelationshipTypesPanel_ru.properties
@@ -22,3 +22,4 @@ any.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0438\u043f \u0441\u04
leftEndAnyType=Left End AnyType
rightEndAnyType=Right End AnyType
description=Description
+typeExtensions=Type extensions for RelationshipType ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.properties
index f6c0c024f65..200b1a020bd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.properties
@@ -16,3 +16,4 @@
# under the License.
attributes.accordion=Own
attributes.membership.accordion=From membership with '${groupName}'
+attributes.relationship.accordion=From relationship ${type} with '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_fr_CA.properties
index be50d3fb661..82afcfe0513 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_fr_CA.properties
@@ -16,3 +16,4 @@
# under the License.
attributes.accordion=Moi
attributes.membership.accordion=De regroupements avec '${groupName}'
+attributes.relationship.accordion=From relationship ${type} with '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_it.properties
index 9b9f1a0c0b6..eb6b11bca50 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_it.properties
@@ -16,3 +16,4 @@
# under the License.
attributes.accordion=Propri
attributes.membership.accordion=Dalla membership con '${groupName}'
+attributes.relationship.accordion=Dalla relationship ${type} con '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ja.properties
index 63f5ae6aa35..1125a339495 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ja.properties
@@ -16,3 +16,4 @@
# under the License.
attributes.accordion=\u81ea\u5206
attributes.membership.accordion='${groupName}' \u3068\u306e\u30e1\u30f3\u30d0\u30fc\u30b7\u30c3\u30d7\u304b\u3089
+attributes.relationship.accordion=From relationship ${type} with '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_pt_BR.properties
index f6c0c024f65..200b1a020bd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_pt_BR.properties
@@ -16,3 +16,4 @@
# under the License.
attributes.accordion=Own
attributes.membership.accordion=From membership with '${groupName}'
+attributes.relationship.accordion=From relationship ${type} with '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ru.properties
index b28194c117f..e2303dc3c9e 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs_ru.properties
@@ -17,3 +17,4 @@
#
attributes.accordion=\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435
attributes.membership.accordion=\u0418\u0437 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u044b '${groupName}'
+attributes.relationship.accordion=From relationship ${type} with '${otherEndName}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/PlainAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/PlainAttrs.html
index 8da9bd9e74c..4196fb3c677 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/PlainAttrs.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/PlainAttrs.html
@@ -22,5 +22,8 @@
+
+
+
-