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