Change Workflow Node Name Dynamically

OpenKM has many interesting features, but requires some configuration process to show its full potential.
Forum rules
Please, before asking something see the documentation wiki or use the search feature of the forum. And remember we don't have a crystal ball or mental readers, so if you post about an issue tell us which OpenKM are you using and also the browser and operating system version. For more info read How to Report Bugs Effectively.
Post Reply
alexwgordon
Gold Boarder
Gold Boarder
Posts: 182
Joined: Fri Sep 05, 2014 6:24 pm

Change Workflow Node Name Dynamically

Post by alexwgordon » Tue Dec 20, 2016 7:57 pm

Hi there,

Is there a way to dynamically change the name of the nodes/tasks that are in a workflow? For example we can have 70 tasks that need to be completed in someone's dashboard and if they're all titled the same thing, they have no idea which one is which without clicking on each one.

I basically want to put the document title in the Task name or include a column that shows the doc name. Thanks!

jllort
Moderator
Moderator
Posts: 10834
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Change Workflow Node Name Dynamically

Post by jllort » Thu Dec 22, 2016 12:39 pm

We have added extra column in professional version for the issue you are talking about, but this is still not present in community edition. Basically the column provide little information about affected nodes etc. The source code needs minimal changes for it, if you want, I can give to you some clues about which are the involved classes for it.

alexwgordon
Gold Boarder
Gold Boarder
Posts: 182
Joined: Fri Sep 05, 2014 6:24 pm

Re: Change Workflow Node Name Dynamically

Post by alexwgordon » Thu Dec 22, 2016 3:15 pm

Yes that would be awesome if you could help me figure out which files need modifying and everything!

jllort
Moderator
Moderator
Posts: 10834
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Change Workflow Node Name Dynamically

Post by jllort » Thu Dec 22, 2016 7:34 pm

You can take a look at these classes
Dashboard.java ( is the main widget, not much interesting for you ).

You should concentrate in WorkflowWidget.java where the table is really build ( line 175 setTasks ). My suggestion is create a more complex row or set data in two rows, for example a second row with document complete path and icon.

With something like it, you can get the uuid of the object ( folder or document what has started the workflow )

Code: Select all

final String uuid = (String) taskInstanceResult.getProcessInstance().getVariables().get("uuid");
With the uuid, you can get document properties

Code: Select all

