@processmaker/modeler 1.31.0 → 1.32.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.
Files changed (40) hide show
  1. package/dist/.DS_Store +0 -0
  2. package/dist/img/issue-close.5d1630e6.svg +3 -0
  3. package/dist/img/issue-item.3187f291.svg +3 -0
  4. package/dist/img/issue-open.707390b4.svg +4 -0
  5. package/dist/img/validate-close.09ace97a.svg +4 -0
  6. package/dist/img/validate-open.b0ecf74e.svg +4 -0
  7. package/dist/modeler.common.js +1074 -398
  8. package/dist/modeler.common.js.map +1 -1
  9. package/dist/modeler.umd.js +1074 -398
  10. package/dist/modeler.umd.js.map +1 -1
  11. package/dist/modeler.umd.min.js +4 -4
  12. package/dist/modeler.umd.min.js.map +1 -1
  13. package/package.json +2 -2
  14. package/src/.DS_Store +0 -0
  15. package/src/ModelerApp.vue +0 -9
  16. package/src/assets/topRail/issue-close.svg +3 -0
  17. package/src/assets/topRail/issue-item.svg +3 -0
  18. package/src/assets/topRail/issue-open.svg +4 -0
  19. package/src/assets/topRail/validate-close.svg +4 -0
  20. package/src/assets/topRail/validate-open.svg +4 -0
  21. package/src/components/hotkeys/escKey.js +20 -0
  22. package/src/components/hotkeys/main.js +4 -2
  23. package/src/components/modeler/Modeler.vue +3 -0
  24. package/src/components/modeler/ModelerReadonly.vue +21 -6
  25. package/src/components/railBottom/controls/Controls.vue +7 -75
  26. package/src/components/rails/explorer-rail/nodeTypesLoop/nodeTypesLoop.vue +2 -72
  27. package/src/components/toolbar/ToolBar.vue +23 -14
  28. package/src/components/topRail/TopRail.vue +91 -0
  29. package/src/components/topRail/topRail.scss +6 -0
  30. package/src/components/topRail/validateControl/index.js +3 -0
  31. package/src/components/topRail/validateControl/validateButton/ValidateButton.vue +38 -0
  32. package/src/components/topRail/validateControl/validateButton/validateButton.scss +25 -0
  33. package/src/components/topRail/validateControl/validateIssue/ValidateIssue.vue +59 -0
  34. package/src/components/topRail/validateControl/validateIssue/validateIssue.scss +54 -0
  35. package/src/components/topRail/validateControl/validatePanel/ValidatePanel.vue +51 -0
  36. package/src/components/topRail/validateControl/validatePanel/validatePanel.scss +67 -0
  37. package/src/mixins/clickAndDrop.js +100 -0
  38. package/src/mixins/highlightConfig.js +52 -8
  39. package/src/mixins/linkConfig.js +6 -2
  40. package/src/nodeTypesStore.js +15 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.31.0",
3
+ "version": "1.32.0",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "open-cypress": "TZ=UTC cypress open",
@@ -74,7 +74,7 @@
74
74
  "@babel/core": "^7.12.7",
75
75
  "@cypress/code-coverage": "^1.14.0",
76
76
  "@panter/vue-i18next": "^0.15.2",
77
- "@processmaker/processmaker-bpmn-moddle": "0.13.0",
77
+ "@processmaker/processmaker-bpmn-moddle": "0.14.0",
78
78
  "@types/jest": "^24.9.1",
79
79
  "@vue/babel-preset-app": "^5.0.4",
80
80
  "@vue/cli-plugin-babel": "^4.5.9",
package/src/.DS_Store CHANGED
Binary file
@@ -18,14 +18,6 @@
18
18
  <b-card-body class="overflow-hidden position-relative p-0 vh-100">
19
19
  <modeler ref="modeler" @set-xml-manager="xmlManager = $event" @validate="validationErrors = $event" @warnings="warnings = $event" :decorations="decorations" />
