@itfin/components 1.3.21 → 1.3.23
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/package.json +3 -1
- package/src/assets/scss/_dark-theme.scss +1 -0
- package/src/assets/scss/main.scss +1 -0
- package/src/components/dropdown/Dropdown.vue +2 -2
- package/src/components/dropdown/index.stories.js +3 -5
- package/src/components/editor/Editor.vue +6 -1
- package/src/components/editor/index.stories.js +0 -226
- package/src/components/editor/tools/bpmn/bpmn.js +187 -0
- package/src/components/editor/tools/bpmn/bpmn.scss +63 -0
- package/src/components/editor/tools/drawing/drawing.js +1 -1
- package/src/components/editor/tools/drawing/excalidraw.production.min.js +2 -0
- package/src/components/filter/FilterBadge.vue +61 -0
- package/src/components/filter/Rule.vue +27 -5
- package/src/components/filter/RuleGroup.vue +24 -14
- package/src/components/filter/constants.js +19 -0
- package/src/components/filter/index.stories.js +7 -1
- package/src/components/table/TableGroup.vue +2 -2
- package/src/components/table/TableHeader.vue +31 -33
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import './bpmn.scss';
|
|
2
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
3
|
+
import 'bpmn-js/dist/assets/bpmn-js.css';
|
|
4
|
+
import 'bpmn-js/dist/assets/diagram-js.css';
|
|
5
|
+
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
|
6
|
+
|
|
7
|
+
const icon = '<svg height="24" width="24" viewBox="0 0 2048 2048" xmlns="http://www.w3.org/2000/svg"><path d="m96-593.63783v1280h1856v-1280zm1756 97.69925v1091.54297h-1372v-1091.54103l1372-.002zm-1660 .002 192-.00021v1091.54108l-192 .00021z" transform="translate(0 995.63783)"/></svg>';
|
|
8
|
+
const xml = '<?xml version="1.0" encoding="UTF-8"?>\n' +
|
|
9
|
+
'<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn">\n' +
|
|
10
|
+
' <bpmn2:process id="Process_1" isExecutable="false">\n' +
|
|
11
|
+
' <bpmn2:startEvent id="StartEvent_1"/>\n' +
|
|
12
|
+
' </bpmn2:process>\n' +
|
|
13
|
+
' <bpmndi:BPMNDiagram id="BPMNDiagram_1">\n' +
|
|
14
|
+
' <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">\n' +
|
|
15
|
+
' <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\n' +
|
|
16
|
+
' <dc:Bounds height="36.0" width="36.0" x="412.0" y="240.0"/>\n' +
|
|
17
|
+
' </bpmndi:BPMNShape>\n' +
|
|
18
|
+
' </bpmndi:BPMNPlane>\n' +
|
|
19
|
+
' </bpmndi:BPMNDiagram>\n' +
|
|
20
|
+
'</bpmn2:definitions>';
|
|
21
|
+
|
|
22
|
+
export default class Bpmn {
|
|
23
|
+
data = null;
|
|
24
|
+
readOnly = false;
|
|
25
|
+
|
|
26
|
+
static get sanitize(){
|
|
27
|
+
return {
|
|
28
|
+
svg: true,
|
|
29
|
+
files: true,
|
|
30
|
+
caption: {} // only tags from Inline Toolbar
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Allow to use this tool in read only mode
|
|
36
|
+
*/
|
|
37
|
+
static get isReadOnlySupported() {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
constructor({ data, readOnly }){
|
|
42
|
+
this.data = data;
|
|
43
|
+
this.readOnly = readOnly;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static get toolbox() {
|
|
47
|
+
return {
|
|
48
|
+
title: 'BPMN',
|
|
49
|
+
icon
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render(){
|
|
54
|
+
const wrapper = createWrapper(this.data, this.readOnly);
|
|
55
|
+
if (!this.readOnly) {
|
|
56
|
+
wrapper.classList.remove('readonly');
|
|
57
|
+
wrapper.addEventListener('dblclick', async () => {
|
|
58
|
+
const modal = document.createElement('div');
|
|
59
|
+
modal.classList.add('itf-modal');
|
|
60
|
+
modal.classList.add('modal');
|
|
61
|
+
modal.classList.add('fade');
|
|
62
|
+
modal.classList.add('editorjs-bpmn-modal');
|
|
63
|
+
const modalDialog = document.createElement('div');
|
|
64
|
+
modalDialog.classList.add('modal-dialog');
|
|
65
|
+
modalDialog.classList.add('modal-fullscreen');
|
|
66
|
+
const modalContent = document.createElement('div');
|
|
67
|
+
modalContent.classList.add('modal-content');
|
|
68
|
+
const modalHeader = document.createElement('div');
|
|
69
|
+
modalHeader.classList.add('modal-header');
|
|
70
|
+
const modalTitle = document.createElement('h5');
|
|
71
|
+
modalTitle.classList.add('modal-title');
|
|
72
|
+
modalTitle.textContent = 'BPMN Editor';
|
|
73
|
+
modalHeader.appendChild(modalTitle);
|
|
74
|
+
const btnHolder = document.createElement('div');
|
|
75
|
+
btnHolder.classList.add('d-flex');
|
|
76
|
+
const modalSaveBtn = document.createElement('button');
|
|
77
|
+
modalSaveBtn.classList.add('btn');
|
|
78
|
+
modalSaveBtn.classList.add('btn-primary');
|
|
79
|
+
modalSaveBtn.classList.add('itf-button');
|
|
80
|
+
modalSaveBtn.textContent = 'Save & Close';
|
|
81
|
+
const modalCancelBtn = document.createElement('button');
|
|
82
|
+
modalCancelBtn.classList.add('btn');
|
|
83
|
+
modalCancelBtn.classList.add('btn-secondary');
|
|
84
|
+
modalCancelBtn.classList.add('itf-button');
|
|
85
|
+
modalCancelBtn.classList.add('me-2');
|
|
86
|
+
modalCancelBtn.textContent = 'Cancel';
|
|
87
|
+
btnHolder.appendChild(modalCancelBtn);
|
|
88
|
+
btnHolder.appendChild(modalSaveBtn);
|
|
89
|
+
modalHeader.appendChild(modalTitle);
|
|
90
|
+
modalHeader.appendChild(btnHolder);
|
|
91
|
+
modalContent.appendChild(modalHeader);
|
|
92
|
+
const modalBody = document.createElement('div');
|
|
93
|
+
modalBody.classList.add('modal-body');
|
|
94
|
+
const frame = document.createElement('div');
|
|
95
|
+
modalBody.appendChild(frame);
|
|
96
|
+
modalContent.appendChild(modalBody);
|
|
97
|
+
modalDialog.appendChild(modalContent);
|
|
98
|
+
modal.appendChild(modalDialog);
|
|
99
|
+
document.body.appendChild(modal);
|
|
100
|
+
const {default: Modal} = await import('../../../modal/modalSrc');
|
|
101
|
+
const modalEl = new Modal(modal, {context: document.body, backdrop: 'static'});
|
|
102
|
+
modalEl.show();
|
|
103
|
+
modal.addEventListener('hidden.bs.modal', () => {
|
|
104
|
+
document.body.removeChild(modal);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
frame.classList.add('modal-body-content');
|
|
108
|
+
|
|
109
|
+
let modeler;
|
|
110
|
+
setTimeout(async () => {
|
|
111
|
+
const { default: BpmnModeler } = await import('bpmn-js/dist/bpmn-modeler.production.min');
|
|
112
|
+
modeler = new BpmnModeler({
|
|
113
|
+
container: frame,
|
|
114
|
+
keyboard: {
|
|
115
|
+
bindTo: window
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await modeler.importXML(this.data?.xml || xml);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
console.error('error loading BPMN 2.0 XML', err);
|
|
123
|
+
}
|
|
124
|
+
}, 500)
|
|
125
|
+
|
|
126
|
+
modalSaveBtn.addEventListener('click', async () => {
|
|
127
|
+
this.data = {
|
|
128
|
+
svg: (await modeler.saveSVG())?.svg,
|
|
129
|
+
xml: (await modeler.saveXML({ format: true }))?.xml
|
|
130
|
+
};
|
|
131
|
+
if (this.data.svg) {
|
|
132
|
+
createSvg(wrapper, this.data, this.readOnly);
|
|
133
|
+
}
|
|
134
|
+
modalEl.hide();
|
|
135
|
+
});
|
|
136
|
+
modalCancelBtn.addEventListener('click', () => {
|
|
137
|
+
modalEl.hide();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
wrapper.classList.add('readonly');
|
|
142
|
+
}
|
|
143
|
+
return wrapper;
|
|
144
|
+
|
|
145
|
+
function createWrapper(data, readOnly) {
|
|
146
|
+
const wrapper = document.createElement('div');
|
|
147
|
+
wrapper.classList.add('editorjs-bpmn');
|
|
148
|
+
if (data.svg) {
|
|
149
|
+
wrapper.classList.remove('empty');
|
|
150
|
+
createSvg(wrapper, data, readOnly);
|
|
151
|
+
} else if (!readOnly) {
|
|
152
|
+
wrapper.classList.add('empty');
|
|
153
|
+
wrapper.innerHTML = `<div class="text-muted icon me-2">${icon}</div><div class="text-muted text">Double click to start diagramming your business processes.</div>`;
|
|
154
|
+
}
|
|
155
|
+
return wrapper;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function createSvg(wrapper, { svg, caption }, readOnly) {
|
|
159
|
+
const svgContainer = document.createElement('div');
|
|
160
|
+
svgContainer.innerHTML = svg;
|
|
161
|
+
|
|
162
|
+
const divSvg = document.createElement('div');
|
|
163
|
+
wrapper.innerHTML = '';
|
|
164
|
+
wrapper.classList.remove('empty');
|
|
165
|
+
wrapper.appendChild(divSvg);
|
|
166
|
+
divSvg.appendChild(svgContainer);
|
|
167
|
+
|
|
168
|
+
const captionEl = document.createElement('div');
|
|
169
|
+
captionEl.contentEditable = !readOnly;
|
|
170
|
+
captionEl.classList.add('editorjs-bpmn-caption');
|
|
171
|
+
captionEl.textContent = caption;
|
|
172
|
+
if (!readOnly) {
|
|
173
|
+
captionEl.setAttribute('data-text', 'Caption');
|
|
174
|
+
captionEl.addEventListener('dblclick', (e) => {
|
|
175
|
+
e.stopPropagation();
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
wrapper.appendChild(captionEl);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
save(blockContent){
|
|
182
|
+
const caption = blockContent.querySelector('[contenteditable]');
|
|
183
|
+
const data = cloneDeep(this.data);
|
|
184
|
+
data.caption = caption ? caption.innerHTML : '';
|
|
185
|
+
return data;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.editorjs-bpmn {
|
|
2
|
+
--editorjs-drawing-border: #dcdfe6;
|
|
3
|
+
|
|
4
|
+
&.empty {
|
|
5
|
+
border: 1px dashed var(--editorjs-drawing-border);
|
|
6
|
+
min-height: 150px;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
}
|
|
11
|
+
position: relative;
|
|
12
|
+
z-index: 0;
|
|
13
|
+
margin-bottom: 10px;
|
|
14
|
+
border-radius: 5px;
|
|
15
|
+
height: max-content !important;
|
|
16
|
+
|
|
17
|
+
&:not(.readonly) {
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
|
|
20
|
+
&:hover {
|
|
21
|
+
outline: 3px solid var(--editorjs-drawing-border);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.editorjs-bpmn-caption {
|
|
26
|
+
margin-top: 1rem;
|
|
27
|
+
text-align: center;
|
|
28
|
+
&:empty:not(:focus):before {
|
|
29
|
+
content: attr(data-text);
|
|
30
|
+
opacity: .5;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
svg {
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: auto;
|
|
36
|
+
user-select: none;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
}
|
|
39
|
+
.icon {
|
|
40
|
+
width: 48px;
|
|
41
|
+
height: 48px;
|
|
42
|
+
|
|
43
|
+
path {
|
|
44
|
+
fill: currentColor;
|
|
45
|
+
stroke: none;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
.text {
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.editorjs-bpmn-modal .modal-body {
|
|
54
|
+
padding: 0;
|
|
55
|
+
display: flex;
|
|
56
|
+
}
|
|
57
|
+
.editorjs-bpmn-modal .modal-body-content {
|
|
58
|
+
flex: 1;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
justify-content: center;
|
|
62
|
+
align-items: center;
|
|
63
|
+
}
|
|
@@ -130,7 +130,7 @@ export default class Drawing {
|
|
|
130
130
|
|
|
131
131
|
function createSvg(wrapper, { svg, caption }, readOnly) {
|
|
132
132
|
const svgContainer = document.createElement('div');
|
|
133
|
-
svgContainer.innerHTML = svg.replace(
|
|
133
|
+
svgContainer.innerHTML = svg.replace(/@undefined/g, '@0.16.1'); // глючить версія в excalidraw
|
|
134
134
|
|
|
135
135
|
const divSvg = document.createElement('div');
|
|
136
136
|
wrapper.innerHTML = '';
|