@processmaker/screen-builder 2.84.2 → 2.85.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/dist/vue-form-builder.css +1 -1
- package/dist/vue-form-builder.es.js +48 -29
- package/dist/vue-form-builder.es.js.map +1 -1
- package/dist/vue-form-builder.umd.js +2 -2
- package/dist/vue-form-builder.umd.js.map +1 -1
- package/package.json +3 -3
- package/src/assets/css/custom.css +3 -0
- package/src/assets/css/tabs.css +3 -1
- package/src/components/TabsBar.vue +5 -3
- package/src/components/sortable/sortableList/SortableList.vue +27 -12
- package/src/components/vue-form-builder.vue +15 -1
- package/src/stories/DropdownAndPages.stories.js +34 -1
- package/src/stories/PageTabs.stories.js +57 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.85.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "VITE_COVERAGE=true vite",
|
|
6
6
|
"build": "vite build",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"axios-extensions": "^3.1.6",
|
|
36
36
|
"lodash": "^4.17.21",
|
|
37
37
|
"lru-cache": "^10.0.1",
|
|
38
|
-
"moment": "^2.
|
|
39
|
-
"moment-timezone": "^0.5.
|
|
38
|
+
"moment": "^2.30.1",
|
|
39
|
+
"moment-timezone": "^0.5.45",
|
|
40
40
|
"monaco-editor": "^0.34.0",
|
|
41
41
|
"scrollparent": "^2.0.1",
|
|
42
42
|
"vue-loader": "^15.9.2",
|
package/src/assets/css/tabs.css
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
/* Override Bootstrap default tab styles */
|
|
11
11
|
.nav-tabs {
|
|
12
12
|
border-bottom: 1px solid var(--tabs-border) !important;
|
|
13
|
+
}
|
|
14
|
+
.nav-tabs-nowrap {
|
|
13
15
|
flex-wrap: nowrap !important;
|
|
14
16
|
overflow: hidden !important;
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
|
|
17
19
|
.nav-tabs .nav-item .nav-link {
|
|
18
20
|
display: flex;
|
|
19
21
|
align-items: center;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
v-model="activeTab"
|
|
5
5
|
class="h-100 w-100 flat-tabs"
|
|
6
6
|
content-class="h-tab"
|
|
7
|
+
nav-class="nav-tabs-nowrap"
|
|
7
8
|
lazy
|
|
8
9
|
@changed="tabsUpdated"
|
|
9
10
|
@input="tabOpened"
|
|
@@ -196,9 +197,10 @@ export default {
|
|
|
196
197
|
}, visualThreshold);
|
|
197
198
|
});
|
|
198
199
|
},
|
|
199
|
-
closeTab(
|
|
200
|
-
this.localOpenedPages
|
|
201
|
-
this
|
|
200
|
+
closeTab(tabIndex) {
|
|
201
|
+
const pageIndex = this.localOpenedPages[tabIndex];
|
|
202
|
+
this.localOpenedPages.splice(tabIndex, 1);
|
|
203
|
+
this.$emit("tab-closed", this.pages[pageIndex], this.localOpenedPages);
|
|
202
204
|
},
|
|
203
205
|
updateTabsReferences(pageDelete) {
|
|
204
206
|
this.localOpenedPages = this.localOpenedPages.map((page) =>
|
|
@@ -24,15 +24,16 @@
|
|
|
24
24
|
<div class="rounded sortable-item-name">
|
|
25
25
|
<b-form-input
|
|
26
26
|
v-if="editRowIndex === index"
|
|
27
|
-
v-model="
|
|
27
|
+
v-model="newName"
|
|
28
28
|
type="text"
|
|
29
29
|
autofocus
|
|
30
30
|
required
|
|
31
|
-
:state="validateState(
|
|
32
|
-
:error="validateError(
|
|
33
|
-
@blur.stop="onBlur(
|
|
34
|
-
@keydown.enter.stop="onBlur(
|
|
35
|
-
@
|
|
31
|
+
:state="validateState(newName, item)"
|
|
32
|
+
:error="validateError(newName, item)"
|
|
33
|
+
@blur.stop="onBlur(newName, item)"
|
|
34
|
+
@keydown.enter.stop="onBlur(newName, item)"
|
|
35
|
+
@keydown.esc.stop="onCancel(item)"
|
|
36
|
+
@focus="onFocus(item)"
|
|
36
37
|
/>
|
|
37
38
|
<span v-else>{{ item.name }}</span>
|
|
38
39
|
</div>
|
|
@@ -63,7 +64,7 @@ export default {
|
|
|
63
64
|
},
|
|
64
65
|
data() {
|
|
65
66
|
return {
|
|
66
|
-
|
|
67
|
+
newName: '',
|
|
67
68
|
draggedItem: 0,
|
|
68
69
|
draggedOverItem: 0,
|
|
69
70
|
editRowIndex: null,
|
|
@@ -79,14 +80,14 @@ export default {
|
|
|
79
80
|
},
|
|
80
81
|
methods: {
|
|
81
82
|
validateState(name, item) {
|
|
82
|
-
const isEmpty = !name;
|
|
83
|
+
const isEmpty = !name?.trim();
|
|
83
84
|
const isDuplicated = this.items
|
|
84
85
|
.filter((i) => i !== item)
|
|
85
86
|
.find((i) => i.name === name);
|
|
86
87
|
return isEmpty || isDuplicated ? false : null;
|
|
87
88
|
},
|
|
88
89
|
validateError(name, item) {
|
|
89
|
-
const isEmpty = !name;
|
|
90
|
+
const isEmpty = !name?.trim();
|
|
90
91
|
if (!isEmpty) {
|
|
91
92
|
return this.$t("The Page Name field is required.");
|
|
92
93
|
}
|
|
@@ -98,19 +99,25 @@ export default {
|
|
|
98
99
|
}
|
|
99
100
|
return '';
|
|
100
101
|
},
|
|
101
|
-
onFocus(
|
|
102
|
-
this.
|
|
102
|
+
onFocus(item) {
|
|
103
|
+
this.newName = item.name;
|
|
103
104
|
},
|
|
104
105
|
async onBlur(name, item) {
|
|
105
106
|
if (this.validateState(name, item) === false) {
|
|
107
|
+
this.newName = item.name;
|
|
108
|
+
} else {
|
|
106
109
|
// eslint-disable-next-line no-param-reassign
|
|
107
|
-
item.name =
|
|
110
|
+
item.name = name;
|
|
108
111
|
}
|
|
109
112
|
await this.$nextTick();
|
|
110
113
|
setTimeout(() => {
|
|
111
114
|
this.editRowIndex = null;
|
|
112
115
|
}, 250);
|
|
113
116
|
},
|
|
117
|
+
async onCancel(item) {
|
|
118
|
+
this.newName = item.name;
|
|
119
|
+
this.editRowIndex = null;
|
|
120
|
+
},
|
|
114
121
|
onClick(item, index) {
|
|
115
122
|
this.editRowIndex = index;
|
|
116
123
|
this.$emit("item-edit", item);
|
|
@@ -162,6 +169,14 @@ export default {
|
|
|
162
169
|
|
|
163
170
|
itemsSortedClone[draggedItemIndex].order = tempOrder;
|
|
164
171
|
}
|
|
172
|
+
|
|
173
|
+
// Update order of the items
|
|
174
|
+
const clone = [...itemsSortedClone];
|
|
175
|
+
clone.sort((a, b) => a.order - b.order);
|
|
176
|
+
clone.forEach((item, index) => {
|
|
177
|
+
// eslint-disable-next-line no-param-reassign
|
|
178
|
+
item.order = index + 1;
|
|
179
|
+
});
|
|
165
180
|
}
|
|
166
181
|
|
|
167
182
|
this.$emit('ordered', itemsSortedClone);
|
|
@@ -881,6 +881,7 @@ export default {
|
|
|
881
881
|
config.forEach((page) => this.replaceFormText(page.items));
|
|
882
882
|
config.forEach((page) => this.migrateFormSubmit(page.items));
|
|
883
883
|
config.forEach((page) => this.updateFieldNameValidation(page.items));
|
|
884
|
+
this.updatePageOrder(config);
|
|
884
885
|
config.forEach((page) =>
|
|
885
886
|
this.removeDataVariableFromNestedScreens(page.items)
|
|
886
887
|
);
|
|
@@ -889,6 +890,18 @@ export default {
|
|
|
889
890
|
page.order = page.order || index + 1;
|
|
890
891
|
});
|
|
891
892
|
},
|
|
893
|
+
updatePageOrder(pages) {
|
|
894
|
+
const clone = [...pages];
|
|
895
|
+
clone.sort((a, b) => {
|
|
896
|
+
const aOrder = a.order || pages.indexOf(a) + 1;
|
|
897
|
+
const bOrder = b.order || pages.indexOf(b) + 1;
|
|
898
|
+
return aOrder - bOrder;
|
|
899
|
+
});
|
|
900
|
+
clone.forEach((item, index) => {
|
|
901
|
+
// eslint-disable-next-line no-param-reassign
|
|
902
|
+
item.order = index + 1;
|
|
903
|
+
});
|
|
904
|
+
},
|
|
892
905
|
updateFieldNameValidation(items) {
|
|
893
906
|
items.forEach((item) => {
|
|
894
907
|
if (item.inspector) {
|
|
@@ -1148,9 +1161,9 @@ export default {
|
|
|
1148
1161
|
this.updateState();
|
|
1149
1162
|
},
|
|
1150
1163
|
addPage(e) {
|
|
1151
|
-
this.showAddPageValidations = true;
|
|
1152
1164
|
const error = this.checkPageName(this.addPageName, true);
|
|
1153
1165
|
if (error) {
|
|
1166
|
+
this.showAddPageValidations = true;
|
|
1154
1167
|
e.preventDefault();
|
|
1155
1168
|
return;
|
|
1156
1169
|
}
|
|
@@ -1227,6 +1240,7 @@ export default {
|
|
|
1227
1240
|
globalObject.ProcessMaker.alert(error.message, "danger");
|
|
1228
1241
|
return;
|
|
1229
1242
|
}
|
|
1243
|
+
this.updatePageOrder(this.config);
|
|
1230
1244
|
this.$store.dispatch("undoRedoModule/pushState", {
|
|
1231
1245
|
config: JSON.stringify(this.config),
|
|
1232
1246
|
currentPage: this.currentPage,
|
|
@@ -80,7 +80,6 @@ export const OpenPageUsingDropdown = {
|
|
|
80
80
|
"[data-test=page-dropdown] button"
|
|
81
81
|
);
|
|
82
82
|
let selectorAddPage = canvasElement.querySelector("[data-test=page-Page3]");
|
|
83
|
-
console.log(selectorAddPage);
|
|
84
83
|
await selector.click(selector);
|
|
85
84
|
await selectorAddPage.click(selectorAddPage);
|
|
86
85
|
// Open Page 3 (index=2)
|
|
@@ -111,3 +110,37 @@ export const OpenPageUsingDropdown = {
|
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
112
|
};
|
|
113
|
+
|
|
114
|
+
// Open a page using the PageDropdown(index)
|
|
115
|
+
export const ScrollWithMoreThanTenPages = {
|
|
116
|
+
args: {
|
|
117
|
+
pages: [
|
|
118
|
+
{ name: "Page1" },
|
|
119
|
+
{ name: "Page2" },
|
|
120
|
+
{ name: "Page3" },
|
|
121
|
+
{ name: "Page4" },
|
|
122
|
+
{ name: "Page5" },
|
|
123
|
+
{ name: "Page6" },
|
|
124
|
+
{ name: "Page7" },
|
|
125
|
+
{ name: "Page8" },
|
|
126
|
+
{ name: "Page9" },
|
|
127
|
+
{ name: "Page10" },
|
|
128
|
+
{ name: "Page11" },
|
|
129
|
+
{ name: "Page12" }
|
|
130
|
+
],
|
|
131
|
+
initialOpenedPages: [0]
|
|
132
|
+
},
|
|
133
|
+
play: async ({ canvasElement }) => {
|
|
134
|
+
const selector = canvasElement.querySelector(
|
|
135
|
+
"[data-test=page-dropdown] button"
|
|
136
|
+
);
|
|
137
|
+
await selector.click(selector);
|
|
138
|
+
// Test .page-dropdown-menu has scroll (scrollHeight > clientHeight)
|
|
139
|
+
await waitFor(() => {
|
|
140
|
+
const dropdownMenu = canvasElement.querySelector(".page-dropdown-menu");
|
|
141
|
+
expect(dropdownMenu.scrollHeight).toBeGreaterThan(
|
|
142
|
+
dropdownMenu.clientHeight
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
};
|
|
@@ -336,3 +336,60 @@ export const WithoutAnyPageOpened = {
|
|
|
336
336
|
);
|
|
337
337
|
}
|
|
338
338
|
};
|
|
339
|
+
|
|
340
|
+
// User can close tabs
|
|
341
|
+
export const UserCanCloseTabs = {
|
|
342
|
+
args: {
|
|
343
|
+
pages: [
|
|
344
|
+
{ name: "Page 1" },
|
|
345
|
+
{ name: "Page 2" },
|
|
346
|
+
{ name: "Page 3" },
|
|
347
|
+
{ name: "Page 4" },
|
|
348
|
+
{ name: "Page 5" }
|
|
349
|
+
],
|
|
350
|
+
initialOpenedPages: [0, 1, 2, 3, 4]
|
|
351
|
+
},
|
|
352
|
+
play: async ({ canvasElement, step }) => {
|
|
353
|
+
const canvas = within(canvasElement);
|
|
354
|
+
|
|
355
|
+
// Close Tab #1 = Page 1 (tab index=0)
|
|
356
|
+
await step("Close Page 1 (tab index=0)", async () => {
|
|
357
|
+
canvas.getByTestId("close-tab-0").click();
|
|
358
|
+
await waitFor(
|
|
359
|
+
() => {
|
|
360
|
+
expect(canvas.getByTestId("tab-content")).toContainHTML(
|
|
361
|
+
"Here comes content of Page 2 (#1)"
|
|
362
|
+
);
|
|
363
|
+
},
|
|
364
|
+
{ timeout: 1000 }
|
|
365
|
+
);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Close Tab #1 = Page 2 (tab index=0)
|
|
369
|
+
await step("Close Page 2 (tab index=0)", async () => {
|
|
370
|
+
canvas.getByTestId("close-tab-0").click();
|
|
371
|
+
await waitFor(
|
|
372
|
+
() => {
|
|
373
|
+
expect(canvas.getByTestId("tab-content")).toContainHTML(
|
|
374
|
+
"Here comes content of Page 3 (#2)"
|
|
375
|
+
);
|
|
376
|
+
},
|
|
377
|
+
{ timeout: 1000 }
|
|
378
|
+
);
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
// Close Tab #2 = Page 4 (tab index=1)
|
|
382
|
+
await step("Close Page 4 (tab index=1)", async () => {
|
|
383
|
+
canvas.getByTestId("close-tab-1").click();
|
|
384
|
+
await waitFor(
|
|
385
|
+
() => {
|
|
386
|
+
// keep focus in the tab #1
|
|
387
|
+
expect(canvas.getByTestId("tab-content")).toContainHTML(
|
|
388
|
+
"Here comes content of Page 3 (#2)"
|
|
389
|
+
);
|
|
390
|
+
},
|
|
391
|
+
{ timeout: 1000 }
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
};
|