@usssa/component-library 1.0.0-alpha.15 → 1.0.0-alpha.151

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 (57) hide show
  1. package/README.md +6 -3
  2. package/package.json +23 -5
  3. package/src/assets/logo.svg +19 -0
  4. package/src/assets/no-result.svg +25 -0
  5. package/src/assets/quasar-logo-vertical.svg +15 -0
  6. package/src/assets/upload-illustration.svg +48 -0
  7. package/src/components/core/UAvatar.vue +56 -24
  8. package/src/components/core/UAvatarGroup.vue +62 -52
  9. package/src/components/core/UBadgeStd.vue +6 -1
  10. package/src/components/core/UBannerStd.vue +100 -31
  11. package/src/components/core/UBreadCrumbs.vue +171 -0
  12. package/src/components/core/UBtnIcon.vue +58 -53
  13. package/src/components/core/UBtnStd.vue +39 -31
  14. package/src/components/core/UBtnToggle.vue +11 -6
  15. package/src/components/core/UCheckboxStd.vue +26 -20
  16. package/src/components/core/UChip.vue +76 -42
  17. package/src/components/core/UDate.vue +565 -0
  18. package/src/components/core/UDialogStd.vue +460 -53
  19. package/src/components/core/UDrawer.vue +321 -0
  20. package/src/components/core/UInnerLoader.vue +69 -0
  21. package/src/components/core/UInputAddressLookup.vue +471 -0
  22. package/src/components/core/UInputPhoneStd.vue +73 -68
  23. package/src/components/core/UInputTextStd.vue +133 -116
  24. package/src/components/core/UInputTypeahead.vue +44 -0
  25. package/src/components/core/UInputTypeaheadAdvanceSearch.vue +126 -0
  26. package/src/components/core/UMenuButtonStd.vue +280 -0
  27. package/src/components/core/UMenuDropdown.vue +80 -0
  28. package/src/components/core/UMenuDropdownAdvancedSearch.vue +293 -0
  29. package/src/components/core/UMenuItem.vue +161 -0
  30. package/src/components/core/UMenuSearch.vue +69 -0
  31. package/src/components/core/UMultiSelectStd.vue +258 -54
  32. package/src/components/core/UPagination.vue +67 -27
  33. package/src/components/core/URadioBtn.vue +66 -43
  34. package/src/components/core/URadioStd.vue +19 -12
  35. package/src/components/core/USelectStd.vue +360 -80
  36. package/src/components/core/USheet.vue +349 -0
  37. package/src/components/core/UTabBtnStd.vue +87 -59
  38. package/src/components/core/UTable/UTable.vue +811 -42
  39. package/src/components/core/UTableStd.vue +875 -275
  40. package/src/components/core/UTabsStd.vue +57 -16
  41. package/src/components/core/UToggleStd.vue +43 -29
  42. package/src/components/core/UToolbar/UCustomMenuIcon.vue +58 -0
  43. package/src/components/core/UToolbar/UToolbar.vue +210 -0
  44. package/src/components/core/UTooltip.vue +31 -10
  45. package/src/components/core/UTypeahead.vue +830 -0
  46. package/src/components/core/UUploader.vue +535 -0
  47. package/src/components/index.js +61 -21
  48. package/src/composables/useNotify.js +16 -16
  49. package/src/composables/useOverlayLoader.js +23 -0
  50. package/src/composables/useScreenType.js +30 -0
  51. package/src/css/app.sass +168 -0
  52. package/src/css/colors.sass +103 -0
  53. package/src/css/media.sass +1 -0
  54. package/src/css/quasar.variables.sass +121 -0
  55. package/src/css/typography.sass +0 -0
  56. package/src/css/vars/colors.variables.sass +127 -0
  57. package/src/utils/data.ts +146 -0
@@ -1,9 +1,59 @@
1
1
  <script setup>
