Skip to content

Commit

Permalink
self-contained token sumulator with bpmn-io/bpmn-js-token-simulation#110
Browse files Browse the repository at this point in the history
 included
  • Loading branch information
Vladimir Panfilov authored and vpanfilov committed Sep 23, 2022
1 parent a0a6a9f commit e570929
Show file tree
Hide file tree
Showing 9 changed files with 3,230 additions and 21 deletions.
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

19 changes: 19 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<title>BPMN Token Simulation Demo</title>
</head>
<body>
<div class="canvas-parent">
<div class="canvas" id="canvas">
<div class="drop-message"><strong>Подсказка:</strong> можно перетащить файл с готовой BPMN-диаграммой в это окно</div>
</div>
</div>

<div class="links bottom-links">
<button class="link" id="download-button">Скачать BPMN</button>
</div>
</body>
</html>
172 changes: 172 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import TokenSimulationModule from 'bpmn-js-token-simulation/lib/modeler';
import BpmnModeler from 'bpmn-js/lib/Modeler';

import fileDrop from 'file-drops';
import fileOpen from 'file-open';
import download from 'downloadjs';

import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
import 'bpmn-js-token-simulation/assets/css/bpmn-js-token-simulation.css';
import './styles.css';

const defaultBPMN = require('./test.bpmn');

const url = new URL(window.location.href);

const persistent = url.searchParams.has('p');
const active = url.searchParams.has('e');
const presentationMode = url.searchParams.has('pm');

let fileName = 'diagram.bpmn';

function showMessage(cls, message) {
const messageEl = document.querySelector('.drop-message');

messageEl.textContent = message;
messageEl.className = `drop-message ${cls || ''}`;

messageEl.style.display = 'block';
}

function hideMessage() {
const messageEl = document.querySelector('.drop-message');

messageEl.style.display = 'none';
}

if (persistent) {
hideMessage();
}

const ExampleModule = {
__init__: [
[ 'eventBus', 'bpmnjs', 'toggleMode', function(eventBus, bpmnjs, toggleMode) {

if (persistent) {
eventBus.on('commandStack.changed', function() {
bpmnjs.saveXML().then(result => {
localStorage['diagram-xml'] = result.xml;
});
});
}

if ('history' in window) {
eventBus.on('tokenSimulation.toggleMode', event => {

document.body.classList.toggle('token-simulation-active', event.active);

if (event.active) {
url.searchParams.set('e', '1');
} else {
url.searchParams.delete('e');
}

history.replaceState({}, document.title, url.toString());
});
}

eventBus.on('diagram.init', 500, () => {
toggleMode.toggleMode(active);
});
} ]
]
};

const modeler = new BpmnModeler({
container: '#canvas',
additionalModules: [
TokenSimulationModule,
ExampleModule
],
keyboard: {
bindTo: document
}
});

function openDiagram(diagram) {
return modeler.importXML(diagram)
.then(({ warnings }) => {
if (warnings.length) {
console.warn(warnings);
}

if (persistent) {
localStorage['diagram-xml'] = diagram;
}

modeler.get('canvas').zoom('fit-viewport');
})
.catch(err => {
console.error(err);
});
}

if (presentationMode) {
document.body.classList.add('presentation-mode');
}

function openFile(files) {

// files = [ { name, contents }, ... ]

if (!files.length) {
return;
}

hideMessage();

fileName = files[0].name;

openDiagram(files[0].contents);
}

document.body.addEventListener('dragover', fileDrop('Open BPMN diagram', openFile), false);

function downloadDiagram() {
modeler.saveXML({ format: true }, function(err, xml) {
if (!err) {
download(xml, fileName, 'application/xml');
}
});
}

document.body.addEventListener('keydown', function(event) {
if (event.code === 'KeyS' && (event.metaKey || event.ctrlKey)) {
event.preventDefault();

downloadDiagram();
}

if (event.code === 'KeyO' && (event.metaKey || event.ctrlKey)) {
event.preventDefault();

fileOpen().then(openFile);
}
});

document.querySelector('#download-button').addEventListener('click', function(event) {
downloadDiagram();
});

const remoteDiagram = url.searchParams.get('diagram');

if (remoteDiagram) {
fetch(remoteDiagram).then(
r => {
if (r.ok) {
return r.text();
}

throw new Error(`Status ${r.status}`);
}
).then(
text => openDiagram(text)
).catch(
err => {
showMessage('error', `Failed to open remote diagram: ${err.message}`);
}
);
}

modeler.importXML(defaultBPMN);
33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "bpmn-token-simulator",
"version": "0.1.0",
"description": "BPMN Token Simulator Prototype",
"main": "index.js",
"license": "MIT",
"private": true,
"dependencies": {
"bpmn-js": "8.9.1",
"bpmn-js-token-simulation": "bpmn-io/bpmn-js-token-simulation#110/head",
"downloadjs": "^1.4.7",
"file-drops": "^0.4.0",
"file-open": "^0.1.1",
"rollup": "^2.79.1",
"rollup-plugin-string": "^3.0.0"
},
"scripts": {
"bundle": "rollup -c && webpack --mode production",
"bundle:watch": "rollup -c && webpack -w",
"start": "rollup -c && webpack serve"
},
"devDependencies": {
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.1",
"html-inline-css-webpack-plugin": "^1.11.1",
"html-inline-script-webpack-plugin": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
14 changes: 14 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { string } from 'rollup-plugin-string';

export default {
input: 'node_modules/bpmn-js-token-simulation/src/icons/index.js',
output: {
file: 'node_modules/bpmn-js-token-simulation/lib/icons/index.js',
format: 'esm'
},
plugins: [
string({
include: '**/*.svg'
})
]
};
123 changes: 123 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
html, body, #canvas {
width: 100%;
height: 100%;
margin: 0;
padding: 0;

font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;

color: var(--token-simulation-grey-darken-30, #212121);
}

body:not(.presentation-mode) .bts-notifications {
bottom: 60px;
}

.links, .drop-message {
z-index: 1;
}

.top-links {
position: absolute;
top: 24px;
right: 24px;
}

.bottom-links {
position: absolute;
bottom: 24px;
left: 24px;
}

.link {
color: var(--token-simulation-grey-darken-30, #212121);
display: inline-block;
padding: 6px;
font-size: 16px;
border-radius: 2px;
background-color: var(--token-simulation-silver-darken-94, #EFEFEF);
text-decoration: none;
border: none;
}

.link:hover {
color: var(--token-simulation-white, #FFFFFF);
background-color: var(--token-simulation-green-base-44, #10D070);
}

.links .link + .link {
margin-left: 20px;
}

.presentation-mode .drop-message,
.presentation-mode .links {
display: none;
}

.canvas-parent {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;

display: flex;
}

.canvas {
flex: 1;
position: relative;
justify-content: stretch;
}


/** file-drops */

.drop-message {
position: absolute;
top: 24px;
left: 50%;
transform: translateX(-50%);
background-color: var(--token-simulation-silver-darken-94, #EFEFEF);
border-radius: 2px;
padding: 6px 12px;
font-size: 16px;
color: var(--token-simulation-grey-darken-30, #212121);
user-select: none;
}

.drop-message.error {
background: #dd7373;
}

.drop-overlay {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;

padding: 50px;

background: rgba(255, 255, 255, .9);

z-index: 1000;
}

.drop-overlay .box {
text-align: center;
border: dashed 4px #CCC;
height: 100%;
width: 100%;
display: table;
}

.drop-overlay .label {
font-size: 26px;
color: #888;
margin: auto;

display: table-cell;
vertical-align: middle;
}
Loading

0 comments on commit e570929

Please sign in to comment.