20
20
  </b-card-body>
21
- <!-- TODO remove me when the time comes -->
22
- <!-- <validation-status ref="validationStatus"-->
23
- <!-- :validation-errors="validationErrors"-->
24
- <!-- :warnings="warnings"-->
25
- <!-- :xml-manager="xmlManager"-->
26
- <!-- >-->
27
- <!-- <component v-for="(component, index) in validationBar" :key="index" :is="component" />-->
28
- <!-- </validation-status>-->
29
21
  </b-card>
30
22
 
31
23
  <b-modal
@@ -64,7 +56,6 @@ export default {
64
56
  },
65
57
  data() {
66
58
  return {
67
- validationBar: [],
68
59
  decorations: {
69
60
  borderOutline: {},
70
61
  },
@@ -0,0 +1,3 @@
1
+ <svg width="8" height="12" viewBox="0 0 8 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M0.693905 5.53599L6.00816 0.222004C6.26437 -0.0342065 6.68 -0.0342065 6.93621 0.222004L7.55609 0.841887C7.81203 1.09782 7.8123 1.51236 7.55719 1.76884L3.34543 6.00001L7.55691 10.2315C7.8123 10.4879 7.81176 10.9025 7.55582 11.1584L6.93594 11.7783C6.67973 12.0345 6.2641 12.0345 6.00789 11.7783L0.693905 6.46404C0.437694 6.20782 0.437694 5.7922 0.693905 5.53599Z" />
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M6 0.1875C2.78906 0.1875 0.1875 2.78906 0.1875 6C0.1875 9.21094 2.78906 11.8125 6 11.8125C9.21094 11.8125 11.8125 9.21094 11.8125 6C11.8125 2.78906 9.21094 0.1875 6 0.1875ZM8.85 7.52578C8.96016 7.63594 8.96016 7.81406 8.85 7.92422L7.92188 8.85C7.81172 8.96016 7.63359 8.96016 7.52344 8.85L6 7.3125L4.47422 8.85C4.36406 8.96016 4.18594 8.96016 4.07578 8.85L3.15 7.92188C3.03984 7.81172 3.03984 7.63359 3.15 7.52344L4.6875 6L3.15 4.47422C3.03984 4.36406 3.03984 4.18594 3.15 4.07578L4.07812 3.14766C4.18828 3.0375 4.36641 3.0375 4.47656 3.14766L6 4.6875L7.52578 3.15C7.63594 3.03984 7.81406 3.03984 7.92422 3.15L8.85234 4.07812C8.9625 4.18828 8.9625 4.36641 8.85234 4.47656L7.3125 6L8.85 7.52578Z" />
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="15" height="8" viewBox="0 0 15 8" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M6.96966 7.43098L0.896437 2.11689C0.603531 1.8606 0.603531 1.44508 0.896437 1.18881L1.60478 0.569014C1.89719 0.313159 2.37109 0.312666 2.66419 0.56792L7.5 4.77943L12.3358 0.56792C12.6289 0.312666 13.1028 0.313159 13.3952 0.569014L14.1035 1.18881C14.3964 1.44511 14.3964 1.86062 14.1035 2.11689L8.03034 7.43098C7.73744 7.68725 7.26256 7.68725 6.96966 7.43098Z" />
3
+ </svg>
4
+
@@ -0,0 +1,4 @@
1
+ <svg width="18" height="16" viewBox="0 0 18 16" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.81873 8C1.81873 4.39289 4.74287 1.46875 8.34998 1.46875C9.54059 1.46875 10.6551 1.78679 11.6152 2.34215C11.899 2.50635 12.2622 2.40935 12.4264 2.1255C12.5906 1.84166 12.4936 1.47844 12.2098 1.31424C11.0739 0.657144 9.75491 0.28125 8.34998 0.28125C4.08703 0.28125 0.631226 3.73705 0.631226 8C0.631226 12.2629 4.08703 15.7188 8.34998 15.7188C12.6129 15.7188 16.0687 12.2629 16.0687 8C16.0687 7.67208 15.8029 7.40625 15.475 7.40625C15.1471 7.40625 14.8812 7.67208 14.8812 8C14.8812 11.6071 11.9571 14.5312 8.34998 14.5312C4.74287 14.5312 1.81873 11.6071 1.81873 8Z" />
3
+ <path d="M17.0823 2.48234C17.3142 2.25047 17.3142 1.87453 17.0823 1.64266C16.8504 1.41078 16.4745 1.41078 16.2426 1.64266L8.34998 9.53531L5.20732 6.39266C4.97545 6.16078 4.5995 6.16078 4.36763 6.39266C4.13576 6.62453 4.13576 7.00047 4.36763 7.23234L7.93013 10.7948C8.162 11.0267 8.53795 11.0267 8.76982 10.7948L17.0823 2.48234Z" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="19" height="18" viewBox="0 0 19 18" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.80589 9C1.80589 13.2502 5.25137 16.6957 9.50156 16.6957C13.7517 16.6957 17.1972 13.2502 17.1972 9C17.1972 4.75024 13.7524 1.30498 9.50272 1.30435C9.14254 1.30429 8.85058 1.01226 8.85063 0.652077C8.85069 0.291891 9.14273 -5.34573e-05 9.50291 7.34216e-09C14.4729 0.000737734 18.5016 4.02995 18.5016 9C18.5016 13.9706 14.4721 18 9.50156 18C4.53099 18 0.501541 13.9706 0.501541 9C0.501541 7.11913 1.08174 5.32928 2.12769 3.83814L1.38144 3.18945C0.988324 2.84772 1.13471 2.20576 1.63712 2.06822L4.47212 1.29212C4.92098 1.16925 5.3504 1.54254 5.29118 2.00413L4.9172 4.91955C4.85093 5.43621 4.23559 5.67051 3.84247 5.32877L3.11835 4.6993C2.27288 5.95119 1.80589 7.43811 1.80589 9Z" />
3
+ <path d="M12.7244 5.87213C13.0539 5.54262 13.5881 5.54262 13.9176 5.87213C14.2431 6.19759 14.2471 6.72279 13.9296 7.05316L9.43837 12.6672C9.43189 12.6753 9.42496 12.683 9.41763 12.6904C9.08812 13.0199 8.55389 13.0199 8.22438 12.6904L5.24713 9.71312C4.91762 9.38361 4.91762 8.84938 5.24713 8.51988C5.57663 8.19037 6.11087 8.19037 6.44037 8.51988L8.79558 10.8751L12.702 5.89737C12.709 5.88851 12.7164 5.88009 12.7244 5.87213Z" />
4
+ </svg>
@@ -0,0 +1,20 @@
1
+ import nodeTypesStore from '@/nodeTypesStore';
2
+
3
+ export default {
4
+ methods: {
5
+ escapeKeyHandler(event) {
6
+ if (this.selectedNode) {
7
+ event.preventDefault();
8
+ window.ProcessMaker.EventBus.$emit('custom-pointerclick', event);
9
+ }
10
+ },
11
+ },
12
+ computed: {
13
+ selectedNode() {
14
+ return nodeTypesStore.getters.getSelectedNode;
15
+ },
16
+ movedElement() {
17
+ return nodeTypesStore.getters.getGhostNode;
18
+ },
19
+ },
20
+ };
@@ -1,10 +1,11 @@
1
1
  import ZoomInOut from './zoomInOut';
2
2
  import CopyPaste from './copyPaste.js';
3
- import store from '@/store';
4
3
  import moveShapeByKeypress from './moveWithArrowKeys';
4
+ import EscKey from './escKey';
5
+ import store from '@/store';
5
6
 
6
7
  export default {
7
- mixins: [ZoomInOut, CopyPaste],
8
+ mixins: [ZoomInOut, CopyPaste, EscKey],
8
9
  computed: {
9
10
  clientLeftPaper() {
10
11
  return store.getters.clientLeftPaper;
@@ -19,6 +20,7 @@ export default {
19
20
  // Pass event to all handlers
20
21
  this.zoomInOutHandler(event, options);
21
22
  this.copyPasteHandler(event, options);
23
+ this.escapeKeyHandler(event);
22
24
  },
23
25
  keyupListener(event) {
24
26
  if (event.code === 'Space') {
@@ -7,6 +7,9 @@
7
7
  :paper-manager="paperManager"
8
8
  :breadcrumb-data="breadcrumbData"
9
9
  :panelsCompressed="panelsCompressed"
10
+ :validation-errors="validationErrors"
11
+ :warnings="allWarnings"
12
+ :xml-manager="xmlManager"
10
13
  @load-xml="loadXML"
11
14
  @toggle-panels-compressed="panelsCompressed = !panelsCompressed"
12
15
  @toggle-mini-map-open="miniMapOpen = $event"
@@ -31,7 +31,6 @@
31
31
  :paper="paper"
32
32
  :node="node"
33
33
  :id="node.id"
34
- :highlighted="highlightedNodes.includes(node)"
35
34
  :border-outline="borderOutline(node.id)"
36
35
  :collaboration="collaboration"
37
36
  :process-node="processNode"
@@ -40,11 +39,14 @@
40
39
  :moddle="moddle"
41
40
  :nodeRegistry="nodeRegistry"
42
41
  :root-elements="definitions.get('rootElements')"
43
- :isRendering="isRendering"
44
42
  :paperManager="paperManager"
45
43
  :auto-validate="autoValidate"
46
- :is-active="node === activeNode"
47
44
  :node-id-generator="nodeIdGenerator"
45
+ :highlighted="highlightedNodes.includes(node)"
46
+ :is-active="node === activeNode"
47
+ :is-rendering="isRendering"
48
+ :is-completed="requestCompletedNodes.includes(node.definition.id)"
49
+ :is-in-progress="requestInProgressNodes.includes(node.definition.id)"
48
50
  @add-node="addNode"
49
51
  @set-cursor="cursor = $event"
50
52
  @set-pool-target="poolTarget = $event"
@@ -132,6 +134,14 @@ export default {
132
134
  type: Boolean,
133
135
  default: true,
134
136
  },
137
+ requestCompletedNodes: {
138
+ type: Array,
139
+ default: () => [],
140
+ },
141
+ requestInProgressNodes: {
142
+ type: Array,
143
+ default: () => [],
144
+ },
135
145
  },
136
146
  data() {
137
147
  return {
@@ -215,7 +225,6 @@ export default {
215
225
  canvasScale(canvasScale) {
216
226
  this.paperManager.scale = canvasScale;
217
227
  },
218
-
219
228
  },
220
229
  computed: {
221
230
  showControls() {
@@ -926,10 +935,16 @@ export default {
926
935
  return;
927
936
  }
928
937
 
929
- // ignore click event if the user is Grabbing the paper
930
- if (this.isGrabbing) return;
938
+ // ignore click event if the user is grabbing the paper.
939
+ if (this.isGrabbing) {
940
+ return;
941
+ }
931
942
 
932
943
  shape.component.$emit('click', event);
944
+ this.$emit('click', {
945
+ event,
946
+ node: this.highlightedNode.definition,
947
+ });
933
948
  });
934
949
 
935
950
  this.paperManager.addEventHandler('cell:pointerdown', ({ model: shape }, event) => {
@@ -5,7 +5,7 @@
5
5
  >
6
6
  <li
7
7
  v-for="item in controls"
8
- :class="['control-item', {'active': selectedItem === item.type}]"
8
+ :class="['control-item', {'active': selectedItem && (selectedItem.type === item.type)}]"
9
9
  :id="item.id"
10
10
  :key="item.id"
11
11
  @click.stop="onClickHandler($event, item)"
@@ -35,6 +35,7 @@
35
35
  import InlineSvg from 'vue-inline-svg';
36
36
  import nodeTypesStore from '@/nodeTypesStore';
37
37
  import SubmenuPopper from './SubmenuPopper/SubmenuPopper.vue';
38
+ import clickAndDrop from '@/mixins/clickAndDrop';
38
39
 
39
40
  export default ({
40
41
  components: {
@@ -44,29 +45,15 @@ export default ({
44
45
  props: {
45
46
  nodeTypes: Array,
46
47
  },
48
+ mixins: [clickAndDrop],
47
49
  data() {
48
50
  return {
49
51
  plusIcon: require('@/assets/railBottom/plus.svg'),
50
- wasClicked: false,
51
- element: null,
52
- selectedItem: null,
53
- selectedSubmenuItem: null,
54
- xOffset: 0,
55
- yOffset: 0,
56
- movedElement: null,
57
- isDragging: false,
58
- helperStyles: {
59
- backgroundColor:'#ffffff',
60
- position: 'absolute',
61
- height: '40px',
62
- width: '40px',
63
- zIndex: '10',
64
- opacity: '0.5',
65
- pointerEvents: 'none',
66
- },
67
- popperType: null,
68
52
  };
69
53
  },
54
+ created() {
55
+ nodeTypesStore.dispatch('getUserPinnedObjects');
56
+ },
70
57
  computed: {
71
58
  controls() {
72
59
  return nodeTypesStore.getters.getPinnedNodeTypes;
@@ -79,69 +66,14 @@ export default ({
79
66
  clickToSubmenuHandler(data){
80
67
  window.ProcessMaker.EventBus.$off('custom-pointerclick');
81
68
  this.wasClicked = false;
82
- this.parent = this.element;
69
+ this.parent = this.selectedItem;
83
70
  this.selectedSubmenuItem = data.control.type;
84
71
  this.onClickHandler(data.event, data.control);
85
72
  },
86
- onClickHandler(event, control) {
87
- this.createDraggingHelper(event, control);
88
- document.addEventListener('mousemove', this.setDraggingPosition);
89
- this.setDraggingPosition(event);
90
- this.wasClicked = true;
91
- this.element = control;
92
- this.$emit('onSetCursor', 'crosshair');
93
- if (!this.parent) {
94
- this.selectedItem = control.type;
95
- this.popperType = control.type;
96
- }
97
- window.ProcessMaker.EventBus.$on('custom-pointerclick', message => {
98
- window.ProcessMaker.EventBus.$off('custom-pointerclick');
99
- document.removeEventListener('mousemove', this.setDraggingPosition);
100
- if (this.movedElement) {
101
- document.body.removeChild(this.movedElement);
102
- }
103
- this.popperType = null;
104
- this.selectedSubmenuItem = null;
105
- this.selectedItem = null;
106
- this.movedElement = null;
107
- this.onCreateElement(message);
108
- });
109
- },
110
- onCreateElement(event){
111
- if (this.wasClicked && this.element) {
112
- if (this.parent) {
113
- this.parent = null;
114
- }
115
- this.$emit('onCreateElement', { event, control: this.element });
116
- this.$emit('onSetCursor', 'none');
117
- event.preventDefault();
118
- this.wasClicked = false;
119
- }
120
- },
121
- setDraggingPosition({ pageX, pageY }) {
122
- this.movedElement.style.left = `${pageX}px`;
123
- this.movedElement.style.top = `${pageY}px`;
124
- },
125
73
  toggleExplorer() {
126
74
  nodeTypesStore.commit('toggleExplorer');
127
75
  nodeTypesStore.commit('clearFilteredNodes');
128
76
  },
129
- createDraggingHelper(event, control) {
130
- if (this.movedElement) {
131
- document.removeEventListener('mousemove', this.setDraggingPosition);
132
- document.body.removeChild(this.movedElement);
133
- this.movedElement = null;
134
- }
135
- const sourceElement = event.target;
136
- this.movedElement = document.createElement('img');
137
- Object.keys(this.helperStyles).forEach((property) => {
138
- this.movedElement.style[property] = this.helperStyles[property];
139
- });
140
- this.movedElement.src = control.icon;
141
- document.body.appendChild(this.movedElement);
142
- this.xOffset = event.clientX - sourceElement.getBoundingClientRect().left;
143
- this.yOffset = event.clientY - sourceElement.getBoundingClientRect().top;
144
- },
145
77
  },
146
78
  });
147
79
  </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() {
@@ -40,63 +27,6 @@ export default {
40
27
  addPin(object) {
41
28
  return nodeTypesStore.dispatch('addUserPinnedObject', object);
42
29
  },
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
30
  },
101
31
  computed: {
102
32
  pinnedObjects() {
@@ -4,9 +4,13 @@
4
4
  aria-label="Toolbar" :class="{ 'ignore-pointer': canvasDragPosition }"
5
5
  >
6
6
  <breadcrumb :breadcrumb-data="breadcrumbData" />
7
- <div class="mr-3">
8
- <align-buttons @save-state="$emit('save-state')" />
7
+ <div class="d-flex mr-3">
8
+ <TopRail
9
+ :validation-errors="validationErrors"
10
+ :warnings="warnings"
11
+ />
9
12
 
13
+ <align-buttons @save-state="$emit('save-state')" />
10
14
 
11
15
  <div class="btn-group btn-group-sm mr-2" role="group" aria-label="Additional controls">
12
16
  <b-button
@@ -78,23 +82,28 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
78
82
  import { faCompress, faExpand, faMapMarked, faMinus, faPlus, faRedo, faUndo, faSave, faCheckCircle, faSpinner } from '@fortawesome/free-solid-svg-icons';
79
83
  import undoRedoStore from '@/undoRedoStore';
80
84
  import Breadcrumb from '@/components/toolbar/breadcrumb/Breadcrumb';
85
+ import TopRail from '@/components/topRail/TopRail.vue';
81
86
  import AlignButtons from '@/components/toolbar/alignButtons/AlignButtons';
82
87
 
83
88
  export default {
84
89
  name: 'tool-bar',
85
- components: { Breadcrumb, FontAwesomeIcon, AlignButtons },
86
- props: {
87
- canvasDragPosition: {},
88
- cursor: {},
89
- paperManager: {},
90
- isRendering: {
91
- type: Boolean,
92
- },
93
- breadcrumbData: {
94
- type: Array,
95
- },
96
- panelsCompressed: Boolean,
90
+ components: {
91
+ Breadcrumb,
92
+ TopRail,
93
+ FontAwesomeIcon,
94
+ AlignButtons,
97
95
  },
96
+ props: [
97
+ 'canvasDragPosition',
98
+ 'cursor',
99
+ 'paperManager',
100
+ 'isRendering',
101
+ 'breadcrumbData',
102
+ 'panelsCompressed',
103
+ 'validationErrors',
104
+ 'warnings',
105
+ 'xmlManager',
106
+ ],
98
107
  watch: {
99
108
  miniMapOpen(isOpen) {
100
109
  this.$emit('toggle-mini-map-open', isOpen);
@@ -0,0 +1,91 @@
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
+ </div>
17
+ </template>
18
+
19
+ <script>
20
+ import store from '@/store';
21
+ import { ValidateButton, ValidateIssue, ValidatePanel } from '@/components/topRail/validateControl';
22
+
23
+ export default {
24
+ components: {
25
+ ValidateButton,
26
+ ValidateIssue,
27
+ ValidatePanel,
28
+ },
29
+ props: {
30
+ validationErrors: {
31
+ type: Object,
32
+ required: true,
33
+ },
34
+ warnings: {
35
+ type: Array,
36
+ required: true,
37
+ },
38
+ },
39
+ data() {
40
+ return {
41
+ isOpenIssue: false,
42
+ isOpenPanel: false,
43
+ };
44
+ },
45
+ computed: {
46
+ errorList() {
47
+ // Get a formatted error list to show in the issue panel
48
+ return Object.entries(this.validationErrors)
49
+ .flatMap(([errorKey, errors]) => (
50
+ errors.flatMap(error => ({
51
+ ...error,
52
+ errorKey,
53
+ ...{ 'errorId': `${error.id}_${error.message.split(' ').join('_')}` },
54
+ }))
55
+ ));
56
+ },
57
+ numberOfErrors() {
58
+ // Get the number of errors
59
+ return this.errorList.length + this.warnings.length;
60
+ },
61
+ },
62
+ watch: {
63
+ numberOfErrors(newValue) {
64
+ // Checks the number of errors, if it is "0" hides the panel errors
65
+ if (newValue === 0) {
66
+ this.isOpenPanel = false;
67
+ }
68
+ },
69
+ },
70
+ methods: {
71
+ /**
72
+ * Show/hide the issue button
73
+ * @param {boolean} value
74
+ */
75
+ handleOpenIssue(value) {
76
+ this.isOpenIssue = value;
77
+ // Set the auto-validate value store
78
+ store.commit('setAutoValidate', this.isOpenIssue);
79
+ },
80
+ /**
81
+ * Show/hide the issue panel
82
+ * @param {boolean} value
83
+ */
84
+ handleOpenPanel(value) {
85
+ this.isOpenPanel = value;
86
+ },
87
+ },
88
+ };
89
+ </script>
90
+
91
+ <style scoped lang="scss" src="./topRail.scss"></style>
@@ -0,0 +1,6 @@
1
+ .top-rail-container {
2
+ position: relative;
3
+ display: flex;
4
+ align-items: center;
5
+ padding: 0px 8px;
6
+ }
@@ -0,0 +1,3 @@
1
+ export { default as ValidateButton } from './validateButton/ValidateButton.vue';
2
+ export { default as ValidateIssue } from './validateIssue/ValidateIssue.vue';
3
+ export { default as ValidatePanel } from './validatePanel/ValidatePanel.vue';
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <button
3
+ type="button"
4
+ @click.prevent="handleOpen"
5
+ :class="['validate-button', { 'validate-button-active': isOpen }]"
6
+ >
7
+ <inline-svg :src="isOpen ? validateOpenIcon : validateCloseIcon" />
8
+ </button>
9
+ </template>
10
+
11
+ <script>
12
+ import InlineSvg from 'vue-inline-svg';
13
+
14
+ export default {
15
+ components: {
16
+ InlineSvg,
17
+ },
18
+ data() {
19
+ return {
20
+ isOpen: false,
21
+ validateCloseIcon: require('@/assets/topRail/validate-close.svg'),
22
+ validateOpenIcon: require('@/assets/topRail/validate-open.svg'),
23
+ };
24
+ },
25
+ methods: {
26
+ /**
27
+ * Show/hide issue button
28
+ */
29
+ handleOpen() {
30
+ this.isOpen = !this.isOpen;
31
+
32
+ this.$emit('openIssue', this.isOpen);
33
+ },
34
+ },
35
+ };
36
+ </script>
37
+
38
+ <style scoped lang="scss" src="./validateButton.scss"></style>
@@ -0,0 +1,25 @@
1
+ .validate-button {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+ width: 32px;
6
+ height: 32px;
7
+ background-color: #EBEEF2;
8
+ border: 0 none;
9
+ border-radius: 4px;
10
+ transition: background-color 0.3s ease;
11
+
12
+ & > svg {
13
+ width: 18px;
14
+ fill: #212529;
15
+ }
16
+
17
+ &:active,
18
+ &-active {
19
+ background-color: #104A75;
20
+
21
+ & > svg {
22
+ fill: #ffffff;
23
+ }
24
+ }
25
+ }