@processmaker/screen-builder 3.0.1 → 3.0.3

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 (31) hide show
  1. package/dist/vue-form-builder.css +1 -1
  2. package/dist/vue-form-builder.es.js +6134 -5704
  3. package/dist/vue-form-builder.es.js.map +1 -1
  4. package/dist/vue-form-builder.umd.js +51 -51
  5. package/dist/vue-form-builder.umd.js.map +1 -1
  6. package/package.json +3 -3
  7. package/src/assets/Shape.svg +3 -0
  8. package/src/assets/pencil-square.svg +3 -0
  9. package/src/components/ScreenTemplateCard.vue +128 -74
  10. package/src/components/ScreenTemplates.vue +138 -110
  11. package/src/components/accordions.js +1 -1
  12. package/src/components/editor/loop.vue +26 -0
  13. package/src/components/editor/multi-column.vue +26 -0
  14. package/src/components/inspector/collection-data-source.vue +3 -1
  15. package/src/components/inspector/collection-designer-mode.vue +73 -0
  16. package/src/components/inspector/color-select-modern.vue +101 -0
  17. package/src/components/inspector/encrypted-config.vue +1 -1
  18. package/src/components/inspector/index.js +3 -0
  19. package/src/components/renderer/file-upload.vue +60 -13
  20. package/src/components/renderer/form-collection-record-control.vue +5 -4
  21. package/src/components/renderer/form-collection-view-control.vue +2 -2
  22. package/src/components/renderer/form-masked-input.vue +7 -5
  23. package/src/components/renderer/form-record-list.vue +200 -23
  24. package/src/components/sortable/tableStyles.scss +42 -0
  25. package/src/components/task.vue +82 -38
  26. package/src/components/vue-form-builder.vue +84 -7
  27. package/src/form-builder-controls.js +14 -2
  28. package/src/form-control-common-properties.js +115 -2
  29. package/src/main.js +8 -0
  30. package/src/mixins/Clipboard.js +15 -5
  31. package/src/mixins/HasColorProperty.js +5 -0
@@ -61,32 +61,34 @@
61
61
  </ul>
62
62
  </template>
63
63
  </uploader-list>
64
- <uploader-drop v-if="uploaderLoaded && isConversationalForm" class="form-control-file">
64
+ <uploader-drop v-if="uploaderLoaded && isConversationalForm" class="form-control-file"
65
+ :class="this.files.length > 0 && !this.multipleUpload ? 'cf-single-file-upload' : ''"
66
+ >
65
67
  <b-button
66
68
  v-if="!required"
67
69
  @click="cfSkipFileUpload"
68
- class="btn cf-skip-btn mb-3"
70
+ class="btn cf-skip-btn"
71
+ :class="showMultiUploadButton ? 'mb-3' : ''"
69
72
  >
70
73
  <i class="fas fa-arrow-left mr-2"></i> {{ $t('Skip Uploading') }}
71
74
  </b-button>
72
-
73
75
  <uploader-btn
74
76
  :attrs="nativeButtonAttrs"
75
77
  :class="[
76
78
  { disabled: disabled },
77
79
  'btn',
78
- showSingleUploadButton ? 'cf-single-upload-btn' : (showMultiUploadButton ? 'cf-multi-upload-btn' : '')
80
+ showSingleUploadButton || files.length === 0 && !showMultiUploadButton ? 'cf-single-upload-btn mt-3' : (showMultiUploadButton ? 'cf-multi-upload-btn' : '')
79
81
  ]"
80
82
  tabindex="0"
81
83
  v-on:keyup.native="browse"
82
84
  :aria-label="$attrs['aria-label']"
83
85
  >
84
- <span v-if="showSingleUploadButton"><i class="far fa-image mr-2"></i> {{ $t('Add File/Photo') }}</span>
86
+ <span v-if="showSingleUploadButton || files.length === 0 && !showMultiUploadButton"><i class="far fa-image mr-2"></i> {{ $t('Add File/Photo') }}</span>
85
87
  <span v-else-if="showMultiUploadButton"><i class="fas fa-plus mr-2"></i> {{ $t('Add another') }}</span>
86
88
  </uploader-btn>
87
89
 
88
- <b-button v-if="files.length !== 0" class="cf-file-upload-submit" variant="primary" @click="emitConversationalFormSubmit" :aria-label="$t('Submit')">
89
- <i class="fas fa-paper-plane"></i> <span v-if="files.length !== 0 && showMultiUploadButton">{{ $t('Send All') }}</span>
90
+ <b-button v-if="files.length !== 0" class="cf-file-upload-submit" :class="!showMultiUploadButton ? 'w-100 mt-3' : ''" variant="primary" @click="emitConversationalFormSubmit" :aria-label="$t('Submit')">
91
+ <i class="fas fa-paper-plane"></i> <span v-if="showMultiUploadButton">{{ $t('Send All') }}</span> <span v-else>{{ $t('Submit File/Photo') }}</span>
90
92
  </b-button>
