@mythpe/quasar-ui-qui 0.1.65 → 0.1.67
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 +101 -22
- package/src/components/form/MAxios.vue +15 -3
- package/src/components/form/MOptions.vue +26 -5
- package/src/composable/useDtHelpers.ts +2 -2
- package/src/types/components.d.ts +5 -1
- package/src/types/m-datatable.d.ts +9 -1
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import type { MDatatableProps } from '../../types'
|
|
14
14
|
import type { InvalidSubmissionHandler, SubmissionHandler } from 'vee-validate'
|
|
15
15
|
import { useForm } from 'vee-validate'
|
|
16
|
-
import { onMounted, ref, toValue, watch } from 'vue'
|
|
16
|
+
import { computed, onMounted, ref, toValue, watch } from 'vue'
|
|
17
17
|
import { is as quasarHelpers, QCardSection, QTable, useQuasar } from 'quasar'
|
|
18
18
|
import lodash from 'lodash'
|
|
19
19
|
import { useDtHelpers, useMyth } from '../../composable'
|
|
@@ -78,6 +78,8 @@ type Props = {
|
|
|
78
78
|
imageSize?: MDatatableProps['imageSize'];
|
|
79
79
|
noBackBtn?: boolean;
|
|
80
80
|
backIcon?: MDatatableProps['backIcon'];
|
|
81
|
+
urlColumns?: MDatatableProps['urlColumns'];
|
|
82
|
+
colorColumns?: MDatatableProps['colorColumns'];
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -138,7 +140,9 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
138
140
|
imageMode: () => 'image',
|
|
139
141
|
imageSize: () => '35px',
|
|
140
142
|
noBackBtn: !1,
|
|
141
|
-
backIcon: undefined
|
|
143
|
+
backIcon: undefined,
|
|
144
|
+
urlColumns: () => ([]),
|
|
145
|
+
colorColumns: () => ([])
|
|
142
146
|
})
|
|
143
147
|
|
|
144
148
|
interface Emits {
|
|
@@ -155,7 +159,9 @@ const {
|
|
|
155
159
|
scrollToElementFromErrors,
|
|
156
160
|
props: pluginOptions,
|
|
157
161
|
theme,
|
|
158
|
-
isSmall
|
|
162
|
+
isSmall,
|
|
163
|
+
openWindow,
|
|
164
|
+
copyText
|
|
159
165
|
} = useMyth()
|
|
160
166
|
|
|
161
167
|
const $q = useQuasar()
|
|
@@ -363,7 +369,8 @@ const onInvalidSubmit: InvalidSubmissionHandler = ({ errors }) => {
|
|
|
363
369
|
}
|
|
364
370
|
}
|
|
365
371
|
const defaultSubmitItem = handleSubmit.withControlled(onSuccess, onInvalidSubmit)
|
|
366
|
-
|
|
372
|
+
const urlColumnsProp = computed<string[]>(() => toValue(props.urlColumns) || [])
|
|
373
|
+
const colorColumnsProp = computed<string[]>(() => toValue(props.colorColumns) || [])
|
|
367
374
|
onMounted(() => refresh())
|
|
368
375
|
watch(loading, v => {
|
|
369
376
|
if (pluginOptions.value?.dt?.useQuasarLoading) {
|
|
@@ -499,21 +506,6 @@ defineExpose({
|
|
|
499
506
|
@update:selected="onUpdateSelectedItems"
|
|
500
507
|
@virtual-scroll="endReach ? onScroll : undefined"
|
|
501
508
|
>
|
|
502
|
-
<template
|
|
503
|
-
v-for="slotName in getSlots"
|
|
504
|
-
:key="slotName"
|
|
505
|
-
#[slotName]="inputSlot"
|
|
506
|
-
>
|
|
507
|
-
<slot
|
|
508
|
-
:dt="datatableItemsScope"
|
|
509
|
-
:form="useFormContext"
|
|
510
|
-
:index="dialogItemIndex"
|
|
511
|
-
:item="dialogItem"
|
|
512
|
-
:name="slotName"
|
|
513
|
-
v-bind="inputSlot || {}"
|
|
514
|
-
/>
|
|
515
|
-
</template>
|
|
516
|
-
|
|
517
509
|
<template #item="iTempProps">
|
|
518
510
|
<slot
|
|
519
511
|
:dt="datatableItemsScope"
|
|
@@ -599,6 +591,37 @@ defineExpose({
|
|
|
599
591
|
</q-img>
|
|
600
592
|
</template>
|
|
601
593
|
</template>
|
|
594
|
+
<template v-else-if="urlColumnsProp.indexOf(col.name) !== -1">
|
|
595
|
+
<MBtn
|
|
596
|
+
v-if="!!col.value"
|
|
597
|
+
dense
|
|
598
|
+
fab-mini
|
|
599
|
+
flat
|
|
600
|
+
icon="ion-ios-open"
|
|
601
|
+
@click="openWindow(col.value)"
|
|
602
|
+
>
|
|
603
|
+
<q-tooltip>
|
|
604
|
+
{{ col.value }}
|
|
605
|
+
</q-tooltip>
|
|
606
|
+
</MBtn>
|
|
607
|
+
</template>
|
|
608
|
+
<template v-else-if="colorColumnsProp.indexOf(col.name) !== -1">
|
|
609
|
+
<div
|
|
610
|
+
v-if="!!col.value"
|
|
611
|
+
class="row q-gutter-lg justify-center items-center"
|
|
612
|
+
>
|
|
613
|
+
<div>
|
|
614
|
+
{{ col.value }}
|
|
615
|
+
</div>
|
|
616
|
+
<div
|
|
617
|
+
:style="`width: 20px; height: 20px; background-color: ${col.value};`"
|
|
618
|
+
class="m--input__color-preview cursor-pointer"
|
|
619
|
+
@click="copyText(col.value)"
|
|
620
|
+
>
|
|
621
|
+
<q-tooltip>{{ __('labels.copy') }}</q-tooltip>
|
|
622
|
+
</div>
|
|
623
|
+
</div>
|
|
624
|
+
</template>
|
|
602
625
|
<template v-else-if="col.name === controlKey">
|
|
603
626
|
<MRow
|
|
604
627
|
class="m--dt-context_menu_items"
|
|
@@ -631,7 +654,6 @@ defineExpose({
|
|
|
631
654
|
</div>
|
|
632
655
|
</slot>
|
|
633
656
|
</template>
|
|
634
|
-
|
|
635
657
|
<template #top="topSlotProps">
|
|
636
658
|
<MCol col="12">
|
|
637
659
|
<MContainer
|
|
@@ -1073,7 +1095,6 @@ defineExpose({
|
|
|
1073
1095
|
</MContainer>
|
|
1074
1096
|
</MCol>
|
|
1075
1097
|
</template>
|
|
1076
|
-
|
|
1077
1098
|
<template
|
|
1078
1099
|
v-if="endReach"
|
|
1079
1100
|
#bottom
|
|
@@ -1081,7 +1102,6 @@ defineExpose({
|
|
|
1081
1102
|
<q-space />
|
|
1082
1103
|
<div v-text="__('replace.from_to', { from: pagination.rowsNumber, to: getRows.length })" />
|
|
1083
1104
|
</template>
|
|
1084
|
-
|
|
1085
1105
|
<template
|
|
1086
1106
|
v-if="!noBodyControl"
|
|
1087
1107
|
#[`body-cell-${controlKey}`]="noBodyProps"
|
|
@@ -1171,6 +1191,65 @@ defineExpose({
|
|
|
1171
1191
|
</template>
|
|
1172
1192
|
</q-td>
|
|
1173
1193
|
</template>
|
|
1194
|
+
<template
|
|
1195
|
+
v-for="u in urlColumnsProp"
|
|
1196
|
+
:key="`a-u-${u}`"
|
|
1197
|
+
#[`body-cell-${u}`]="urlProps"
|
|
1198
|
+
>
|
|
1199
|
+
<q-td :props="urlProps">
|
|
1200
|
+
<template v-if="!!urlProps.row[u]">
|
|
1201
|
+
<MBtn
|
|
1202
|
+
dense
|
|
1203
|
+
fab-mini
|
|
1204
|
+
flat
|
|
1205
|
+
icon="ion-ios-open"
|
|
1206
|
+
@click="openWindow(urlProps.row[u])"
|
|
1207
|
+
>
|
|
1208
|
+
<q-tooltip>
|
|
1209
|
+
{{ urlProps.row[u] }}
|
|
1210
|
+
</q-tooltip>
|
|
1211
|
+
</MBtn>
|
|
1212
|
+
</template>
|
|
1213
|
+
</q-td>
|
|
1214
|
+
</template>
|
|
1215
|
+
<template
|
|
1216
|
+
v-for="cc in colorColumnsProp"
|
|
1217
|
+
:key="`a-cc-${cc}`"
|
|
1218
|
+
#[`body-cell-${cc}`]="ccProps"
|
|
1219
|
+
>
|
|
1220
|
+
<q-td :props="ccProps">
|
|
1221
|
+
<div
|
|
1222
|
+
v-if="!!ccProps.row[cc]"
|
|
1223
|
+
class="row q-gutter-lg justify-center items-center"
|
|
1224
|
+
>
|
|
1225
|
+
<div>
|
|
1226
|
+
{{ ccProps.row[cc] }}
|
|
1227
|
+
</div>
|
|
1228
|
+
<div
|
|
1229
|
+
:style="`width: 20px; height: 20px; background-color: ${ccProps.row[cc]};`"
|
|
1230
|
+
class="m--input__color-preview cursor-pointer"
|
|
1231
|
+
@click="copyText(ccProps.row[cc])"
|
|
1232
|
+
>
|
|
1233
|
+
<q-tooltip>{{ __('labels.copy') }}</q-tooltip>
|
|
1234
|
+
</div>
|
|
1235
|
+
</div>
|
|
1236
|
+
</q-td>
|
|
1237
|
+
</template>
|
|
1238
|
+
|
|
1239
|
+
<template
|
|
1240
|
+
v-for="slotName in getSlots"
|
|
1241
|
+
:key="slotName"
|
|
1242
|
+
#[slotName]="inputSlot"
|
|
1243
|
+
>
|
|
1244
|
+
<slot
|
|
1245
|
+
:dt="datatableItemsScope"
|
|
1246
|
+
:form="useFormContext"
|
|
1247
|
+
:index="dialogItemIndex"
|
|
1248
|
+
:item="dialogItem"
|
|
1249
|
+
:name="slotName"
|
|
1250
|
+
v-bind="inputSlot || {}"
|
|
1251
|
+
/>
|
|
1252
|
+
</template>
|
|
1174
1253
|
</q-table>
|
|
1175
1254
|
<slot
|
|
1176
1255
|
:dt="datatableItemsScope"
|
|
@@ -62,9 +62,21 @@ const prepare = async (fromWatch = !1) => {
|
|
|
62
62
|
if (!props.service || loading.value) {
|
|
63
63
|
return
|
|
64
64
|
}
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
const s = props.service
|
|
66
|
+
let method: any = null
|
|
67
|
+
if (typeof s === 'string' && s.includes('.')) {
|
|
68
|
+
const args = s.split('.')
|
|
69
|
+
do {
|
|
70
|
+
if (!method) {
|
|
71
|
+
method = api.value.services[args.shift() as any]
|
|
72
|
+
}
|
|
73
|
+
method = method[args.shift() as any]
|
|
74
|
+
}
|
|
75
|
+
while (args.length)
|
|
76
|
+
} else {
|
|
77
|
+
method = typeof s === 'function' ? s : (isGuest.value ? api.value.services[s].staticIndex : api.value.services[s].index)
|
|
78
|
+
}
|
|
79
|
+
|
|
68
80
|
if (!method) {
|
|
69
81
|
throw Error(`No service: ${props.service}`)
|
|
70
82
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { useField } from 'vee-validate'
|
|
15
15
|
import type { MOptionsOptionContext, MOptionsProps as Props } from '../../types'
|
|
16
|
-
import { reactive, toValue, useTemplateRef } from 'vue'
|
|
16
|
+
import { onMounted, reactive, toValue, useTemplateRef } from 'vue'
|
|
17
17
|
import { QField, QOptionGroup, type QOptionGroupSlots } from 'quasar'
|
|
18
18
|
import { useBindInput, useMyth } from '../../composable'
|
|
19
19
|
|
|
@@ -40,6 +40,7 @@ interface P {
|
|
|
40
40
|
type?: Props['type'];
|
|
41
41
|
keepColor?: Props['keepColor'];
|
|
42
42
|
service?: Props['service'];
|
|
43
|
+
guest?: boolean;
|
|
43
44
|
fullWidth?: Props['fullWidth'];
|
|
44
45
|
fitWidth?: Props['fullWidth'];
|
|
45
46
|
fieldOptions?: Props['fieldOptions'];
|
|
@@ -67,6 +68,7 @@ const props = withDefaults(defineProps<P>(), {
|
|
|
67
68
|
color: () => 'primary',
|
|
68
69
|
type: 'radio',
|
|
69
70
|
keepColor: undefined,
|
|
71
|
+
guest: !1,
|
|
70
72
|
service: undefined,
|
|
71
73
|
fullWidth: () => !1,
|
|
72
74
|
fitWidth: () => !1,
|
|
@@ -91,13 +93,29 @@ const listeners = {
|
|
|
91
93
|
const input = useTemplateRef<InstanceType<typeof QField> | InstanceType<typeof QOptionGroup>>('input')
|
|
92
94
|
const scopes = reactive(inputScope)
|
|
93
95
|
defineExpose<typeof scopes & { input: typeof input }>({ input, ...scopes })
|
|
94
|
-
const { alertError, __, props: pluginProps } = useMyth()
|
|
96
|
+
const { alertError, __, props: pluginProps, api } = useMyth()
|
|
95
97
|
const fetchData = async () => {
|
|
96
98
|
if (props.service) {
|
|
99
|
+
const s = props.service
|
|
97
100
|
loading.value = !0
|
|
98
101
|
try {
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
let method: any = null
|
|
103
|
+
if (typeof s === 'string' && s.includes('.')) {
|
|
104
|
+
const args = s.split('.')
|
|
105
|
+
do {
|
|
106
|
+
if (!method) {
|
|
107
|
+
method = api.value.services[args.shift() as any]
|
|
108
|
+
}
|
|
109
|
+
method = method[args.shift() as any]
|
|
110
|
+
}
|
|
111
|
+
while (args.length)
|
|
112
|
+
} else {
|
|
113
|
+
method = typeof s === 'function' ? s : (props.guest ? api.value.services[s].staticIndex : api.value.services[s].index)
|
|
114
|
+
}
|
|
115
|
+
if (method != null) {
|
|
116
|
+
const { _data } = await method()
|
|
117
|
+
options.value = _data as any
|
|
118
|
+
}
|
|
101
119
|
} catch (e: any) {
|
|
102
120
|
alertError(e?._message || e?.message || 'Failed to fetch data')
|
|
103
121
|
} finally {
|
|
@@ -105,7 +123,10 @@ const fetchData = async () => {
|
|
|
105
123
|
}
|
|
106
124
|
}
|
|
107
125
|
}
|
|
108
|
-
|
|
126
|
+
|
|
127
|
+
onMounted(() => {
|
|
128
|
+
fetchData()
|
|
129
|
+
})
|
|
109
130
|
defineOptions({
|
|
110
131
|
name: 'MOptions',
|
|
111
132
|
inheritAttrs: !1
|
|
@@ -424,8 +424,8 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>) => {
|
|
|
424
424
|
const resetDialogForm = useResetForm()
|
|
425
425
|
const resetVeeForm = async (attrs?: Record<string, any>) => {
|
|
426
426
|
const init: any = {}
|
|
427
|
-
for (const k in
|
|
428
|
-
init[k] = attrs && k in attrs ? attrs[k] :
|
|
427
|
+
for (const k in defaultItem.value) {
|
|
428
|
+
init[k] = attrs && k in attrs ? attrs[k] : defaultItem.value[k]
|
|
429
429
|
}
|
|
430
430
|
resetDialogForm({ values: init || {} }, { force: !0 })
|
|
431
431
|
attrs && setValues(attrs, !1)
|
|
@@ -546,10 +546,14 @@ export type MOptionsProps = Omit<QOptionGroupProps, 'name' | 'modelValue' | 'opt
|
|
|
546
546
|
* Array of objects with value, label, and disable (optional) props. The binary components will be created according to this array; Props from QToggle & QCheckbox or QRadio can also be added as key/value pairs to control the components singularly
|
|
547
547
|
*/
|
|
548
548
|
options?: MOptionsOptionContext[];
|
|
549
|
+
/**
|
|
550
|
+
* Uset auto static index myth api helpers.
|
|
551
|
+
*/
|
|
552
|
+
guest?: boolean | undefined;
|
|
549
553
|
/**
|
|
550
554
|
* Get options by function. any send the current value to this function to get options.
|
|
551
555
|
*/
|
|
552
|
-
service?: ((value?: any) => Promise<ApiInterface>) |
|
|
556
|
+
service?: ((value?: any) => Promise<ApiInterface>) | string;
|
|
553
557
|
/**
|
|
554
558
|
* Service loading.
|
|
555
559
|
*/
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { AxiosResponse } from 'axios'
|
|
10
10
|
import type { NamedColor, QAvatarProps, QAvatarSlots, QTableProps, QTableSlots } from 'quasar'
|
|
11
|
-
import type { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs, UnwrapRef, VNode } from 'vue'
|
|
11
|
+
import type { ComputedRef, MaybeRef, MaybeRefOrGetter, Ref, UnwrapNestedRefs, UnwrapRef, VNode } from 'vue'
|
|
12
12
|
import type { RouteLocationRaw } from 'vue-router'
|
|
13
13
|
import type { GenericFormValues, MBtnProps, MBtnSlots, MFormSlots } from './components'
|
|
14
14
|
import type { StubSchema } from './api-helpers'
|
|
@@ -297,6 +297,14 @@ export type MDatatableProps<I extends GenericFormValues = GenericFormValues> = O
|
|
|
297
297
|
* default back icon.
|
|
298
298
|
*/
|
|
299
299
|
backIcon?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Names of url/link columns in the table.
|
|
302
|
+
*/
|
|
303
|
+
urlColumns?: MaybeRefOrGetter<string[]>;
|
|
304
|
+
/**
|
|
305
|
+
* Names of color pattern columns in the table.
|
|
306
|
+
*/
|
|
307
|
+
colorColumns?: MaybeRefOrGetter<string[]>;
|
|
300
308
|
}
|
|
301
309
|
|
|
302
310
|
export interface MDtAvatarProps extends QAvatarProps {
|