@mythpe/quasar-ui-qui 0.4.97 → 0.4.99
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/boot/register.ts +1 -1
- package/src/components/datatable/MDatatable.vue +15 -1
- package/src/components/form/MAvatarViewer.vue +8 -1
- package/src/components/form/MInput.vue +1 -1
- package/src/components/form/MOptions.vue +2 -2
- package/src/components/form/MPicker.vue +1 -0
- package/src/components/form/MSelect.vue +1 -0
- package/src/components/form/MToggle.vue +1 -0
- package/src/components/form/MUploader.vue +6 -5
- package/src/components/parials/MUploaderItem.vue +6 -5
- package/src/components/sar/MSarIcon.vue +3 -23
- package/src/composable/useDtHelpers.ts +11 -10
- package/src/icons/config.ts +13 -0
- package/src/icons/index.ts +10 -0
- package/src/style/typography.sass +3 -0
- package/src/types/api/MSar.d.ts +1 -1
- package/src/types/api/MUploader.d.ts +12 -7
- package/src/utils/vue-plugin.ts +16 -0
package/package.json
CHANGED
package/src/boot/register.ts
CHANGED
|
@@ -232,7 +232,7 @@ const $q = useQuasar()
|
|
|
232
232
|
const $router = useRouter()
|
|
233
233
|
const { te } = useI18n({ useScope: 'global' })
|
|
234
234
|
const useFormContext = useForm<any, any>()
|
|
235
|
-
const { resetForm: resetDialogForm, handleSubmit } = useFormContext
|
|
235
|
+
const { resetForm: resetDialogForm, handleSubmit, errors, meta } = useFormContext
|
|
236
236
|
|
|
237
237
|
const {
|
|
238
238
|
onRowContextmenu,
|
|
@@ -254,6 +254,7 @@ const {
|
|
|
254
254
|
dialogErrors,
|
|
255
255
|
setDialogErrors,
|
|
256
256
|
resetDialogs,
|
|
257
|
+
resetVeeForm,
|
|
257
258
|
getHeaders,
|
|
258
259
|
getSortedHeaders,
|
|
259
260
|
arrangementColumns,
|
|
@@ -417,6 +418,7 @@ const onSuccess: SubmissionHandler = async (form) => {
|
|
|
417
418
|
if (isUpdateMode.value) {
|
|
418
419
|
if (_data) {
|
|
419
420
|
updateDatatableItem(_data as any, dialogItemIndex.value)
|
|
421
|
+
resetVeeForm(_data)
|
|
420
422
|
}
|
|
421
423
|
emit('update', response)
|
|
422
424
|
if (!props.noUpdateClose && !props.noAutoClose) {
|
|
@@ -495,9 +497,17 @@ watch(loading, v => {
|
|
|
495
497
|
watch([filterForm, () => $q.lang.nativeName], () => refreshNoUpdate(), { deep: !0 })
|
|
496
498
|
watch(formDialogModel, (v) => {
|
|
497
499
|
if (!v) {
|
|
500
|
+
const keys = { ...dialogErrors.value, ...errors.value }
|
|
501
|
+
for (const k in keys) {
|
|
502
|
+
useFormContext.setFieldError(k, undefined)
|
|
503
|
+
useFormContext.setFieldTouched(k, !1)
|
|
504
|
+
}
|
|
498
505
|
dialogErrors.value = {}
|
|
499
506
|
}
|
|
500
507
|
})
|
|
508
|
+
watch(dialogErrors, (v) => {
|
|
509
|
+
useFormContext.setErrors(v || {})
|
|
510
|
+
}, { deep: !0 })
|
|
501
511
|
const table = ref<InstanceType<typeof QTable>>()
|
|
502
512
|
const mainAttrs = computed(() => ({
|
|
503
513
|
title: getTableTitle.value,
|
|
@@ -557,6 +567,7 @@ defineOptions({
|
|
|
557
567
|
defineExpose({
|
|
558
568
|
formContext: useFormContext,
|
|
559
569
|
resetDialogs,
|
|
570
|
+
resetVeeForm,
|
|
560
571
|
tableOptions,
|
|
561
572
|
getMythApiServicesSchema,
|
|
562
573
|
updateSelectedItems,
|
|
@@ -1691,8 +1702,10 @@ defineExpose({
|
|
|
1691
1702
|
>
|
|
1692
1703
|
<MBtn
|
|
1693
1704
|
:class="{'full-width': $q.screen.xs}"
|
|
1705
|
+
:disable="isUpdateMode ? (!meta.dirty && !meta.touched) || (!meta.dirty && meta.touched) : false"
|
|
1694
1706
|
:label="__(`myth.titles.${isUpdateMode ? 'save' : 'store'}`)"
|
|
1695
1707
|
:loading="loading"
|
|
1708
|
+
style="min-width: 120px"
|
|
1696
1709
|
type="submit"
|
|
1697
1710
|
v-bind="pluginOptions.dt?.dialogButtonsProps"
|
|
1698
1711
|
/>
|
|
@@ -1702,6 +1715,7 @@ defineExpose({
|
|
|
1702
1715
|
:disable="loading"
|
|
1703
1716
|
label="myth.titles.close"
|
|
1704
1717
|
outline
|
|
1718
|
+
style="min-width: 120px"
|
|
1705
1719
|
text-color="body"
|
|
1706
1720
|
v-bind="pluginOptions.dt?.dialogButtonsProps"
|
|
1707
1721
|
@click="closeFormDialog"
|
|
@@ -241,7 +241,7 @@ defineOptions({
|
|
|
241
241
|
<MRow
|
|
242
242
|
v-if="label !== undefined"
|
|
243
243
|
key="label"
|
|
244
|
-
class="items-center q-mb-
|
|
244
|
+
class="items-center q-mb-sm"
|
|
245
245
|
>
|
|
246
246
|
<q-skeleton
|
|
247
247
|
v-if="loading"
|
|
@@ -261,6 +261,7 @@ defineOptions({
|
|
|
261
261
|
<MHelpRow
|
|
262
262
|
v-if="!!help && !loading"
|
|
263
263
|
:text="help"
|
|
264
|
+
style="margin-top: 0"
|
|
264
265
|
tooltip
|
|
265
266
|
/>
|
|
266
267
|
</MRow>
|
|
@@ -316,6 +317,12 @@ defineOptions({
|
|
|
316
317
|
class="text-white text-h3"
|
|
317
318
|
v-text="getAvatarText"
|
|
318
319
|
/>
|
|
320
|
+
<div v-else>
|
|
321
|
+
<q-icon
|
|
322
|
+
:name="`ion-ios-${readonly ? 'aperture' : 'cloud-upload'}`"
|
|
323
|
+
color="primary"
|
|
324
|
+
/>
|
|
325
|
+
</div>
|
|
319
326
|
</q-avatar>
|
|
320
327
|
</MTransition>
|
|
321
328
|
</div>
|
|
@@ -255,13 +255,13 @@ defineOptions({
|
|
|
255
255
|
<MHelpRow
|
|
256
256
|
v-if="!!help"
|
|
257
257
|
:text="help"
|
|
258
|
-
class="q-ml-
|
|
258
|
+
class="q-ml-sm"
|
|
259
259
|
tooltip
|
|
260
260
|
/>
|
|
261
261
|
<template v-if="loading">
|
|
262
262
|
<div class="flex-break" />
|
|
263
263
|
<q-spinner-dots
|
|
264
|
-
class="q-mt-lg q-ml-
|
|
264
|
+
class="q-mt-lg q-ml-sm"
|
|
265
265
|
color="primary"
|
|
266
266
|
size="25px"
|
|
267
267
|
/>
|
|
@@ -365,15 +365,15 @@ defineOptions({
|
|
|
365
365
|
<div class="col">
|
|
366
366
|
<div
|
|
367
367
|
v-if="!!label"
|
|
368
|
-
class="q-uploader__title"
|
|
368
|
+
class="q-uploader__title text-large"
|
|
369
369
|
>
|
|
370
370
|
{{ __(label) }}
|
|
371
371
|
</div>
|
|
372
372
|
<div
|
|
373
|
-
v-if="!readonly"
|
|
373
|
+
v-if="!readonly && (scope.uploadSizeLabel !== '0.0B' && scope.uploadProgressLabel !== '0.00%')"
|
|
374
374
|
class="q-uploader__subtitle"
|
|
375
375
|
>
|
|
376
|
-
{{ scope.uploadSizeLabel }}
|
|
376
|
+
{{ scope.uploadSizeLabel }} • {{ scope.uploadProgressLabel }}
|
|
377
377
|
</div>
|
|
378
378
|
</div>
|
|
379
379
|
<template v-if="!readonly">
|
|
@@ -472,8 +472,8 @@ defineOptions({
|
|
|
472
472
|
</MRow>
|
|
473
473
|
<q-list
|
|
474
474
|
v-else
|
|
475
|
-
:class="{'row
|
|
476
|
-
:separator="displayMode === 'list' ? !0 : undefined"
|
|
475
|
+
:class="{'row q-gutter-sm': displayMode === 'card' && !$q.screen.xs}"
|
|
476
|
+
:separator="displayMode === 'list' || $q.screen.xs ? !0 : undefined"
|
|
477
477
|
>
|
|
478
478
|
<template
|
|
479
479
|
v-for="(file,i) in scope.files"
|
|
@@ -508,6 +508,7 @@ defineOptions({
|
|
|
508
508
|
>
|
|
509
509
|
<MUploaderItem
|
|
510
510
|
:audio-props="audioProps"
|
|
511
|
+
:class="{'q-mb-sm': $q.screen.xs}"
|
|
511
512
|
:collection="collection"
|
|
512
513
|
:default-file-icon="defaultFileIcon"
|
|
513
514
|
:delete-media-icon="deleteMediaIcon"
|
|
@@ -61,7 +61,7 @@ const props = withDefaults(defineProps<P>(), {
|
|
|
61
61
|
defaultFileIcon: undefined,
|
|
62
62
|
deleteMediaIcon: undefined,
|
|
63
63
|
downloadFileIcon: undefined,
|
|
64
|
-
mediaLabel:
|
|
64
|
+
mediaLabel: undefined,
|
|
65
65
|
ratio: 16 / 9,
|
|
66
66
|
videoProps: undefined,
|
|
67
67
|
audioProps: undefined
|
|
@@ -83,7 +83,7 @@ const emit = defineEmits<Emits>()
|
|
|
83
83
|
|
|
84
84
|
const q = useQuasar()
|
|
85
85
|
const { te } = useI18n({ useScope: 'global' })
|
|
86
|
-
const { alertError, alertSuccess, confirmMessage, __, props: pluginOptions, api: mApi } = useMyth()
|
|
86
|
+
const { alertError, alertSuccess, confirmMessage, __, props: pluginOptions, api: mApi, ucFirst } = useMyth()
|
|
87
87
|
const api = computed(() => mApi.value.services)
|
|
88
88
|
const setModelValue = (value: Props['modelValue']) => emit('values', value)
|
|
89
89
|
const deleting = ref(!1)
|
|
@@ -199,7 +199,7 @@ defineOptions({
|
|
|
199
199
|
/>
|
|
200
200
|
</q-item-section>
|
|
201
201
|
<q-item-section :class="{'overflow-hidden': displayMode === 'card'}">
|
|
202
|
-
<q-item-label v-if="!!mediaProp[mediaLabel]">
|
|
202
|
+
<q-item-label v-if="mediaLabel && !!mediaProp[mediaLabel]">
|
|
203
203
|
{{ mediaProp[mediaLabel] }}
|
|
204
204
|
<q-icon
|
|
205
205
|
v-if="updateBtn"
|
|
@@ -274,8 +274,9 @@ defineOptions({
|
|
|
274
274
|
caption
|
|
275
275
|
class="print-hide"
|
|
276
276
|
>
|
|
277
|
-
<span v-if="!!mediaProp.size_to_string">{{ mediaProp.size_to_string }}
|
|
278
|
-
<span v-if="
|
|
277
|
+
<span v-if="!!mediaProp.size_to_string && modelValue.type_to_string">{{ mediaProp.size_to_string }} • {{ modelValue.type_to_string }}</span>
|
|
278
|
+
<span v-else-if="!!mediaProp.size_to_string">{{ mediaProp.size_to_string }}</span>
|
|
279
|
+
<span v-if="modelValue.__sizeLabel">{{ modelValue.__sizeLabel }} • {{ modelValue.__progressLabel }}</span>
|
|
279
280
|
</q-item-label>
|
|
280
281
|
<q-item-label
|
|
281
282
|
v-if="(mediaProp.id && mediaProp.url) || (!hideDeleteMedia || (hideDeleteMedia && !mediaProp.id))"
|
|
@@ -7,17 +7,9 @@
|
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
<script lang="ts" setup>
|
|
10
|
-
import type { QIconProps } from 'quasar'
|
|
11
|
-
import { computed } from 'vue'
|
|
12
10
|
|
|
13
|
-
type Props = QIconProps
|
|
14
|
-
const noDefault = defineModel<boolean>('noDefault', { required: !1, default: !1 })
|
|
15
|
-
const props = defineProps<Props>()
|
|
16
|
-
const getSize = computed<any>(() => ({
|
|
17
|
-
size: noDefault.value ? props.size : (props.size || '100%')
|
|
18
|
-
}))
|
|
19
11
|
defineOptions({
|
|
20
|
-
name: '
|
|
12
|
+
name: 'MSarIcon',
|
|
21
13
|
inheritAttrs: !1
|
|
22
14
|
})
|
|
23
15
|
</script>
|
|
@@ -25,20 +17,8 @@ defineOptions({
|
|
|
25
17
|
<template>
|
|
26
18
|
<q-icon
|
|
27
19
|
class="m-sar-icon"
|
|
28
|
-
v-bind="
|
|
20
|
+
v-bind="{...$attrs, name: 'myth-sar'}"
|
|
29
21
|
>
|
|
30
|
-
<slot
|
|
31
|
-
<svg
|
|
32
|
-
viewBox="0 0 1124.14 1256.39"
|
|
33
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
34
|
-
>
|
|
35
|
-
<path
|
|
36
|
-
d="M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z"
|
|
37
|
-
/>
|
|
38
|
-
<path
|
|
39
|
-
d="M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z"
|
|
40
|
-
/>
|
|
41
|
-
</svg>
|
|
42
|
-
</slot>
|
|
22
|
+
<slot />
|
|
43
23
|
</q-icon>
|
|
44
24
|
</template>
|
|
@@ -21,7 +21,7 @@ import { useMyth } from './useMyth'
|
|
|
21
21
|
import { extend, is, useQuasar } from 'quasar'
|
|
22
22
|
import { useRoute, useRouter } from 'vue-router'
|
|
23
23
|
import type { AxiosRequestConfig } from 'axios'
|
|
24
|
-
import { useResetForm
|
|
24
|
+
import { useResetForm } from 'vee-validate'
|
|
25
25
|
import { MFrameDialog } from '../components'
|
|
26
26
|
|
|
27
27
|
const initPaginationOptions: MDatatablePagination = {
|
|
@@ -491,15 +491,16 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
const openDialogTimeout = 100
|
|
494
|
-
const setValues = useSetFormValues()
|
|
495
494
|
const resetDialogForm = useResetForm()
|
|
496
495
|
const resetVeeForm = async (attrs?: Record<string, any>) => {
|
|
497
|
-
|
|
496
|
+
let init: any = {}
|
|
498
497
|
for (const k in defaultItem.value) {
|
|
499
498
|
init[k] = attrs && k in attrs ? attrs[k] : defaultItem.value[k]
|
|
500
499
|
}
|
|
501
|
-
|
|
502
|
-
|
|
500
|
+
if (attrs) {
|
|
501
|
+
init = { ...init, ...attrs }
|
|
502
|
+
}
|
|
503
|
+
resetDialogForm({ values: init || {}, errors: undefined }, { force: !0 })
|
|
503
504
|
}
|
|
504
505
|
const beforeShowFilterDialog = async () => {
|
|
505
506
|
resetDialogForm({ values: {}, errors: {} }, { force: !0 })
|
|
@@ -633,11 +634,10 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
|
|
|
633
634
|
getRows.value[index] = { ..._data } as any
|
|
634
635
|
nextTick(() => setTimeout(() => (selected.value = [getRows.value[index] as any]), openDialogTimeout))
|
|
635
636
|
}
|
|
636
|
-
setTimeout(() => {
|
|
637
|
-
resetVeeForm(_data)
|
|
638
|
-
nextTick(
|
|
639
|
-
|
|
640
|
-
})
|
|
637
|
+
setTimeout(async () => {
|
|
638
|
+
await resetVeeForm(_data)
|
|
639
|
+
await nextTick()
|
|
640
|
+
formDialogModel.value = !0
|
|
641
641
|
}, openDialogTimeout)
|
|
642
642
|
})
|
|
643
643
|
.catch((e: any) => {
|
|
@@ -1024,6 +1024,7 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
|
|
|
1024
1024
|
dialogErrors,
|
|
1025
1025
|
setDialogErrors,
|
|
1026
1026
|
resetDialogs,
|
|
1027
|
+
resetVeeForm,
|
|
1027
1028
|
getHeaders,
|
|
1028
1029
|
getSortedHeaders,
|
|
1029
1030
|
arrangementColumns,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MyTh Ahmed Faiz Copyright © 2016-2026 All rights reserved.
|
|
3
|
+
* Email: mythpe@gmail.com
|
|
4
|
+
* Mobile: +966590470092
|
|
5
|
+
* Website: https://www.4myth.com
|
|
6
|
+
* Github: https://github.com/mythpe
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const iconSet = 'myth-'
|
|
10
|
+
export const icons = {
|
|
11
|
+
sar: 'M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z&&M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z|0 0 1124.14 1256.39'
|
|
12
|
+
}
|
|
13
|
+
export default {}
|
package/src/types/api/MSar.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { VNode } from 'vue'
|
|
10
10
|
import type { QIconProps } from 'quasar'
|
|
11
11
|
|
|
12
|
-
export type MSarIconProps = Omit<QIconProps, 'name'
|
|
12
|
+
export type MSarIconProps = Omit<QIconProps, 'name'>;
|
|
13
13
|
|
|
14
14
|
export interface MSarIconSlots {
|
|
15
15
|
default: () => VNode[]
|
|
@@ -20,22 +20,27 @@ export interface MUploaderMediaItem {
|
|
|
20
20
|
name: string;
|
|
21
21
|
file_name: string;
|
|
22
22
|
type: MediaType;
|
|
23
|
-
type_to_string: string;
|
|
23
|
+
type_to_string: string | null;
|
|
24
|
+
mime_type: string;
|
|
24
25
|
size: number;
|
|
25
26
|
size_to_string: string;
|
|
27
|
+
collection_name: string;
|
|
28
|
+
collection_to_string: string;
|
|
26
29
|
url: string;
|
|
27
30
|
download_url: string;
|
|
28
|
-
icon: string;
|
|
29
|
-
description: string;
|
|
30
|
-
attachment_type: string;
|
|
31
|
-
collection_to_string: string;
|
|
31
|
+
icon: string | null;
|
|
32
|
+
description: string | null;
|
|
33
|
+
attachment_type: string | null;
|
|
32
34
|
attachment_type_id: number | null;
|
|
33
|
-
attachment_type_id_to_string: string;
|
|
35
|
+
attachment_type_id_to_string: string | null;
|
|
34
36
|
user_id: number | null;
|
|
35
|
-
user_id_to_string: string;
|
|
37
|
+
user_id_to_string: string | null;
|
|
36
38
|
order_column: number;
|
|
37
39
|
original_url: boolean;
|
|
38
40
|
preview_url: boolean;
|
|
41
|
+
model_id: number;
|
|
42
|
+
model_id_to_string: string;
|
|
43
|
+
model_type: string;
|
|
39
44
|
model_type_to_string: string;
|
|
40
45
|
is_image: boolean;
|
|
41
46
|
is_pdf: boolean;
|
package/src/utils/vue-plugin.ts
CHANGED
|
@@ -13,6 +13,8 @@ import { defineComponents } from '../plugin/defineComponents'
|
|
|
13
13
|
|
|
14
14
|
import { createMyth, extendOptions } from './createMyth'
|
|
15
15
|
import { MythKey } from './const'
|
|
16
|
+
import { icons, iconSet } from '../icons'
|
|
17
|
+
import { Str } from './Str'
|
|
16
18
|
|
|
17
19
|
function install (app: App, options: InstallOptions) {
|
|
18
20
|
const opts = extendOptions(options)
|
|
@@ -35,6 +37,20 @@ function install (app: App, options: InstallOptions) {
|
|
|
35
37
|
// for (const routesKey in routes) {
|
|
36
38
|
// console.log(routesKey)
|
|
37
39
|
// }
|
|
40
|
+
const otherIconMapFn = app.config.globalProperties.$q.iconMapFn
|
|
41
|
+
app.config.globalProperties.$q.iconMapFn = (iconName) => {
|
|
42
|
+
if (iconName.startsWith(iconSet)) {
|
|
43
|
+
const name = Str.camelCase(iconName.slice(iconSet.length))
|
|
44
|
+
if (Object.keys(icons).includes(name)) {
|
|
45
|
+
return {
|
|
46
|
+
icon: icons[name]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (typeof otherIconMapFn === 'function') {
|
|
51
|
+
return otherIconMapFn(iconName)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
export {
|