@usssa/component-library 1.0.0-alpha.21 → 1.0.0-alpha.210

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 (97) hide show
  1. package/README.md +8 -5
  2. package/package.json +25 -6
  3. package/src/assets/fonts/CorneroRegular.woff +0 -0
  4. package/src/assets/fonts/CorneroRegular.woff2 +0 -0
  5. package/src/assets/logo.svg +19 -0
  6. package/src/assets/no-result.svg +25 -0
  7. package/src/assets/upload-illustration.svg +48 -0
  8. package/src/components/core/UAccordionSelect.vue +237 -0
  9. package/src/components/core/UAvatar.vue +90 -26
  10. package/src/components/core/UAvatarGroup.vue +62 -52
  11. package/src/components/core/UBadgeStd.vue +6 -1
  12. package/src/components/core/UBannerStd.vue +100 -31
  13. package/src/components/core/UBreadCrumbs.vue +171 -0
  14. package/src/components/core/UBtnIcon.vue +57 -52
  15. package/src/components/core/UBtnStd.vue +38 -31
  16. package/src/components/core/UBtnToggle.vue +11 -6
  17. package/src/components/core/UCheckboxStd.vue +26 -20
  18. package/src/components/core/UChip.vue +91 -43
  19. package/src/components/core/UDate.vue +581 -0
  20. package/src/components/core/UDialogStd.vue +452 -58
  21. package/src/components/core/UDrawer/UDrawer.vue +471 -0
  22. package/src/components/core/UDrawer/UDrawerMenuItem.vue +124 -0
  23. package/src/components/core/UEventCard.vue +419 -0
  24. package/src/components/core/UExpansionStd.vue +274 -0
  25. package/src/components/core/UExpansionTableStd.vue +297 -0
  26. package/src/components/core/UFilter.vue +89 -0
  27. package/src/components/core/UGameObject.vue +441 -0
  28. package/src/components/core/UInnerLoader.vue +69 -0
  29. package/src/components/core/UInputAddressLookup.vue +484 -0
  30. package/src/components/core/UInputPhoneStd.vue +74 -68
  31. package/src/components/core/UInputTextStd.vue +137 -116
  32. package/src/components/core/UInputTypeahead.vue +44 -0
  33. package/src/components/core/UInputTypeaheadAdvanceSearch.vue +134 -0
  34. package/src/components/core/UMenuButtonStd.vue +280 -0
  35. package/src/components/core/UMenuDropdown.vue +82 -0
  36. package/src/components/core/UMenuDropdownAdvancedSearch.vue +306 -0
  37. package/src/components/core/UMenuItem.vue +221 -0
  38. package/src/components/core/UMenuSearch.vue +73 -0
  39. package/src/components/core/UModal.vue +660 -0
  40. package/src/components/core/UMultiSelectStd.vue +501 -61
  41. package/src/components/core/UPagination.vue +84 -25
  42. package/src/components/core/URadioBtn.vue +66 -43
  43. package/src/components/core/URadioStd.vue +23 -14
  44. package/src/components/core/USelectStd.vue +415 -84
  45. package/src/components/core/USheet.vue +349 -0
  46. package/src/components/core/UStepper/UProgress.vue +157 -0
  47. package/src/components/core/UStepper/UStepper.vue +211 -0
  48. package/src/components/core/UTabBtnStd.vue +36 -22
  49. package/src/components/core/UTable/UTable.vue +2055 -57
  50. package/src/components/core/UTableStd.vue +1301 -273
  51. package/src/components/core/UTabsStd.vue +52 -23
  52. package/src/components/core/UToggleStd.vue +18 -13
  53. package/src/components/core/UToolbar/UCustomMenuIcon.vue +58 -0
  54. package/src/components/core/UToolbar/UToolbar.vue +226 -0
  55. package/src/components/core/UTooltip.vue +31 -10
  56. package/src/components/core/UTypeahead.vue +890 -0
  57. package/src/components/core/UUploader.vue +644 -0
  58. package/src/components/index.js +77 -26
  59. package/src/composables/useNotify.js +16 -16
  60. package/src/composables/useOverlayLoader.js +23 -0
  61. package/src/composables/useScreenType.js +30 -0
  62. package/src/css/app.sass +42 -25
  63. package/src/css/colors.sass +2 -0
  64. package/src/css/quasar.variables.sass +99 -68
  65. package/src/css/vars/colors.variables.sass +28 -41
  66. package/src/utils/data.ts +177 -0
  67. package/src/App.vue +0 -9
  68. package/src/boot/.gitkeep +0 -0
  69. package/src/layouts/MainLayout.vue +0 -137
  70. package/src/pages/Avatar.vue +0 -77
  71. package/src/pages/AvatarGroup.vue +0 -139
  72. package/src/pages/BadgeStd.vue +0 -83
  73. package/src/pages/BannerPage.vue +0 -76
  74. package/src/pages/BtnIcon.vue +0 -120
  75. package/src/pages/BtnStd.vue +0 -126
  76. package/src/pages/BtnToggle.vue +0 -131
  77. package/src/pages/CheckBox.vue +0 -62
  78. package/src/pages/Chip.vue +0 -92
  79. package/src/pages/ComponentBase.vue +0 -54
  80. package/src/pages/Dialog.vue +0 -206
  81. package/src/pages/ErrorNotFound.vue +0 -11
  82. package/src/pages/IndexPage.vue +0 -11
  83. package/src/pages/InputPhone.vue +0 -152
  84. package/src/pages/InputText.vue +0 -139
  85. package/src/pages/MultiSelectStd.vue +0 -174
  86. package/src/pages/NotifyPage.vue +0 -109
  87. package/src/pages/Pagination.vue +0 -71
  88. package/src/pages/Radio.vue +0 -80
  89. package/src/pages/RadioBtn.vue +0 -104
  90. package/src/pages/SelectStd.vue +0 -160
  91. package/src/pages/TabButtonPage.vue +0 -126
  92. package/src/pages/TablePage.vue +0 -371
  93. package/src/pages/TabsPage.vue +0 -261
  94. package/src/pages/TogglePage.vue +0 -58
  95. package/src/pages/TooltipPage.vue +0 -125
  96. package/src/router/index.js +0 -34
  97. package/src/router/routes.js +0 -113
@@ -1,109 +1,209 @@
1
1
  <script setup>
2
- import UTd from './UTable/UTd.vue'
3
- import UTh from './UTable/UTh.vue'
4
- import UTr from './UTable/UTr.vue'
5
- import UTable from './UTable/UTable.vue'
6
- import { computed, ref } from 'vue'
7
- import UCheckboxStd from './UCheckboxStd.vue'
8
- import UChip from './UChip.vue'
2
+ import { useQuasar } from 'quasar'
3
+ import { computed, ref, watch } from 'vue'
4
+ import { useScreenType } from '../../composables/useScreenType'
9
5
  import UAvatar from './UAvatar.vue'
6
+ import UBtnIcon from './UBtnIcon.vue'
10
7
  import UBtnStd from './UBtnStd.vue'
11
- import UTooltip from './UTooltip.vue'
8
+ import UCheckboxStd from './UCheckboxStd.vue'
9
+ import UChip from './UChip.vue'
10
+ import UMenuDropdown from './UMenuDropdown.vue'
12
11
  import UPagination from './UPagination.vue'
