Camunda Version 7.16: Migrating a Tasklist Plugin (Angular JS)

Daniel Xav De Oliveira
3 min readMay 1, 2022

Introduction

In this blog, we are concerned with the using the plugin feature to extend the Tasklist web application, in Camunda Version 7.16. I will include an example to demonstrate this migration.

Migrating a 7.13 Plugin

Let’s have a look at the structure of a 7.13 plugin, in the below example. I have added placeholders to make it more readable:

// plugin.js
// A require.js callback with angular injected
define(["angular"], function(angular) {

// A AngularJS controller with Dependency injection
var theController = [/* ... */];

// The template, related to your Controller (HTML)
var template = '...';

// Your custom module
var ngModule = angular.module("tasklist.pluginID", []);

// Injecting the 'ViewsProvider' to register a Plugin
ngModule.config([
"ViewsProvider",
function(ViewsProvider) {
// Registering the Plugin with template and controller at 'tasklist.navbar.action.', adding labels and priority
ViewsProvider.registerDefaultView("tasklist.navbar.action.", {
id: "tasklist.pluginID",
label: "label text here",
priority: 9001,
template: template,
controller: theController
});
}
]);

// Returns the module
return ngModule;
});

The 7.16 Tasklist Plugin System is framework agnostic. This means that we will have to create and bootstrap our own AngularJS application.

Furthermore, require.js was replaced with the JavaScript module system, and the plugin-point definitions are moved to the top level. Template and Controller are still present, but need to be adjusted to work in a standalone AngularJS app.

7.16 Plugin

// plugin.js
// include AngularJS in your Plugin
import angular from "angular";

// Javascript Module syntax, using the default export to define the Plugin details
export default {
id: "tasklist.pluginID",
pluginPoint: "tasklist.navbar.action.",
priority: 9,
// The render function is called when the view with the plugin is loaded
render: node => {

// The AngularJS Controller
var theController = [/* ... */];

// Make sure to explicitly use the controller
var template = '<div ng-controller="theController">...</div>';

// Create module and register the controller
var ngModule = angular.module("tasklist.pluginID", []);
ngModule.controller(
"theController",
theController
);

// Set the template and bootstrap your application into the node
node.innerHTML = template;
angular.bootstrap(node, [ngModule.name]);
},
properties: {
label: "Search Processes"
}
};

Roll up

Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD.

Ensure to include the following file in the root directory of your Maven plugin projects, rollup.config.js:

import resolve from “@rollup/plugin-node-resolve”;
import commonjs from “@rollup/plugin-commonjs”;
export default {
input: “plugin.js”,
output: {
file: “dist/plugin.js”
},
plugins: [resolve(), commonjs()]
};

Package.json

Furthermore, add this package.json to the same root directory.

{
“name”: “angularJS”,
“version”: “1.0.0”,
“main”: “plugin.js”,
“scripts”: {
“build”: “rollup -c”
},
“dependencies”: {
“angular”: “¹.8.2”
},
“devDependencies”: {
@rollup/plugin-commonjs”: “²¹.0.3”,
@rollup/plugin-node-resolve”: “¹³.1.3”,
“rollup”: “².70.1”
}
}

Plugin.js

Furthermore, move your plugin.js file to the root directory.

Building the Plugin

Install the project with npm i and build the plugin with npm run build. Your plugin will be created in dist/plugin.js.

Integrate into Camunda Webapp

Copy the plugin.js file into the app/tasklist/scripts/ folder in your Camunda webapp distribution.

For the Tomcat distribution, this would be server/apache-tomcat-X.X.XX/webapps/camunda/app/tasklist/scripts/.

Add the following content to the app/tasklist/scripts/config.js file:

// …
customScripts: [
'scripts/plugin.js'
]
// …

Thank you for reading! Feel free to make any other suggestions or recommendations for future challenges. Leave a few claps if you enjoyed it !

Side Note

The Uri dependency previously used in plugins is no longer used in these plugins.

Uri.appUri(‘/plugin/tasklist-plugin/${api.engine}/process-instance’),

Instead use {api}.

7.16 Plugin

export default {
id: "tasklist-plugin",
pluginPoint: "tasklist.navbar.action.",
priority: 12,
render: (node, { api }) => {
node.innerHTML = `<button class="btn btn-default action-button" style="width: 40px; margin-top: 5px">Retry</button>` node.onclick = function() {
fetch(
`${api.tasklistApi}/plugin/tasklist-plugin/${api.engine}/process-instance`
).then(async res => {
alert(res["status"]);
});
}
}
};

--

--

Daniel Xav De Oliveira

My aim is to document my journey as a Software Developer. Writing as I go along. To enforce new knowledge in my mind and to share with others !