@processmaker/screen-builder 3.0.1 → 3.0.2

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.
@@ -4,7 +4,7 @@
4
4
  <div class="col">
5
5
  <h4>{{ label }}</h4>
6
6
  </div>
7
- <div class="col text-right">
7
+ <div v-if="styleMode === 'Classic'" class="col text-right">
8
8
  <button
9
9
  v-if="editable && !selfReferenced"
10
10
  class="btn btn-primary"
@@ -21,6 +21,7 @@
21
21
  <template v-else>
22
22
  <b-table
23
23
  ref="vuetable"
24
+ :class="tableClassModern"
24
25
  :per-page="perPage"
25
26
  :data-manager="dataManager"
26
27
  :fields="tableFields"
@@ -32,7 +33,9 @@
32
33
  :empty-text="$t('No Data Available')"
33
34
  :current-page="currentPage"
34
35
  data-cy="table"
36
+ :tbody-tr-class="rowClass"
35
37
  >
38
+
36
39
  <!-- Slot header for checkbox (Select All) -->
37
40
  <template #head(checkbox)="data">
38
41
  <b-form-checkbox
@@ -61,7 +64,7 @@
61
64
  </template>
62
65
 
63
66
  <template #cell()="{ index, field, item }">
64
-
67
+
65
68
  <template v-if="isFiledownload(field, item)">
66
69
  <span href="#" @click="downloadFile(item, field.key, index)">{{
67
70
  mustache(field.key, item)
@@ -86,35 +89,71 @@
86
89
  aria-label="Actions"
87
90
  >
88
91
  <button
89
- class="btn btn-primary"
92
+ :class="{
93
+ btn: true,
94
+ 'btn-primary': styleMode === 'Classic'
95
+ }"
90
96
  :title="$t('Edit')"
91
97
  data-cy="edit-row"
92
98
  @click="showEditForm(index, item.row_id)"
93
99
  >
94
- <i class="fas fa-edit" />
100
+
101
+ <i v-if="styleMode === 'Classic'" class="fas fa-edit"></i>
102
+ <img v-else src="../../assets/pencil-square.svg" alt="edit" />
95
103
  </button>
104
+
96
105
  <button
97
- class="btn btn-danger"
106
+ :class="{
107
+ btn: true,
108
+ 'btn-danger': styleMode === 'Classic'
109
+ }"
98
110
  :title="$t('Delete')"
99
111
  data-cy="remove-row"
100
- @click="showDeleteConfirmation(index, item.row_id)"
112
+ popover="manual"
113
+ @click="styleMode === 'Modern'
114
+ ? togglePopover(index, $event, item.row_id)
115
+ : showDeleteConfirmation(index, item.row_id)"
116
+ ref="deleteButton"
101
117
  >
102
- <i class="fas fa-trash-alt" />
118
+ <i v-if="styleMode === 'Classic'" class="fas fa-trash-alt" />
119
+ <img v-else src="../../assets/Shape.svg" alt="delete" />
103
120
  </button>
121
+
122
+ <div v-show="isPopoverVisible === index" class="popover-content">
123
+ <p>Are you sure you want to delete it?</p>
124
+ <button class="btn btn-light" @click="hidePopover">CANCEL</button>
125
+ <button class="btn btn-danger" @click="popover_remove()">DELETE</button>
126
+ </div>
127
+
104
128
  </div>
105
129
  </div>
106
130
  </template>
131
+
107
132
  </b-table>