12
+ import UTable from './UTable/UTable.vue'
13
+ import UTd from './UTable/UTd.vue'
14
+ import UTh from './UTable/UTh.vue'
15
+ import UTooltip from './UTooltip.vue'
16
+ import UTr from './UTable/UTr.vue'
17
+
18
+ const emit = defineEmits(['onCustomSort', 'onLoadMore', 'parentPageChange'])
19
+
20
+ const columns = defineModel('columns', {
21
+ default: () => [],
22
+ type: Array,
23
+ })
24
+ const filteredRows = defineModel('filteredRows', { default: [], type: Array })
25
+ const grid = defineModel('grid', {
26
+ default: false,
27
+ type: Boolean,
28
+ })
29
+ const loading = defineModel('loading', {
30
+ default: () => {},
31
+ type: Boolean,
32
+ })
33
+ const moreActionDialogData = defineModel('moreActionDialogData', {
34
+ type: Object,
35
+ default: null,
36
+ })
37
+ const pagination = defineModel('pagination', {
38
+ default: { page: 1, rowsPerPage: 5 },
39
+ type: Object,
40
+ })
41
+ const rows = defineModel('rows', {
42
+ default: () => [],
43
+ type: Array,
44
+ })
45
+ const selectedRows = defineModel('selectedRows', {
46
+ default: () => [],
47
+ type: Array,
48
+ })
13
49
  const props = defineProps({
14
- title: {
50
+ actionBtnAriaLabel: {
15
51
  type: String,
16
- default: '',
52
+ default: 'More actions',
17
53
  },
18
- tableRowHover: {
54
+ applyLabel: {
55
+ type: String,
56
+ default: 'Apply',
57
+ },
58
+ bordered: {
19
59
  type: Boolean,
20
60
  default: false,
21
61
  },
22
- separator: {
62
+ cancelLabel: {
23
63
  type: String,
24
- default: 'horizontal',
64
+ default: 'Cancel',
25
65
  },
26
- multiSelection: {
66
+ closeIconLabel: {
67
+ type: String,
68
+ default: 'Close Icon',
69
+ },
70
+ customClass: {
71
+ type: String,
72
+ default: '',
73
+ },
74
+ dataTestId: {
75
+ type: String,
76
+ default: 'table-std',
77
+ },
78
+ enableIconToggle: {
79
+ type: Boolean,
80
+ default: false,
81
+ },
82
+
83
+ enableGridOn: {
84
+ type: Array,
85
+ default: () => ['tablet', 'mobile'],
86
+ },
87
+ enableMultiColMobileExpansion: {
88
+ type: Boolean,
89
+ default: false,
90
+ },
91
+ expansion: {
27
92
  type: Boolean,
28
93
  default: false,
29
94
  },
95
+ filter: {
96
+ type: String,
97
+ default: '',
98
+ },
30
99
  flat: {
31
100
  type: Boolean,
32
101
  default: false,
33
102
  },
34
- bordered: {
103
+ infiniteScroll: {
35
104
  type: Boolean,
36
105
  default: false,
37
106
  },
38
- grid: {
107
+ infiniteScrollProperty: {
108
+ type: Object,
109
+ default: () => {
110
+ return {
111
+ color: 'primary',
112
+ height: '55rem',
113
+ image: '',
114
+ loading: false,
115
+ loadingMessage: 'Loading data',
116
+ noMoreData: false,
117
+ noMoreDataText: 'No more data',
118
+ padding: true,
119
+ size: '1rem',
120
+ type: 'default',
121
+ }
122
+ },
123
+ },
124
+ isCustomSort: {
39
125
  type: Boolean,
40
126
  default: false,
41
127
  },
42
- virtualScroll: {
128
+ multiSelection: {
43
129
  type: Boolean,
44
130
  default: false,
45
131
  },
132
+ noDataFound: {
133
+ type: String,
134
+ default: 'No Data Found',
135
+ },
136
+ pageOptions: {
137
+ type: Array,
138
+ default: () => [
139
+ { label: '5 / per page', value: 5 },
140
+ { label: '10 / per page', value: 10 },
141
+ { label: '15 / per page', value: 15 },
142
+ { label: '20 / per page', value: 20 },
143
+ { label: '25 / per page', value: 25 },
144
+ ],
145
+ },
146
+ rowCardHeight: {
147
+ type: Number,
148
+ default: 25,
149
+ },
150
+ selectMoreOptions: {
151
+ type: String,
152
+ default: 'Select More Options',
153
+ },
154
+ separator: {
155
+ type: String,
156
+ default: 'horizontal',
157
+ },
158
+ sheetLabel: {
159
+ type: String,
160
+ default: 'Selections Per Page',
161
+ },
162
+ showPagination: {
163
+ type: Boolean,
164
+ default: true,
165
+ },
46
166
  stickyHeader: {
47
167
  type: Boolean,
48
168
  default: false,
49
169
  },
50
- isCustomSort: {
170
+ tableRowHover: {
51
171
  type: Boolean,
52
172
  default: false,
53
173
  },
54
- customClass: {
174
+ title: {
55
175
  type: String,
56
176
  default: '',
57
177
  },
58
- showPagination: {
178
+ verticalMoreActions: {
59
179
  type: Boolean,
60
- default: true,
180
+ default: false,
181
+ },
182
+ viewMoreLabel: {
183
+ type: String,
184
+ default: 'View More',
185
+ },
186
+ virtualScroll: {
187
+ type: Boolean,
188
+ default: false,
61
189
  },
62
190
  })
63
191
 
64
- const selectedRows = defineModel('selectedRows', {
65
- default: () => [],
66
- type: Array,
67
- })
68
- const rows = defineModel('rows', {
69
- default: () => [],
70
- type: Array,
71
- })
72
- const columns = defineModel('columns', {
73
- default: () => [],
74
- type: Array,
75
- })
76
- const pagination = defineModel('pagination', {
77
- default: { page: 1, rowsPerPage: 15 },
78
- type: Object,
79
- })
80
- const loading = defineModel('loading', {
81
- default: () => {},
82
- type: Boolean,
83
- })
84
- const customLoading = ref(false)
85
- const rowsPerPageOptions = ref([
86
- { label: '5 / per page', value: 5 },
87
- { label: '10 / per page', value: 10 },
88
- { label: '15 / per page', value: 15 },
89
- { label: '20 / per page', value: 20 },
90
- { label: '25 / per page', value: 25 },
91
- ])
192
+ const $q = useQuasar()
193
+ const $screen = useScreenType()
92
194
 
195
+ const customLoading = ref(false)
196
+ const rowsPerPageOptions = ref(props.pageOptions)
93
197
  const tableDataChip = ref(true) // this is required to show chip
198
+ const tailClass = ref(null)
94
199
 
95
- //adding a new row to selectedRows
96
- const handleToSelectRow = (row) => {
97
- if (row) {
98
- const index = selectedRows.value.findIndex((item) => item._id === row._id)
99
- if (index === -1) {
100
- selectedRows.value.push(row)
101
- } else {
102
- selectedRows.value.splice(index, 1)
103
- }
104
- }
105
- }
106
- // if virtual scroll is enbaled then adding large rows per page to view in virtual scroll
200
+ const currentScreen = computed(() => {
201
+ if ($screen.value.isDesktop) return 'desktop'
202
+ if ($screen.value.isTablet) return 'tablet'
203
+ return 'mobile'
204
+ })
205
+
206
+ // if virtual scroll is enabled then adding large rows per page to view in virtual scroll
107
207
  const getRowsPerPageOptions = computed(() => {
108
208
  if (props.virtualScroll) {
109
209
  return [
@@ -117,6 +217,76 @@ const getRowsPerPageOptions = computed(() => {
117
217
  }
118
218
  })
119
219
 
220
+ const isMobileOrTablet = computed(
221
+ () => $screen.value.isMobile || $screen.value.isTablet
222
+ )
223
+ const isSmallDevices = computed(() => $q.screen.width < 390)
224
+
225
+ const updatedRows = computed(() => {
226
+ if (props.filter.length && filteredRows.value?.length)
227
+ return filteredRows.value
228
+ else if (props.filter.length) return []
229
+ return rows.value
230
+ })
231
+
232
+ // checking the menu position after show menu
233
+ const checkMenuPosition = (id) => {
234
+ const menuElement = document.getElementById(`actionPopupRef-${id}`) // Access the menu by ID
235
+ const buttonElement = document.getElementById(`actionPopupRefBtn-${id}`) // Access the button element
236
+
237
+ if (menuElement && buttonElement) {
238
+ const menuRect = menuElement.getBoundingClientRect() // Menu position
239
+ const buttonRect = buttonElement.getBoundingClientRect() // Button position
240
+
241
+ // Determine if the menu opens above or below
242
+ if (menuRect.top < buttonRect.top) {
243
+ tailClass.value = 'tail-bottom' // Menu opens below, tail at the bottom
244
+ } else {
245
+ tailClass.value = 'tail-top' // Menu opens above, tail at the top
246
+ }
247
+ }
248
+ }
249
+
250
+ // sorting function to handle text and number type of data
251
+ const dataSort = (data, key, order, type) => {
252
+ if (type === 'text') {
253
+ return data.sort((a, b) =>
254
+ order === 'asc'
255
+ ? a[key].localeCompare(b[key])
256
+ : b[key].localeCompare(a[key])
257
+ )
258
+ } else {
259
+ return data.sort((a, b) =>
260
+ order === 'asc' ? a[key] - b[key] : b[key] - a[key]
261
+ )
262
+ }
263
+ }
264
+
265
+ //getting the chip color accroding to value of chip from row
266
+ const getChipColor = (data, value) => {
267
+ const foundObject = data.find((chip) => chip.value === value)
268
+ if (foundObject) {
269
+ return foundObject['color']
270
+ } else {
271
+ return 'neutral-3'
272
+ }
273
+ }
274
+
275
+ // Methods to filter actions based on responsiveDisplay
276
+ const getInlineActions = (col) => {
277
+ return col.actions.filter((action) => {
278
+ const display = action.responsiveDisplay?.[currentScreen.value] || 'menu'
279
+ return display === 'inline'
280
+ })
281
+ }
282
+
283
+ const getMenuActions = (col) => {
284
+ return col.actions.filter((action) => {
285
+ const display = action.responsiveDisplay?.[currentScreen.value] || 'menu'
286
+ return display === 'menu'
287
+ })
288
+ }
289
+
120
290
  //getting the sorted icon according the order
121
291
  const getSortingIcon = (col) => {
122
292
  if (col) {
@@ -128,45 +298,19 @@ const getSortingIcon = (col) => {
128
298
  }
129
299
  }
130
300
 
131
- // it is giving the selected row and setting the new selection
132
- const isRowSelected = (row) => {
133
- if (row) {
134
- const index = selectedRows.value.findIndex((item) => item._id === row._id)
135
- return computed({
136
- get: () => {
137
- return index === -1 ? false : true
138
- },
139
- set: () => {
140
- if (index === -1) {
141
- selectedRows.value.push(row)
142
- } else {
143
- selectedRows.value.splice(index, 1)
144
- }
145
- },
146
- })
147
- } else {
148
- return computed({
149
- get: () => {
150
- let dataLength = props.rows.length
151
- return selectedRows.value.length === dataLength
152
- ? true
153
- : selectedRows.value.length === 0
154
- ? false
155
- : null
156
- },
157
- set: (value) => {
158
- if (value !== null) {
159
- selectedRows.value.splice(0, selectedRows.value.length)
160
- } else {
161
- handleSelectAllData().then((res) => {
162
- if (res === 200) {
163
- customLoading.value = false
164
- }
165
- })
166
- }
167
- },
168
- })
169
- }
301
+ const handleActionColClick = (e) => {
302
+ e.preventDefault()
303
+ e.stopPropagation()
304
+ }
305
+
306
+ //if user want to add custom sort on data
307
+ const handleCustomSort = (key, sortOrder, type) => {
308
+ emit('onCustomSort', key, sortOrder, type)
309
+ }
310
+
311
+ const handleMenuEventStop = (e) => {
312
+ e.preventDefault()
313
+ e.stopPropagation()
170
314
  }
171
315
 
172
316
  // handling the large selection data in chunks
@@ -199,23 +343,6 @@ const handleSelectAllData = () => {
199
343
  })
200
344
  }
201
345
 
202
- const emit = defineEmits(['onCustomSort'])
203
-
204
- // sorting funtion to handle text and number type of data
205
- const dataSort = (data, key, order, type) => {
206
- if (type === 'text') {
207
- return data.sort((a, b) =>
208
- order === 'asc'
209
- ? a[key].localeCompare(b[key])
210
- : b[key].localeCompare(a[key])
211
- )
212
- } else {
213
- return data.sort((a, b) =>
214
- order === 'asc' ? a[key] - b[key] : b[key] - a[key]
215
- )
216
- }
217
- }
218
-
219
346
  //it is sorting the data according to type like text or number type of data
220
347
  const handleSort = (key, sortOrder, type) => {
221
348
  rows.value = dataSort(rows.value, key, sortOrder, type)
@@ -226,154 +353,258 @@ const handleSort = (key, sortOrder, type) => {
226
353
  })
227
354
  }
228
355
 
229
- //if user want to add custom sort on data
230
- const handleCustomSort = (key, sortOrder, type) => {
231
- emit('onCustomSort', key, sortOrder, type)
232
- }
233
-
234
356
  //adding a new row to selectedRows
235
- const onRowClick = (event, row) => {
236
- if (props.multiSelection) {
237
- event.stopPropagation()
238
- handleToSelectRow(row)
357
+ const handleToSelectRow = (row) => {
358
+ if (row) {
359
+ const index = selectedRows.value.findIndex((item) => item._id === row._id)
360
+ if (index === -1) {
361
+ selectedRows.value.push(row)
362
+ } else {
363
+ selectedRows.value.splice(index, 1)
364
+ }
239
365
  }
240
366
  }
241
367
 
242
- //getting the chip color accroding to value of chip from row
243
- const getChipColor = (data, value) => {
244
- const foundObject = data.find((chip) => chip.value === value)
245
- if (foundObject) {
246
- return foundObject['color']
368
+ // it is giving the selected row and setting the new selection
369
+ const isRowSelected = (row) => {
370
+ if (row) {
371
+ const index = selectedRows.value.findIndex((item) => item._id === row._id)
372
+ return computed({
373
+ get: () => {
374
+ return index === -1 ? false : true
375
+ },
376
+ set: () => {
377
+ if (index === -1) {
378
+ selectedRows.value.push(row)
379
+ } else {
380
+ selectedRows.value.splice(index, 1)
381
+ }
382
+ },
383
+ })
247
384
  } else {
248
- return 'neutral-3'
385
+ return computed({
386
+ get: () => {
387
+ let dataLength = props.rows.length
388
+ return selectedRows.value.length === dataLength
389
+ ? true
390
+ : selectedRows.value.length === 0
391
+ ? false
392
+ : null
393
+ },
394
+ set: (value) => {
395
+ if (value !== null) {
396
+ selectedRows.value.splice(0, selectedRows.value.length)
397
+ } else {
398
+ handleSelectAllData().then((res) => {
399
+ if (res === 200) {
400
+ customLoading.value = false
401
+ }
402
+ })
403
+ }
404
+ },
405
+ })
406
+ }
407
+ }
408
+
409
+ // removing console error for show dialog
410
+ const onMoreActionButtonClick = (id) => {
411
+ if (moreActionDialogData.value) {
412
+ moreActionDialogData.value.showDialog[id] = false
249
413
  }
250
414
  }
251
415
 
252
416
  // handle to change the page, and if virtual scroll is enabled and user scrolled to bottom it will take user to the top
253
417
  const onPageChange = (value) => {
254
418
  pagination.value.page = value
419
+ emit('parentPageChange', value)
420
+ }
421
+
422
+ //adding a new row to selectedRows
423
+ const onRowClick = (event, row) => {
424
+ if (props.multiSelection) {
425
+ event.stopPropagation()
426
+ handleToSelectRow(row)
427
+ }
255
428
  }
256
429
 
257
430
  //handle to change the rows per page
258
431
  const onRowPerPageChange = (value) => {
259
432
  pagination.value.rowsPerPage = value
260
433
  }
434
+
435
+ // watchers
436
+ watch(
437
+ () => currentScreen.value,
438
+ (newVal) => {
439
+ grid.value = props.enableGridOn.includes(newVal)
440
+ },
441
+ { immediate: true }
442
+ )
261
443
  </script>
262
444
 
263
445
  <template>
264
446
  <UTable
265
- :title="title"
266
- v-model:rows="rows"
267
447
  v-model:columns="columns"
268
- :separator="separator"
269
- :loading="loading"
270
- :flat="flat"
271
- :bordered="bordered"
448
+ v-model:filteredRows="filteredRows"
449
+ v-model:moreActionDialogData="moreActionDialogData"
272
450
  v-model:pagination="pagination"
273
- :grid="grid"
274
- :virtualScroll="virtualScroll"
275
- :stickyHeader="stickyHeader"
451
+ v-model:rows="rows"
276
452
  :class="customClass"
277
- :showPagination="showPagination"
453
+ :bordered="bordered"
454
+ :close-icon-label="closeIconLabel"
455
+ :dataTestId="dataTestId"
456
+ :enable-icon-toggle="enableIconToggle"
457
+ :enable-multi-col-mobile-expansion="enableMultiColMobileExpansion"
458
+ :expansion="expansion"
459
+ :filter="filter"
460
+ :flat="flat"
461
+ :grid="grid"
462
+ :infinite-scroll="infiniteScroll"
463
+ :infinite-scroll-property="infiniteScrollProperty"
464
+ :loading="loading"
465
+ :row-card-height="rowCardHeight"
466
+ :select-more-options="selectMoreOptions"
467
+ :separator="separator"
468
+ :show-pagination="showPagination"
469
+ :sticky-header="stickyHeader"
470
+ :title="title"
471
+ :view-more-label="viewMoreLabel"
472
+ :virtual-scroll="virtualScroll"
473
+ @on-load-more="(payload) => $emit('onLoadMore', payload)"
278
474
  >
279
475
  <!-- custom header slot to add customized header -->
280
476
  <template v-slot:header="props">
281
477
  <UTr :props="props" :tableRowHover="tableRowHover">
282
478
  <UTh
283
479
  v-if="multiSelection"
480
+ :separator="separator"
284
481
  style="width: 3% !important"
285
- :tableHeaderAutoWidth="false"
286
482
  tableHeadAlignment="left"
287
- :separator="separator"
483
+ :tableHeaderAutoWidth="false"
288
484
  >
289
485
  <UCheckboxStd
290
- :id="`u-checkbox-table-header`"
291
486
  v-model="isRowSelected(null).value"
292
- name="Table Header"
487
+ id="u-checkbox-table-header"
293
488
  :indeterminate="true"
489
+ name="Table Header"
294
490
  />
295
491
  </UTh>
296
- <UTh
297
- v-for="(col, key) in props.cols"
298
- :class="`${col.sortable ? 'cursor-pointer' : ''} ${
299
- col.headerClasses
300
- }`"
301
- :key="key"
302
- :tableHeaderAutoWidth="col.autoWidth"
303
- :tableHeadAlignment="col.field === 'action' ? col.align : col.align"
304
- @click="
305
- col.sortable
306
- ? isCustomSort
307
- ? handleCustomSort(col.field, col.sortOrder, col.type)
308
- : handleSort(col.field, col.sortOrder, col.type)
309
- : null
310
- "
311
- :separator="separator"
312
- :style="col.headerStyle"
313
- >
314
- {{ col.label }}
315
- <span v-if="col.sortable && col.field !== 'action'">
316
- <q-btn label="Sorting Button" :ripple="false" class="u-sorting-btn">
317
- <q-icon
318
- size="xs"
319
- :class="`${getSortingIcon(col)} sorting-icon`"
320
- :aria-label="col.label"
321
- alt="sort-desc"
322
- tabindex="0"
323
- ></q-icon>
324
- </q-btn>
325
- </span>
326
- </UTh>
492
+ <template v-for="(col, key) in props.cols">
493
+ <UTh
494
+ v-if="typeof col.show === 'undefined' || col.show"
495
+ :class="`${col.sortable ? 'cursor-pointer' : ''} ${
496
+ col.headerClasses
497
+ }`"
498
+ :key="key"
499
+ :separator="separator"
500
+ :style="
501
+ typeof col.headerStyle === 'function'
502
+ ? col.headerStyle($screen)
503
+ : col.headerStyle
504
+ "
505
+ :tableHeadAlignment="col.field === 'action' ? col.align : col.align"
506
+ :tableHeaderAutoWidth="col.autoWidth"
507
+ @click="
508
+ col.sortable
509
+ ? isCustomSort
510
+ ? handleCustomSort(col.field, col.sortOrder, col.type)
511
+ : handleSort(col.field, col.sortOrder, col.type)
512
+ : null
513
+ "
514
+ >
515
+ <span
516
+ :class="`${col.field === 'action' ? 'hidden-header-label' : ''}`"
517
+ >
518
+ {{ col.field === 'action' ? 'Action' : col.label }}
519
+ </span>
520
+
521
+ <span v-if="col.sortable && col.field !== 'action'">
522
+ <UBtnIcon
523
+ :class="`more-action-icon cursor-pointer`"
524
+ :iconClass="`${getSortingIcon(col)}`"
525
+ :aria-label="`Sort ${col.label}`"
526
+ ref="btn-icon"
527
+ size="sm"
528
+ />
529
+ </span>
530
+ </UTh>
531
+ </template>
327
532
  </UTr>
328
533
  </template>
329
534
  <!-- custom body slots to add customized cell data -->
330
535
  <template v-slot:body="props">
331
536
  <UTr
537
+ :class="`${isRowSelected(props.row).value ? 'selected-data-row' : ''}`"
332
538
  :props="props"
333
- @click="onRowClick($event, props.row)"
334
539
  :tableRowHover="tableRowHover"
335
- :class="`${isRowSelected(props.row).value ? 'selected-data-row' : ''}`"
540
+ @click="onRowClick($event, props.row)"
336
541
  >
337
542
  <UTd
338
543
  v-if="multiSelection"
339
544
  :index="-1"
545
+ :separator="separator"
340
546
  tableDataAlignment="left"
341
547
  :tableHeaderAutoWidth="false"
342
- :separator="separator"
343
548
  >
344
549
  <UCheckboxStd
345
- :id="`u-checkbox-${props.row._id}`"
346
550
  v-model="isRowSelected(props.row).value"
551
+ :id="`u-checkbox-${props.row._id}`"
347
552
  :name="props.row._id"
348
553
  />
349
554
  </UTd>
555
+
350
556
  <template v-for="(col, index) in props.cols" :key="index">
351
557
  <!-- to show the cell data without the action cell -->
352
558
  <UTd
353
- v-if="col.field !== 'action'"
354
- :row="props.row"
559
+ v-if="
560
+ col.field !== 'action' &&
561
+ (typeof col.show === 'undefined' || col.show)
562
+ "
563
+ :class="col.classes"
355
564
  :col="col"
356
565
  :index="index"
357
- :tableDataAlignment="col.align"
358
- :tableDataAutoWidth="col.autoWidth"
566
+ :row="props.row"
359
567
  :separator="separator"
360
568
  :style="col.style"
361
- :class="col.classes"
569
+ :tableDataAlignment="col.align"
570
+ :tableDataAutoWidth="col.autoWidth"
362
571
  >
363
572
  <!-- to show the chips with different variant -->
364
573
  <template v-if="col.chipValues && col.chipValues.length > 0">
365
574
  <UChip
366
575
  v-model="tableDataChip"
367
- :type="getChipColor(col.chipValues, props.row[col.field])"
576
+ class="u-table-chip"
577
+ :anchor="col.anchor"
368
578
  avatarLabel=""
369
579
  :chipLabel="props.row[col.field].toString()"
580
+ :dense="col.denseChip"
581
+ :is-show-tooltip="col.showChipTooltip"
582
+ :offset="col.offset"
370
583
  :removable="false"
371
- class="u-table-chip"
584
+ :type="getChipColor(col.chipValues, props.row[col.field])"
372
585
  />
373
586
  </template>
374
587
  <!-- to show the avatar of user image with name and other details -->
375
588
  <template v-else-if="col.avatarKey">
376
- <div class="flex justify-start items-center">
589
+ <div class="flex justify-start items-center no-wrap">
590
+ <UChip
591
+ v-if="
592
+ isMobileOrTablet &&
593
+ col.showAlignedChip &&
594
+ typeof col.showAlignedChip === 'function' &&
595
+ col.showAlignedChip(props.row)
596
+ "
597
+ v-model="tableDataChip"
598
+ :class="[
599
+ expansion ? 'q-ma-none' : 'q-mr-xs',
600
+ col.showAlignedChip(props.row).class,
601
+ ]"
602
+ :avatarLabel="col.showAlignedChip(props.row).avatarLabel"
603
+ :chipLabel="col.showAlignedChip(props.row).chipLabel"
604
+ :dense="col.showAlignedChip(props.row).dense"
605
+ :removable="col.showAlignedChip(props.row).removable"
606
+ :type="col.showAlignedChip(props.row).type"
607
+ />
377
608
  <div
378
609
  v-if="
379
610
  props.row[col.avatarKey] &&
@@ -383,106 +614,578 @@ const onRowPerPageChange = (value) => {
383
614
  >
384
615
  <UAvatar
385
616
  v-if="props.row[col.avatarKey]?.type === 'initials'"
386
- size="md"
617
+ :indicatorColor="
618
+ typeof col.indicatorColor === 'function' &&
619
+ col.indicatorColor(props.row)
620
+ ? col.indicatorColor(props.row)
621
+ : ''
622
+ "
623
+ :indicatorIcon="
624
+ typeof col.indicatorIcon === 'function' &&
625
+ col.indicatorIcon(props.row)
626
+ ? col.indicatorIcon(props.row)
627
+ : ''
628
+ "
387
629
  :name="`${props.row[col.avatarKey]?.value}`"
630
+ :showIndicator="col.showIndicator"
631
+ size="md"
388
632
  />
389
633
  <UAvatar
390
634
  v-else-if="props.row[col.avatarKey]?.type === 'image'"
391
- size="md"
635
+ :image="`${props.row[col.avatarKey]?.value}`"
636
+ :indicatorColor="
637
+ typeof col.indicatorColor === 'function' &&
638
+ col.indicatorColor(props.row)
639
+ ? col.indicatorColor(props.row)
640
+ : ''
641
+ "
642
+ :indicatorIcon="
643
+ typeof col.indicatorIcon === 'function' &&
644
+ col.indicatorIcon(props.row)
645
+ ? col.indicatorIcon(props.row)
646
+ : ''
647
+ "
392
648
  :name="
393
649
  props.row[col.avatarKey]?.name ??
394
650
  props.row[col.avatarKey]?.value
395
651
  "
396
- :image="`${props.row[col.avatarKey]?.value}`"
652
+ :showIndicator="col.showIndicator"
653
+ size="md"
397
654
  />
398
655
  </div>
399
656
  <div v-else class="table-data-avatar">
400
657
  <UAvatar
401
- size="md"
402
- :name="`${props.row[col.avatarKey]}`"
403
658
  :image="`${props.row[col.avatarKey]}`"
659
+ :indicatorColor="
660
+ typeof col.indicatorColor === 'function' &&
661
+ col.indicatorColor(props.row)
662
+ ? col.indicatorColor(props.row)
663
+ : ''
664
+ "
665
+ :indicatorIcon="
666
+ typeof col.indicatorIcon === 'function' &&
667
+ col.indicatorIcon(props.row)
668
+ ? col.indicatorIcon(props.row)
669
+ : ''
670
+ "
671
+ :name="`${props.row[col.avatarKey]}`"
672
+ :showIndicator="col.showIndicator"
673
+ size="md"
404
674
  />
405
675
  </div>
406
676
  <div class="td-grid-content">
407
- <div>{{ props.row[col.field] }}</div>
408
- <div class="td-caption text-body-xs" v-if="col.captionKey">
409
- {{ props.row[col.captionKey] }}
677
+ <div>
678
+ {{ props.row[col.field] }}
679
+ </div>
680
+
681
+ <div
682
+ v-if="
683
+ col.captionKey &&
684
+ typeof col.showCaption === 'function' &&
685
+ col.showCaption(props.row)
686
+ ? col.showCaption(props.row)
687
+ : false
688
+ "
689
+ class="td-caption mobile-primary-caption text-body-xs"
690
+ >
691
+ <span v-if="col.captionKeyTitle">
692
+ {{ col.captionKeyTitle }}:
693
+ </span>
694
+ <span> {{ props.row[col.captionKey] }}</span>
695
+ <UTooltip
696
+ v-if="props.row[col.captionKey].length > 15"
697
+ anchor="top middle"
698
+ :description="props.row[col.captionKey]"
699
+ :offset="[0, 0]"
700
+ self="bottom middle"
701
+ />
410
702
  </div>
411
703
  </div>
412
704
  </div>
413
705
  </template>
414
706
  <!-- to show other cell data -->
415
707
  <template v-else>
416
- <div class="td-grid-content">
417
- <div>{{ props.row[col.field] }}</div>
418
- <div class="td-caption text-body-xs" v-if="col.captionKey">
708
+ <div
709
+ :class="`td-grid-content${
710
+ typeof col.combineColoumn === 'function' &&
711
+ col.combineColoumn(props.row)
712
+ ? ' combine-col-wrapper'
713
+ : ''
714
+ }`"
715
+ >
716
+ <div v-if="col.type !== 'icon'">
717
+ {{ props.row[col.field] }}
718
+ </div>
719
+ <div v-else-if="col.type === 'icon'">
720
+ <template v-if="props.row[col.field]">
721
+ <q-icon
722
+ :class="props.row[col.field]"
723
+ :alt="props.row.ariaLabel"
724
+ :aria-label="props.row.ariaLabel"
725
+ :color="props?.row?.iconColor ?? 'primary'"
726
+ size="1.5rem"
727
+ />
728
+ </template>
729
+ </div>
730
+ <div
731
+ v-if="col.captionKey && col.type !== 'icon'"
732
+ class="td-caption text-body-xs"
733
+ >
419
734
  {{ props.row[col.captionKey] }}
420
735
  </div>
736
+ <template
737
+ v-if="
738
+ typeof col.combineColoumn === 'function' &&
739
+ col.combineColoumn(props.row)
740
+ "
741
+ >
742
+ <template
743
+ v-for="(combineCol, colKey) in col.combineColoumn(
744
+ props.row
745
+ )"
746
+ :key="colKey"
747
+ >
748
+ <q-icon
749
+ v-if="combineCol.icon"
750
+ :class="combineCol.icon"
751
+ :alt="combineCol.ariaLabel"
752
+ :aria-label="combineCol.ariaLabel"
753
+ :color="combineCol?.iconColor ?? 'primary'"
754
+ :key="colKey"
755
+ size="1rem"
756
+ />
757
+ <div v-else>{{ props.row[combineCol.key] }}</div>
758
+ </template>
759
+ </template>
421
760
  </div>
422
761
  </template>
423
762
  </UTd>
424
763
  <!-- to the action cell, it can have single and multiple -->
764
+
425
765
  <UTd
426
- v-else
766
+ v-else-if="typeof col.show === 'undefined' || col.show"
767
+ :class="col.classes"
427
768
  :index="index"
428
- :tableDataAlignment="col.align"
429
- :tableDataAutoWidth="false"
430
- style="width: 3%"
431
769
  :separator="separator"
432
770
  :style="col.style"
433
- :class="col.classes"
771
+ style="width: 3%"
772
+ :tableDataAlignment="col.align"
773
+ :tableDataAutoWidth="false"
774
+ @click="handleActionColClick"
434
775
  >
435
- <template v-if="col.actions && col.actions.length === 1">
436
- <UBtnStd
437
- v-for="(action, key) in col.actions"
438
- :key="key"
439
- :size="action.size"
440
- :flat="action.flat"
441
- :label="action.label"
442
- :color="action.color"
443
- :leftIcon="action.icon"
444
- @onClick="action.handler(props.row)"
445
- />
776
+ <!-- Responsive actions logic -->
777
+ <template v-if="col.useResponsiveActions">
778
+ <div class="table-desktop-multi-actions">
779
+ <!-- Inline actions -->
780
+ <template
781
+ v-for="(action, key) in getInlineActions(col)"
782
+ :key="key"
783
+ >
784
+ <UBtnStd
785
+ v-if="
786
+ typeof action.hide === 'function'
787
+ ? !action.hide(props.row)
788
+ : true
789
+ "
790
+ :class="`more-action-icon cursor-pointer table-more-action`"
791
+ :iconClass="
792
+ typeof action.icon === 'function'
793
+ ? action.icon(props.row)
794
+ : action.icon
795
+ "
796
+ :anchor="action.anchor"
797
+ :ariaLabel="
798
+ typeof action.label === 'function'
799
+ ? action.label(props.row)
800
+ : action.label
801
+ "
802
+ :color="
803
+ typeof action.color === 'function'
804
+ ? action.color(props.row)
805
+ : action.color
806
+ "
807
+ :disable="
808
+ typeof action.disable === 'function' &&
809
+ action.disable(props.row)
810
+ "
811
+ :flat="
812
+ typeof action.flat === 'function'
813
+ ? action.flat(props.row)
814
+ : action.flat
815
+ "
816
+ :label="
817
+ typeof action.label === 'function'
818
+ ? action.label(props.row)
819
+ : action.label
820
+ "
821
+ :loading="
822
+ typeof action.loading === 'function'
823
+ ? action.loading(props.row)
824
+ : action.loading
825
+ "
826
+ :offset="action.offset ? action.offset : [10, 40]"
827
+ :outline="
828
+ typeof action.outline === 'function'
829
+ ? action.outline()
830
+ : action.outline
831
+ "
832
+ :self="action.self"
833
+ :size="action.size"
834
+ :tooltip="
835
+ typeof action.tooltip === 'function'
836
+ ? action.tooltip(props.row)
837
+ : action.tooltip
838
+ "
839
+ @click.stop="handleMenuEventStop"
840
+ @on-click="action.handler(props.row)"
841
+ />
842
+ </template>
843
+ <!-- Three-dot menu for menu actions -->
844
+ <UBtnIcon
845
+ v-if="getMenuActions(col).length > 0"
846
+ :class="`action-icon cursor-pointer`"
847
+ iconClass="fa-kit fa-ellipsis-vertical"
848
+ :aria-label="actionBtnAriaLabel"
849
+ :id="`actionPopupRefBtn-${props.row.id}`"
850
+ ref="btn-icon"
851
+ @click.stop="handleMenuEventStop"
852
+ @on-click="onMoreActionButtonClick(props.row.id)"
853
+ >
854
+ <template #menu>
855
+ <q-menu v-if="!verticalMoreActions" auto-close role="list">
856
+ <div
857
+ :class="`${
858
+ verticalMoreActions ? 'vertical' : 'horizontal'
859
+ }-more-action-wrapper more-action-common`"
860
+ >
861
+ <template
862
+ v-for="(action, key) in getMenuActions(col)"
863
+ :key="key"
864
+ >
865
+ <UBtnIcon
866
+ v-if="
867
+ typeof action.hide === 'function'
868
+ ? !action.hide(props.row)
869
+ : true
870
+ "
871
+ :class="`more-action-icon cursor-pointer table-more-action`"
872
+ :iconClass="
873
+ typeof action.icon === 'function'
874
+ ? action.icon(props.row)
875
+ : action.icon
876
+ "
877
+ :anchor="action.anchor"
878
+ :ariaLabel="
879
+ typeof action.label === 'function'
880
+ ? action.label(props.row)
881
+ : action.label
882
+ "
883
+ :disable="
884
+ typeof action.disable === 'function' &&
885
+ action.disable(props.row)
886
+ "
887
+ :id="`more-action-${key}`"
888
+ :offset="action.offset ? action.offset : [10, 40]"
889
+ ref="btn-icon"
890
+ :self="action.self"
891
+ :size="action.size"
892
+ :tooltip="
893
+ typeof action.tooltip === 'function'
894
+ ? action.tooltip(props.row)
895
+ : action.tooltip
896
+ "
897
+ @click.stop="handleMenuEventStop"
898
+ @on-click="action.handler(props.row)"
899
+ />
900
+ </template>
901
+ </div>
902
+ </q-menu>
903
+ <q-menu v-else auto-close role="list">
904
+ <UMenuDropdown
905
+ v-if="verticalMoreActions"
906
+ :data="
907
+ getMenuActions(col).map((action) => ({
908
+ destructive: action.destructive,
909
+ disable:
910
+ typeof action.disable === 'function' &&
911
+ action.disable(props.row),
912
+ hide: !(typeof action.hide === 'function'
913
+ ? !action.hide(props.row)
914
+ : true),
915
+ label:
916
+ typeof action.label === 'function'
917
+ ? action.label(props.row)
918
+ : action.label,
919
+ leftIcon:
920
+ typeof action.icon === 'function'
921
+ ? action.icon(props.row)
922
+ : action.icon,
923
+ positive: action.positive,
924
+ handler: function () {
925
+ return action.handler(props.row)
926
+ },
927
+ }))
928
+ "
929
+ />
930
+ </q-menu>
931
+ </template>
932
+ </UBtnIcon>
933
+ </div>
446
934
  </template>
447
- <!-- to show the actions list if the actions are multiple -->
448
935
  <template v-else>
449
- <q-icon
450
- size="xs"
451
- class="fa-kit fa-ellipsis-vertical action-icon cursor-pointer"
452
- aria-label="more-action-icon"
453
- alt="action-icon-more"
454
- tabindex="0"
455
- >
456
- <UTooltip description="More Actions" />
457
- <q-menu
458
- transition-show="slide-left"
459
- transition-hide="slide-right"
460
- anchor="center start"
461
- self="center left"
462
- >
463
- <div
464
- class="flex justify-end items-center more-action-wrapper"
936
+ <template v-if="col.actions && col.actions.length === 1">
937
+ <template v-for="(action, key) in col.actions" :key="key">
938
+ <UBtnStd
939
+ v-if="
940
+ typeof action.hide === 'function'
941
+ ? !action.hide(props.row)
942
+ : true
943
+ "
944
+ :color="
945
+ typeof action.color === 'function'
946
+ ? action.color(props.row)
947
+ : action.color
948
+ "
949
+ :disable="
950
+ typeof action.disable === 'function' &&
951
+ action.disable(props.row)
952
+ "
953
+ :flat="
954
+ typeof action.flat === 'function'
955
+ ? action.flat(props.row)
956
+ : action.flat
957
+ "
958
+ :key="key"
959
+ :label="
960
+ typeof action.label === 'function'
961
+ ? action.label(props.row)
962
+ : action.label
963
+ "
964
+ :leftIcon="
965
+ typeof action.icon === 'function'
966
+ ? action.icon(props.row)
967
+ : action.icon
968
+ "
969
+ :loading="
970
+ typeof action.loading === 'function'
971
+ ? action.loading(props.row)
972
+ : action.loading
973
+ "
974
+ :outline="
975
+ typeof action.outline === 'function'
976
+ ? action.outline(props.row)
977
+ : action.outline
978
+ "
979
+ :size="action.size"
980
+ @on-click="action.handler(props.row)"
465
981
  >
466
- <template v-for="(action, key) in col.actions" :key="key">
982
+ <template #tooltip>
467
983
  <UTooltip
468
- :target="`#more-action-${key}`"
469
- :description="action.tooltip"
470
- />
471
- <q-icon
472
- :size="action.size"
473
- :id="`more-action-${key}`"
474
- :class="`more-action-icon ${
475
- action.icon
476
- } cursor-pointer ${key > 0 ? 'q-ml-sm' : ''}`"
477
- :aria-label="action.label"
478
- :alt="`${action.label}-key`"
479
- @click="action.handler(props.row)"
480
- tabindex="0"
984
+ v-if="
985
+ typeof action.tooltip === 'function'
986
+ ? action.tooltip(props.row)
987
+ : action.tooltip
988
+ "
989
+ :anchor="action.anchor"
990
+ :description="
991
+ typeof action.tooltip === 'function'
992
+ ? action.tooltip(props.row)
993
+ : action.tooltip
994
+ "
995
+ :offset="action.offset ? action.offset : [10, 40]"
996
+ :self="action.self"
481
997
  />
482
998
  </template>
483
- </div>
999
+ </UBtnStd>
1000
+ </template>
1001
+ </template>
1002
+ <!-- to show the actions list if the actions are multiple -->
1003
+ <template v-else>
1004
+ <q-menu
1005
+ v-if="
1006
+ moreActionDialogData &&
1007
+ moreActionDialogData.showDialog[props.row.id]
1008
+ "
1009
+ v-model="moreActionDialogData.showDialog[props.row.id]"
1010
+ :class="`more-action-popup q-px-ba q-py-ba`"
1011
+ anchor="top left"
1012
+ :cover="false"
1013
+ :fit="true"
1014
+ :id="`actionPopupRef-${props.row.id}`"
1015
+ :offset="[85, 0]"
1016
+ role="list"
1017
+ self="bottom middle"
1018
+ transition-hide="scale"
1019
+ transition-show="scale"
1020
+ @show="checkMenuPosition(props.row.id)"
1021
+ >
1022
+ <div :class="tailClass"></div>
1023
+ <q-card class="more-action-popup-wrapper">
1024
+ <q-card-section>
1025
+ <div class="content-wrapper text-center">
1026
+ <div class="q-pb-ba flex justify-center items-center">
1027
+ <div
1028
+ :class="`remove-icon-wrapper ${
1029
+ moreActionDialogData.row.iconColor === 'accent'
1030
+ ? 'icon-bg-accent'
1031
+ : 'icon-bg-primary'
1032
+ }`"
1033
+ >
1034
+ <q-icon
1035
+ :class="`${moreActionDialogData.row.icon} ${
1036
+ moreActionDialogData.row.iconColor === 'accent'
1037
+ ? 'icon-text-accent'
1038
+ : 'icon-text-primary'
1039
+ }`"
1040
+ alt="confirmation icon"
1041
+ aria-label="confirmation icon"
1042
+ size="1.5rem"
1043
+ />
1044
+ </div>
1045
+ </div>
1046
+
1047
+ <div
1048
+ class="text-heading-xxs primary-content-text q-pb-xxs"
1049
+ >
1050
+ {{ moreActionDialogData.row.title }}
1051
+ </div>
1052
+ <div
1053
+ v-if="moreActionDialogData.row.description"
1054
+ class="text-body-sm secondary-content-text q-pb-xs"
1055
+ >
1056
+ {{ moreActionDialogData.row.description }}
1057
+ </div>
1058
+ </div>
1059
+ <!-- <p class="hidden-scope-value">{{ scope.value }}</p> -->
1060
+ </q-card-section>
1061
+
1062
+ <q-card-actions align="right">
1063
+ <UBtnStd
1064
+ v-if="moreActionDialogData.secondaryAction"
1065
+ :color="moreActionDialogData.secondaryAction.color"
1066
+ :disable="moreActionDialogData.secondaryAction.disable"
1067
+ :flat="moreActionDialogData.secondaryAction.flat"
1068
+ :label="moreActionDialogData.secondaryAction.label"
1069
+ :loading="moreActionDialogData.secondaryAction.loading"
1070
+ :outline="moreActionDialogData.secondaryAction.outline"
1071
+ :size="moreActionDialogData.secondaryAction.size"
1072
+ @on-click="
1073
+ moreActionDialogData.secondaryAction.handler(
1074
+ props.row
1075
+ )
1076
+ "
1077
+ />
1078
+ <UBtnStd
1079
+ v-if="moreActionDialogData.primaryAction"
1080
+ class="confirm-primary-action"
1081
+ :color="moreActionDialogData.primaryAction.color"
1082
+ :disable="moreActionDialogData.primaryAction.disable"
1083
+ :flat="moreActionDialogData.primaryAction.flat"
1084
+ :label="moreActionDialogData.primaryAction.label"
1085
+ :loading="moreActionDialogData.primaryAction.loading"
1086
+ :outline="moreActionDialogData.primaryAction.outline"
1087
+ :size="moreActionDialogData.primaryAction.size"
1088
+ @on-click="
1089
+ moreActionDialogData.primaryAction.handler(props.row)
1090
+ "
1091
+ />
1092
+ </q-card-actions>
1093
+ </q-card>
484
1094
  </q-menu>
485
- </q-icon>
1095
+
1096
+ <UBtnIcon
1097
+ :class="`action-icon cursor-pointer`"
1098
+ iconClass="fa-kit fa-ellipsis-vertical"
1099
+ :aria-label="actionBtnAriaLabel"
1100
+ :id="`actionPopupRefBtn-${props.row.id}`"
1101
+ :key="index"
1102
+ ref="btn-icon"
1103
+ @click.stop="handleMenuEventStop"
1104
+ @on-click="onMoreActionButtonClick(props.row.id)"
1105
+ >
1106
+ <template #menu>
1107
+ <q-menu v-if="!verticalMoreActions" auto-close role="list">
1108
+ <div
1109
+ :class="`${
1110
+ verticalMoreActions ? 'vertical' : 'horizontal'
1111
+ }-more-action-wrapper more-action-common`"
1112
+ >
1113
+ <template
1114
+ v-for="(action, key) in col.actions"
1115
+ :key="key"
1116
+ >
1117
+ <UBtnIcon
1118
+ v-if="
1119
+ typeof action.hide === 'function'
1120
+ ? !action.hide(props.row)
1121
+ : true && !verticalMoreActions
1122
+ "
1123
+ :class="`more-action-icon cursor-pointer table-more-action`"
1124
+ :iconClass="
1125
+ typeof action.icon === 'function'
1126
+ ? action.icon(props.row)
1127
+ : action.icon
1128
+ "
1129
+ :anchor="action.anchor"
1130
+ :ariaLabel="
1131
+ typeof action.label === 'function'
1132
+ ? action.label(props.row)
1133
+ : action.label
1134
+ "
1135
+ :disable="
1136
+ typeof action.disable === 'function' &&
1137
+ action.disable(props.row)
1138
+ "
1139
+ :id="`more-action-${key}`"
1140
+ :offset="action.offset ? action.offset : [10, 40]"
1141
+ ref="btn-icon"
1142
+ :self="action.self"
1143
+ :size="action.size"
1144
+ :tooltip="
1145
+ typeof action.tooltip === 'function'
1146
+ ? action.tooltip(props.row)
1147
+ : action.tooltip
1148
+ "
1149
+ @click.stop="handleMenuEventStop"
1150
+ @on-click="action.handler(props.row)"
1151
+ />
1152
+ </template>
1153
+ </div>
1154
+ </q-menu>
1155
+
1156
+ <q-menu v-else auto-close role="list">
1157
+ <UMenuDropdown
1158
+ v-if="verticalMoreActions"
1159
+ :data="
1160
+ col.actions.map((action) => {
1161
+ return {
1162
+ destructive: action.destructive,
1163
+ disable:
1164
+ typeof action.disable === 'function' &&
1165
+ action.disable(props.row),
1166
+ hide: !(typeof action.hide === 'function'
1167
+ ? !action.hide(props.row)
1168
+ : true),
1169
+ label:
1170
+ typeof action.label === 'function'
1171
+ ? action.label(props.row)
1172
+ : action.label,
1173
+ leftIcon:
1174
+ typeof action.icon === 'function'
1175
+ ? action.icon(props.row)
1176
+ : action.icon,
1177
+ positive: action.positive,
1178
+ handler: function () {
1179
+ return action.handler(props.row)
1180
+ },
1181
+ }
1182
+ })
1183
+ "
1184
+ />
1185
+ </q-menu>
1186
+ </template>
1187
+ </UBtnIcon>
1188
+ </template>
486
1189
  </template>
487
1190
  </UTd>
488
1191
  </template>
@@ -491,7 +1194,7 @@ const onRowPerPageChange = (value) => {
491
1194
  <!-- slot to show if there is no data in rows -->
492
1195
  <template v-slot:no-data>
493
1196
  <div class="full-width row flex-center text-accent q-gutter-sm">
494
- <span> No Data Found </span>
1197
+ <span> {{ props.noDataFound }} </span>
495
1198
  </div>
496
1199
  </template>
497
1200
  <!-- to add the custom loading state -->
@@ -501,20 +1204,33 @@ const onRowPerPageChange = (value) => {
501
1204
  </UTable>
502
1205
  <!-- customized pagination with the vitual scroll functionality and rows per page selection -->
503
1206
  <div
504
- v-if="showPagination"
505
- class="row justify-end items-center pagination-wrapper"
1207
+ v-if="showPagination && !infiniteScroll"
1208
+ :class="`row justify-end items-center pagination-wrapper${
1209
+ grid ? ' grid-row-pagination' : ''
1210
+ }${isSmallDevices ? ' small-device-pagination' : ''}`"
1211
+ dataTestId="table-pagination"
506
1212
  >
507
1213
  <UPagination
508
- v-if="rows.length >= 6"
1214
+ v-if="updatedRows.length >= 6"
509
1215
  v-model="pagination.page"
510
- :rowPerPage="pagination.rowsPerPage"
1216
+ :apply-label="applyLabel"
1217
+ :cancel-label="cancelLabel"
1218
+ :close-icon-label="closeIconLabel"
1219
+ :maxPageLink="
1220
+ Number(
1221
+ Math.ceil(updatedRows.length / pagination.rowsPerPage) > 10
1222
+ ? grid
1223
+ ? 3
1224
+ : 6
1225
+ : 3
1226
+ )
1227
+ "
1228
+ :maxPages="Number(Math.ceil(updatedRows.length / pagination.rowsPerPage))"
511
1229
  :perPageOptions="getRowsPerPageOptions"
1230
+ :rowPerPage="pagination.rowsPerPage"
1231
+ :sheet-label="sheetLabel"
512
1232
  @onPageChange="onPageChange"
513
1233
  @onRowChange="onRowPerPageChange"
514
- :maxPageLink="
515
- Number(Math.ceil(rows.length / pagination.rowsPerPage > 10 ? 6 : 3))
516
- "
517
- :maxPages="Number(Math.ceil(rows.length / pagination.rowsPerPage))"
518
1234
  />
519
1235
  </div>
520
1236
  <q-inner-loading :showing="customLoading" class="custom-table-loader" />
@@ -522,9 +1238,16 @@ const onRowPerPageChange = (value) => {
522
1238
 
523
1239
  <style lang="sass">
524
1240
  .action-icon
525
- height: $md
526
- width: $md
527
- color: $neutral-9
1241
+ &:hover
1242
+ background: $blue-1
1243
+
1244
+ .q-icon
1245
+ height: $md !important
1246
+ width: $md !important
1247
+ color: $neutral-9 !important
1248
+ font-size: $ba !important
1249
+ &:hover
1250
+ color: $primary !important
528
1251
 
529
1252
  .table-data-avatar
530
1253
  padding: $xs
@@ -532,23 +1255,54 @@ const onRowPerPageChange = (value) => {
532
1255
 
533
1256
  .td-caption
534
1257
  color: $description
1258
+ width: 12.5rem
1259
+ word-break: break-word
535
1260
 
536
- .more-action-wrapper
1261
+ .more-action-common
537
1262
  min-width: 3.125rem
538
1263
  padding: $xs
539
1264
  min-height: $xl
540
1265
  gap: $xs
541
1266
  border-bottom: 1.5px solid $neutral-4
542
1267
  background: $surface-bg-1
543
- box-shadow: 0px 0px 4px 0px rgba(16, 17, 20, 0.08)
1268
+ box-shadow: 0px 0px $xxs 0px rgba(16, 17, 20, 0.08)
544
1269
 
545
- .more-action-icon
546
- color: $neutral-9
1270
+ .vertical-more-action-wrapper
1271
+ display: grid
1272
+ place-items: flex-start
1273
+ place-content: center
1274
+ padding: $xxs
1275
+ gap: $xxs
547
1276
 
548
- .sorting-icon
549
- color: $description
550
- padding-left: $xs
551
- font-size: $ba !important
1277
+ .horizontal-more-action-wrapper
1278
+ display: flex
1279
+ align-items: center
1280
+ justify-content: start
1281
+
1282
+ .vertical-single-action
1283
+ width: 100%
1284
+ gap: $xs
1285
+ padding: 0 $xs
1286
+ height: $lg
1287
+
1288
+ .q-item__section--main
1289
+ color: $neutral-9
1290
+ white-space: nowrap
1291
+
1292
+ .q-item__section--avatar
1293
+ min-width: 0px
1294
+
1295
+ .q-item__section--side
1296
+ padding-right: 0
1297
+
1298
+ .q-icon
1299
+ color: $neutral-9
1300
+ font-size: $ba
1301
+
1302
+ .more-action-icon
1303
+ .q-icon
1304
+ color: $neutral-9 !important
1305
+ font-size: $ba !important
552
1306
 
553
1307
  .selected-data-row
554
1308
  background: #F7F7F7
@@ -570,9 +1324,97 @@ const onRowPerPageChange = (value) => {
570
1324
  .u-virtualscroll-table
571
1325
  height: 50rem
572
1326
 
1327
+ .u-virtualscroll-grid-table.grid-card-mobile
1328
+ .q-table__grid-content
1329
+ .grid-style-transition
1330
+ padding-left: 0px
1331
+ padding-right: 0px
1332
+
1333
+ .u-virtualscroll-grid-table.grid-card-tablet
1334
+ .q-table__grid-content
1335
+ > :nth-child(odd)
1336
+ padding-left: 0px
1337
+ > :nth-child(even)
1338
+ padding-right: 0px
1339
+
573
1340
  .u-virtualscroll-grid-table
574
- max-height: 50rem
575
- overflow: auto
1341
+ // max-height: 50rem
1342
+ // overflow-y: auto
1343
+ .q-table__middle
1344
+ display: none
1345
+
1346
+ .q-item.q-item-type .q-item__section--main
1347
+ padding-bottom: $xxs !important
1348
+
1349
+ .q-list
1350
+ display: grid
1351
+ row-gap: $xs
1352
+ column-gap: $xs
1353
+ grid-template-columns: 1fr 1fr
1354
+ padding-left: $ba
1355
+ padding-right: $ba
1356
+ height: 100%
1357
+ min-height: 26.125rem
1358
+
1359
+ .q-item__label
1360
+ color: $neutral-9
1361
+ font-size: 0.875rem
1362
+ font-weight: 500
1363
+ line-height: 1.063rem !important
1364
+ opacity: 1
1365
+ word-break: break-word
1366
+
1367
+ .q-item__label.q-item__label--caption
1368
+ color: $dark
1369
+ font-size: $ba
1370
+ font-weight: 400
1371
+ line-height: 1.188rem !important
1372
+ word-break: break-word
1373
+
1374
+ .q-table__grid-content
1375
+ .q-table__grid-item
1376
+ padding: $xs
1377
+
1378
+ .q-card
1379
+ overflow: auto
1380
+ padding-top: 0px !important
1381
+ border-radius: $xs
1382
+ border: 1px solid $neutral-4
1383
+ box-shadow: none
1384
+
1385
+ .mobile-centered-col
1386
+ grid-column: span 2
1387
+
1388
+ .q-item.q-item-type
1389
+ margin-top: 0px !important
1390
+ align-self: start
1391
+ height: auto
1392
+ display: grid !important
1393
+ padding: 0px !important
1394
+ .q-item__section--side
1395
+ align-items: flex-start
1396
+ padding-left: 0px
1397
+
1398
+ .q-item.q-item-type:last-child
1399
+ grid-column: span 2
1400
+ padding-top: $ba !important
1401
+ margin-bottom: $ba !important
1402
+
1403
+ .column.q-item__section--main
1404
+ display: none
1405
+
1406
+ .q-item.q-item-type:first-child
1407
+ grid-column: span 2
1408
+ padding-top: $sm !important
1409
+ padding-bottom: $sm !important
1410
+ .q-item__section--main
1411
+ display: none
1412
+ .q-item__label.q-item__label--caption span
1413
+ color: $dark
1414
+ font-size: 1rem
1415
+ font-weight: 500
1416
+ line-height: 1.063rem
1417
+ width: 100%
576
1418
 
577
1419
  .u-sticky-table-header
578
1420
  .q-table__top,
@@ -588,10 +1430,10 @@ const onRowPerPageChange = (value) => {
588
1430
  top: 0
589
1431
 
590
1432
  &.q-table--loading thead tr:last-child th
591
- top: 48px
1433
+ top: 3rem
592
1434
 
593
1435
  tbody
594
- scroll-margin-top: 48px
1436
+ scroll-margin-top: 3rem
595
1437
 
596
1438
  .u-sorting-btn
597
1439
  padding: 0
@@ -622,4 +1464,190 @@ const onRowPerPageChange = (value) => {
622
1464
  .td-grid-content
623
1465
  text-wrap: balance
624
1466
  word-break: break-all
1467
+
1468
+ .hidden-header-label
1469
+ visibility: hidden
1470
+
1471
+ .confirmation-dialog-wrapper
1472
+ border-radius: $border-radius-sm !important
1473
+ background: $neutral-1
1474
+ box-shadow: 0rem 0rem $sm 0rem rgba(16, 17, 20, 0.16) !important
1475
+
1476
+ .confirmation-dialog-wrapper.mobile-confirmation-dialog
1477
+ max-width: 100% !important
1478
+ padding: 0px !important
1479
+
1480
+ .more-action-popup
1481
+ border-radius: $border-radius-sm
1482
+ background: $neutral-1
1483
+ box-shadow: 0rem 0rem $sm 0rem rgba(16, 17, 20, 0.16)
1484
+ max-width: 18.375rem !important
1485
+ width: 100%
1486
+ position: relative
1487
+ overflow: visible
1488
+
1489
+ .more-action-popup-wrapper
1490
+ box-shadow: none !important
1491
+ max-width: 18.375rem !important
1492
+ width: 100%
1493
+ .hidden-scope-value
1494
+ display: none
1495
+ .q-card__section
1496
+ padding: 0
1497
+ .q-card__actions
1498
+ flex-wrap: nowrap
1499
+ padding: $ba 0 0 0
1500
+ .q-btn
1501
+ width: 50%
1502
+
1503
+ .content-wrapper
1504
+ display: grid
1505
+ place-content: center
1506
+ place-items: center
1507
+
1508
+ .secondary-content-text
1509
+ color: $description
1510
+
1511
+ .primary-content-text
1512
+ color: $dark
1513
+
1514
+ .remove-icon-wrapper
1515
+ border-radius: 7.75rem
1516
+ padding: $sm
1517
+ width: 3.125rem
1518
+ height: 3.125rem
1519
+ .q-icon
1520
+ color: $accent
1521
+
1522
+ .confirm-primary-action
1523
+ margin-left: $ba !important
1524
+
1525
+ .icon-bg-accent
1526
+ background-color: $red-1
1527
+
1528
+ .icon-bg-primary
1529
+ background-color: $blue-1
1530
+
1531
+ .icon-text-accent
1532
+ color: $accent
1533
+
1534
+ .icon-text-primary
1535
+ color: $primary !important
1536
+
1537
+ .tail-top
1538
+ width: 1.25rem
1539
+ height: 1.25rem
1540
+ transform: rotate(45deg)
1541
+ position: absolute
1542
+ right: 1.304rem
1543
+ top: -0.604rem
1544
+ border-top-left-radius: $border-radius-xs
1545
+ background: $neutral-1
1546
+ box-shadow: -3px -2px 5px -3px rgba(0, 0, 0, 0.2)
1547
+
1548
+ .tail-bottom
1549
+ width: 1.25rem
1550
+ height: 1.25rem
1551
+ transform: rotate(45deg)
1552
+ position: absolute
1553
+ right: 1.304rem
1554
+ bottom: -0.604rem
1555
+ border-bottom-right-radius: $border-radius-xs
1556
+ background: $neutral-1
1557
+ box-shadow: 3px $xxs 5px -3px rgba(0, 0, 0, 0.2)
1558
+
1559
+ .mobile-tail-top
1560
+ right: 1.304rem !important
1561
+
1562
+ .mobile-tail-bottom
1563
+ right: 1.304rem !important
1564
+
1565
+ .grid-row-pagination
1566
+ .u-pagination-container
1567
+ flex-wrap: nowrap
1568
+ .q-pagination__middle
1569
+ flex-wrap: nowrap
1570
+
1571
+ .small-device-pagination
1572
+ .u-pagination-container
1573
+ flex-wrap: wrap
1574
+ gap: $xs
1575
+ justify-content: flex-end
1576
+
1577
+ .mobile-grid-more-action
1578
+ padding: 0px !important
1579
+ .q-item
1580
+ border-radius: $xs
1581
+
1582
+ .grid-more-action
1583
+ padding: $ba
1584
+ .q-item__section--avatar
1585
+ min-width: 0
1586
+ .q-item
1587
+ border-radius: $xs
1588
+
1589
+ .long-text-content
1590
+ display: block
1591
+ white-space: nowrap
1592
+ width: 5.5rem !important
1593
+ overflow: hidden
1594
+ text-overflow: ellipsis
1595
+
1596
+ .no-ellipsis-content
1597
+ white-space: normal !important
1598
+
1599
+ .full-width-text-content
1600
+ width: 19.5rem !important
1601
+
1602
+ .tablet-event-text
1603
+ width: 10.5rem
1604
+
1605
+ .mobile-primary-caption
1606
+ width: 11.5rem !important
1607
+ white-space: nowrap
1608
+ overflow: hidden
1609
+ text-overflow: ellipsis
1610
+
1611
+ .combine-col-wrapper
1612
+ display: flex
1613
+ justify-content: center
1614
+ align-items: center
1615
+ gap: $xxs
1616
+
1617
+ .combine-col-small-device-wrapper
1618
+ display: flex
1619
+ justify-content: flex-start
1620
+ align-items: center
1621
+ gap: $xxs
1622
+
1623
+ .q-table__grid-content .u-expansion-table
1624
+ .u-expansion-body
1625
+ display: flex
1626
+ flex-wrap: wrap
1627
+ gap: $xs
1628
+
1629
+ > *:not(:last-child)
1630
+ margin-bottom: $ba
1631
+
1632
+ .table-data-avatar
1633
+ display: flex
1634
+ align-items: center
1635
+ .u-avatar
1636
+ margin-right: $xxs !important
1637
+
1638
+ .u-table-infinite-scroll-container
1639
+ color: #000
1640
+ background-color: #fff
1641
+ border-radius: $xxs
1642
+ box-shadow: 0px 0px $xs 0px rgba(16, 17, 20, 0.12)
1643
+
1644
+ .table-desktop-multi-actions
1645
+ display: flex
1646
+ justify-content: space-between
1647
+ align-items: center
1648
+ flex-wrap: nowrap
1649
+ gap: $ba
1650
+
1651
+ .mobile-expansion-item
1652
+ flex: calc(50% - 8px)
625
1653
  </style>