91
93
  </uploader-drop>
92
94
 
@@ -156,6 +158,10 @@ export default {
156
158
  this.removeDefaultClasses();
157
159
  },
158
160
  mounted() {
161
+ if (this.value) {
162
+ this.fetchFiles();
163
+ }
164
+
159
165
  this.$root.$on('set-upload-data-name',
160
166
  (recordList, index, id) => this.listenRecordList(recordList, index, id));
161
167
 
@@ -270,7 +276,7 @@ export default {
270
276
  return this.screenType === 'conversational-forms';
271
277
  },
272
278
  showSingleUploadButton() {
273
- return this.files.length === 0 || !this.multipleUpload;
279
+ return this.files.length === 0 && !this.multipleUpload;
274
280
  },
275
281
  showMultiUploadButton() {
276
282
  return this.files.length !== 0 && this.multipleUpload;
@@ -402,7 +408,6 @@ export default {
402
408
  },
403
409
  setRequestFiles() {
404
410
  _.set(window, `PM4ConfigOverrides.requestFiles["${this.fileDataName}"]`, this.files);
405
- console.log("!!!!!! SET REQUEST FILES", this.valueToSend());
406
411
  this.$emit('input', this.valueToSend());
407
412
  },
408
413
  valueToSend() {
@@ -491,7 +496,7 @@ export default {
491
496
  }
492
497
  this.$delete(this.nativeFiles, id);
493
498
  }
494
-
499
+ this.$emit('file-deleted', this.files);
495
500
  },
496
501
  addToFiles(fileInfo) {
497
502
  if (this.multipleUpload) {
@@ -528,6 +533,19 @@ export default {
528
533
  this.prefix = parent.loopContext + '.';
529
534
  }
530
535
  },
536
+ validateFile(file, acceptFiles){
537
+ const extensions = acceptFiles.filter(item => item.startsWith('.'));
538
+ const mimeTypes = acceptFiles.filter(item => !item.startsWith('.'));
539
+ const fileExtension = '.' + file.name.split('.').pop().toLowerCase();
540
+ const fileType = file.fileType;
541
+ const isExtensionValid = extensions.includes(fileExtension);
542
+ const isMimeTypeValid = mimeTypes.includes(fileType);
543
+
544
+ if (!isExtensionValid && !isMimeTypeValid) {
545
+ return false;
546
+ }
547
+ return true;
548
+ },
531
549
  addFile(file) {
532
550
  if (this.disabled) {
533
551
  file.ignored = true;
@@ -544,7 +562,7 @@ export default {
544
562
 
545
563
  if (this.filesAccept) {
546
564
  file.ignored = true;
547
- if (this.filesAccept.indexOf(file.fileType) !== -1) {
565
+ if (this.validateFile(file, this.filesAccept)) {
548
566
  file.ignored = false;
549
567
  }
550
568
  if (file.ignored) {
@@ -583,6 +601,10 @@ export default {
583
601
  }
584
602
 
585
603
  if (displayMessage.length > 0) {
604
+ const data = JSON.parse(displayMessage);
605
+ if (data.message) {
606
+ displayMessage = data.message;
607
+ }
586
608
  window.ProcessMaker.alert(`${this.$t('File Upload Error:')} ${displayMessage}`, 'danger');
587
609
  }
588
610
 
@@ -612,7 +634,6 @@ export default {
612
634
  this.$set(this.nativeFiles, id, rootFile);
613
635
  this.addToFiles(fileInfo);
614
636
  } else {
615
- console.log("!!!!!! FILE UPLOADED", name);
616
637
  this.$emit('input', name);
617
638
  }
618
639
  },
@@ -686,7 +707,29 @@ export default {
686
707
  },
687
708
  cfSkipFileUpload() {
688
709
  this.$emit('cf-skip-file-upload');
689
- }
710
+ },
711
+ async fetchFiles() {
712
+ const fileIds = Array.isArray(this.value) ? this.value : [this.value];
713
+
714
+ const fetchPromises = fileIds.map(async (file) => {
715
+ const id = file?.file ?? file;
716
+ const endpoint = `files/${id}`;
717
+ try {
718
+ const response = await ProcessMaker.apiClient.get(endpoint);
719
+ if (response?.data) {
720
+ const fileExists = this.files.some(existingFile => existingFile.id === response.data.id);
721
+ // Check if the file already exists in the list before adding it.
722
+ if (!fileExists) {
723
+ this.files.push(response.data);
724
+ }
725
+ }
726
+ } catch (error) {
727
+ console.error(`Failed to fetch file ${id}`, error);
728
+ }
729
+ });
730
+
731
+ return await Promise.all(fetchPromises);
732
+ },
690
733
  },
691
734
  };
692
735
  </script>
@@ -750,4 +793,8 @@ export default {
750
793
  box-shadow: 0px 12px 24px -12px #0000001F;
751
794
  }
752
795
 
796
+ .form-control-file.cf-single-file-upload label {
797
+ display: none;
798
+ }
799
+
753
800
  </style>
@@ -16,6 +16,7 @@
16
16
  <script>
17
17
  import VueFormRenderer from "../vue-form-renderer.vue";
18
18
  import CollectionRecordsList from "../inspector/collection-records-list.vue";
19
+ import _ from 'lodash';
19
20
 
20
21
  const globalObject = typeof window === "undefined" ? global : window;
21
22
 
@@ -179,12 +180,12 @@ export default {
179
180
  this.selDisplayMode === "View" ? viewScreen : editScreen;
180
181
 
181
182
  this.loadScreen(this.screenCollectionId);
182
-
183
+
183
184
  //This section validates if Collection has draft data
184
185
  if(this.taskDraft?.draft?.data == null || this.taskDraft.draft.data === '') {
185
186
  this.localData = respData;
186
187
  }else{
187
- this.localData = this.taskDraft.draft.data;
188
+ this.localData = _.merge({}, respData, this.taskDraft.draft.data);
188
189
  }
189
190
 
190
191
  })
@@ -212,9 +213,9 @@ export default {
212
213
  },
213
214
  record(record) {
214
215
  this.hasMustache = false;
215
- if (record && !isNaN(record) && record > 0 && this.collection) {
216
+ if (record && !isNaN(record) && record > 0 && this.collection.collectionId) {
216
217
  this.selRecordId = record;
217
- this.loadRecordCollection(this.selCollectionId, record, this.collectionmode);
218
+ this.loadRecordCollection(this.collection.collectionId, record, this.selDisplayMode);
218
219
  } else {
219
220
  if (this.isMustache(record)) {
220
221
  this.callbackRecord();
@@ -206,9 +206,9 @@ export default {
206
206
  },
207
207
  record(record) {
208
208
  this.hasMustache = false;
209
- if (record && !isNaN(record) && record > 0 && this.collection) {
209
+ if (record && !isNaN(record) && record > 0 && this.collection.collectionId) {
210
210
  this.selRecordId = record;
211
- this.loadRecordCollection(this.selCollectionId, record, this.collectionmode);
211
+ this.loadRecordCollection(this.collection.collectionId, record, this.collectionmode);
212
212
  } else {
213
213
  if (this.isMustache(record)) {
214
214
  this.callbackRecord();
@@ -41,7 +41,7 @@
41
41
  <input
42
42
  v-else
43
43
  v-model="localValue"
44
- v-bind="componentConfig"
44
+ v-bind="componentConfigEncField"
45
45
  v-uni-id="name"
46
46
  :name="name"
47
47
  class="form-control"
@@ -231,6 +231,7 @@ export default {
231
231
  labelBtn: '',
232
232
  errorEncryptedField: '',
233
233
  concealExecuted: false,
234
+ componentConfigEncField: null,
234
235
  };
235
236
  },
236
237
  computed: {
@@ -289,17 +290,18 @@ export default {
289
290
  * "encrypted" attribute is enabled
290
291
  */
291
292
  if (this.encryptedConfig?.encrypted) {
293
+ this.componentConfigEncField = JSON.parse(JSON.stringify(this.componentConfig));
292
294
  if (uuidValidate(this.localValue)) {
293
295
  this.inputType = "password";
294
296
  this.iconBtn = "fas fa-eye";
295
297
  this.labelBtn = this.$t("Reveal");
296
298
  this.concealExecuted = true;
297
- this.componentConfig.readonly = true;
299
+ this.componentConfigEncField.readonly = true;
298
300
  } else {
299
301
  this.inputType = "text";
300
302
  this.iconBtn = "fas fa-eye-slash";
301
303
  this.labelBtn = this.$t("Conceal");
302
- this.componentConfig.readonly = false;
304
+ this.componentConfigEncField.readonly = this.componentConfig.readonly;
303
305
  }
304
306
  } else {
305
307
  this.inputType = this.dataType;
@@ -381,7 +383,7 @@ export default {
381
383
  this.iconBtn = "fas fa-eye";
382
384
  this.labelBtn = this.$t("Reveal");
383
385
  this.concealExecuted = true;
384
- this.componentConfig.readonly = true;
386
+ this.componentConfigEncField.readonly = true;
385
387
  this.errorEncryptedField = "";
386
388
 
387
389
  // Assign uuid from encrypted data
@@ -392,7 +394,7 @@ export default {
392
394
  this.inputType = this.dataType;
393
395
  this.iconBtn = "fas fa-eye-slash";
394
396
  this.labelBtn = this.$t("Conceal");
395
- this.componentConfig.readonly = false;
397
+ this.componentConfigEncField.readonly = this.componentConfig.readonly;
396
398
 
397
399
  // Assign value decrypted
398
400
  this.localValue = decryptedValue;
@@ -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
+ }