108
- <b-pagination
109
- v-if="tableData.total > perPage && (perPage !== 0)"
110
- v-model="currentPage"
111
- data-cy="table-pagination"
112
- :total-rows="tableData.total"
113
- :per-page="perPage"
114
- :aria-label="$t('Pagination')"
115
- aria-controls="vuetable"
116
- @change="onChangePage"
117
- />
133
+ <div class="d-flex justify-content-between align-items-center">
134
+ <div class="col text-left">
135
+ <b-pagination
136
+ v-if="tableData.total > perPage && (perPage !== 0)"
137
+ v-model="currentPage"
138
+ data-cy="table-pagination"
139
+ :total-rows="tableData.total"
140
+ :per-page="perPage"
141
+ :aria-label="$t('Pagination')"
142
+ aria-controls="vuetable"
143
+ @change="onChangePage"
144
+ />
145
+ </div>
146
+ <div v-if="styleMode === 'Modern'" class="col text-right">
147
+ <button
148
+ v-if="editable && !selfReferenced"
149
+ class="btn btn-link text-primary class-button-modern"
150
+ data-cy="add-row"
151
+ @click="showAddForm"
152
+ >
153
+ <span class="mr-1">+</span> {{ $t("Add") }}
154
+ </button>
155
+ </div>
156
+ </div>
118
157
  </template>
119
158
 
120
159
  <b-modal
@@ -199,6 +238,7 @@
199
238
  >
200
239
  <p>{{ $t("The form to be displayed is not assigned.") }}</p>
201
240
  </b-modal>
241
+
202
242
  <div v-if="editable && selfReferenced" class="alert alert-danger">
