@processmaker/screen-builder 2.99.2 → 3.0.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 (48) hide show
  1. package/dist/vue-form-builder.css +1 -1
  2. package/dist/vue-form-builder.es.js +9092 -7133
  3. package/dist/vue-form-builder.es.js.map +1 -1
  4. package/dist/vue-form-builder.umd.js +53 -53
  5. package/dist/vue-form-builder.umd.js.map +1 -1
  6. package/package.json +2 -1
  7. package/src/App.vue +14 -2
  8. package/src/DataProvider.js +42 -1
  9. package/src/VariableDataTypeProperties.js +1 -1
  10. package/src/components/ClipboardButton.vue +77 -0
  11. package/src/components/CssIcon.vue +21 -0
  12. package/src/components/ScreenTemplateCard.vue +257 -0
  13. package/src/components/ScreenTemplates.vue +216 -0
  14. package/src/components/ScreenToolbar.vue +24 -2
  15. package/src/components/SelectUserGroup.vue +274 -0
  16. package/src/components/TabsBar.vue +47 -1
  17. package/src/components/accordions.js +7 -1
  18. package/src/components/editor/loop.vue +22 -1
  19. package/src/components/editor/multi-column.vue +22 -2
  20. package/src/components/editor/pagesDropdown.vue +20 -2
  21. package/src/components/index.js +7 -1
  22. package/src/components/inspector/collection-data-source.vue +200 -0
  23. package/src/components/inspector/collection-display-mode.vue +87 -0
  24. package/src/components/inspector/collection-records-list.vue +156 -0
  25. package/src/components/inspector/column-setup.vue +123 -7
  26. package/src/components/inspector/encrypted-config.vue +78 -0
  27. package/src/components/inspector/index.js +4 -0
  28. package/src/components/inspector/page-select.vue +1 -0
  29. package/src/components/renderer/file-upload.vue +136 -3
  30. package/src/components/renderer/form-collection-record-control.vue +248 -0
  31. package/src/components/renderer/form-collection-view-control.vue +236 -0
  32. package/src/components/renderer/form-masked-input.vue +194 -9
  33. package/src/components/renderer/form-record-list.vue +271 -69
  34. package/src/components/renderer/index.js +2 -0
  35. package/src/components/screen-renderer.vue +2 -0
  36. package/src/components/task.vue +3 -1
  37. package/src/components/vue-form-builder.vue +156 -22
  38. package/src/components/vue-form-renderer.vue +10 -2
  39. package/src/form-builder-controls.js +168 -21
  40. package/src/global-properties.js +8 -0
  41. package/src/main.js +60 -1
  42. package/src/mixins/Clipboard.js +153 -0
  43. package/src/mixins/ScreenBase.js +7 -1
  44. package/src/mixins/index.js +1 -0
  45. package/src/store/modules/ClipboardManager.js +79 -0
  46. package/src/store/modules/clipboardModule.js +210 -0
  47. package/src/stories/ClipboardButton.stories.js +66 -0
  48. package/src/stories/PagesDropdown.stories.js +11 -8
@@ -8,7 +8,7 @@
8
8
  no-body
9
9
  class="h-100 rounded-0 border-top-0 border-bottom-0 border-left-0"
10
10
  >
11
- <b-input-group size="sm" style="height: 42px">
11
+ <b-input-group size="sm" style="height: 42px">
12
12
  <b-input-group-prepend>
13
13
  <span
14
14
  class="input-group-text rounded-0 border-left-0 border-top-0 border-bottom-0"
@@ -72,9 +72,12 @@
72
72
  customClass: 'custom-popover',
73
73
  boundaryPadding: 16
74
74
  }"
75
+ :data-control="controls.indexOf(element)"
75
76
  :boundary="'viewport'"
76
77
  :data-cy="`controls-${element.component}`"
77
78
  class="gray-text"
79
+ :disabled="!canDragControl(element)"
80
+ @mousedown="disableEnableDragControl(element, $event)"
78
81
  >
79
82
  <i
80
83
  v-if="element.config && element.config.icon"
@@ -105,7 +108,9 @@
105
108
  ref="tabsBar"
106
109
  :pages="config"
107
110
  :is-multi-page="showToolbar"
111
+ :show-clipboard="showClipboard"
108
112
  @tab-opened="currentPage = $event"
113
+ @close-clipboard="closeClipboard"
109
114
  >
110
115
  <template #tabs-start>
111
116
  <pages-dropdown
