@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mythpe/quasar-ui-qui",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "MyTh Quasar UI Kit App Extension",
5
5
  "author": {
6
6
  "name": "MyTh Ahmed Faiz",
@@ -48,54 +48,55 @@ const initMetaServer: MDatatableMetaServer = {
48
48
  total: null
49
49
  }
50
50
 
51
- interface Props {
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?: MDatatableProps['hideAutoMessage'];
56
+ hideAutoMessage?: boolean;
57
57
  headers: MDatatableProps['headers'];
58
58
  serviceName?: MDatatableProps['serviceName'];
59
59
  requestParams?: MDatatableProps['requestParams'];
60
- pdf?: MDatatableProps['pdf'];
61
- excel?: MDatatableProps['excel'];
60
+ pdf?: boolean;
61
+ excel?: boolean;
62
62
  exportUrl?: MDatatableProps['exportUrl'];
63
- hideSearch?: MDatatableProps['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?: MDatatableProps['hideAddBtn'];
70
- hideUpdateBtn?: MDatatableProps['hideUpdateBtn'];
71
- hideShowBtn?: MDatatableProps['hideShowBtn'];
72
- hideDestroyBtn?: MDatatableProps['hideDestroyBtn'];
69
+ hideAddBtn?: boolean;
70
+ hideUpdateBtn?: boolean;
71
+ cloneBtn?: boolean;
72
+ hideShowBtn?: boolean;
73
+ hideDestroyBtn?: boolean;
73
74
  storeRoute?: MDatatableProps['storeRoute'];
74
- storeQueryParams?: MDatatableProps['storeQueryParams'];
75
+ storeQueryParams?: boolean;
75
76
  updateRoute?: MDatatableProps['updateRoute'];
76
- updateQueryParams?: MDatatableProps['updateQueryParams'];
77
+ updateQueryParams?: boolean;
77
78
  showRoute?: MDatatableProps['showRoute'];
78
- showQueryParams?: MDatatableProps['showQueryParams'];
79
- mouse?: MDatatableProps['mouse'];
80
- noRefreshBtn?: MDatatableProps['noRefreshBtn'];
81
- endReach?: MDatatableProps['endReach'];
82
- showSelection?: MDatatableProps['showSelection'];
83
- hideSelection?: MDatatableProps['hideSelection'];
84
- multiSelection?: MDatatableProps['multiSelection'];
85
- multiDestroy?: MDatatableProps['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?: MDatatableProps['manageColumns'];
91
+ manageColumns?: boolean;
91
92
  visibleColumns?: MDatatableProps['visibleColumns'];
92
93
  searchColumns?: MDatatableProps['searchColumns'];
93
- addTopBtn?: MDatatableProps['addTopBtn'];
94
- addListBtn?: MDatatableProps['addListBtn'];
95
- addFabBtn?: MDatatableProps['addFabBtn'];
96
- fullscreenBtn?: MDatatableProps['fullscreenBtn'];
97
- noBodyControl?: MDatatableProps['noBodyControl'];
98
- showCardControlHeader?: MDatatableProps['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: undefined,
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: undefined,
129
- hideUpdateBtn: undefined,
130
- hideShowBtn: undefined,
131
- hideDestroyBtn: undefined,
129
+ hideAddBtn: !1,
130
+ hideUpdateBtn: !1,
131
+ cloneBtn: !1,
132
+ hideShowBtn: !1,
133
+ hideDestroyBtn: !1,
132
134
  storeRoute: undefined,
133
- storeQueryParams: undefined,
135
+ storeQueryParams: !1,
134
136
  updateRoute: undefined,
135
- updateQueryParams: undefined,
137
+ updateQueryParams: !1,
136
138
  showRoute: undefined,
137
- showQueryParams: undefined,
138
- mouse: undefined,
139
- noRefreshBtn: undefined,
140
- endReach: undefined,
141
- showSelection: undefined,
142
- hideSelection: undefined,
143
- multiSelection: undefined,
144
- multiDestroy: undefined,
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 visibleColumnsProp = computed(() => props.visibleColumns)
286
- const visibleHeaders = ref(parseHeaders(visibleColumnsProp.value || headersProp.value).map(e => e.name))
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 || !!props.updateQueryParams
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 || !!props.showQueryParams
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 = !!props.pdf && getRows.value.length > 0
366
- const excel = !!props.excel && getRows.value.length > 0
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: 200
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: 300
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="row q-gutter-x-sm q-gutter-xs-y-sm items-center">
1555
- <!--More Menu-->
1584
+ <MRow class="q-gutter-x-sm q-gutter-xs-y-sm items-center">
1585
+ <!-- Export PDF-->
1556
1586
  <MDtBtn
1557
- v-if="hasMenu"
1558
- key="more-selection-btn"
1559
- :disable="tableOptions.loading"
1560
- icon="ion-ios-options"
1561
- label="myth.datatable.hints.options"
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
- <MModalMenu
1566
- :offset="[10,10]"
1567
- position="bottom"
1568
- v-bind="pluginOptions.dt?.buttons?.moreMenu as any"
1569
- >
1570
- <q-list
1571
- style="min-width: 250px"
1572
- v-bind="pluginOptions.dt?.buttons?.moreList"
1573
- >
1574
- <!-- Add Btn -->
1575
- <q-item
1576
- v-if="hasAddBtn && !!addListBtnComputed"
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
- <!--&gt;-->
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
- // const getLabel = computed(() => {
87
- // if (props.label) {
88
- // return __(props.label)
89
- // } else if (props.show) {
90
- // return __('labels.show')
91
- // } else if (props.update) {
92
- // return __('labels.update')
93
- // } else if (props.destroy) {
94
- // return __('labels.destroy')
95
- // }
96
- // return props.label
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
- {{ label ? __(label) : label }}
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 && m.label === undefined ? __(m.tooltip || m.attr?.label || m.attr?.tooltip || m.name) : (m.label !== undefined ?
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}"
@@ -19,7 +19,6 @@ $m--input-helpers-margin: 5px !default
19
19
  width: 0 !important
20
20
 
21
21
 
22
-
23
22
  .m--row + .m--row
24
23
  margin-top: $m--row-margin-top
25
24
 
@@ -1,6 +1,6 @@
1
1
  import type { NamedColor, QAvatarProps, QAvatarSlots, QImgProps } from 'quasar'
2
2
  import type { VNode } from 'vue'
3
- import type { InputErrorsContext, InputFormErrorsContext, InputRulesContext, MColProps } from '../components'
3
+ import type { InputRulesContext, MColProps } from '../components'
4
4
 
5
5
  export type MAvatarViewerModelValue = File | null | undefined;
6
6
 
@@ -36,5 +36,5 @@ export interface MAxiosProps extends Omit<MSelectProps, 'options' | 'axiosMode'>
36
36
  }
37
37
 
38
38
  export interface MAxiosSlots extends MSelectSlots {
39
- [ k : keyof MSelectSlots ]
39
+ [k: keyof MSelectSlots]
40
40
  }
@@ -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>;
@@ -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)