@usssa/component-library 1.0.0-alpha.93 → 1.0.0-alpha.95

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usssa/component-library",
3
- "version": "1.0.0-alpha.93",
3
+ "version": "1.0.0-alpha.95",
4
4
  "description": "A Quasar component library project",
5
5
  "productName": "Quasar component library App",
6
6
  "author": "Troy Moreland <troy.moreland@usssa.com>",
@@ -6,6 +6,16 @@ import UBtnIcon from './UBtnIcon.vue'
6
6
  import UBtnStd from './UBtnStd.vue'
7
7
  import UMenuItem from './UMenuItem.vue'
8
8
  import UTooltip from './UTooltip.vue'
9
+
10
+ const emit = defineEmits(['menuItemClicked', 'closeDrawer'])
11
+ const miniState = defineModel('miniState', {
12
+ default: false,
13
+ type: Boolean,
14
+ })
15
+ const open = defineModel('open', {
16
+ default: false,
17
+ type: Boolean,
18
+ })
9
19
  const props = defineProps({
10
20
  menu: {
11
21
  default: () => [],
@@ -23,32 +33,15 @@ const props = defineProps({
23
33
  type: String,
24
34
  },
25
35
  })
26
- const emit = defineEmits(['menuItemClicked', 'closeDrawer'])
27
- const open = defineModel('open', {
28
- default: false,
29
- type: Boolean,
30
- })
31
- const miniState = defineModel('miniState', {
32
- default: false,
33
- type: Boolean,
34
- })
35
36
 
36
37
  const $router = useRouter()
37
- const currentRoute = computed(() => $router.currentRoute.value.fullPath)
38
38
  const currentPath = computed(() => getCurrentPath())
39
+ const currentRoute = computed(() => $router.currentRoute.value.fullPath)
39
40
 
40
41
  const getCurrentPath = (int = 1) => {
41
42
  return currentRoute.value.split('/')[int]
42
43
  }
43
44
 
44
- const handleClick = (menu) => {
45
- emit('menuItemClicked', menu)
46
- }
47
-
48
- const handleCloseDrawer = () => {
49
- emit('closeDrawer')
50
- }
51
-
52
45
  /**
53
46
  * returning x offset for tooltip for long text
54
47
  * @param {*} label
@@ -57,6 +50,14 @@ const getXOffset = (label) => {
57
50
  let labelLength = label.trim().length
58
51
  return labelLength <= 4 ? 65 : labelLength < 9 ? 85 : 145
59
52
  }
53
+
54
+ const handleClick = (menu) => {
55
+ emit('menuItemClicked', menu)
56
+ }
57
+
58
+ const handleCloseDrawer = () => {
59
+ emit('closeDrawer')
60
+ }
60
61
  </script>
61
62
  <template>
62
63
  <q-drawer
@@ -65,14 +66,14 @@ const getXOffset = (label) => {
65
66
  :breakpoint="400"
66
67
  :mini="miniState"
67
68
  :mini-width="64"
68
- side="left"
69
69
  show-if-above
70
+ side="left"
70
71
  :width="224"
71
72
  >
72
73
  <q-scroll-area class="u-drawer-scrollable-area">
73
74
  <div
74
75
  :class="`flex items-center justify-${
75
- miniState ? 'center q-py-sm' : 'between q-py-xs q-pl-ba q-pr-xxs'
76
+ miniState ? 'center q-py-xs' : 'between q-py-xs q-pl-ba q-pr-xxs'
76
77
  } `"
77
78
  >
78
79
  <UBtnStd
@@ -102,10 +103,10 @@ const getXOffset = (label) => {
102
103
  class="drawer-open-close-icon-wrapper flex items-center justify-center"
103
104
  >
104
105
  <UBtnIcon
106
+ iconClass="fa-kit-duotone fa-sidebar-shrink"
105
107
  ariaLabel="Sidebar shrink icon"
106
108
  color="primary"
107
109
  dense
108
- iconClass="fa-kit-duotone fa-sidebar-shrink"
109
110
  ref="btn-icon"
110
111
  size="sm"
111
112
  @click="handleCloseDrawer"
@@ -132,7 +133,7 @@ const getXOffset = (label) => {
132
133
  @onClick="handleClick(m)"
133
134
  >
134
135
  <template v-if="!miniState" #trailing_slot>
135
- <UBadgeStd v-if="m.badgeInfo" size="lg" :label="m.badgeInfo" />
136
+ <UBadgeStd v-if="m.badgeInfo" :label="m.badgeInfo" size="lg" />
136
137
  <q-icon
137
138
  v-if="m.rightIcon"
138
139
  :class="`${m.rightIcon} ${
@@ -146,12 +147,12 @@ const getXOffset = (label) => {
146
147
  </template>
147
148
  </UMenuItem>
148
149
  <UTooltip
149
- :description="m.label"
150
150
  v-if="miniState"
151
- :target="`#u-drawer-menu-${i}`"
152
151
  anchor="center right"
153
- self="center right"
152
+ :description="m.label"
154
153
  :offset="[getXOffset(m.label), 20]"
154
+ self="center right"
155
+ :target="`#u-drawer-menu-${i}`"
155
156
  />
156
157
  </template>
157
158
  </q-list>
@@ -26,13 +26,13 @@ const props = defineProps({
26
26
  <q-list :class="`u-menu-dropdown size-${size} ${menuClass} q-gutter-y-xxs`">
27
27
  <template v-for="(item, index) in data" :key="index">
28
28
  <UMenuItem
29
+ :iconClass="iconClass"
30
+ :destructive="item.destructive"
31
+ :disable="item.disable"
32
+ :hide="item.hide"
29
33
  :label="item.label"
30
34
  :leftIcon="item.leftIcon"
31
35
  :rightIcon="item.rightIcon"
32
- :destructive="item.destructive"
33
- :iconClass="iconClass"
34
- :hide="item.hide"
35
- :disable="item.disable"
36
36
  @onClick="item.handler"
37
37
  >
38
38
  <template #leading_slot>
@@ -1,6 +1,7 @@
1
1
  <script setup>
2
2
  import { computed, ref, watch } from 'vue'
3
3
 
4
+ const emit = defineEmits(['onClick'])
4
5
  const props = defineProps({
5
6
  leftIcon: {
6
7
  type: String,
@@ -32,8 +33,6 @@ const props = defineProps({
32
33
  },
33
34
  })
34
35
 
35
- const emit = defineEmits(['onClick'])
36
-
37
36
  const type = ref(props.destructive ? 'destructive' : 'default')
38
37
 
39
38
  /* Computed variables */
@@ -98,9 +97,9 @@ watch(
98
97
  <q-item-section v-if="rightIcon" side>
99
98
  <q-icon
100
99
  :class="`${rightIcon} ${iconClass}`"
100
+ :aria-hidden="true"
101
101
  :color="iconColor"
102
102
  size="1rem"
103
- :aria-hidden="true"
104
103
  />
105
104
  </q-item-section>
106
105
  <slot name="trailing_slot"></slot>
@@ -1,4 +1,21 @@
1
1
  <script setup>
2
+ const pagination = defineModel('pagination', {
3
+ default: { page: 1, rowsPerPage: 15 },
4
+ type: Object,
5
+ })
6
+ const loading = defineModel('loading', {
7
+ default: null,
8
+ type: Boolean,
9
+ })
10
+ const rows = defineModel('rows', {
11
+ default: () => [],
12
+ type: Array,
13
+ })
14
+ const columns = defineModel('columns', {
15
+ default: () => [],
16
+ type: Array,
17
+ })
18
+
2
19
  const props = defineProps({
3
20
  title: {
4
21
  type: String,
@@ -37,38 +54,12 @@ const props = defineProps({
37
54
  default: true,
38
55
  },
39
56
  })
40
-
41
- const pagination = defineModel('pagination', {
42
- default: { page: 1, rowsPerPage: 15 },
43
- type: Object,
44
- })
45
- const loading = defineModel('loading', {
46
- default: null,
47
- type: Boolean,
48
- })
49
- const rows = defineModel('rows', {
50
- default: () => [],
51
- type: Array,
52
- })
53
- const columns = defineModel('columns', {
54
- default: () => [],
55
- type: Array,
56
- })
57
57
  </script>
58
58
 
59
59
  <template>
60
60
  <q-table
61
+ v-model:pagination="pagination"
61
62
  v-bind="$attrs"
62
- :title="title"
63
- :columns="columns"
64
- :rows="rows"
65
- :row-key="rowKey"
66
- :flat="flat"
67
- :bordered="bordered"
68
- :separator="separator"
69
- :loading="loading"
70
- hide-pagination
71
- :grid="grid"
72
63
  :class="`u-table ${virtualScroll ? 'u-virtualscroll-table' : ''} ${
73
64
  grid ? 'u-virtualscroll-grid-table' : ''
74
65
  } ${stickyHeader ? 'u-sticky-table-header' : ''} ${
@@ -76,9 +67,18 @@ const columns = defineModel('columns', {
76
67
  ? 'force-auto-height-table'
77
68
  : ''
78
69
  }`"
79
- :virtual-scroll="!grid && virtualScroll"
80
- v-model:pagination="pagination"
70
+ :bordered="bordered"
71
+ :columns="columns"
72
+ :flat="flat"
73
+ :grid="grid"
74
+ hide-pagination
75
+ :loading="loading"
76
+ :separator="separator"
77
+ :rows="rows"
78
+ :row-key="rowKey"
81
79
  :rows-per-page-options="[0]"
80
+ :title="title"
81
+ :virtual-scroll="!grid && virtualScroll"
82
82
  :virtual-scroll-item-size="48"
83
83
  :virtual-scroll-sticky-size-start="48"
84
84
  >
@@ -12,6 +12,31 @@ import UTd from './UTable/UTd.vue'
12
12
  import UTh from './UTable/UTh.vue'
13
13
  import UTr from './UTable/UTr.vue'
14
14
 
15
+ const emit = defineEmits(['onCustomSort'])
16
+ const selectedRows = defineModel('selectedRows', {
17
+ default: () => [],
18
+ type: Array,
19
+ })
20
+ const rows = defineModel('rows', {
21
+ default: () => [],
22
+ type: Array,
23
+ })
24
+ const columns = defineModel('columns', {
25
+ default: () => [],
26
+ type: Array,
27
+ })
28
+ const pagination = defineModel('pagination', {
29
+ default: { page: 1, rowsPerPage: 15 },
30
+ type: Object,
31
+ })
32
+ const loading = defineModel('loading', {
33
+ default: () => {},
34
+ type: Boolean,
35
+ })
36
+ const moreActionDialogData = defineModel('moreActionDialogData', {
37
+ type: Object,
38
+ default: null,
39
+ })
15
40
  const props = defineProps({
16
41
  title: {
17
42
  type: String,
@@ -67,29 +92,6 @@ const props = defineProps({
67
92
  },
68
93
  })
69
94
 
70
- const emit = defineEmits(['onCustomSort'])
71
-
72
- const selectedRows = defineModel('selectedRows', {
73
- default: () => [],
74
- type: Array,
75
- })
76
- const rows = defineModel('rows', {
77
- default: () => [],
78
- type: Array,
79
- })
80
- const columns = defineModel('columns', {
81
- default: () => [],
82
- type: Array,
83
- })
84
- const pagination = defineModel('pagination', {
85
- default: { page: 1, rowsPerPage: 15 },
86
- type: Object,
87
- })
88
- const loading = defineModel('loading', {
89
- default: () => {},
90
- type: Boolean,
91
- })
92
-
93
95
  const customLoading = ref(false)
94
96
  const rowsPerPageOptions = ref([
95
97
  { label: '5 / per page', value: 5 },
@@ -99,9 +101,7 @@ const rowsPerPageOptions = ref([
99
101
  { label: '25 / per page', value: 25 },
100
102
  ])
101
103
  const tableDataChip = ref(true) // this is required to show chip
102
- const openMenu = ref([])
103
- const hoveringButton = ref({})
104
- const hoveringMenu = ref({})
104
+ const tailClass = ref(null)
105
105
 
106
106
  // if virtual scroll is enbaled then adding large rows per page to view in virtual scroll
107
107
  const getRowsPerPageOptions = computed(() => {
@@ -117,18 +117,39 @@ const getRowsPerPageOptions = computed(() => {
117
117
  }
118
118
  })
119
119
 
120
- //adding a new row to selectedRows
121
- const handleToSelectRow = (row) => {
122
- if (row) {
123
- const index = selectedRows.value.findIndex((item) => item._id === row._id)
124
- if (index === -1) {
125
- selectedRows.value.push(row)
120
+ // chekcing the menu position after show
121
+ const checkMenuPosition = (id) => {
122
+ const menuElement = document.getElementById(`actionPopupRef-${id}`) // Access the menu by ID
123
+ const buttonElement = document.getElementById(`actionPopupRefBtn-${id}`) // Access the button element
124
+
125
+ if (menuElement && buttonElement) {
126
+ const menuRect = menuElement.getBoundingClientRect() // Menu position
127
+ const buttonRect = buttonElement.getBoundingClientRect() // Button position
128
+
129
+ // Determine if the menu opens above or below
130
+ if (menuRect.top < buttonRect.top) {
131
+ tailClass.value = 'tail-bottom' // Menu opens below, tail at the bottom
126
132
  } else {
127
- selectedRows.value.splice(index, 1)
133
+ tailClass.value = 'tail-top' // Menu opens above, tail at the top
128
134
  }
129
135
  }
130
136
  }
131
137
 
138
+ // sorting funtion to handle text and number type of data
139
+ const dataSort = (data, key, order, type) => {
140
+ if (type === 'text') {
141
+ return data.sort((a, b) =>
142
+ order === 'asc'
143
+ ? a[key].localeCompare(b[key])
144
+ : b[key].localeCompare(a[key])
145
+ )
146
+ } else {
147
+ return data.sort((a, b) =>
148
+ order === 'asc' ? a[key] - b[key] : b[key] - a[key]
149
+ )
150
+ }
151
+ }
152
+
132
153
  //getting the sorted icon according the order
133
154
  const getSortingIcon = (col) => {
134
155
  if (col) {
@@ -140,47 +161,31 @@ const getSortingIcon = (col) => {
140
161
  }
141
162
  }
142
163
 
143
- // it is giving the selected row and setting the new selection
144
- const isRowSelected = (row) => {
145
- if (row) {
146
- const index = selectedRows.value.findIndex((item) => item._id === row._id)
147
- return computed({
148
- get: () => {
149
- return index === -1 ? false : true
150
- },
151
- set: () => {
152
- if (index === -1) {
153
- selectedRows.value.push(row)
154
- } else {
155
- selectedRows.value.splice(index, 1)
156
- }
157
- },
158
- })
164
+ //getting the chip color accroding to value of chip from row
165
+ const getChipColor = (data, value) => {
166
+ const foundObject = data.find((chip) => chip.value === value)
167
+ if (foundObject) {
168
+ return foundObject['color']
159
169
  } else {
160
- return computed({
161
- get: () => {
162
- let dataLength = props.rows.length
163
- return selectedRows.value.length === dataLength
164
- ? true
165
- : selectedRows.value.length === 0
166
- ? false
167
- : null
168
- },
169
- set: (value) => {
170
- if (value !== null) {
171
- selectedRows.value.splice(0, selectedRows.value.length)
172
- } else {
173
- handleSelectAllData().then((res) => {
174
- if (res === 200) {
175
- customLoading.value = false
176
- }
177
- })
178
- }
179
- },
180
- })
170
+ return 'neutral-3'
181
171
  }
182
172
  }
183
173
 
174
+ const handleActionColClick = (e) => {
175
+ e.preventDefault()
176
+ e.stopPropagation()
177
+ }
178
+
179
+ const handleMenuEventStop = (e) => {
180
+ e.preventDefault()
181
+ e.stopPropagation()
182
+ }
183
+
184
+ //if user want to add custom sort on data
185
+ const handleCustomSort = (key, sortOrder, type) => {
186
+ emit('onCustomSort', key, sortOrder, type)
187
+ }
188
+
184
189
  // handling the large selection data in chunks
185
190
  const handleSelectAllData = () => {
186
191
  customLoading.value = true
@@ -211,21 +216,6 @@ const handleSelectAllData = () => {
211
216
  })
212
217
  }
213
218
 
214
- // sorting funtion to handle text and number type of data
215
- const dataSort = (data, key, order, type) => {
216
- if (type === 'text') {
217
- return data.sort((a, b) =>
218
- order === 'asc'
219
- ? a[key].localeCompare(b[key])
220
- : b[key].localeCompare(a[key])
221
- )
222
- } else {
223
- return data.sort((a, b) =>
224
- order === 'asc' ? a[key] - b[key] : b[key] - a[key]
225
- )
226
- }
227
- }
228
-
229
219
  //it is sorting the data according to type like text or number type of data
230
220
  const handleSort = (key, sortOrder, type) => {
231
221
  rows.value = dataSort(rows.value, key, sortOrder, type)
@@ -236,26 +226,56 @@ const handleSort = (key, sortOrder, type) => {
236
226
  })
237
227
  }
238
228
 
239
- //if user want to add custom sort on data
240
- const handleCustomSort = (key, sortOrder, type) => {
241
- emit('onCustomSort', key, sortOrder, type)
242
- }
243
-
244
229
  //adding a new row to selectedRows
245
- const onRowClick = (event, row) => {
246
- if (props.multiSelection) {
247
- event.stopPropagation()
248
- handleToSelectRow(row)
230
+ const handleToSelectRow = (row) => {
231
+ if (row) {
232
+ const index = selectedRows.value.findIndex((item) => item._id === row._id)
233
+ if (index === -1) {
234
+ selectedRows.value.push(row)
235
+ } else {
236
+ selectedRows.value.splice(index, 1)
237
+ }
249
238
  }
250
239
  }
251
240
 
252
- //getting the chip color accroding to value of chip from row
253
- const getChipColor = (data, value) => {
254
- const foundObject = data.find((chip) => chip.value === value)
255
- if (foundObject) {
256
- return foundObject['color']
241
+ // it is giving the selected row and setting the new selection
242
+ const isRowSelected = (row) => {
243
+ if (row) {
244
+ const index = selectedRows.value.findIndex((item) => item._id === row._id)
245
+ return computed({
246
+ get: () => {
247
+ return index === -1 ? false : true
248
+ },
249
+ set: () => {
250
+ if (index === -1) {
251
+ selectedRows.value.push(row)
252
+ } else {
253
+ selectedRows.value.splice(index, 1)
254
+ }
255
+ },
256
+ })
257
257
  } else {
258
- return 'neutral-3'
258
+ return computed({
259
+ get: () => {
260
+ let dataLength = props.rows.length
261
+ return selectedRows.value.length === dataLength
262
+ ? true
263
+ : selectedRows.value.length === 0
264
+ ? false
265
+ : null
266
+ },
267
+ set: (value) => {
268
+ if (value !== null) {
269
+ selectedRows.value.splice(0, selectedRows.value.length)
270
+ } else {
271
+ handleSelectAllData().then((res) => {
272
+ if (res === 200) {
273
+ customLoading.value = false
274
+ }
275
+ })
276
+ }
277
+ },
278
+ })
259
279
  }
260
280
  }
261
281
 
@@ -264,70 +284,51 @@ const onPageChange = (value) => {
264
284
  pagination.value.page = value
265
285
  }
266
286
 
267
- //handle to change the rows per page
268
- const onRowPerPageChange = (value) => {
269
- pagination.value.rowsPerPage = value
270
- }
271
-
272
- const handleMenuEventStop = (e) => {
273
- e.preventDefault()
274
- e.stopPropagation()
275
- }
276
-
277
- const handleMouseEnter = (type, index) => {
278
- if (type === 'button') {
279
- hoveringButton.value[index] = true
280
- } else {
281
- hoveringMenu.value[index] = true
287
+ //adding a new row to selectedRows
288
+ const onRowClick = (event, row) => {
289
+ if (props.multiSelection) {
290
+ event.stopPropagation()
291
+ handleToSelectRow(row)
282
292
  }
283
- openMenu.value[index] = true
284
293
  }
285
294
 
286
- const handleMouseLeave = (type, index) => {
287
- if (type === 'button') {
288
- hoveringButton.value[index] = false
289
- } else {
290
- hoveringMenu.value[index] = false
291
- }
292
- setTimeout(() => {
293
- if (!hoveringButton.value[index] && !hoveringMenu.value[index]) {
294
- openMenu.value[index] = false
295
- }
296
- }, 100)
295
+ //handle to change the rows per page
296
+ const onRowPerPageChange = (value) => {
297
+ pagination.value.rowsPerPage = value
297
298
  }
298
299
  </script>
299
300
 
300
301
  <template>
301
302
  <UTable
302
- :title="title"
303
- v-model:rows="rows"
304
303
  v-model:columns="columns"
305
- :separator="separator"
306
- :loading="loading"
307
- :flat="flat"
308
- :bordered="bordered"
309
304
  v-model:pagination="pagination"
310
- :grid="grid"
311
- :virtualScroll="virtualScroll"
312
- :stickyHeader="stickyHeader"
305
+ v-model:rows="rows"
313
306
  :class="customClass"
307
+ :bordered="bordered"
308
+ :flat="flat"
309
+ :grid="grid"
310
+ :loading="loading"
311
+ :separator="separator"
314
312
  :showPagination="showPagination"
313
+ :stickyHeader="stickyHeader"
314
+ :title="title"
315
+ :virtualScroll="virtualScroll"
315
316
  >
316
317
  <!-- custom header slot to add customized header -->
317
318
  <template v-slot:header="props">
318
319
  <UTr :props="props" :tableRowHover="tableRowHover">
319
320
  <UTh
320
321
  v-if="multiSelection"
322
+ :separator="separator"
321
323
  style="width: 3% !important"
322
324
  :tableHeaderAutoWidth="false"
323
325
  tableHeadAlignment="left"
324
- :separator="separator"
325
326
  >
326
327
  <UCheckboxStd
327
- :id="`u-checkbox-table-header`"
328
328
  v-model="isRowSelected(null).value"
329
- name="Table Header"
329
+ id="u-checkbox-table-header"
330
330
  :indeterminate="true"
331
+ name="Table Header"
331
332
  />
332
333
  </UTh>
333
334
  <template v-for="(col, key) in props.cols">
@@ -337,6 +338,8 @@ const handleMouseLeave = (type, index) => {
337
338
  col.headerClasses
338
339
  }`"
339
340
  :key="key"
341
+ :separator="separator"
342
+ :style="col.headerStyle"
340
343
  :tableHeaderAutoWidth="col.autoWidth"
341
344
  :tableHeadAlignment="col.field === 'action' ? col.align : col.align"
342
345
  @click="
@@ -346,8 +349,6 @@ const handleMouseLeave = (type, index) => {
346
349
  : handleSort(col.field, col.sortOrder, col.type)
347
350
  : null
348
351
  "
349
- :separator="separator"
350
- :style="col.headerStyle"
351
352
  >
352
353
  <span
353
354
  :class="`${col.field === 'action' ? 'hidden-header-label' : ''}`"
@@ -359,8 +360,8 @@ const handleMouseLeave = (type, index) => {
359
360
  <UBtnIcon
360
361
  :class="`more-action-icon cursor-pointer`"
361
362
  :iconClass="`${getSortingIcon(col)}`"
362
- ref="btn-icon"
363
363
  :aria-label="`Sort ${col.label}`"
364
+ ref="btn-icon"
364
365
  size="sm"
365
366
  />
366
367
  </span>
@@ -379,16 +380,17 @@ const handleMouseLeave = (type, index) => {
379
380
  <UTd
380
381
  v-if="multiSelection"
381
382
  :index="-1"
383
+ :separator="separator"
382
384
  tableDataAlignment="left"
383
385
  :tableHeaderAutoWidth="false"
384
- :separator="separator"
385
386
  >
386
387
  <UCheckboxStd
387
- :id="`u-checkbox-${props.row._id}`"
388
388
  v-model="isRowSelected(props.row).value"
389
+ :id="`u-checkbox-${props.row._id}`"
389
390
  :name="props.row._id"
390
391
  />
391
392
  </UTd>
393
+
392
394
  <template v-for="(col, index) in props.cols" :key="index">
393
395
  <!-- to show the cell data without the action cell -->
394
396
  <UTd
@@ -396,28 +398,28 @@ const handleMouseLeave = (type, index) => {
396
398
  col.field !== 'action' &&
397
399
  (typeof col.show === 'undefined' || col.show)
398
400
  "
399
- :row="props.row"
401
+ :class="col.classes"
400
402
  :col="col"
401
403
  :index="index"
402
- :tableDataAlignment="col.align"
403
- :tableDataAutoWidth="col.autoWidth"
404
+ :row="props.row"
404
405
  :separator="separator"
405
406
  :style="col.style"
406
- :class="col.classes"
407
+ :tableDataAlignment="col.align"
408
+ :tableDataAutoWidth="col.autoWidth"
407
409
  >
408
410
  <!-- to show the chips with different variant -->
409
411
  <template v-if="col.chipValues && col.chipValues.length > 0">
410
412
  <UChip
411
413
  v-model="tableDataChip"
412
- :type="getChipColor(col.chipValues, props.row[col.field])"
414
+ class="u-table-chip"
413
415
  avatarLabel=""
416
+ :anchor="col.anchor"
414
417
  :chipLabel="props.row[col.field].toString()"
415
- :removable="false"
416
- class="u-table-chip"
418
+ :dense="col.denseChip"
417
419
  :is-show-tooltip="col.showChipTooltip"
418
420
  :offset="col.offset"
419
- :anchor="col.anchor"
420
- :dense="col.denseChip"
421
+ :removable="false"
422
+ :type="getChipColor(col.chipValues, props.row[col.field])"
421
423
  />
422
424
  </template>
423
425
  <!-- to show the avatar of user image with name and other details -->
@@ -432,29 +434,29 @@ const handleMouseLeave = (type, index) => {
432
434
  >
433
435
  <UAvatar
434
436
  v-if="props.row[col.avatarKey]?.type === 'initials'"
435
- size="md"
436
437
  :name="`${props.row[col.avatarKey]?.value}`"
438
+ size="md"
437
439
  />
438
440
  <UAvatar
439
441
  v-else-if="props.row[col.avatarKey]?.type === 'image'"
440
- size="md"
442
+ :image="`${props.row[col.avatarKey]?.value}`"
441
443
  :name="
442
444
  props.row[col.avatarKey]?.name ??
443
445
  props.row[col.avatarKey]?.value
444
446
  "
445
- :image="`${props.row[col.avatarKey]?.value}`"
447
+ size="md"
446
448
  />
447
449
  </div>
448
450
  <div v-else class="table-data-avatar">
449
451
  <UAvatar
450
- size="md"
451
- :name="`${props.row[col.avatarKey]}`"
452
452
  :image="`${props.row[col.avatarKey]}`"
453
+ :name="`${props.row[col.avatarKey]}`"
454
+ size="md"
453
455
  />
454
456
  </div>
455
457
  <div class="td-grid-content">
456
458
  <div>{{ props.row[col.field] }}</div>
457
- <div class="td-caption text-body-xs" v-if="col.captionKey">
459
+ <div v-if="col.captionKey" class="td-caption text-body-xs">
458
460
  {{ props.row[col.captionKey] }}
459
461
  </div>
460
462
  </div>
@@ -478,8 +480,8 @@ const handleMouseLeave = (type, index) => {
478
480
  </template>
479
481
  </div>
480
482
  <div
481
- class="td-caption text-body-xs"
482
483
  v-if="col.captionKey && col.type !== 'icon'"
484
+ class="td-caption text-body-xs"
483
485
  >
484
486
  {{ props.row[col.captionKey] }}
485
487
  </div>
@@ -492,11 +494,12 @@ const handleMouseLeave = (type, index) => {
492
494
  v-else-if="typeof col.show === 'undefined' || col.show"
493
495
  :class="col.classes"
494
496
  :index="index"
495
- :tableDataAlignment="col.align"
496
- :tableDataAutoWidth="false"
497
- style="width: 3%"
498
497
  :separator="separator"
499
498
  :style="col.style"
499
+ style="width: 3%"
500
+ :tableDataAlignment="col.align"
501
+ :tableDataAutoWidth="false"
502
+ @click="handleActionColClick"
500
503
  >
501
504
  <template v-if="col.actions && col.actions.length === 1">
502
505
  <template v-for="(action, key) in col.actions" :key="key">
@@ -506,16 +509,16 @@ const handleMouseLeave = (type, index) => {
506
509
  ? !action.hide(props.row)
507
510
  : true
508
511
  "
509
- :key="key"
510
- :label="action.label"
511
- :flat="action.flat"
512
- :outline="action.outline"
513
- :leftIcon="action.icon"
514
512
  :color="action.color"
515
513
  :disable="
516
514
  typeof action.disable === 'function' &&
517
515
  action.disable(props.row)
518
516
  "
517
+ :flat="action.flat"
518
+ :key="key"
519
+ :label="action.label"
520
+ :leftIcon="action.icon"
521
+ :outline="action.outline"
519
522
  :size="action.size"
520
523
  @onClick="action.handler(props.row)"
521
524
  />
@@ -523,31 +526,102 @@ const handleMouseLeave = (type, index) => {
523
526
  </template>
524
527
  <!-- to show the actions list if the actions are multiple -->
525
528
  <template v-else>
529
+ <q-menu
530
+ v-if="moreActionDialogData.showDialog[props.row.id]"
531
+ v-model="moreActionDialogData.showDialog[props.row.id]"
532
+ :class="`more-action-popup q-px-ba q-py-ba`"
533
+ anchor="top left"
534
+ :cover="false"
535
+ :fit="true"
536
+ :id="`actionPopupRef-${props.row.id}`"
537
+ :offset="[85, 0]"
538
+ role="list"
539
+ self="bottom middle"
540
+ transition-show="scale"
541
+ transition-hide="scale"
542
+ @show="checkMenuPosition(props.row.id)"
543
+ >
544
+ <div :class="tailClass"></div>
545
+ <q-card class="more-action-popup-wrapper">
546
+ <q-card-section>
547
+ <div class="content-wrapper text-center">
548
+ <div class="q-pb-ba flex justify-center items-center">
549
+ <div
550
+ :class="`remove-icon-wrapper ${
551
+ moreActionDialogData.row.iconColor === 'accent'
552
+ ? 'icon-bg-accent'
553
+ : 'icon-bg-primary'
554
+ }`"
555
+ >
556
+ <q-icon
557
+ :class="`${moreActionDialogData.row.icon} ${
558
+ moreActionDialogData.row.iconColor === 'accent'
559
+ ? 'icon-text-accent'
560
+ : 'icon-text-primary'
561
+ }`"
562
+ alt="confirmation icon"
563
+ aria-label="confirmation icon"
564
+ size="1.5rem"
565
+ />
566
+ </div>
567
+ </div>
568
+
569
+ <div
570
+ class="text-heading-xxs primary-content-text q-pb-xxs"
571
+ >
572
+ {{ moreActionDialogData.row.title }}
573
+ </div>
574
+ <div
575
+ v-if="moreActionDialogData.row.description"
576
+ class="text-body-sm secondary-content-text q-pb-xs"
577
+ >
578
+ {{ moreActionDialogData.row.description }}
579
+ </div>
580
+ </div>
581
+ <!-- <p class="hidden-scope-value">{{ scope.value }}</p> -->
582
+ </q-card-section>
583
+
584
+ <q-card-actions align="right">
585
+ <UBtnStd
586
+ v-if="moreActionDialogData.secondaryAction"
587
+ :color="moreActionDialogData.secondaryAction.color"
588
+ :disable="moreActionDialogData.secondaryAction.disable"
589
+ :flat="moreActionDialogData.secondaryAction.flat"
590
+ :label="moreActionDialogData.secondaryAction.label"
591
+ :outline="moreActionDialogData.secondaryAction.outline"
592
+ :size="moreActionDialogData.secondaryAction.size"
593
+ @on-click="
594
+ moreActionDialogData.secondaryAction.handler(props.row)
595
+ "
596
+ />
597
+ <UBtnStd
598
+ v-if="moreActionDialogData.primaryAction"
599
+ class="confirm-primary-action"
600
+ :color="moreActionDialogData.primaryAction.color"
601
+ :disable="moreActionDialogData.primaryAction.disable"
602
+ :flat="moreActionDialogData.primaryAction.flat"
603
+ :label="moreActionDialogData.primaryAction.label"
604
+ :outline="moreActionDialogData.primaryAction.outline"
605
+ :size="moreActionDialogData.primaryAction.size"
606
+ @on-click="
607
+ moreActionDialogData.primaryAction.handler(props.row)
608
+ "
609
+ />
610
+ </q-card-actions>
611
+ </q-card>
612
+ </q-menu>
613
+
526
614
  <UBtnIcon
527
- :key="index"
528
615
  :class="`action-icon cursor-pointer`"
529
616
  iconClass="fa-kit fa-ellipsis-vertical"
530
- ref="btn-icon"
531
617
  ariaLabel="More action"
532
- @focus="handleMouseEnter('button', props.row.id)"
533
- @mouseover="handleMouseEnter('button', props.row.id)"
534
- @mouseleave="handleMouseLeave('button', props.row.id)"
535
- @blur="handleMouseLeave('button', props.row.id)"
618
+ :id="`actionPopupRefBtn-${props.row.id}`"
619
+ :key="index"
620
+ ref="btn-icon"
536
621
  @click.stop="handleMenuEventStop"
537
622
  >
538
623
  <template #menu>
539
- <q-menu
540
- v-if="!verticalMoreActions"
541
- v-model="openMenu[props.row.id]"
542
- role="list"
543
- no-focus
544
- no-refocus
545
- persistent
546
- @focus="handleMouseEnter('button', props.row.id)"
547
- @mouseleave="handleMouseLeave('menu', props.row.id)"
548
- @mouseover="handleMouseEnter('menu', props.row.id)"
549
- @blur="handleMouseLeave('button', props.row.id)"
550
- >
624
+ <q-menu v-if="!verticalMoreActions" auto-close role="list">
551
625
  <div
552
626
  :class="`${
553
627
  verticalMoreActions ? 'vertical' : 'horizontal'
@@ -560,37 +634,25 @@ const handleMouseLeave = (type, index) => {
560
634
  ? !action.hide(props.row)
561
635
  : true && !verticalMoreActions
562
636
  "
563
- :id="`more-action-${key}`"
564
- :class="`more-action-icon cursor-pointer`"
637
+ :class="`more-action-icon cursor-pointer table-more-action`"
565
638
  :iconClass="action.icon"
566
- ref="btn-icon"
567
639
  :ariaLabel="action.label"
568
640
  :disable="
569
641
  typeof action.disable === 'function' &&
570
642
  action.disable(props.row)
571
643
  "
644
+ :id="`more-action-${key}`"
645
+ ref="btn-icon"
572
646
  :size="action.size"
573
647
  :tooltip="action.tooltip"
574
- @onClick="action.handler(props.row)"
575
648
  @click.stop="handleMenuEventStop"
576
- @focus="handleMouseEnter('button', props.row.id)"
649
+ @onClick="action.handler(props.row)"
577
650
  />
578
651
  </template>
579
652
  </div>
580
653
  </q-menu>
581
654
 
582
- <q-menu
583
- v-else
584
- v-model="openMenu[props.row.id]"
585
- role="list"
586
- no-focus
587
- no-refocus
588
- persistent
589
- @focus="handleMouseEnter('button', props.row.id)"
590
- @mouseleave="handleMouseLeave('menu', props.row.id)"
591
- @mouseover="handleMouseEnter('menu', props.row.id)"
592
- @blur="handleMouseLeave('button', props.row.id)"
593
- >
655
+ <q-menu v-else auto-close role="list">
594
656
  <UMenuDropdown
595
657
  v-if="verticalMoreActions"
596
658
  :data="
@@ -639,12 +701,12 @@ const handleMouseLeave = (type, index) => {
639
701
  <UPagination
640
702
  v-if="rows.length >= 6"
641
703
  v-model="pagination.page"
642
- :rowPerPage="pagination.rowsPerPage"
643
- :perPageOptions="getRowsPerPageOptions"
644
704
  :maxPageLink="
645
705
  Number(Math.ceil(rows.length / pagination.rowsPerPage > 10 ? 6 : 3))
646
706
  "
647
707
  :maxPages="Number(Math.ceil(rows.length / pagination.rowsPerPage))"
708
+ :perPageOptions="getRowsPerPageOptions"
709
+ :rowPerPage="pagination.rowsPerPage"
648
710
  @onPageChange="onPageChange"
649
711
  @onRowChange="onRowPerPageChange"
650
712
  />
@@ -665,7 +727,6 @@ const handleMouseLeave = (type, index) => {
665
727
  &:hover
666
728
  color: $primary !important
667
729
 
668
-
669
730
  .table-data-avatar
670
731
  padding: $xs
671
732
  padding-left: 0px
@@ -682,7 +743,6 @@ const handleMouseLeave = (type, index) => {
682
743
  background: $surface-bg-1
683
744
  box-shadow: 0px 0px 4px 0px rgba(16, 17, 20, 0.08)
684
745
 
685
-
686
746
  .vertical-more-action-wrapper
687
747
  display: grid
688
748
  place-items: flex-start
@@ -758,10 +818,10 @@ const handleMouseLeave = (type, index) => {
758
818
  top: 0
759
819
 
760
820
  &.q-table--loading thead tr:last-child th
761
- top: 48px
821
+ top: 3rem
762
822
 
763
823
  tbody
764
- scroll-margin-top: 48px
824
+ scroll-margin-top: 3rem
765
825
 
766
826
  .u-sorting-btn
767
827
  padding: 0
@@ -795,4 +855,83 @@ const handleMouseLeave = (type, index) => {
795
855
 
796
856
  .hidden-header-label
797
857
  visibility: hidden
858
+
859
+ .more-action-popup
860
+ border-radius: $border-radius-sm
861
+ background: $neutral-1
862
+ box-shadow: 0rem 0rem 0.75rem 0rem rgba(16, 17, 20, 0.16)
863
+ max-width: 18.375rem !important
864
+ width: 100%
865
+ position: relative
866
+ overflow: visible
867
+
868
+ .more-action-popup-wrapper
869
+ box-shadow: none
870
+ max-width: 18.375rem !important
871
+ width: 100%
872
+ .hidden-scope-value
873
+ display: none
874
+ .q-card__section
875
+ padding: 0
876
+ .q-card__actions
877
+ flex-wrap: nowrap
878
+ padding: $ba 0 0 0
879
+ .q-btn
880
+ width: 50%
881
+
882
+ .content-wrapper
883
+ display: grid
884
+ place-content: center
885
+ place-items: center
886
+
887
+ .secondary-content-text
888
+ color: $description
889
+
890
+ .primary-content-text
891
+ color: $dark
892
+
893
+ .remove-icon-wrapper
894
+ border-radius: 7.75rem
895
+ padding: $sm
896
+ width: 3.125rem
897
+ height: 3.125rem
898
+ .q-icon
899
+ color: $accent
900
+
901
+ .confirm-primary-action
902
+ margin-left: $ba !important
903
+
904
+ .icon-bg-accent
905
+ background-color: $red-1
906
+
907
+ .icon-bg-primary
908
+ background-color: $blue-1
909
+
910
+ .icon-text-accent
911
+ color: $accent
912
+
913
+ .icon-text-primary
914
+ color: $primary !important
915
+
916
+ .tail-top
917
+ width: 1.25rem
918
+ height: 1.25rem
919
+ transform: rotate(45deg)
920
+ position: absolute
921
+ right: 1.304rem
922
+ top: -0.604rem
923
+ border-top-left-radius: $border-radius-xs
924
+ background: $neutral-1
925
+ box-shadow: -3px -2px 5px -3px rgba(0, 0, 0, 0.2)
926
+
927
+ .tail-bottom
928
+ width: 1.25rem
929
+ height: 1.25rem
930
+ transform: rotate(45deg)
931
+ position: absolute
932
+ right: 1.304rem
933
+ bottom: -0.604rem
934
+ border-bottom-right-radius: $border-radius-xs
935
+ background: $neutral-1
936
+ box-shadow: 3px 4px 5px -3px rgba(0, 0, 0, 0.2)
798
937
  </style>
@@ -99,7 +99,7 @@ $xxl : $space-base * 3.375 !default
99
99
  $space-none : (x: 0, y: 0) !default
100
100
  $space-xxs : (x: ($space-x-base * .25), y: ($space-y-base * .25)) !default
101
101
  $space-xs : (x: ($space-x-base * .5), y: ($space-y-base * .5)) !default
102
- $space-sm : (x: ($space-x-base * .75), y: ($space-y-base * .5)) !default
102
+ $space-sm : (x: ($space-x-base * .75), y: ($space-y-base * .75)) !default
103
103
  $space-ms : (x: ($space-x-base * 1.5), y: ($space-y-base * 1.5)) !default
104
104
  $space-ba : (x: ($space-x-base * 1), y: ($space-y-base * 1)) !default
105
105
  $space-md : (x: $space-x-base * 2, y: $space-y-base * 2) !default
@@ -117,3 +117,5 @@ $stroke-skeuomorphic: 1px solid rgba(255, 255, 255, 0.12)
117
117
  $shadow-2: 0px 0px 8px 0px rgba(16, 17, 20, 0.12)
118
118
  $accent-bg-hover: rgba(203, 42, 61, 0.15)
119
119
  $surface-bg-link-hover :rgba(16, 17, 20, .5)
120
+ $border-radius-sm: .75rem
121
+ $border-radius-xs: .5rem