2
+ import { useQuasar } from 'quasar'
3
+ import { computed, ref, watch } from 'vue'
4
+ import { useScreenType } from '../../../composables/useScreenType'
5
+ import UAvatar from '../UAvatar.vue'
6
+ import UBtnStd from '../UBtnStd.vue'
7
+ import UChip from '../UChip.vue'
8
+ import USheet from '../USheet.vue'
9
+ import UTooltip from '../UTooltip.vue'
10
+
11
+ const columns = defineModel('columns', {
12
+ default: () => [],
13
+ type: Array,
14
+ })
15
+ const filteredRows = defineModel('filteredRows', {
16
+ default: () => [],
17
+ type: Array,
18
+ })
19
+ const loading = defineModel('loading', {
20
+ default: null,
21
+ type: Boolean,
22
+ })
23
+ const moreActionDialogData = defineModel('moreActionDialogData', {
24
+ type: Object,
25
+ default: null,
26
+ })
27
+ const pagination = defineModel('pagination', {
28
+ default: { page: 1, rowsPerPage: 15 },
29
+ type: Object,
30
+ })
31
+ const rows = defineModel('rows', {
32
+ default: () => [],
33
+ type: Array,
34
+ })
35
+
2
36
  const props = defineProps({
3
- title: {
37
+ bordered: {
38
+ type: Boolean,
39
+ default: false,
40
+ },
41
+ filter: {
4
42
  type: String,
5
43
  default: '',
6
44
  },
45
+ flat: {
46
+ type: Boolean,
47
+ default: false,
48
+ },
49
+ grid: {
50
+ type: Boolean,
51
+ default: false,
52
+ },
53
+ rowCardHeight: {
54
+ type: Number,
55
+ default: 25,
56
+ },
7
57
  rowKey: {
8
58
  type: String,
9
59
  default: 'name',
@@ -12,67 +62,176 @@ const props = defineProps({
12
62
  type: String,
13
63
  default: 'horizontal',
14
64
  },
15
- flat: {
65
+ showPagination: {
16
66
  type: Boolean,
17
- default: false,
67
+ default: true,
18
68
  },
19
- bordered: {
69
+ stickyHeader: {
20
70
  type: Boolean,
21
71
  default: false,
22
72
  },
23
- grid: {
24
- type: Boolean,
25
- default: false,
73
+ title: {
74
+ type: String,
75
+ default: '',
26
76
  },
27
77
  virtualScroll: {
28
78
  type: Boolean,
29
79
  default: false,
30
80
  },
31
- stickyHeader: {
32
- type: Boolean,
33
- default: false,
34
- },
35
81
  })
36
82
 
37
- const pagination = defineModel('pagination', {
38
- default: null,
39
- type: Object,
40
- })
41
- const loading = defineModel('loading', {
42
- default: null,
43
- type: Boolean,
44
- })
45
- const rows = defineModel('rows', {
46
- default: () => [],
47
- type: Array,
48
- })
49
- const columns = defineModel('columns', {
50
- default: () => [],
51
- type: Array,
52
- })
83
+ const $q = useQuasar()
84
+ const $screen = useScreenType()
85
+
86
+ const mobileActionsDialog = ref({})
87
+ const moreActionsDialogs = ref({})
88
+ const tableDataChip = ref(true) // this is required to show chip
89
+ const tailClass = ref(null)
90
+
91
+ const isDesktop = computed(() => $screen.value.isDesktop)
92
+ const isMobile = computed(() => $screen.value.isMobile)
93
+ const isResponsiveTablet = computed(
94
+ () => $q.screen.width > 600 && $q.screen.width < 768
95
+ )
96
+ const isTablet = computed(() => $screen.value.isTablet)
97
+
98
+ // chekcing the menu position after show
99
+ const checkMenuPosition = (id) => {
100
+ const menuElement = document.getElementById(`actionPopupRef-${id}`) // Access the menu by ID
101
+ const buttonElement = document.getElementById(`actionPopupRefBtn-${id}`) // Access the button element
102
+
103
+ if (menuElement && buttonElement) {
104
+ const menuRect = menuElement.getBoundingClientRect() // Menu position
105
+ const buttonRect = buttonElement.getBoundingClientRect() // Button position
106
+
107
+ // Determine if the menu opens above or below
108
+ if (menuRect.top < buttonRect.top) {
109
+ tailClass.value = 'tail-bottom mobile-tail-bottom' // Menu opens below, tail at the bottom
110
+ } else {
111
+ tailClass.value = 'tail-top mobile-tail-top' // Menu opens above, tail at the top
112
+ }
113
+ }
114
+ }
115
+
116
+ const filterMethod = (rows, terms, cols, getCellValue) => {
117
+ let updatedRows = []
118
+ rows.forEach((row) => {
119
+ cols.forEach((col) => {
120
+ if (
121
+ col.type === 'text' &&
122
+ row[col.id].toLowerCase().includes(terms.toLowerCase()) &&
123
+ !updatedRows.includes(row)
124
+ ) {
125
+ updatedRows.push(row)
126
+ }
127
+ })
128
+ })
129
+ filteredRows.value = updatedRows
130
+
131
+ return updatedRows
132
+ }
133
+
134
+ const getActionItemColor = (action, row) => {
135
+ if (action.destructive) {
136
+ return 'accent'
137
+ } else {
138
+ return typeof action.color === 'function'
139
+ ? action.color(row)
140
+ : action.color
141
+ ? action.color
142
+ : 'primary'
143
+ }
144
+ }
145
+
146
+ //getting the chip color accroding to value of chip from row
147
+ const getChipColor = (data, value) => {
148
+ const foundObject = data.find((chip) => chip.value === value)
149
+ if (foundObject) {
150
+ return foundObject['color']
151
+ } else {
152
+ return 'neutral-3'
153
+ }
154
+ }
155
+
156
+ const handleItemClick = (action, row) => {
157
+ moreActionsDialogs.value[row.id][0].open = false
158
+ setTimeout(() => {
159
+ moreActionsDialogs.value[row.id].splice(0, 1)
160
+ }, 200)
161
+ return action.handler(row)
162
+ }
163
+
164
+ const handleOpenMobileMoreActions = (id) => {
165
+ const dialogObjMap = {
166
+ [id]: [
167
+ {
168
+ open: true,
169
+ height: 270,
170
+ persistent: true,
171
+ transitionDuration: 500, // ms
172
+ position: 'bottom',
173
+ },
174
+ ],
175
+ }
176
+ moreActionsDialogs.value = dialogObjMap
177
+ }
178
+
179
+ // checking for tooltip is content is visible
180
+ const isContentVisible = (field, id, type) => {
181
+ return document.getElementById(`long-${type}-${field}-${id}`)
182
+ }
183
+
184
+ watch(
185
+ moreActionDialogData,
186
+ (newData) => {
187
+ if (newData && newData.showDialog) {
188
+ const dialogObjMap = {
189
+ [newData.row.id]: [
190
+ {
191
+ open: true,
192
+ height: 270,
193
+ persistent: true,
194
+ transitionDuration: 500, // ms
195
+ position: 'bottom',
196
+ },
197
+ ],
198
+ }
199
+ mobileActionsDialog.value = dialogObjMap
200
+ } else {
201
+ mobileActionsDialog.value = []
202
+ }
203
+ },
204
+ { immediate: true }
205
+ )
53
206
  </script>
54
207
 
55
208
  <template>
56
209
  <q-table
57
210
  v-bind="$attrs"
58
- :title="title"
211
+ v-model:pagination="pagination"
212
+ :class="`u-table${virtualScroll ? ' u-virtualscroll-table' : ''}${
213
+ grid ? ' u-virtualscroll-grid-table' : ''
214
+ }${stickyHeader ? ' u-sticky-table-header' : ''}${
215
+ showPagination && pagination.rowsPerPage < 50
216
+ ? ' force-auto-height-table'
217
+ : ''
218
+ }${
219
+ !isDesktop ? (isMobile ? ' grid-card-mobile' : ' grid-card-tablet') : ''
220
+ }`"
221
+ :bordered="bordered"
59
222
  :columns="columns"
60
- :rows="rows"
61
- :row-key="rowKey"
223
+ :filter="filter"
224
+ :filter-method="filterMethod"
62
225
  :flat="flat"
63
- :bordered="bordered"
64
- :separator="separator"
65
- :loading="loading"
66
- hide-pagination
67
226
  :grid="grid"
68
- :class="`u-table ${virtualScroll ? 'u-virtualscroll-table' : ''} ${
69
- grid ? 'u-virtualscroll-grid-table' : ''
70
- } ${stickyHeader ? 'u-sticky-table-header' : ''} ${
71
- pagination.rowsPerPage < 50 ? 'force-auto-height-table' : ''
72
- }`"
73
- :virtual-scroll="!grid && virtualScroll"
74
- v-model:pagination="pagination"
227
+ hide-pagination
228
+ :loading="loading"
229
+ :row-key="rowKey"
230
+ :rows="rows"
75
231
  :rows-per-page-options="[0]"
232
+ :separator="separator"
233
+ :title="title"
234
+ :virtual-scroll="!grid && virtualScroll"
76
235
  :virtual-scroll-item-size="48"
77
236
  :virtual-scroll-sticky-size-start="48"
78
237
  >
@@ -81,7 +240,617 @@ const columns = defineModel('columns', {
81
240
  v-slot:[slotName]="scope"
82
241
  :key="index"
83
242
  >
84
- <slot :name="slotName" v-bind="{ ...scope }" />
243
+ <slot v-bind="{ ...scope }" :name="slotName" />
244
+ </template>
245
+ <template v-slot:item="props">
246
+ <div
247
+ class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3 grid-style-transition"
248
+ :style="props.selected ? 'transform: scale(0.95);' : ''"
249
+ >
250
+ <q-card bordered flat>
251
+ <q-list
252
+ dense
253
+ :style="{
254
+ 'min-height': `${rowCardHeight}rem`,
255
+ overflowX: 'hidden',
256
+ }"
257
+ >
258
+ <template v-for="(col, __k) in props.cols" :key="__k">
259
+ <q-item
260
+ v-if="
261
+ typeof col.show === 'undefined' ||
262
+ col.show ||
263
+ col.field === 'action'
264
+ "
265
+ :class="col.doubleSpan ? 'mobile-centered-col' : ''"
266
+ >
267
+ <q-item-section
268
+ v-if="
269
+ typeof col.show === 'undefined' ||
270
+ col.show ||
271
+ col.field === 'action'
272
+ "
273
+ >
274
+ <q-item-label> {{ col.label }}</q-item-label>
275
+ </q-item-section>
276
+ <q-item-section
277
+ v-if="
278
+ typeof col.show === 'undefined' ||
279
+ col.show ||
280
+ col.field === 'action'
281
+ "
282
+ side
283
+ >
284
+ <template v-if="col.type === 'icon' && props.row[col.field]">
285
+ <q-icon
286
+ :class="props.row[col.field]"
287
+ :alt="props.row.ariaLabel"
288
+ :aria-label="props.row.ariaLabel"
289
+ :color="props?.row?.iconColor ?? 'primary'"
290
+ size="1.5rem"
291
+ />
292
+ </template>
293
+ <template v-if="col.chipValues && col.chipValues.length > 0">
294
+ <UChip
295
+ v-model="tableDataChip"
296
+ class="u-table-chip"
297
+ :anchor="col.anchor"
298
+ avatarLabel=""
299
+ :chipLabel="props.row[col.field].toString()"
300
+ :dense="isMobile || isTablet ? true : col.denseChip"
301
+ :is-show-tooltip="col.showChipTooltip"
302
+ :offset="col.offset"
303
+ :removable="false"
304
+ :type="getChipColor(col.chipValues, props.row[col.field])"
305
+ />
306
+ </template>
307
+
308
+ <template v-else>
309
+ <div class="flex justify-center items-center no-wrap">
310
+ <div v-if="col.avatarKey">
311
+ <div
312
+ v-if="
313
+ props.row[col.avatarKey] &&
314
+ typeof props.row[col.avatarKey] === 'object'
315
+ "
316
+ class="table-data-avatar"
317
+ >
318
+ <UAvatar
319
+ v-if="props.row[col.avatarKey]?.type === 'initials'"
320
+ :name="`${props.row[col.avatarKey]?.value}`"
321
+ size="lg"
322
+ />
323
+ <UAvatar
324
+ v-else-if="
325
+ props.row[col.avatarKey]?.type === 'image'
326
+ "
327
+ :image="`${props.row[col.avatarKey]?.value}`"
328
+ :name="
329
+ props.row[col.avatarKey]?.name ??
330
+ props.row[col.avatarKey]?.value
331
+ "
332
+ size="lg"
333
+ />
334
+ </div>
335
+ <div v-else class="table-data-avatar">
336
+ <UAvatar
337
+ :image="`${props.row[col.avatarKey]}`"
338
+ :name="`${props.row[col.avatarKey]}`"
339
+ size="lg"
340
+ />
341
+ </div>
342
+ </div>
343
+
344
+ <q-item-label v-if="col.type !== 'icon'" caption>
345
+ <span
346
+ :class="[
347
+ col.value ? 'long-text-content' : '',
348
+ col.noEllipsis ? 'no-ellipsis-content' : '',
349
+ col.doubleSpan && col.noEllipsis
350
+ ? 'full-width-text-content'
351
+ : '',
352
+ !isResponsiveTablet &&
353
+ isTablet &&
354
+ col.classes &&
355
+ col.classes.length > 0 &&
356
+ col.classes[0] === 'no-wrap-text'
357
+ ? 'tablet-event-text'
358
+ : '',
359
+ ]"
360
+ :id="`long-content-${col.field}-${props.row.id}`"
361
+ >
362
+ {{ col.value }}
363
+ </span>
364
+ <UTooltip
365
+ v-if="
366
+ col.value &&
367
+ col.value.length > 12 &&
368
+ isContentVisible(col.field, props.row.id, 'content')
369
+ "
370
+ anchor="bottom middle"
371
+ :description="col.value"
372
+ :offset="[10, 40]"
373
+ self="bottom middle"
374
+ :target="`#long-content-${col.field}-${props.row.id}`"
375
+ />
376
+ <div
377
+ v-if="col.captionKey"
378
+ class="td-caption mobile-primary-caption text-body-md"
379
+ :id="`long-caption-${col.field}-${props.row.id}`"
380
+ >
381
+ <template v-if="col.captionKeyTitle">
382
+ {{ col.captionKeyTitle }}:
383
+ </template>
384
+ {{ props.row[col.captionKey] }}
385
+ </div>
386
+ <UTooltip
387
+ v-if="
388
+ props.row[col.captionKey] &&
389
+ props.row[col.captionKey].length > 12 &&
390
+ isContentVisible(col.field, props.row.id, 'caption')
391
+ "
392
+ anchor="bottom middle"
393
+ :description="props.row[col.captionKey]"
394
+ :offset="[10, 40]"
395
+ self="bottom middle"
396
+ :target="`#long-caption-${col.field}-${props.row.id}`"
397
+ />
398
+ </q-item-label>
399
+ </div>
400
+ </template>
401
+ <template v-if="col.actions && col.actions.length === 1">
402
+ <template v-for="(action, key) in col.actions" :key="key">
403
+ <UBtnStd
404
+ v-if="
405
+ typeof action.hide === 'function'
406
+ ? !action.hide(props.row)
407
+ : true
408
+ "
409
+ :color="
410
+ typeof action.color === 'function'
411
+ ? action.color(props.row)
412
+ : action.color
413
+ "
414
+ :disable="
415
+ typeof action.disable === 'function' &&
416
+ action.disable(props.row)
417
+ "
418
+ :flat="
419
+ typeof action.flat === 'function'
420
+ ? action.flat(props.row)
421
+ : action.flat
422
+ "
423
+ full-width
424
+ :key="key"
425
+ :label="
426
+ typeof action.label === 'function'
427
+ ? action.label(props.row)
428
+ : action.label
429
+ "
430
+ :leftIcon="
431
+ typeof action.icon === 'function'
432
+ ? action.icon(props.row)
433
+ : action.icon
434
+ "
435
+ :loading="
436
+ typeof action.loading === 'function'
437
+ ? action.loading(props.row)
438
+ : action.loading
439
+ "
440
+ :outline="
441
+ typeof action.outline === 'function'
442
+ ? action.outline(props.row)
443
+ : action.outline
444
+ "
445
+ :size="action.size"
446
+ @on-click="action.handler(props.row)"
447
+ >
448
+ <template #tooltip>
449
+ <UTooltip
450
+ v-if="
451
+ typeof action.tooltip === 'function'
452
+ ? action.tooltip(props.row)
453
+ : action.tooltip
454
+ "
455
+ :anchor="action.anchor"
456
+ :description="
457
+ typeof action.tooltip === 'function'
458
+ ? action.tooltip(props.row)
459
+ : action.tooltip
460
+ "
461
+ :offset="action.offset ? action.offset : [10, 40]"
462
+ :self="action.anchor"
463
+ />
464
+ </template>
465
+ </UBtnStd>
466
+ </template>
467
+ </template>
468
+ <template v-if="col.actions && col.actions.length > 1">
469
+ <q-dialog
470
+ v-if="
471
+ isTablet &&
472
+ moreActionDialogData &&
473
+ moreActionDialogData.showDialog[props.row.id]
474
+ "
475
+ v-model="moreActionDialogData.showDialog[props.row.id]"
476
+ class="more-action-popup"
477
+ persistent
478
+ >
479
+ <q-card
480
+ class="more-action-popup-wrapper confirmation-dialog-wrapper q-px-ba q-py-ba"
481
+ >
482
+ <q-card-section>
483
+ <div class="content-wrapper text-center">
484
+ <div
485
+ class="q-pb-ba flex justify-center items-center"
486
+ >
487
+ <div
488
+ :class="`remove-icon-wrapper ${
489
+ moreActionDialogData.row.iconColor ===
490
+ 'accent'
491
+ ? 'icon-bg-accent'
492
+ : 'icon-bg-primary'
493
+ }`"
494
+ >
495
+ <q-icon
496
+ :class="`${moreActionDialogData.row.icon} ${
497
+ moreActionDialogData.row.iconColor ===
498
+ 'accent'
499
+ ? 'icon-text-accent'
500
+ : 'icon-text-primary'
501
+ }`"
502
+ alt="confirmation icon"
503
+ aria-label="confirmation icon"
504
+ size="1.5rem"
505
+ />
506
+ </div>
507
+ </div>
508
+
509
+ <div
510
+ class="text-heading-xxs primary-content-text q-pb-xxs"
511
+ >
512
+ {{ moreActionDialogData.row.title }}
513
+ </div>
514
+ <div
515
+ v-if="moreActionDialogData.row.description"
516
+ class="text-body-sm secondary-content-text q-pb-xs"
517
+ >
518
+ {{ moreActionDialogData.row.description }}
519
+ </div>
520
+ </div>
521
+ <!-- <p class="hidden-scope-value">{{ scope.value }}</p> -->
522
+ </q-card-section>
523
+
524
+ <q-card-actions align="right">
525
+ <UBtnStd
526
+ v-if="moreActionDialogData.secondaryAction"
527
+ :color="moreActionDialogData.secondaryAction.color"
528
+ :disable="
529
+ moreActionDialogData.secondaryAction.disable
530
+ "
531
+ :flat="moreActionDialogData.secondaryAction.flat"
532
+ :label="moreActionDialogData.secondaryAction.label"
533
+ :loading="
534
+ moreActionDialogData.secondaryAction.loading
535
+ "
536
+ :outline="
537
+ moreActionDialogData.secondaryAction.outline
538
+ "
539
+ :size="moreActionDialogData.secondaryAction.size"
540
+ @on-click="
541
+ moreActionDialogData.secondaryAction.handler(
542
+ props.row
543
+ )
544
+ "
545
+ />
546
+ <UBtnStd
547
+ v-if="moreActionDialogData.primaryAction"
548
+ class="confirm-primary-action"
549
+ :color="moreActionDialogData.primaryAction.color"
550
+ :disable="
551
+ moreActionDialogData.primaryAction.disable
552
+ "
553
+ :flat="moreActionDialogData.primaryAction.flat"
554
+ :label="moreActionDialogData.primaryAction.label"
555
+ :loading="
556
+ moreActionDialogData.primaryAction.loading
557
+ "
558
+ :outline="
559
+ moreActionDialogData.primaryAction.outline
560
+ "
561
+ :size="moreActionDialogData.primaryAction.size"
562
+ @on-click="
563
+ moreActionDialogData.primaryAction.handler(
564
+ props.row
565
+ )
566
+ "
567
+ />
568
+ </q-card-actions>
569
+ </q-card>
570
+ </q-dialog>
571
+
572
+ <UBtnStd
573
+ v-if="!isMobile"
574
+ color="primary"
575
+ full-width
576
+ :id="`actionPopupRefBtn-${props.row.id}`"
577
+ label="View More"
578
+ outline
579
+ >
580
+ <template #menu>
581
+ <q-menu
582
+ class="more-action-popup"
583
+ auto-close
584
+ fit
585
+ :id="`actionPopupRef-${props.row.id}`"
586
+ :offset="[10, 20]"
587
+ transition-show="jump-down"
588
+ transition-hide="jump-up"
589
+ @show="checkMenuPosition(props.row.id)"
590
+ >
591
+ <div :class="tailClass"></div>
592
+ <div
593
+ class="q-pt-ba q-px-ba q-pb-none text-heading-xxs text-dark"
594
+ >
595
+ Select More Options
596
+ </div>
597
+ <q-list class="grid-more-action">
598
+ <template v-for="(action, __i) in col.actions">
599
+ <q-item
600
+ v-if="
601
+ typeof action.hide === 'function'
602
+ ? !action.hide(props.row)
603
+ : true
604
+ "
605
+ class="q-px-sm q-py-ba bg-neutral-2 q-mb-xs"
606
+ :aria-label="
607
+ typeof action.label === 'function'
608
+ ? action.label(props.row)
609
+ : action.label
610
+ "
611
+ clickable
612
+ :key="__i"
613
+ tabindex="-1"
614
+ @click="action.handler(props.row)"
615
+ >
616
+ <q-item-section class="q-pr-xs" avatar>
617
+ <q-icon
618
+ v-if="
619
+ typeof action.icon === 'function'
620
+ ? action.icon(props.row)
621
+ : action.icon
622
+ "
623
+ :class="`${
624
+ typeof action.icon === 'function'
625
+ ? action.icon(props.row)
626
+ : action.icon
627
+ } text-${getActionItemColor(
628
+ action,
629
+ props.row
630
+ )}`"
631
+ size="1.5rem"
632
+ tabindex="-1"
633
+ />
634
+ </q-item-section>
635
+ <q-item-section
636
+ :class="`text-caption-lg text-${getActionItemColor(
637
+ action,
638
+ props.row
639
+ )}`"
640
+ tabindex="0"
641
+ >
642
+ {{
643
+ typeof action.label === 'function'
644
+ ? action.label(props.row)
645
+ : action.label
646
+ }}
647
+ </q-item-section>
648
+ </q-item>
649
+ </template>
650
+ </q-list>
651
+ </q-menu>
652
+ </template>
653
+ </UBtnStd>
654
+ <template v-if="isMobile">
655
+ <UBtnStd
656
+ color="primary"
657
+ full-width
658
+ :id="`view-more-actions-${props.row['id']}`"
659
+ label="View More"
660
+ outline
661
+ @on-click="handleOpenMobileMoreActions(props.row['id'])"
662
+ />
663
+ <USheet
664
+ v-if="
665
+ moreActionDialogData &&
666
+ moreActionDialogData.showDialog[props.row.id]
667
+ "
668
+ v-model:dialogs="mobileActionsDialog[props.row['id']]"
669
+ closeIconLabel="Close Icon"
670
+ :heading="moreActionDialogData.row.title"
671
+ :is-left-icon="false"
672
+ :show-action-buttons="true"
673
+ >
674
+ <template #content>
675
+ <q-card
676
+ class="more-action-popup-wrapper confirmation-dialog-wrapper mobile-confirmation-dialog q-px-ba q-py-ba"
677
+ >
678
+ <q-card-section>
679
+ <div class="content-wrapper text-center">
680
+ <div
681
+ class="q-pb-ba flex justify-center items-center"
682
+ >
683
+ <div
684
+ :class="`remove-icon-wrapper ${
685
+ moreActionDialogData.row.iconColor ===
686
+ 'accent'
687
+ ? 'icon-bg-accent'
688
+ : 'icon-bg-primary'
689
+ }`"
690
+ >
691
+ <q-icon
692
+ :class="`${
693
+ moreActionDialogData.row.icon
694
+ } ${
695
+ moreActionDialogData.row.iconColor ===
696
+ 'accent'
697
+ ? 'icon-text-accent'
698
+ : 'icon-text-primary'
699
+ }`"
700
+ alt="confirmation icon"
701
+ aria-label="confirmation icon"
702
+ size="1.5rem"
703
+ />
704
+ </div>
705
+ </div>
706
+
707
+ <div
708
+ class="text-heading-xxs primary-content-text q-pb-xxs"
709
+ >
710
+ {{ moreActionDialogData.row.title }}
711
+ </div>
712
+ <div
713
+ v-if="moreActionDialogData.row.description"
714
+ class="text-body-sm secondary-content-text q-pb-xs"
715
+ >
716
+ {{ moreActionDialogData.row.description }}
717
+ </div>
718
+ </div>
719
+ </q-card-section>
720
+ </q-card>
721
+ </template>
722
+ <template
723
+ v-if="
724
+ moreActionDialogData &&
725
+ moreActionDialogData.showDialog[props.row.id] &&
726
+ moreActionDialogData.secondaryAction
727
+ "
728
+ #action_primary_one
729
+ >
730
+ <UBtnStd
731
+ :color="moreActionDialogData.secondaryAction.color"
732
+ :disable="
733
+ moreActionDialogData.secondaryAction.disable
734
+ "
735
+ :flat="moreActionDialogData.secondaryAction.flat"
736
+ :label="moreActionDialogData.secondaryAction.label"
737
+ :loading="
738
+ moreActionDialogData.secondaryAction.loading
739
+ "
740
+ :outline="
741
+ moreActionDialogData.secondaryAction.outline
742
+ "
743
+ :size="moreActionDialogData.secondaryAction.size"
744
+ @on-click="
745
+ moreActionDialogData.secondaryAction.handler(
746
+ props.row
747
+ )
748
+ "
749
+ />
750
+ </template>
751
+ <template
752
+ v-if="
753
+ moreActionDialogData &&
754
+ moreActionDialogData.showDialog[props.row.id] &&
755
+ moreActionDialogData.primaryAction
756
+ "
757
+ #action_primary_two
758
+ >
759
+ <UBtnStd
760
+ class="confirm-primary-action"
761
+ :color="moreActionDialogData.primaryAction.color"
762
+ :disable="
763
+ moreActionDialogData.primaryAction.disable
764
+ "
765
+ :flat="moreActionDialogData.primaryAction.flat"
766
+ :label="moreActionDialogData.primaryAction.label"
767
+ :loading="
768
+ moreActionDialogData.primaryAction.loading
769
+ "
770
+ :outline="
771
+ moreActionDialogData.primaryAction.outline
772
+ "
773
+ :size="moreActionDialogData.primaryAction.size"
774
+ @on-click="
775
+ moreActionDialogData.primaryAction.handler(
776
+ props.row
777
+ )
778
+ "
779
+ />
780
+ </template>
781
+ </USheet>
782
+ <USheet
783
+ v-model:dialogs="moreActionsDialogs[props.row['id']]"
784
+ closeIconLabel="Close Icon"
785
+ heading="Select More Options"
786
+ :is-left-icon="false"
787
+ :show-action-buttons="false"
788
+ >
789
+ <template #content>
790
+ <q-list class="mobile-grid-more-action">
791
+ <template v-for="(action, __i) in col.actions">
792
+ <q-item
793
+ v-if="
794
+ typeof action.hide === 'function'
795
+ ? !action.hide(props.row)
796
+ : true
797
+ "
798
+ class="q-px-sm q-py-ba bg-neutral-2 q-mb-xs"
799
+ :aria-label="
800
+ typeof action.label === 'function'
801
+ ? action.label(props.row)
802
+ : action.label
803
+ "
804
+ clickable
805
+ :key="__i"
806
+ tabindex="-1"
807
+ @click="handleItemClick(action, props.row)"
808
+ >
809
+ <q-item-section class="q-pr-xs" avatar>
810
+ <q-icon
811
+ v-if="
812
+ typeof action.icon === 'function'
813
+ ? action.icon(props.row)
814
+ : action.icon
815
+ "
816
+ :class="`${
817
+ typeof action.icon === 'function'
818
+ ? action.icon(props.row)
819
+ : action.icon
820
+ } text-${getActionItemColor(
821
+ action,
822
+ props.row
823
+ )}`"
824
+ size="1.5rem"
825
+ tabindex="-1"
826
+ />
827
+ </q-item-section>
828
+ <q-item-section
829
+ :class="`text-caption-lg text-${getActionItemColor(
830
+ action,
831
+ props.row
832
+ )}`"
833
+ tabindex="0"
834
+ >
835
+ {{
836
+ typeof action.label === 'function'
837
+ ? action.label(props.row)
838
+ : action.label
839
+ }}
840
+ </q-item-section>
841
+ </q-item>
842
+ </template>
843
+ </q-list>
844
+ </template>
845
+ </USheet>
846
+ </template>
847
+ </template>
848
+ </q-item-section>
849
+ </q-item>
850
+ </template>
851
+ </q-list>
852
+ </q-card>
853
+ </div>
85
854
  </template>
86
855
  </q-table>
87
856
  </template>