@mythpe/quasar-ui-qui 0.1.9 → 0.1.11
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 +1 -1
- package/src/components/datatable/MDatatable.vue +121 -183
- package/src/components/datatable/MDtBtn.vue +23 -14
- package/src/components/datatable/MDtContextmenuItems.vue +3 -3
- package/src/components/form/MAvatarViewer.vue +1 -1
- package/src/components/form/MPicker.vue +1 -1
- package/src/style/main.sass +0 -1
- package/src/types/api/MAvatarViewer.d.ts +1 -1
- package/src/types/api/MAxios.d.ts +1 -1
- package/src/types/api-helpers.d.ts +2 -0
- package/src/types/components.d.ts +1 -10
- package/src/types/m-datatable.d.ts +2 -0
- package/src/types/plugin-props-option.d.ts +4 -4
- package/src/utils/Helpers.ts +6 -0
package/package.json
CHANGED
|
@@ -48,54 +48,55 @@ const initMetaServer: MDatatableMetaServer = {
|
|
|
48
48
|
total: null
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
type Props = {
|
|
52
52
|
controlKey?: MDatatableProps['controlKey'];
|
|
53
53
|
defaultItem?: MDatatableProps['defaultItem'];
|
|
54
54
|
contextItems?: MDatatableProps['contextItems'];
|
|
55
55
|
contextItemsLength?: MDatatableProps['contextItemsLength'];
|
|
56
|
-
hideAutoMessage?:
|
|
56
|
+
hideAutoMessage?: boolean;
|
|
57
57
|
headers: MDatatableProps['headers'];
|
|
58
58
|
serviceName?: MDatatableProps['serviceName'];
|
|
59
59
|
requestParams?: MDatatableProps['requestParams'];
|
|
60
|
-
pdf?:
|
|
61
|
-
excel?:
|
|
60
|
+
pdf?: boolean;
|
|
61
|
+
excel?: boolean;
|
|
62
62
|
exportUrl?: MDatatableProps['exportUrl'];
|
|
63
|
-
hideSearch?:
|
|
63
|
+
hideSearch?: boolean;
|
|
64
64
|
searchDebounce?: MDatatableProps['searchDebounce'];
|
|
65
65
|
withIndex?: MDatatableProps['withIndex'];
|
|
66
66
|
withStore?: MDatatableProps['withStore'];
|
|
67
67
|
withShow?: MDatatableProps['withShow'];
|
|
68
68
|
withUpdate?: MDatatableProps['withUpdate'];
|
|
69
|
-
hideAddBtn?:
|
|
70
|
-
hideUpdateBtn?:
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
hideAddBtn?: boolean;
|
|
70
|
+
hideUpdateBtn?: boolean;
|
|
71
|
+
cloneBtn?: boolean;
|
|
72
|
+
hideShowBtn?: boolean;
|
|
73
|
+
hideDestroyBtn?: boolean;
|
|
73
74
|
storeRoute?: MDatatableProps['storeRoute'];
|
|
74
|
-
storeQueryParams?:
|
|
75
|
+
storeQueryParams?: boolean;
|
|
75
76
|
updateRoute?: MDatatableProps['updateRoute'];
|
|
76
|
-
updateQueryParams?:
|
|
77
|
+
updateQueryParams?: boolean;
|
|
77
78
|
showRoute?: MDatatableProps['showRoute'];
|
|
78
|
-
showQueryParams?:
|
|
79
|
-
mouse?:
|
|
80
|
-
noRefreshBtn?:
|
|
81
|
-
endReach?:
|
|
82
|
-
showSelection?:
|
|
83
|
-
hideSelection?:
|
|
84
|
-
multiSelection?:
|
|
85
|
-
multiDestroy?:
|
|
79
|
+
showQueryParams?: boolean;
|
|
80
|
+
mouse?: boolean;
|
|
81
|
+
noRefreshBtn?: boolean;
|
|
82
|
+
endReach?: boolean;
|
|
83
|
+
showSelection?: boolean;
|
|
84
|
+
hideSelection?: boolean;
|
|
85
|
+
multiSelection?: boolean;
|
|
86
|
+
multiDestroy?: boolean;
|
|
86
87
|
rowsPerPageOptions?: MDatatableProps['rowsPerPageOptions'];
|
|
87
88
|
ignoreKeys?: MDatatableProps['ignoreKeys'];
|
|
88
89
|
grid?: MDatatableProps['grid'];
|
|
89
90
|
title?: MDatatableProps['title'];
|
|
90
|
-
manageColumns?:
|
|
91
|
+
manageColumns?: boolean;
|
|
91
92
|
visibleColumns?: MDatatableProps['visibleColumns'];
|
|
92
93
|
searchColumns?: MDatatableProps['searchColumns'];
|
|
93
|
-
addTopBtn?:
|
|
94
|
-
addListBtn?:
|
|
95
|
-
addFabBtn?:
|
|
96
|
-
fullscreenBtn?:
|
|
97
|
-
noBodyControl?:
|
|
98
|
-
showCardControlHeader?:
|
|
94
|
+
addTopBtn?: boolean;
|
|
95
|
+
addListBtn?: boolean;
|
|
96
|
+
addFabBtn?: boolean;
|
|
97
|
+
fullscreenBtn?: boolean;
|
|
98
|
+
noBodyControl?: boolean;
|
|
99
|
+
showCardControlHeader?: boolean;
|
|
99
100
|
dense?: MDatatableProps['dense'];
|
|
100
101
|
bordered?: MDatatableProps['bordered'];
|
|
101
102
|
flat?: MDatatableProps['flat'];
|
|
@@ -119,29 +120,30 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
119
120
|
pdf: undefined,
|
|
120
121
|
excel: undefined,
|
|
121
122
|
exportUrl: undefined,
|
|
122
|
-
hideSearch:
|
|
123
|
+
hideSearch: !1,
|
|
123
124
|
searchDebounce: () => 600,
|
|
124
125
|
withIndex: undefined,
|
|
125
126
|
withStore: undefined,
|
|
126
127
|
withShow: undefined,
|
|
127
128
|
withUpdate: undefined,
|
|
128
|
-
hideAddBtn:
|
|
129
|
-
hideUpdateBtn:
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
hideAddBtn: !1,
|
|
130
|
+
hideUpdateBtn: !1,
|
|
131
|
+
cloneBtn: !1,
|
|
132
|
+
hideShowBtn: !1,
|
|
133
|
+
hideDestroyBtn: !1,
|
|
132
134
|
storeRoute: undefined,
|
|
133
|
-
storeQueryParams:
|
|
135
|
+
storeQueryParams: !1,
|
|
134
136
|
updateRoute: undefined,
|
|
135
|
-
updateQueryParams:
|
|
137
|
+
updateQueryParams: !1,
|
|
136
138
|
showRoute: undefined,
|
|
137
|
-
showQueryParams:
|
|
138
|
-
mouse:
|
|
139
|
-
noRefreshBtn:
|
|
140
|
-
endReach:
|
|
141
|
-
showSelection:
|
|
142
|
-
hideSelection:
|
|
143
|
-
multiSelection:
|
|
144
|
-
multiDestroy:
|
|
139
|
+
showQueryParams: !1,
|
|
140
|
+
mouse: !1,
|
|
141
|
+
noRefreshBtn: !1,
|
|
142
|
+
endReach: !1,
|
|
143
|
+
showSelection: !1,
|
|
144
|
+
hideSelection: !1,
|
|
145
|
+
multiSelection: !1,
|
|
146
|
+
multiDestroy: !1,
|
|
145
147
|
rowsPerPageOptions: () => [50, 250, 500, 0],
|
|
146
148
|
ignoreKeys: undefined,
|
|
147
149
|
grid: undefined,
|
|
@@ -282,8 +284,10 @@ const resetDialogs = () => {
|
|
|
282
284
|
/** --- */
|
|
283
285
|
const headersProp = computed(() => props.headers)
|
|
284
286
|
const getHeaders = computed<any[]>(() => parseHeaders(headersProp.value, reactive({ noSort: props.imageColumns })) || [])
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
+
const visibleHeaders = ref<string[]>(parseHeaders(props.visibleColumns || headersProp.value).map(e => e.name))
|
|
288
|
+
watch(() => toValue(props.visibleColumns), v => {
|
|
289
|
+
visibleHeaders.value = v ? parseHeaders(v).map(e => e.name) : []
|
|
290
|
+
}, { deep: !0 })
|
|
287
291
|
/** --- */
|
|
288
292
|
|
|
289
293
|
const selected = ref<MDtItem[]>([])
|
|
@@ -332,7 +336,7 @@ const tableOptions = reactive<MDatatableOptions>({
|
|
|
332
336
|
/** Table */
|
|
333
337
|
|
|
334
338
|
/** --- */
|
|
335
|
-
const addListBtnComputed = computed(() => {
|
|
339
|
+
/* const addListBtnComputed = computed(() => {
|
|
336
340
|
if (props.addListBtn !== undefined) {
|
|
337
341
|
return props.addListBtn
|
|
338
342
|
}
|
|
@@ -340,7 +344,7 @@ const addListBtnComputed = computed(() => {
|
|
|
340
344
|
return pluginOptions.value.datatable?.addListBtn
|
|
341
345
|
}
|
|
342
346
|
return !1
|
|
343
|
-
})
|
|
347
|
+
}) */
|
|
344
348
|
const hasAddBtn = computed<boolean>(() => {
|
|
345
349
|
if (props.hideAddBtn) {
|
|
346
350
|
return !1
|
|
@@ -351,24 +355,25 @@ const hasUpdateBtn = computed<boolean>(() => {
|
|
|
351
355
|
if (props.hideUpdateBtn) {
|
|
352
356
|
return !1
|
|
353
357
|
}
|
|
354
|
-
return !!slots.form || !!props.updateRoute ||
|
|
358
|
+
return !!slots.form || !!props.updateRoute || props.updateQueryParams
|
|
355
359
|
})
|
|
360
|
+
const hasCloneBtn = computed<boolean>(() => Boolean(props.cloneBtn))
|
|
356
361
|
const hasShowBtn = computed<boolean>(() => {
|
|
357
362
|
if (props.hideShowBtn) {
|
|
358
363
|
return !1
|
|
359
364
|
}
|
|
360
|
-
return !!slots.show || !!props.showRoute ||
|
|
365
|
+
return !!slots.show || !!props.showRoute || props.showQueryParams
|
|
361
366
|
})
|
|
362
367
|
const hasDestroyBtn = computed<boolean>(() => !props.hideDestroyBtn)
|
|
363
368
|
const hasFilterDialog = computed<boolean>(() => !!slots.filter)
|
|
364
|
-
const hasMenu = computed<boolean>(() => {
|
|
365
|
-
const pdf =
|
|
366
|
-
const excel =
|
|
369
|
+
/* const hasMenu = computed<boolean>(() => {
|
|
370
|
+
const pdf = props.pdf && getRows.value.length > 0
|
|
371
|
+
const excel = props.excel && getRows.value.length > 0
|
|
367
372
|
if (pdf || excel) {
|
|
368
373
|
return !0
|
|
369
374
|
}
|
|
370
375
|
return hasAddBtn.value && !!addListBtnComputed.value
|
|
371
|
-
})
|
|
376
|
+
}) */
|
|
372
377
|
|
|
373
378
|
const isUpdateMode = ref<boolean>(!1)
|
|
374
379
|
const formMode = computed<'update' | 'store'>(() => isUpdateMode.value ? 'update' : 'store')
|
|
@@ -1014,7 +1019,6 @@ const onRowContextmenu = (e: MouseEvent | Event, row: MDtItem, index: number | u
|
|
|
1014
1019
|
}
|
|
1015
1020
|
const contextmenuItemsProp = computed(() => props.contextItems)
|
|
1016
1021
|
const contextmenuItems = computed<any>(() => ([
|
|
1017
|
-
...(contextmenuItemsProp.value || []),
|
|
1018
1022
|
{
|
|
1019
1023
|
name: 'show',
|
|
1020
1024
|
label: pluginOptions.value?.dt?.contextmenu?.btnStyle?.showLabel ? 'labels.show' : undefined,
|
|
@@ -1024,6 +1028,13 @@ const contextmenuItems = computed<any>(() => ([
|
|
|
1024
1028
|
showIf: hasShowBtn.value,
|
|
1025
1029
|
order: 100
|
|
1026
1030
|
},
|
|
1031
|
+
{
|
|
1032
|
+
name: 'clone',
|
|
1033
|
+
label: pluginOptions.value?.dt?.contextmenu?.btnStyle?.showLabel ? 'labels.clone' : undefined,
|
|
1034
|
+
click: onCloneItem,
|
|
1035
|
+
showIf: hasCloneBtn.value,
|
|
1036
|
+
order: 200
|
|
1037
|
+
},
|
|
1027
1038
|
{
|
|
1028
1039
|
name: 'update',
|
|
1029
1040
|
label: pluginOptions.value?.dt?.contextmenu?.btnStyle?.showLabel ? 'labels.update' : undefined,
|
|
@@ -1031,7 +1042,7 @@ const contextmenuItems = computed<any>(() => ([
|
|
|
1031
1042
|
openUpdateDialog(item, index)
|
|
1032
1043
|
},
|
|
1033
1044
|
showIf: hasUpdateBtn.value,
|
|
1034
|
-
order:
|
|
1045
|
+
order: 300
|
|
1035
1046
|
},
|
|
1036
1047
|
{
|
|
1037
1048
|
name: 'destroy',
|
|
@@ -1044,9 +1055,28 @@ const contextmenuItems = computed<any>(() => ([
|
|
|
1044
1055
|
attr: {
|
|
1045
1056
|
color: 'negative'
|
|
1046
1057
|
},
|
|
1047
|
-
order:
|
|
1048
|
-
}
|
|
1058
|
+
order: 400
|
|
1059
|
+
},
|
|
1060
|
+
...(contextmenuItemsProp.value || [])
|
|
1049
1061
|
].sort((a, b) => (a.order ?? 0) - (b.order ?? 0))))
|
|
1062
|
+
const onCloneItem = (item: MDtItem) => {
|
|
1063
|
+
item = toValue(item)
|
|
1064
|
+
confirmMessage()
|
|
1065
|
+
.onOk(() => {
|
|
1066
|
+
$q.loading.show()
|
|
1067
|
+
getMythApiServicesSchema().clone(item.id)
|
|
1068
|
+
.then(({ _message }) => {
|
|
1069
|
+
_message && alertSuccess(_message)
|
|
1070
|
+
refreshNoUpdate()
|
|
1071
|
+
})
|
|
1072
|
+
.catch(({ _message }) => {
|
|
1073
|
+
_message && alertError(_message)
|
|
1074
|
+
})
|
|
1075
|
+
.finally(() => {
|
|
1076
|
+
$q.loading.hide()
|
|
1077
|
+
})
|
|
1078
|
+
})
|
|
1079
|
+
}
|
|
1050
1080
|
const endReach = computed<boolean>(() => Boolean(props.endReach))
|
|
1051
1081
|
const rowsPerPageOptions = computed(() => props.rowsPerPageOptions)
|
|
1052
1082
|
const getRowsPerPageOptions = computed<any[]>(() => endReach.value ? [0] : (rowsPerPageOptions.value || [0]))
|
|
@@ -1551,124 +1581,29 @@ defineOptions({
|
|
|
1551
1581
|
/>
|
|
1552
1582
|
</MRow>
|
|
1553
1583
|
<!--Buttons-->
|
|
1554
|
-
<MRow class="
|
|
1555
|
-
<!--
|
|
1584
|
+
<MRow class="q-gutter-x-sm q-gutter-xs-y-sm items-center">
|
|
1585
|
+
<!-- Export PDF-->
|
|
1556
1586
|
<MDtBtn
|
|
1557
|
-
v-if="
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
tooltip="myth.datatable.hints.more"
|
|
1563
|
-
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.more}"
|
|
1587
|
+
v-if="pdf && getRows.length > 0"
|
|
1588
|
+
icon="fa-solid fa-file-pdf"
|
|
1589
|
+
text-color="red"
|
|
1590
|
+
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter}"
|
|
1591
|
+
@click="exportData('pdf')"
|
|
1564
1592
|
>
|
|
1565
|
-
<
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
v-close-popup
|
|
1578
|
-
clickable
|
|
1579
|
-
v-bind="pluginOptions.dt?.buttons?.moreItem"
|
|
1580
|
-
@click="openCreateDialog()"
|
|
1581
|
-
>
|
|
1582
|
-
<q-item-section thumbnail>
|
|
1583
|
-
<q-icon
|
|
1584
|
-
color="primary"
|
|
1585
|
-
name="add"
|
|
1586
|
-
right
|
|
1587
|
-
size="xs"
|
|
1588
|
-
/>
|
|
1589
|
-
</q-item-section>
|
|
1590
|
-
<q-item-section>
|
|
1591
|
-
<span> {{ getFormTitle }}</span>
|
|
1592
|
-
</q-item-section>
|
|
1593
|
-
</q-item>
|
|
1594
|
-
<!-- Export PDF-->
|
|
1595
|
-
<q-item
|
|
1596
|
-
v-if="pdf && getRows.length > 0"
|
|
1597
|
-
v-close-popup
|
|
1598
|
-
clickable
|
|
1599
|
-
v-bind="pluginOptions.dt?.buttons?.moreItem"
|
|
1600
|
-
@click="exportData('pdf')"
|
|
1601
|
-
>
|
|
1602
|
-
<q-item-section thumbnail>
|
|
1603
|
-
<q-icon
|
|
1604
|
-
color="red"
|
|
1605
|
-
name="fa-solid fa-file-pdf"
|
|
1606
|
-
right
|
|
1607
|
-
size="xs"
|
|
1608
|
-
/>
|
|
1609
|
-
</q-item-section>
|
|
1610
|
-
<q-item-section>
|
|
1611
|
-
<span>
|
|
1612
|
-
{{ __('myth.titles.exportPdf') }}
|
|
1613
|
-
<q-badge
|
|
1614
|
-
v-if="tableOptions.selected.length > 1"
|
|
1615
|
-
:label="tableOptions.selected.length"
|
|
1616
|
-
align="top"
|
|
1617
|
-
rounded
|
|
1618
|
-
/>
|
|
1619
|
-
</span>
|
|
1620
|
-
</q-item-section>
|
|
1621
|
-
</q-item>
|
|
1622
|
-
<!-- Export Excel-->
|
|
1623
|
-
<q-item
|
|
1624
|
-
v-if="excel && getRows.length > 0"
|
|
1625
|
-
v-close-popup
|
|
1626
|
-
clickable
|
|
1627
|
-
v-bind="pluginOptions.dt?.buttons?.moreItem"
|
|
1628
|
-
@click="exportData('excel')"
|
|
1629
|
-
>
|
|
1630
|
-
<q-item-section thumbnail>
|
|
1631
|
-
<q-icon
|
|
1632
|
-
color="green"
|
|
1633
|
-
name="fa-solid fa-file-excel"
|
|
1634
|
-
right
|
|
1635
|
-
size="xs"
|
|
1636
|
-
/>
|
|
1637
|
-
</q-item-section>
|
|
1638
|
-
<q-item-section>
|
|
1639
|
-
<span>
|
|
1640
|
-
{{ __('myth.titles.exportExcel') }}
|
|
1641
|
-
<q-badge
|
|
1642
|
-
v-if="tableOptions.selected.length>1"
|
|
1643
|
-
:label="tableOptions.selected.length"
|
|
1644
|
-
align="top"
|
|
1645
|
-
rounded
|
|
1646
|
-
/>
|
|
1647
|
-
</span>
|
|
1648
|
-
</q-item-section>
|
|
1649
|
-
</q-item>
|
|
1650
|
-
<q-item
|
|
1651
|
-
v-if="fullscreenBtn === undefined ? ( !!pluginOptions.datatable?.fullscreenBtn) : fullscreenBtn"
|
|
1652
|
-
v-close-popup
|
|
1653
|
-
clickable
|
|
1654
|
-
v-bind="pluginOptions.dt?.buttons?.moreItem"
|
|
1655
|
-
@click="tableOptions.fullscreen = !tableOptions.fullscreen"
|
|
1656
|
-
>
|
|
1657
|
-
<q-item-section thumbnail>
|
|
1658
|
-
<q-icon
|
|
1659
|
-
:name="tableOptions.fullscreen ? 'ion-ios-contract' : 'ion-ios-desktop'"
|
|
1660
|
-
right
|
|
1661
|
-
/>
|
|
1662
|
-
</q-item-section>
|
|
1663
|
-
<q-item-section>
|
|
1664
|
-
<q-item-label>
|
|
1665
|
-
{{ __('myth.datatable.' + (tableOptions.fullscreen ? 'exitFullscreen' : 'fullscreen')) }}
|
|
1666
|
-
</q-item-label>
|
|
1667
|
-
</q-item-section>
|
|
1668
|
-
</q-item>
|
|
1669
|
-
</q-list>
|
|
1670
|
-
</MModalMenu>
|
|
1593
|
+
<q-tooltip>{{ __('myth.titles.exportPdf') }}</q-tooltip>
|
|
1594
|
+
</MDtBtn>
|
|
1595
|
+
|
|
1596
|
+
<!-- Export Excel-->
|
|
1597
|
+
<MDtBtn
|
|
1598
|
+
v-if="excel && getRows.length > 0"
|
|
1599
|
+
icon="fa-solid fa-file-excel"
|
|
1600
|
+
text-color="green"
|
|
1601
|
+
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter}"
|
|
1602
|
+
@click="exportData('excel')"
|
|
1603
|
+
>
|
|
1604
|
+
<q-tooltip>{{ __('myth.titles.exportExcel') }}</q-tooltip>
|
|
1671
1605
|
</MDtBtn>
|
|
1606
|
+
|
|
1672
1607
|
<!-- Filter dialog -->
|
|
1673
1608
|
<MDtBtn
|
|
1674
1609
|
v-if="hasFilterDialog"
|
|
@@ -1744,6 +1679,7 @@ defineOptions({
|
|
|
1744
1679
|
</q-card>
|
|
1745
1680
|
</MModalMenu>
|
|
1746
1681
|
</MDtBtn>
|
|
1682
|
+
|
|
1747
1683
|
<!--Refresh-->
|
|
1748
1684
|
<MDtBtn
|
|
1749
1685
|
v-if="!noRefreshBtn"
|
|
@@ -1754,6 +1690,7 @@ defineOptions({
|
|
|
1754
1690
|
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.refresh}"
|
|
1755
1691
|
@click="refreshNoUpdate()"
|
|
1756
1692
|
/>
|
|
1693
|
+
|
|
1757
1694
|
<!--Fullscreen-->
|
|
1758
1695
|
<MDtBtn
|
|
1759
1696
|
v-if="fullscreenBtn === undefined ? ( !!pluginOptions.datatable?.fullscreenBtn) : fullscreenBtn"
|
|
@@ -1774,6 +1711,15 @@ defineOptions({
|
|
|
1774
1711
|
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn}"
|
|
1775
1712
|
@click="openUpdateDialogNoIndex(tableOptions.selected[0] as any)"
|
|
1776
1713
|
/>
|
|
1714
|
+
<MDtBtn
|
|
1715
|
+
v-if="hasCloneBtn && isSingleSelectedItem"
|
|
1716
|
+
key="clone-dt-selection-btn"
|
|
1717
|
+
:disable="tableOptions.loading"
|
|
1718
|
+
clone
|
|
1719
|
+
tooltip="labels.clone"
|
|
1720
|
+
v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn}"
|
|
1721
|
+
@click="onCloneItem(tableOptions.selected[0] as any)"
|
|
1722
|
+
/>
|
|
1777
1723
|
<MDtBtn
|
|
1778
1724
|
v-if="hasShowBtn && isSingleSelectedItem"
|
|
1779
1725
|
key="show-dt-selection-btn"
|
|
@@ -1926,7 +1872,7 @@ defineOptions({
|
|
|
1926
1872
|
<q-td :props="noBodyProps">
|
|
1927
1873
|
<!--Control-->
|
|
1928
1874
|
<q-btn-dropdown
|
|
1929
|
-
v-if="contextmenuItems.length>contextItemsLength"
|
|
1875
|
+
v-if="contextmenuItems.length > contextItemsLength"
|
|
1930
1876
|
v-close-popup
|
|
1931
1877
|
:menu-offset="[0,10]"
|
|
1932
1878
|
color="primary"
|
|
@@ -1934,24 +1880,16 @@ defineOptions({
|
|
|
1934
1880
|
outline
|
|
1935
1881
|
v-bind="pluginOptions.dt?.controlDropdown"
|
|
1936
1882
|
>
|
|
1937
|
-
<q-list
|
|
1883
|
+
<q-list
|
|
1884
|
+
:dense="getProp('dense')"
|
|
1885
|
+
separator
|
|
1886
|
+
>
|
|
1938
1887
|
<MDtContextmenuItems
|
|
1939
1888
|
:index="noBodyProps.rowIndex"
|
|
1940
1889
|
:item="noBodyProps.row"
|
|
1941
1890
|
:items="contextmenuItems"
|
|
1942
1891
|
display-mode="item"
|
|
1943
1892
|
/>
|
|
1944
|
-
<!--<q-item-->
|
|
1945
|
-
<!-- v-for="contextmenuItem in contextmenuItems"-->
|
|
1946
|
-
<!-- :key="`dt-r${contextmenuItem.name}`"-->
|
|
1947
|
-
<!-- v-close-popup-->
|
|
1948
|
-
<!-- clickable-->
|
|
1949
|
-
<!-->-->
|
|
1950
|
-
<!-- <pre>{{ contextmenuItem }}</pre>-->
|
|
1951
|
-
<!-- <q-item-section>-->
|
|
1952
|
-
<!-- <q-item-label>{{ contextmenuItem.label }}</q-item-label>-->
|
|
1953
|
-
<!-- </q-item-section>-->
|
|
1954
|
-
<!--</q-item>-->
|
|
1955
1893
|
</q-list>
|
|
1956
1894
|
</q-btn-dropdown>
|
|
1957
1895
|
<MRow
|
|
@@ -18,6 +18,7 @@ interface Props {
|
|
|
18
18
|
show?: boolean | undefined;
|
|
19
19
|
update?: boolean | undefined;
|
|
20
20
|
destroy?: boolean | undefined;
|
|
21
|
+
clone?: boolean | undefined;
|
|
21
22
|
tooltip?: string | null | undefined;
|
|
22
23
|
color?: string | undefined;
|
|
23
24
|
icon?: string | undefined;
|
|
@@ -32,6 +33,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
32
33
|
show: undefined,
|
|
33
34
|
update: undefined,
|
|
34
35
|
destroy: undefined,
|
|
36
|
+
clone: undefined,
|
|
35
37
|
color: undefined,
|
|
36
38
|
icon: undefined,
|
|
37
39
|
tooltip: undefined,
|
|
@@ -46,7 +48,7 @@ type Events = {
|
|
|
46
48
|
}
|
|
47
49
|
const emit = defineEmits<Events>()
|
|
48
50
|
|
|
49
|
-
const hasTooltip = computed(() => !!props.tooltip || !!props.show || !!props.update || !!props.destroy)
|
|
51
|
+
const hasTooltip = computed(() => !!props.tooltip || !!props.show || !!props.update || !!props.destroy || !!props.clone)
|
|
50
52
|
const { __, props: pluginOptions } = useMyth()
|
|
51
53
|
const getTooltip = computed(() => {
|
|
52
54
|
if (props.tooltip !== undefined) {
|
|
@@ -57,6 +59,8 @@ const getTooltip = computed(() => {
|
|
|
57
59
|
return __('labels.update')
|
|
58
60
|
} else if (props.destroy) {
|
|
59
61
|
return __('labels.destroy')
|
|
62
|
+
} else if (props.clone) {
|
|
63
|
+
return __('labels.clone')
|
|
60
64
|
}
|
|
61
65
|
return props.tooltip
|
|
62
66
|
})
|
|
@@ -67,6 +71,8 @@ const getIcon = computed(() => {
|
|
|
67
71
|
return 'ion-ios-create'
|
|
68
72
|
} else if (props.destroy) {
|
|
69
73
|
return 'ion-ios-trash'
|
|
74
|
+
} else if (props.clone) {
|
|
75
|
+
return 'ion-copy'
|
|
70
76
|
}
|
|
71
77
|
return props.icon
|
|
72
78
|
})
|
|
@@ -83,18 +89,20 @@ const getColor = computed<string | undefined>(() => {
|
|
|
83
89
|
}
|
|
84
90
|
return props.color
|
|
85
91
|
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
const getLabel = computed(() => {
|
|
93
|
+
if (props.label !== undefined) {
|
|
94
|
+
return __(props.label)
|
|
95
|
+
} else if (props.show) {
|
|
96
|
+
return __('labels.show')
|
|
97
|
+
} else if (props.update) {
|
|
98
|
+
return __('labels.update')
|
|
99
|
+
} else if (props.destroy) {
|
|
100
|
+
return __('labels.destroy')
|
|
101
|
+
} else if (props.clone) {
|
|
102
|
+
return __('labels.clone')
|
|
103
|
+
}
|
|
104
|
+
return props.label
|
|
105
|
+
})
|
|
98
106
|
|
|
99
107
|
defineOptions({
|
|
100
108
|
name: 'MDtBtn',
|
|
@@ -111,6 +119,7 @@ defineOptions({
|
|
|
111
119
|
@click="emit('click',$event)"
|
|
112
120
|
>
|
|
113
121
|
<q-item-section
|
|
122
|
+
v-if="!!getIcon"
|
|
114
123
|
side
|
|
115
124
|
v-bind="pluginOptions.dt?.MDtBtn?.item?.avatarProps"
|
|
116
125
|
>
|
|
@@ -123,7 +132,7 @@ defineOptions({
|
|
|
123
132
|
<q-item-section v-bind="pluginOptions.dt?.MDtBtn?.item?.labelSectionProps">
|
|
124
133
|
<q-item-label v-bind="pluginOptions.dt?.MDtBtn?.item?.itemLabelProps">
|
|
125
134
|
<slot>
|
|
126
|
-
{{
|
|
135
|
+
{{ __(getLabel) }}
|
|
127
136
|
</slot>
|
|
128
137
|
</q-item-label>
|
|
129
138
|
</q-item-section>
|
|
@@ -15,6 +15,7 @@ import type { MDatatableDialogsOptions, MDatatableProps } from '../../types'
|
|
|
15
15
|
import type { UnwrapRef } from 'vue'
|
|
16
16
|
import { computed } from 'vue'
|
|
17
17
|
import { useMyth } from '../../composable'
|
|
18
|
+
import { useI18n } from 'vue-i18n'
|
|
18
19
|
|
|
19
20
|
interface Props {
|
|
20
21
|
items: MDatatableProps['contextItems'],
|
|
@@ -31,6 +32,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
31
32
|
})
|
|
32
33
|
const itemMode = computed(() => props.displayMode === 'item')
|
|
33
34
|
const { __ } = useMyth()
|
|
35
|
+
const { te } = useI18n({ useScope: 'global' })
|
|
34
36
|
defineOptions({
|
|
35
37
|
name: 'MDtContextmenuItems',
|
|
36
38
|
inheritAttrs: !1
|
|
@@ -46,9 +48,7 @@ defineOptions({
|
|
|
46
48
|
<MDtBtn
|
|
47
49
|
v-if="typeof m.showIf === 'function' ? m.showIf(item,index) : m.showIf"
|
|
48
50
|
:[m.name]="!0"
|
|
49
|
-
:label="itemMode
|
|
50
|
-
__(m.label || m.name) :
|
|
51
|
-
undefined)"
|
|
51
|
+
:label="itemMode&&m.label===undefined?(te(`labels.${m.name}`)?__(`labels.${m.name}`):__(m.tooltip || m.attr?.label || m.attr?.tooltip || m.name)):(m.label!==undefined?__(m.label || m.name):undefined)"
|
|
52
52
|
:list-item="itemMode"
|
|
53
53
|
:tooltip="m.tooltip !== undefined ? m.tooltip : (m.label === undefined ? `labels.${m.name}` : undefined)"
|
|
54
54
|
dense
|
|
@@ -290,9 +290,9 @@ defineOptions({
|
|
|
290
290
|
<MBtn
|
|
291
291
|
v-else
|
|
292
292
|
:disable="!isLoaded && !!url"
|
|
293
|
+
:label="'labels.' + ( clearable ? ( hasSrc ? 'remove' : btnLabel ) : ( required ? ( hasSrc ? 'change' : btnLabel ) : btnLabel ) )"
|
|
293
294
|
:loading="loadingSrc"
|
|
294
295
|
icon="ion-ios-images"
|
|
295
|
-
:label="'labels.' + ( clearable ? ( hasSrc ? 'remove' : btnLabel ) : ( required ? ( hasSrc ? 'change' : btnLabel ) : btnLabel ) )"
|
|
296
296
|
outline
|
|
297
297
|
@click="onClick"
|
|
298
298
|
/>
|
|
@@ -210,8 +210,8 @@ defineOptions({
|
|
|
210
210
|
<template #append>
|
|
211
211
|
<q-btn
|
|
212
212
|
v-if="!disable && !readonly && !viewMode"
|
|
213
|
-
:icon="isDate ? 'ion-ios-calendar' : 'ion-ios-clock'"
|
|
214
213
|
:color="!!errorMessage ? 'negative' : undefined"
|
|
214
|
+
:icon="isDate ? 'ion-ios-calendar' : 'ion-ios-clock'"
|
|
215
215
|
flat
|
|
216
216
|
round
|
|
217
217
|
v-bind="{...pluginOptions?.pickerBtn, ...btnProps}"
|
package/src/style/main.sass
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { NamedColor, QAvatarProps, QAvatarSlots, QImgProps } from 'quasar'
|
|
2
2
|
import type { VNode } from 'vue'
|
|
3
|
-
import type {
|
|
3
|
+
import type { InputRulesContext, MColProps } from '../components'
|
|
4
4
|
|
|
5
5
|
export type MAvatarViewerModelValue = File | null | undefined;
|
|
6
6
|
|
|
@@ -38,6 +38,8 @@ export type HelpersStubSchema = {
|
|
|
38
38
|
|
|
39
39
|
update (id: UrlType, data?: ParamsType, config?: AxiosRequestConfig): Promise<ApiInterface>;
|
|
40
40
|
|
|
41
|
+
clone (id: UrlType, data?: ParamsType, config?: AxiosRequestConfig): Promise<ApiInterface>;
|
|
42
|
+
|
|
41
43
|
destroy (id: UrlType, config?: AxiosRequestConfig): Promise<ApiInterface>;
|
|
42
44
|
|
|
43
45
|
destroyAll (ids?: UrlType[], config?: AxiosRequestConfig): Promise<ApiInterface>;
|
|
@@ -37,16 +37,7 @@ import type { TypedOptions } from 'typed.js'
|
|
|
37
37
|
import type { FieldContext, FieldOptions, FormContext, FormOptions, FormState } from 'vee-validate'
|
|
38
38
|
import type { ThemeShadow, ThemeSize } from './theme'
|
|
39
39
|
import type { ApiInterface, HelpersStubSchema } from './api-helpers'
|
|
40
|
-
import type {
|
|
41
|
-
MDatatableProps,
|
|
42
|
-
MDatatableSlots,
|
|
43
|
-
MDtAvatarProps,
|
|
44
|
-
MDtAvatarSlots,
|
|
45
|
-
MDtBtnProps,
|
|
46
|
-
MDtBtnSlots,
|
|
47
|
-
MDtContextmenuItemsProps,
|
|
48
|
-
MDtContextmenuItemsSlots
|
|
49
|
-
} from './m-datatable'
|
|
40
|
+
import type { MDatatableProps, MDatatableSlots, MDtAvatarProps, MDtAvatarSlots, MDtBtnProps, MDtBtnSlots, MDtContextmenuItemsProps, MDtContextmenuItemsSlots } from './m-datatable'
|
|
50
41
|
import type { EditorConfig } from 'ckeditor5'
|
|
51
42
|
import type { MAvatarViewerProps, MAvatarViewerSlots } from './api/MAvatarViewer'
|
|
52
43
|
import type { MTransitionProps, MTransitionsSlots } from './api/MTransition'
|
|
@@ -114,6 +114,7 @@ export type MDatatableDialogsOptions<T extends MDDIP = MDDIP> = {
|
|
|
114
114
|
export interface MDtBtnProps extends MBtnProps {
|
|
115
115
|
show?: boolean;
|
|
116
116
|
update?: boolean;
|
|
117
|
+
clone?: boolean;
|
|
117
118
|
destroy?: boolean;
|
|
118
119
|
tooltip?: string | undefined;
|
|
119
120
|
color?: string;
|
|
@@ -226,6 +227,7 @@ export type MDatatableProps<I extends GenericFormValues = GenericFormValues> = O
|
|
|
226
227
|
withUpdate?: string | string[];
|
|
227
228
|
hideAddBtn?: boolean;
|
|
228
229
|
hideUpdateBtn?: boolean;
|
|
230
|
+
cloneBtn?: boolean;
|
|
229
231
|
hideShowBtn?: boolean;
|
|
230
232
|
hideDestroyBtn?: boolean;
|
|
231
233
|
storeRoute?: string | RouteLocationRaw;
|
|
@@ -231,11 +231,11 @@ export interface MythComponentsProps {
|
|
|
231
231
|
buttons?: {
|
|
232
232
|
filter?: Partial<MDtBtnProps>;
|
|
233
233
|
refresh?: Partial<MDtBtnProps>;
|
|
234
|
-
more?: Partial<MDtBtnProps>;
|
|
234
|
+
// more?: Partial<MDtBtnProps>;
|
|
235
235
|
fullscreen?: Partial<MDtBtnProps>;
|
|
236
|
-
moreMenu?: Partial<QMenuProps>;
|
|
237
|
-
moreList?: Partial<QListProps>;
|
|
238
|
-
moreItem?: Partial<QItemProps>;
|
|
236
|
+
// moreMenu?: Partial<QMenuProps>;
|
|
237
|
+
// moreList?: Partial<QListProps>;
|
|
238
|
+
// moreItem?: Partial<QItemProps>;
|
|
239
239
|
},
|
|
240
240
|
topSelection?: {
|
|
241
241
|
btn?: Partial<MDtBtnProps>;
|
package/src/utils/Helpers.ts
CHANGED
|
@@ -87,6 +87,12 @@ export const Helpers = {
|
|
|
87
87
|
data && Helpers.appendArray(formData, data)
|
|
88
88
|
return axios().post(u, formData, config)
|
|
89
89
|
},
|
|
90
|
+
async clone (id: UrlType, data?: ParamsType, config?: AxiosRequestConfig) {
|
|
91
|
+
const u = makeUrl(`${id}/Clone`)
|
|
92
|
+
const formData = new FormData()
|
|
93
|
+
data && Helpers.appendArray(formData, data)
|
|
94
|
+
return axios().post(u, formData, config)
|
|
95
|
+
},
|
|
90
96
|
async destroy (id: UrlType, config?: AxiosRequestConfig) {
|
|
91
97
|
const u = makeUrl(id)
|
|
92
98
|
return axios().delete(u, config)
|