203
243
  {{
204
244
  $t(
@@ -241,7 +281,9 @@ export default {
241
281
  "formWatchers",
242
282
  "_perPage",
243
283
  "source",
244
- "paginationOption"
284
+ "paginationOption",
285
+ "designerMode",
286
+ "bgcolormodern"
245
287
  ],
246
288
  data() {
247
289
  return {
@@ -278,10 +320,30 @@ export default {
278
320
  selectedRows: [],
279
321
  selectedIndex: null,
280
322
  rows: [],
281
- selectAll: false
323
+ selectAll: false,
324
+ styleMode: "Classic",
325
+ isPopoverVisible: null,
326
+ popoverPosition: { top: '0px', left: '0px' }
282
327
  };
283
328
  },
284
329
  computed: {
330
+ tableClassModern() {
331
+ if (this.styleMode === 'Modern') {
332
+ switch (this.bgcolormodern) {
333
+ case 'alert alert-primary':
334
+ return 'record-list-table-primary';
335
+ case 'alert alert-success':
336
+ return 'record-list-table-success';
337
+ case 'alert alert-warning':
338
+ return 'record-list-table-warning';
339
+ case 'alert alert-secondary':
340
+ return 'record-list-table-secondary';
341
+ default:
342
+ return 'record-list-table-secondary';
343
+ }
344
+ }
345
+ return '';
346
+ },
285
347
  indeterminate() {
286
348
  return this.selectedRows.length > 0 && this.selectedRows.length < this.tableData.data.length;
287
349
  },
@@ -420,9 +482,37 @@ export default {
420
482
  this.onCollectionChange(this.source?.collectionFields?.collectionId, this.source?.collectionFields?.pmql);
421
483
  }
422
484
 
485
+ this.setStyleMode(this.designerMode?.designerOptions);
423
486
  this.$root.$emit("record-list-option", this.source?.sourceOptions);
424
487
  },
425
488
  methods: {
489
+ togglePopover(index, event, rowId) {
490
+ this.deleteIndex = _.find(this.tableData.data, { row_id: rowId });
491
+ this.isPopoverVisible = this.isPopoverVisible === index ? null : index;
492
+ if (this.isPopoverVisible !== null) {
493
+ const rect = event.target.getBoundingClientRect();
494
+ this.popoverPosition = {
495
+ top: `${rect.bottom + window.scrollY}px`,
496
+ left: `${rect.left + window.scrollX}px`
497
+ };
498
+ }
499
+ },
500
+ hidePopover() {
501
+ this.isPopoverVisible = null;
502
+ },
503
+ popover_remove() {
504
+ this.remove();
505
+ this.hidePopover();
506
+ },
507
+ rowClass(item) {
508
+ return this.isRowSelected(item) ? 'sel-row' : '';
509
+ },
510
+ isRowSelected(item) {
511
+ return this.selectedRows.includes(item) || this.selectedRow === item;
512
+ },
513
+ setStyleMode(value) {
514
+ this.styleMode = value ? value : "Classic";
515
+ },
426
516
  selectAllRows() {
427
517
  if (this.allRowsSelected) {
428
518
  const updatedRows = this.tableData.data.map((item, index) => {
@@ -769,13 +859,100 @@ export default {
769
859
  // Emit the newly updated data model
770
860
  this.$emit("input", data);
771
861
  this.$root.$emit("removed-record", this, recordData);
772
- }
862
+ },
773
863
  }
774
864
  };
775
865
  </script>
776
866
 
777
- <style>
778
- .table td.table-column {
779
- max-width: 300px;
867
+ <style lang="scss">
868
+ @import '../sortable/tableStyles.scss';
869
+ .popover-content {
870
+ background-color: white;
871
+ border: 1px solid #ddd;
872
+ padding: 10px;
873
+ border-radius: 5px;
874
+ position: fixed;
875
+ z-index: 1000;
876
+ width: 285px;
877
+ text-align: center;
878
+ margin-top: 30px;
879
+ }
880
+ .popover-content p {
881
+ margin: 0 0 10px;
882
+ }
883
+ .popover-content .btn-light {
884
+ margin-right: 5px;
885
+ }
886
+ .sel-row {
887
+ background-color: #eaf2ff;
888
+ }
889
+ .class-button-modern {
890
+ font-size: 14px;
891
+ font-weight: bold;
892
+ text-decoration: none;
893
+ }
894
+
895
+ .record-list-table-base {
896
+ border-collapse: separate;
897
+ border-spacing: 0;
898
+
899
+ thead th {
900
+ border-top: 1px solid;
901
+ border-bottom: 1px solid;
902
+ &:first-child {
903
+ border-top-left-radius: 10px;
904
+ border-left: 1px solid;
905
+ }
906
+ &:last-child {
907
+ border-top-right-radius: 10px;
908
+ border-right: 1px solid;
909
+ }
910
+ }
911
+
912
+ tbody tr {
913
+ td {
914
+ border-bottom: 1px solid;
915
+ }
916
+
917
+ td:first-child {
918
+ border-left: 1px solid;
919
+ }
920
+
921
+ td:last-child {
922
+ border-right: 1px solid;
923
+ }
924
+
925
+ &:last-child {
926
+ td:first-child {
927
+ border-bottom-left-radius: 10px;
928
+ }
929
+ td:last-child {
930
+ border-bottom-right-radius: 10px;
931
+ }
932
+ }
933
+ }
934
+
935
+ th:not(:first-child):not(:last-child),
936
+ td:not(:first-child):not(:last-child) {
937
+ border-left: none;
938
+ border-right: none;
939
+ }
780
940
  }
941
+
942
+ .record-list-table-primary {
943
+ @include record-list-table($primary-bg-color, $primary-border-color);
944
+ }
945
+
946
+ .record-list-table-success {
947
+ @include record-list-table($success-bg-color, $success-border-color);
948
+ }
949
+
950
+ .record-list-table-warning {
951
+ @include record-list-table($warning-bg-color, $warning-border-color);
952
+ }
953
+
954
+ .record-list-table-secondary {
955
+ @include record-list-table($secondary-bg-color, $secondary-border-color);
956
+ }
957
+
781
958
  </style>
@@ -0,0 +1,42 @@
1
+ $primary-bg-color: #f8fbff;
2
+ $primary-border-color: #e6efff;
3
+
4
+ $success-bg-color: #71d188;
5
+ $success-border-color: #28a745;
6
+
7
+ $warning-bg-color: #fff3cd;
8
+ $warning-border-color: #ffc107;
9
+
10
+ $secondary-bg-color: #fbfbfc;
11
+ $secondary-border-color: #f3f5f7;
12
+
13
+ @mixin record-list-table($bg-color, $border-color) {
14
+ @extend .record-list-table-base;
15
+
16
+ thead th {
17
+ background-color: $bg-color;
18
+ border-top-color: $border-color;
19
+ border-bottom-color: $border-color;
20
+ &:first-child {
21
+ border-left-color: $border-color;
22
+ }
23
+ &:last-child {
24
+ border-right-color: $border-color;
25
+ }
26
+ }
27
+
28
+ tbody tr {
29
+ td {
30
+ border-color: $border-color;
31
+ border-top: solid 0;
32
+ }
33
+
34
+ td:first-child {
35
+ border-left-color: $border-color;
36
+ }
37
+
38
+ td:last-child {
39
+ border-right-color: $border-color;
40
+ }
41
+ }
42
+ }
@@ -866,6 +866,7 @@ export default {
866
866
 
867
867
  if (
868
868
  elementDestinationValue &&
869
+ elementDestinationValue !== 'taskSource' &&
869
870
  data?.params[0]?.tokenId === this.taskId &&
870
871
  data?.params[0]?.requestStatus === 'ACTIVE'
871
872
  ) {
@@ -245,7 +245,7 @@
245
245
  v-model="element.items"
246
246
  :validation-errors="validationErrors"
247
247
  class="card-body"
248
- :class="elementCssClass(element)"
248
+ :class="styleMode === 'Modern' ? elementCssClassModern(element) : elementCssClass(element)"
249
249
  :selected="selected"
250
250
  :config="element.config"
251
251
  :ai-element="element"
@@ -299,7 +299,7 @@
299
299
  :tabindex="element.config.interactive ? 0 : -1"
300
300
  class="card-body m-0 pb-4 pt-4"
301
301
  :class="[
302
- elementCssClass(element),
302
+ styleMode === 'Modern' ? elementCssClassModern(element) : elementCssClass(element),
303
303
  { 'prevent-interaction': !element.config.interactive }
304
304
  ]"
305
305
  @input="
@@ -376,7 +376,7 @@
376
376
  v-model="accordion.open"
377
377
  >
378
378
  <component
379
- v-if="shouldShow(item)"
379
+ v-if="shouldShow(item, accordion)"
380
380
  :is="item.type"
381
381
  v-for="(item, index) in getInspectorFields(accordion)"
382
382
  :key="index"
@@ -694,8 +694,10 @@ export default {
694
694
  collapse: {},
695
695
  groupOrder: {},
696
696
  searchProperties: ['name'],
697
- showTemplatesPanel: false,
698
- enableOption: true
697
+ enableOption: true,
698
+ enableDesignOption: true,
699
+ styleMode: null,
700
+ showTemplatesPanel: false
699
701
  };
700
702
  },
701
703
  computed: {
@@ -711,7 +713,7 @@ export default {
711
713
  clipboardItems() {
712
714
  return this.$store.getters["clipboardModule/clipboardItems"];
713
715
  },
714
-
716
+
715
717
  sortedPages() {
716
718
  return [...this.config].sort((a, b) => a.order - b.order);
717
719
  },
@@ -855,6 +857,9 @@ export default {
855
857
  this.$root.$on("ai-form-progress-updated", (progress, nonce) => {
856
858
  this.updateProgress(progress, nonce);
857
859
  });
860
+ this.$root.$on("style-mode", (mode) => {
861
+ this.styleMode = mode;
862
+ });
858
863
  this.setGroupOrder(defaultGroupOrder);
859
864
  },
860
865
  methods: {
@@ -876,7 +881,7 @@ export default {
876
881
  this.$refs.tabsBar.openClipboard();
877
882
  });
878
883
  },
879
- shouldShow(item) {
884
+ shouldShow(item, accordion) {
880
885
  const sourceOptions = this.inspection.config[item.field]?.sourceOptions;
881
886
 
882
887
  if (sourceOptions === 'Variable') {
@@ -888,6 +893,21 @@ export default {
888
893
  this.enableOption = false;
889
894
  }
890
895
 
896
+ if(this.styleMode === "Modern") {
897
+ this.enableDesignOption = false;
898
+ } else {
899
+ this.enableDesignOption = true;
900
+ }
901
+
902
+ if(accordion.name === "Design") {
903
+ if(item.type === "ColorSelectRecord" && !this.enableDesignOption) {
904
+ return false;
905
+ }
906
+ if(item.type === "ColorSelectModern" && this.enableDesignOption ) {
907
+ return false;
908
+ }
909
+ }
910
+
891
911
  return !(item.if === "hideControl" && this.enableOption === false);
892
912
  },
893
913
  isCurrentPageEmpty(currentPage) {
@@ -1189,6 +1209,9 @@ export default {
1189
1209
  });
1190
1210
  },
1191
1211
  updateState() {
1212
+ if (this.selected) {
1213
+ this.checkAndRefreshUuids(this.selected, this.clipboardPage.items);
1214
+ }
1192
1215
  // paste the clipboard items into the current page
1193
1216
  this.replaceClipboardContent(this.config);
1194
1217
  this.$store.dispatch("undoRedoModule/pushState", {
@@ -1523,6 +1546,26 @@ export default {
1523
1546
  this.updateState();
1524
1547
  this.inspect(clone);
1525
1548
  },
1549
+ /**
1550
+ * Compares a config with an array and updates UUIDs if different.
1551
+ *
1552
+ * @param {Object} selected - The config to compare.
1553
+ * @param {Array<Object>} clipboardItems - Array of configs to check.
1554
+ * @returns {Array<Object>} - Updated array with new UUIDs.
1555
+ */
1556
+ checkAndRefreshUuids(selected, clipboardItems) {
1557
+ return clipboardItems.map(config => {
1558
+ // Use lodash to compare the config objects
1559
+ const isEqual = _.isEqual(selected.config, config.config);
1560
+
1561
+ // If they are not equal, update the UUID
1562
+ if (!isEqual) {
1563
+ config.uuid = this.generateUUID(); // Update UUID
1564
+ }
1565
+
1566
+ return config;
1567
+ });
1568
+ },
1526
1569
  }
1527
1570
  };
1528
1571
  </script>
@@ -46,6 +46,9 @@ import {
46
46
  tooltipProperty,
47
47
  LoadingSubmitButtonProperty,
48
48
  LabelSubmitButtonProperty,
49
+ bgcolorModern,
50
+ bgcolorPropertyRecord,
51
+ colorPropertyRecord,
49
52
  } from './form-control-common-properties';
50
53
 
51
54
  export default [
@@ -557,8 +560,17 @@ export default [
557
560
  },
558
561
  if: 'hideControl'
559
562
  },
560
- colorProperty,
561
- bgcolorProperty,
563
+ {
564
+ type: 'collectionDesignerMode',
565
+ field: 'designerMode',
566
+ config: {
567
+ label: 'Table Style',
568
+ helper: ''
569
+ }
570
+ },
571
+ colorPropertyRecord,
572
+ bgcolorPropertyRecord,
573
+ bgcolorModern
562
574
  ],
563
575
  },
564
576
  },
@@ -1,6 +1,33 @@
1
1
  import Tooltip from './components/inspector/tooltip';
2
2
  import DeviceVisibility from './components/inspector/device-visibility';
3
3
 
4
+ export const bgcolorModern = {
5
+ type: 'ColorSelectModern',
6
+ field: 'bgcolormodern',
7
+ config: {
8
+ label: '',
9
+ helper: '',
10
+ options: [
11
+ {
12
+ value: 'alert alert-primary',
13
+ content: 'primary',
14
+ },
15
+ {
16
+ value: 'alert alert-success',
17
+ content: 'success',
18
+ },
19
+ {
20
+ value: 'alert alert-warning',
21
+ content: 'warning',
22
+ },
23
+ {
24
+ value: 'alert alert-secondary',
25
+ content: 'secondary',
26
+ },
27
+ ],
28
+ },
29
+ };
30
+
4
31
  export const bgcolorProperty = {
5
32
  type: 'ColorSelect',
6
33
  field: 'bgcolor',
@@ -44,6 +71,49 @@ export const bgcolorProperty = {
44
71
  },
45
72
  };
46
73
 
74
+ export const bgcolorPropertyRecord = {
75
+ type: 'ColorSelectRecord',
76
+ field: 'bgcolor',
77
+ config: {
78
+ label: 'Background Color',
79
+ helper: 'Set the element\'s background color',
80
+ options: [
81
+ {
82
+ value: 'alert alert-primary',
83
+ content: 'primary',
84
+ },
85
+ {
86
+ value: 'alert alert-secondary',
87
+ content: 'secondary',
88
+ },
89
+ {
90
+ value: 'alert alert-success',
91
+ content: 'success',
92
+ },
93
+ {
94
+ value: 'alert alert-danger',
95
+ content: 'danger',
96
+ },
97
+ {
98
+ value: 'alert alert-warning',
99
+ content: 'warning',
100
+ },
101
+ {
102
+ value: 'alert alert-info',
103
+ content: 'info',
104
+ },
105
+ {
106
+ value: 'alert alert-light',
107
+ content: 'light',
108
+ },
109
+ {
110
+ value: 'alert alert-dark',
111
+ content: 'dark',
112
+ },
113
+ ],
114
+ },
115
+ };
116
+
47
117
  export const colorProperty = {
48
118
  type: 'ColorSelect',
49
119
  field: 'color',
@@ -87,6 +157,49 @@ export const colorProperty = {
87
157
  },
88
158
  };
89
159
 
160
+ export const colorPropertyRecord = {
161
+ type: 'ColorSelectRecord',
162
+ field: 'color',
163
+ config: {
164
+ label: 'Text Color',
165
+ helper: 'Set the element\'s text color',
166
+ options: [
167
+ {
168
+ value: 'text-primary',
169
+ content: 'primary',
170
+ },
171
+ {
172
+ value: 'text-secondary',
173
+ content: 'secondary',
174
+ },
175
+ {
176
+ value: 'text-success',
177
+ content: 'success',
178
+ },
179
+ {
180
+ value: 'text-danger',
181
+ content: 'danger',
182
+ },
183
+ {
184
+ value: 'text-warning',
185
+ content: 'warning',
186
+ },
187
+ {
188
+ value: 'text-info',
189
+ content: 'info',
190
+ },
191
+ {
192
+ value: 'text-light',
193
+ content: 'light',
194
+ },
195
+ {
196
+ value: 'text-dark',
197
+ content: 'dark',
198
+ },
199
+ ],
200
+ },
201
+ };
202
+
90
203
  // Ref https://mathiasbynens.be/notes/javascript-identifiers
91
204
  export const javascriptReservedKeywords = 'null,break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with,class,const,enum,export,extends,import,super,true,false';
92
205
 
@@ -96,8 +209,8 @@ export const keyNameProperty = {
96
209
  config: {
97
210
  label: 'Variable Name',
98
211
  name: 'Variable Name',
99
- // Update tests/e2e/specs/Builder.spec.js when changing this
100
- validation: 'regex:/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(?<!\\.)$/|required|not_in:' + javascriptReservedKeywords,
212
+ // Update tests/e2e/specs/Builder.spec.js when changing dot_notation
213
+ validation: 'dot_notation|required|not_in:' + javascriptReservedKeywords,
101
214
  helper: 'A variable name is a symbolic name to reference information.',
102
215
  },
103
216
  };
@@ -58,11 +58,17 @@ export default {
58
58
  addUuidToElements(screenConfig) {
59
59
  const replaceInPage = (page) => {
60
60
  page.items.forEach((item, index) => {
61
- if (!item.uuid) {
62
- item.uuid = this.generateUUID();
63
- }
64
- if (item.items) {
65
- replaceInPage(item);
61
+ if (item instanceof Array) {
62
+ // multi-column each item in the column
63
+ replaceInPage({ items: item });
64
+ } else {
65
+ // loop through children
66
+ if (!item.uuid) {
67
+ item.uuid = this.generateUUID();
68
+ }
69
+ if (item.items) {
70
+ replaceInPage(item);
71
+ }
66
72
  }
67
73
  });
68
74
  }
@@ -7,6 +7,11 @@ export default {
7
7
  element.config.color ? css.push(element.config.color) : null;
8
8
  return css.join(' ');
9
9
  },
10
+ elementCssClassModern(element) {
11
+ const css = [];
12
+ element.config.bgcolormodern ? css.push(element.config.bgcolormodern) : null;
13
+ return css.join(' ');
14
+ }
10
15
  },
11
16
  };
12
17