@processmaker/screen-builder 2.83.10 → 2.84.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.
@@ -0,0 +1,132 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import { within, expect, waitFor } from "@storybook/test";
3
+ import "../bootstrap";
4
+ // b-tabs from bootstrap-vue
5
+ import PagesDropdown from "../components/editor/pagesDropdown.vue";
6
+
7
+ export default {
8
+ title: "Components/PagesDropdown",
9
+ component: PagesDropdown,
10
+ tags: ["autodocs"],
11
+ render: (args, { argTypes }) => ({
12
+ props: Object.keys(argTypes),
13
+ components: { PagesDropdown },
14
+ template: `
15
+ <pages-dropdown
16
+ :data="data"
17
+ @addPage="onAddPage"
18
+ @clickPage="onClick"
19
+ @seeAllPages="onSeeAllPages"
20
+ />
21
+ `,
22
+ data() {
23
+ return {};
24
+ },
25
+ methods: {
26
+ onAddPage() {
27
+ console.log("Add page clicked");
28
+ },
29
+ onSeeAllPages() {
30
+ console.log("See all pages clicked");
31
+ },
32
+ onClick(index) {
33
+ console.log("Click page item:", index);
34
+ }
35
+ }
36
+ })
37
+ };
38
+
39
+ /**
40
+ * Stories of the component
41
+ */
42
+ // Preview the component
43
+ export const Preview = {
44
+ args: {
45
+ data: [
46
+ { name: "Page 1" },
47
+ { name: "Page 2" },
48
+ { name: "Page 3" },
49
+ { name: "Page 4" },
50
+ { name: "Page 5" }
51
+ ]
52
+ }
53
+ };
54
+
55
+ // Open the pages dropdown
56
+ export const ClickInDropdown = {
57
+ args: {
58
+ data: [{ name: "Page 1" }, { name: "Page 2" }, { name: "Page 3" }]
59
+ },
60
+ play: async ({ canvasElement }) => {
61
+ const canvas = within(canvasElement);
62
+ const selector = canvasElement.querySelector(
63
+ "[data-test=page-dropdown] button"
64
+ );
65
+ console.log(selector);
66
+ await selector.click(selector);
67
+ await waitFor(
68
+ () => {
69
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML(
70
+ "Create Page"
71
+ );
72
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML(
73
+ "See all pages"
74
+ );
75
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML("Page 1");
76
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML("Page 2");
77
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML("Page 3");
78
+ },
79
+ { timeout: 1000 }
80
+ );
81
+ }
82
+ };
83
+ // Open the Create Page
84
+ export const ClickInCreatePage = {
85
+ args: {
86
+ data: [{ name: "Page 1" }]
87
+ },
88
+ play: async ({ canvasElement }) => {
89
+ const canvas = within(canvasElement);
90
+ const selector = canvasElement.querySelector(
91
+ "[data-test=page-dropdown] button"
92
+ );
93
+ const selectorAddPage = canvasElement.querySelector("[data-test=add-page]");
94
+ console.log(selectorAddPage);
95
+ await selector.click(selector);
96
+ await waitFor(
97
+ () => {
98
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML(
99
+ "Create Page"
100
+ );
101
+ },
102
+ { timeout: 1000 }
103
+ );
104
+ await selectorAddPage.click(selectorAddPage);
105
+ }
106
+ };
107
+ // Open the See all Pages
108
+ export const ClickInSeeAllPages = {
109
+ args: {
110
+ data: [{ name: "Page 1" }]
111
+ },
112
+ play: async ({ canvasElement }) => {
113
+ const canvas = within(canvasElement);
114
+ const selector = canvasElement.querySelector(
115
+ "[data-test=page-dropdown] button"
116
+ );
117
+ const selectorAddPage = canvasElement.querySelector(
118
+ "[data-test=see-all-pages]"
119
+ );
120
+ console.log(selectorAddPage);
121
+ await selector.click(selector);
122
+ await waitFor(
123
+ () => {
124
+ expect(canvas.getByTestId("page-dropdown")).toContainHTML(
125
+ "See all pages"
126
+ );
127
+ },
128
+ { timeout: 1000 }
129
+ );
130
+ await selectorAddPage.click(selectorAddPage);
131
+ }
132
+ };
@@ -0,0 +1,188 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import "../bootstrap";
3
+ // b-tabs from bootstrap-vue
4
+ import ScreenToolbar from "../components/ScreenToolbar.vue";
5
+
6
+ const options = [
7
+ {
8
+ id: "group_design",
9
+ type: "group",
10
+ section: "left",
11
+ items: [
12
+ {
13
+ id: "button_design",
14
+ type: "button",
15
+ title: "Design Screen",
16
+ name: "Design",
17
+ variant: "secondary",
18
+ icon: "fas fa-drafting-compass pr-1",
19
+ action: "changeMode(\"editor\")",
20
+ },
21
+ {
22
+ id: "button_preview",
23
+ type: "button",
24
+ title: "Preview Screen",
25
+ name: "Preview",
26
+ variant: "outline-secondary",
27
+ icon: "fas fa-cogs pr-1",
28
+ action: "changeMode(\"preview\")",
29
+ },
30
+ ],
31
+ },
32
+ {
33
+ id: "group_preview",
34
+ type: "group",
35
+ section: "left",
36
+ displayCondition: "displayPreview",
37
+ items: [
38
+ {
39
+ id: "button_preview_desktop",
40
+ type: "button",
41
+ title: "Preview Desktop",
42
+ variant: "secondary",
43
+ icon: "fas fa-desktop",
44
+ action: "changeDeviceScreen(\"desktop\")",
45
+ },
46
+ {
47
+ id: "button_preview_mobile",
48
+ type: "button",
49
+ title: "Preview Mobile",
50
+ variant: "outline-secondary",
51
+ icon: "fas fa-mobile pr-1",
52
+ action: "changeDeviceScreen(\"mobile\")",
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ id: "group_properties",
58
+ type: "group",
59
+ section: "right",
60
+ items: [
61
+ {
62
+ id: "button_calcs",
63
+ type: "button",
64
+ title: "Calculated Properties",
65
+ name: "Calcs",
66
+ variant: "secondary",
67
+ icon: "fas fa-flask",
68
+ action: "openComputedProperties()",
69
+ },
70
+ {
71
+ id: "button_custom_css",
72
+ type: "button",
73
+ title: "Custom CSS",
74
+ name: "CSS",
75
+ variant: "secondary",
76
+ icon: "fab fa-css3",
77
+ action: "openCustomCSS()",
78
+ },
79
+ {
80
+ id: "button_watchers",
81
+ type: "button",
82
+ title: "Watchers",
83
+ name: "Watchers",
84
+ variant: "secondary",
85
+ icon: "fas fa-mask",
86
+ action: "openWatchersPopup()",
87
+ },
88
+ ],
89
+ },
90
+ {
91
+ id: "button_export",
92
+ section: "right",
93
+ type: "button",
94
+ title: "Export Screen",
95
+ name: "",
96
+ variant: "secondary",
97
+ icon: "fas fa-file-export",
98
+ action: "beforeExportScreen()",
99
+ },
100
+ {
101
+ id: "button_save",
102
+ section: "right",
103
+ type: "button",
104
+ title: "Save Screen",
105
+ name: "",
106
+ variant: "secondary",
107
+ icon: "fas fa-save",
108
+ action: () => {
109
+ ProcessMaker.EventBus.$emit("save-screen", false);
110
+ },
111
+ },
112
+ ];
113
+
114
+ export default {
115
+ title: "Components/ScreenToolbar",
116
+ component: ScreenToolbar,
117
+ tags: ["autodocs"],
118
+ render: (args, { argTypes }) => ({
119
+ props: Object.keys(argTypes),
120
+ components: { Toolbar: ScreenToolbar },
121
+ template: `
122
+ <toolbar v-bind="$props">
123
+ <b-btn
124
+ variant="secondary"
125
+ size="sm"
126
+ class="mr-2"
127
+ :title="$t('Load Screen')"
128
+ >
129
+ <i class="fas fa-upload mr-1" />
130
+ </b-btn>
131
+ <button
132
+ type="button"
133
+ class="btn btn-secondary btn-sm ml-1"
134
+ :title="$t('Save Screen')"
135
+ @click="saveToLocalStorage()"
136
+ >
137
+ <i class="fas fa-save" />
138
+ </button>
139
+ </toolbar>
140
+ `,
141
+ data() {
142
+ return {};
143
+ },
144
+ methods: {
145
+ sorted(orderedArray) {
146
+ console.log("edit", orderedArray);
147
+ },
148
+ editPage(page) {
149
+ console.log("edit", page);
150
+ },
151
+ deletePage(page) {
152
+ this.items.splice(this.items.indexOf(page), 1);
153
+ },
154
+ openPage(index) {
155
+ this.$refs.tabsBar.openPageByIndex(index);
156
+ }
157
+ }
158
+ }),
159
+ decorators: [
160
+ () => ({
161
+ template: `<div class="d-flex flex-row align-items-center border">
162
+ <b-button-group size="sm" class="mx-2 text-nowrap">
163
+ <b-button
164
+ variant="secondary"
165
+ >
166
+ <i class="fas fa-drafting-compass pr-1" />{{ $t("Design") }}
167
+ </b-button>
168
+ <b-button
169
+ variant="outline-secondary"
170
+ >
171
+ <i class="fas fa-cogs pr-1" />{{ $t("Preview") }}
172
+ </b-button>
173
+ </b-button-group>
174
+ <story />
175
+ </div>`
176
+ })
177
+ ]
178
+ };
179
+
180
+ /**
181
+ * Stories of the component
182
+ */
183
+ // Preview the component
184
+ export const Preview = {
185
+ args: {
186
+ options
187
+ },
188
+ };
@@ -0,0 +1,225 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import { within, userEvent, fireEvent, expect, waitFor } from "@storybook/test";
3
+ import "../bootstrap";
4
+ // b-tabs from bootstrap-vue
5
+ import Sortable from "../components/sortable/Sortable.vue";
6
+
7
+ /**
8
+ * Simulates a drag and drop action from one element to another.
9
+ *
10
+ * @param {HTMLElement} sourceElement - The element to drag.
11
+ * @param {HTMLElement} targetElement - The element to drop onto.
12
+ */
13
+ async function dragAndDrop(sourceElement, targetElement) {
14
+ await fireEvent.dragStart(sourceElement);
15
+ await fireEvent.dragEnter(targetElement);
16
+ await fireEvent.dragOver(targetElement);
17
+ await fireEvent.drop(targetElement);
18
+ await fireEvent.dragEnd(sourceElement);
19
+ }
20
+
21
+ export default {
22
+ title: "Components/Sortable",
23
+ component: Sortable,
24
+ tags: ["autodocs"],
25
+ render: (args, { argTypes }) => ({
26
+ props: Object.keys(argTypes),
27
+ components: { Sortable },
28
+ template: `
29
+ <sortable
30
+ v-bind="$props"
31
+ @sorted="sorted"
32
+ @item-edit="editPage"
33
+ @item-delete="deletePage"
34
+ />
35
+ `,
36
+ data() {
37
+ return {};
38
+ },
39
+ methods: {
40
+ sorted(orderedArray) {
41
+ console.log("edit", orderedArray);
42
+ },
43
+ editPage(page) {
44
+ console.log("edit", page);
45
+ },
46
+ deletePage(page) {
47
+ this.items.splice(this.items.indexOf(page), 1);
48
+ },
49
+ openPage(index) {
50
+ this.$refs.tabsBar.openPageByIndex(index);
51
+ }
52
+ }
53
+ })
54
+ };
55
+
56
+ /**
57
+ * Stories of the component
58
+ */
59
+ // Preview the component
60
+ export const Preview = {
61
+ args: {
62
+ filterKey: "name",
63
+ items: [
64
+ { name: "Page 1", order: 1 },
65
+ { name: "Page 2", order: 2 },
66
+ { name: "Page 3", order: 3 },
67
+ { name: "Page 4", order: 4 },
68
+ { name: "Page 5", order: 5 }
69
+ ]
70
+ }
71
+ };
72
+
73
+ // User can reorder items
74
+ export const UserCanReorderItems = {
75
+ args: {
76
+ filterKey: "name",
77
+ items: [
78
+ { name: "Page 1", order: 1 },
79
+ { name: "Page 2", order: 2 },
80
+ { name: "Page 3", order: 3 },
81
+ { name: "Page 4", order: 4 },
82
+ { name: "Page 5", order: 5 }
83
+ ]
84
+ },
85
+ play: async ({ canvasElement }) => {
86
+ const canvas = within(canvasElement);
87
+
88
+ // Drag item-1 item-5 position
89
+ await dragAndDrop(
90
+ canvas.getByTestId("item-1"),
91
+ canvas.getByTestId("item-5")
92
+ );
93
+
94
+ // Drag item-1 item-4 position
95
+ await dragAndDrop(
96
+ canvas.getByTestId("item-1"),
97
+ canvas.getByTestId("item-4")
98
+ );
99
+
100
+ // Drag item-1 item-3 position
101
+ await dragAndDrop(
102
+ canvas.getByTestId("item-1"),
103
+ canvas.getByTestId("item-3")
104
+ );
105
+
106
+ // Drag item-1 item-2 position
107
+ await dragAndDrop(
108
+ canvas.getByTestId("item-1"),
109
+ canvas.getByTestId("item-2")
110
+ );
111
+
112
+ // Check the new order
113
+ const items = canvas.getAllByTestId(/item-\d+/);
114
+ expect(items[0]).toHaveTextContent("Page 5");
115
+ expect(items[1]).toHaveTextContent("Page 4");
116
+ expect(items[2]).toHaveTextContent("Page 3");
117
+ expect(items[3]).toHaveTextContent("Page 2");
118
+ expect(items[4]).toHaveTextContent("Page 1");
119
+ }
120
+ };
121
+
122
+ // User can filter by text
123
+ export const UserCanFilterByText = {
124
+ args: {
125
+ filterKey: "name",
126
+ items: [
127
+ { name: "Zeus", order: 1 },
128
+ { name: "Hera", order: 2 },
129
+ { name: "Poseidon", order: 3 },
130
+ { name: "Athena", order: 4 },
131
+ { name: "Hephaïstus", order: 5 }
132
+ ]
133
+ },
134
+ play: async ({ canvasElement, step }) => {
135
+ const canvas = within(canvasElement);
136
+ const search = canvas.getByTestId("search");
137
+
138
+ // Type "Zeus"
139
+ await step("Type 'Zeus'", async () => {
140
+ await userEvent.clear(search);
141
+ await userEvent.type(search, "Zeus");
142
+ const items = canvas.getAllByTestId(/item-\d+/);
143
+ await waitFor(() => {
144
+ expect(items).toHaveLength(1);
145
+ });
146
+ });
147
+
148
+ // Type "a" should be case insensitive
149
+ await step("Type 'a'", async () => {
150
+ await userEvent.clear(search);
151
+ await userEvent.type(search, "a");
152
+ const items = canvas.getAllByTestId(/item-\d+/);
153
+ await waitFor(() => {
154
+ expect(items).toHaveLength(3);
155
+ });
156
+ });
157
+
158
+ // Type "Ï" support unicode
159
+ await step("Type 'Ï'", async () => {
160
+ await userEvent.clear(search);
161
+ await userEvent.type(search, "Ï");
162
+ const items = canvas.getAllByTestId(/item-\d+/);
163
+ await waitFor(() => {
164
+ expect(items).toHaveLength(1);
165
+ });
166
+ });
167
+ }
168
+ };
169
+
170
+ // User can sort with filter by text
171
+ export const UserCanSortWithFilterByText = {
172
+ args: {
173
+ filterKey: "name",
174
+ items: [
175
+ { name: "Zeus", order: 1 },
176
+ { name: "Hera", order: 2 },
177
+ { name: "Poseidon", order: 3 },
178
+ { name: "Athena", order: 4 },
179
+ { name: "Hephaïstus", order: 5 }
180
+ ]
181
+ },
182
+ play: async ({ canvasElement, step }) => {
183
+ const canvas = within(canvasElement);
184
+ const search = canvas.getByTestId("search");
185
+
186
+ // Type "A"
187
+ await step("Type 'A'", async () => {
188
+ await userEvent.clear(search);
189
+ await userEvent.type(search, "A");
190
+ const items = canvas.getAllByTestId(/item-\d+/);
191
+ await waitFor(() => {
192
+ expect(items).toHaveLength(3);
193
+ });
194
+ });
195
+
196
+ // Drag "Hera" to "Hephaïstus" position
197
+ await dragAndDrop(
198
+ canvas.getByTitle("Hera"),
199
+ canvas.getByTitle("Hephaïstus")
200
+ );
201
+
202
+ // Drag "Athena" to "Hephaïstus" position
203
+ await dragAndDrop(
204
+ canvas.getByTitle("Athena"),
205
+ canvas.getByTitle("Hephaïstus")
206
+ );
207
+
208
+ // Clean search
209
+ await step("Clean search", async () => {
210
+ await userEvent.clear(search);
211
+ const items = canvas.getAllByTestId(/item-\d+/);
212
+ await waitFor(() => {
213
+ expect(items).toHaveLength(5);
214
+ });
215
+ });
216
+
217
+ // Check the new order
218
+ const items = canvas.getAllByTestId(/item-\d+/);
219
+ expect(items[0]).toHaveTextContent("Zeus");
220
+ expect(items[1]).toHaveTextContent("Poseidon");
221
+ expect(items[2]).toHaveTextContent("Hephaïstus");
222
+ expect(items[3]).toHaveTextContent("Athena");
223
+ expect(items[4]).toHaveTextContent("Hera");
224
+ }
225
+ };