initial commit.

This commit is contained in:
Dan 2022-09-15 11:31:35 -04:00
commit aad4e2e294
12 changed files with 16826 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
node_modules
public

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Sartography
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# BPMN.js Seed
A quick-start repo, designed to be forked and modified to create extensions and modifications to BPMN.io
# About
This project provides a baseline for creating you own modifications to BPMN,io - there are many excellent examples available on the [BPMN.io Repository](https://github.com/bpmn-io/bpmn-js-examples). But they are gathered into one large repository. This is designed to be a SEED project - a good starting point that will let you get up and running quickly.
This extension creates a BPMN editor with all the capabilities of [BPMN.js](https://github.com/bpmn-io/bpmn-js) and the following additions / modifications:
* Changes the color of all the lines to be a pretty blue!
## Running the Modeler
You need a [NodeJS](http://nodejs.org) development stack with [npm](https://npmjs.org) installed to build the project.
To install all project dependencies execute
```sh
npm install
```
To start playing around, start the server up in develpment mode. Any changes you make the Javascript files will be authmatically updated.
```sh
npm run dev
```
## License
MIT

View File

@ -0,0 +1,42 @@
import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
import { attr as svgAttr } from 'tiny-svg';
import { getBusinessObject, is } from 'bpmn-js/lib/util/ModelUtil';
import { isAny } from 'bpmn-js/lib/features/modeling/util/ModelingUtil';
// Setting a high priority level helps us slip in ahead of BPMN.js rules and apply our own instead.
const HIGH_PRIORITY = 1500;
/**
* Just a simple example that will change the Connections from black to Blue
*/
export default class SequenceFlowRenderer extends BaseRenderer {
constructor(eventBus, bpmnRenderer) {
super(eventBus, HIGH_PRIORITY);
this.bpmnRenderer = bpmnRenderer;
}
/**
* This tells BPMN.js that this function should be used to render the connections
* @param element
* @returns {boolean}
*/
canRender(element) {
return is(element, 'bpmn:SequenceFlow');
}
/**
* In this case, we want to override the drawConnection -- because this is a Sequence Flow,
* this would be drawShape if we were overriding how a Task object was rendered.
* @param parentNode
* @param element
* @returns {*}
*/
drawConnection(parentNode, element) {
const shape = this.bpmnRenderer.drawShape(parentNode, element);
//
svgAttr(shape, 'stroke', 'red');
return shape;
}
}
SequenceFlowRenderer.$inject = [ 'eventBus', 'bpmnRenderer' ];

14
app/MyExtension/index.js Normal file
View File

@ -0,0 +1,14 @@
import SequenceFlowRenderer from './SequenceFlowRenderer';
/**
* This allows us to import "MyExtension" into BPMN.io and
* get everything that is a part of our extension. Here
* we just have a Connection Renderer, but we might have
* dozens of other slight modifications in other files and
* directories.
*/
export default {
__init__: [ 'sequenceFlowRenderer' ],
sequenceFlowRenderer: [ 'type', SequenceFlowRenderer ],
};

142
app/app.js Normal file
View File

@ -0,0 +1,142 @@
/**
* This file provides an example of how to hook all of your parts together to create
* a simple web page that contains your customized BPMN Modeler.
* There are comments throughout to explain what is happening.
*/
/**
* IMPORTS - where we load up all the dependencies
===============================================
*/
// the BPMN.js libraries
import BpmnModeler from 'bpmn-js/lib/Modeler';
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule} from 'bpmn-js-properties-panel';
// FileSaver helps us build a download button so you can save files you create in the browser.
import FileSaver from 'file-saver';
// This is the diagram that is opened by default.
import diagramXML from '../example.bpmn';
// Here is where we import your library code
import myExtension from './MyExtension';
/**
* MODELER - Where we instantiate the modeler
===============================================
This is where you will create a BPMN modeler and configure it to load in your extensions.
*/
const modelerEl = document.getElementById('modeler');
const panelEl = document.getElementById('panel');
let bpmnModeler;
// create modeler
try {
bpmnModeler = new BpmnModeler({
container: modelerEl,
propertiesPanel: {
parent: panelEl,
},
additionalModules: [
myExtension,
BpmnPropertiesPanelModule,
BpmnPropertiesProviderModule,
]
});
} catch (error) {
if (error.constructor.name === 'AggregateError') {
console.log(error.message);
console.log(error.name);
console.log(error.errors);
}
throw error;
}
// import XML
bpmnModeler.importXML(diagramXML).then(() => {});
/**
* Open and Save Files
* ===============================================
* The rest of this stuff is concerned with making it easy to open a BPMN file and save it - these
* are general tools - nothing very specific to BPMN.io -
* -----------------------------------------
*/
/**
* Just a quick bit of code so we can save the XML that is output.
* Helps for debugging against other libraries (like SpiffWorkflow)
*/
const btn = document.getElementById('downloadButton');
btn.addEventListener('click', (_event) => {
saveXML();
});
async function saveXML() {
const { xml } = await bpmnModeler.saveXML({ format: true });
const blob = new Blob([xml], { type: 'text/xml' });
FileSaver.saveAs(blob, 'diagram.bpmn');
}
/**
* Just a quick bit of code so we can open a local XML file
* Helps for debugging against other libraries (like SpiffWorkflow)
*/
const uploadBtn = document.getElementById('uploadButton');
uploadBtn.addEventListener('click', (_event) => {
openFile(displayFile);
});
function clickElem(elem) {
const eventMouse = document.createEvent('MouseEvents');
eventMouse.initMouseEvent(
'click',
true,
false,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
);
elem.dispatchEvent(eventMouse);
}
function displayFile(contents) {
bpmnModeler.importXML(contents).then(() => {});
}
export default function openFile(func) {
const readFile = function readFileCallback(e) {
const file = e.target.files[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = function onloadCallback(onloadEvent) {
const contents = onloadEvent.target.result;
fileInput.func(contents);
document.body.removeChild(fileInput);
};
reader.readAsText(file);
};
let fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.style.display = 'none';
fileInput.onchange = readFile;
fileInput.func = func;
document.body.appendChild(fileInput);
clickElem(fileInput);
}

53
app/css/app.css Normal file
View File

@ -0,0 +1,53 @@
* {
box-sizing: border-box;
margin: 0;
outline: none;
padding: 0;
}
html, body {
height: 100%;
}
.hidden {
display: none;
}
#container {
display: flex;
width: 100%;
height: 100%;
}
#modeler {
flex-grow: 1;
}
#panel {
background-color: #fafafa;
border: solid 1px #ccc;
border-radius: 2px;
font-family: 'Arial', sans-serif;
padding: 10px;
min-width: 400px;
}
.djs-label {
font-family: 'Arial', sans-serif;
}
/* Style buttons */
.btn {
background-color: DodgerBlue;
border: none;
color: white;
padding: 8px 15px;
cursor: pointer;
font-size: 16px;
margin: 12px;
}
/* Darker background on mouse-over */
.btn:hover {
background-color: RoyalBlue;
}

