Skip to content

Commit

Permalink
simulations - improved default sorting (by timestamp) for sim results…
Browse files Browse the repository at this point in the history
… & added new column with progress bar & processed objects changes counts
  • Loading branch information
1azyman committed Mar 16, 2023
1 parent 5b5db80 commit 7646b54
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@

package com.evolveum.midpoint.gui.impl.page.admin.simulation;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
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.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import com.evolveum.midpoint.authentication.api.authorization.AuthorizationAction;
import com.evolveum.midpoint.authentication.api.authorization.PageDescriptor;
import com.evolveum.midpoint.authentication.api.authorization.Url;
Expand Down Expand Up @@ -37,30 +57,6 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
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.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import javax.xml.datatype.XMLGregorianCalendar;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
* Created by Viliam Repan (lazyman).
*/
Expand Down Expand Up @@ -242,31 +238,26 @@ protected List<DashboardWidgetType> load() {
}

private void addBuiltInMetrics(List<DetailsTableItem> result) {
List<SimulationMetricValuesType> metrics = resultModel.getObject().getMetric();
List<SimulationMetricValuesType> builtIn = metrics.stream().filter(m -> m.getRef() != null && m.getRef().getBuiltIn() != null)
.collect(Collectors.toList());
SimulationResultType simResult = resultModel.getObject();
Map<BuiltInSimulationMetricType, Integer> builtIn = SimulationsGuiUtil.getBuiltInMetrics(simResult);

List<DetailsTableItem> items = new ArrayList<>();

int totalCount = SimulationResultTypeUtil.getObjectsProcessed(resultModel.getObject());
int unmodifiedCount = totalCount;

for (SimulationMetricValuesType metric : builtIn) {
BuiltInSimulationMetricType identifier = metric.getRef().getBuiltIn();

BigDecimal value = SimulationMetricValuesTypeUtil.getValue(metric);
unmodifiedCount = unmodifiedCount - value.intValue();
for (Map.Entry<BuiltInSimulationMetricType, Integer> entry : builtIn.entrySet()) {
BuiltInSimulationMetricType identifier = entry.getKey();
int value = entry.getValue();

items.add(createDetailsItemForBuiltInMetric(identifier, value));
}

final int finalUnmodified = unmodifiedCount;
int unmodifiedCount = SimulationsGuiUtil.getUnmodifiedProcessedObjectCount(simResult, builtIn);

items.sort(Comparator.comparing(d -> d.getLabel().getObject(), Comparator.naturalOrder()));

items.add(createDetailsItemForBuiltInMetric(
createStringResource("PageSimulationResultObject.UnmodifiedObjects"),
() -> Integer.toString(finalUnmodified),
() -> Integer.toString(unmodifiedCount),
target -> redirectToProcessedObjects((BuiltInSimulationMetricType) null))
);

Expand All @@ -279,7 +270,7 @@ private void addBuiltInMetrics(List<DetailsTableItem> result) {
result.addAll(items);
}

private DetailsTableItem createDetailsItemForBuiltInMetric(BuiltInSimulationMetricType identifier, BigDecimal value) {
private DetailsTableItem createDetailsItemForBuiltInMetric(BuiltInSimulationMetricType identifier, Number value) {
IModel<String> nameModel = createStringResource("PageSimulationResultObject." + WebComponentUtil.createEnumResourceKey(identifier));
IModel<String> valueModel = () -> MetricWidgetPanel.formatValue(value, getPrincipal().getLocale());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2010-2023 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.page.admin.simulation;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.model.IModel;
import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.gui.api.component.progressbar.ProgressBar;
import com.evolveum.midpoint.gui.api.util.LocalizationUtil;
import com.evolveum.midpoint.util.SingleLocalizableMessage;
import com.evolveum.midpoint.web.component.data.column.ProgressBarColumn;

/**
* Created by Viliam Repan (lazyman).
*/
public abstract class ProcessedObjectsCountColumn<R extends Serializable, S extends Serializable> extends ProgressBarColumn<R, S> {

public ProcessedObjectsCountColumn(IModel<String> displayModel) {
super(displayModel);
}

protected abstract @NotNull IModel<ObjectCounts> createCountModel(IModel<R> rowModel);

@Override
protected @NotNull IModel<List<ProgressBar>> createProgressBarModel(IModel<R> rowModel) {
return () -> {
ObjectCounts counts = createCountModel(rowModel).getObject();

List<ProgressBar> list = new ArrayList<>();
addProgressBar(list, ProgressBar.State.SUCCESS, counts.getAdded(), counts, "ProcessedObjectsCountColumn.added");
addProgressBar(list, ProgressBar.State.INFO, counts.getModified(), counts, "ProcessedObjectsCountColumn.modified");
addProgressBar(list, ProgressBar.State.DANGER, counts.getDeleted(), counts, "ProcessedObjectsCountColumn.deleted");
addProgressBar(list, ProgressBar.State.SECONDARY, counts.getUnmodified(), counts, "ProcessedObjectsCountColumn.unmodified");

return list;
};
}

private void addProgressBar(List<ProgressBar> list, ProgressBar.State state, int value, ObjectCounts counts, String key) {
list.add(new ProgressBar(value * 100 / (double) counts.getTotal(), state, new SingleLocalizableMessage(key, new Object[] { value })));
}

@Override
protected @NotNull IModel<String> createTextModel(IModel<R> rowModel, IModel<List<ProgressBar>> model) {
return () -> {
Object[] array = model.getObject().stream()
.filter(p -> p.getValue() > 0)
.map(p -> LocalizationUtil.translateMessage(p.getText()))
.toArray();

if (array.length == 0) {
return LocalizationUtil.translate("ProcessedObjectsCountColumn.noChanges");
}

return StringUtils.joinWith(" / ", array);
};
}

public static class ObjectCounts implements Serializable {

private int added;

private int modified;

private int deleted;

private int unmodified;

private int total;

public int getAdded() {
return added;
}

public void setAdded(int added) {
this.added = added;
}

public int getModified() {
return modified;
}

public void setModified(int modified) {
this.modified = modified;
}

public int getDeleted() {
return deleted;
}

public void setDeleted(int deleted) {
this.deleted = deleted;
}

public int getUnmodified() {
return unmodified;
}

public void setUnmodified(int unmodified) {
this.unmodified = unmodified;
}

public int getTotal() {
return total;
}

public void setTotal(int total) {
this.total = total;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,16 @@

package com.evolveum.midpoint.gui.impl.page.admin.simulation;

import java.util.ArrayList;
import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;

import com.evolveum.midpoint.gui.api.component.data.provider.ISelectableDataProvider;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.LambdaColumn;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import com.evolveum.midpoint.gui.api.component.MainObjectListPanel;
import com.evolveum.midpoint.gui.api.component.data.provider.ISelectableDataProvider;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.impl.component.icon.CompositedIconBuilder;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.SimulationResultTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.logging.LoggingUtils;
Expand All @@ -43,10 +29,26 @@
import com.evolveum.midpoint.web.component.util.SelectableBean;
import com.evolveum.midpoint.web.page.admin.users.component.ExecuteChangeOptionsDto;
import com.evolveum.midpoint.web.session.UserProfileStorage;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ContainerPanelConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiObjectColumnType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SimulationResultType;
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.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.LambdaColumn;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.jetbrains.annotations.NotNull;

import javax.xml.datatype.XMLGregorianCalendar;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Created by Viliam Repan (lazyman).
Expand All @@ -67,7 +69,11 @@ public SimulationResultsPanel(String id, ContainerPanelConfigurationType config)

@Override
protected ISelectableDataProvider<SelectableBean<SimulationResultType>> createProvider() {
return super.createProvider();
ISelectableDataProvider<SelectableBean<SimulationResultType>> provider = super.createProvider();
if (provider instanceof SortableDataProvider) {
((SortableDataProvider) provider).setSort(SimulationResultType.F_START_TIMESTAMP.getLocalPart(), SortOrder.DESCENDING);
}
return provider;
}

@Override
Expand Down Expand Up @@ -226,6 +232,7 @@ public void populateItem(Item<ICellPopulator<SelectableBean<SimulationResultType
item.add(label);
}
});
columns.add(createProcessedObjectsColumn());

return columns;
}
Expand All @@ -249,6 +256,46 @@ protected IColumn<SelectableBean<SimulationResultType>, String> createCustomExpo
return super.createCustomExportableColumn(displayModel, customColumn, expression);
}

private IColumn<SelectableBean<SimulationResultType>, String> createProcessedObjectsColumn() {
return new ProcessedObjectsCountColumn<>(createStringResource("SimulationResultsPanel.processedObjects")) {

@Override
protected @NotNull IModel<ObjectCounts> createCountModel(IModel<SelectableBean<SimulationResultType>> rowModel) {
return new LoadableDetachableModel<>() {

@Override
protected ObjectCounts load() {
ObjectCounts counts = new ObjectCounts();

SimulationResultType result = rowModel.getObject().getValue();
int total = SimulationResultTypeUtil.getObjectsProcessed(result);
counts.setTotal(total);

Map<BuiltInSimulationMetricType, Integer> builtIn = SimulationsGuiUtil.getBuiltInMetrics(result);
builtIn.forEach((k, v) -> {
switch (k) {
case ADDED:
counts.setAdded(v);
break;
case MODIFIED:
counts.setModified(v);
break;
case DELETED:
counts.setDeleted(v);
break;
}
});

int unmodified = SimulationsGuiUtil.getUnmodifiedProcessedObjectCount(result, builtIn);
counts.setUnmodified(unmodified);

return counts;
}
};
}
};
}

private IColumn<SelectableBean<SimulationResultType>, String> createStartTimestampColumn(IModel<String> displayModel) {
return new LambdaColumn<>(displayModel, SimulationResultType.F_START_TIMESTAMP.getLocalPart(), row -> {
XMLGregorianCalendar start = row.getValue().getStartTimestamp();
Expand Down

0 comments on commit 7646b54

Please sign in to comment.