make main look like bd16223ccf
This commit is contained in:
parent
52f2a9bd98
commit
2bb11c33bb
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Sartography
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -96,3 +96,10 @@ Below is a table of all the events that are sent and accepted:
|
||||||
| spff.dmn\_files.requested | request of list of local dmn files. | | | |
|
| 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'}\] |
|
| 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'}\] |
|
| spff.dmn\_files.returned | Return a list of available dmn files. | Recieved | options | \[{lable:'My Label', value:'1'}\] |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
MIT
|
||||||
|
|
18
app/app.js
18
app/app.js
|
@ -23,13 +23,6 @@ try {
|
||||||
keyboard: { bindTo: document },
|
keyboard: { bindTo: document },
|
||||||
propertiesPanel: {
|
propertiesPanel: {
|
||||||
parent: panelEl,
|
parent: panelEl,
|
||||||
layout: {
|
|
||||||
groups: {
|
|
||||||
general: {
|
|
||||||
open: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
additionalModules: [
|
additionalModules: [
|
||||||
spiffworkflow,
|
spiffworkflow,
|
||||||
|
@ -189,8 +182,8 @@ bpmnModeler.on('spiff.dmn_files.requested', (event) => {
|
||||||
bpmnModeler.on('spiff.data_stores.requested', (event) => {
|
bpmnModeler.on('spiff.data_stores.requested', (event) => {
|
||||||
event.eventBus.fire('spiff.data_stores.returned', {
|
event.eventBus.fire('spiff.data_stores.returned', {
|
||||||
options: [
|
options: [
|
||||||
{ id: 'countriesID', type: 'json', name: 'countries', clz: 'JSONDataStore' },
|
{ type: 'typeahead', name: 'countries' },
|
||||||
{ id: 'foodsID', type: 'kkv', name: 'foods', clz: 'JSONDataStore' }
|
{ type: 'kkv', name: 'foods' }
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -213,7 +206,7 @@ bpmnModeler.on('import.parse.complete', event => {
|
||||||
refs.forEach(ref => {
|
refs.forEach(ref => {
|
||||||
const props = {
|
const props = {
|
||||||
id: ref.id,
|
id: ref.id,
|
||||||
name: ref.id ? typeof (ref.name) === 'undefined' : ref.name,
|
name: ref.id ? typeof(ref.name) === 'undefined': ref.name,
|
||||||
};
|
};
|
||||||
let elem = bpmnModeler._moddle.create(desc, props);
|
let elem = bpmnModeler._moddle.create(desc, props);
|
||||||
elem.$parent = ref.element;
|
elem.$parent = ref.element;
|
||||||
|
@ -221,10 +214,7 @@ bpmnModeler.on('import.parse.complete', event => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
bpmnModeler.importXML(diagramXML).then(() => {
|
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
|
// 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
|
// the BPMN modeler or these extensions, just a quick way to allow you to
|
||||||
|
|
347
app/css/app.css
347
app/css/app.css
|
@ -1,8 +1,6 @@
|
||||||
html,
|
|
||||||
body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
|
@ -11,7 +9,8 @@ body {
|
||||||
|
|
||||||
#container {
|
#container {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: calc(100% - 80px);
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#modeler {
|
#modeler {
|
||||||
|
@ -19,14 +18,16 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#panel {
|
#panel {
|
||||||
background-color: white;
|
background-color: #fafafa;
|
||||||
border-left: 1px solid #5F5F5F;
|
border: solid 1px #ccc;
|
||||||
/* background-color: #fafafa; */
|
border-radius: 2px;
|
||||||
/* border: solid 1px #ccc; */
|
font-family: 'Arial', sans-serif;
|
||||||
/* border-radius: 2px; */
|
padding: 10px;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.djs-label {
|
||||||
font-family: 'Arial', sans-serif;
|
font-family: 'Arial', sans-serif;
|
||||||
/* padding: 10px; */
|
|
||||||
min-width: 350px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.spiffworkflow-properties-panel-button {
|
.spiffworkflow-properties-panel-button {
|
||||||
|
@ -37,342 +38,46 @@ body {
|
||||||
|
|
||||||
/* Style buttons */
|
/* Style buttons */
|
||||||
.bpmn-js-spiffworkflow-btn {
|
.bpmn-js-spiffworkflow-btn {
|
||||||
background-color: #ffffff;
|
background-color: DodgerBlue;
|
||||||
color: #393939;
|
border: none;
|
||||||
border: 1px solid #393939;
|
|
||||||
padding: 8px 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
margin: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-btn {
|
|
||||||
background-color: #0F62FE;
|
|
||||||
color: white;
|
color: white;
|
||||||
border: 1px solid #0F62FE;
|
|
||||||
padding: 8px 15px;
|
padding: 8px 15px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-btn i {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Darker background on mouse-over */
|
/* Darker background on mouse-over */
|
||||||
.bpmn-js-spiffworkflow-btn:hover {
|
.bpmn-js-spiffworkflow-btn:hover {
|
||||||
background-color: rgb(0, 0, 0);
|
background-color: RoyalBlue;
|
||||||
border: 1px solid #000000;
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code Editor -- provided as a div overlay */
|
/* Code Editor -- provided as a div overlay */
|
||||||
.overlay {
|
.overlay {
|
||||||
position: fixed;
|
position: fixed; /* Sit on top of the page content */
|
||||||
/* Sit on top of the page content */
|
display: none; /* Hidden by default */
|
||||||
display: none;
|
width: 100%; /* Full width (cover the whole page) */
|
||||||
/* Hidden by default */
|
height: 100%; /* Full height (cover the whole page) */
|
||||||
width: 100%;
|
|
||||||
/* Full width (cover the whole page) */
|
|
||||||
height: 100%;
|
|
||||||
/* Full height (cover the whole page) */
|
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
|
||||||
/* Black background with opacity */
|
z-index: 200; /* BPMN Canvas has some huge z-indexes, pop-up tools are 100 for ex.*/
|
||||||
z-index: 200;
|
|
||||||
/* BPMN Canvas has some huge z-indexes, pop-up tools are 100 for ex.*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#code_editor,
|
#code_editor, #markdown_editor {
|
||||||
#markdown_editor {
|
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
margin: 50px auto 10px auto;
|
margin: 50px auto 10px auto;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#code_buttons,
|
#code_buttons, #markdown_buttons {
|
||||||
#markdown_buttons {
|
|
||||||
margin: 50px auto 10px auto;
|
margin: 50px auto 10px auto;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header */
|
.djs-palette.two-column.open {
|
||||||
#header {
|
width: 95px;
|
||||||
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: 18px;
|
|
||||||
color: #333;
|
|
||||||
/* margin-bottom: 5px; */
|
|
||||||
padding: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.group-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-block: 5px;
|
|
||||||
padding-inline: 10px;
|
|
||||||
/* background: #f8f8f8; */
|
|
||||||
/* background: #f5f5f58c; */
|
|
||||||
/* border-bottom: 1px solid #ddd; */
|
|
||||||
/* cursor: pointer; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-title span {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group.collapsed .entry {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-toggle {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry-label {
|
|
||||||
color: #22242A;
|
|
||||||
text-align: center;
|
|
||||||
font-family: unset;
|
|
||||||
font-size: 12px;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.property-tabs {
|
|
||||||
display: -webkit-box;
|
|
||||||
width: 100%;
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border-right: unset;
|
|
||||||
justify-content: space-between;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.property-tabs li {
|
|
||||||
padding: 10px 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
border-bottom: 2px solid grey;
|
|
||||||
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.property-tabs li.active {
|
|
||||||
border-bottom: 2px solid blue;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs-group .tab-content {
|
|
||||||
width: 100%;
|
|
||||||
border: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BPMN JS CSS */
|
|
||||||
/* Override default palette styles */
|
|
||||||
|
|
||||||
.bjs-container .djs-palette {
|
|
||||||
width: 100% !important;
|
|
||||||
height: 90%;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bjs-container .djs-palette.two-column.open {
|
|
||||||
width: 230px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bjs-container .djs-palette-entries {
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.djs-palette .entry,
|
|
||||||
.djs-palette .djs-palette-toggle {
|
|
||||||
justify-items: center;
|
|
||||||
height: unset;
|
|
||||||
width: unset;
|
|
||||||
line-height: unset;
|
|
||||||
display: inline-grid;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bio-properties-panel-header {
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
}
|
|
||||||
|
|
||||||
.djs-label {
|
|
||||||
font-family: 'Arial', sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
BIN
app/favicon.png
BIN
app/favicon.png
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB |
|
@ -32,28 +32,6 @@ export default function setupFileOperations(bpmnModeler) {
|
||||||
uploadBtn.addEventListener('click', (_event) => {
|
uploadBtn.addEventListener('click', (_event) => {
|
||||||
openFile(bpmnModeler);
|
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) {
|
function clickElem(elem) {
|
||||||
|
@ -99,88 +77,3 @@ export function openFile(bpmnModeler) {
|
||||||
document.body.appendChild(fileInput);
|
document.body.appendChild(fileInput);
|
||||||
clickElem(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);
|
|
||||||
}
|
|
||||||
}
|
|
199
app/index.html
199
app/index.html
|
@ -1,19 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<!--
|
||||||
|
IMPORTANT:
|
||||||
|
This is here to provide an exmaple of how you might use this library in your application.
|
||||||
|
You should be able to take this example, and modify it to suite your own needs.
|
||||||
|
-->
|
||||||
<title>bpmn-js-spiffworkflow</title>
|
<title>bpmn-js-spiffworkflow</title>
|
||||||
<meta charset="utf-8" />
|
|
||||||
|
|
||||||
|
<meta charset="utf-8"/>
|
||||||
<!-- here are the core dependencies you will need to include -->
|
<!-- 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/diagram-js.css"/>
|
||||||
<link rel="stylesheet" href="vendor/bpmn-js/assets/bpmn-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/assets/bpmn-font/css/bpmn-embedded.css"/>
|
||||||
<link rel="stylesheet" href="vendor/bpmn-js-properties-panel/assets/properties-panel.css" />
|
<link rel="stylesheet" href="vendor/bpmn-js-properties-panel/assets/properties-panel.css"/>
|
||||||
|
|
||||||
<!-- Some local css settings -->
|
<!-- Some local css settings -->
|
||||||
<link rel="stylesheet" href="css/app.css" />
|
<link rel="stylesheet" href="css/app.css"/>
|
||||||
<!-- <link rel="stylesheet" href="css/bpmn-js.css" /> -->
|
|
||||||
<link rel="shortcut icon" href="#">
|
<link rel="shortcut icon" href="#">
|
||||||
|
|
||||||
<!-- A python code editor, we are using CodeMirror here -- see app.js for how this is wired in -->
|
<!-- A python code editor, we are using CodeMirror here -- see app.js for how this is wired in -->
|
||||||
|
@ -29,163 +32,33 @@
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<style>
|
|
||||||
.djs-palette {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
width: 100% !important;
|
|
||||||
height: 90%;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.djs-palette.two-column.open {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="header">
|
<div id="menu">
|
||||||
<div id="process-info">
|
<button id="downloadButton" class="bpmn-js-spiffworkflow-btn"><i class="fa fa-download"></i> Download</button>
|
||||||
<h1>Process Name</h1>
|
<button id="uploadButton" class="bpmn-js-spiffworkflow-btn">Open a file</button>
|
||||||
<p>. / Process Groups / bpmn_process.bpmn </p>
|
</div>
|
||||||
</div>
|
<div id="container">
|
||||||
<div id="header-actions-center">
|
<div id="modeler"></div>
|
||||||
<button class="header-btn" title="Hand" data-action="hand">
|
<div id="panel"></div>
|
||||||
<i class="bpmn-icon-hand-tool"></i>
|
</div>
|
||||||
</button>
|
<!-- the following are overlays to provide editors for Python and Markdown -->
|
||||||
<button class="header-btn" title="LassoTool" data-action="lasso">
|
<div id="code_overlay" class="overlay">
|
||||||
<i class="bpmn-icon-lasso-tool"></i>
|
<div id="code_editor"></div>
|
||||||
</button>
|
<div id="code_buttons">
|
||||||
<button class="header-btn" title="SpaceTool" data-action="space">
|
<button id="saveCode" class="bpmn-js-spiffworkflow-btn">Save</button>
|
||||||
<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>
|
||||||
<div id="left-sidebar">
|
</div>
|
||||||
<div class="tabs">
|
<div id="markdown_overlay" class="overlay">
|
||||||
<button class="tab-button active" data-tab-target="BPMNElements">
|
<div id="markdown_editor">
|
||||||
<i class="fa fa-th-large"></i>
|
<textarea id="markdown_textarea"></textarea>
|
||||||
</button>
|
</div>
|
||||||
<button class="tab-button" data-tab-target="SearchTab">
|
<div id="markdown_buttons">
|
||||||
<i class="fa fa-search"></i>
|
<button id="saveMarkdown" class="bpmn-js-spiffworkflow-btn">Save</button>
|
||||||
</button>
|
</div>
|
||||||
<button class="tab-button" data-tab-target="ActionTab">
|
</div>
|
||||||
<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">
|
<!-- Here we load up our application, it's where the configuration happens. -->
|
||||||
<div class="bpmn-elements-header">
|
<script src="app.js"></script>
|
||||||
<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>
|
</body>
|
||||||
|
</html><!---->
|
||||||
</html>
|
|
||||||
|
|
|
@ -68,7 +68,6 @@ function createDataObjectSelector(element, translate, moddle, commandStack, mode
|
||||||
return {
|
return {
|
||||||
id: 'data_object_properties',
|
id: 'data_object_properties',
|
||||||
label: translate('Data Object Properties'),
|
label: translate('Data Object Properties'),
|
||||||
isDefault: true,
|
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
id: 'selectDataObject',
|
id: 'selectDataObject',
|
||||||
|
|
|
@ -51,7 +51,6 @@ function createCustomDataStoreGroup(
|
||||||
const group = {
|
const group = {
|
||||||
label: translate('Custom Data Store Properties'),
|
label: translate('Custom Data Store Properties'),
|
||||||
id: 'custom-datastore-properties',
|
id: 'custom-datastore-properties',
|
||||||
isDefault: true,
|
|
||||||
entries: [],
|
entries: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,19 +21,13 @@ export function DataStoreSelect(props) {
|
||||||
const bpmnFactory = useService('bpmnFactory');
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
const getValue = () => {
|
const getValue = () => {
|
||||||
const dtRef = element.businessObject.dataStoreRef;
|
return element.businessObject.dataStoreRef
|
||||||
return dtRef
|
? element.businessObject.dataStoreRef.id
|
||||||
? `${dtRef.id}___${dtRef.name}`
|
|
||||||
: '';
|
: '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const setValue = (value) => {
|
const setValue = (value) => {
|
||||||
|
if (!value || value == '') {
|
||||||
const splitValue = value.split('___');
|
|
||||||
const valId = splitValue[0]
|
|
||||||
const valClz = splitValue[1]
|
|
||||||
|
|
||||||
if (!valId || valId == '') {
|
|
||||||
modeling.updateProperties(element, {
|
modeling.updateProperties(element, {
|
||||||
dataStoreRef: null,
|
dataStoreRef: null,
|
||||||
});
|
});
|
||||||
|
@ -52,20 +46,19 @@ export function DataStoreSelect(props) {
|
||||||
|
|
||||||
// Create DataStore
|
// Create DataStore
|
||||||
let dataStore = definitions.get('rootElements').find(element =>
|
let dataStore = definitions.get('rootElements').find(element =>
|
||||||
element.$type === 'bpmn:DataStore' && element.id === valId
|
element.$type === 'bpmn:DataStore' && element.id === value
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the DataStore doesn't exist, create new one
|
// If the DataStore doesn't exist, create new one
|
||||||
if (!dataStore) {
|
if (!dataStore) {
|
||||||
dataStore = bpmnFactory.create('bpmn:DataStore', {
|
dataStore = bpmnFactory.create('bpmn:DataStore', {
|
||||||
id: valId,
|
id: value,
|
||||||
name: valClz
|
name: 'DataStore_' + value
|
||||||
});
|
});
|
||||||
definitions.get('rootElements').push(dataStore);
|
definitions.get('rootElements').push(dataStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
modeling.updateProperties(element, {
|
modeling.updateProperties(element, {
|
||||||
name: `Data Store (${valId})`,
|
|
||||||
dataStoreRef: dataStore,
|
dataStoreRef: dataStore,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -96,7 +89,7 @@ export function DataStoreSelect(props) {
|
||||||
spiffExtensionOptions[optionType].forEach((opt) => {
|
spiffExtensionOptions[optionType].forEach((opt) => {
|
||||||
optionList.push({
|
optionList.push({
|
||||||
label: opt.name,
|
label: opt.name,
|
||||||
value: `${opt.id}___${opt.clz}`,
|
value: opt.name,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,34 +4,19 @@ import translate from 'diagram-js/lib/i18n/translate/translate';
|
||||||
/**
|
/**
|
||||||
* Add data inputs and data outputs to the panel.
|
* Add data inputs and data outputs to the panel.
|
||||||
*/
|
*/
|
||||||
export default function IoPalette(palette, create, elementFactory, eventBus, handTool, globalConnect, lassoTool, spaceTool) {
|
export default function IoPalette(palette, create, elementFactory,) {
|
||||||
this._create = create;
|
this._create = create;
|
||||||
this._elementFactory = elementFactory;
|
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);
|
palette.registerProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IoPalette.$inject = [
|
IoPalette.$inject = [
|
||||||
'palette',
|
'palette',
|
||||||
'create',
|
'create',
|
||||||
'elementFactory',
|
'elementFactory'
|
||||||
'eventBus',
|
|
||||||
'handTool',
|
|
||||||
'globalConnect',
|
|
||||||
'lassoTool',
|
|
||||||
'spaceTool'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
IoPalette.prototype.getPaletteEntries = function (e) {
|
IoPalette.prototype.getPaletteEntries = function() {
|
||||||
|
|
||||||
let input_type = 'bpmn:DataInput';
|
let input_type = 'bpmn:DataInput';
|
||||||
let output_type = 'bpmn:DataOutput';
|
let output_type = 'bpmn:DataOutput';
|
||||||
|
@ -39,7 +24,7 @@ IoPalette.prototype.getPaletteEntries = function (e) {
|
||||||
|
|
||||||
function createListener(event, type) {
|
function createListener(event, type) {
|
||||||
let shape = elementFactory.createShape(assign({ type: type }, {}));
|
let shape = elementFactory.createShape(assign({ type: type }, {}));
|
||||||
shape.width = 36;
|
shape.width = 36; // Fix up the shape dimensions from the defaults.
|
||||||
shape.height = 50;
|
shape.height = 50;
|
||||||
create.start(event, shape);
|
create.start(event, shape);
|
||||||
}
|
}
|
||||||
|
@ -52,268 +37,26 @@ IoPalette.prototype.getPaletteEntries = function (e) {
|
||||||
createListener(event, output_type);
|
createListener(event, output_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createShape(type, options = {}) {
|
|
||||||
return function (event) {
|
|
||||||
let shape = elementFactory.createShape(assign({ type: type }, options));
|
|
||||||
create.start(event, shape);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
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')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 'create.dmn-task': {
|
|
||||||
// group: 'activities',
|
|
||||||
// className: 'bpmn-icon-business-rule',
|
|
||||||
// title: translate('Business Rule Task'),
|
|
||||||
// action: {
|
|
||||||
// dragstart: createShape('bpmn:BusinessRuleTask'),
|
|
||||||
// click: createShape('bpmn:BusinessRuleTask')
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// 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: 'data',
|
|
||||||
className: 'bpmn-icon-data-store',
|
|
||||||
title: translate('Data Store'),
|
|
||||||
action: {
|
|
||||||
dragstart: createShape('bpmn:DataStoreReference'),
|
|
||||||
click: createShape('bpmn:DataStoreReference')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'create.data-object': {
|
|
||||||
group: 'data',
|
|
||||||
className: 'bpmn-icon-data-object',
|
|
||||||
title: translate('Data Object'),
|
|
||||||
action: {
|
|
||||||
dragstart: createShape('bpmn:DataObjectReference'),
|
|
||||||
click: createShape('bpmn:DataObjectReference')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'create.data-input': {
|
'create.data-input': {
|
||||||
group: 'data',
|
group: 'data-object',
|
||||||
className: 'bpmn-icon-data-input',
|
className: 'bpmn-icon-data-input',
|
||||||
title: translate('Data Input'),
|
title: translate('Create DataInput'),
|
||||||
action: {
|
action: {
|
||||||
dragstart: createInputListener,
|
dragstart: createInputListener,
|
||||||
click: createInputListener
|
click: createInputListener
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'create.data-output': {
|
'create.data-output': {
|
||||||
group: 'data',
|
group: 'data-object',
|
||||||
className: 'bpmn-icon-data-output',
|
className: 'bpmn-icon-data-output',
|
||||||
title: translate('Data Output'),
|
title: translate('Create DataOutput'),
|
||||||
action: {
|
action: {
|
||||||
dragstart: createOutputListener,
|
dragstart: createOutputListener,
|
||||||
click: createOutputListener
|
click: createOutputListener
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
// Advanced
|
|
||||||
'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('Sub Process'),
|
|
||||||
action: {
|
|
||||||
dragstart: createShape('bpmn:SubProcess', { isExpanded: true }),
|
|
||||||
click: createShape('bpmn:SubProcess', { isExpanded: true })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'create.transaction': {
|
|
||||||
group: 'advanced',
|
|
||||||
className: 'bpmn-icon-transaction',
|
|
||||||
title: translate('Transaction'),
|
|
||||||
action: {
|
|
||||||
dragstart: createShape('bpmn:Transaction', { isExpanded: true }),
|
|
||||||
click: createShape('bpmn:Transaction', { 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 ? bpmnElementsDiv.appendChild(paletteContainer): null;
|
|
||||||
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
};
|
|
|
@ -36,7 +36,6 @@ function createCalledElementGroup(element, translate, moddle, commandStack) {
|
||||||
return {
|
return {
|
||||||
id: 'called_element',
|
id: 'called_element',
|
||||||
label: translate('Called Element'),
|
label: translate('Called Element'),
|
||||||
isDefault: true,
|
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
id: `called_element_text_field`,
|
id: `called_element_text_field`,
|
||||||
|
|
|
@ -48,8 +48,6 @@ function createConditionsGroup(element, translate, moddle, commandStack) {
|
||||||
return {
|
return {
|
||||||
id: 'conditions',
|
id: 'conditions',
|
||||||
label: translate('Conditions'),
|
label: translate('Conditions'),
|
||||||
// is default property is mainly used to mark this group as a high priority group that located in General Tab
|
|
||||||
isDefault: true,
|
|
||||||
entries: conditionGroup(
|
entries: conditionGroup(
|
||||||
element,
|
element,
|
||||||
moddle,
|
moddle,
|
||||||
|
|
|
@ -87,7 +87,6 @@ function getConfigureGroupForType(eventDetails, label, includeCode, getSelect) {
|
||||||
return {
|
return {
|
||||||
id: `${idPrefix}-group`,
|
id: `${idPrefix}-group`,
|
||||||
label: label,
|
label: label,
|
||||||
isDefault: true,
|
|
||||||
entries,
|
entries,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ export function setExtensionValue(element, name, value, moddle, commandStack, bu
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExtension(businessObject, name) {
|
function getExtension(businessObject, name) {
|
||||||
if (!businessObject.extensionElements) {
|
if (!businessObject || !businessObject.extensionElements) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const extensionElements = businessObject.extensionElements.get('values');
|
const extensionElements = businessObject.extensionElements.get('values');
|
||||||
|
|
|
@ -9,14 +9,14 @@ import {
|
||||||
ServiceTaskParameterArray,
|
ServiceTaskParameterArray,
|
||||||
ServiceTaskOperatorSelect, ServiceTaskResultTextInput,
|
ServiceTaskOperatorSelect, ServiceTaskResultTextInput,
|
||||||
} from './SpiffExtensionServiceProperties';
|
} from './SpiffExtensionServiceProperties';
|
||||||
import { OPTION_TYPE, spiffExtensionOptions, SpiffExtensionSelect } from './SpiffExtensionSelect';
|
import {OPTION_TYPE, spiffExtensionOptions, SpiffExtensionSelect} from './SpiffExtensionSelect';
|
||||||
import { SpiffExtensionLaunchButton } from './SpiffExtensionLaunchButton';
|
import {SpiffExtensionLaunchButton} from './SpiffExtensionLaunchButton';
|
||||||
import { SpiffExtensionTextArea } from './SpiffExtensionTextArea';
|
import {SpiffExtensionTextArea} from './SpiffExtensionTextArea';
|
||||||
import { SpiffExtensionTextInput } from './SpiffExtensionTextInput';
|
import {SpiffExtensionTextInput} from './SpiffExtensionTextInput';
|
||||||
import { SpiffExtensionCheckboxEntry } from './SpiffExtensionCheckboxEntry';
|
import {SpiffExtensionCheckboxEntry} from './SpiffExtensionCheckboxEntry';
|
||||||
import { hasEventDefinition } from 'bpmn-js/lib/util/DiUtil';
|
import {hasEventDefinition} from 'bpmn-js/lib/util/DiUtil';
|
||||||
import { PropertyDescription } from 'bpmn-js-properties-panel/';
|
import { PropertyDescription } from 'bpmn-js-properties-panel/';
|
||||||
import { setExtensionValue } from "../extensionHelpers";
|
import {setExtensionValue} from "../extensionHelpers";
|
||||||
|
|
||||||
const LOW_PRIORITY = 500;
|
const LOW_PRIORITY = 500;
|
||||||
|
|
||||||
|
@ -112,8 +112,6 @@ function createScriptGroup(element, translate, moddle, commandStack) {
|
||||||
return {
|
return {
|
||||||
id: 'spiff_script',
|
id: 'spiff_script',
|
||||||
label: translate('Script'),
|
label: translate('Script'),
|
||||||
// is default property is mainly used to mark this group as a high priority group that located in General Tab
|
|
||||||
isDefault: true,
|
|
||||||
entries: scriptGroup({
|
entries: scriptGroup({
|
||||||
element,
|
element,
|
||||||
moddle,
|
moddle,
|
||||||
|
@ -156,7 +154,7 @@ function preScriptPostScriptGroup(element, translate, moddle, commandStack) {
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
const loopCharacteristics = element.businessObject.loopCharacteristics;
|
const loopCharacteristics = element.businessObject.loopCharacteristics;
|
||||||
if (typeof (loopCharacteristics) !== 'undefined') {
|
if (typeof(loopCharacteristics) !== 'undefined') {
|
||||||
entries.push({
|
entries.push({
|
||||||
id: 'scriptValence',
|
id: 'scriptValence',
|
||||||
component: ScriptValenceCheckbox,
|
component: ScriptValenceCheckbox,
|
||||||
|
@ -213,14 +211,13 @@ function createUserGroup(element, translate, moddle, commandStack) {
|
||||||
setExtensionValue(element, 'formUiSchemaFilename', uiName, moddle, commandStack);
|
setExtensionValue(element, 'formUiSchemaFilename', uiName, moddle, commandStack);
|
||||||
const matches = spiffExtensionOptions[OPTION_TYPE.json_schema_files].filter((opt) => opt.value === value);
|
const matches = spiffExtensionOptions[OPTION_TYPE.json_schema_files].filter((opt) => opt.value === value);
|
||||||
if (matches.length === 0) {
|
if (matches.length === 0) {
|
||||||
spiffExtensionOptions[OPTION_TYPE.json_schema_files].push({ label: value, value: value });
|
spiffExtensionOptions[OPTION_TYPE.json_schema_files].push({label: value, value: value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: 'user_task_properties',
|
id: 'user_task_properties',
|
||||||
label: translate('Web Form (with Json Schemas)'),
|
label: translate('Web Form (with Json Schemas)'),
|
||||||
isDefault: true,
|
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
element,
|
element,
|
||||||
|
@ -291,7 +288,7 @@ function createBusinessRuleGroup(element, translate, moddle, commandStack) {
|
||||||
* @param moddle
|
* @param moddle
|
||||||
* @returns entries
|
* @returns entries
|
||||||
*/
|
*/
|
||||||
function createUserInstructionsGroup(
|
function createUserInstructionsGroup (
|
||||||
element,
|
element,
|
||||||
translate,
|
translate,
|
||||||
moddle,
|
moddle,
|
||||||
|
@ -332,7 +329,7 @@ function createUserInstructionsGroup(
|
||||||
* @param moddle
|
* @param moddle
|
||||||
* @returns entries
|
* @returns entries
|
||||||
*/
|
*/
|
||||||
function createAllowGuestGroup(
|
function createAllowGuestGroup (
|
||||||
element,
|
element,
|
||||||
translate,
|
translate,
|
||||||
moddle,
|
moddle,
|
||||||
|
@ -382,14 +379,14 @@ function createAllowGuestGroup(
|
||||||
* @param moddle
|
* @param moddle
|
||||||
* @returns entries
|
* @returns entries
|
||||||
*/
|
*/
|
||||||
function createSignalButtonGroup(
|
function createSignalButtonGroup (
|
||||||
element,
|
element,
|
||||||
translate,
|
translate,
|
||||||
moddle,
|
moddle,
|
||||||
commandStack
|
commandStack
|
||||||
) {
|
) {
|
||||||
let description =
|
let description =
|
||||||
<p style={{ maxWidth: "330px" }}> If attached to a user/manual task, setting this value will display a button which a user can click to immediately fire this signal event.
|
<p style={{maxWidth : "330px"}}> If attached to a user/manual task, setting this value will display a button which a user can click to immediately fire this signal event.
|
||||||
</p>
|
</p>
|
||||||
return {
|
return {
|
||||||
id: 'signal_button',
|
id: 'signal_button',
|
||||||
|
@ -420,7 +417,6 @@ function createServiceGroup(element, translate, moddle, commandStack) {
|
||||||
return {
|
return {
|
||||||
id: 'service_task_properties',
|
id: 'service_task_properties',
|
||||||
label: translate('Spiffworkflow Service Properties'),
|
label: translate('Spiffworkflow Service Properties'),
|
||||||
isDefault: true,
|
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
element,
|
element,
|
||||||
|
|
|
@ -18,7 +18,6 @@ import EscalationPropertiesProvider from './escalations/propertiesPanel/Escalati
|
||||||
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
||||||
import StandardLoopPropertiesProvider from './loops/propertiesPanel/StandardLoopPropertiesProvider';
|
import StandardLoopPropertiesProvider from './loops/propertiesPanel/StandardLoopPropertiesProvider';
|
||||||
import MultiInstancePropertiesProvider from './loops/propertiesPanel/MultiInstancePropertiesProvider';
|
import MultiInstancePropertiesProvider from './loops/propertiesPanel/MultiInstancePropertiesProvider';
|
||||||
import PropertiesPanelProvider from './properties/PropertiesPanelProvider';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
__depends__: [RulesModule],
|
__depends__: [RulesModule],
|
||||||
|
@ -37,8 +36,6 @@ export default {
|
||||||
'escalationPropertiesProvider',
|
'escalationPropertiesProvider',
|
||||||
'callActivityPropertiesProvider',
|
'callActivityPropertiesProvider',
|
||||||
'ioPalette',
|
'ioPalette',
|
||||||
'paletteProvider',
|
|
||||||
'propertiesPanelProvider',
|
|
||||||
'ioRules',
|
'ioRules',
|
||||||
'ioInterceptor',
|
'ioInterceptor',
|
||||||
'dataObjectRenderer',
|
'dataObjectRenderer',
|
||||||
|
@ -60,8 +57,6 @@ export default {
|
||||||
messagesPropertiesProvider: ['type', MessagesPropertiesProvider],
|
messagesPropertiesProvider: ['type', MessagesPropertiesProvider],
|
||||||
callActivityPropertiesProvider: ['type', CallActivityPropertiesProvider],
|
callActivityPropertiesProvider: ['type', CallActivityPropertiesProvider],
|
||||||
ioPalette: ['type', IoPalette],
|
ioPalette: ['type', IoPalette],
|
||||||
paletteProvider: ['type', IoPalette],
|
|
||||||
propertiesPanelProvider: ['type', PropertiesPanelProvider],
|
|
||||||
ioRules: ['type', IoRules],
|
ioRules: ['type', IoRules],
|
||||||
ioInterceptor: ['type', IoInterceptor],
|
ioInterceptor: ['type', IoInterceptor],
|
||||||
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
||||||
|
|
|
@ -181,7 +181,6 @@ function createMessageGroup(
|
||||||
return {
|
return {
|
||||||
id: 'messages',
|
id: 'messages',
|
||||||
label: translate('Message'),
|
label: translate('Message'),
|
||||||
isDefault: true,
|
|
||||||
entries,
|
entries,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
const LOW_PRIORITY = 800;
|
|
||||||
|
|
||||||
export default function PropertiesPanelProvider(propertiesPanel, eventBus) {
|
|
||||||
let el;
|
|
||||||
|
|
||||||
// eventBus.on('propertiesPanel.providersChanged', function (event) {
|
|
||||||
// console.log('------------------- propertiesPanel.providersChanged', event);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// eventBus.on('propertiesPanel.getProviders', function (event) {
|
|
||||||
// console.log('------------------- propertiesPanel.getProviders', event);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// eventBus.on('propertiesPanel.setLayout', function (event) {
|
|
||||||
// console.log('------------------- propertiesPanel.setLayout', event);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// eventBus.on('propertiesPanel.layoutChanged', function (event) {
|
|
||||||
// console.log('------------------- propertiesPanel.layoutChanged', event);
|
|
||||||
// });
|
|
||||||
|
|
||||||
this.getGroups = function (element) {
|
|
||||||
return function (groups) {
|
|
||||||
// Only render when : el is undefined (editor onload state) or user selects new element or user changes the type of a selected element
|
|
||||||
if (!el || element.id !== el.id || (element.type !== el.type && element.id === el.id)) {
|
|
||||||
el = {
|
|
||||||
id: element.id,
|
|
||||||
type: element.type
|
|
||||||
}
|
|
||||||
this.render(groups);
|
|
||||||
}
|
|
||||||
return groups;
|
|
||||||
}.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertiesPanelProvider.$inject = ['propertiesPanel', 'eventBus'];
|
|
||||||
|
|
||||||
PropertiesPanelProvider.prototype.render = function (groups) {
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
const propertiesPanelContainer = document.querySelector('.bio-properties-panel-container');
|
|
||||||
if (!propertiesPanelContainer) return;
|
|
||||||
|
|
||||||
// Within that big container, find the part where we can scroll
|
|
||||||
const scrollContainer = propertiesPanelContainer.querySelector('.bio-properties-panel-scroll-container');
|
|
||||||
if (!scrollContainer) return;
|
|
||||||
|
|
||||||
// Functions :
|
|
||||||
|
|
||||||
// This function makes the groups able to open and close.
|
|
||||||
function makeGroupCollapsible(group) {
|
|
||||||
const header = group.querySelector('.bio-properties-panel-group-header');
|
|
||||||
const entries = group.querySelector('.bio-properties-panel-group-entries');
|
|
||||||
const arrow = header.querySelector('svg');
|
|
||||||
|
|
||||||
let isFirstClick = true;
|
|
||||||
|
|
||||||
if (header && entries && arrow) {
|
|
||||||
header.classList.add('open');
|
|
||||||
entries.classList.add('open');
|
|
||||||
arrow.classList.add('bio-properties-panel-arrow-down');
|
|
||||||
arrow.classList.remove('bio-properties-panel-arrow-right');
|
|
||||||
|
|
||||||
// Handles the first click, to prevent the bpmn js library from handling it instead
|
|
||||||
header.addEventListener('click', function() {
|
|
||||||
if (isFirstClick) {
|
|
||||||
header.click();
|
|
||||||
isFirstClick = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function decides what to show based on which tab is clicked.
|
|
||||||
function updateTabContent(activeTab) {
|
|
||||||
const allGroups = scrollContainer.querySelectorAll('.bio-properties-panel-group');
|
|
||||||
allGroups.forEach(group => group.style.display = 'none'); // Hide everything first.
|
|
||||||
|
|
||||||
groups.forEach(group => {
|
|
||||||
const groupElement = scrollContainer.querySelector(`[data-group-id="group-${group.id}"]`);
|
|
||||||
if (groupElement) {
|
|
||||||
// If we're on the "General" tab, show the general groups and any group that's set as default.
|
|
||||||
if (activeTab.dataset.tab === 'general' && (group.id === 'general' || group.isDefault)) {
|
|
||||||
groupElement.style.display = '';
|
|
||||||
if (group.isDefault) {
|
|
||||||
makeGroupCollapsible(groupElement);
|
|
||||||
}
|
|
||||||
} else if (activeTab.dataset.tab === 'advanced' && group.id !== 'general' && !group.isDefault) {
|
|
||||||
groupElement.style.display = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to always start with the 'General' tab opened
|
|
||||||
function resetTabsToShowGeneral() {
|
|
||||||
const generalTab = scrollContainer.querySelector('li[data-tab="general"]');
|
|
||||||
const advancedTab = scrollContainer.querySelector('li[data-tab="advanced"]');
|
|
||||||
|
|
||||||
if (generalTab && advancedTab) {
|
|
||||||
generalTab.classList.add('active');
|
|
||||||
advancedTab.classList.remove('active');
|
|
||||||
updateTabContent(generalTab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a click event to each tab to change what's shown
|
|
||||||
document.querySelectorAll('.tabs li').forEach(tab => {
|
|
||||||
tab.addEventListener('click', function (event) {
|
|
||||||
document.querySelectorAll('.tabs li').forEach(t => t.classList.remove('active'));
|
|
||||||
tab.classList.add('active');
|
|
||||||
updateTabContent(tab);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create the tabs if they don't exist yet.
|
|
||||||
if (!scrollContainer.querySelector('.tabs')) {
|
|
||||||
const tabsHeader = document.createElement('ul');
|
|
||||||
tabsHeader.className = 'tabs property-tabs';
|
|
||||||
|
|
||||||
const generalTab = document.createElement('li');
|
|
||||||
generalTab.textContent = 'General';
|
|
||||||
generalTab.dataset.tab = 'general';
|
|
||||||
generalTab.className = 'active';
|
|
||||||
tabsHeader.appendChild(generalTab);
|
|
||||||
|
|
||||||
const advancedTab = document.createElement('li');
|
|
||||||
advancedTab.textContent = 'Advanced';
|
|
||||||
advancedTab.dataset.tab = 'advanced';
|
|
||||||
tabsHeader.appendChild(advancedTab);
|
|
||||||
|
|
||||||
scrollContainer.insertBefore(tabsHeader, scrollContainer.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure each tab can do its thing when clicked.
|
|
||||||
const tabs = scrollContainer.querySelectorAll('.tabs li');
|
|
||||||
tabs.forEach(tab => {
|
|
||||||
if (!tab.dataset.listenerAttached) {
|
|
||||||
tab.addEventListener('click', function (event) {
|
|
||||||
tabs.forEach(t => t.classList.remove('active'));
|
|
||||||
tab.classList.add('active');
|
|
||||||
updateTabContent(tab);
|
|
||||||
});
|
|
||||||
tab.dataset.listenerAttached = 'true'; // This is just to make sure we don't add the same event more than once.
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// When we first load, show the right tab and its contents.
|
|
||||||
const activeTab = document.querySelector('.tabs li.active');
|
|
||||||
if (activeTab) {
|
|
||||||
updateTabContent(activeTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetTabsToShowGeneral();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "bpmn-js-spiffworkflow",
|
"name": "bpmn-js-spiffworkflow",
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"license": "LGPL",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
"inherits-browser": "^0.0.1",
|
"inherits-browser": "^0.0.1",
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"url": "https://github.com/bpmn-io"
|
"url": "https://github.com/bpmn-io"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "LGPL",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.18.6",
|
"@babel/core": "^7.18.6",
|
||||||
"@babel/plugin-transform-react-jsx": "^7.17.12",
|
"@babel/plugin-transform-react-jsx": "^7.17.12",
|
||||||
|
|
|
@ -22,8 +22,8 @@ describe('BPMN Input / Output', function() {
|
||||||
it('should have a data input and data output in the properties panel', function() {
|
it('should have a data input and data output in the properties panel', function() {
|
||||||
var paletteElement = domQuery('.djs-palette', CONTAINER);
|
var paletteElement = domQuery('.djs-palette', CONTAINER);
|
||||||
var entries = domQueryAll('.entry', paletteElement);
|
var entries = domQueryAll('.entry', paletteElement);
|
||||||
expect(entries[14].title).to.equals('Data Input');
|
expect(entries[11].title).to.equals('Create DataInput');
|
||||||
expect(entries[15].title).to.equals('Data Output');
|
expect(entries[12].title).to.equals('Create DataOutput');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,8 +23,8 @@ import DataStoreInterceptor from '../../app/spiffworkflow/DataStoreReference/Dat
|
||||||
const return_datastores = (event) => {
|
const return_datastores = (event) => {
|
||||||
event.eventBus.fire('spiff.data_stores.returned', {
|
event.eventBus.fire('spiff.data_stores.returned', {
|
||||||
options: [
|
options: [
|
||||||
{ id: 'countriesID', type: 'json', name: 'countries', clz: 'JSONDataStore' },
|
{ type: 'typeahead', name: 'countries' },
|
||||||
{ id: 'foodsID', type: 'kkv', name: 'foods', clz: 'JSONDataStore' }
|
{ type: 'kkv', name: 'foods' }
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,11 @@ describe('Data Source Reference Test cases', function () {
|
||||||
// Verification if the dataStoreRef attribute is updated
|
// Verification if the dataStoreRef attribute is updated
|
||||||
let selector = findSelect(entry);
|
let selector = findSelect(entry);
|
||||||
expect(selector.length).to.equal(3);
|
expect(selector.length).to.equal(3);
|
||||||
expect(selector[1].value === 'foodsID___JSONDataStore');
|
expect(selector[1].value === 'countries');
|
||||||
expect(selector[2].value === 'countriesID___JSONDataStore');
|
expect(selector[2].value === 'foods');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update dataStoreRef after a select event && should add new DataStore in the level of process definition - DataStoreReference element', async function () {
|
it('should update dataStoreRef after a select event && should add new DataState in the level of process definition - DataStoreReference element', async function () {
|
||||||
const modeler = getBpmnJS();
|
const modeler = getBpmnJS();
|
||||||
modeler.get('eventBus').once('spiff.data_stores.requested', return_datastores);
|
modeler.get('eventBus').once('spiff.data_stores.requested', return_datastores);
|
||||||
|
|
||||||
|
@ -104,16 +104,17 @@ describe('Data Source Reference Test cases', function () {
|
||||||
|
|
||||||
// Verification if the dataStoreRef attribute is updated
|
// Verification if the dataStoreRef attribute is updated
|
||||||
let selector = findSelect(entry);
|
let selector = findSelect(entry);
|
||||||
changeInput(selector, 'foodsID___JSONDataStore');
|
changeInput(selector, 'foods');
|
||||||
const nwbusinessObject = getBusinessObject(shapeElement);
|
const nwbusinessObject = getBusinessObject(shapeElement);
|
||||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foodsID');
|
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foods');
|
||||||
|
|
||||||
// Check if the DataStore is added at the root level
|
// Check if the DataStore is added at the root level
|
||||||
const definitions = modeler.getDefinitions();
|
const definitions = modeler.getDefinitions();
|
||||||
const dataStoreExists = definitions.get('rootElements').some(element =>
|
const dataStoreExists = definitions.get('rootElements').some(element =>
|
||||||
element.$type === 'bpmn:DataStore' && element.id === 'foodsID'
|
element.$type === 'bpmn:DataStore' && element.id === 'foods'
|
||||||
);
|
);
|
||||||
expect(dataStoreExists, "DataStore 'foodsID' should be added at the root level").to.be.true;
|
expect(dataStoreExists, "DataStore 'foods' should be added at the root level").to.be.true;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete dataStore if dataStorRef is updated - DataStoreReference element', async function () {
|
it('should delete dataStore if dataStorRef is updated - DataStoreReference element', async function () {
|
||||||
|
@ -133,22 +134,22 @@ describe('Data Source Reference Test cases', function () {
|
||||||
|
|
||||||
// Verification if the dataStoreRef attribute is updated
|
// Verification if the dataStoreRef attribute is updated
|
||||||
let selector = findSelect(entry);
|
let selector = findSelect(entry);
|
||||||
changeInput(selector, 'foodsID___JSONDataStore');
|
changeInput(selector, 'foods');
|
||||||
let nwbusinessObject = getBusinessObject(shapeElement);
|
let nwbusinessObject = getBusinessObject(shapeElement);
|
||||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foodsID');
|
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foods');
|
||||||
// Then choose new dataStore
|
// Then choose new dataStore
|
||||||
changeInput(selector, 'countriesID___JSONDataStore');
|
changeInput(selector, 'countries');
|
||||||
nwbusinessObject = getBusinessObject(shapeElement);
|
nwbusinessObject = getBusinessObject(shapeElement);
|
||||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('countriesID');
|
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('countries');
|
||||||
|
|
||||||
// Check if the DataStore is added at the root level with the updated dataStore
|
// Check if the DataStore is added at the root level with the updated dataStore
|
||||||
const definitions = modeler.getDefinitions();
|
const definitions = modeler.getDefinitions();
|
||||||
const countriesDataStoreExists = definitions.get('rootElements').some(element =>
|
const countriesDataStoreExists = definitions.get('rootElements').some(element =>
|
||||||
element.$type === 'bpmn:DataStore' && element.id === 'countriesID'
|
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||||
);
|
);
|
||||||
expect(countriesDataStoreExists, "DataStore 'countries' should be added at the root level").to.be.true;
|
expect(countriesDataStoreExists, "DataStore 'countries' should be added at the root level").to.be.true;
|
||||||
const foodsDataStoreExists = definitions.get('rootElements').some(element =>
|
const foodsDataStoreExists = definitions.get('rootElements').some(element =>
|
||||||
element.$type === 'bpmn:DataStore' && element.id === 'foodsID'
|
element.$type === 'bpmn:DataStore' && element.id === 'foods'
|
||||||
);
|
);
|
||||||
expect(foodsDataStoreExists, "DataStore 'countries' should be removed from the root level").not.to.be.true;
|
expect(foodsDataStoreExists, "DataStore 'countries' should be removed from the root level").not.to.be.true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue