@processmaker/modeler 1.31.0 → 1.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/babel.config.js +1 -2
- package/dist/img/inclusive-gateway.0f0afffd.svg +4 -0
- package/dist/img/inspector.42e5d40d.svg +5 -0
- package/dist/img/issue-close.5d1630e6.svg +3 -0
- package/dist/img/issue-item.3187f291.svg +3 -0
- package/dist/img/issue-open.707390b4.svg +4 -0
- package/dist/img/validate-close.09ace97a.svg +4 -0
- package/dist/img/validate-open.b0ecf74e.svg +4 -0
- package/dist/modeler.common.js +3354 -2489
- package/dist/modeler.common.js.map +1 -1
- package/dist/modeler.umd.js +3354 -2489
- package/dist/modeler.umd.js.map +1 -1
- package/dist/modeler.umd.min.js +4 -4
- package/dist/modeler.umd.min.js.map +1 -1
- package/package.json +2 -2
- package/src/.DS_Store +0 -0
- package/src/ModelerApp.vue +0 -9
- package/src/NodeIdGenerator.js +16 -1
- package/src/assets/inspector.svg +5 -0
- package/src/assets/toolpanel/inclusive-gateway.svg +2 -2
- package/src/assets/topRail/issue-close.svg +3 -0
- package/src/assets/topRail/issue-item.svg +3 -0
- package/src/assets/topRail/issue-open.svg +4 -0
- package/src/assets/topRail/validate-close.svg +4 -0
- package/src/assets/topRail/validate-open.svg +4 -0
- package/src/components/controls/controls.vue +2 -11
- package/src/components/crown/crownButtons/addLaneAboveButton.vue +3 -1
- package/src/components/crown/crownButtons/addLaneBelowButton.vue +3 -1
- package/src/components/crown/crownButtons/crownBoundaryEventDropdown.vue +2 -1
- package/src/components/crown/crownButtons/genericFlowButton.vue +2 -1
- package/src/components/crown/crownButtons/icons/faAlignLeft.js +1 -1
- package/src/components/crown/crownMultiselect/crownAlign.vue +3 -0
- package/src/components/crown/crownMultiselect/crownMultiselect.vue +4 -2
- package/src/components/hotkeys/escKey.js +20 -0
- package/src/components/hotkeys/main.js +4 -2
- package/src/components/inspectors/InspectorPanel.vue +26 -3
- package/src/components/inspectors/inspector.scss +11 -0
- package/src/components/inspectors/inspectorButton/InspectorButton.vue +38 -0
- package/src/components/inspectors/inspectorButton/inspectorButton.scss +19 -0
- package/src/components/inspectors/process.js +1 -1
- package/src/components/modeler/Modeler.vue +62 -5
- package/src/components/modeler/ModelerReadonly.vue +52 -6
- package/src/components/modeler/Selection.vue +9 -1
- package/src/components/nodes/association/index.js +1 -1
- package/src/components/nodes/baseStartEvent/index.js +1 -1
- package/src/components/nodes/boundaryEvent/index.js +1 -1
- package/src/components/nodes/dataInputAssociation/index.js +1 -1
- package/src/components/nodes/dataObject/index.js +1 -1
- package/src/components/nodes/dataOutputAssociation/index.js +1 -1
- package/src/components/nodes/dataStore/index.js +1 -1
- package/src/components/nodes/endEvent/index.js +1 -1
- package/src/components/nodes/eventBasedGateway/index.js +1 -1
- package/src/components/nodes/exclusiveGateway/index.js +1 -1
- package/src/components/nodes/gateway/index.js +1 -1
- package/src/components/nodes/inclusiveGateway/index.js +1 -1
- package/src/components/nodes/intermediateEvent/index.js +1 -1
- package/src/components/nodes/intermediateMessageEvent/index.js +1 -1
- package/src/components/nodes/intermediateTimerEvent/index.js +1 -1
- package/src/components/nodes/manualTask/index.js +1 -1
- package/src/components/nodes/messageFlow/index.js +1 -1
- package/src/components/nodes/parallelGateway/index.js +1 -1
- package/src/components/nodes/pool/index.js +1 -1
- package/src/components/nodes/pool/pool.vue +10 -4
- package/src/components/nodes/poolLane/index.js +1 -1
- package/src/components/nodes/scriptTask/index.js +1 -1
- package/src/components/nodes/sequenceFlow/index.js +1 -1
- package/src/components/nodes/serviceTask/index.js +1 -1
- package/src/components/nodes/subProcess/index.js +1 -1
- package/src/components/nodes/task/index.js +1 -1
- package/src/components/nodes/textAnnotation/index.js +1 -1
- package/src/components/railBottom/controls/Controls.vue +15 -75
- package/src/components/railBottom/controls/SubmenuPopper/SubmenuPopper.vue +5 -5
- package/src/components/rails/explorer-rail/explorer-rail.scss +11 -0
- package/src/components/rails/explorer-rail/explorer.vue +12 -3
- package/src/components/rails/explorer-rail/filterNodeTypes/filterNodeTypes.vue +15 -3
- package/src/components/rails/explorer-rail/nodeTypesLoop/nodeTypesLoop.vue +8 -73
- package/src/components/rails/explorer-rail/pmBlocksLoop/pmBlocksLoop.vue +76 -0
- package/src/components/shapeStackUtils.js +1 -1
- package/src/components/toolbar/ToolBar.vue +62 -55
- package/src/components/toolbar/toolbar.scss +55 -15
- package/src/components/topRail/TopRail.vue +92 -0
- package/src/components/topRail/topRail.scss +6 -0
- package/src/components/topRail/validateControl/index.js +3 -0
- package/src/components/topRail/validateControl/validateButton/ValidateButton.vue +39 -0
- package/src/components/topRail/validateControl/validateButton/validateButton.scss +25 -0
- package/src/components/topRail/validateControl/validateIssue/ValidateIssue.vue +60 -0
- package/src/components/topRail/validateControl/validateIssue/validateIssue.scss +54 -0
- package/src/components/topRail/validateControl/validatePanel/ValidatePanel.vue +54 -0
- package/src/components/topRail/validateControl/validatePanel/validatePanel.scss +67 -0
- package/src/mixins/clickAndDrop.js +107 -0
- package/src/mixins/highlightConfig.js +78 -10
- package/src/mixins/linkConfig.js +32 -8
- package/src/nodeTypesStore.js +48 -0
- package/src/setup/registerPmBlock.js +0 -0
- package/vue.config.js +1 -0
- package/dist/img/distribute-horizontally-icon.5c513cf4.svg +0 -3
- package/dist/img/distribute-vertically-icon.a35fb699.svg +0 -3
- package/dist/img/inclusive-gateway.754cb36f.svg +0 -4
- package/src/components/controls/rankConstants.js +0 -1
|
@@ -4,6 +4,7 @@ import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
|
|
4
4
|
import nodeTypesStore from '@/nodeTypesStore';
|
|
5
5
|
import FilterNodeTypes from '@/components/rails/explorer-rail/filterNodeTypes/filterNodeTypes.vue';
|
|
6
6
|
import NodeTypesLoop from '@/components/rails/explorer-rail/nodeTypesLoop/nodeTypesLoop.vue';
|
|
7
|
+
import PmBlocksLoop from '@/components/rails/explorer-rail/pmBlocksLoop/pmBlocksLoop.vue';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
name: 'ExplorerRail',
|
|
@@ -14,11 +15,15 @@ export default {
|
|
|
14
15
|
nodeTypes: {
|
|
15
16
|
type: Array,
|
|
16
17
|
},
|
|
18
|
+
pmBlockNodes: {
|
|
19
|
+
type: Array,
|
|
20
|
+
},
|
|
17
21
|
},
|
|
18
22
|
components: {
|
|
19
23
|
FontAwesomeIcon,
|
|
20
24
|
FilterNodeTypes,
|
|
21
25
|
NodeTypesLoop,
|
|
26
|
+
PmBlocksLoop,
|
|
22
27
|
},
|
|
23
28
|
data() {
|
|
24
29
|
return {
|
|
@@ -59,6 +64,7 @@ export default {
|
|
|
59
64
|
},
|
|
60
65
|
clearFilteredObjects() {
|
|
61
66
|
nodeTypesStore.commit('clearFilteredNodes');
|
|
67
|
+
nodeTypesStore.commit('clearFilteredPmBlockNodes');
|
|
62
68
|
},
|
|
63
69
|
},
|
|
64
70
|
};
|
|
@@ -79,13 +85,16 @@ export default {
|
|
|
79
85
|
</div>
|
|
80
86
|
</div>
|
|
81
87
|
<div class="node-types__container" v-if="tabIndex === 0">
|
|
82
|
-
<filter-node-types />
|
|
88
|
+
<filter-node-types :type="'object'"/>
|
|
83
89
|
<node-types-loop
|
|
84
90
|
v-on="$listeners"
|
|
85
91
|
/>
|
|
86
92
|
</div>
|
|
87
|
-
<div class="pm-blocks__container">
|
|
88
|
-
|
|
93
|
+
<div class="pm-blocks__container" v-if="tabIndex === 1">
|
|
94
|
+
<filter-node-types :type="'pmBlock'"/>
|
|
95
|
+
<pm-blocks-loop
|
|
96
|
+
v-on="$listeners"
|
|
97
|
+
/>
|
|
89
98
|
</div>
|
|
90
99
|
</div>
|
|
91
100
|
</template>
|
|
@@ -2,16 +2,21 @@
|
|
|
2
2
|
import nodeTypesStore from '@/nodeTypesStore';
|
|
3
3
|
export default {
|
|
4
4
|
name: 'FilterNodeTypes',
|
|
5
|
+
props: ['type'],
|
|
5
6
|
data() {
|
|
6
7
|
return {
|
|
7
8
|
searchTerm: '',
|
|
8
|
-
placeholder: this.$t('Seach Objects'),
|
|
9
9
|
};
|
|
10
10
|
},
|
|
11
11
|
watch: {
|
|
12
12
|
searchTerm(value) {
|
|
13
|
-
if (
|
|
14
|
-
|
|
13
|
+
if (this.type === 'pmBlock') {
|
|
14
|
+
if (value.length === 0) nodeTypesStore.commit('clearFilteredPmBlockNodes');
|
|
15
|
+
if (value.length > 0) nodeTypesStore.commit('setFilteredPmBlockNodeTypes', value);
|
|
16
|
+
} else {
|
|
17
|
+
if (value.length === 0) nodeTypesStore.commit('clearFilteredNodes');
|
|
18
|
+
if (value.length > 0) nodeTypesStore.commit('setFilteredNodeTypes', value);
|
|
19
|
+
}
|
|
15
20
|
},
|
|
16
21
|
},
|
|
17
22
|
computed: {
|
|
@@ -20,6 +25,13 @@ export default {
|
|
|
20
25
|
const nodeTypes = nodeTypesStore.getters.getNodeTypes;
|
|
21
26
|
return [...pinnedNodeTypes, ...nodeTypes];
|
|
22
27
|
},
|
|
28
|
+
pmBlockNodes() {
|
|
29
|
+
const pmBlockNodeTypes = nodeTypesStore.getters.getPmBlockNodeTypes;
|
|
30
|
+
return [...pmBlockNodeTypes];
|
|
31
|
+
},
|
|
32
|
+
placeholder() {
|
|
33
|
+
return this.type === 'pmBlock' ? this.$t('Search PM Blocks') : this.$t('Search Objects');
|
|
34
|
+
},
|
|
23
35
|
},
|
|
24
36
|
};
|
|
25
37
|
</script>
|
|
@@ -2,29 +2,16 @@
|
|
|
2
2
|
import pinIcon from '@/assets/pin-angle.svg';
|
|
3
3
|
import pinFillIcon from '@/assets/pin-angle-fill.svg';
|
|
4
4
|
import nodeTypesStore from '@/nodeTypesStore';
|
|
5
|
+
import clickAndDrop from '@/mixins/clickAndDrop';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
name: 'NodeTypesLoop',
|
|
9
|
+
mixins: [clickAndDrop],
|
|
8
10
|
data() {
|
|
9
11
|
return {
|
|
10
12
|
pinIcon,
|
|
11
13
|
pinFillIcon,
|
|
12
14
|
showPin: false,
|
|
13
|
-
wasClicked: false,
|
|
14
|
-
element: null,
|
|
15
|
-
selectedItem: null,
|
|
16
|
-
xOffset: 0,
|
|
17
|
-
yOffset: 0,
|
|
18
|
-
movedElement: null,
|
|
19
|
-
helperStyles: {
|
|
20
|
-
backgroundColor:'#ffffff',
|
|
21
|
-
position: 'absolute',
|
|
22
|
-
height: '40px',
|
|
23
|
-
width: '40px',
|
|
24
|
-
zIndex: '10',
|
|
25
|
-
opacity: '0.5',
|
|
26
|
-
pointerEvents: 'none',
|
|
27
|
-
},
|
|
28
15
|
};
|
|
29
16
|
},
|
|
30
17
|
created() {
|
|
@@ -35,68 +22,13 @@ export default {
|
|
|
35
22
|
return !!this.pinnedObjects.find(obj => obj.type === type);
|
|
36
23
|
},
|
|
37
24
|
unPin(object) {
|
|
25
|
+
this.deselect();
|
|
38
26
|
return nodeTypesStore.dispatch('removeUserPinnedObject', object);
|
|
39
27
|
},
|
|
40
28
|
addPin(object) {
|
|
29
|
+
this.deselect();
|
|
41
30
|
return nodeTypesStore.dispatch('addUserPinnedObject', object);
|
|
42
31
|
},
|
|
43
|
-
onClickHandler(event, control) {
|
|
44
|
-
this.createDraggingHelper(event, control);
|
|
45
|
-
document.addEventListener('mousemove', this.setDraggingPosition);
|
|
46
|
-
this.setDraggingPosition(event);
|
|
47
|
-
// Deselect control on click if same control is already selected
|
|
48
|
-
if (this.selectedItem === control.type) {
|
|
49
|
-
document.removeEventListener('mousemove', this.setDraggingPosition);
|
|
50
|
-
document.body.removeChild(this.movedElement);
|
|
51
|
-
this.$emit('onSetCursor', 'none');
|
|
52
|
-
this.selectedItem = null;
|
|
53
|
-
this.movedElement = null;
|
|
54
|
-
this.wasClicked = false;
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
this.wasClicked = true;
|
|
58
|
-
this.element = control;
|
|
59
|
-
this.$emit('onSetCursor', 'crosshair');
|
|
60
|
-
this.selectedItem = control.type;
|
|
61
|
-
window.ProcessMaker.EventBus.$on('custom-pointerclick', message => {
|
|
62
|
-
window.ProcessMaker.EventBus.$off('custom-pointerclick');
|
|
63
|
-
document.removeEventListener('mousemove', this.setDraggingPosition);
|
|
64
|
-
if (this.movedElement) {
|
|
65
|
-
document.body.removeChild(this.movedElement);
|
|
66
|
-
}
|
|
67
|
-
this.selectedItem = null;
|
|
68
|
-
this.movedElement = null;
|
|
69
|
-
this.onCreateElement(message);
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
createDraggingHelper(event, control) {
|
|
73
|
-
if (this.movedElement) {
|
|
74
|
-
document.removeEventListener('mousemove', this.setDraggingPosition);
|
|
75
|
-
document.body.removeChild(this.movedElement);
|
|
76
|
-
this.movedElement = null;
|
|
77
|
-
}
|
|
78
|
-
const sourceElement = event.target;
|
|
79
|
-
this.movedElement = document.createElement('img');
|
|
80
|
-
Object.keys(this.helperStyles).forEach((property) => {
|
|
81
|
-
this.movedElement.style[property] = this.helperStyles[property];
|
|
82
|
-
});
|
|
83
|
-
this.movedElement.src = control.icon;
|
|
84
|
-
document.body.appendChild(this.movedElement);
|
|
85
|
-
this.xOffset = event.clientX - sourceElement.getBoundingClientRect().left;
|
|
86
|
-
this.yOffset = event.clientY - sourceElement.getBoundingClientRect().top;
|
|
87
|
-
},
|
|
88
|
-
setDraggingPosition({ pageX, pageY }) {
|
|
89
|
-
this.movedElement.style.left = pageX + 'px';
|
|
90
|
-
this.movedElement.style.top = pageY + 'px';
|
|
91
|
-
},
|
|
92
|
-
onCreateElement(event){
|
|
93
|
-
if (this.wasClicked && this.element) {
|
|
94
|
-
this.$emit('onCreateElement', { event, control: this.element });
|
|
95
|
-
this.$emit('onSetCursor', 'none');
|
|
96
|
-
event.preventDefault();
|
|
97
|
-
this.wasClicked = false;
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
32
|
},
|
|
101
33
|
computed: {
|
|
102
34
|
pinnedObjects() {
|
|
@@ -125,10 +57,11 @@ export default {
|
|
|
125
57
|
<template v-for="object in filteredNodes">
|
|
126
58
|
<div
|
|
127
59
|
class="node-types__item"
|
|
60
|
+
:data-test="object.type"
|
|
128
61
|
:key="object.id"
|
|
129
62
|
@mouseover="showPin = true"
|
|
130
63
|
@mouseleave="showPin = false"
|
|
131
|
-
@click.
|
|
64
|
+
@click.self="onClickHandler($event, object)"
|
|
132
65
|
>
|
|
133
66
|
<img class="node-types__item__icon" :src="object.icon" :alt="$t(object.label)">
|
|
134
67
|
<span>{{ $t(object.label) }}</span>
|
|
@@ -155,6 +88,7 @@ export default {
|
|
|
155
88
|
<template v-for="pinnedObject in pinnedObjects">
|
|
156
89
|
<div
|
|
157
90
|
class="node-types__item"
|
|
91
|
+
:data-test="pinnedObject.type"
|
|
158
92
|
:key="pinnedObject.id"
|
|
159
93
|
@mouseover="showPin = true"
|
|
160
94
|
@mouseleave="showPin = false"
|
|
@@ -176,6 +110,7 @@ export default {
|
|
|
176
110
|
<template v-for="nodeType in unpinnedObjects">
|
|
177
111
|
<div
|
|
178
112
|
class="node-types__item"
|
|
113
|
+
:data-test="nodeType.type"
|
|
179
114
|
:key="nodeType.id"
|
|
180
115
|
@mouseover="showPin = true"
|
|
181
116
|
@mouseleave="showPin = false"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import nodeTypesStore from '@/nodeTypesStore';
|
|
3
|
+
import clickAndDrop from '@/mixins/clickAndDrop';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
name: 'PmBlocksLoop',
|
|
7
|
+
mixins: [clickAndDrop],
|
|
8
|
+
computed: {
|
|
9
|
+
pmBlockNodeTypes() {
|
|
10
|
+
return nodeTypesStore.getters.getPmBlockNodeTypes;
|
|
11
|
+
},
|
|
12
|
+
filteredPmBlockNodes() {
|
|
13
|
+
return nodeTypesStore.getters.getFilteredPmBlockNodeTypes;
|
|
14
|
+
},
|
|
15
|
+
searchTerm() {
|
|
16
|
+
return nodeTypesStore.getters.getSearchTerm;
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<div id="pmBlockNodeTypesList">
|
|
24
|
+
<div id="filteredPmBlockNodes-container" v-if="filteredPmBlockNodes.length > 0">
|
|
25
|
+
<template v-for="object in filteredPmBlockNodes">
|
|
26
|
+
<div
|
|
27
|
+
class="node-types__item"
|
|
28
|
+
:key="object.id"
|
|
29
|
+
@click.stop="onClickHandler($event, object)"
|
|
30
|
+
>
|
|
31
|
+
<img class="node-types__item__icon" :src="object.icon" :alt="$t(object.label)">
|
|
32
|
+
<span>{{ $t(object.label) }}</span>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
</div>
|
|
36
|
+
<template v-if="filteredPmBlockNodes.length === 0 && !searchTerm">
|
|
37
|
+
<div class="pmBlocksContainer p-2">
|
|
38
|
+
<template v-for="nodeType in pmBlockNodeTypes">
|
|
39
|
+
<div
|
|
40
|
+
class="pm-block-node-types__item p-2 d-block"
|
|
41
|
+
:key="nodeType.id"
|
|
42
|
+
@click.stop="onClickHandler($event, nodeType)"
|
|
43
|
+
>
|
|
44
|
+
<label>{{ $t(nodeType.label) }}</label>
|
|
45
|
+
<span class="d-block">{{ nodeType.description }}</span>
|
|
46
|
+
</div>
|
|
47
|
+
</template>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<style lang="scss">
|
|
54
|
+
.pm-block-node-types {
|
|
55
|
+
&__item {
|
|
56
|
+
display: block;
|
|
57
|
+
border-radius: 4px;
|
|
58
|
+
user-select: none;
|
|
59
|
+
margin-bottom: 8px;
|
|
60
|
+
border: 1px solid #b6bfc6;
|
|
61
|
+
&:hover {
|
|
62
|
+
background-color: #EBEEF2;
|
|
63
|
+
}
|
|
64
|
+
label {
|
|
65
|
+
font-size: 14px;
|
|
66
|
+
line-height: 8px;
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
color: #104A75;
|
|
69
|
+
}
|
|
70
|
+
span {
|
|
71
|
+
font-size: 12px;
|
|
72
|
+
color:#6C757D;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
@@ -26,7 +26,7 @@ function isNotLane(shape) {
|
|
|
26
26
|
function bringPoolToFront(poolShape) {
|
|
27
27
|
bringShapeToFront(poolShape);
|
|
28
28
|
|
|
29
|
-
const hasLanes = poolShape.component.node.definition.processRef.laneSets[0];
|
|
29
|
+
const hasLanes = poolShape.component.node.definition.processRef && poolShape.component.node.definition.processRef.laneSets[0];
|
|
30
30
|
if (!hasLanes) {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
@@ -4,49 +4,53 @@
|
|
|
4
4
|
aria-label="Toolbar" :class="{ 'ignore-pointer': canvasDragPosition }"
|
|
5
5
|
>
|
|
6
6
|
<breadcrumb :breadcrumb-data="breadcrumbData" />
|
|
7
|
-
<div class="mr-3">
|
|
8
|
-
<
|
|
7
|
+
<div class="d-flex mr-3">
|
|
8
|
+
<TopRail
|
|
9
|
+
:validation-errors="validationErrors"
|
|
10
|
+
:warnings="warnings"
|
|
11
|
+
>
|
|
12
|
+
<component
|
|
13
|
+
:is="component.button"
|
|
14
|
+
v-for="(component, index) in validationBar"
|
|
15
|
+
:key="`validation-status-${index}`"
|
|
16
|
+
/>
|
|
17
|
+
</TopRail>
|
|
9
18
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
v-b-tooltip.hover
|
|
17
|
-
:title="panelsCompressed ? $t('Show Menus') : $t('Hide Menus')"
|
|
18
|
-
>
|
|
19
|
-
<font-awesome-icon :icon="panelsCompressed ? expandIcon : compressIcon" />
|
|
20
|
-
</b-button>
|
|
21
|
-
</div>
|
|
22
|
-
<div class="btn-group btn-group-sm" role="group" aria-label="Publish controls">
|
|
19
|
+
<div
|
|
20
|
+
class="d-flex align-items-center btn-group btn-group-sm"
|
|
21
|
+
role="group"
|
|
22
|
+
aria-label="Publish controls"
|
|
23
|
+
data-cy="publish-control"
|
|
24
|
+
>
|
|
23
25
|
<template v-if="isVersionsInstalled">
|
|
24
|
-
<div
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
<div
|
|
27
|
+
class="toolbar-item toolbar-version-status"
|
|
28
|
+
data-cy="publish-version-status"
|
|
29
|
+
>
|
|
30
|
+
{{ versionStatus }}
|
|
28
31
|
</div>
|
|
29
|
-
<div
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
<div
|
|
33
|
+
class="toolbar-item toolbar-loading-status"
|
|
34
|
+
data-cy="publish-loading-status"
|
|
35
|
+
>
|
|
33
36
|
<span>
|
|
34
|
-
|
|
37
|
+
{{ loadingStatus }}
|
|
35
38
|
</span>
|
|
39
|
+
<font-awesome-icon class="text-success" :icon="loadingIcon" :spin="isLoading" />
|
|
36
40
|
</div>
|
|
37
41
|
<a
|
|
38
|
-
class="btn btn-sm btn-primary btn-autosave text-uppercase mx-2"
|
|
39
|
-
data-test="publish-btn"
|
|
40
42
|
:title="$t('Publish')"
|
|
41
43
|
@click="$emit('saveBpmn')"
|
|
44
|
+
class="toolbar-item toolbar-publish"
|
|
45
|
+
data-cy="publish-btn"
|
|
42
46
|
>
|
|
43
47
|
{{ $t('Publish') }}
|
|
44
48
|
</a>
|
|
45
49
|
<a
|
|
46
|
-
class="btn btn-sm btn-link toolbar-item btn-autosave text-black text-uppercase"
|
|
47
|
-
data-test="close-btn"
|
|
48
50
|
:title="$t('Close')"
|
|
49
51
|
@click="$emit('close')"
|
|
52
|
+
class="toolbar-item toolbar-close"
|
|
53
|
+
data-cy="close-btn"
|
|
50
54
|
>
|
|
51
55
|
{{ $t('Close') }}
|
|
52
56
|
</a>
|
|
@@ -56,18 +60,9 @@
|
|
|
56
60
|
@navigate="onNavigate"
|
|
57
61
|
@show="onShow"
|
|
58
62
|
@hide="onHide"
|
|
63
|
+
data-cy="ellipsis-menu"
|
|
59
64
|
/>
|
|
60
65
|
</template>
|
|
61
|
-
<b-button
|
|
62
|
-
v-else
|
|
63
|
-
class="btn btn-sm btn-secondary mini-map-btn mx-1"
|
|
64
|
-
data-test="mini-map-btn"
|
|
65
|
-
v-b-tooltip.hover
|
|
66
|
-
:title="$t('Save')"
|
|
67
|
-
@click="$emit('saveBpmn')"
|
|
68
|
-
>
|
|
69
|
-
<font-awesome-icon :icon="saveIcon" />
|
|
70
|
-
</b-button>
|
|
71
66
|
</div>
|
|
72
67
|
</div>
|
|
73
68
|
</div>
|
|
@@ -78,23 +73,27 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
|
78
73
|
import { faCompress, faExpand, faMapMarked, faMinus, faPlus, faRedo, faUndo, faSave, faCheckCircle, faSpinner } from '@fortawesome/free-solid-svg-icons';
|
|
79
74
|
import undoRedoStore from '@/undoRedoStore';
|
|
80
75
|
import Breadcrumb from '@/components/toolbar/breadcrumb/Breadcrumb';
|
|
81
|
-
import
|
|
76
|
+
import TopRail from '@/components/topRail/TopRail.vue';
|
|
82
77
|
|
|
83
78
|
export default {
|
|
84
79
|
name: 'tool-bar',
|
|
85
|
-
components: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
paperManager: {},
|
|
90
|
-
isRendering: {
|
|
91
|
-
type: Boolean,
|
|
92
|
-
},
|
|
93
|
-
breadcrumbData: {
|
|
94
|
-
type: Array,
|
|
95
|
-
},
|
|
96
|
-
panelsCompressed: Boolean,
|
|
80
|
+
components: {
|
|
81
|
+
Breadcrumb,
|
|
82
|
+
TopRail,
|
|
83
|
+
FontAwesomeIcon,
|
|
97
84
|
},
|
|
85
|
+
props: [
|
|
86
|
+
'canvasDragPosition',
|
|
87
|
+
'cursor',
|
|
88
|
+
'paperManager',
|
|
89
|
+
'isRendering',
|
|
90
|
+
'breadcrumbData',
|
|
91
|
+
'panelsCompressed',
|
|
92
|
+
'validationErrors',
|
|
93
|
+
'warnings',
|
|
94
|
+
'xmlManager',
|
|
95
|
+
'validationBar',
|
|
96
|
+
],
|
|
98
97
|
watch: {
|
|
99
98
|
miniMapOpen(isOpen) {
|
|
100
99
|
this.$emit('toggle-mini-map-open', isOpen);
|
|
@@ -154,13 +153,18 @@ export default {
|
|
|
154
153
|
spinner: faSpinner,
|
|
155
154
|
ellipsisMenuActions: [
|
|
156
155
|
{
|
|
157
|
-
value: '
|
|
158
|
-
content: this.$t('
|
|
156
|
+
value: 'save-template',
|
|
157
|
+
content: this.$t('Save as Template'),
|
|
159
158
|
icon: '',
|
|
160
159
|
},
|
|
161
160
|
{
|
|
162
|
-
value: 'save-
|
|
163
|
-
content: this.$t('Save as
|
|
161
|
+
value: 'save-pm-block',
|
|
162
|
+
content: this.$t('Save as PM Block'),
|
|
163
|
+
icon: '',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
value: 'discard-draft',
|
|
167
|
+
content: this.$t('Discard Draft'),
|
|
164
168
|
icon: '',
|
|
165
169
|
},
|
|
166
170
|
],
|
|
@@ -193,6 +197,9 @@ export default {
|
|
|
193
197
|
case 'save-template':
|
|
194
198
|
this.$emit('publishTemplate');
|
|
195
199
|
break;
|
|
200
|
+
case 'save-pm-block':
|
|
201
|
+
this.$emit('publishPmBlock');
|
|
202
|
+
break;
|
|
196
203
|
default:
|
|
197
204
|
break;
|
|
198
205
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
$toolbar-background-color: #fff;
|
|
2
2
|
|
|
3
3
|
.toolbar {
|
|
4
|
-
z-index:
|
|
4
|
+
z-index: 3;
|
|
5
5
|
height: $toolbar-height;
|
|
6
6
|
cursor: auto;
|
|
7
7
|
width: 100%;
|
|
@@ -10,14 +10,61 @@ $toolbar-background-color: #fff;
|
|
|
10
10
|
> button {
|
|
11
11
|
cursor: pointer;
|
|
12
12
|
}
|
|
13
|
-
}
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
&-item {
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: center;
|
|
18
|
+
font-family: "Open Sans";
|
|
19
|
+
font-size: 14px;
|
|
20
|
+
font-style: normal;
|
|
21
|
+
font-weight: 400;
|
|
22
|
+
color: #000000;
|
|
23
|
+
text-transform: capitalize;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&-version-status {
|
|
27
|
+
margin: 0 12px;
|
|
28
|
+
padding-left: 12px;
|
|
29
|
+
border-left: 1px solid #ADB3B8;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
color: #6C757D;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&-loading-status {
|
|
35
|
+
margin-right: 21px;
|
|
36
|
+
|
|
37
|
+
> svg {
|
|
38
|
+
margin-left: 5px;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&-publish {
|
|
43
|
+
width: 72px;
|
|
44
|
+
height: 30px;
|
|
45
|
+
margin-right: 21px;
|
|
46
|
+
background-color: #1572C2;
|
|
47
|
+
border-radius: 4px;
|
|
48
|
+
color: #FFFFFF !important;
|
|
49
|
+
text-transform: uppercase;
|
|
50
|
+
text-decoration: none !important;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
outline: none;
|
|
53
|
+
|
|
54
|
+
&:hover {
|
|
55
|
+
background-color: #065c9d;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&-close {
|
|
60
|
+
width: 42px;
|
|
61
|
+
height: 22px;
|
|
62
|
+
margin-right: 21px;
|
|
63
|
+
color: #000000 !important;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
text-transform: uppercase;
|
|
66
|
+
text-decoration: none !important;
|
|
67
|
+
}
|
|
21
68
|
}
|
|
22
69
|
|
|
23
70
|
.text-black {
|
|
@@ -28,13 +75,6 @@ $toolbar-background-color: #fff;
|
|
|
28
75
|
cursor: default !important;
|
|
29
76
|
}
|
|
30
77
|
|
|
31
|
-
.btn-autosave {
|
|
32
|
-
display: flex;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
align-items: center;
|
|
35
|
-
border-radius: 4px !important;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
78
|
.btn-ellipsis {
|
|
39
79
|
border-top-left-radius: 4px !important;
|
|
40
80
|
border-bottom-left-radius: 4px !important;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="top-rail-container">
|
|
3
|
+
<ValidateIssue
|
|
4
|
+
v-show="isOpenIssue"
|
|
5
|
+
:number-of-errors="numberOfErrors"
|
|
6
|
+
@openPanel="handleOpenPanel"
|
|
7
|
+
/>
|
|
8
|
+
|
|
9
|
+
<ValidateButton @openIssue="handleOpenIssue" />
|
|
10
|
+
|
|
11
|
+
<ValidatePanel
|
|
12
|
+
v-show="isOpenIssue && isOpenPanel"
|
|
13
|
+
:error-list="errorList"
|
|
14
|
+
:warnings="warnings"
|
|
15
|
+
/>
|
|
16
|
+
<slot />
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
import store from '@/store';
|
|
22
|
+
import { ValidateButton, ValidateIssue, ValidatePanel } from '@/components/topRail/validateControl';
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
components: {
|
|
26
|
+
ValidateButton,
|
|
27
|
+
ValidateIssue,
|
|
28
|
+
ValidatePanel,
|
|
29
|
+
},
|
|
30
|
+
props: {
|
|
31
|
+
validationErrors: {
|
|
32
|
+
type: Object,
|
|
33
|
+
required: true,
|
|
34
|
+
},
|
|
35
|
+
warnings: {
|
|
36
|
+
type: Array,
|
|
37
|
+
required: true,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
data() {
|
|
41
|
+
return {
|
|
42
|
+
isOpenIssue: false,
|
|
43
|
+
isOpenPanel: false,
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
computed: {
|
|
47
|
+
errorList() {
|
|
48
|
+
// Get a formatted error list to show in the issue panel
|
|
49
|
+
return Object.entries(this.validationErrors)
|
|
50
|
+
.flatMap(([errorKey, errors]) => (
|
|
51
|
+
errors.flatMap(error => ({
|
|
52
|
+
...error,
|
|
53
|
+
errorKey,
|
|
54
|
+
...{ 'errorId': `${error.id}_${error.message.split(' ').join('_')}` },
|
|
55
|
+
}))
|
|
56
|
+
));
|
|
57
|
+
},
|
|
58
|
+
numberOfErrors() {
|
|
59
|
+
// Get the number of errors
|
|
60
|
+
return this.errorList.length + this.warnings.length;
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
watch: {
|
|
64
|
+
numberOfErrors(newValue) {
|
|
65
|
+
// Checks the number of errors, if it is "0" hides the panel errors
|
|
66
|
+
if (newValue === 0) {
|
|
67
|
+
this.isOpenPanel = false;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
methods: {
|
|
72
|
+
/**
|
|
73
|
+
* Show/hide the issue button
|
|
74
|
+
* @param {boolean} value
|
|
75
|
+
*/
|
|
76
|
+
handleOpenIssue(value) {
|
|
77
|
+
this.isOpenIssue = value;
|
|
78
|
+
// Set the auto-validate value store
|
|
79
|
+
store.commit('setAutoValidate', this.isOpenIssue);
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Show/hide the issue panel
|
|
83
|
+
* @param {boolean} value
|
|
84
|
+
*/
|
|
85
|
+
handleOpenPanel(value) {
|
|
86
|
+
this.isOpenPanel = value;
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style scoped lang="scss" src="./topRail.scss"></style>
|