@@ -114,9 +119,17 @@
114
119
  @addPage="$bvModal.show('addPageModal')"
115
120
  @clickPage="onClick"
116
121
  @seeAllPages="$bvModal.show('openSortable')"
122
+ @clipboard="openClipboard"
117
123
  />
118
124
  </template>
119
125
  <template #default="{ currentPage: tabPage }">
126
+ <b-button
127
+ v-if="isClipboardPage(tabPage)"
128
+ variant="link"
129
+ @click="clearClipboard"
130
+ >
131
+ {{ $t('Clear All') }}
132
+ </b-button>
120
133
  <div
121
134
  v-if="isCurrentPageEmpty(tabPage)"
122
135
  data-cy="screen-drop-zone"
@@ -151,7 +164,7 @@
151
164
  data-cy="editor-content"
152
165
  class="h-100"
153
166
  ghost-class="form-control-ghost"
154
- :value="config[tabPage].items"
167
+ :value="extendedPages[tabPage].items"
155
168
  v-bind="{
156
169
  group: { name: 'controls' },
157
170
  swapThreshold: 0.5
@@ -159,7 +172,7 @@
159
172
  @input="updateConfig"
160
173
  >
161
174
  <div
162
- v-for="(element, index) in config[tabPage].items"
175
+ v-for="(element, index) in extendedPages[tabPage].items"
163
176
  :key="index"
164
177
  class="control-item mt-4 mb-4"
165
178
  :class="{
@@ -189,6 +202,16 @@
189
202
  />
190
203
  {{ element.config.name || element.label || $t("Field Name") }}
191
204
  <div class="ml-auto">
205
+ <clipboard-button
206
+ v-if="!isClipboardPage(tabPage)"
207
+ :index="index"
208
+ :config="element.config"
209
+ :isInClipboard="isInClipboard(extendedPages[tabPage].items[index])"
210
+ :addTitle="$t('Add to clipboard')"
211
+ :removeTitle="$t('Remove from clipboard')"
212
+ @addToClipboard="addToClipboard(extendedPages[tabPage].items[index])"
213
+ @removeFromClipboard="removeFromClipboard(extendedPages[tabPage].items[index])"
214
+ />
192
215
  <button
193
216
  v-if="isAiSection(element) && aiPreview(element)"
194
217
  data-test="apply-ai-btn"
@@ -244,6 +267,16 @@
244
267
  />
245
268
  {{ element.config.name || $t("Variable Name") }}
246
269
  <div class="ml-auto">
270
+ <clipboard-button
271
+ v-if="!isClipboardPage(tabPage)"
272
+ :index="index"
273
+ :config="element.config"
274
+ :isInClipboard="isInClipboard(extendedPages[tabPage].items[index])"
275
+ :addTitle="$t('Add to clipboard')"
276
+ :removeTitle="$t('Remove from clipboard')"
277
+ @addToClipboard="addToClipboard(extendedPages[tabPage].items[index])"
278
+ @removeFromClipboard="removeFromClipboard(extendedPages[tabPage].items[index])"
279
+ />
247
280
  <button
248
281
  class="btn btn-sm btn-secondary mr-2"
249
282
  :title="$t('Copy Control')"
@@ -290,13 +323,26 @@
290
323
  <!-- Inspector -->
291
324
  <b-col
292
325
  v-if="renderControls"
293
- class="overflow-hidden h-100 p-0 inspector-column"
326
+ class="overflow-auto mh-100 p-0 d-flex flex-column position-relative inspector-column"
294
327
  >
295
328
  <b-card
296
329
  no-body
297
- class="p-0 h-100 border-top-0 border-bottom-0 border-right-0 rounded-0"
330
+ class="p-0 h-100 border-top-0 border-bottom-0 border-right-0 rounded-0 inspector-column"
298
331
  >
299
- <b-card-body class="p-0 h-100 overflow-auto">
332
+ <div v-if="showTemplatesPanel">
333
+ <b-card-body class="p-2 h-100 overflow-auto screen-templates-column">
334
+ <screen-templates
335
+ ref="screenTemplates"
336
+ :shared-templates-data="sharedTemplatesData"
337
+ @close-templates-panel="closeTemplatesPanel"
338
+ :screen-id="screen.id"
339
+ :screen-type="screen.type"
340
+ :currentScreenPage="currentPage"
341
+ />
342
+ </b-card-body>
343
+ </div>
344
+ <div v-else>
345
+ <b-card-body class="p-0 h-100 overflow-auto">
300
346
  <template v-for="accordion in accordions">