28
app/index.html Normal file
View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>My BPMN.io Project</title>
<meta charset="utf-8"/>
<link rel="stylesheet" href="vendor/bpmn-js/assets/diagram-js.css"/>
<link rel="stylesheet" href="vendor/bpmn-js/assets/bpmn-js.css"/>
<link rel="stylesheet" href="vendor/bpmn-js/assets/bpmn-font/css/bpmn-embedded.css"/>
<link rel="stylesheet" href="vendor/bpmn-js-properties-panel/assets/properties-panel.css"/>
<link rel="stylesheet" href="css/app.css"/>
<link rel="shortcut icon" href="#">
<!-- Just have this for the download file icon -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<div id="menu">
<button id="downloadButton" class="btn"><i class="fa fa-download"></i> Download</button>
<button id="uploadButton" class="btn">Open a file</button>
</div>
<div id="container">
<div id="modeler"></div>
<div id="panel"></div>
</div>
<script src="app.js"></script>
</body>
</html>
<!---->

52
example.bpmn Normal file
View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1q815ou" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="Process_1yfrbgo" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1x9wjxw</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:task id="Activity_0zf1o8m" name="A">
<bpmn:incoming>Flow_1x9wjxw</bpmn:incoming>
<bpmn:outgoing>Flow_1ol300i</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_1x9wjxw" sourceRef="StartEvent_1" targetRef="Activity_0zf1o8m" />
<bpmn:task id="Activity_1n5n6n2" name="B">
<bpmn:incoming>Flow_1ol300i</bpmn:incoming>
<bpmn:outgoing>Flow_1poxcyr</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_1ol300i" sourceRef="Activity_0zf1o8m" targetRef="Activity_1n5n6n2" />
<bpmn:endEvent id="Event_0wsytli">
<bpmn:incoming>Flow_1poxcyr</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1poxcyr" sourceRef="Activity_1n5n6n2" targetRef="Event_0wsytli" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1yfrbgo">
<bpmndi:BPMNEdge id="Flow_1x9wjxw_di" bpmnElement="Flow_1x9wjxw">
<di:waypoint x="215" y="117" />
<di:waypoint x="270" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ol300i_di" bpmnElement="Flow_1ol300i">
<di:waypoint x="370" y="117" />
<di:waypoint x="430" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1poxcyr_di" bpmnElement="Flow_1poxcyr">
<di:waypoint x="530" y="117" />
<di:waypoint x="592" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0zf1o8m_di" bpmnElement="Activity_0zf1o8m">
<dc:Bounds x="270" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1n5n6n2_di" bpmnElement="Activity_1n5n6n2">
<dc:Bounds x="430" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0wsytli_di" bpmnElement="Event_0wsytli">
<dc:Bounds x="592" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

