Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
more cleanup for multi-value container list panels.
- new providers for assignments and shadows - new details panel for assignments - containers on separated tabs - default details panel is now "tabbed" this should bring better UX for assignments and later for other containers which has rich data structure
- Loading branch information
Showing
32 changed files
with
848 additions
and
691 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
275 changes: 275 additions & 0 deletions
275
...n-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/AssignmentsDetailsPanel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,275 @@ | ||
/* | ||
* Copyright (C) 2021 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
package com.evolveum.midpoint.gui.impl.component; | ||
|
||
import java.util.List; | ||
import javax.xml.namespace.QName; | ||
|
||
import org.apache.wicket.extensions.markup.html.tabs.ITab; | ||
import org.apache.wicket.markup.html.WebMarkupContainer; | ||
import org.apache.wicket.model.IModel; | ||
import org.apache.wicket.model.Model; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import com.evolveum.midpoint.gui.api.component.DisplayNamePanel; | ||
import com.evolveum.midpoint.gui.api.component.tabs.PanelTab; | ||
import com.evolveum.midpoint.gui.api.prism.wrapper.ItemWrapper; | ||
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper; | ||
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerWrapper; | ||
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; | ||
import com.evolveum.midpoint.gui.impl.prism.panel.SingleContainerPanel; | ||
import com.evolveum.midpoint.gui.impl.prism.wrapper.ConstructionValueWrapper; | ||
import com.evolveum.midpoint.prism.Containerable; | ||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.prism.path.ItemPath; | ||
import com.evolveum.midpoint.schema.result.OperationResult; | ||
import com.evolveum.midpoint.task.api.Task; | ||
import com.evolveum.midpoint.util.QNameUtil; | ||
import com.evolveum.midpoint.util.exception.SchemaException; | ||
import com.evolveum.midpoint.util.logging.Trace; | ||
import com.evolveum.midpoint.util.logging.TraceManager; | ||
import com.evolveum.midpoint.web.component.assignment.AssignmentsUtil; | ||
import com.evolveum.midpoint.web.component.assignment.ConstructionAssociationPanel; | ||
import com.evolveum.midpoint.web.component.prism.ItemVisibility; | ||
import com.evolveum.midpoint.web.model.PrismContainerWrapperModel; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.*; | ||
|
||
public class AssignmentsDetailsPanel extends MultivalueContainerDetailsPanel<AssignmentType> { | ||
|
||
private static final Trace LOGGER = TraceManager.getTrace(AssignmentsDetailsPanel.class); | ||
private boolean isEntitledAssignemnt; | ||
|
||
public AssignmentsDetailsPanel(String id, IModel<PrismContainerValueWrapper<AssignmentType>> model, boolean isEntitledAssignment) { | ||
super(id, model, !isEntitledAssignment); | ||
this.isEntitledAssignemnt = isEntitledAssignment; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
protected List<ITab> createTabs() { | ||
List<ITab> tabs = super.createTabs(); | ||
if (isEntitledAssignemnt) { | ||
tabs.add(getConstructionAssociationPanel()); | ||
return tabs; | ||
} | ||
|
||
AssignmentsUtil.AssignmentTypeType assignmentTypeType = AssignmentsUtil.getAssignmentType(getModelObject()); | ||
switch (assignmentTypeType) { | ||
case CONSTRUCTION: | ||
tabs.add(createConstructionTabs()); | ||
break; | ||
case POLICY_RULE: | ||
tabs.add(createTabs("AssignmentType.policyRule", AssignmentType.F_POLICY_RULE, PolicyRuleType.COMPLEX_TYPE)); | ||
break; | ||
case FOCUS_MAPPING: | ||
tabs.add(createTabs("AssignmentType.focusMappings", AssignmentType.F_FOCUS_MAPPINGS, MappingType.COMPLEX_TYPE)); | ||
break; | ||
case PERSONA_CONSTRUCTION: | ||
tabs.add(createTabs("AssignmentType.personaConstruction", AssignmentType.F_PERSONA_CONSTRUCTION, PersonaConstructionType.COMPLEX_TYPE)); | ||
break; | ||
case ASSIGNMENT_RELATION: | ||
tabs.add(createTabs("AssignmentType.assignmentRelation", AssignmentType.F_ASSIGNMENT_RELATION, AssignmentRelationType.COMPLEX_TYPE)); | ||
break; | ||
} | ||
|
||
tabs.add(createActivationTab()); | ||
tabs.add(createConditionTab()); | ||
return tabs; | ||
} | ||
|
||
private PanelTab getConstructionAssociationPanel() { | ||
return new PanelTab(createStringResource("AssignmentPanel.inducedEntitlements")) { | ||
@Override | ||
public WebMarkupContainer createPanel(String panelId) { | ||
IModel<PrismContainerWrapper<ConstructionType>> constructionModel = PrismContainerWrapperModel.fromContainerValueWrapper(getModel(), AssignmentType.F_CONSTRUCTION); | ||
ConstructionAssociationPanel constructionDetailsPanel = new ConstructionAssociationPanel(panelId, constructionModel); | ||
constructionDetailsPanel.setOutputMarkupId(true); | ||
return constructionDetailsPanel; | ||
} | ||
}; | ||
} | ||
@Override | ||
protected ItemVisibility getBasicTabVisibity(ItemWrapper<?, ?> itemWrapper) { | ||
return getContainerVisibility(itemWrapper); | ||
} | ||
|
||
@Override | ||
protected boolean getBasicTabEditability(ItemWrapper<?, ?> itemWrapper) { | ||
return getContainerReadability(itemWrapper); | ||
} | ||
|
||
@Override | ||
protected DisplayNamePanel<AssignmentType> createDisplayNamePanel(String displayNamePanelId) { | ||
IModel<AssignmentType> displayNameModel = getDisplayModel(getModelObject().getRealValue()); | ||
return new DisplayNamePanel<>(displayNamePanelId, displayNameModel) { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
@Override | ||
protected QName getRelation() { | ||
return getRelationForDisplayNamePanel(AssignmentsDetailsPanel.this.getModelObject()); | ||
} | ||
|
||
@Override | ||
protected IModel<String> getKindIntentLabelModel() { | ||
return getKindIntentLabelModelForDisplayNamePanel(AssignmentsDetailsPanel.this.getModelObject()); | ||
} | ||
|
||
}; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private <C extends Containerable> IModel<C> getDisplayModel(AssignmentType assignment) { | ||
return () -> { | ||
if (assignment.getTargetRef() != null && assignment.getTargetRef().getOid() != null) { | ||
Task task = getPageBase().createSimpleTask("Load target"); | ||
OperationResult result = task.getResult(); | ||
PrismObject<ObjectType> targetObject = WebModelServiceUtils.loadObject(assignment.getTargetRef(), getPageBase(), task, result); | ||
return targetObject != null ? (C) targetObject.asObjectable() : null; | ||
} | ||
if (assignment.getConstruction() != null && assignment.getConstruction().getResourceRef() != null) { | ||
if (assignment.getConstruction().getResourceRef().getOid() != null) { | ||
Task task = getPageBase().createSimpleTask("Load resource"); | ||
OperationResult result = task.getResult(); | ||
PrismObject<?> object = WebModelServiceUtils.loadObject(assignment.getConstruction().getResourceRef(), getPageBase(), task, result); | ||
if (object != null) { | ||
return (C) object.asObjectable(); | ||
} | ||
} else { | ||
return (C) assignment.getConstruction(); | ||
} | ||
} else if (assignment.getPersonaConstruction() != null) { | ||
return (C) assignment.getPersonaConstruction(); | ||
} else if (assignment.getPolicyRule() != null) { | ||
return (C) assignment.getPolicyRule(); | ||
} | ||
return null; | ||
}; | ||
} | ||
|
||
private QName getRelationForDisplayNamePanel(PrismContainerValueWrapper<AssignmentType> modelObject) { | ||
AssignmentType assignment = modelObject.getRealValue(); | ||
if (assignment.getTargetRef() != null) { | ||
return assignment.getTargetRef().getRelation(); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
private IModel<String> getKindIntentLabelModelForDisplayNamePanel(PrismContainerValueWrapper<AssignmentType> modelObject) { | ||
AssignmentType assignment = modelObject.getRealValue(); | ||
if (assignment.getConstruction() != null) { | ||
PrismContainerValueWrapper<ConstructionType> constructionValue = null; | ||
try { | ||
PrismContainerWrapper<ConstructionType> construction = modelObject.findContainer(AssignmentType.F_CONSTRUCTION); | ||
if (construction == null) { | ||
return null; | ||
} | ||
constructionValue = construction.getValue(); | ||
} catch (SchemaException e) { | ||
LOGGER.error("Unexpected problem during construction wrapper lookup, {}", e.getMessage(), e); | ||
} | ||
ShadowKindType kind; | ||
String intent; | ||
if (constructionValue instanceof ConstructionValueWrapper) { | ||
kind = ((ConstructionValueWrapper) constructionValue).getKind(); | ||
intent = ((ConstructionValueWrapper) constructionValue).getIntent(); | ||
} else { | ||
kind = assignment.getConstruction().getKind(); | ||
intent = assignment.getConstruction().getIntent(); | ||
} | ||
|
||
return createStringResource("DisplayNamePanel.kindIntentLabel", kind, intent); | ||
} | ||
return Model.of(); | ||
} | ||
|
||
protected boolean getContainerReadability(ItemWrapper<?, ?> wrapper) { | ||
if (QNameUtil.match(ConstructionType.F_KIND, wrapper.getItemName())) { | ||
return false; | ||
} | ||
|
||
return !QNameUtil.match(ConstructionType.F_INTENT, wrapper.getItemName()); | ||
} | ||
|
||
private ItemVisibility getContainerVisibility(ItemWrapper<?, ?> wrapper) { | ||
if (wrapper instanceof PrismContainerWrapper) { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
return ItemVisibility.AUTO; | ||
} | ||
|
||
private PanelTab createTabs(String titleKey, ItemPath path, QName type) { | ||
return new PanelTab(createStringResource(titleKey)) { | ||
|
||
@Override | ||
public WebMarkupContainer createPanel(String panelId) { | ||
return new SingleContainerPanel<>(panelId, PrismContainerWrapperModel.fromContainerValueWrapper(getModel(), path), type); | ||
} | ||
}; | ||
|
||
} | ||
private PanelTab createConstructionTabs() { | ||
return createTabs("AssignmentType.construction", AssignmentType.F_CONSTRUCTION, ConstructionType.COMPLEX_TYPE); | ||
} | ||
|
||
private PanelTab createActivationTab() { | ||
return new PanelTab(createStringResource("AssignmentType.activation")) { | ||
@Override | ||
public WebMarkupContainer createPanel(String panelId) { | ||
return new SingleContainerPanel<>(panelId, | ||
PrismContainerWrapperModel.fromContainerValueWrapper(getModel(), AssignmentType.F_ACTIVATION), ActivationType.COMPLEX_TYPE) { | ||
|
||
@Override | ||
protected ItemVisibility getVisibility(ItemPath itemPath) { | ||
if (ItemPath.create(AssignmentHolderType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP).equivalent(itemPath.namedSegmentsOnly())) { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
|
||
if (ItemPath.create(AssignmentHolderType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).equivalent(itemPath.namedSegmentsOnly())) { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
|
||
if (ItemPath.create(AbstractRoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP).equivalent(itemPath.namedSegmentsOnly())) { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
|
||
if (ItemPath.create(AbstractRoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).equivalent(itemPath.namedSegmentsOnly())) { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
|
||
return super.getVisibility(itemPath); | ||
} | ||
}; | ||
} | ||
}; | ||
} | ||
|
||
private PanelTab createConditionTab() { | ||
return new PanelTab(createStringResource("AssignmentType.condition")) { | ||
|
||
@Override | ||
public WebMarkupContainer createPanel(String panelId) { | ||
return new SingleContainerPanel<>(panelId, PrismContainerWrapperModel.fromContainerValueWrapper(getModel(), AssignmentType.F_CONDITION), MappingType.COMPLEX_TYPE) { | ||
|
||
@Override | ||
protected ItemVisibility getVisibility(ItemPath itemPath) { | ||
ItemPath assignmentConditionExpressionPath = ItemPath.create(AssignmentHolderType.F_ASSIGNMENT, AssignmentType.F_CONDITION, MappingType.F_EXPRESSION); | ||
ItemPath inducementConditionExpressionPath = ItemPath.create(AbstractRoleType.F_INDUCEMENT, AssignmentType.F_CONDITION, MappingType.F_EXPRESSION); | ||
if (itemPath.namedSegmentsOnly().equivalent(assignmentConditionExpressionPath) || itemPath.namedSegmentsOnly().equivalent(inducementConditionExpressionPath)) { | ||
return ItemVisibility.AUTO; | ||
} else { | ||
return ItemVisibility.HIDDEN; | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.