Skip to content
Snippets Groups Projects
Commit 40ceb65d authored by S.Listl's avatar S.Listl
Browse files

1058847 - open Workflow definition inside modeler

parent b6a4e7a2
No related branches found
No related tags found
No related merge requests found
Showing
with 359 additions and 19 deletions
......@@ -38,6 +38,12 @@
<iconId>VAADIN:EXTERNAL_LINK</iconId>
<stateProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/tableactions/children/openmodeler/stateProcess.js</stateProcess>
</entityActionField>
<entityActionField>
<name>createModel</name>
<title>Create model</title>
<onActionProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/tableactions/children/createmodel/onActionProcess.js</onActionProcess>
<iconId>NEON:PLUS</iconId>
</entityActionField>
</children>
</entityActionGroup>
<entityField>
......@@ -55,6 +61,7 @@
<name>FILEUPLOAD</name>
<title>BPMN</title>
<contentType>FILE</contentType>
<mandatory v="true" />
<onValidation>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/fileupload/onValidation.js</onValidation>
</entityField>
<entityConsumer>
......@@ -75,8 +82,7 @@
<entityField>
<name>KEY</name>
<title>Key</title>
<mandatory v="true" />
<state>READONLY</state>
<mandatory v="false" />
<valueProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/key/valueProcess.js</valueProcess>
</entityField>
<entityField>
......@@ -197,6 +203,17 @@
<entityField>
<name>VERSION_TITLE</name>
</entityField>
<entityParameter>
<name>IsWorkflowImport_param</name>
<expose v="true" />
</entityParameter>
<entityActionField>
<name>editWorkflow</name>
<title>Edit workflow</title>
<onActionProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/editworkflow/onActionProcess.js</onActionProcess>
<iconId>VAADIN:EDIT</iconId>
<tooltip>Edit workflow</tooltip>
</entityActionField>
</entityFields>
<recordContainers>
<jDitoRecordContainer>
......
import("system.vars");
import("Workflow_lib");
import("system.workflow");
import("system.util");
import("system.neon");
var processXML = workflow.getProcessXML(vars.get("$field.UID"));
if (processXML)
{
processXML = util.decodeBase64String(processXML);
var model = new WorkflowModelerApiCall().processXML(processXML).importModel();
if (model)
neon.openUrl(WorkflowUtils.getModelerUrl(model.id, true), false);
}
\ No newline at end of file
......@@ -3,4 +3,4 @@ import("system.neon");
var modelerUrl = WorkflowUtils.getModelerUrl();
if (modelerUrl)
neon.openUrl(modelerUrl, true);
\ No newline at end of file
neon.openUrl(modelerUrl + "/#/processes", true);
\ No newline at end of file
import("Employee_lib");
import("system.workflow");
import("system.neon");
import("system.vars");
import("system.util");
import("system.notification");
import("Document_lib");
import("Employee_lib");
import("system.translate")
import("Workflow_lib");
var upload = new FileUpload(vars.get("$field.FILEUPLOAD"));
var rowData = vars.get("$local.rowdata");
var xml = util.decodeBase64String(upload.bindata);
//the xml could be invalid
try {
workflow.deployProcess(rowData["KEY.value"], xml);
} catch (ex) {}
if (upload.isFilled())
{
if (workflow.deployProcess(rowData["KEY.value"], upload.getBase64DecodedData()) === null)
{
var notificationConfig = notification.createConfig()
.addUserWithId(EmployeeUtils.getCurrentUserId())
.notificationType("WorkflowDeployFailed")
.caption(translate.text("Workflow deploy failed"))
.description(translate.text("The workflow could not be deployed"));
notification.addNotificationWith(notificationConfig);
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<neonNotificationType xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonNotificationType/1.1.0">
<name>WorkflowDeployFailed</name>
<title>Workflow deploy failed</title>
<majorModelMode>DISTRIBUTED</majorModelMode>
<icon>VAADIN:EXCLAMATION_CIRCLE</icon>
<deletePerLogout v="true" />
</neonNotificationType>
......@@ -3,6 +3,7 @@
<name>WorkflowDefinitionEdit_view</name>
<majorModelMode>DISTRIBUTED</majorModelMode>
<size>SMALL</size>
<isOverlay v="false" />
<overlayOrientation>PORTRAIT</overlayOrientation>
<layout>
<boxLayout>
......@@ -16,17 +17,13 @@
<entityField>#ENTITY</entityField>
<fields>
<entityFieldLink>
<name>bfec3b64-2cc5-4e51-b321-6d898ddaca9e</name>
<name>42a373cb-956d-4c0a-8a4e-ece1b64c9a95</name>
<entityField>FILEUPLOAD</entityField>
</entityFieldLink>
<entityFieldLink>
<name>88c2c956-966a-4ad9-b744-ccb729b024bc</name>
<entityField>KEY</entityField>
</entityFieldLink>
<entityFieldLink>
<name>14bd4671-d876-430e-8574-277118395ff0</name>
<entityField>ISACTIVE</entityField>
</entityFieldLink>
</fields>
</genericViewTemplate>
</children>
......
......@@ -13,6 +13,7 @@
<iconField>DIAGRAM</iconField>
<titleField>NAME</titleField>
<subtitleField>KEY</subtitleField>
<favoriteAction1>editWorkflow</favoriteAction1>
<entityField>#ENTITY</entityField>
</cardViewTemplate>
<genericViewTemplate>
......
......@@ -100,7 +100,7 @@
<customStringProperty>
<name>workflow.modelerUrl</name>
<description></description>
<property>http://localhost:8080/flowable-modeler/#/processes</property>
<property>http://localhost:8080/flowable-modeler/</property>
</customStringProperty>
</customProperties>
<customConfigProperties>
......
......@@ -8,6 +8,10 @@ import("system.vars");
import("system.entities");
import("system.workflow");
import("KeywordRegistry_basic");
import("system.net");
import("system.auth");
import("system.util");
import("MimeType_lib");
/**
* Provides general functions for working with workflows and the workflow engine.
......@@ -80,9 +84,17 @@ WorkflowUtils.engineIsEnabled = function ()
*
* @return {String} the url of the workflow modeler
*/
WorkflowUtils.getModelerUrl = function ()
WorkflowUtils.getModelerUrl = function (pModelId, pIsEditor)
{
return project.getPreferenceValue("custom.workflow.modelerUrl", "");
var modelerUrl = project.getPreferenceValue("custom.workflow.modelerUrl", "").replace(/\/$/, "");
if (pModelId)
{
if (pIsEditor)
modelerUrl += "/#/editor/" + pModelId;
else
modelerUrl += "/#/processes/" + pModelId;
}
return modelerUrl;
}
/**
......@@ -391,3 +403,251 @@ WorkflowServiceTaskParameter.ENUM = function ()
{
return "enum";
}
/**
* Representation of a process model from the modeler
*/
function WorkflowModel (pId, pName, pKey, pDescription)
{
this.id = pId;
this.name = pName;
this.key = pKey;
this.description = pDescription || "";
this.lastUpdated = new Date();
this.createdBy = WorkflowModelerApiCall.getDefaultRestUser();
this.lastUpdatedBy = this.createdBy;
this.latestVersion = true;
this.version = 1;
this.comment = null;
this.modelType = 0;
this.tenantId = null;
}
/**
* Creates a new WorkflowModel object with the properties of the given object. This is used for deserialization.
*
* @param {Object} pPropertyObj object containing the properties to set
* @return {WorkflowModel} a new WorkflowModel object with the given properties
*/
WorkflowModel.fromObject = function (pPropertyObj)
{
return Object.assign(new WorkflowModel(), pPropertyObj);
}
/**
* An object that provides functions for using the REST API of the workflow modeler
*/
function WorkflowModelerApiCall ()
{
this._baseUrl = WorkflowUtils.getModelerUrl();
this._modelId = null;
this._model = null;
this._processXML = null;
this._authUser = WorkflowModelerApiCall.getDefaultRestUser();
this._authPassword = WorkflowModelerApiCall.getDefaultRestPassword();
}
/**
* Configuration for the urls that are used for webservices of the modeler's rest api
*/
WorkflowModelerApiCall.urls = {
MODEL : function (pModelId)
{
return "/api/editor/models/" + pModelId;
},
MODEL_NEWVERSION : function (pModelId)
{
return "/api/editor/models/" + pModelId + "/newversion";
},
MODEL_THUMBNAIL : function (pModelId)
{
return "/api/editor/models/" + pModelId + "/thumbnail";
},
MODEL_JSON : function (pModelId)
{
return "/api/editor/models/" + pModelId + "/editor/json";
},
MODEL_IMPORT : function ()
{
return "/api/editor/import-process-xml";
},
MODELS : function ()
{
return "/api/editor/models";
}
};
/**
* Gets the default user for the rest api.
*
* @return {String} the username
*/
WorkflowModelerApiCall.getDefaultRestUser = function ()
{
return "admin";
}
/**
* Gets the default password for the rest api.
*
* @return {String} the password
*/
WorkflowModelerApiCall.getDefaultRestPassword = function ()
{
return "test";
}
/**
* Sets the model id.
*
* @param {String} pModelId
* @return {WorkflowModelerApiCall} current object
*/
WorkflowModelerApiCall.prototype.modelId = function (pModelId)
{
this._modelId = pModelId;
return this;
}
/**
* Sets the workflow model that is required for create and update.
*
* @param {WorkflowModel} pModel
* @return {WorkflowModelerApiCall} current object
*/
WorkflowModelerApiCall.prototype.model = function (pModel)
{
this._model = pModel;
if (this._modelId == null && pModel.id != null)
this._modelId = pModel.id;
return this;
}
/**
* Sets the process xml that is required for an import to the modeler.
*
* @param {String} pProcessXML the bpmn2.0 process xml
* @return {WorkflowModelerApiCall} current object
*/
WorkflowModelerApiCall.prototype.processXML = function (pProcessXML)
{
this._processXML = pProcessXML;
return this;
}
/**
* Sets the user and the password for basic auth
*
* @param {String} pUser the user
* @param {String} pPassword the password
* @return {WorkflowModelerApiCall} current object
*/
WorkflowModelerApiCall.prototype.setBasicAuth = function (pUser, pPassword)
{
this._authUser = pUser;
this._authPassword = pPassword;
return this;
}
/**
* Helper function to make rest calls
*/
WorkflowModelerApiCall.prototype._callWebservice = function (pUrl, pHttpMethod, pHeaders, pBody, pDataTypeSend, pQueryParams)
{
if (!this._baseUrl)
return null;
var restConfig = net.createConfigForRestWebserviceCall()
.url(this._baseUrl + pUrl)
.dataTypeJDitoAccept(util.DATA_TEXT)
.dataTypeJDitoSend(util.DATA_TEXT)
.dataTypeSend(pDataTypeSend || MimeTypes.JSON())
.dataTypeAccept(MimeTypes.JSON())
.actionType(pHttpMethod);
if (pHeaders)
{
for (let headerName in pHeaders)
restConfig.addHeader(headerName, pHeaders[headerName]);
}
if (pQueryParams)
{
for (let paramName in pQueryParams)
restConfig.addQueryParameter(paramName, pQueryParams[paramName]);
}
if (pBody)
restConfig.requestEntity(pBody);
var authConfig = this._authUser != null
? auth.createConfigForBasicAuth().userName(this._authUser).password(this._authPassword)
: auth.createConfigForNoAuth();
return net.callRestWebservice(restConfig, authConfig);
}
/**
* Retrieves a process model from the workflow modeler rest api
*
* @return {WorkflowModel}
*/
WorkflowModelerApiCall.prototype.getModel = function ()
{
var modelJson = this._callWebservice(WorkflowModelerApiCall.urls.MODEL(this._modelId), net.GET);
if (!modelJson)
return null;
return WorkflowModel.fromObject(JSON.parse(modelJson));
}
/**
* Loads the models from the workflow modeler.
*
* @return {WorkflowModel[]} array of models
*/
WorkflowModelerApiCall.prototype.getModels = function (pFilter)
{
var headers = pFilter ? {filter : pFilter} : null;
var modelsJson = this._callWebservice(WorkflowModelerApiCall.urls.MODELS(), net.GET, headers);
if (!modelsJson)
return [];
var models = JSON.parse(modelsJson).data || [];
return models.map(function (model)
{
return WorkflowModel.fromObject(model);
});
}
/**
* Creates a new process model in the workflow modeler over the rest api
*
* @return {WorkflowModel} representation of the created model
*/
WorkflowModelerApiCall.prototype.createModel = function ()
{
var modelJson = this._callWebservice(WorkflowModelerApiCall.urls.MODELS(), net.POST, null, JSON.stringify(this._model));
if (!modelJson)
return null;
return WorkflowModel.fromObject(JSON.parse(modelJson));
}
/**
* Imports a bpmn2.0 xml into the workflow modeler. If a model with the same key already exists, a new version will be created.
*
* @return {WorkflowModel} representation of the created model
*/
WorkflowModelerApiCall.prototype.importModel = function ()
{
var modelJson = this._callWebservice(WorkflowModelerApiCall.urls.MODEL_IMPORT(), net.POST, null, this._processXML, MimeTypes.TXT(), {userName : this._authUser});
if (!modelJson)
return null;
return WorkflowModel.fromObject(JSON.parse(modelJson));
}
import("system.workflow");
import("system.util");
function restpost (pRequest)
{
var request = JSON.parse(pRequest);
var processObj = JSON.parse(util.decodeBase64String(request.body));
if (processObj && processObj.processXML)
{
var processIds = workflow.getProcessIds(processObj.processXML);
processIds = processIds != null ? JSON.parse(processIds) : [];
if (processIds.length > 0)
{
processObj.deploymentId = workflow.deployProcess(processIds[0], processObj.processXML);
request.response.statuscode = 200;
request.response.body = JSON.stringify(processObj);
}
}
return JSON.stringify(request);
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
<name>workflowDeploy_rest</name>
<majorModelMode>DISTRIBUTED</majorModelMode>
<process>%aditoprj%/process/workflowDeploy_rest/process.js</process>
<publishAsWebservice v="true" />
<style>REST</style>
<restAcceptedMimeType>application/json</restAcceptedMimeType>
<restDeliveredMimeType>application/json</restDeliveredMimeType>
<jditoWebserviceUser>flowableIdmService</jditoWebserviceUser>
<variants>
<element>EXECUTABLE</element>
</variants>
</process>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment