Skip to content

Commit

Permalink
[SYNCOPE-1686] Added the End attribute to RelationshipTO to indicate …
Browse files Browse the repository at this point in the history
…the side of the current Any in the relationship. (#924)
  • Loading branch information
TatoniMatteo authored and ilgrosso committed Dec 2, 2024
1 parent e51b14a commit 5a67773
Show file tree
Hide file tree
Showing 10 changed files with 467 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.client.console.panels;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;

public final class RelationshipViewPanel extends WizardMgtPanel<RelationshipTO> {

private static final long serialVersionUID = -7510529471158257903L;

private ActionLinksTogglePanel<RelationshipTO> togglePanel;

private final ListView<RelationshipTO> relationshipsList;

private RelationshipViewPanel(
final String id,
final List<RelationshipTO> relationships,
final AnyTO anyTO,
final boolean reuseItem,
final boolean wizardInModal) {
super(id, wizardInModal);
addInnerObject(getHeader());
relationshipsList = new ListView<>("relationships", relationships) {

private static final long serialVersionUID = 4983556433071042668L;

@Override
protected void populateItem(final ListItem<RelationshipTO> relationshipItem) {
RelationshipTO relationshipTO = relationshipItem.getModelObject();
buildRowLabels(relationshipItem, relationshipTO, anyTO);

ActionsPanel<RelationshipTO> action = new ActionsPanel<>("action", new Model<>(relationshipTO));
action.add(new ActionLink<>() {

private static final long serialVersionUID = 5207800927605869051L;

@Override
public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
relationships.remove(modelObject);
target.add(RelationshipViewPanel.this);
}
}, ActionLink.ActionType.DELETE, AnyEntitlement.UPDATE.getFor(anyTO.getType()), true).hideLabel();

if (togglePanel != null) {
relationshipItem.add(new AttributeModifier("style", "cursor: pointer;"));
relationshipItem.add(new AjaxEventBehavior(Constants.ON_CLICK) {

private static final long serialVersionUID = -9027652037484739586L;

@Override
protected String findIndicatorId() {
return StringUtils.EMPTY;
}

@Override
protected void onEvent(final AjaxRequestTarget target) {
togglePanel.toggleWithContent(target, action, relationshipTO);
}
});
}

if (togglePanel == null) {
relationshipItem.add(action);
} else {
relationshipItem.add(new ActionsPanel<>("action", new Model<>(relationshipTO))
.setVisible(false)
.setEnabled(false));
}
}
};
relationshipsList.setOutputMarkupId(true);
relationshipsList.setReuseItems(reuseItem);
relationshipsList.setRenderBodyOnly(true);

addInnerObject(relationshipsList);

}

private WebMarkupContainer getHeader() {
WebMarkupContainer headerContainer = new WebMarkupContainer("header");
headerContainer.add(new Label("header_left_end", getString("left.end")));
headerContainer.add(new Label("header_relationship", new ResourceModel("relationship")));
headerContainer.add(new Label("header_right_end", new ResourceModel("right.end")));
return headerContainer;
}

private void buildRowLabels(
final ListItem<RelationshipTO> row,
final RelationshipTO relationshipTO,
final AnyTO anyTO) {
boolean isLeftRelation = relationshipTO.getEnd() == RelationshipTO.End.LEFT;
String anyName = anyTO instanceof UserTO
? UserTO.class.cast(anyTO).getUsername()
: AnyObjectTO.class.cast(anyTO).getName();

row.add(new Label("relationship", relationshipTO.getType()));
Label leftEnd = new Label("left_end", isLeftRelation
? String.format("%s %s", anyTO.getType() , anyName)
: String.format("%s %s", relationshipTO.getOtherEndType(), relationshipTO.getOtherEndName()));

Label rightEnd = new Label("right_end", isLeftRelation
? String.format("%s %s", relationshipTO.getOtherEndType(), relationshipTO.getOtherEndName())
: String.format("%s %s", anyTO.getType() , anyName));

if (anyTO.getKey() != null && anyTO.getKey().equals(relationshipTO.getOtherEndKey())) {
setBold(leftEnd, rightEnd);
} else {
setBold(isLeftRelation ? leftEnd : rightEnd);
}
row.add(leftEnd, rightEnd);
}

private void setBold(final Label... labels) {
for (Label label : labels) {
label.add(new AttributeModifier("style", "font-weight: bold;"));
}
}

public static class Builder extends WizardMgtPanel.Builder<RelationshipTO> {

private static final long serialVersionUID = -3643771352897992172L;

private List<RelationshipTO> relationships;

private AnyTO anyTO;

private boolean reuseItem = true;

public Builder(final PageReference pageRef) {
super(pageRef);
this.relationships = null;
this.anyTO = null;
}

public RelationshipViewPanel.Builder setAnyTO(final AnyTO anyTO) {
this.anyTO = anyTO;
return this;
}


public RelationshipViewPanel.Builder setRelationships(final List<RelationshipTO> relationships) {
this.relationships = relationships;
return this;
}

public RelationshipViewPanel.Builder addItem(final RelationshipTO item) {
if (item == null) {
return this;
}

if (this.relationships == null) {
this.relationships = new ArrayList<>();
}

this.relationships.add(item);
return this;
}

public RelationshipViewPanel.Builder setReuseItem(final boolean reuseItem) {
this.reuseItem = reuseItem;
return this;
}

@Override
protected WizardMgtPanel<RelationshipTO> newInstance(final String id, final boolean wizardInModal) {
return new RelationshipViewPanel(id, relationships, anyTO, reuseItem, wizardInModal);
}

}

}

Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,13 @@
package org.apache.syncope.client.console.wizards.any;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.panels.AnyDirectoryPanel;
import org.apache.syncope.client.console.panels.ListViewPanel;
import org.apache.syncope.client.console.panels.ListViewPanel.ListViewReload;
import org.apache.syncope.client.console.panels.RelationshipViewPanel;
import org.apache.syncope.client.console.panels.search.AnyObjectSearchPanel;
import org.apache.syncope.client.console.panels.search.AnyObjectSelectionDirectoryPanel;
import org.apache.syncope.client.console.panels.search.AnySelectionDirectoryPanel;
Expand All @@ -47,7 +44,6 @@
import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
import org.apache.syncope.common.lib.to.AnyObjectTO;
Expand All @@ -61,20 +57,17 @@
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.wizard.IWizard;
import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
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.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.util.ListModel;
Expand Down Expand Up @@ -133,47 +126,16 @@ public Component getHeader(final String id, final Component parent, final IWizar
}

