Init React Project
This commit is contained in:
parent
67edf4c756
commit
60f2f25158
54
.eslintrc.js
54
.eslintrc.js
|
@ -1,54 +0,0 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: [
|
||||
'airbnb',
|
||||
'plugin:bpmn-io/es6',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:sonarjs/recommended',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/warnings',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'jsx-a11y/no-autofocus': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'off',
|
||||
'no-console': 'off',
|
||||
'no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
destructuredArrayIgnorePattern: '^_',
|
||||
varsIgnorePattern: '_',
|
||||
argsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'ignorePackages',
|
||||
{
|
||||
js: 'never',
|
||||
jsx: 'never',
|
||||
ts: 'never',
|
||||
tsx: 'never',
|
||||
},
|
||||
],
|
||||
|
||||
// We could try turning these on at some point but do not want to force it now
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'react/prop-types': 'off',
|
||||
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
|
||||
'no-use-before-define': 0,
|
||||
'func-names': 'off',
|
||||
'react/destructuring-assignment': 'off',
|
||||
'import/prefer-default-export': 'off',
|
||||
'no-restricted-syntax': 'off',
|
||||
},
|
||||
};
|
|
@ -1,18 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: pip
|
||||
directory: "/.github/workflows"
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: pip
|
||||
directory: "/docs"
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: pip
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
|
@ -1,66 +0,0 @@
|
|||
---
|
||||
# Labels names are important as they are used by Release Drafter to decide
|
||||
# regarding where to record them in changelog or if to skip them.
|
||||
#
|
||||
# The repository labels will be automatically configured using this file and
|
||||
# the GitHub Action https://github.com/marketplace/actions/github-labeler.
|
||||
- name: breaking
|
||||
description: Breaking Changes
|
||||
color: bfd4f2
|
||||
- name: bug
|
||||
description: Something isn't working
|
||||
color: d73a4a
|
||||
- name: build
|
||||
description: Build System and Dependencies
|
||||
color: bfdadc
|
||||
- name: ci
|
||||
description: Continuous Integration
|
||||
color: 4a97d6
|
||||
- name: dependencies
|
||||
description: Pull requests that update a dependency file
|
||||
color: 0366d6
|
||||
- name: documentation
|
||||
description: Improvements or additions to documentation
|
||||
color: 0075ca
|
||||
- name: duplicate
|
||||
description: This issue or pull request already exists
|
||||
color: cfd3d7
|
||||
- name: enhancement
|
||||
description: New feature or request
|
||||
color: a2eeef
|
||||
- name: github_actions
|
||||
description: Pull requests that update Github_actions code
|
||||
color: "000000"
|
||||
- name: good first issue
|
||||
description: Good for newcomers
|
||||
color: 7057ff
|
||||
- name: help wanted
|
||||
description: Extra attention is needed
|
||||
color: 008672
|
||||
- name: invalid
|
||||
description: This doesn't seem right
|
||||
color: e4e669
|
||||
- name: performance
|
||||
description: Performance
|
||||
color: "016175"
|
||||
- name: python
|
||||
description: Pull requests that update Python code
|
||||
color: 2b67c6
|
||||
- name: question
|
||||
description: Further information is requested
|
||||
color: d876e3
|
||||
- name: refactoring
|
||||
description: Refactoring
|
||||
color: ef67c4
|
||||
- name: removal
|
||||
description: Removals and Deprecations
|
||||
color: 9ae7ea
|
||||
- name: style
|
||||
description: Style
|
||||
color: c120e5
|
||||
- name: testing
|
||||
description: Testing
|
||||
color: b1fc6f
|
||||
- name: wontfix
|
||||
description: This will not be worked on
|
||||
color: ffffff
|
|
@ -1,29 +0,0 @@
|
|||
categories:
|
||||
- title: ":boom: Breaking Changes"
|
||||
label: "breaking"
|
||||
- title: ":rocket: Features"
|
||||
label: "enhancement"
|
||||
- title: ":fire: Removals and Deprecations"
|
||||
label: "removal"
|
||||
- title: ":beetle: Fixes"
|
||||
label: "bug"
|
||||
- title: ":racehorse: Performance"
|
||||
label: "performance"
|
||||
- title: ":rotating_light: Testing"
|
||||
label: "testing"
|
||||
- title: ":construction_worker: Continuous Integration"
|
||||
label: "ci"
|
||||
- title: ":books: Documentation"
|
||||
label: "documentation"
|
||||
- title: ":hammer: Refactoring"
|
||||
label: "refactoring"
|
||||
- title: ":lipstick: Style"
|
||||
label: "style"
|
||||
- title: ":package: Dependencies"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "build"
|
||||
template: |
|
||||
## Changes
|
||||
|
||||
$CHANGES
|
|
@ -1,28 +0,0 @@
|
|||
name: Dependabot auto-merge
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Tests"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
dependabot:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.actor == 'dependabot[bot]' && github.event.workflow_run.conclusion == 'success' && github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
- name: Dependabot metadata
|
||||
id: metadata
|
||||
uses: dependabot/fetch-metadata@v1.6.0
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Enable auto-merge for Dependabot PRs
|
||||
# if: ${{contains(steps.metadata.outputs.dependency-names, 'pytest') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
|
||||
# if: ${{contains(steps.metadata.outputs.dependency-names, 'pytest')}}
|
||||
# ideally we auto-merge if all checks pass
|
||||
run: gh pr merge --auto --merge "$PR_URL"
|
||||
env:
|
||||
PR_URL: ${{github.event.pull_request.html_url}}
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
|
@ -1,19 +0,0 @@
|
|||
name: Labeler
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Labeler
|
||||
uses: crazy-max/ghaction-github-labeler@v5.0.0
|
||||
with:
|
||||
skip-delete: true
|
|
@ -1,27 +0,0 @@
|
|||
name: Publish NPM
|
||||
|
||||
# On a published release, run tests and deploy to NPM
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
# Job Setup
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4 #Checkout Repo
|
||||
- uses: actions/setup-node@v4 #Setup Node
|
||||
with:
|
||||
node-version: 18
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- uses: JS-DevTools/npm-publish@v3
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
access: public
|
||||
- if: steps.publish.outputs.type != 'none'
|
||||
run: |
|
||||
echo "Version changed: ${{ steps.publish.outputs.old-version }} => ${{ steps.publish.outputs.version }}"
|
|
@ -1,30 +0,0 @@
|
|||
name: Tests
|
||||
|
||||
# Run on Pull Requests and pushes to main
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# This allows a subsequently queued workflow run to interrupt previous runs
|
||||
concurrency:
|
||||
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
# Job Setup
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 #Checkout Repo
|
||||
- uses: actions/setup-node@v4 #Setup Node
|
||||
- uses: nanasess/setup-chromedriver@v2 #Setup ChromeDriver
|
||||
with:
|
||||
node-version: '18'
|
||||
- name: Run Karma Tests
|
||||
run: |
|
||||
npm ci
|
||||
npm run test
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
node_modules/
|
||||
public/
|
||||
.idea/
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
singleQuote: true,
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
nodejs 18.3.0
|
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
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.
|
123
README.md
123
README.md
|
@ -1,105 +1,70 @@
|
|||
# Getting Started with Create React App
|
||||
|
||||
![Tests](https://github.com/sartography/bpmn-js-spiffworkflow/actions/workflows/tests.yml/badge.svg?branch=main)
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
# SpiffWorkflow Extensions for BPMN.js
|
||||
This package provides extensions that can be applied to BPMN.js that will enable some important features of [SpiffWorkflow](https://github.com/sartography/SpiffWorkflow) - the Python BPMN Library for executing business processes. See below for more information.
|
||||
## Available Scripts
|
||||
|
||||
**IMPORTANT**: This is a work in progress, and is not yet released.
|
||||
In the project directory, you can run:
|
||||
|
||||
# About
|
||||
### `npm start`
|
||||
|
||||
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:
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
* Ability to insert BPMN's Data Input and Data Output Objects.
|
||||
* A SpiffWorkflow centric Properties Panel for specifying scripts to run before and after a task, and for defining documentation, and Mark-up content for displaying in user and manual tasks. Among other things.
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
# Data Input and Data Output Element
|
||||
This extension will allow you to drag BPMN Data Input and Data Output elements onto the diagram and give them appropriate labels. This will generate valid BPMN elements in the underlying XML file - connecting them to the IO Specification of the process, as shown below:
|
||||
```xml
|
||||
<bpmn:process id="my_delightful_process" isExecutable="true">
|
||||
<bpmn:ioSpecification>
|
||||
<bpmn:dataInput id="DataInput-745019423-1" name="num_dogs" />
|
||||
<bpmn:dataOutput id="DataOutput-711207596-1" name="happy_index" />
|
||||
</bpmn:ioSpecification>
|
||||
...
|
||||
```
|
||||
![Screenshot](docs/io.png)
|
||||
### `npm test`
|
||||
|
||||
Using these data input and outputs will allow you to create processes designed to be used as Call Activities. SpiffWorkflow (in a soon-to-be released version) will pick up this information, and enforce it. So that you must provide these input variables to execute, and only the variables mentioned in the output will be passed back to the calling process.
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
## Usage
|
||||
```javascript
|
||||
import BpmnModeler from 'bpmn-js/lib/Modeler';
|
||||
import spiffworkflow from 'bpmn-js-spiffworkflow/app/spiffworkflow';
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
var bpmnJS = new BpmnModeler({
|
||||
additionalModules: [
|
||||
spiffworkflow
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflowModdle: spiffModdleExtension
|
||||
}
|
||||
});
|
||||
```
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
## Run the Example
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
You need a [NodeJS](http://nodejs.org) development stack with [npm](https://npmjs.org) installed to build the project.
|
||||
### `npm run eject`
|
||||
|
||||
To install all project dependencies execute
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
To start the example execute
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
To build the example into the `public` folder execute
|
||||
## Learn More
|
||||
|
||||
```sh
|
||||
npm run all
|
||||
```
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
# Integration Points
|
||||
You can use the EventBus to communicate with this UI, sending and receiving messages to change
|
||||
the behavior of the editor making it easier for your end users. There are many examples of
|
||||
this in the app.js file.
|
||||
Below is a table of all the events that are sent and accepted:
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
| Event Name | Description | Fired or Acceped | Parameters | Description |
|
||||
|--------------------------------|------------------------------------------------------------------|---------|----------------------|--------------------------------------------------------------------------|
|
||||
| spiff.service\_tasks.requested | Request a list of available services for service task. | Fired | \- | |
|
||||
| spiff.service\_tasks.returned | Provides a list of services. | Recieved | serviceTaskOperators | ex: \[{id:'Chuck Facts', parameters\[{id:'category', type:'string'}\]}\] |
|
||||
| spiff.script.edit | Request to edit a python script in some sort of facy editor. | Fired | scriptType | one of: script, preScript, postScript |
|
||||
| | | | value | The actual python script |
|
||||
| | | | element | The element that needs updating |
|
||||
| | | | eventBus | Used by receiver to fire back an event |
|
||||
| spiff.script.update | Update a python script to a new value. | Recieved | scriptType | one of: script, preScript, postScript |
|
||||
| | | | value | The updated script |
|
||||
| | | | element | The element that needs updating |
|
||||
| spiff.markdown.edit | Request to edit markdown in a fancy editor. | Fired | element | The element that needs updating |
|
||||
| | | | value | The current markdown content |
|
||||
| spiff.markdown.update | Update Markdown content for a paticular elements 'instructions'. | Recieved | element | The element that needs updating |
|
||||
| | | | value | Tne updated Markdown content |
|
||||
| spiff.callactivity.edit | Requst to edit a call activity by process id. | Fired | processId | The Process the users wants to edit |
|
||||
| spiff.callactivity.search | Requst to search for a call activity | Fired | processUd | The currently seleted process id |
|
||||
| | | | eventBus | For sending back the selected process id. |
|
||||
| spiff.callactivity.update | Update the process id from a call activity (based on search) | Received | processId | The Process the users wants to edit |
|
||||
| spiff.file.edit | request to edit a file, but file name. | Fired | value | The file name the user wants to edit |
|
||||
| spiff.dmn.edit | request to edit a dmn by process id. | Fired | value | The DMN id the user wants to edit |
|
||||
| spiff.json\_files.requested | request a list of local json files. | Fired | optionType | The type of options required ('json' or 'dmn') |
|
||||
| spff.dmn\_files.requested | request of list of local dmn files. | | | |
|
||||
| spiff.json\_files.returned | Return a list of available json files | Recieved | options | \[{lable:'My Label', value:'1'}\] |
|
||||
| spff.dmn\_files.returned | Return a list of available dmn files. | Recieved | options | \[{lable:'My Label', value:'1'}\] |
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
## License
|
||||
MIT
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
## Releases
|
||||
|
||||
Be sure to edit the package.json, and update the version. Releases won't create
|
||||
a new NPM package unless the version was updated.
|
||||
A good way to do go about this is with npm version. Which will increment the version in package.json and create a new commit and tag. Here are few examples that you might use, but
|
||||
there is more information on [NPM Version](https://docs.npmjs.com/cli/v8/commands/npm-version).
|
||||
|
||||
For doing a patch release, you can do
|
||||
```bash
|
||||
npm version patch -m "Upgrade to %s for reasons"
|
||||
```
|
||||
aside from patch, you can use the keywords `minor`, and `major` (there are some others).
|
||||
|
||||
Once this is complete, log into GitHub and do an offical release of the package. A published release will result in a new published version on NPM (via a GitHub Action)
|
||||
|
225
app/app.js
225
app/app.js
|
@ -1,225 +0,0 @@
|
|||
import BpmnModeler from 'bpmn-js/lib/Modeler';
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import diagramXML from '../test/spec/bpmn/user_form.bpmn';
|
||||
import spiffworkflow from './spiffworkflow';
|
||||
import setupFileOperations from './fileOperations';
|
||||
|
||||
const modelerEl = document.getElementById('modeler');
|
||||
const panelEl = document.getElementById('panel');
|
||||
const spiffModdleExtension = require('./spiffworkflow/moddle/spiffworkflow.json');
|
||||
|
||||
let bpmnModeler;
|
||||
|
||||
/**
|
||||
* This provides an example of how to instantiate a BPMN Modeler configured with
|
||||
* all the extensions and modifications in this application.
|
||||
*/
|
||||
try {
|
||||
bpmnModeler = new BpmnModeler({
|
||||
container: modelerEl,
|
||||
keyboard: { bindTo: document },
|
||||
propertiesPanel: {
|
||||
parent: panelEl,
|
||||
},
|
||||
additionalModules: [
|
||||
spiffworkflow,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflowModdle: spiffModdleExtension,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.constructor.name === 'AggregateError') {
|
||||
console.log(error.message);
|
||||
console.log(error.name);
|
||||
console.log(error.errors);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
/**
|
||||
* It is possible to populate certain components using API calls to
|
||||
* a backend. Here we mock out the API call, but this gives you
|
||||
* a sense of how things might work.
|
||||
*
|
||||
*/
|
||||
bpmnModeler.on('spiff.service_tasks.requested', (event) => {
|
||||
event.eventBus.fire('spiff.service_tasks.returned', {
|
||||
serviceTaskOperators: [
|
||||
{
|
||||
id: 'Chuck Norris Fact Service',
|
||||
parameters: [
|
||||
{
|
||||
id: 'category',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Fact about a Number',
|
||||
parameters: [
|
||||
{
|
||||
id: 'number',
|
||||
type: 'integer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Python Script authoring is best done in some sort of editor
|
||||
* here is an example that will connect a large CodeMirror editor
|
||||
* to the "Launch Editor" buttons (Script Tasks, and the Pre and Post
|
||||
* scripts on all other tasks.
|
||||
*/
|
||||
const myCodeMirror = CodeMirror(document.getElementById('code_editor'), {
|
||||
lineNumbers: true,
|
||||
mode: 'python',
|
||||
});
|
||||
|
||||
const saveCodeBtn = document.getElementById('saveCode');
|
||||
let launchCodeEvent = null;
|
||||
|
||||
bpmnModeler.on('spiff.script.edit', (newEvent) => {
|
||||
launchCodeEvent = newEvent;
|
||||
myCodeMirror.setValue(launchCodeEvent.script);
|
||||
setTimeout(function () {
|
||||
myCodeMirror.refresh();
|
||||
}, 1); // We have to wait a moment before calling refresh.
|
||||
document.getElementById('code_overlay').style.display = 'block';
|
||||
document.getElementById('code_editor').focus();
|
||||
});
|
||||
|
||||
saveCodeBtn.addEventListener('click', (_event) => {
|
||||
const { scriptType, element } = launchCodeEvent;
|
||||
launchCodeEvent.eventBus.fire('spiff.script.update', {
|
||||
element,
|
||||
scriptType,
|
||||
script: myCodeMirror.getValue(),
|
||||
});
|
||||
document.getElementById('code_overlay').style.display = 'none';
|
||||
});
|
||||
|
||||
/**
|
||||
* Like Python Script Editing, it can be nice to edit your Markdown in a
|
||||
* good editor as well.
|
||||
*/
|
||||
const simplemde = new SimpleMDE({
|
||||
element: document.getElementById('markdown_textarea'),
|
||||
});
|
||||
let launchMarkdownEvent = null;
|
||||
bpmnModeler.on('spiff.markdown.edit', (newEvent) => {
|
||||
launchMarkdownEvent = newEvent;
|
||||
simplemde.value(launchMarkdownEvent.value);
|
||||
document.getElementById('markdown_overlay').style.display = 'block';
|
||||
document.getElementById('markdown_editor').focus();
|
||||
});
|
||||
|
||||
const saveMarkdownBtn = document.getElementById('saveMarkdown');
|
||||
saveMarkdownBtn.addEventListener('click', (_event) => {
|
||||
const { element } = launchMarkdownEvent;
|
||||
launchMarkdownEvent.eventBus.fire('spiff.markdown.update', {
|
||||
element,
|
||||
value: simplemde.value(),
|
||||
});
|
||||
document.getElementById('markdown_overlay').style.display = 'none';
|
||||
});
|
||||
|
||||
/**
|
||||
* Also can be good to launch an editor for a call activity, or file
|
||||
* Not implemented here but imagine opening up a new browser tab
|
||||
* and showing a different process or completly different file editor.
|
||||
*/
|
||||
bpmnModeler.on('spiff.callactivity.edit', (newEvent) => {
|
||||
console.log(
|
||||
'Open new window with editor for call activity: ',
|
||||
newEvent.processId
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Also can be good to launch an editor for a call activity, or DMN
|
||||
* Not implemented here but imagine opening up a new browser tab
|
||||
* and showing a different process.
|
||||
*/
|
||||
bpmnModeler.on('spiff.file.edit', (newEvent) => {
|
||||
console.log('Open new window to edit file: ', newEvent.value);
|
||||
});
|
||||
bpmnModeler.on('spiff.dmn.edit', (newEvent) => {
|
||||
console.log('Open new window to edit DMN table: ', newEvent.value);
|
||||
});
|
||||
|
||||
/**
|
||||
* Also handy to get a list of available files that can be used in a given
|
||||
* context, say json files for a form, or a DMN file for a BusinessRuleTask
|
||||
*/
|
||||
bpmnModeler.on('spiff.json_schema_files.requested', (event) => {
|
||||
event.eventBus.fire('spiff.json_schema_files.returned', {
|
||||
options: [
|
||||
{ label: 'pizza_form.json', value: 'pizza_form.json' },
|
||||
{ label: 'credit_card_form.json', value: 'credit_card_form.json' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
bpmnModeler.on('spiff.dmn_files.requested', (event) => {
|
||||
event.eventBus.fire('spiff.dmn_files.returned', {
|
||||
options: [
|
||||
{ label: 'Pizza Special Prices', value: 'pizza_prices' },
|
||||
{ label: 'Topping Prices', value: 'topping_prices' },
|
||||
{ label: 'Test Decision', value: 'test_decision' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
bpmnModeler.on('spiff.data_stores.requested', (event) => {
|
||||
event.eventBus.fire('spiff.data_stores.returned', {
|
||||
options: [
|
||||
{ type: 'typeahead', name: 'countries' },
|
||||
{ type: 'kkv', name: 'foods' }
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// As call activites might refernce processes across the system
|
||||
// it should be possible to search for a paticular call activity.
|
||||
bpmnModeler.on('spiff.callactivity.search', (event) => {
|
||||
console.log("Firing call activity update", event.element)
|
||||
event.eventBus.fire('spiff.callactivity.update', {
|
||||
value: 'searched_bpmn_id',
|
||||
element: event.element,
|
||||
});
|
||||
});
|
||||
|
||||
/* This restores unresolved references that camunda removes */
|
||||
|
||||
bpmnModeler.on('import.parse.complete', event => {
|
||||
const refs = event.references.filter(r => r.property === 'bpmn:loopDataInputRef' || r.property === 'bpmn:loopDataOutputRef');
|
||||
const desc = bpmnModeler._moddle.registry.getEffectiveDescriptor('bpmn:ItemAwareElement');
|
||||
refs.forEach(ref => {
|
||||
const props = {
|
||||
id: ref.id,
|
||||
name: ref.id ? typeof (ref.name) === 'undefined' : ref.name,
|
||||
};
|
||||
let elem = bpmnModeler._moddle.create(desc, props);
|
||||
elem.$parent = ref.element;
|
||||
ref.element.set(ref.property, elem);
|
||||
});
|
||||
});
|
||||
|
||||
bpmnModeler.importXML(diagramXML).then(() => {
|
||||
// Zoom up and center workflow in the middle of the canvas
|
||||
bpmnModeler.get('canvas').zoom('fit-viewport', 'auto');
|
||||
});
|
||||
|
||||
// This handles the download and upload buttons - it isn't specific to
|
||||
// the BPMN modeler or these extensions, just a quick way to allow you to
|
||||
// create and save files, so keeping it outside the example.
|
||||
setupFileOperations(bpmnModeler);
|
341
app/css/app.css
341
app/css/app.css
|
@ -1,341 +0,0 @@
|
|||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#container {
|
||||
display: flex;
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
.spiffworkflow-properties-panel-button {
|
||||
margin: 2px 32px 6px 12px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
/* Style buttons */
|
||||
.bpmn-js-spiffworkflow-btn {
|
||||
background-color: #ffffff;
|
||||
color: #393939;
|
||||
border: 1px solid #393939;
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.main-btn {
|
||||
background-color: #0F62FE;
|
||||
color: white;
|
||||
border: 1px solid #0F62FE;
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.main-btn i {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
/* Darker background on mouse-over */
|
||||
.bpmn-js-spiffworkflow-btn:hover {
|
||||
background-color: rgb(0, 0, 0);
|
||||
border: 1px solid #000000;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Code Editor -- provided as a div overlay */
|
||||
.overlay {
|
||||
position: fixed;
|
||||
/* Sit on top of the page content */
|
||||
display: none;
|
||||
/* Hidden by default */
|
||||
width: 100%;
|
||||
/* Full width (cover the whole page) */
|
||||
height: 100%;
|
||||
/* Full height (cover the whole page) */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
/* Black background with opacity */
|
||||
z-index: 200;
|
||||
/* BPMN Canvas has some huge z-indexes, pop-up tools are 100 for ex.*/
|
||||
}
|
||||
|
||||
#code_editor,
|
||||
#markdown_editor {
|
||||
background-color: #ccc;
|
||||
margin: 50px auto 10px auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
#code_buttons,
|
||||
#markdown_buttons {
|
||||
margin: 50px auto 10px auto;
|
||||
max-width: 800px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.djs-palette.two-column.open {
|
||||
width: 95px;
|
||||
}
|
||||
|
||||
|
||||
/* Header */
|
||||
#header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: black;
|
||||
border-bottom: 1px solid #5F5F5F;
|
||||
}
|
||||
|
||||
#header-actions-center {
|
||||
/* Adjust as needed */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
border: 0.75px solid #8F8F8F;
|
||||
}
|
||||
|
||||
.header-btn {
|
||||
background: none;
|
||||
color: #3c3c3c;
|
||||
border: none;
|
||||
padding: 10px 10px;
|
||||
cursor: pointer;
|
||||
margin-left: 5px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.header-btn i {
|
||||
margin-right: 5px;
|
||||
/* Icon spacing */
|
||||
}
|
||||
|
||||
|
||||
#process-info h1 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
#process-info p {
|
||||
margin: 5px 0 0 0;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bpmn-js-spiffworkflow-btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* Left sidebar */
|
||||
#left-sidebar {
|
||||
display: flex;
|
||||
max-width: 300px;
|
||||
background-color: #ffffff;
|
||||
/* background-color: #f4f4f4; */
|
||||
overflow: hidden;
|
||||
height: calc(100% - 80px);
|
||||
float: left;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid #5F5F5F;
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 50px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab-button i {
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.tab-button .text {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tab-button.active i {
|
||||
color: #146D83;
|
||||
}
|
||||
|
||||
.tab-button i {
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.tab-button.active i {
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.tab-button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab-button.active,
|
||||
.tab-button:hover {
|
||||
background-color: #e9e9e9;
|
||||
color: DodgerBlue;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
height: 100%;
|
||||
width: 300px;
|
||||
border-right: 1px solid #5F5F5F;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#container::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#BPMNElements {
|
||||
border-bottom: 1px solid #5F5F5F;
|
||||
}
|
||||
|
||||
.bpmn-elements-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #5F5F5F;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.bpmn-elements-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bpmn-elements-toggle {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.djs-palette {
|
||||
position: relative;
|
||||
display: unset;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.group-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-block: 5px;
|
||||
padding-inline: 10px;
|
||||
background: #f8f8f8;
|
||||
border-bottom: 1px solid #ddd;
|
||||
/* cursor: pointer; */
|
||||
}
|
||||
|
||||
.group-title span {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.group.collapsed .entry {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.group-toggle {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.djs-palette-entries {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.djs-palette .entry,
|
||||
.djs-palette .djs-palette-toggle {
|
||||
justify-items: center;
|
||||
padding-block: 5px;
|
||||
height: unset;
|
||||
width: unset;
|
||||
line-height: unset;
|
||||
display: inline-grid;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.entry-label {
|
||||
color: #22242A;
|
||||
text-align: center;
|
||||
font-family: Inter;
|
||||
font-size: 10px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.entries-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.entry {
|
||||
flex: 0 0 calc(25% - 10px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-block: 5px;
|
||||
}
|
BIN
app/favicon.png
BIN
app/favicon.png
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB |
|
@ -1,186 +0,0 @@
|
|||
// FileSaver isn't really a dependency, we use it here to provide an example.
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import FileSaver from 'file-saver';
|
||||
|
||||
/** ****************************************
|
||||
* Below are a few helper methods so we can upload and download files
|
||||
* easily from the editor for testing purposes.
|
||||
* -----------------------------------------
|
||||
*/
|
||||
export default function setupFileOperations(bpmnModeler) {
|
||||
/**
|
||||
* 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(bpmnModeler);
|
||||
});
|
||||
|
||||
// Handle header actions
|
||||
const headerButtons = document.querySelectorAll('.header-btn');
|
||||
headerButtons.forEach(function (btn) {
|
||||
btn.addEventListener('click', function (event) {
|
||||
const action = event.target.closest('.header-btn').getAttribute('data-action');
|
||||
handleHeaderAction(action, bpmnModeler);
|
||||
});
|
||||
});
|
||||
|
||||
// Handle sidebar toggle button
|
||||
const toggleButtons = document.querySelectorAll('.bpmn-elements-toggle');
|
||||
toggleButtons.forEach(function (btn) {
|
||||
btn.addEventListener('click', function (event) {
|
||||
// Use a data attribute to identify which tab to toggle
|
||||
const tabTarget = event.target.closest('button').getAttribute('data-tab-target');
|
||||
toggleTab(tabTarget);
|
||||
});
|
||||
});
|
||||
|
||||
// Setup tabs after modeler is initialized
|
||||
setupTabs();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
export function openFile(bpmnModeler) {
|
||||
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;
|
||||
bpmnModeler.importXML(contents);
|
||||
document.body.removeChild(fileInput);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
};
|
||||
let fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.style.display = 'none';
|
||||
fileInput.onchange = readFile;
|
||||
document.body.appendChild(fileInput);
|
||||
clickElem(fileInput);
|
||||
}
|
||||
|
||||
/** ****************************************
|
||||
* Tab functionality
|
||||
*/
|
||||
function openTab(event, tabName) {
|
||||
|
||||
// Hide all tab contents
|
||||
const tabContents = document.querySelectorAll('.tab-content');
|
||||
tabContents.forEach(content => {
|
||||
content.classList.remove('active');
|
||||
});
|
||||
|
||||
// Remove active class from all tabs
|
||||
const tabButtons = document.querySelectorAll('.tab-button');
|
||||
tabButtons.forEach(button => {
|
||||
button.classList.remove('active');
|
||||
});
|
||||
|
||||
// append active tab content class to the clicked tab button
|
||||
document.getElementById(tabName).classList.add('active');
|
||||
event.currentTarget.classList.add('active');
|
||||
}
|
||||
|
||||
function setupTabs() {
|
||||
const tabs = document.querySelectorAll('.tab-button');
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', function (event) {
|
||||
openTab(event, this.getAttribute('data-tab-target'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function toggleTab(tabId) {
|
||||
const tabContent = document.getElementById(tabId);
|
||||
const allTabContents = document.querySelectorAll('.tab-content');
|
||||
|
||||
// Remove 'active' from all tabs
|
||||
allTabContents.forEach(function (tab) {
|
||||
tab.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Header functionality
|
||||
*/
|
||||
function handleHeaderAction(action, bpmnModeler) {
|
||||
var commandStack = bpmnModeler.get('commandStack');
|
||||
var paletteProvider = bpmnModeler.get('paletteProvider');
|
||||
var canvas = bpmnModeler.get('canvas');
|
||||
switch (action) {
|
||||
case 'zoom-in':
|
||||
bpmnModeler.get('zoomScroll').stepZoom(1);
|
||||
break;
|
||||
case 'zoom-out':
|
||||
bpmnModeler.get('zoomScroll').stepZoom(-1);
|
||||
break;
|
||||
case 'expand':
|
||||
canvas.zoom('fit-viewport', 'auto');
|
||||
break;
|
||||
case 'undo':
|
||||
commandStack.undo();
|
||||
break;
|
||||
case 'redo':
|
||||
commandStack.redo();
|
||||
break;
|
||||
case 'hand':
|
||||
const handTool = paletteProvider._handTool;
|
||||
handTool.activateHand();
|
||||
break;
|
||||
case 'lasso':
|
||||
const lassoTool = paletteProvider._lassoTool;
|
||||
lassoTool.activateSelection(event);
|
||||
break;
|
||||
case 'space':
|
||||
const spaceTool = paletteProvider._spaceTool;
|
||||
spaceTool.activateSelection();
|
||||
break;
|
||||
case 'connect':
|
||||
const globalConnect = paletteProvider._globalConnect;
|
||||
globalConnect.start();
|
||||
break;
|
||||
default:
|
||||
console.log('Unknown action:', action);
|
||||
}
|
||||
}
|
172
app/index.html
172
app/index.html
|
@ -1,172 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>bpmn-js-spiffworkflow</title>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- here are the core dependencies you will need to include -->
|
||||
<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" />
|
||||
|
||||
<!-- Some local css settings -->
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<link rel="shortcut icon" href="#">
|
||||
|
||||
<!-- A python code editor, we are using CodeMirror here -- see app.js for how this is wired in -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/codemirror.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/mode/python/python.min.js"></script>
|
||||
|
||||
<!-- Markdown Editor -- see app.js for how to wire these in. -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
|
||||
|
||||
<!-- 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="header">
|
||||
<div id="process-info">
|
||||
<h1>Process Name</h1>
|
||||
<p>./Process Groups/bpmn_process.bpmn</p>
|
||||
</div>
|
||||
<div id="header-actions-center">
|
||||
<button class="header-btn" title="Hand" data-action="hand">
|
||||
<i class="bpmn-icon-hand-tool"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="LassoTool" data-action="lasso">
|
||||
<i class="bpmn-icon-lasso-tool"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="SpaceTool" data-action="space">
|
||||
<i class="bpmn-icon-space-tool"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Connect" data-action="connect">
|
||||
<i class="bpmn-icon-connection-multi"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Zoom In" data-action="zoom-in">
|
||||
<i class="fa fa-search-plus"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Zoom Out" data-action="zoom-out">
|
||||
<i class="fa fa-search-minus"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Expand" data-action="expand">
|
||||
<i class="fa fa-expand"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Undo" data-action="undo">
|
||||
<i class="fa fa-undo"></i>
|
||||
</button>
|
||||
<button class="header-btn" title="Redo" data-action="redo">
|
||||
<i class="fa fa-repeat"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="header-actions">
|
||||
<button id="downloadButton" class="bpmn-js-spiffworkflow-btn">
|
||||
Download
|
||||
</button>
|
||||
<button id="uploadButton" class="bpmn-js-spiffworkflow-btn">Open a file</button>
|
||||
<button id="viewXmlButton" class="bpmn-js-spiffworkflow-btn">View XML</button>
|
||||
<button id="saveButton" class="bpmn-js-spiffworkflow-btn main-btn">
|
||||
Save <i class="fa fa-long-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left-sidebar">
|
||||
<div class="tabs">
|
||||
<button class="tab-button active" data-tab-target="BPMNElements">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</button>
|
||||
<button class="tab-button" data-tab-target="SearchTab">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
<button class="tab-button" data-tab-target="ActionTab">
|
||||
<i class="fa fa-bolt"></i>
|
||||
</button>
|
||||
<button class="tab-button" data-tab-target="ConnectorTab">
|
||||
<i class="fa fa-cube"></i>
|
||||
</button>
|
||||
<button class="tab-button" data-tab-target="HistoryTab">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="BPMNElements" class="tab-content active">
|
||||
<div class="bpmn-elements-header">
|
||||
<span class="bpmn-elements-title">BPMN Elements</span>
|
||||
<button class="bpmn-elements-toggle">
|
||||
<i class="fa fa-outdent" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content for BPMN Elements -->
|
||||
</div>
|
||||
<div id="HistoryTab" class="tab-content">
|
||||
<div class="bpmn-elements-header">
|
||||
<span class="bpmn-elements-title">History</span>
|
||||
<button class="bpmn-elements-toggle">
|
||||
<i class="fa fa-outdent" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content for BPMN Elements -->
|
||||
History Tab Content
|
||||
</div>
|
||||
<div id="ActionTab" class="tab-content">
|
||||
<div class="bpmn-elements-header">
|
||||
<span class="bpmn-elements-title">Visual Activity</span>
|
||||
<button class="bpmn-elements-toggle">
|
||||
<i class="fa fa-outdent" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content for BPMN Elements -->
|
||||
Pre built Actions Tab Content
|
||||
</div>
|
||||
<div id="SearchTab" class="tab-content">
|
||||
<div class="bpmn-elements-header">
|
||||
<span class="bpmn-elements-title">Search</span>
|
||||
<button class="bpmn-elements-toggle">
|
||||
<i class="fa fa-outdent" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content for BPMN Elements -->
|
||||
Search Tab Content
|
||||
</div>
|
||||
<div id="ConnectorTab" class="tab-content">
|
||||
<div class="bpmn-elements-header">
|
||||
<span class="bpmn-elements-title">Integrations / Connectors </span>
|
||||
<button class="bpmn-elements-toggle">
|
||||
<i class="fa fa-outdent" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content for BPMN Elements -->
|
||||
Connectors Tab Content
|
||||
</div>
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="modeler"></div>
|
||||
<div id="panel"></div>
|
||||
</div>
|
||||
<!-- the following are overlays to provide editors for Python and Markdown -->
|
||||
<div id="code_overlay" class="overlay">
|
||||
<div id="code_editor"></div>
|
||||
<div id="code_buttons">
|
||||
<button id="saveCode" class="bpmn-js-spiffworkflow-btn">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="markdown_overlay" class="overlay">
|
||||
<div id="markdown_editor">
|
||||
<textarea id="markdown_textarea"></textarea>
|
||||
</div>
|
||||
<div id="markdown_buttons">
|
||||
<button id="saveMarkdown" class="bpmn-js-spiffworkflow-btn">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Here we load up our application, it's where the configuration happens. -->
|
||||
<script src="app.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,299 +0,0 @@
|
|||
import { assign } from 'min-dash';
|
||||
import translate from 'diagram-js/lib/i18n/translate/translate';
|
||||
|
||||
/**
|
||||
* Add data inputs and data outputs to the panel.
|
||||
*/
|
||||
export default function IoPalette(palette, create, elementFactory, eventBus, handTool, globalConnect, lassoTool, spaceTool) {
|
||||
this._create = create;
|
||||
this._elementFactory = elementFactory;
|
||||
|
||||
this._handTool = handTool;
|
||||
this._globalConnect = globalConnect;
|
||||
this._lassoTool = lassoTool;
|
||||
this._spaceTool = spaceTool;
|
||||
|
||||
eventBus.on('palette.create', function (event) {
|
||||
this.init(event);
|
||||
}.bind(this));
|
||||
|
||||
palette.registerProvider(this);
|
||||
}
|
||||
|
||||
IoPalette.$inject = [
|
||||
'palette',
|
||||
'create',
|
||||
'elementFactory',
|
||||
'eventBus',
|
||||
'handTool',
|
||||
'globalConnect',
|
||||
'lassoTool',
|
||||
'spaceTool'
|
||||
];
|
||||
|
||||
IoPalette.prototype.getPaletteEntries = function (e) {
|
||||
|
||||
let input_type = 'bpmn:DataInput';
|
||||
let output_type = 'bpmn:DataOutput';
|
||||
let elementFactory = this._elementFactory, create = this._create;
|
||||
|
||||
function createListener(event, type) {
|
||||
let shape = elementFactory.createShape(assign({ type: type }, {}));
|
||||
shape.width = 36; // Fix up the shape dimensions from the defaults.
|
||||
shape.height = 50;
|
||||
create.start(event, shape);
|
||||
}
|
||||
|
||||
function createInputListener(event) {
|
||||
createListener(event, input_type);
|
||||
}
|
||||
|
||||
function createOutputListener(event) {
|
||||
createListener(event, output_type);
|
||||
}
|
||||
|
||||
function createShape(type, options = {}) {
|
||||
return function(event) {
|
||||
let shape = elementFactory.createShape(assign({ type: type }, options));
|
||||
create.start(event, shape);
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
// Events
|
||||
'create.start-event': {
|
||||
group: 'events',
|
||||
className: 'bpmn-icon-start-event-none',
|
||||
title: translate('Start'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:StartEvent'),
|
||||
click: createShape('bpmn:StartEvent')
|
||||
}
|
||||
},
|
||||
'create.intermediate-event': {
|
||||
group: 'events',
|
||||
className: 'bpmn-icon-intermediate-event-none',
|
||||
title: translate('Intermediate'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:IntermediateCatchEvent'),
|
||||
click: createShape('bpmn:IntermediateCatchEvent')
|
||||
}
|
||||
},
|
||||
'create.end-event': {
|
||||
group: 'events',
|
||||
className: 'bpmn-icon-end-event-none',
|
||||
title: translate('End'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:EndEvent'),
|
||||
click: createShape('bpmn:EndEvent')
|
||||
}
|
||||
},
|
||||
// Activities
|
||||
'create.task': {
|
||||
group: 'activities',
|
||||
className: 'bpmn-icon-task',
|
||||
title: translate('Task'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:Task'),
|
||||
click: createShape('bpmn:Task')
|
||||
}
|
||||
},
|
||||
'create.user-task': {
|
||||
group: 'activities',
|
||||
className: 'bpmn-icon-user',
|
||||
title: translate('User Task'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:UserTask'),
|
||||
click: createShape('bpmn:UserTask')
|
||||
}
|
||||
},
|
||||
'create.scirpt-task': {
|
||||
group: 'activities',
|
||||
className: 'bpmn-icon-script',
|
||||
title: translate('Script Task'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:ScriptTask'),
|
||||
click: createShape('bpmn:ScriptTask')
|
||||
}
|
||||
},
|
||||
'create.service-task': {
|
||||
group: 'activities',
|
||||
className: 'bpmn-icon-service',
|
||||
title: translate('Service Task'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:ServiceTask'),
|
||||
click: createShape('bpmn:ServiceTask')
|
||||
}
|
||||
},
|
||||
// Gateways
|
||||
'create.condition-gateaway': {
|
||||
group: 'decisions',
|
||||
className: 'bpmn-icon-gateway-xor',
|
||||
title: translate('Decision'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:ExclusiveGateway'),
|
||||
click: createShape('bpmn:ExclusiveGateway')
|
||||
}
|
||||
},
|
||||
'create.parallel-gateaway': {
|
||||
group: 'decisions',
|
||||
className: 'bpmn-icon-gateway-parallel',
|
||||
title: translate('Parallel'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:ParallelGateway'),
|
||||
click: createShape('bpmn:ParallelGateway')
|
||||
}
|
||||
},
|
||||
'create.eventbased-gateaway': {
|
||||
group: 'decisions',
|
||||
className: 'bpmn-icon-gateway-eventbased',
|
||||
title: translate('Event Based'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:EventBasedGateway'),
|
||||
click: createShape('bpmn:EventBasedGateway')
|
||||
}
|
||||
},
|
||||
'create.inclusive-gateaway': {
|
||||
group: 'decisions',
|
||||
className: 'bpmn-icon-gateway-or',
|
||||
title: translate('xOR'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:InclusiveGateway'),
|
||||
click: createShape('bpmn:InclusiveGateway')
|
||||
}
|
||||
},
|
||||
// Data Object
|
||||
'create.data-store': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-data-store',
|
||||
title: translate('Data Store'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:DataStoreReference'),
|
||||
click: createShape('bpmn:DataStoreReference')
|
||||
}
|
||||
},
|
||||
'create.data-object': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-data-object',
|
||||
title: translate('Data Object'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:DataObjectReference'),
|
||||
click: createShape('bpmn:DataObjectReference')
|
||||
}
|
||||
},
|
||||
'create.data-input': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-data-input',
|
||||
title: translate('DataInput'),
|
||||
action: {
|
||||
dragstart: createInputListener,
|
||||
click: createInputListener
|
||||
}
|
||||
},
|
||||
'create.data-output': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-data-output',
|
||||
title: translate('DataOutput'),
|
||||
action: {
|
||||
dragstart: createOutputListener,
|
||||
click: createOutputListener
|
||||
}
|
||||
},
|
||||
'create.call-activity': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-call-activity',
|
||||
title: translate('Call Activity'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:CallActivity'),
|
||||
click: createShape('bpmn:CallActivity')
|
||||
}
|
||||
},
|
||||
'create.participant': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-participant',
|
||||
title: translate('Participant'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:Participant'),
|
||||
click: createShape('bpmn:Participant')
|
||||
}
|
||||
},
|
||||
'create.sub-process-expanded': {
|
||||
group: 'advanced',
|
||||
className: 'bpmn-icon-subprocess-expanded',
|
||||
title: translate('SubProcess'),
|
||||
action: {
|
||||
dragstart: createShape('bpmn:SubProcess', {isExpanded: true}),
|
||||
click: createShape('bpmn:SubProcess', {isExpanded: true})
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
IoPalette.prototype.init = function (event) {
|
||||
|
||||
// Override Palette DOM Generated by BPMN-JS Library
|
||||
const paletteContainer = event.container;
|
||||
const bpmnElementsDiv = document.getElementById('BPMNElements');
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
// Query all group elements
|
||||
const groups = paletteContainer.querySelectorAll('.group');
|
||||
|
||||
groups.forEach(group => {
|
||||
const groupName = group.getAttribute('data-group');
|
||||
const title = groupName.charAt(0).toUpperCase() + groupName.slice(1).replace(/-/g, ' '); // Capitalize and format the title
|
||||
|
||||
// Check if group title already exists
|
||||
let header = group.querySelector('.group-title');
|
||||
let entriesContainer = group.querySelector('.entries-container'); // Container for entries
|
||||
|
||||
if (!header) {
|
||||
// Creation the collapsible header
|
||||
header = document.createElement('div');
|
||||
header.classList.add('group-title');
|
||||
|
||||
// Creation the title span
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = title;
|
||||
header.appendChild(titleSpan);
|
||||
|
||||
// Creation the toggle button
|
||||
const toggleButton = document.createElement('button');
|
||||
toggleButton.classList.add('group-toggle');
|
||||
toggleButton.innerHTML = '<i class="fa fa-chevron-down" aria-hidden="true"></i>';
|
||||
header.appendChild(toggleButton);
|
||||
|
||||
// Insert the header
|
||||
group.insertBefore(header, group.firstChild);
|
||||
|
||||
// Create the entries container
|
||||
entriesContainer = document.createElement('div');
|
||||
entriesContainer.classList.add('entries-container');
|
||||
group.appendChild(entriesContainer); // Append entries container after the header
|
||||
|
||||
toggleButton.addEventListener('click', function () {
|
||||
entriesContainer.style.display = entriesContainer.style.display === 'none' ? '' : 'none';
|
||||
toggleButton.innerHTML = entriesContainer.style.display === 'none' ? '<i class="fa fa-chevron-right" aria-hidden="true"></i>' : '<i class="fa fa-chevron-down" aria-hidden="true"></i>';
|
||||
});
|
||||
}
|
||||
const entries = group.querySelectorAll('.entry');
|
||||
entries.forEach(entry => {
|
||||
entriesContainer.appendChild(entry);
|
||||
|
||||
let label = entry.querySelector('.entry-label');
|
||||
if (!label) {
|
||||
label = document.createElement('span');
|
||||
label.classList.add('entry-label');
|
||||
entry.appendChild(label);
|
||||
}
|
||||
label.textContent = entry.getAttribute('title');
|
||||
});
|
||||
});
|
||||
|
||||
// Move the palette
|
||||
bpmnElementsDiv.appendChild(paletteContainer);
|
||||
|
||||
}, 200);
|
||||
|
||||
};
|
BIN
docs/io.png
BIN
docs/io.png
Binary file not shown.
Before Width: | Height: | Size: 9.1 KiB |
126
karma.conf.js
126
karma.conf.js
|
@ -1,126 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const coverage = process.env.COVERAGE;
|
||||
const path = require('path');
|
||||
const {
|
||||
DefinePlugin,
|
||||
NormalModuleReplacementPlugin
|
||||
} = require('webpack');
|
||||
const basePath = '.';
|
||||
const absoluteBasePath = path.resolve(path.join(__dirname, basePath));
|
||||
|
||||
module.exports = function(karma) {
|
||||
karma.set({
|
||||
|
||||
frameworks: [
|
||||
'webpack',
|
||||
'mocha',
|
||||
'sinon-chai'
|
||||
],
|
||||
|
||||
files: [
|
||||
'test/spec/**/*Spec.js',
|
||||
],
|
||||
|
||||
reporters: [ 'dots' ],
|
||||
|
||||
preprocessors: {
|
||||
'test/spec/**/*Spec.js': [ 'webpack', 'env' ]
|
||||
},
|
||||
|
||||
browsers: [ 'ChromeHeadless' ],
|
||||
|
||||
browserNoActivityTimeout: 30000,
|
||||
|
||||
singleRun: true,
|
||||
autoWatch: false,
|
||||
|
||||
webpack: {
|
||||
mode: 'development',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(css|bpmn)$/,
|
||||
use: 'raw-loader'
|
||||
},
|
||||
{
|
||||
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: /\.svg$/,
|
||||
use: [ 'react-svg-loader' ]
|
||||
}
|
||||
].concat(coverage ?
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: {
|
||||
loader: 'istanbul-instrumenter-loader',
|
||||
options: { esModules: true }
|
||||
},
|
||||
enforce: 'post',
|
||||
include: /src\.*/,
|
||||
exclude: /node_modules/
|
||||
} : []
|
||||
)
|
||||
},
|
||||
plugins: [
|
||||
new DefinePlugin({
|
||||
// @barmac: process.env has to be defined to make @testing-library/preact work
|
||||
'process.env': {}
|
||||
}),
|
||||
new NormalModuleReplacementPlugin(
|
||||
/^preact(\/[^/]+)?$/,
|
||||
function(resource) {
|
||||
|
||||
const replMap = {
|
||||
'preact/hooks': path.resolve('node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js'),
|
||||
'preact/jsx-runtime': path.resolve('node_modules/@bpmn-io/properties-panel/preact/jsx-runtime/dist/jsxRuntime.module.js'),
|
||||
'preact': path.resolve('node_modules/@bpmn-io/properties-panel/preact/dist/preact.module.js')
|
||||
};
|
||||
|
||||
const replacement = replMap[resource.request];
|
||||
|
||||
if (!replacement) {
|
||||
return;
|
||||
}
|
||||
|
||||
resource.request = replacement;
|
||||
}
|
||||
),
|
||||
new NormalModuleReplacementPlugin(
|
||||
/^preact\/hooks/,
|
||||
path.resolve('node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js')
|
||||
)
|
||||
],
|
||||
resolve: {
|
||||
mainFields: [
|
||||
'browser',
|
||||
'module',
|
||||
'main'
|
||||
],
|
||||
alias: {
|
||||
'preact': '@bpmn-io/properties-panel/preact',
|
||||
'react': '@bpmn-io/properties-panel/preact/compat',
|
||||
'react-dom': '@bpmn-io/properties-panel/preact/compat'
|
||||
},
|
||||
modules: [
|
||||
'node_modules',
|
||||
absoluteBasePath
|
||||
]
|
||||
},
|
||||
devtool: 'eval-source-map'
|
||||
}
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load Diff
118
package.json
118
package.json
|
@ -1,88 +1,42 @@
|
|||
{
|
||||
"name": "bpmn-js-spiffworkflow",
|
||||
"version": "0.0.8",
|
||||
"description": "Extensions and modifications of BPMN.js to improve BPMN development for SpiffWorkflow",
|
||||
"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 app *.js",
|
||||
"lint:fix": "./node_modules/.bin/eslint --fix app *.js",
|
||||
"start": "run-s build serve",
|
||||
"test": "karma start karma.conf.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sartography/bpmn-js-spiffworkflow"
|
||||
},
|
||||
"keywords": [
|
||||
"bpmn",
|
||||
"spiffworkflow"
|
||||
],
|
||||
"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"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"name": "bpmn-js-react",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"bpmn-js": "^13.0.0",
|
||||
"bpmn-js-properties-panel": "*",
|
||||
"diagram-js": "*"
|
||||
"diagram-js": "*",
|
||||
"font-awesome": "^4.7.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"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"
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
<?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_19o7vxg" 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="ProcessTest" isExecutable="true">
|
||||
<bpmn:ioSpecification>
|
||||
<bpmn:dataInput id="num_dogs" name="Number of Dogs" />
|
||||
<bpmn:dataOutput id="happy_index" name="Happiness Index" />
|
||||
</bpmn:ioSpecification>
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1mezzcx</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:endEvent id="Event_14wzv4j">
|
||||
<bpmn:incoming>Flow_0q4oys2</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_01jg677" sourceRef="Activity_15zz6ya" targetRef="my_script_task" />
|
||||
<bpmn:sequenceFlow id="Flow_1mezzcx" sourceRef="StartEvent_1" targetRef="Activity_15zz6ya" />
|
||||
<bpmn:manualTask id="Activity_15zz6ya" name="eat hot dog">
|
||||
<bpmn:incoming>Flow_1mezzcx</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_01jg677</bpmn:outgoing>
|
||||
<bpmn:dataOutputAssociation id="DataOutputAssociation_1uj5jzs">
|
||||
<bpmn:targetRef>my_data_ref_1</bpmn:targetRef>
|
||||
</bpmn:dataOutputAssociation>
|
||||
<bpmn:standardLoopCharacteristics />
|
||||
</bpmn:manualTask>
|
||||
<bpmn:sequenceFlow id="Flow_0q4oys2" sourceRef="my_script_task" targetRef="Event_14wzv4j" />
|
||||
<bpmn:scriptTask id="my_script_task" name="calculate contentment">
|
||||
<bpmn:incoming>Flow_01jg677</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0q4oys2</bpmn:outgoing>
|
||||
<bpmn:property id="Property_1w1963p" name="__targetRef_placeholder" />
|
||||
<bpmn:dataInputAssociation id="DataInputAssociation_0thubmi">
|
||||
<bpmn:sourceRef>my_data_ref_2</bpmn:sourceRef>
|
||||
<bpmn:targetRef>Property_1w1963p</bpmn:targetRef>
|
||||
</bpmn:dataInputAssociation>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:dataObject id="my_data_object" />
|
||||
<bpmn:dataObject id="my_other_data_object" />
|
||||
<bpmn:dataObject id="my_third_data_object" />
|
||||
<bpmn:dataObjectReference id="my_data_ref_1" name="my_data_object" dataObjectRef="my_data_object" />
|
||||
<bpmn:dataObjectReference id="my_data_ref_2" name="my_data_object" dataObjectRef="my_data_object" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ProcessTest">
|
||||
<bpmndi:BPMNEdge id="Flow_0q4oys2_di" bpmnElement="Flow_0q4oys2">
|
||||
<di:waypoint x="540" y="197" />
|
||||
<di:waypoint x="602" y="197" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1mezzcx_di" bpmnElement="Flow_1mezzcx">
|
||||
<di:waypoint x="215" y="197" />
|
||||
<di:waypoint x="280" y="197" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_01jg677_di" bpmnElement="Flow_01jg677">
|
||||
<di:waypoint x="380" y="197" />
|
||||
<di:waypoint x="440" y="197" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="179" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_14wzv4j_di" bpmnElement="Event_14wzv4j">
|
||||
<dc:Bounds x="602" y="179" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0t7iwfm_di" bpmnElement="Activity_15zz6ya">
|
||||
<dc:Bounds x="280" y="157" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0h86vbv_di" bpmnElement="my_script_task">
|
||||
<dc:Bounds x="440" y="157" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_1cezipn_di" bpmnElement="my_data_ref_1">
|
||||
<dc:Bounds x="312" y="275" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="314" y="332" width="33" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_08bm72g_di" bpmnElement="my_data_ref_2">
|
||||
<dc:Bounds x="462" y="275" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="464" y="332" width="33" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="dataInput_1" bpmnElement="num_dogs">
|
||||
<dc:Bounds x="179" y="85" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="158" y="135" width="81" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="dataInput_2" bpmnElement="happy_index">
|
||||
<dc:Bounds x="602" y="85" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="580" y="142" width="83" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="DataOutputAssociation_1uj5jzs_di" bpmnElement="DataOutputAssociation_1uj5jzs">
|
||||
<di:waypoint x="329" y="237" />
|
||||
<di:waypoint x="328" y="275" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataInputAssociation_0thubmi_di" bpmnElement="DataInputAssociation_0thubmi">
|
||||
<di:waypoint x="483" y="275" />
|
||||
<di:waypoint x="489" y="237" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
html, body, .App, #root {
|
||||
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;
|
||||
}
|
||||
|
||||
.spiffworkflow-properties-panel-button {
|
||||
margin: 2px 32px 6px 12px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
/* Style buttons */
|
||||
.bpmn-js-spiffworkflow-btn {
|
||||
background-color: DodgerBlue;
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
/* Darker background on mouse-over */
|
||||
.bpmn-js-spiffworkflow-btn:hover {
|
||||
background-color: RoyalBlue;
|
||||
}
|
||||
|
||||
/* Code Editor -- provided as a div overlay */
|
||||
.overlay {
|
||||
position: fixed; /* Sit on top of the page content */
|
||||
display: none; /* Hidden by default */
|
||||
width: 100%; /* Full width (cover the whole page) */
|
||||
height: 100%; /* Full height (cover the whole page) */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
|
||||
z-index: 200; /* BPMN Canvas has some huge z-indexes, pop-up tools are 100 for ex.*/
|
||||
}
|
||||
|
||||
#code_editor, #markdown_editor {
|
||||
background-color: #ccc;
|
||||
margin: 50px auto 10px auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
#code_buttons, #markdown_buttons {
|
||||
margin: 50px auto 10px auto;
|
||||
max-width: 800px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.djs-palette.two-column.open {
|
||||
width: 95px;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
import BpmnModeler from 'bpmn-js/lib/Modeler';
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
|
||||
import spiffworkflow from './spiffworkflow';
|
||||
|
||||
import './App.css';
|
||||
|
||||
|
||||
// Import BPMN JS CSS
|
||||
import 'bpmn-js/dist/assets/diagram-js.css'
|
||||
import 'bpmn-js/dist/assets/bpmn-js.css'
|
||||
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
|
||||
import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'
|
||||
|
||||
// Import Font Awesome
|
||||
import 'font-awesome/css/font-awesome.min.css';
|
||||
|
||||
function App() {
|
||||
|
||||
const modelerRef = useRef(null);
|
||||
const panelRef = useRef(null);
|
||||
// const codeEditorRef = useRef(null);
|
||||
// const markdownTextareaRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
console.log('Hi App!');
|
||||
|
||||
|
||||
// If modelerRef or panelRef are not empty, make it empty
|
||||
if (modelerRef.current) {
|
||||
modelerRef.current.innerHTML = '';
|
||||
}
|
||||
if (panelRef.current) {
|
||||
panelRef.current.innerHTML = '';
|
||||
}
|
||||
|
||||
// Initialize BPMN Modeler
|
||||
const spiffModdleExtension = require('./spiffworkflow/moddle/spiffworkflow.json');
|
||||
let bpmnModeler;
|
||||
|
||||
// Initialize BPMN Modeler
|
||||
try {
|
||||
bpmnModeler = new BpmnModeler({
|
||||
container: modelerRef.current,
|
||||
keyboard: { bindTo: document },
|
||||
propertiesPanel: {
|
||||
parent: panelRef.current,
|
||||
},
|
||||
additionalModules: [
|
||||
spiffworkflow,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflowModdle: spiffModdleExtension,
|
||||
},
|
||||
});
|
||||
// ... rest of the initialization code
|
||||
|
||||
// Declare XML content as string example
|
||||
try {
|
||||
let xmlContent = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn">
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:startEvent id="StartEvent_1"/>
|
||||
<bpmn:task id="Task_1" name="Sample Task"/>
|
||||
<bpmn:endEvent id="EndEvent_1"/>
|
||||
<bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="Task_1"/>
|
||||
<bpmn:sequenceFlow id="Flow_2" sourceRef="Task_1" targetRef="EndEvent_1"/>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="173" y="102" width="36" height="36"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="233" y="80" width="100" height="80"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="EndEvent_1_di" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds x="383" y="102" width="36" height="36"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_1_di" bpmnElement="Flow_1">
|
||||
<di:waypoint x="209" y="120"/>
|
||||
<di:waypoint x="233" y="120"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_2_di" bpmnElement="Flow_2">
|
||||
<di:waypoint x="333" y="120"/>
|
||||
<di:waypoint x="383" y="120"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
`
|
||||
bpmnModeler.importXML(xmlContent).then(() => { });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
// setupFileOperations(bpmnModeler);
|
||||
|
||||
} catch (error) {
|
||||
// Error handling
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
// Initialize CodeMirror and SimpleMDE if necessary
|
||||
// ...
|
||||
|
||||
return () => {
|
||||
// Cleanup
|
||||
// Destroy instances or remove event listeners if necessary
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div id="menu">
|
||||
<button id="downloadButton" className="bpmn-js-spiffworkflow-btn"><i className="fa fa-download"></i> Download</button>
|
||||
<button id="uploadButton" className="bpmn-js-spiffworkflow-btn">Open a file</button>
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="modeler" ref={modelerRef}></div>
|
||||
<div id="panel" ref={panelRef}></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
|
@ -0,0 +1,8 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,13 @@
|
|||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
|
@ -0,0 +1,5 @@
|
|||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
|
@ -44,6 +44,7 @@ export default function DataObjectPropertiesProvider(
|
|||
return groups;
|
||||
};
|
||||
};
|
||||
console.log('DataObjectPropertiesProvider', this);
|
||||
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import { assign } from 'min-dash';
|
||||
import translate from 'diagram-js/lib/i18n/translate/translate';
|
||||
|
||||
/**
|
||||
* Add data inputs and data outputs to the panel.
|
||||
*/
|
||||
export default function IoPalette(palette, create, elementFactory,) {
|
||||
this._create = create;
|
||||
this._elementFactory = elementFactory;
|
||||
palette.registerProvider(this);
|
||||
}
|
||||
|
||||
IoPalette.$inject = [
|
||||
'palette',
|
||||
'create',
|
||||
'elementFactory'
|
||||
];
|
||||
|
||||
IoPalette.prototype.getPaletteEntries = function() {
|
||||
|
||||
let input_type = 'bpmn:DataInput';
|
||||
let output_type = 'bpmn:DataOutput';
|
||||
let elementFactory = this._elementFactory, create = this._create;
|
||||
|
||||
function createListener(event, type) {
|
||||
let shape = elementFactory.createShape(assign({ type: type }, {}));
|
||||
shape.width = 36; // Fix up the shape dimensions from the defaults.
|
||||
shape.height = 50;
|
||||
create.start(event, shape);
|
||||
}
|
||||
|
||||
function createInputListener(event) {
|
||||
createListener(event, input_type);
|
||||
}
|
||||
|
||||
function createOutputListener(event) {
|
||||
createListener(event, output_type);
|
||||
}
|
||||
|
||||
return {
|
||||
'create.data-input': {
|
||||
group: 'data-object',
|
||||
className: 'bpmn-icon-data-input',
|
||||
title: translate('Create DataInput'),
|
||||
action: {
|
||||
dragstart: createInputListener,
|
||||
click: createInputListener
|
||||
}
|
||||
},
|
||||
'create.data-output': {
|
||||
group: 'data-object',
|
||||
className: 'bpmn-icon-data-output',
|
||||
title: translate('Create DataOutput'),
|
||||
action: {
|
||||
dragstart: createOutputListener,
|
||||
click: createOutputListener
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
|
@ -36,7 +36,6 @@ export default {
|
|||
'escalationPropertiesProvider',
|
||||
'callActivityPropertiesProvider',
|
||||
'ioPalette',
|
||||
'paletteProvider',
|
||||
'ioRules',
|
||||
'ioInterceptor',
|
||||
'dataObjectRenderer',
|
||||
|
@ -58,7 +57,6 @@ export default {
|
|||
messagesPropertiesProvider: ['type', MessagesPropertiesProvider],
|
||||
callActivityPropertiesProvider: ['type', CallActivityPropertiesProvider],
|
||||
ioPalette: ['type', IoPalette],
|
||||
paletteProvider: ['type', IoPalette],
|
||||
ioRules: ['type', IoRules],
|
||||
ioInterceptor: ['type', IoInterceptor],
|
||||
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"extends": "plugin:bpmn-io/mocha"
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import { bootstrapPropertiesPanel, expectSelected } from './helpers';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import dataStoreInterceptor from '../../app/spiffworkflow/DataStoreReference';
|
||||
|
||||
describe('DataStore Interceptor', () => {
|
||||
|
||||
let xml = require('./bpmn/data_store.bpmn').default;
|
||||
let modeler;
|
||||
|
||||
beforeEach(() => {
|
||||
// Initialize your properties panel and BPMN modeler here
|
||||
// You'll need to adapt bootstrapPropertiesPanel to return the modeler instance
|
||||
modeler = bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
dataStoreInterceptor,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete dataStore in case dataStoreRef is deleted - DataStoreReference element', async () => {
|
||||
// Replace inject function with direct async function
|
||||
|
||||
// Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement).toBeTruthy(); // Jest assertion
|
||||
|
||||
let definitions = modeler.getDefinitions();
|
||||
let dataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||
);
|
||||
expect(dataStoreExists).toBe(true); // Jest assertion
|
||||
|
||||
// Remove dataStoreReference
|
||||
modeler.get('modeling').removeShape(shapeElement);
|
||||
const nwshapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(nwshapeElement).toBeFalsy(); // Jest assertion
|
||||
|
||||
// Check that DataStore countries is removed from the root of the process
|
||||
definitions = modeler.getDefinitions();
|
||||
dataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||
);
|
||||
expect(dataStoreExists).toBe(false); // Jest assertion
|
||||
});
|
||||
|
||||
// Additional tests...
|
||||
});
|
|
@ -1,29 +0,0 @@
|
|||
import {
|
||||
query as domQuery,
|
||||
queryAll as domQueryAll
|
||||
} from 'min-dom';
|
||||
import { bootstrapPropertiesPanel, CONTAINER } from './helpers';
|
||||
import inputOutput from '../../app/spiffworkflow/InputOutput';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
|
||||
describe('BPMN Input / Output', function() {
|
||||
|
||||
let xml = require('./bpmn/diagram.bpmn').default;
|
||||
|
||||
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
inputOutput,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
]
|
||||
}));
|
||||
|
||||
it('should have a data input and data output in the properties panel', function() {
|
||||
var paletteElement = domQuery('.djs-palette', CONTAINER);
|
||||
var entries = domQueryAll('.entry', paletteElement);
|
||||
expect(entries[11].title).to.equals('Create DataInput');
|
||||
expect(entries[12].title).to.equals('Create DataOutput');
|
||||
});
|
||||
|
||||
});
|
|
@ -1,87 +0,0 @@
|
|||
import { getBpmnJS } from 'bpmn-js/test/helper';
|
||||
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findEntry,
|
||||
findSelect,
|
||||
getPropertiesPanel,
|
||||
} from './helpers';
|
||||
import extensions from '../../app/spiffworkflow/extensions';
|
||||
|
||||
describe('Business Rule Properties Panel', function () {
|
||||
const xml = require('./bpmn/diagram.bpmn').default;
|
||||
|
||||
beforeEach(
|
||||
bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
extensions,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
const return_files = (event) => {
|
||||
event.eventBus.fire('spiff.dmn_files.returned', {
|
||||
options: [
|
||||
{ label: 'Calculate Pizza Price', value: 'Decision_Pizza_Price' },
|
||||
{ label: 'Viking Availability', value: 'Decision_Vikings' },
|
||||
{ label: 'Test Decision', value: 'test_decision' },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
it('should display a dropdown to select from available decision tables', async function () {
|
||||
const modeler = getBpmnJS();
|
||||
modeler.get('eventBus').once('spiff.dmn_files.requested', return_files);
|
||||
expectSelected('business_rule_task');
|
||||
// THEN - a properties panel exists with a section for editing that script
|
||||
const entry = findEntry('extension_spiffworkflow:CalledDecisionId', getPropertiesPanel());
|
||||
expect(entry, 'No Entry').to.exist;
|
||||
const selectList = findSelect(entry);
|
||||
expect(selectList, 'No Select').to.exist;
|
||||
});
|
||||
|
||||
it('should update the spiffworkflow:calledDecisionId tag when you modify the called decision select box', async function () {
|
||||
// IF - a script tag is selected, and you change the script in the properties panel
|
||||
const modeler = getBpmnJS();
|
||||
modeler.get('eventBus').once('spiff.dmn_files.requested', return_files);
|
||||
const businessRuleTask = await expectSelected('business_rule_task');
|
||||
const entry = findEntry('extension_CalledDecisionId', getPropertiesPanel());
|
||||
const selectList = findSelect(entry);
|
||||
changeInput(selectList, 'Decision_Pizza_Price');
|
||||
|
||||
// THEN - the script tag in the BPMN Business object / XML is updated as well.
|
||||
const businessObject = getBusinessObject(businessRuleTask);
|
||||
expect(businessObject.extensionElements).to.exist;
|
||||
const element = businessObject.extensionElements.values[0];
|
||||
expect(element.value).to.equal('Decision_Pizza_Price');
|
||||
});
|
||||
|
||||
it('should load up the xml and the value for the called decision should match the xml', async function () {
|
||||
const businessRuleTask = await expectSelected('business_rule_task');
|
||||
const entry = findEntry('extension_CalledDecisionId', getPropertiesPanel());
|
||||
const selectList = findSelect(entry);
|
||||
expect(selectList.value, "initial value is wrong").to.equal('test_decision');
|
||||
|
||||
// THEN - the script tag in the BPMN Business object / XML is updated as well.
|
||||
const businessObject = getBusinessObject(businessRuleTask);
|
||||
expect(businessObject.extensionElements).to.exist;
|
||||
const element = businessObject.extensionElements.values[0];
|
||||
expect(element.value).to.equal('test_decision');
|
||||
});
|
||||
|
||||
});
|
|
@ -1,112 +0,0 @@
|
|||
import TestContainer from 'mocha-test-container-support';
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import { query as domQuery } from 'min-dom';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { inject } from 'bpmn-js/test/helper';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findButton,
|
||||
findGroupEntry,
|
||||
pressButton,
|
||||
} from './helpers';
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import callActivity from '../../app/spiffworkflow/callActivity';
|
||||
|
||||
describe('Call Activities should work', function () {
|
||||
const xml = require('./bpmn/call_activity.bpmn').default;
|
||||
let container;
|
||||
|
||||
beforeEach(function () {
|
||||
container = TestContainer.get(this);
|
||||
});
|
||||
|
||||
beforeEach(
|
||||
bootstrapPropertiesPanel(xml, {
|
||||
container,
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
callActivity,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
it('should allow you to view the called element section of a Call Activity', async function () {
|
||||
const shapeElement = await expectSelected('the_call_activity');
|
||||
expect(shapeElement, "Can't find Call Activity").to.exist;
|
||||
const entry = findGroupEntry('called_element', container);
|
||||
expect(entry).to.exist;
|
||||
});
|
||||
|
||||
it('should allow you to edit the called element section of a Call Activity', async function () {
|
||||
const shapeElement = await expectSelected('the_call_activity');
|
||||
expect(shapeElement, "Can't find Call Activity").to.exist;
|
||||
const businessObject = getBusinessObject(shapeElement);
|
||||
expect(businessObject.get('calledElement')).to.equal('ProcessIdTBD1');
|
||||
|
||||
const entry = findGroupEntry('called_element', container);
|
||||
expect(entry).to.exist;
|
||||
|
||||
const textInput = domQuery('input', entry);
|
||||
changeInput(textInput, 'newProcessId');
|
||||
expect(businessObject.get('calledElement')).to.equal('newProcessId');
|
||||
});
|
||||
|
||||
it('should issue an event to the event bus if user clicks the edit button', inject(async function (
|
||||
eventBus
|
||||
) {
|
||||
const shapeElement = await expectSelected('the_call_activity');
|
||||
expect(shapeElement, "Can't find Call Activity").to.exist;
|
||||
const businessObject = getBusinessObject(shapeElement);
|
||||
expect(businessObject.get('calledElement')).to.equal('ProcessIdTBD1');
|
||||
|
||||
const entry = findGroupEntry('called_element', container);
|
||||
const button = findButton('spiffworkflow-open-call-activity-button', entry);
|
||||
expect(button).to.exist;
|
||||
|
||||
let launchEvent;
|
||||
eventBus.on('spiff.callactivity.edit', function (event) {
|
||||
launchEvent = event;
|
||||
});
|
||||
await pressButton(button);
|
||||
expect(launchEvent.processId).to.exist;
|
||||
}));
|
||||
|
||||
it('should issue an event to the event bus if user clicks the search button', inject(async function (
|
||||
eventBus
|
||||
) {
|
||||
const shapeElement = await expectSelected('the_call_activity');
|
||||
expect(shapeElement, "Can't find Call Activity").to.exist;
|
||||
const businessObject = getBusinessObject(shapeElement);
|
||||
expect(businessObject.get('calledElement')).to.equal('ProcessIdTBD1');
|
||||
|
||||
const entry = findGroupEntry('called_element', container);
|
||||
const button = findButton(
|
||||
'spiffworkflow-search-call-activity-button',
|
||||
entry
|
||||
);
|
||||
expect(button).to.exist;
|
||||
|
||||
let launchEvent;
|
||||
eventBus.on('spiff.callactivity.search', function (event) {
|
||||
launchEvent = event;
|
||||
});
|
||||
await pressButton(button);
|
||||
expect(launchEvent.processId).to.exist;
|
||||
expect(launchEvent.element).to.exist;
|
||||
|
||||
eventBus.fire('spiff.callactivity.update', {value: 'searchedProcessId', element: launchEvent.element});
|
||||
const textInput = domQuery('input', entry);
|
||||
expect(businessObject.get('calledElement')).to.equal('searchedProcessId');
|
||||
|
||||
}));
|
||||
});
|
|
@ -1,40 +0,0 @@
|
|||
import {
|
||||
query as domQuery,
|
||||
queryAll as domQueryAll
|
||||
} from 'min-dom';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
expectSelected,
|
||||
findGroupEntry,
|
||||
changeInput,
|
||||
PROPERTIES_PANEL_CONTAINER,
|
||||
} from './helpers';
|
||||
import conditionsPanel from '../../app/spiffworkflow/conditions';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
|
||||
describe('BPMN Condition', function() {
|
||||
|
||||
let xml = require('./bpmn/conditional_event.bpmn').default;
|
||||
|
||||
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
conditionsPanel,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
]
|
||||
}));
|
||||
|
||||
it('should add a condition panel when Conditional Event is selected', async function() {
|
||||
const shapeElement = await expectSelected('conditional_event');
|
||||
const businessObject = getBusinessObject(shapeElement);
|
||||
const conditions = findGroupEntry('conditions', PROPERTIES_PANEL_CONTAINER);
|
||||
expect(conditions).to.exist;
|
||||
|
||||
const textInput = domQuery('textarea', conditions);
|
||||
expect(textInput.value).to.equal('cancel_task_2');
|
||||
changeInput(textInput, 'True');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import TestContainer from 'mocha-test-container-support';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findEntry,
|
||||
findSelect,
|
||||
} from './helpers';
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import DataObject from '../../app/spiffworkflow/DataObject';
|
||||
|
||||
describe('Properties Panel for Data Objects', function () {
|
||||
const xml = require('./bpmn/data_objects_in_pools.bpmn').default;
|
||||
let container;
|
||||
|
||||
beforeEach(function () {
|
||||
container = TestContainer.get(this);
|
||||
});
|
||||
|
||||
beforeEach(
|
||||
bootstrapPropertiesPanel(xml, {
|
||||
container,
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
DataObject,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
it('should allow you to select other data objects within the same participant', async function () {
|
||||
// IF - a data object reference is selected
|
||||
const doREF = await expectSelected('pool1Do1_REF');
|
||||
expect(doREF).to.exist;
|
||||
|
||||
// THEN - a select Data Object section should appear in the properties panel
|
||||
const entry = findEntry('selectDataObject', container);
|
||||
const selector = findSelect(entry);
|
||||
changeInput(selector, 'pool1Do2');
|
||||
// then this data reference object now references that data object.
|
||||
const { businessObject } = doREF;
|
||||
expect(businessObject.get('dataObjectRef').id).to.equal('pool1Do2');
|
||||
});
|
||||
|
||||
it('should NOT allow you to select data objects within other participants', async function () {
|
||||
// IF - a data object reference is selected
|
||||
const doREF = await expectSelected('pool1Do1_REF');
|
||||
expect(doREF).to.exist;
|
||||
|
||||
// THEN - a select Data Object section should appear in the properties panel but pool2Do1 should not be an option
|
||||
const entry = findEntry('selectDataObject', container);
|
||||
const selector = findSelect(entry);
|
||||
expect(selector.length).to.equal(2);
|
||||
expect(selector[0].value === 'pool1Do2');
|
||||
expect(selector[1].value === 'pool1Do1');
|
||||
});
|
||||
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue