@mythpe/quasar-ui-qui 0.0.27 → 0.0.29-dev
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/index.d.ts +13 -0
- package/package.json +17 -8
- package/src/boot/register.ts +14 -0
- package/src/components/datatable/MDatatable.vue +2305 -0
- package/src/components/datatable/MDtAvatar.vue +49 -0
- package/src/components/datatable/MDtBtn.vue +153 -0
- package/src/components/datatable/MDtContextmenuItems.vue +54 -0
- package/src/components/datatable/index.ts +6 -0
- package/src/components/form/MAvatarViewer.vue +327 -0
- package/src/components/form/MAxios.vue +144 -0
- package/src/components/form/MBtn.vue +271 -93
- package/src/components/form/MCheckbox.vue +150 -0
- package/src/components/form/MCkeditor.vue +403 -0
- package/src/components/form/MColor.vue +122 -0
- package/src/components/form/MDate.vue +50 -0
- package/src/components/form/MEditor.vue +285 -0
- package/src/components/form/MEmail.vue +43 -0
- package/src/components/form/MField.vue +148 -0
- package/src/components/form/MFile.vue +215 -0
- package/src/components/form/MForm.vue +89 -0
- package/src/components/form/MHidden.vue +86 -0
- package/src/components/form/MHiddenInput.vue +58 -0
- package/src/components/form/MInput.vue +178 -0
- package/src/components/form/MInputFieldControl.vue +27 -0
- package/src/components/form/MInputLabel.vue +38 -0
- package/src/components/form/MMobile.vue +43 -0
- package/src/components/form/MOptions.vue +255 -0
- package/src/components/form/MOtp.vue +292 -0
- package/src/components/form/MPassword.vue +73 -0
- package/src/components/form/MPicker.vue +313 -0
- package/src/components/form/MRadio.vue +181 -0
- package/src/components/form/MSelect.vue +352 -0
- package/src/components/form/MTime.vue +48 -0
- package/src/components/form/MToggle.vue +211 -0
- package/src/components/form/MUploader.vue +511 -0
- package/src/components/form/index.ts +65 -0
- package/src/components/grid/MBlock.vue +39 -18
- package/src/components/grid/MCol.vue +11 -15
- package/src/components/grid/MColumn.vue +12 -1
- package/src/components/grid/MContainer.vue +22 -13
- package/src/components/grid/MHelpRow.vue +13 -12
- package/src/components/grid/MRow.vue +31 -10
- package/src/components/grid/index.ts +16 -0
- package/src/components/index.ts +15 -0
- package/src/components/modal/MDialog.vue +58 -0
- package/src/components/modal/MModalMenu.vue +62 -0
- package/src/components/modal/MTooltip.vue +39 -0
- package/src/components/modal/index.ts +5 -0
- package/src/components/parials/UploaderItem.vue +298 -0
- package/src/components/parials/index.ts +3 -0
- package/src/components/transition/MFadeTransition.vue +27 -0
- package/src/components/transition/MFadeXTransition.vue +26 -0
- package/src/components/transition/MTransition.vue +44 -0
- package/src/components/transition/index.ts +13 -0
- package/src/components/typography/MTypingString.vue +8 -0
- package/src/components/typography/index.ts +11 -0
- package/src/composable/index.ts +12 -0
- package/src/composable/useBindInput.ts +209 -0
- package/src/composable/useError.ts +11 -0
- package/src/composable/useMyth.ts +311 -0
- package/src/composable/useValue.ts +12 -0
- package/src/index.common.js +19 -1
- package/src/index.esm.js +18 -3
- package/src/index.js +19 -0
- package/src/index.sass +9 -26
- package/src/index.ts +18 -4
- package/src/index.umd.js +17 -2
- package/src/style/m-container.sass +13 -0
- package/src/style/main.sass +146 -0
- package/src/style/print.sass +14 -0
- package/src/style/transition.sass +40 -0
- package/src/types/api-helpers.d.ts +62 -0
- package/src/types/components.d.ts +1108 -27
- package/src/types/index.d.ts +21 -1
- package/src/types/install-options.d.ts +19 -0
- package/src/types/lodash.d.ts +26 -0
- package/src/types/m-datatable.d.ts +316 -0
- package/src/types/m-geolocation.d.ts +16 -0
- package/src/types/m-helpers.d.ts +97 -0
- package/src/types/plugin-props-option.d.ts +305 -0
- package/src/types/quasar-helpers.d.ts +7 -0
- package/src/types/theme.d.ts +12 -0
- package/src/utils/Helpers.ts +293 -0
- package/src/utils/Str.ts +211 -0
- package/src/utils/index.ts +13 -0
- package/src/utils/myth.ts +109 -0
- package/src/utils/vee-rules.ts +32 -0
- package/src/utils/vue-plugin.ts +163 -0
- package/tsconfig.json +9 -13
- package/src/myth.ts +0 -30
- package/src/types/myth.ts +0 -42
- package/src/vue-plugin.ts +0 -41
- package/types.d.ts +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
<script
|
|
10
|
+
lang="ts"
|
|
11
|
+
setup
|
|
12
|
+
>
|
|
13
|
+
defineOptions({
|
|
14
|
+
name: 'MFadeTransition',
|
|
15
|
+
inheritAttrs: !1
|
|
16
|
+
})
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<Transition
|
|
21
|
+
appear
|
|
22
|
+
name="myth-transition__fade"
|
|
23
|
+
v-bind="$attrs"
|
|
24
|
+
>
|
|
25
|
+
<slot />
|
|
26
|
+
</Transition>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
<script
|
|
9
|
+
lang="ts"
|
|
10
|
+
setup
|
|
11
|
+
>
|
|
12
|
+
defineOptions({
|
|
13
|
+
name: 'MFadeXTransition',
|
|
14
|
+
inheritAttrs: !1
|
|
15
|
+
})
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<Transition
|
|
20
|
+
appear
|
|
21
|
+
name="myth-transition__fade-x"
|
|
22
|
+
v-bind="$attrs"
|
|
23
|
+
>
|
|
24
|
+
<slot />
|
|
25
|
+
</Transition>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
<script
|
|
10
|
+
lang="ts"
|
|
11
|
+
setup
|
|
12
|
+
>
|
|
13
|
+
import type { MTransitionProps as Props } from '../../types'
|
|
14
|
+
|
|
15
|
+
interface P {
|
|
16
|
+
enterIn?: Props['enterIn'];
|
|
17
|
+
enterOut?: Props['enterOut'];
|
|
18
|
+
slowIn?: Props['slowIn'];
|
|
19
|
+
slowOut?: Props['slowIn'];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
withDefaults(defineProps<P>(), {
|
|
23
|
+
enterIn: () => 'fadeIn',
|
|
24
|
+
enterOut: () => 'fadeOut',
|
|
25
|
+
slowIn: () => !1,
|
|
26
|
+
slowOut: () => !1
|
|
27
|
+
})
|
|
28
|
+
defineOptions({
|
|
29
|
+
name: 'MTransition',
|
|
30
|
+
inheritAttrs: !1
|
|
31
|
+
})
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<TransitionGroup
|
|
36
|
+
:enter-active-class="`animated ${enterIn} ${slowIn ? 'slow' : ''}`"
|
|
37
|
+
:leave-active-class="`animated ${enterOut} ${slowOut ? 'slow' : ''}`"
|
|
38
|
+
appear
|
|
39
|
+
name="m__transition__fade"
|
|
40
|
+
v-bind="$attrs"
|
|
41
|
+
>
|
|
42
|
+
<slot />
|
|
43
|
+
</TransitionGroup>
|
|
44
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
import MFadeTransition from './MFadeTransition.vue'
|
|
10
|
+
import MFadeXTransition from './MFadeXTransition.vue'
|
|
11
|
+
import MTransition from './MTransition.vue'
|
|
12
|
+
|
|
13
|
+
export { MFadeTransition, MFadeXTransition, MTransition }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
import MTypingString from './MTypingString.vue'
|
|
10
|
+
|
|
11
|
+
export { MTypingString }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MyTh Ahmed Faiz Copyright © 2016-2024 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 * from './useBindInput'
|
|
10
|
+
export * from './useMyth'
|
|
11
|
+
export * from './useValue'
|
|
12
|
+
export * from './useError'
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { computed, MaybeRefOrGetter, ref, toValue } from 'vue'
|
|
2
|
+
import { useI18n } from 'vue-i18n'
|
|
3
|
+
import { useMyth } from './useMyth'
|
|
4
|
+
import { useSplitAttrs } from 'quasar'
|
|
5
|
+
import { myth } from '../utils'
|
|
6
|
+
import { camelCase, kebabCase, snakeCase, uniq } from 'lodash'
|
|
7
|
+
import { PropsContext as UiOpt } from '../types/plugin-props-option'
|
|
8
|
+
|
|
9
|
+
type G = { name: string; [k: string]: any };
|
|
10
|
+
type OptsContext = { choose?: boolean; };
|
|
11
|
+
export const useBindInput = <P extends G = G> (Props: MaybeRefOrGetter<P>, key: keyof UiOpt, Opts: MaybeRefOrGetter<OptsContext> = {}) => {
|
|
12
|
+
const { messages, locale } = useI18n({ useScope: 'global' })
|
|
13
|
+
const { __ } = useMyth()
|
|
14
|
+
const { attributes } = useSplitAttrs()
|
|
15
|
+
const props = toValue<P>(Props)
|
|
16
|
+
const opts = toValue<OptsContext>(Opts)
|
|
17
|
+
const getProp = computed(() => (k: string) => {
|
|
18
|
+
if (props[k] !== undefined) {
|
|
19
|
+
return props[k]
|
|
20
|
+
}
|
|
21
|
+
return pluginProps.value[key]?.[k]
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const { themeBtn, themeInput, props: pluginProps } = myth
|
|
25
|
+
const theme = computed(() => (key === 'btn' ? themeBtn.value : themeInput.value) ?? {})
|
|
26
|
+
const mergedTheme = ref({})
|
|
27
|
+
for (const k in theme.value) {
|
|
28
|
+
mergedTheme.value[k] = props[k] !== undefined ? theme.value[k] : props[k]
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Top Label Style.
|
|
32
|
+
*/
|
|
33
|
+
const hasTopLabel = computed(() => {
|
|
34
|
+
if (props.topLabel !== undefined) {
|
|
35
|
+
return props.topLabel !== !1
|
|
36
|
+
}
|
|
37
|
+
if ('topLabel' in theme.value && theme.value.topLabel !== undefined) {
|
|
38
|
+
return theme.value.topLabel !== !1
|
|
39
|
+
}
|
|
40
|
+
if (pluginProps.value[key] && 'topLabel' in pluginProps.value[key]) {
|
|
41
|
+
return pluginProps.value[key]?.topLabel !== !1
|
|
42
|
+
}
|
|
43
|
+
return !1
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const getLabel = computed<string | undefined>(() => {
|
|
47
|
+
const k = props.label === undefined ? props.name : props.label
|
|
48
|
+
return k ? (__(k) || undefined) : undefined
|
|
49
|
+
})
|
|
50
|
+
const getPlaceholder = computed<string | undefined>(() => {
|
|
51
|
+
const replace = computed(() => {
|
|
52
|
+
const val = props.useChoice !== undefined ? props.useChoice : (attributes.value.useChoice !== undefined ? attributes.value.useChoice : opts?.choose)
|
|
53
|
+
if (typeof val === 'string' && val?.length > 0) {
|
|
54
|
+
return val
|
|
55
|
+
}
|
|
56
|
+
return 'enter'
|
|
57
|
+
})
|
|
58
|
+
if (props.placeholder === undefined) {
|
|
59
|
+
const k = props.label !== undefined ? props.label : props.name
|
|
60
|
+
return __(`replace.${replace.value}`, { name: __(k) })
|
|
61
|
+
}
|
|
62
|
+
return __(props.placeholder) || undefined
|
|
63
|
+
})
|
|
64
|
+
const getAutocompleteAttribute = computed<string | null | undefined>(() => {
|
|
65
|
+
const autocomplete = props.autocomplete !== undefined ? props.autocomplete : (pluginProps.value[key] && 'autocomplete' in pluginProps.value[key] ? pluginProps.value[key]?.autocomplete : undefined)
|
|
66
|
+
// const autocomplete = 'autocomplete' in opt && opt?.autocomplete !== undefined ? opt?.autocomplete : props.autocomplete
|
|
67
|
+
if (autocomplete !== undefined) {
|
|
68
|
+
if (autocomplete === !0 || autocomplete === '') {
|
|
69
|
+
return kebabCase(props.name)
|
|
70
|
+
} else if (autocomplete === !1) {
|
|
71
|
+
return 'off'
|
|
72
|
+
} else if (autocomplete?.length > 0) {
|
|
73
|
+
return autocomplete
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return undefined
|
|
77
|
+
})
|
|
78
|
+
const accepts = computed(() => {
|
|
79
|
+
const l: string[] = []
|
|
80
|
+
if (props.accept) {
|
|
81
|
+
if (typeof props.accept === 'string') {
|
|
82
|
+
l.push(props.accept)
|
|
83
|
+
} else if (Array.isArray(props.accept)) {
|
|
84
|
+
l.push(...props.accept)
|
|
85
|
+
} else if (typeof props.accept === 'object') {
|
|
86
|
+
const v = toValue(props.accept)
|
|
87
|
+
l.push(...Object.values<string>(v))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (props.images) {
|
|
91
|
+
if (typeof props.images === 'string' && props.images?.length > 0) {
|
|
92
|
+
l.push(props.images)
|
|
93
|
+
} else {
|
|
94
|
+
l.push('image/png,image/jpg,image/jpeg')
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (props.svg) {
|
|
98
|
+
if (typeof props.svg === 'string' && props.svg?.length > 0) {
|
|
99
|
+
l.push(props.svg)
|
|
100
|
+
} else {
|
|
101
|
+
l.push('image/svg+xml')
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (props.video) {
|
|
105
|
+
if (typeof props.video === 'string' && props.video?.length > 0) {
|
|
106
|
+
l.push(props.video)
|
|
107
|
+
} else {
|
|
108
|
+
l.push('video/mp4')
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (props.pdf) {
|
|
112
|
+
if (typeof props.pdf === 'string' && props.pdf?.length > 0) {
|
|
113
|
+
l.push(props.pdf)
|
|
114
|
+
} else {
|
|
115
|
+
l.push('application/pdf')
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (props.excel) {
|
|
119
|
+
if (typeof props.excel === 'string' && props.excel?.length > 0) {
|
|
120
|
+
l.push(props.excel)
|
|
121
|
+
} else {
|
|
122
|
+
l.push('application/vnd.ms-excel')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return l
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const isNumeric = (str: any) => !isNaN(str) && !isNaN(parseFloat(str))
|
|
129
|
+
const convertRules = (rules: any) => {
|
|
130
|
+
if (!rules) {
|
|
131
|
+
return {}
|
|
132
|
+
}
|
|
133
|
+
let values: Record<string, any> = {}
|
|
134
|
+
const list: any[] = typeof rules === 'string' ? rules.split('|') : (Array.isArray(rules) ? rules : [rules])
|
|
135
|
+
|
|
136
|
+
for (const rule of list) {
|
|
137
|
+
// console.log(rule)
|
|
138
|
+
if (!rule) {
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
if (typeof rule === 'object' && !Array.isArray(rule)) {
|
|
142
|
+
values = { ...values, ...rule }
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
145
|
+
if (Array.isArray(rule)) {
|
|
146
|
+
values = { ...values, ...rule }
|
|
147
|
+
}
|
|
148
|
+
const [name, value] = rule.split(':')
|
|
149
|
+
if (!name) {
|
|
150
|
+
continue
|
|
151
|
+
}
|
|
152
|
+
values[name] = !value ? !0
|
|
153
|
+
: /,/g.test(value) ? value.split(',').map((e: any) => isNumeric(e) ? parseInt(e) : e) : (isNumeric(value) ? parseInt(value) : value)
|
|
154
|
+
}
|
|
155
|
+
if (values.color && props.required) {
|
|
156
|
+
values.requiredColor = values.color
|
|
157
|
+
delete values.color
|
|
158
|
+
}
|
|
159
|
+
return values
|
|
160
|
+
}
|
|
161
|
+
const publicRules = ['required', 'email', 'numeric', 'integer', 'float', 'color']
|
|
162
|
+
const validations = (messages.value as any)?.[locale.value]?.validation?.messages || {}
|
|
163
|
+
const inputRules = computed<Record<string, any>>(() => {
|
|
164
|
+
if (props.viewMode) {
|
|
165
|
+
return {}
|
|
166
|
+
}
|
|
167
|
+
const rules: any = { ...convertRules(toValue(props.rules)) }
|
|
168
|
+
const keys = uniq<string>([...publicRules, ...(myth.rules.value ?? []), ...Object.keys(validations)])
|
|
169
|
+
for (const k of keys) {
|
|
170
|
+
if (['mobile', '_default', 'default'].includes(k)) {
|
|
171
|
+
continue
|
|
172
|
+
}
|
|
173
|
+
const cases = [k, snakeCase(k), camelCase(k), kebabCase(k)]
|
|
174
|
+
|
|
175
|
+
// eslint-disable-next-line no-labels
|
|
176
|
+
mainFor: for (const c of cases) {
|
|
177
|
+
for (const b of [attributes.value, props]) {
|
|
178
|
+
if (c in b && (b[c] === !0 || b[c] === '')) {
|
|
179
|
+
rules[snakeCase(k)] = b[c] === !0 || b[c] === '' ? !0 : b[c]
|
|
180
|
+
// eslint-disable-next-line no-labels
|
|
181
|
+
break mainFor
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const mobile = attributes.value?.mobile !== undefined ? attributes.value.mobile : props.mobile
|
|
188
|
+
if (mobile !== undefined && mobile !== false) {
|
|
189
|
+
const defLen = 10
|
|
190
|
+
rules.digits = typeof mobile === 'boolean' ? defLen : (mobile || defLen)
|
|
191
|
+
}
|
|
192
|
+
return Object.values(rules).filter(e => !!e).length > 0 ? rules : undefined
|
|
193
|
+
})
|
|
194
|
+
const attrs = computed(() => ({
|
|
195
|
+
...props,
|
|
196
|
+
...attributes.value,
|
|
197
|
+
...mergedTheme.value
|
|
198
|
+
}))
|
|
199
|
+
return {
|
|
200
|
+
inputRules,
|
|
201
|
+
accepts,
|
|
202
|
+
hasTopLabel,
|
|
203
|
+
getLabel,
|
|
204
|
+
getPlaceholder,
|
|
205
|
+
getAutocompleteAttribute,
|
|
206
|
+
getProp,
|
|
207
|
+
attrs
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { computed, MaybeRefOrGetter } from 'vue'
|
|
2
|
+
import { useFieldError, useSetFieldError } from 'vee-validate'
|
|
3
|
+
|
|
4
|
+
export const useError = (name: MaybeRefOrGetter<string>) => {
|
|
5
|
+
const [error, setErrors] = [useFieldError(name), useSetFieldError(name)]
|
|
6
|
+
const errors = computed<string | string[] | undefined>({
|
|
7
|
+
get: () => error.value,
|
|
8
|
+
set: (v: string | string[] | undefined) => setErrors(v)
|
|
9
|
+
})
|
|
10
|
+
return { errors, error, setErrors }
|
|
11
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MyTh Ahmed Faiz Copyright © 2016-2024 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
|
+
import lodash from 'lodash'
|
|
10
|
+
import { useI18n } from 'vue-i18n'
|
|
11
|
+
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|
12
|
+
import { copyToClipboard, extend, QDialogOptions, QNotifyCreateOptions, useQuasar } from 'quasar'
|
|
13
|
+
import { Helpers, myth, Str, veeRules } from '../utils'
|
|
14
|
+
import type { MDtColumn, MDtHeadersParameter, ParseHeaderOptions, Vue3MAlertMessage, Vue3MAlertMessageOptions, Vue3MConfirmMessage } from '../types'
|
|
15
|
+
import { computed } from 'vue'
|
|
16
|
+
|
|
17
|
+
export const useMyth = () => {
|
|
18
|
+
const { t, te } = useI18n({ useScope: 'global' })
|
|
19
|
+
const { props: pluginOptions } = myth
|
|
20
|
+
const q = useQuasar()
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
const __ = (key: any, ...rest: unknown[]) => !key ? '' : te(`attributes.${key}`) ? t(`attributes.${key}`, ...rest) : te(key) ? t(key, ...rest) : key
|
|
24
|
+
const getPageTitle = (route: RouteLocationNormalizedLoaded, number?: number | string): string => {
|
|
25
|
+
number = number || 2
|
|
26
|
+
number = parseInt(number.toString())
|
|
27
|
+
const defaultValue = ''
|
|
28
|
+
// Not is route
|
|
29
|
+
// No page title
|
|
30
|
+
if (!route) {
|
|
31
|
+
return defaultValue
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const routePath = route?.path?.toString() || null
|
|
35
|
+
const routeName = route?.name?.toString() || null
|
|
36
|
+
|
|
37
|
+
// Not is route
|
|
38
|
+
// No page title
|
|
39
|
+
if (!routePath || !routeName) {
|
|
40
|
+
return defaultValue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let lastRouteName = routeName.split('.').pop() || ''
|
|
44
|
+
if (lastRouteName === 'index') {
|
|
45
|
+
const s = routeName.split('.')
|
|
46
|
+
lastRouteName = s[s.length - 2] ?? lastRouteName
|
|
47
|
+
}
|
|
48
|
+
const pluralize = Str.pascalCase(lodash.pluralize(lastRouteName))
|
|
49
|
+
const singular = Str.pascalCase(lodash.singularize(lastRouteName))
|
|
50
|
+
const keys = lodash.filter(lodash.uniq([
|
|
51
|
+
`${lastRouteName}Page.title`,
|
|
52
|
+
`${lodash.camelCase(lastRouteName)}Page.title`,
|
|
53
|
+
`choice.${pluralize}`,
|
|
54
|
+
`choice.${singular}`,
|
|
55
|
+
`replace.${lastRouteName}_details`,
|
|
56
|
+
`replace.${lastRouteName}`,
|
|
57
|
+
pluralize,
|
|
58
|
+
lodash.snakeCase(pluralize),
|
|
59
|
+
singular,
|
|
60
|
+
lodash.snakeCase(singular)
|
|
61
|
+
]))
|
|
62
|
+
|
|
63
|
+
let str: string | null = null
|
|
64
|
+
let k: string | any
|
|
65
|
+
|
|
66
|
+
if (te((k = `routes.${routeName}`)) && lodash.isString((str = t(k)))) {
|
|
67
|
+
return str
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (te((k = `routes.${routePath}`)) && lodash.isString((str = t(k)))) {
|
|
71
|
+
return str
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const f in keys) {
|
|
75
|
+
if (!(k = keys[f])) {
|
|
76
|
+
continue
|
|
77
|
+
}
|
|
78
|
+
if (te && te(k) && lodash.isString(t(k))) {
|
|
79
|
+
if (lodash.startsWith(k, 'choice.')) {
|
|
80
|
+
const s = k.split('.')
|
|
81
|
+
const n = routeName.split('.')
|
|
82
|
+
if (s.length === 2 && n.length > 1) {
|
|
83
|
+
const model = n[n.length - 2]
|
|
84
|
+
const pluralizeModel = lodash.pluralize(lodash.pascalCase(model))
|
|
85
|
+
const _modelChoiceKey = `choice.${pluralizeModel}`
|
|
86
|
+
if (te(_modelChoiceKey)) {
|
|
87
|
+
const l = t(_modelChoiceKey, number as any)
|
|
88
|
+
const rep = lodash.singularize(n[n.length - 1]).toLocaleLowerCase()
|
|
89
|
+
const e = `replace.${rep}`
|
|
90
|
+
str = te(e) ? t(e, { name: l }) : null
|
|
91
|
+
} else {
|
|
92
|
+
const pop: string = k.split('.').pop() || ''
|
|
93
|
+
str = te(k) ? t(k, number as any, { [pop]: number }) : null
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
const pop: string = k.split('.').pop() || ''
|
|
97
|
+
str = te(k) ? t(k, number as any, { [pop]: number }) : null
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
const parents: string[] = routeName.split('.')
|
|
101
|
+
if (parents.length > 1) {
|
|
102
|
+
const e = `choice.${Str.pascalCase(lodash.pluralize(parents[parents.length - 2]))}`
|
|
103
|
+
str = te(e) ? t(k, { name: t(e, '1') }) : null
|
|
104
|
+
} else {
|
|
105
|
+
str = te(k) ? t(k, { name: '' }) : null
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return str || defaultValue
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return defaultValue
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Custom transformer
|
|
115
|
+
* @param headers
|
|
116
|
+
* @param options
|
|
117
|
+
*/
|
|
118
|
+
const parseHeaders = (headers: MDtHeadersParameter, options: ParseHeaderOptions = {}): MDtColumn[] => {
|
|
119
|
+
const defaultOptions: Partial<ParseHeaderOptions> = {
|
|
120
|
+
controlKey: 'control',
|
|
121
|
+
// controlStyle: 'max-width: 150px',
|
|
122
|
+
align: 'center'
|
|
123
|
+
// sortable: !0
|
|
124
|
+
}
|
|
125
|
+
const opts = extend<ParseHeaderOptions>(!0, defaultOptions, options)
|
|
126
|
+
let control: string | undefined = defaultOptions.controlKey
|
|
127
|
+
let controlStyle: string | undefined = defaultOptions.controlStyle
|
|
128
|
+
if (opts.controlKey) {
|
|
129
|
+
control = opts.controlKey
|
|
130
|
+
delete opts.controlKey
|
|
131
|
+
}
|
|
132
|
+
if (opts.controlStyle) {
|
|
133
|
+
controlStyle = opts.controlStyle
|
|
134
|
+
delete opts.controlStyle
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const result: MDtColumn[] = []
|
|
138
|
+
|
|
139
|
+
headers.forEach((elm: string | MDtColumn | undefined) => {
|
|
140
|
+
if (typeof elm !== 'string' && !elm?.name) return elm
|
|
141
|
+
// Todo: will do this
|
|
142
|
+
let item: MDtColumn = typeof elm === 'string' ? {
|
|
143
|
+
name: elm as string,
|
|
144
|
+
label: elm as string,
|
|
145
|
+
field: elm as string
|
|
146
|
+
} : { ...elm }
|
|
147
|
+
item.name = item.name ?? ''
|
|
148
|
+
item.label = (item.label === undefined || item.label === null) ? item.name : item.label
|
|
149
|
+
item.field = (item.field === undefined || item.field === null) ? item.name : item.field
|
|
150
|
+
item = {
|
|
151
|
+
...item,
|
|
152
|
+
name: Str.strBefore(Str.strBefore(item.name), 'ToString'),
|
|
153
|
+
label: (item.label !== undefined && item.label !== null) ? Str.strBefore(Str.strBefore(item.label), 'ToString') : item.label
|
|
154
|
+
}
|
|
155
|
+
const name = item.name
|
|
156
|
+
let k
|
|
157
|
+
if (te) {
|
|
158
|
+
if (te((k = `attributes.${item.label}`))) {
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
item.label = t(k)
|
|
162
|
+
} else if (te((k = `attributes.${lodash.snakeCase(item.label)}`))) {
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
item.label = t(k)
|
|
166
|
+
} else if (te((k = `attributes.${lodash.camelCase(item.label)}`))) {
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
item.label = t(k)
|
|
170
|
+
} else if (te((k = `attributes.${Str.pascalCase(item.label)}`))) {
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
item.label = t(k)
|
|
174
|
+
} else if (te((k = `choice.${lodash.pluralize(Str.pascalCase(item.label))}`))) {
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
176
|
+
// @ts-ignore
|
|
177
|
+
item.label = t(k, 2)
|
|
178
|
+
} else if (te((k = item.label))) {
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
item.label = t(k)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (name === control) {
|
|
186
|
+
if (controlStyle && !item.style) {
|
|
187
|
+
item.style = controlStyle + (item.style ? ` ${item.style}` : '')
|
|
188
|
+
}
|
|
189
|
+
item.headerClasses = (item.headerClasses ? item.headerClasses : '') + ' m--control-header'
|
|
190
|
+
item.headerClasses = item.headerClasses.trim()
|
|
191
|
+
item.sortable = !1
|
|
192
|
+
if (!item.align) {
|
|
193
|
+
item.align = 'right'
|
|
194
|
+
}
|
|
195
|
+
opts.classes = opts.classes || ''
|
|
196
|
+
if (typeof opts.classes === 'function') {
|
|
197
|
+
opts.classes = opts.classes()
|
|
198
|
+
}
|
|
199
|
+
opts.classes += ' m--control-cell'
|
|
200
|
+
opts.classes = opts.classes.trim()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
item = { ...opts, ...item }
|
|
204
|
+
|
|
205
|
+
if (item.sortable === undefined && (options.noSort ?? []).length > 0 && options.noSort?.includes(item.name)) {
|
|
206
|
+
item.sortable = !1
|
|
207
|
+
} else if (item.sortable === undefined) {
|
|
208
|
+
item.sortable = !0
|
|
209
|
+
}
|
|
210
|
+
result.push(item)
|
|
211
|
+
})
|
|
212
|
+
return lodash.uniqBy(result, (e: MDtColumn) => e.name)
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Copy text
|
|
216
|
+
* @param text
|
|
217
|
+
*/
|
|
218
|
+
const copyText = async (text: string | any) => copyToClipboard(text)
|
|
219
|
+
|
|
220
|
+
const quasarNotifyOptions = (opts: QNotifyCreateOptions | string): QNotifyCreateOptions => {
|
|
221
|
+
return {
|
|
222
|
+
badgeColor: 'primary',
|
|
223
|
+
progress: !0,
|
|
224
|
+
...pluginOptions.value.notify as any,
|
|
225
|
+
message: typeof opts === 'string' ? opts : opts.message,
|
|
226
|
+
...(typeof opts !== 'string' ? opts : {})
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const alertMessage = (opts: Vue3MAlertMessageOptions): Vue3MAlertMessage => {
|
|
230
|
+
return q.notify(quasarNotifyOptions(opts))
|
|
231
|
+
}
|
|
232
|
+
const alertSuccess = (message: string) => {
|
|
233
|
+
return alertMessage({ type: 'positive', message })
|
|
234
|
+
}
|
|
235
|
+
const alertError = (message: string) => {
|
|
236
|
+
return alertMessage({ type: 'negative', message })
|
|
237
|
+
}
|
|
238
|
+
const confirmMessage = (message?: string, title?: string, opts?: QDialogOptions): Vue3MConfirmMessage => {
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
title = title || t('messages.are_you_sure') || ''
|
|
242
|
+
message = message || ''
|
|
243
|
+
opts = opts || {}
|
|
244
|
+
const buttonsProps = {
|
|
245
|
+
...pluginOptions.value.btn,
|
|
246
|
+
...pluginOptions.value.confirmDialogOptions?.buttons
|
|
247
|
+
}
|
|
248
|
+
const okProps = pluginOptions.value.confirmDialogOptions?.okProps || {}
|
|
249
|
+
const cancelProps = pluginOptions.value.confirmDialogOptions?.cancelProps || {}
|
|
250
|
+
const dialogProps = pluginOptions.value.confirmDialog || {} as any
|
|
251
|
+
dialogProps.transitionShow = dialogProps.transitionShow || 'jump-down'
|
|
252
|
+
dialogProps.transitionHide = dialogProps.transitionHide || 'jump-up'
|
|
253
|
+
dialogProps.class = ('m--confirm ') + (dialogProps.class || '')
|
|
254
|
+
return q.dialog({
|
|
255
|
+
title,
|
|
256
|
+
message,
|
|
257
|
+
focus: 'none',
|
|
258
|
+
cancel: {
|
|
259
|
+
color: cancelProps.color || 'positive',
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
label: t(cancelProps?.label || 'no'),
|
|
263
|
+
...buttonsProps as any,
|
|
264
|
+
flat: !0,
|
|
265
|
+
unelevated: !0,
|
|
266
|
+
...cancelProps as any
|
|
267
|
+
},
|
|
268
|
+
ok: {
|
|
269
|
+
color: okProps.color || 'negative',
|
|
270
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
271
|
+
// @ts-ignore
|
|
272
|
+
label: t(okProps?.label || 'yes'),
|
|
273
|
+
...buttonsProps as any,
|
|
274
|
+
flat: !0,
|
|
275
|
+
unelevated: !0,
|
|
276
|
+
...okProps as any
|
|
277
|
+
},
|
|
278
|
+
persistent: !0,
|
|
279
|
+
...dialogProps as any,
|
|
280
|
+
...opts as any
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
const api = computed(() => myth.api.value)
|
|
284
|
+
const baseUrl = computed(() => myth.baseUrl.value)
|
|
285
|
+
const mAxios = computed(() => myth.mAxios.value)
|
|
286
|
+
const mOptions = computed(() => myth.props.value)
|
|
287
|
+
const isSmall = computed(() => q.screen.lt.md)
|
|
288
|
+
const themeInput = computed(() => myth.themeInput.value)
|
|
289
|
+
const themeBtn = computed(() => myth.themeBtn.value)
|
|
290
|
+
return {
|
|
291
|
+
api,
|
|
292
|
+
baseUrl,
|
|
293
|
+
mAxios,
|
|
294
|
+
mOptions,
|
|
295
|
+
themeInput,
|
|
296
|
+
themeBtn,
|
|
297
|
+
__,
|
|
298
|
+
getPageTitle,
|
|
299
|
+
parseHeaders,
|
|
300
|
+
copyText,
|
|
301
|
+
quasarNotifyOptions,
|
|
302
|
+
alertMessage,
|
|
303
|
+
alertSuccess,
|
|
304
|
+
alertError,
|
|
305
|
+
confirmMessage,
|
|
306
|
+
...Helpers,
|
|
307
|
+
...Str,
|
|
308
|
+
veeRules,
|
|
309
|
+
isSmall
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { computed, MaybeRefOrGetter } from 'vue'
|
|
2
|
+
import { useFieldValue, useSetFieldValue } from 'vee-validate'
|
|
3
|
+
|
|
4
|
+
export const useValue = <T = any> (name: MaybeRefOrGetter<string>) => {
|
|
5
|
+
const [value, setValue] = [useFieldValue<T>(name), useSetFieldValue<T>(name)]
|
|
6
|
+
const field = computed<T>({
|
|
7
|
+
get: () => value.value,
|
|
8
|
+
set: (v: T) => setValue(v)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
return { field, value, setValue }
|
|
12
|
+
}
|