protected Fragment getViewFragment() {
Map<String, List<RelationshipTO>> relationships = new HashMap<>();
addRelationship(relationships, getCurrentRelationships().toArray(RelationshipTO[]::new));

Fragment viewFragment = new Fragment("relationships", "viewFragment", this);
viewFragment.setOutputMarkupId(true);

viewFragment.add(new Accordion("relationships", relationships.keySet().stream().
map(relationship -> new AbstractTab(new ResourceModel("relationship", relationship)) {

private static final long serialVersionUID = 1037272333056449378L;

@Override
public Panel getPanel(final String panelId) {
return new ListViewPanel.Builder<>(RelationshipTO.class, pageRef).
setItems(relationships.get(relationship)).
includes("otherEndType", "otherEndKey", "otherEndName").
addAction(new ActionLink<>() {

private static final long serialVersionUID = -6847033126124401556L;

@Override
public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
removeRelationships(relationships, modelObject);
send(Relationships.this, Broadcast.DEPTH, new ListViewReload<>(target));
}
}, ActionType.DELETE, AnyEntitlement.UPDATE.getFor(anyTO.getType()), true).
build(panelId);
}
}).collect(Collectors.toList())) {

private static final long serialVersionUID = 1037272333056449379L;

@Override
public void renderHead(final IHeaderResponse response) {
super.renderHead(response);
if (relationships.isEmpty()) {
response.render(OnDomReadyHeaderItem.forScript(String.format(
"$('#emptyPlaceholder').append(\"%s\")", getString("relationships.empty.list"))));
}
}
});
List<RelationshipTO> relationships = getCurrentRelationships();
viewFragment.add(relationships.isEmpty()
? new Label("relationships", new Model<>(getString("relationships.empty.list")))
: new RelationshipViewPanel.Builder(pageRef).
setAnyTO(anyTO).
setRelationships(relationships).
build("relationships"));

ActionsPanel<RelationshipTO> panel = new ActionsPanel<>("actions", null);
viewFragment.add(panel);
Expand All @@ -200,42 +162,10 @@ protected List<RelationshipTO> getCurrentRelationships() {
: List.of();
}

protected void addRelationship(
final Map<String, List<RelationshipTO>> relationships,
final RelationshipTO... rels) {

for (RelationshipTO relationship : rels) {
List<RelationshipTO> listrels;
if (relationships.containsKey(relationship.getType())) {
listrels = relationships.get(relationship.getType());
} else {
listrels = new ArrayList<>();
relationships.put(relationship.getType(), listrels);
}
listrels.add(relationship);
}
}

protected void addNewRelationships(final RelationshipTO... rels) {
getCurrentRelationships().addAll(List.of(rels));
}

protected void removeRelationships(
final Map<String, List<RelationshipTO>> relationships, final RelationshipTO... rels) {

List<RelationshipTO> currentRels = getCurrentRelationships();
for (RelationshipTO relationship : rels) {
currentRels.remove(relationship);
if (relationships.containsKey(relationship.getType())) {
List<RelationshipTO> rellist = relationships.get(relationship.getType());
rellist.remove(relationship);
if (rellist.isEmpty()) {
relationships.remove(relationship.getType());
}
}
}
}

@Override
public boolean evaluate() {
// [SYNCOPE-1171] - skip current step when the are no relationships types in Syncope
Expand Down Expand Up @@ -265,6 +195,7 @@ public class Specification extends Panel {
public Specification() {
super("specification");
rel = new RelationshipTO();
rel.setEnd(RelationshipTO.End.LEFT);

List<String> availableRels = relationshipTypeRestClient.list().stream().
map(RelationshipTypeTO::getKey).collect(Collectors.toList());
Expand Down Expand Up @@ -396,6 +327,7 @@ public void onEvent(final IEvent<?> event) {

AnyTO right = AnySelectionDirectoryPanel.ItemSelection.class.cast(event.getPayload()).getSelection();
rel.setOtherEndKey(right.getKey());
rel.setOtherEndName(AnyObjectTO.class.cast(right).getName());

Relationships.this.addNewRelationships(rel);

Expand Down
Loading

0 comments on commit 5a67773

Please sign in to comment.