// convert uuid to path
repositoryService.getPathByUUID(uuid, new AsyncCallback<String>() {
	@Override
	public void onSuccess(final String path) {
		// Getting the document properties
		documentService.getProperties(path, new AsyncCallback<GWTDocument>() {
			@Override
			public void onSuccess(GWTDocument doc) {
				hPanelDocument.add(new HTML(Util.mimeImageHTML(doc.getMimeType())));
				// Here write the table
				
				// To the document icon:
				table.setHTML(row, col, Util.mimeImageHTML(doc.getMimeType()));
			}

			@Override
			public void onFailure(Throwable caught) {
				Main.get().showError("getProperties", caught);
			}
		});
	
	@Override
	public void onFailure(Throwable caught) {
		Main.get().showError("getPathByUUID", caught);
	}
});
Finally if you are interested in GWT debug take a look here https://wiki.openkm.com/index.php/Debugging_with_GWT ( the plugin http://www.gwtproject.org/missing-plugin/ is compatible with firefox 24 and older but not with latest versions. There's a super dev mode for GWT but is quite complex get it running and I do not suggest it ).

alexwgordon
Gold Boarder
Gold Boarder
Posts: 182
Joined: Fri Sep 05, 2014 6:24 pm

Re: Change Workflow Node Name Dynamically

Post by alexwgordon » Wed Jan 04, 2017 7:38 pm

Okay so I should somehow implement the UUID call and the document properties call after Line 175 within the setTasks for loop yes? I'm a little confused because I can't quite figure out where to put it. I placed it and I'm getting all kinds of errors. I'm not understanding all the GWT stuff, so I think that's part of my confusion.
Attachments
Screen Shot 2017-01-04 at 11.38.06.png

jllort
Moderator
Moderator
Posts: 10834
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Change Workflow Node Name Dynamically

Post by jllort » Thu Jan 05, 2017 11:35 am

You need to declare at the begining of the class :

Code: Select all

private final OKMDocumentServiceAsync documentService = (OKMDocumentServiceAsync) GWT.create(OKMDocumentService.class);
the hPanelDocument is an HorizontalPanel ( you should create one ):

Code: Select all

final HorizontalPanel hPanelDocument = new HorizontalPanel();
and make something like:

Code: Select all

table.setWidget(row + 1, 1, hPanelDocument);
table.getFlexCellFormatter().setColSpan(row + 1, 1, 3);
Also must import Util.class

Code: Select all

import com.openkm.frontend.client.util.Util;
I give to you some piece of code from professional edition, obviously can not be directly applied into the community edition, take it as reference ( clues for getting it ).

alexwgordon
Gold Boarder
Gold Boarder
Posts: 182
Joined: Fri Sep 05, 2014 6:24 pm

Re: Change Workflow Node Name Dynamically

Post by alexwgordon » Tue Jun 27, 2017 2:53 pm

is there any new documentation on how to do something like this? I'm still quite confused on how to accomplish this. I've tried the above codes, but with no success unfortunately

alexwgordon
Gold Boarder
Gold Boarder
Posts: 182
Joined: Fri Sep 05, 2014 6:24 pm

Re: Change Workflow Node Name Dynamically

Post by alexwgordon » Wed Jun 28, 2017 4:46 pm

So I've got most of the errors resolved (at least in Eclipse), except the documentService.getProperties... and table.setHTML(row, col...

Errors are:
1. getProperties for documentService (which is true based on documentation)
2. row Cannot refer to a non-final variable row inside an inner class defined in a different method

Everything else has been more or less resolved by importing the various classes.

Here is what I have:

Code: Select all

OpenKM, Open Document Management System (http://www.openkm.com)
 *  Copyright (c) 2006-2015  Paco Avila & Josep Llort
 *
 *  No bytes were intentionally harmed during the development of this application.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package com.openkm.frontend.client.widget.dashboard.workflow;

import java.util.List;
import java.util.ListIterator;

import org.apache.chemistry.opencmis.server.impl.browser.RepositoryService;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.openkm.frontend.client.Main;
import com.openkm.frontend.client.bean.GWTDocument;
import com.openkm.frontend.client.bean.GWTTaskInstance;
import com.openkm.frontend.client.widget.ConfirmPopup;
import com.openkm.frontend.client.widget.dashboard.Status;
import com.openkm.frontend.client.service.OKMDocumentService;
import com.openkm.frontend.client.service.OKMDocumentServiceAsync;
import com.openkm.frontend.client.service.OKMRepositoryService;
//Alex
import com.openkm.frontend.client.util.Util;
import com.openkm.frontend.client.service.OKMRepositoryServiceAsync;
import com.openkm.rest.endpoint.DocumentService;

/**
 * WorkflowWidget
 * 
 * @author jllort
 *
 */
public class WorkflowWidget extends Composite {
	
	private static final int TYPE_PENDING_TASK 	= 1;
	private static final int TYPE_POOLED_TASK 	= 2;

	private static int HEADER_SQUARE = 24;
	private static int SEPARATOR_HEIGHT = 20;
	private static int SEPARATOR_WIDTH = 20;
	
	private VerticalPanel vPanel;
	private SimplePanel spTop;
	private HorizontalPanel hPanel;
	private SimplePanel spLeft;
	private VerticalPanel vCenterPanel;
	private SimplePanel spRight;
	private Header header;
	private SimplePanel panelData;
	private FlexTable table;
	private Image zoomImage;
	private boolean zoom = false;
	private boolean flagZoom = true;
	public Status status;
	private String headerTextKey;
	private int widgetType = TYPE_PENDING_TASK;
	private GWTTaskInstance taskInstancePooled = null;
	private double processToExecuteNextTask = -1;

	private final OKMDocumentServiceAsync documentService = (OKMDocumentServiceAsync) GWT.create(OKMDocumentService.class);
	private final OKMRepositoryServiceAsync repositoryService = (OKMRepositoryServiceAsync) GWT.create(OKMRepositoryService.class);
	
	/**
	 * WorkflowWidget
	 */
	public WorkflowWidget(String headerTextKey, String iconUrl, boolean zoom) {
		status = new Status();
		status.setStyleName("okm-StatusPopup");
		
		spTop = new SimplePanel();
		spLeft = new SimplePanel();
		spRight = new SimplePanel();
		panelData = new SimplePanel();
		table = new FlexTable();
		vCenterPanel = new VerticalPanel();
		hPanel = new HorizontalPanel();
		header = new Header(iconUrl, zoom);
		vPanel = new VerticalPanel();
		this.headerTextKey = headerTextKey;
		
		// Sets or unsets visible table
		table.setVisible(zoom);
		
		header.setHeaderText(Main.i18n(headerTextKey));
		
		panelData.add(table);
		
		vCenterPanel.add(header);
		vCenterPanel.add(panelData);
		
		hPanel.add(spLeft);
		hPanel.add(vCenterPanel);
		hPanel.add(spRight);
		
		vPanel.add(spTop);
		vPanel.add(hPanel);
		
		spTop.setHeight(""+SEPARATOR_HEIGHT);
		spLeft.setWidth(""+SEPARATOR_WIDTH);
		spRight.setWidth(""+SEPARATOR_WIDTH);
		
		vPanel.setStyleName("okm-DashboardWidget ");
		panelData.setStyleName("data");
		table.setStyleName("okm-NoWrap");
		
		panelData.setWidth("99.6%");
		header.setWidth("100%");
		
		table.setCellPadding(0);
		table.setCellSpacing(0);
		
		vPanel.addStyleName("okm-DisableSelect");
		
		initWidget(vPanel);
	}
	
	/**
	 * setHeaderText
	 * 
	 * @param text
	 */
	public void setHeaderText(String text) {
		header.setHeaderText(text);
	}
	
	/**
	 * setHeaderResults
	 * 
	 * @param value
	 */
	public void setHeaderResults(int value) {
		header.setHeaderResults(value);
	}
	
	/**
	 * setWidth
	 * 
	 * @param width
	 */
	public void setWidth(int width) {
		vCenterPanel.setWidth(""+(width-2*SEPARATOR_WIDTH));
	}
	
	/**
	 * removeAllRows
	 */
	private void removeAllRows() {
		while (table.getRowCount()>0) {
			table.removeRow(0);
		}
	}
	
	/**
	 * Setting documents
	 * 
	 * @param docList document list
	 */
	public void setTasks(List<GWTTaskInstance> taskIntanceList) {
		int tasksNotViewed = 0;
		removeAllRows();
		
		for (ListIterator<GWTTaskInstance> it = taskIntanceList.listIterator(); it.hasNext();) {
			int row = table.getRowCount();
			final GWTTaskInstance taskInstanceResult = it.next();
			
			if (taskInstanceResult.getProcessInstance().getId() == processToExecuteNextTask) {
				processToExecuteNextTask = -1;
				Main.get().mainPanel.dashboard.workflowDashboard.workflowFormPanel.setTaskInstance(taskInstanceResult);
			}
			
			Anchor taskName = new Anchor();
			taskName.setText(taskInstanceResult.getName());
			taskName.setTitle(taskInstanceResult.getProcessInstance().getProcessDefinition().getName());
			
			switch (widgetType) {
				case TYPE_PENDING_TASK:
					final String uuid = (String) taskInstanceResult.getProcessInstance().getVariables().get("uuid");
					taskName.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(ClickEvent event) {
							Main.get().mainPanel.dashboard.workflowDashboard.workflowFormPanel.setTaskInstance(taskInstanceResult);
							
							// convert uuid to path
							repositoryService.getPathByUUID(uuid, new AsyncCallback<String>() {
								@Override
								public void onSuccess(final String path) {
								   // Getting the document properties
									documentService.getProperties(path, new AsyncCallback<GWTDocument>() {
											@Override
											public void onSuccess(GWTDocument doc) {
													hPanel.add(new HTML(Util.mimeImageHTML(doc.getMimeType())));
													// Here write the table
													
													// To the document icon:
													table.setHTML(row, col, Util.mimeImageHTML(doc.getMimeType()));
											}

											@Override
											public void onFailure(Throwable caught) {
													Main.get().showError("getProperties", caught);
											}
									});
								};
								
								@Override
								public void onFailure(Throwable caught) {
										Main.get().showError("getPathByUUID", caught);
								}
							});
						}
					});
					break;
					
				case TYPE_POOLED_TASK:
					taskName.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(ClickEvent event) {
							Main.get().confirmPopup.setConfirm(ConfirmPopup.CONFIRM_GET_POOLED_WORKFLOW_TASK);
							Main.get().confirmPopup.show();
							taskInstancePooled = taskInstanceResult;
						}
					});
					break;
			}
			
			taskName.setStyleName("okm-Hyperlink");
						
			table.setHTML(row, 0, "");
			table.setWidget(row, 1, taskName);
			DateTimeFormat dtf = DateTimeFormat.getFormat(Main.i18n("general.date.pattern"));
			table.setHTML(row, 2, dtf.format(taskInstanceResult.getCreate()));
			table.getCellFormatter().setWidth(row, 0, "20"); 
			table.getCellFormatter().setWidth(row, 1, "100%"); // Table sets de 100% of space
			table.getCellFormatter().setHorizontalAlignment(row, 2, HasAlignment.ALIGN_RIGHT);
			
			tasksNotViewed++;
			table.getRowFormatter().setStyleName(row, "okm-NotViewed"); 
		}
		
		header.setHeaderNotViewedResults(tasksNotViewed);
	}
	

Any ideas on how to finish this up? I would love to get this completed!

jllort
Moderator
Moderator
Posts: 10834
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Change Workflow Node Name Dynamically

Post by jllort » Sat Jul 01, 2017 9:38 am

With a quick look I see this line is sure wrong:

Code: Select all

import org.apache.chemistry.opencmis.server.impl.browser.RepositoryService;
Take in mind, GWT emulates some java packages etc.. - more information about it here http://www.gwtproject.org/doc/latest/Re ... ation.html - but sure this library is not supported. You will not get errors from eclipse view, but when you will going to compile sure GWT will raise an error.

Post Reply