301
347
  <b-button
302
348
  v-if="
@@ -330,6 +376,7 @@
330
376
  v-model="accordion.open"
331
377
  >
332
378
  <component
379
+ v-if="shouldShow(item)"
333
380
  :is="item.type"
334
381
  v-for="(item, index) in getInspectorFields(accordion)"
335
382
  :key="index"
@@ -342,7 +389,7 @@
342
389
  ''
343
390
  )}`"
344
391
  :builder="builder"
345
- :form-config="config"
392
+ :form-config="extendedPages"
346
393
  :screen-type="screenType"
347
394
  :current-page="currentPage"
348
395
  :selected-control="selected"
@@ -354,7 +401,8 @@
354
401
  </b-collapse>
355
402
  </template>
356
403
  </b-card-body>
357
- </b-card>
404
+ </div>
405
+ </b-card>
358
406
  </b-col>
359
407
 
360
408
  <!-- Modals -->
@@ -474,6 +522,7 @@ import {
474
522
  } from "@processmaker/vue-form-elements";
475
523
  import Validator from "@chantouchsek/validatorjs";
476
524
  import HasColorProperty from "../mixins/HasColorProperty";
525
+ import Clipboard from "../mixins/Clipboard";
477
526
  import * as renderer from "./renderer";
478
527
  import * as inspector from "./inspector";
479
528
  import "@processmaker/vue-form-elements/dist/vue-form-elements.css";
@@ -488,6 +537,8 @@ import MultipleUploadsCheckbox from "./utils/multiple-uploads-checkbox";
488
537
  import { formTypes } from "@/global-properties";
489
538
  import TabsBar from "./TabsBar.vue";
490
539
  import Sortable from './sortable/Sortable.vue';
540
+ import ClipboardButton from './ClipboardButton.vue';
541
+ import ScreenTemplates from './ScreenTemplates.vue';
491
542
 
492
543
  // To include another language in the Validator with variable processmaker
493
544
  const globalObject = typeof window === "undefined" ? global : window;
@@ -527,12 +578,13 @@ const defaultConfig = [
527
578
  ];
528
579
 
529
580
  const defaultGroupOrder = {
530
- "Input Fields" : 1.0,
531
- "Content Fields" : 2.0,
532
- "Dashboards" : 2.5,
533
- "Navigation" : 3.0,
534
- "Files" : 4.0,
535
- "Advanced" : 5.0,
581
+ "Clipboard": 1.0,
582
+ "Input Fields" : 2.0,
583
+ "Content Fields" : 3.0,
584
+ "Dashboards" : 3.5,
585
+ "Navigation" : 4.0,
586
+ "Files" : 5.0,
587
+ "Advanced" : 6.0,
536
588
  };
537
589
 
538
590
  const DEFAULT_GROUP = "Advanced";
@@ -555,8 +607,10 @@ export default {
555
607
  ...renderer,
556
608
  PagesDropdown,
557
609
  Sortable,
610
+ ClipboardButton,
611
+ ScreenTemplates,
558
612
  },
559
- mixins: [HasColorProperty, testing],
613
+ mixins: [HasColorProperty, testing, Clipboard],
560
614
  props: {
561
615
  renderControls: {
562
616
  type: Boolean,
@@ -580,7 +634,10 @@ export default {
580
634
  },
581
635
  processId: {
582
636
  default: 0
583
- }
637
+ },
638
+ sharedTemplatesData: {
639
+ type: Array,
640
+ },
584
641
  },
585
642
  data() {
586
643
  const config = this.initialConfig || defaultConfig;
@@ -592,7 +649,13 @@ export default {
592
649
  config[0].name = this.title;
593
650
  }
594
651
 
652
+ const clipboardPage = {
653
+ name: this.$t("Clipboard"),
654
+ items: this.$store.getters["clipboardModule/clipboardItems"],
655
+ };
656
+
595
657
  return {
658
+ clipboardPage,
596
659
  showAddPageValidations: false,
597
660
  openedPages: [0],
598
661
  currentPage: 0,
@@ -631,9 +694,24 @@ export default {
631
694
  collapse: {},
632
695
  groupOrder: {},
633
696
  searchProperties: ['name'],
697
+ showTemplatesPanel: false,
698
+ enableOption: true
634
699
  };
635
700
  },
636
701
  computed: {
702
+ isCurrentPageClipboard() {
703
+ return this.isClipboardPage(this.currentPage);
704
+ },
705
+ extendedPages() {
706
+ return [
707
+ ...this.config,
708
+ this.clipboardPage,
709
+ ];
710
+ },
711
+ clipboardItems() {
712
+ return this.$store.getters["clipboardModule/clipboardItems"];
713
+ },
714
+
637
715
  sortedPages() {
638
716
  return [...this.config].sort((a, b) => a.order - b.order);
639
717
  },
@@ -700,7 +778,6 @@ export default {
700
778
  return orderA - orderB;
701
779
  });
702
780
  });
703
-
704
781
  return grouped;
705
782
  },
706
783
  showToolbar() {
@@ -713,7 +790,7 @@ export default {
713
790
  this.checkForCaptchaInLoops();
714
791
  this.$emit("change", this.config);
715
792
  },
716
- deep: true
793
+ deep: true,
717
794
  },
718
795
  currentPage() {
719
796
  this.inspect();
@@ -747,6 +824,7 @@ export default {
747
824
  }
748
825
  },
749
826
  created() {
827
+ this.addUuidToElements(this.config);
750
828
  this.$store.dispatch("undoRedoModule/pushState", {
751
829
  config: JSON.stringify(this.config),
752
830
  currentPage: this.currentPage
@@ -780,6 +858,38 @@ export default {
780
858
  this.setGroupOrder(defaultGroupOrder);
781
859
  },
782
860
  methods: {
861
+ isClipboardPage(page) {
862
+ return page === this.config.length;
863
+ },
864
+ disableEnableDragControl(control, event) {
865
+ if (!this.canDragControl(control)) {
866
+ event.preventDefault();
867
+ }
868
+ },
869
+ canDragControl(control) {
870
+ const isDragAndPaste = control.component === "Clipboard";
871
+ return !(isDragAndPaste && this.isClipboardPage(this.currentPage));
872
+ },
873
+ openClipboard() {
874
+ this.showClipboard = true;
875
+ this.$nextTick(() => {
876
+ this.$refs.tabsBar.openClipboard();
877
+ });
878
+ },
879
+ shouldShow(item) {
880
+ const sourceOptions = this.inspection.config[item.field]?.sourceOptions;
881
+
882
+ if (sourceOptions === 'Variable') {
883
+ this.enableOption = true;
884
+ return true;
885
+ }
886
+
887
+ if (sourceOptions === 'Collection') {
888
+ this.enableOption = false;
889
+ }
890
+
891
+ return !(item.if === "hideControl" && this.enableOption === false);
892
+ },
783
893
  isCurrentPageEmpty(currentPage) {
784
894
  return this.config[currentPage]?.items?.length === 0;
785
895
  },
@@ -895,6 +1005,7 @@ export default {
895
1005
  accordion.open = true;
896
1006
  },
897
1007
  migrateConfig(config = this.config) {
1008
+ this.addUuidToElements(config);
898
1009
  config.forEach((page) => this.replaceFormText(page.items));
899
1010
  config.forEach((page) => this.migrateFormSubmit(page.items));
900
1011
  config.forEach((page) => this.updateFieldNameValidation(page.items));
@@ -1078,10 +1189,14 @@ export default {
1078
1189
  });
1079
1190
  },
1080
1191
  updateState() {
1192
+ // paste the clipboard items into the current page
1193
+ this.replaceClipboardContent(this.config);
1081
1194
  this.$store.dispatch("undoRedoModule/pushState", {
1082
1195
  config: JSON.stringify(this.config),
1083
1196
  currentPage: this.currentPage
1084
1197
  });
1198
+ this.replaceClipboardContent([this.clipboardPage]);
1199
+ this.$store.dispatch("clipboardModule/pushState", this.clipboardPage.items);
1085
1200
  },
1086
1201
  async undo() {
1087
1202
  this.inspect();
@@ -1105,8 +1220,14 @@ export default {
1105
1220
  this.$store.getters["undoRedoModule/currentState"].currentPage
1106
1221
  );
1107
1222
  },
1223
+ openTemplatesPanel() {
1224
+ this.showTemplatesPanel = true;
1225
+ },
1226
+ closeTemplatesPanel() {
1227
+ this.showTemplatesPanel = false;
1228
+ },
1108
1229
  updateConfig(items) {
1109
- this.config[this.currentPage].items = items;
1230
+ this.extendedPages[this.currentPage].items = items;
1110
1231
  this.updateState();
1111
1232
  },
1112
1233
  hasError(element) {
@@ -1154,13 +1275,14 @@ export default {
1154
1275
  },
1155
1276
  deleteItem(index) {
1156
1277
  // Remove the item from the array in currentPage
1157
- this.config[this.currentPage].items.splice(index, 1);
1278
+ this.extendedPages[this.currentPage].items.splice(index, 1);
1158
1279
  this.inspection.inspector.splice(0, this.inspection.inspector.length);
1159
1280
  this.updateState();
1160
1281
  },
1161
1282
  duplicateItem(index) {
1162
1283
  const duplicate = _.cloneDeep(this.config[this.currentPage].items[index]);
1163
- this.config[this.currentPage].items.push(duplicate);
1284
+ this.updateUuids(duplicate);
1285
+ this.extendedPages[this.currentPage].items.push(duplicate);
1164
1286
  },
1165
1287
  openEditPageModal(index) {
1166
1288
  this.editPageIndex = index;
@@ -1263,8 +1385,10 @@ export default {
1263
1385
  currentPage: this.currentPage,
1264
1386
  deletedPage: true
1265
1387
  });
1388
+ this.$store.dispatch("clipboardModule/pushState", this.clipboardPage.items);
1266
1389
  },
1267
1390
  inspect(element = {}) {
1391
+ this.closeTemplatesPanel();
1268
1392
  this.inspection = element;
1269
1393
  this.selected = element;
1270
1394
  const defaultAccordion = this.accordions.find(
@@ -1278,6 +1402,7 @@ export default {
1278
1402
  // This will ensure each control in the editor has it's own config and it's not shared
1279
1403
  cloneControl(control) {
1280
1404
  const copy = {
1405
+ uuid: this.generateUUID(),
1281
1406
  config: JSON.parse(JSON.stringify(control.config)),
1282
1407
  inspector: JSON.parse(JSON.stringify(control.inspector)),
1283
1408
  component: control.component,
@@ -1398,7 +1523,6 @@ export default {
1398
1523
  this.updateState();
1399
1524
  this.inspect(clone);
1400
1525
  },
1401
-
1402
1526
  }
1403
1527
  };
1404
1528
  </script>
@@ -1532,6 +1656,12 @@ $side-bar-font-size: 0.875rem;
1532
1656
  .inspector-column {
1533
1657
  max-width: 265px;
1534
1658
  font-size: $side-bar-font-size;
1659
+ border-left: 1px solid rgba(0, 0, 0, 0.125);
1660
+ height: 100%;
1661
+ }
1662
+
1663
+ .screen-templates-column {
1664
+ overflow-y: auto;
1535
1665
  }
1536
1666
 
1537
1667
  .form-control-ghost {
@@ -1568,4 +1698,8 @@ $side-bar-font-size: 0.875rem;
1568
1698
  font-size: 15px;
1569
1699
  font-weight: normal;
1570
1700
  }
1701
+ .gray-text.disabled {
1702
+ cursor: not-allowed; /* Cambia el cursor cuando se pasa por encima */
1703
+ pointer-events: all; /* Permite que el pseudo-elemento reciba eventos del ratón */
1704
+ }
1571
1705
  </style>
@@ -18,6 +18,7 @@
18
18
  :test-screen-definition="testScreenDefinition || false"
19
19
  class="p-0"
20
20
  :loop-context="loopContext"
21
+ :taskdraft="taskdraft"
21
22
  @after-submit="afterSubmit"
22
23
  @submit="submit"
23
24
  />
@@ -60,7 +61,8 @@ export default {
60
61
  "loopContext",
61
62
  "showErrors",
62
63
  "testScreenDefinition",
63
- "deviceScreen"
64
+ "deviceScreen",
65
+ "taskdraft"
64
66
  ],
65
67
  data() {
66
68
  return {
@@ -180,6 +182,9 @@ export default {
180
182
  this.scrollable = Scrollparent(this.$el);
181
183
 
182
184
  this.containerObserver.observe(this.$refs.formRendererContainer);
185
+
186
+ // Initialize the clipboard module
187
+ this.$store.dispatch('clipboardModule/initializeClipboard');
183
188
  },
184
189
  methods: {
185
190
  ...mapActions("globalErrorsModule", [
@@ -362,7 +367,10 @@ export default {
362
367
  // Control coordinates
363
368
  const controlEl = entries[0].target.getBoundingClientRect();
364
369
  this.parseCss();
365
- }
370
+ },
371
+ saveClipboarToLocalStorage(items){
372
+ localStorage.setItem("savedClipboard", JSON.stringify(items));
373
+ },
366
374
  }
367
375
  };
368
376
  </script>