package com.evolveum.midpoint.web.page.admin.workflow; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.web.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.data.column.CheckBoxHeaderColumn; import com.evolveum.midpoint.web.component.data.column.IconColumn; import com.evolveum.midpoint.web.component.data.column.LinkColumn; import com.evolveum.midpoint.web.page.admin.server.PageTaskEdit; import com.evolveum.midpoint.web.page.admin.server.dto.ApprovalOutcomeIcon; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.web.util.TooltipBehavior; import com.evolveum.midpoint.wf.util.ApprovalUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.List; import static com.evolveum.midpoint.gui.api.util.WebComponentUtil.dispatchToObjectDetailsPage; import static com.evolveum.midpoint.web.page.admin.workflow.ProcessInstancesPanel.View.FULL_LIST; import static com.evolveum.midpoint.web.page.admin.workflow.ProcessInstancesPanel.View.TASKS_FOR_PROCESS; import static com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto.*; /** * @author Kate * @author mederly */ public class ProcessInstancesPanel extends BasePanel { private static final String ID_REQUESTS_TABLE = "requestsTable"; private ISortableDataProvider<ProcessInstanceDto, String> provider; public enum View { FULL_LIST, // selectable, full information DASHBOARD, // view for dashboard (not selectable, maybe reduced view) TASKS_FOR_PROCESS // tasks for a process } public ProcessInstancesPanel(String id, ISortableDataProvider<ProcessInstanceDto, String> provider, UserProfileStorage.TableId tableId, int pageSize, View view, @Nullable IModel<String> currentInstanceIdModel) { super(id); this.provider = provider; initLayout(tableId, pageSize, view, currentInstanceIdModel); } private void initLayout(UserProfileStorage.TableId tableId, int pageSize, View view, final IModel<String> currentInstanceIdModel) { BoxedTablePanel<ProcessInstanceDto> table = new BoxedTablePanel<ProcessInstanceDto>( ID_REQUESTS_TABLE, provider, initColumns(view), tableId, pageSize) { @Override protected Item<ProcessInstanceDto> customizeNewRowItem(Item<ProcessInstanceDto> item, final IModel<ProcessInstanceDto> rowModel) { item.add(new AttributeAppender("class", new AbstractReadOnlyModel<String>() { @Override public String getObject() { if (currentInstanceIdModel == null || currentInstanceIdModel.getObject() == null) { return ""; } ProcessInstanceDto rowDto = rowModel.getObject(); if (currentInstanceIdModel.getObject().equals(rowDto.getProcessInstanceId())) { return "info"; } else { return ""; } } })); return item; } }; table.setOutputMarkupId(true); table.setAdditionalBoxCssClasses("without-box-header-top-border"); add(table); } public BoxedTablePanel<ProcessInstanceDto> getTablePanel() { return (BoxedTablePanel<ProcessInstanceDto>) get(ID_REQUESTS_TABLE); } private List<IColumn<ProcessInstanceDto, String>> initColumns(View view) { List<IColumn<ProcessInstanceDto, String>> columns = new ArrayList<>(); if (view != TASKS_FOR_PROCESS) { if (view == FULL_LIST) { columns.add(new CheckBoxHeaderColumn<>()); } columns.add(createNameColumn()); columns.add(createTypeIconColumn(true)); columns.add(createObjectNameColumn("pageProcessInstances.item.object")); columns.add(createTypeIconColumn(false)); columns.add(createTargetNameColumn("pageProcessInstances.item.target")); columns.add(createStageColumn()); //columns.add(createStateColumn()); columns.add(new PropertyColumn<ProcessInstanceDto, String>(createStringResource("pageProcessInstances.item.started"), F_START_FORMATTED)); columns.add(createOutcomeColumn()); columns.add(createFinishedColumn()); } else { columns.add(createNameColumn()); columns.add(createStageColumn()); //columns.add(createStateColumn()); columns.add(createOutcomeColumn()); columns.add(createFinishedColumn()); } return columns; } @NotNull private PropertyColumn<ProcessInstanceDto, String> createFinishedColumn() { return new PropertyColumn<>(createStringResource("pageProcessInstances.item.finished"), F_END_FORMATTED); } // @NotNull // private PropertyColumn<ProcessInstanceDto, String> createStateColumn() { // return new PropertyColumn<>(createStringResource("pageProcessInstances.item.state"), F_STATE); // } @NotNull private PropertyColumn<ProcessInstanceDto, String> createStageColumn() { return new PropertyColumn<>(createStringResource("pageProcessInstances.item.stage"), F_STAGE); } @NotNull private IColumn<ProcessInstanceDto,String> createNameColumn() { if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_TASKS_ALL_URL, AuthorizationConstants.AUTZ_UI_TASK_URL)) { return new LinkColumn<ProcessInstanceDto>(createStringResource("MyRequestsPanel.name"), "name") { @Override public void onClick(AjaxRequestTarget target, IModel<ProcessInstanceDto> rowModel) { ProcessInstanceDto piDto = rowModel.getObject(); itemDetailsPerformed(target, piDto.getTaskOid()); } }; } else { return new PropertyColumn<>(createStringResource("MyRequestsPanel.name"), F_NAME); } } @NotNull private IconColumn<ProcessInstanceDto> createOutcomeColumn() { return new IconColumn<ProcessInstanceDto>(createStringResource("pageProcessInstances.item.result")) { @Override protected IModel<String> createIconModel(final IModel<ProcessInstanceDto> rowModel) { return new AbstractReadOnlyModel<String>() { @Override public String getObject() { return choose(rowModel, null, ApprovalOutcomeIcon.IN_PROGRESS.getIcon(), ApprovalOutcomeIcon.APPROVED.getIcon(), ApprovalOutcomeIcon.REJECTED.getIcon()); } }; } @Override protected IModel<String> createTitleModel(final IModel<ProcessInstanceDto> rowModel) { return new AbstractReadOnlyModel<String>() { @Override public String getObject() { return choose(rowModel, null, createStringResource("MyRequestsPanel.inProgress").getString(), createStringResource("MyRequestsPanel.approved").getString(), createStringResource("MyRequestsPanel.rejected").getString()); } }; } private String choose(IModel<ProcessInstanceDto> rowModel, String noReply, String inProgress, String approved, String rejected) { ProcessInstanceDto dto = rowModel.getObject(); Boolean result = ApprovalUtils.approvalBooleanValueFromUri(dto.getOutcome()); if (result == null) { if (dto.getEndTimestamp() != null) { return noReply; } else { return inProgress; } } else { return result ? approved : rejected; } } }; } private void itemDetailsPerformed(AjaxRequestTarget target, String pid) { PageParameters parameters = new PageParameters(); parameters.add(OnePageParameterEncoder.PARAMETER, pid); getPageBase().navigateToNext(PageTaskEdit.class, parameters); } // copied and adapted from WorkItemsPanel - TODO deduplicate IColumn<ProcessInstanceDto, String> createObjectNameColumn(final String headerKey) { return new LinkColumn<ProcessInstanceDto>(createStringResource(headerKey), ProcessInstanceDto.F_OBJECT_NAME) { @Override public void onClick(AjaxRequestTarget target, IModel<ProcessInstanceDto> rowModel) { ProcessInstanceDto dto = rowModel.getObject(); dispatchToObjectDetailsPage(dto.getObjectRef(), getPageBase(), false); } }; } IColumn<ProcessInstanceDto, String> createTargetNameColumn(final String headerKey) { return new LinkColumn<ProcessInstanceDto>(createStringResource(headerKey), ProcessInstanceDto.F_TARGET_NAME) { @Override public void onClick(AjaxRequestTarget target, IModel<ProcessInstanceDto> rowModel) { ProcessInstanceDto dto = rowModel.getObject(); dispatchToObjectDetailsPage(dto.getTargetRef(), getPageBase(), false); } }; } public IColumn<ProcessInstanceDto, String> createTypeIconColumn(final boolean object) { // true = object, false = target return new IconColumn<ProcessInstanceDto>(createStringResource("")) { @Override protected IModel<String> createIconModel(IModel<ProcessInstanceDto> rowModel) { if (getObjectType(rowModel) == null) { return null; } ObjectTypeGuiDescriptor guiDescriptor = getObjectTypeDescriptor(rowModel); String icon = guiDescriptor != null ? guiDescriptor.getBlackIcon() : ObjectTypeGuiDescriptor.ERROR_ICON; return new Model<>(icon); } private ObjectTypeGuiDescriptor getObjectTypeDescriptor(IModel<ProcessInstanceDto> rowModel) { QName type = getObjectType(rowModel); return ObjectTypeGuiDescriptor.getDescriptor(ObjectTypes.getObjectTypeFromTypeQName(type)); } private QName getObjectType(IModel<ProcessInstanceDto> rowModel) { return object ? rowModel.getObject().getObjectType() : rowModel.getObject().getTargetType(); } @Override public void populateItem(Item<ICellPopulator<ProcessInstanceDto>> item, String componentId, IModel<ProcessInstanceDto> rowModel) { super.populateItem(item, componentId, rowModel); ObjectTypeGuiDescriptor guiDescriptor = getObjectTypeDescriptor(rowModel); if (guiDescriptor != null) { item.add(AttributeModifier.replace("title", createStringResource(guiDescriptor.getLocalizationKey()))); item.add(new TooltipBehavior()); } } }; } }