Skip to content

Commit

Permalink
change step with basic setting for construction to selecting resource…
Browse files Browse the repository at this point in the history
… object types (role wizard)
  • Loading branch information
skublik committed Feb 16, 2023
1 parent 27964dd commit 5f6bb3b
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2289,7 +2289,10 @@ public static String createShadowIcon(PrismObject<ShadowType> object) {
return GuiStyleConstants.CLASS_SHADOW_ICON_PROTECTED;
}

ShadowKindType kind = shadow.getKind();
return createShadowIcon(shadow.getKind());
}

public static String createShadowIcon(@Nullable ShadowKindType kind) {
if (kind == null) {
return GuiStyleConstants.CLASS_SHADOW_ICON_UNKNOWN;
}
Expand Down Expand Up @@ -3715,7 +3718,6 @@ public static List<ResourceAssociationDefinition> getRefinedAssociationDefinitio

public static ResourceObjectDefinition getResourceObjectDefinition(ConstructionType construction, PageBase pageBase) throws CommonException {

PrismContext prismContext = pageBase.getPrismContext();
if (construction == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
import com.evolveum.midpoint.gui.impl.page.admin.assignmentholder.FocusDetailsModels;

import com.evolveum.midpoint.gui.impl.page.admin.resource.component.wizard.objectType.attributeMapping.AttributeOutboundStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction.BasicConstructionStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction.ConstructionGroupStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction.ConstructionOutboundMappingsStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction.ConstructionResourceStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction.*;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType;
Expand Down Expand Up @@ -125,7 +122,7 @@ protected void onExitPerformed(AjaxRequestTarget target) {

steps.add(selectResource);

steps.add(new BasicConstructionStepPanel(getHelper().getDetailsModel(), selectResource.getValueModel()){
steps.add(new ConstructionResourceObjectTypeStepPanel(getHelper().getDetailsModel(), selectResource.getValueModel()){
@Override
protected void onExitPerformed(AjaxRequestTarget target) {
super.onExitPerformed(target);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>

<!--
~ Copyright (c) 2022 Evolveum
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:extend>
<div class="request-access-wizard d-flex flex-wrap gap-3 justify-content-center" wicket:id="tilesContainer">
<wicket:container wicket:id="tiles">
<div class="card mb-0 simple-tile selectable" wicket:id="tile"/>
</wicket:container>
</div>
</wicket:extend>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
package com.evolveum.midpoint.gui.impl.page.admin.role.component.wizard.construction;

import com.evolveum.midpoint.gui.api.component.result.Toast;
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismPropertyWrapper;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.impl.component.tile.Tile;
import com.evolveum.midpoint.gui.impl.component.tile.TilePanel;
import com.evolveum.midpoint.gui.impl.component.wizard.AbstractWizardStepPanel;
import com.evolveum.midpoint.gui.impl.page.admin.assignmentholder.FocusDetailsModels;
import com.evolveum.midpoint.gui.impl.page.admin.resource.component.TemplateTile;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.processor.ResourceObjectTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.processor.ResourceSchemaFactory;
import com.evolveum.midpoint.util.exception.CommonException;
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.application.PanelDisplay;
import com.evolveum.midpoint.web.application.PanelInstance;
import com.evolveum.midpoint.web.application.PanelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@PanelType(name = "roleWizard-construction-objectType")
@PanelInstance(identifier = "roleWizard-construction-objectType",
applicableForType = RoleType.class,
applicableForOperation = OperationTypeType.ADD,
display = @PanelDisplay(label = "PageRole.wizard.step.construction.objectType", icon = "fa fa-database"),
containerPath = "empty")
public class ConstructionResourceObjectTypeStepPanel extends AbstractWizardStepPanel<FocusDetailsModels<RoleType>> {

private static final Trace LOGGER = TraceManager.getTrace(ConstructionResourceObjectTypeStepPanel.class);

public static final String PANEL_TYPE = "roleWizard-construction-objectType";

private static final String ID_TILES_CONTAINER = "tilesContainer";
private static final String ID_TILES = "tiles";
private static final String ID_TILE = "tile";

private final IModel<PrismContainerValueWrapper<ConstructionType>> valueModel;
private IModel<List<Tile<ResourceObjectTypeWrapper>>> tilesModel;

public ConstructionResourceObjectTypeStepPanel(
FocusDetailsModels<RoleType> model, IModel<PrismContainerValueWrapper<AssignmentType>> valueModel) {
super(model);
this.valueModel = new LoadableDetachableModel<>() {
@Override
protected PrismContainerValueWrapper<ConstructionType> load() {
try {
PrismContainerValueWrapper value =
valueModel.getObject().findContainer(AssignmentType.F_CONSTRUCTION).getValue();
return value;
} catch (SchemaException e) {
LOGGER.error("Couldn't find construction container in assignment");
}
return null;
}
};
}

@Override
protected void onInitialize() {
super.onInitialize();
initTilesModel();
initLayout();
}

private void initTilesModel() {
if (tilesModel == null) {
tilesModel = new LoadableModel<>(false) {
@Override
protected List<Tile<ResourceObjectTypeWrapper>> load() {
List<Tile<ResourceObjectTypeWrapper>> list = new ArrayList<>();
ConstructionType construction = valueModel.getObject().getRealValue();
if (construction == null) {
return list;
}
PrismObject<ResourceType> resource =
WebComponentUtil.getConstructionResource(construction, "load resource", getPageBase());
if (resource == null) {
return list;
}

try {
ResourceSchema schema = ResourceSchemaFactory.getCompleteSchema(resource);
ResourceObjectTypeDefinition actualOc =
(ResourceObjectTypeDefinition) WebComponentUtil.getResourceObjectDefinition(construction, getPageBase());
schema.getObjectTypeDefinitions().forEach(oc -> {
String icon = WebComponentUtil.createShadowIcon(oc.getKind());

String description = oc.getDescription();

String name;
if (oc.isDefaultForKind()) {
name = createStringResource(
"ConstructionResourceObjectTypeStepPanel.isDefaultForKindName",
createStringResource(oc.getKind()).getString()).getString();
} else {
name = createStringResource(
"ConstructionResourceObjectTypeStepPanel.kindIntentName",
createStringResource(oc.getKind()).getString(),
oc.getIntent()).getString();
}
TemplateTile<ResourceObjectTypeWrapper> t = new TemplateTile<>(
icon, name, new ResourceObjectTypeWrapper(oc))
.description(description);
t.setSelected(matchResourceObjectTypes(actualOc, oc));
list.add(t);
});
} catch (CommonException e) {
LOGGER.error("Couldn't create ResourceSchema for resource: " + resource, e);
}
return list;
}
};
}
}

private boolean matchResourceObjectTypes(ResourceObjectTypeDefinition actualOc, ResourceObjectTypeDefinition oc) {
if (actualOc == null) {
return false;
}

if (actualOc.isDefaultForKind()) {
return oc.isDefaultForKind() && actualOc.matchesKind(oc.getKind());
}
return actualOc.matches(oc.getKind(), oc.getIntent());
}

private void initLayout() {
WebMarkupContainer tilesContainer = new WebMarkupContainer(ID_TILES_CONTAINER);
tilesContainer.setOutputMarkupId(true);
add(tilesContainer);

ListView<Tile<ResourceObjectTypeWrapper>> list = new ListView<>(ID_TILES, tilesModel) {

@Override
protected void populateItem(ListItem<Tile<ResourceObjectTypeWrapper>> item) {
item.add(createTilePanel(ID_TILE, item.getModel()));
}
};
tilesContainer.add(list);
}

protected Component createTilePanel(String id, IModel<Tile<ResourceObjectTypeWrapper>> model) {
return new TilePanel<>(id, model) {

@Override
protected void onInitialize() {
super.onInitialize();
get("title").add(AttributeAppender.replace("class", "mt-4 text-secondary text-center"));
add(AttributeAppender.replace(
"class", () -> {
String active = "";
if (getModelObject().isSelected()) {
active = "active ";
}
return active +
"catalog-tile-panel card mb-0 simple-tile selectable tile-panel "
+ "d-flex flex-column align-items-center rounded p-3";
}));
}

@Override
protected void onClick(AjaxRequestTarget target) {
boolean oldState = getModelObject().isSelected();
tilesModel.getObject().forEach(tile -> tile.setSelected(false));

getModelObject().setSelected(!oldState);

target.add(ConstructionResourceObjectTypeStepPanel.this.get(ID_TILES_CONTAINER));
}
};
}

@Override
protected boolean isExitButtonVisible() {
return true;
}

protected String getIcon() {
return "fa fa-database";
}

@Override
public IModel<String> getTitle() {
return createStringResource("PageRole.wizard.step.construction.objectType");
}

@Override
protected IModel<?> getTextModel() {
return createStringResource("PageRole.wizard.step.construction.objectType.text");
}

@Override
protected IModel<?> getSubTextModel() {
return createStringResource("PageRole.wizard.step.construction.objectType.subText");
}

@Override
public String appendCssToWizard() {
return "mt-5 mx-auto col-10 col-sm-12";
}

@Override
public boolean onNextPerformed(AjaxRequestTarget target) {
if (isValid(target)) {
performSelectedObjects();
return super.onNextPerformed(target);
}
return false;
}

private void performSelectedObjects() {
Optional<Tile<ResourceObjectTypeWrapper>> selectedTile =
tilesModel.getObject().stream().filter(tile -> tile.isSelected()).findFirst();
try {
PrismPropertyWrapper<ShadowKindType> kind = valueModel.getObject().findProperty(ConstructionType.F_KIND);
kind.getValue().setRealValue(selectedTile.get().getValue().kind);
} catch (SchemaException e) {
LOGGER.error("Couldn't find kind property in construction value");
}

try {
PrismPropertyWrapper<String> kind = valueModel.getObject().findProperty(ConstructionType.F_INTENT);
kind.getValue().setRealValue(selectedTile.get().getValue().intent);
} catch (SchemaException e) {
LOGGER.error("Couldn't find kind property in construction value");
}
}

private boolean isValid(AjaxRequestTarget target) {
if (isNotSelected()) {
String key = "ConstructionResourceObjectTypeStepPanel.isMandatory";
new Toast()
.error()
.title(PageBase.createStringResourceStatic(key).getString())
.icon("fas fa-circle-exclamation")
.autohide(true)
.delay(5_000)
.body(PageBase.createStringResourceStatic(key + ".text").getString())
.show(target);
return false;
}
return true;
}

private boolean isNotSelected() {
Optional<Tile<ResourceObjectTypeWrapper>> selectedTile =
tilesModel.getObject().stream().filter(tile -> tile.isSelected()).findFirst();
return selectedTile.isEmpty();
}

class ResourceObjectTypeWrapper implements Serializable {

private final ShadowKindType kind;
private final String intent;

private ResourceObjectTypeWrapper(ResourceObjectTypeDefinition oc) {
this.kind = oc.getKind();
this.intent = oc.getIntent();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
containerPath = "empty")
public class ConstructionResourceStepPanel extends SingleTileWizardStepPanel<ResourceType, FocusDetailsModels<RoleType>, AssignmentType> {

private static final Trace LOGGER = TraceManager.getTrace(SelectTileWizardStepPanel.class);
private static final Trace LOGGER = TraceManager.getTrace(ConstructionResourceStepPanel.class);

public static final String PANEL_TYPE = "roleWizard-construction-resource";

Expand Down

0 comments on commit 5f6bb3b

Please sign in to comment.