16308
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

86
package.json Normal file
View File

@ -0,0 +1,86 @@
{
"name": "bpmn-js-base",
"version": "0.0.1",
"description": "A seed for developing your own BPMN.io extensions",
"scripts": {
"all": "run-s lint test build",
"build": "webpack --mode production",
"build:watch": "webpack --watch",
"dev": "run-p build:watch serve",
"serve": "sirv public --dev",
"lint": "./node_modules/.bin/eslint src *.js",
"lint:fix": "./node_modules/.bin/eslint --fix src *.js",
"start": "run-s build serve",
"test": "karma start karma.conf.js"
},
"repository": {
"type": "git",
"url": "https://github.com/sartography/bpmn-js-base"
},
"keywords": [
"bpmn"
],
"author": {
"name": "Dan Funk (Sartography)",
"url": "https://github.com/danfunk"
},
"contributors": [
{
"name": "bpmn.io contributors",
"url": "https://github.com/bpmn-io"
}
],
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.18.6",
"@babel/plugin-transform-react-jsx": "^7.17.12",
"@babel/preset-env": "^7.18.6",
"@babel/preset-react": "^7.18.2",
"@testing-library/preact": "^2.0.1",
"@testing-library/preact-hooks": "^1.1.0",
"@types/mocha": "^9.1.1",
"babel-loader": "^8.2.5",
"chai": "^4.3.6",
"copy-webpack-plugin": "^11.0.0",
"eslint": "^8.18.0",
"eslint_d": "^12.2.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-bpmn-io": "^0.14.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-sonarjs": "^0.13.0",
"file-saver": "^2.0.5",
"karma": "^6.3.4",
"karma-chrome-launcher": "^3.1.1",
"karma-coverage": "^2.2.0",
"karma-env-preprocessor": "^0.1.1",
"karma-mocha": "^2.0.1",
"karma-sinon-chai": "^2.0.2",
"karma-webpack": "^5.0.0",
"mocha": "^10.0.0",
"mocha-test-container-support": "^0.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"raw-loader": "^4.0.2",
"sinon": "^14.0.0",
"sinon-chai": "^3.7.0",
"sirv-cli": "^2.0.2",
"stringify": "^5.2.0",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"@bpmn-io/properties-panel": "^0.20.1",
"bpmn-js": "^9.4.0",
"bpmn-js-properties-panel": "^1.5.0",
"diagram-js": "^8.5.0",
"inherits": "^2.0.4",
"inherits-browser": "^0.0.1",
"min-dash": "^3.8.1",
"min-dom": "^3.2.1",
"moddle": "^5.0.3",
"tiny-svg": "^2.2.3"
}
}

49
webpack.config.js Normal file
View File

@ -0,0 +1,49 @@
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
bundle: ['./app/app.js']
},
output: {
path: __dirname + '/public',
filename: 'app.js'
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [
[ '@babel/plugin-transform-react-jsx', {
'importSource': '@bpmn-io/properties-panel/preact',
'runtime': 'automatic'
} ]
]
}
}
},
{
test: /\.bpmn$/,
use: 'raw-loader'
}
]
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: 'assets/**', to: 'vendor/bpmn-js', context: 'node_modules/bpmn-js/dist/' },
{
from: 'assets/**',
to: 'vendor/bpmn-js-properties-panel',
context: 'node_modules/bpmn-js-properties-panel/dist/'
},
{from: '**/*.{html,css}', context: 'app/'}
]
})
],
mode: 'development',
devtool: 'source-map'
};