@mythpe/quasar-ui-qui 0.0.23-dev → 0.0.24-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 +4 -0
- package/package.json +8 -5
- package/src/components/form/MAvatarViewer.vue +324 -0
- package/src/components/form/MBtn.vue +258 -91
- package/src/components/form/MCheckbox.vue +123 -0
- package/src/components/form/MColor.vue +122 -0
- package/src/components/form/MDate.vue +47 -0
- package/src/components/form/MEditor.vue +285 -0
- package/src/components/form/MEmail.vue +40 -0
- package/src/components/form/MField.vue +142 -0
- package/src/components/form/MFile.vue +209 -0
- package/src/components/form/MForm.vue +83 -0
- package/src/components/form/MHidden.vue +83 -0
- package/src/components/form/MHiddenInput.vue +55 -0
- package/src/components/form/MInput.vue +62 -65
- package/src/components/form/MInputFieldControl.vue +4 -1
- package/src/components/form/MInputLabel.vue +6 -2
- package/src/components/form/MMobile.vue +37 -0
- package/src/components/form/MPicker.vue +310 -0
- package/src/components/form/MRadio.vue +175 -0
- package/src/components/form/MSelect.vue +343 -0
- package/src/components/form/MTime.vue +45 -0
- package/src/components/form/index.ts +38 -1
- package/src/components/grid/MBlock.vue +31 -17
- package/src/components/grid/MCol.vue +2 -14
- package/src/components/grid/MContainer.vue +21 -12
- package/src/components/grid/MHelpRow.vue +4 -9
- package/src/components/grid/MRow.vue +22 -9
- package/src/components/index.ts +1 -0
- package/src/components/transition/MFadeTransition.vue +27 -0
- package/src/components/transition/MFadeXTransition.vue +26 -0
- package/src/components/transition/MTransition.vue +41 -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} +92 -62
- package/src/composable/useError.ts +11 -0
- package/src/composable/useMyth.ts +280 -3
- package/src/composable/useValue.ts +12 -0
- package/src/index.sass +7 -33
- package/src/style/m-container.sass +13 -0
- package/src/style/main.sass +42 -0
- package/src/types/api-helpers.d.ts +120 -0
- package/src/types/components.d.ts +550 -52
- package/src/types/dt.d.ts +142 -0
- package/src/types/index.d.ts +128 -47
- package/src/types/lodash.d.ts +26 -0
- package/src/types/quasar-helpers.d.ts +7 -0
- package/src/types/theme.d.ts +12 -0
- package/src/utils/Helpers.ts +321 -0
- package/src/utils/Str.ts +210 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/myth.ts +75 -22
- package/src/utils/vee-rules.ts +2 -1
- package/src/utils/vue-plugin.ts +80 -3
- package/tsconfig.json +8 -11
|
@@ -0,0 +1,321 @@
|
|
|
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 { AxiosInstance, AxiosRequestConfig } from 'axios'
|
|
10
|
+
import lodash from 'lodash'
|
|
11
|
+
import { openURL, scroll } from 'quasar'
|
|
12
|
+
import type {
|
|
13
|
+
ConfigType,
|
|
14
|
+
DownloadFromResponse,
|
|
15
|
+
DownloadFromResponseCode,
|
|
16
|
+
HelpersStubSchema,
|
|
17
|
+
ParamsType,
|
|
18
|
+
UrlType
|
|
19
|
+
} from '../types'
|
|
20
|
+
|
|
21
|
+
import { nextTick } from 'vue'
|
|
22
|
+
|
|
23
|
+
export const Helpers = {
|
|
24
|
+
appendArray (formData: FormData, values: File | Blob | Record<string, any> | any, name?: string | null | undefined) {
|
|
25
|
+
let value: never | any
|
|
26
|
+
if ((values instanceof File || values instanceof Blob) && name) {
|
|
27
|
+
const _name = values instanceof File ? values.name : name
|
|
28
|
+
formData.append(name, values, _name)
|
|
29
|
+
} else {
|
|
30
|
+
for (const key in values) {
|
|
31
|
+
value = values[key]
|
|
32
|
+
if (value !== null && value !== undefined && typeof value === 'object') {
|
|
33
|
+
const k = name ? name + '[' + key + ']' : key
|
|
34
|
+
if (lodash.isArray(value) && value.length < 1) {
|
|
35
|
+
formData.append(`${key}`, '')
|
|
36
|
+
} else {
|
|
37
|
+
this.appendArray(formData, value, k)
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
if (value === !0) {
|
|
41
|
+
value = 1
|
|
42
|
+
}
|
|
43
|
+
if (value === false) {
|
|
44
|
+
value = 0
|
|
45
|
+
}
|
|
46
|
+
if (value === null || value === undefined) {
|
|
47
|
+
value = ''
|
|
48
|
+
// console.log('null----', name,key, value)
|
|
49
|
+
}
|
|
50
|
+
// if (value !== undefined) {
|
|
51
|
+
if (name) {
|
|
52
|
+
formData.append(name + '[' + key + ']', value)
|
|
53
|
+
} else {
|
|
54
|
+
formData.append(key, value)
|
|
55
|
+
}
|
|
56
|
+
// }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return formData
|
|
61
|
+
},
|
|
62
|
+
Stub (baseUrl: UrlType, axios: () => AxiosInstance): HelpersStubSchema {
|
|
63
|
+
const makeUrl = Helpers.StubUrl(baseUrl)
|
|
64
|
+
return {
|
|
65
|
+
async index (config?: ConfigType) {
|
|
66
|
+
const u = makeUrl()
|
|
67
|
+
return axios().get(u, config)
|
|
68
|
+
// return typeof config === 'boolean' ? u : axios().get(u, config)
|
|
69
|
+
},
|
|
70
|
+
async staticIndex (config?: ConfigType) {
|
|
71
|
+
const u = `Static${baseUrl ? `/${baseUrl}` : ''}`
|
|
72
|
+
return axios().get(u, config)
|
|
73
|
+
// config = config || {}
|
|
74
|
+
// config.params = {
|
|
75
|
+
// page: 1,
|
|
76
|
+
// itemsPerPage: -1,
|
|
77
|
+
// ...(config.params ?? {})
|
|
78
|
+
// }
|
|
79
|
+
// return axios().get(u, config)
|
|
80
|
+
},
|
|
81
|
+
async export (data?: ParamsType, config?: AxiosRequestConfig) {
|
|
82
|
+
return axios().post(makeUrl('Export'), data, config)
|
|
83
|
+
},
|
|
84
|
+
async store (data?: ParamsType, config?: AxiosRequestConfig) {
|
|
85
|
+
const u = makeUrl()
|
|
86
|
+
// if (typeof data === 'boolean') {
|
|
87
|
+
// return u
|
|
88
|
+
// }
|
|
89
|
+
const formData = new FormData()
|
|
90
|
+
data && Helpers.appendArray(formData, data)
|
|
91
|
+
return axios().post(u, formData, config)
|
|
92
|
+
},
|
|
93
|
+
async show (id: UrlType, config?: AxiosRequestConfig) {
|
|
94
|
+
const u = makeUrl(id)
|
|
95
|
+
return axios().get(u, config)
|
|
96
|
+
// return typeof id === 'boolean' ? u : axios().get(u, config)
|
|
97
|
+
},
|
|
98
|
+
async staticShow (id: UrlType, config?: AxiosRequestConfig) {
|
|
99
|
+
// const m = baseUrl ? baseUrl.toString().split('/').pop() : ''
|
|
100
|
+
// const u = 'Static' + (m ? `/${m}` : '') + `/${id}`
|
|
101
|
+
const u = `Static${baseUrl ? `/${baseUrl}` : ''}` + `/${id}`
|
|
102
|
+
// if (typeof id === 'boolean') {
|
|
103
|
+
// return u
|
|
104
|
+
// }
|
|
105
|
+
return axios().get(u, config)
|
|
106
|
+
},
|
|
107
|
+
async update (id: UrlType, data?: ParamsType, config?: AxiosRequestConfig) {
|
|
108
|
+
const u = makeUrl(id)
|
|
109
|
+
// if (typeof id === 'boolean') {
|
|
110
|
+
// return u
|
|
111
|
+
// }
|
|
112
|
+
const formData = new FormData()
|
|
113
|
+
formData.append('_method', 'put')
|
|
114
|
+
data && Helpers.appendArray(formData, data)
|
|
115
|
+
return axios().post(u, formData, config)
|
|
116
|
+
},
|
|
117
|
+
async destroy (id: UrlType, config?: AxiosRequestConfig) {
|
|
118
|
+
const u = makeUrl(id)
|
|
119
|
+
return axios().delete(u, config)
|
|
120
|
+
// return typeof id === 'boolean' ? u : axios().delete(u, config)
|
|
121
|
+
},
|
|
122
|
+
async destroyAll (ids?: UrlType[], config?: AxiosRequestConfig) {
|
|
123
|
+
const u = makeUrl('DestroyAll')
|
|
124
|
+
return axios().post(u, { ids: (ids || []) }, config)
|
|
125
|
+
},
|
|
126
|
+
getUploadAttachmentsUrl: (id: UrlType) => makeUrl(`${id}/Attachment/Upload`),
|
|
127
|
+
async uploadAttachments (id: UrlType, data: Record<string, any>, config?: AxiosRequestConfig) {
|
|
128
|
+
const _url = makeUrl(`${id}/Attachment/Upload`)
|
|
129
|
+
return axios().post(_url, data, config)
|
|
130
|
+
},
|
|
131
|
+
async deleteAttachment (id: UrlType, fileId: string | number, config?: AxiosRequestConfig) {
|
|
132
|
+
const _url = makeUrl(`${id}/Attachment/${fileId}/Delete`)
|
|
133
|
+
return axios().delete(_url, config)
|
|
134
|
+
},
|
|
135
|
+
async updateAttachment (id: UrlType, fileId: string | number, data: Record<string, any>, config?: AxiosRequestConfig) {
|
|
136
|
+
const _url = makeUrl(`${id}/Attachment/${fileId}/Update`)
|
|
137
|
+
return axios().post(_url, data, config)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
StubUrl: (group?: UrlType): ((segments?: UrlType, parent?: UrlType) => string) => (
|
|
142
|
+
segments?: UrlType,
|
|
143
|
+
parent?: UrlType
|
|
144
|
+
): string => ((parent ?? '') + (parent && group ? '/' : '')) + (group ?? '') + ((group && segments ? '/' : '') + (segments ?? '')),
|
|
145
|
+
findBy (search: any, value: any, column: string | number = 'id') {
|
|
146
|
+
return lodash.find(search, (e: any) => lodash.isPlainObject(e) ? e[column] === value : e === value)
|
|
147
|
+
},
|
|
148
|
+
// queryStringify: (v: never) => new URLSearchParams(qs.stringify(v, {
|
|
149
|
+
// arrayFormat: 'indices'
|
|
150
|
+
// // encodeValuesOnly: true,
|
|
151
|
+
// // encode: false,
|
|
152
|
+
// })),
|
|
153
|
+
/**
|
|
154
|
+
* Open unique window popup of application
|
|
155
|
+
*
|
|
156
|
+
* @param url
|
|
157
|
+
* @param reject
|
|
158
|
+
* @param windowFeatures
|
|
159
|
+
*/
|
|
160
|
+
openWindow<F extends (...args: any[]) => any> (url: string, reject?: F, windowFeatures?: object) {
|
|
161
|
+
return openURL(url, reject, windowFeatures)
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Customized helper to download blob from axios response
|
|
165
|
+
* @param response
|
|
166
|
+
* @param callback
|
|
167
|
+
*/
|
|
168
|
+
downloadFromResponse (response: any, callback?: ((url: string, response: any) => void)) {
|
|
169
|
+
return new Promise<DownloadFromResponse>((resolve, reject) => {
|
|
170
|
+
const rejectPromise = (e?: { code: DownloadFromResponseCode }) => reject(e ?? { status: !1, code: 'unknown' })
|
|
171
|
+
const resolvePromise = (response: DownloadFromResponse['response']) => resolve({ status: !0, response })
|
|
172
|
+
try {
|
|
173
|
+
if (!response) {
|
|
174
|
+
rejectPromise({ code: 'no_response' })
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (response?.data?.data?.url) {
|
|
179
|
+
const url = response?.data?.data?.url
|
|
180
|
+
if (callback) {
|
|
181
|
+
callback(url, response)
|
|
182
|
+
resolvePromise(response)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
const elm = document.createElement('a')
|
|
186
|
+
elm.setAttribute('href', url)
|
|
187
|
+
elm.setAttribute('target', '_blank')
|
|
188
|
+
document.body.appendChild(elm)
|
|
189
|
+
elm.click()
|
|
190
|
+
resolvePromise(response)
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const name = (response.headers['content-disposition'] || '').split('filename=').pop().replace(/^"+|"+$/g, '')
|
|
195
|
+
if (!name) {
|
|
196
|
+
rejectPromise({ code: 'no_file_name' })
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
const file = new Blob([response.data])
|
|
200
|
+
const fileURL = window.URL.createObjectURL(file)
|
|
201
|
+
const fileLink = document.createElement('a')
|
|
202
|
+
if (!fileLink || !fileURL) {
|
|
203
|
+
rejectPromise({ code: 'no_file_url' })
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
fileLink.href = fileURL
|
|
208
|
+
fileLink.setAttribute('download', name)
|
|
209
|
+
document.body.appendChild(fileLink)
|
|
210
|
+
fileLink.click()
|
|
211
|
+
resolvePromise(response)
|
|
212
|
+
setTimeout(() => {
|
|
213
|
+
try {
|
|
214
|
+
document.body.removeChild(fileLink)
|
|
215
|
+
URL.revokeObjectURL(fileURL)
|
|
216
|
+
} catch (e: any) {
|
|
217
|
+
console.log(e)
|
|
218
|
+
if (e?.message) {
|
|
219
|
+
alert(e.message)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}, 3000)
|
|
223
|
+
} catch (e: any) {
|
|
224
|
+
console.log(e)
|
|
225
|
+
rejectPromise(e)
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
},
|
|
229
|
+
async scrollToElement (el: HTMLElement | string, opt?: { target?: HTMLElement | string, duration?: number; }) {
|
|
230
|
+
await nextTick()
|
|
231
|
+
const { getScrollTarget, setVerticalScrollPosition, getVerticalScrollPosition } = scroll
|
|
232
|
+
const scrollTo = typeof el === 'string' ? document.querySelector(el) as HTMLElement : el
|
|
233
|
+
if (!scrollTo) {
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
await nextTick()
|
|
237
|
+
const { target: t } = opt || {}
|
|
238
|
+
const targetSelector = typeof t === 'string' ? document.querySelector(t) as HTMLElement : t
|
|
239
|
+
const target = getScrollTarget(scrollTo, targetSelector || window.document.documentElement)
|
|
240
|
+
// console.log(targetSelector, target)
|
|
241
|
+
// let offset = 0
|
|
242
|
+
// try {
|
|
243
|
+
// let parent = scrollTo
|
|
244
|
+
// do {
|
|
245
|
+
// // console.log(parent.getBoundingClientRect().top)
|
|
246
|
+
// offset += parent?.offsetTop || 0
|
|
247
|
+
// parent = parent.offsetParent as HTMLElement
|
|
248
|
+
// } while (parent?.offsetParent)
|
|
249
|
+
// } catch (e) {
|
|
250
|
+
// offset = scrollTo?.offsetTop || 0
|
|
251
|
+
// }
|
|
252
|
+
// offset = scrollTo.getBoundingClientRect().top
|
|
253
|
+
const current = getVerticalScrollPosition(target)
|
|
254
|
+
// console.log(current, target)
|
|
255
|
+
// const offset = scrollTo.getBoundingClientRect().top
|
|
256
|
+
const duration = opt?.duration || 1000
|
|
257
|
+
|
|
258
|
+
let offset = 0
|
|
259
|
+
let parent = scrollTo
|
|
260
|
+
try {
|
|
261
|
+
do {
|
|
262
|
+
offset = parent.getBoundingClientRect().top
|
|
263
|
+
if (offset === 0 && !parent.parentElement) {
|
|
264
|
+
offset = parent.scrollTop
|
|
265
|
+
break
|
|
266
|
+
} else if (offset !== 0 && parent.parentElement) {
|
|
267
|
+
break
|
|
268
|
+
}
|
|
269
|
+
parent = parent.parentElement as HTMLElement
|
|
270
|
+
} while (parent)
|
|
271
|
+
} catch (e) {
|
|
272
|
+
console.log(e)
|
|
273
|
+
offset = scrollTo?.offsetTop || 0
|
|
274
|
+
}
|
|
275
|
+
// console.log(offset, parent, current)
|
|
276
|
+
// const position = offset
|
|
277
|
+
// if (offset > current) {
|
|
278
|
+
// position = (current - offset) + current
|
|
279
|
+
// } else if (offset < current) {
|
|
280
|
+
// position = current + offset
|
|
281
|
+
// }
|
|
282
|
+
// console.log({
|
|
283
|
+
// target,
|
|
284
|
+
// scrollTo,
|
|
285
|
+
// position,
|
|
286
|
+
// offset,
|
|
287
|
+
// current
|
|
288
|
+
// })
|
|
289
|
+
setVerticalScrollPosition(target, (offset + current) - 100, duration)
|
|
290
|
+
},
|
|
291
|
+
async scrollToElementFromErrors (errors?: Partial<Record<string, string[] | string | null | undefined>>, elm?: any, target?: any) {
|
|
292
|
+
if (!errors) {
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
for (const [name, value] of Object.entries(errors)) {
|
|
296
|
+
const val = value && Array.isArray(value) ? value[0] : value
|
|
297
|
+
if (val?.toString?.()?.length) {
|
|
298
|
+
if (!elm) {
|
|
299
|
+
const selector = `[data-input-name='${name}']`
|
|
300
|
+
const e = document.querySelector(selector) as HTMLElement
|
|
301
|
+
// console.log(e)
|
|
302
|
+
await this.scrollToElement(e || `[name='${name}']`, { target })
|
|
303
|
+
} else {
|
|
304
|
+
await this.scrollToElement(elm, { target })
|
|
305
|
+
}
|
|
306
|
+
break
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
makeUrl (path: string) {
|
|
311
|
+
path = path || ''
|
|
312
|
+
if (path.slice(0, 1) === '/') {
|
|
313
|
+
path = path.slice(1)
|
|
314
|
+
}
|
|
315
|
+
if (window) {
|
|
316
|
+
const l = window.location
|
|
317
|
+
return `${l.protocol}//${l.host}/${path}`
|
|
318
|
+
}
|
|
319
|
+
return `//${path}`
|
|
320
|
+
}
|
|
321
|
+
}
|
package/src/utils/Str.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
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 _ from 'lodash'
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
import inflection from 'lodash-inflection'
|
|
13
|
+
_.mixin(inflection)
|
|
14
|
+
|
|
15
|
+
export const Str = {
|
|
16
|
+
/**
|
|
17
|
+
* Str vue3
|
|
18
|
+
* @param str
|
|
19
|
+
* @param needle
|
|
20
|
+
*/
|
|
21
|
+
strBefore (str: string, needle = '_to_string'): string {
|
|
22
|
+
if (!str) {
|
|
23
|
+
return ''
|
|
24
|
+
}
|
|
25
|
+
if (str.slice(-needle.length) === needle) {
|
|
26
|
+
str = str.slice(0, str.length - needle.length)
|
|
27
|
+
}
|
|
28
|
+
return str
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Str to number format
|
|
32
|
+
* @param num
|
|
33
|
+
* @param c
|
|
34
|
+
*/
|
|
35
|
+
toNumberFormat (num = null, c: any) {
|
|
36
|
+
if (!num) {
|
|
37
|
+
// console.log(num)
|
|
38
|
+
return num
|
|
39
|
+
}
|
|
40
|
+
const splitArray: any = Str.toNumber(num).split('.')
|
|
41
|
+
const rgx = /(\d+)(\d{3})/
|
|
42
|
+
while (rgx.test(splitArray[0])) {
|
|
43
|
+
splitArray[0] = splitArray[0].replace(rgx, '$1' + ',' + '$2')
|
|
44
|
+
}
|
|
45
|
+
let t = splitArray.join('.')
|
|
46
|
+
if (c) t = `${t} ${c}`
|
|
47
|
+
return t
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Convert To string
|
|
51
|
+
* @param value
|
|
52
|
+
*/
|
|
53
|
+
fromArabicNumber (value: any): string {
|
|
54
|
+
if (!value) return ''
|
|
55
|
+
value = value?.toString().replace(/٠/g, 0).replace(/١/g, 1).replace(/٢/g, 2).replace(/٣/g, 3).replace(/٤/g, 4).replace(/٥/g, 5).replace(/٦/g,
|
|
56
|
+
6).replace(/٧/g, 7).replace(/٨/g, 8).replace(/٩/g, 9)
|
|
57
|
+
|
|
58
|
+
return '' + (value || '')
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* Str to number 'return string'
|
|
62
|
+
* @param n
|
|
63
|
+
*/
|
|
64
|
+
toNumber (n: string | null | undefined | number): string {
|
|
65
|
+
if (!n) return ''
|
|
66
|
+
n = '' + n
|
|
67
|
+
n = Str.fromArabicNumber(n)
|
|
68
|
+
n = n.replace(/,/g, '')
|
|
69
|
+
return '' + n
|
|
70
|
+
},
|
|
71
|
+
isKsaMobile (mobile: string | null) {
|
|
72
|
+
mobile = Str.fromArabicNumber(mobile) || ''
|
|
73
|
+
if (!mobile) return !1
|
|
74
|
+
const c1 = mobile.slice(0, 2)
|
|
75
|
+
// const c2 = parseInt(mobile.substr(0, 1))
|
|
76
|
+
return mobile && (mobile.length === 10 && (c1 === '05' || parseInt(c1) === 5))
|
|
77
|
+
// return mobile && ((mobile.length === 10 && (c1 === '05' || parseInt(c1) === 5)) || (mobile.length === 9 && c2 === 5))
|
|
78
|
+
},
|
|
79
|
+
pascalCase (string?: string): string {
|
|
80
|
+
if (!_.pascalCase) {
|
|
81
|
+
_.mixin({ pascalCase: _.flow(_.camelCase, _.upperFirst) })
|
|
82
|
+
}
|
|
83
|
+
return _.pascalCase(string)
|
|
84
|
+
},
|
|
85
|
+
pluralize (string?: string): string {
|
|
86
|
+
return _.pluralize(string)
|
|
87
|
+
},
|
|
88
|
+
singular (string?: string): string {
|
|
89
|
+
return _.singularize(string)
|
|
90
|
+
},
|
|
91
|
+
flipChoice (data: Record<any, any>) {
|
|
92
|
+
const f: Record<any, any> = {}
|
|
93
|
+
for (const a in data) {
|
|
94
|
+
let c
|
|
95
|
+
c = data[a].split('|')
|
|
96
|
+
c = [c[1], c[0]].join('|')
|
|
97
|
+
f[a] = c
|
|
98
|
+
}
|
|
99
|
+
return f
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* Remove 'الـ' from words
|
|
104
|
+
* Example: الغرب => غرب
|
|
105
|
+
*
|
|
106
|
+
* @param words
|
|
107
|
+
* @param locale
|
|
108
|
+
*/
|
|
109
|
+
wordsWithoutThe<T extends string = any> (words: any, locale: string): string | T {
|
|
110
|
+
if (words && locale?.toString()?.toLowerCase() === 'ar') {
|
|
111
|
+
const e = words.split(' ')
|
|
112
|
+
for (const i in e) {
|
|
113
|
+
if (e[i].slice(0, 2) === 'ال') {
|
|
114
|
+
e[i] = e[i].slice(2)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
words = e.join(' ')
|
|
118
|
+
}
|
|
119
|
+
return words
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* Add 'الـ' to words
|
|
124
|
+
*
|
|
125
|
+
* Example: غرب => الغرب
|
|
126
|
+
*
|
|
127
|
+
* @param words
|
|
128
|
+
* @param locale
|
|
129
|
+
*/
|
|
130
|
+
wordsWithThe<T extends string = any> (words: any, locale: string): string | T {
|
|
131
|
+
if (words && locale?.toString()?.toLowerCase() === 'ar') {
|
|
132
|
+
let i
|
|
133
|
+
const e = words.split(' ')
|
|
134
|
+
if (e[e.length - 1].slice(0, 2) === 'ال') {
|
|
135
|
+
return words
|
|
136
|
+
}
|
|
137
|
+
for (i in e) {
|
|
138
|
+
if (e[i].slice(0, 2) !== 'ال') {
|
|
139
|
+
e[i] = 'ال' + e[i]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
words = e.join(' ')
|
|
143
|
+
}
|
|
144
|
+
return words
|
|
145
|
+
},
|
|
146
|
+
/**
|
|
147
|
+
* Example: غرب => 'الغربي'
|
|
148
|
+
* @param words
|
|
149
|
+
* @param locale
|
|
150
|
+
*/
|
|
151
|
+
wordsToSingle<T extends string = any> (words: any, locale: string): string | T {
|
|
152
|
+
if (words && locale?.toString()?.toLowerCase() === 'ar') {
|
|
153
|
+
let i
|
|
154
|
+
const e = words.split(' ')
|
|
155
|
+
for (i in e) {
|
|
156
|
+
if (e[i].slice(0, 2) !== 'ال') {
|
|
157
|
+
e[i] = 'ال' + e[i]
|
|
158
|
+
}
|
|
159
|
+
if (e[i].slice(-1) !== 'ي') {
|
|
160
|
+
e[i] += 'ي'
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
words = e.join(' ')
|
|
164
|
+
}
|
|
165
|
+
return words
|
|
166
|
+
},
|
|
167
|
+
/**
|
|
168
|
+
* Custom helper
|
|
169
|
+
* @param a
|
|
170
|
+
* @param b
|
|
171
|
+
*/
|
|
172
|
+
sortNumberFormatted (a: any, b: any) {
|
|
173
|
+
const f = parseFloat(Str.toNumber(a).replace(/[^\d]/g, '')) || 0
|
|
174
|
+
const s = parseFloat(Str.toNumber(b).replace(/[^\d]/g, '')) || 0
|
|
175
|
+
return f - s
|
|
176
|
+
},
|
|
177
|
+
/**
|
|
178
|
+
* Convert string new line to BR
|
|
179
|
+
* @param str
|
|
180
|
+
* @param isXhtml
|
|
181
|
+
*/
|
|
182
|
+
nl2br<T extends string = any> (str: any, isXhtml: (boolean | null | undefined) = !1): string | T {
|
|
183
|
+
if (!str) {
|
|
184
|
+
return str
|
|
185
|
+
}
|
|
186
|
+
const breakTag = (isXhtml || typeof isXhtml === 'undefined') ? '<br />' : '<br>'
|
|
187
|
+
return str?.toString?.()?.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, `$1${breakTag}$2`) || str
|
|
188
|
+
},
|
|
189
|
+
prettyPrint (string: any) {
|
|
190
|
+
const jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg
|
|
191
|
+
return JSON.stringify(string, null, 3)
|
|
192
|
+
.replace(/&/g, '&').replace(/\\"/g, '"')
|
|
193
|
+
.replace(/</g, '<').replace(/>/g, '>')
|
|
194
|
+
.replace(jsonLine, (match, pIndent, pKey, pVal, pEnd) => {
|
|
195
|
+
const key = '<span class="json-key" style="color: brown">'
|
|
196
|
+
const val = '<span class="json-value" style="color: navy">'
|
|
197
|
+
const str = '<span class="json-string" style="color: olive">'
|
|
198
|
+
let r = pIndent || ''
|
|
199
|
+
if (pKey) {
|
|
200
|
+
r = r + key + pKey.replace(/[": ]/g, '') + '</span>: '
|
|
201
|
+
}
|
|
202
|
+
if (pVal) {
|
|
203
|
+
r = r + (pVal[0] === '"' ? str : val) + pVal + '</span>'
|
|
204
|
+
}
|
|
205
|
+
return r + (pEnd || '')
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export default {}
|
package/src/utils/index.ts
CHANGED
package/src/utils/myth.ts
CHANGED
|
@@ -7,31 +7,84 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { ref } from 'vue'
|
|
10
|
-
import type { QBtnProps } from 'quasar'
|
|
11
10
|
import { extend } from 'quasar'
|
|
12
|
-
import type {
|
|
13
|
-
|
|
14
|
-
const defGutters = 'md'
|
|
15
|
-
const defaultOptions: UiOptionsContext = {
|
|
16
|
-
style: {
|
|
17
|
-
gutters: defGutters
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
const optionsRef = ref<UiOptionsContext>({ ...defaultOptions })
|
|
11
|
+
import type { BtnLoading, PropsContext, ThemeBtn, ThemeInput, ThemeRounded, ThemeShadow, ThemeSize } from '../types'
|
|
21
12
|
|
|
13
|
+
const props = ref<PropsContext>({})
|
|
14
|
+
const size = ref<ThemeSize>('md')
|
|
15
|
+
const rounded = ref<ThemeRounded>(!1)
|
|
16
|
+
const shadow = ref<ThemeShadow>(2)
|
|
17
|
+
const fluid = ref<boolean>(!1)
|
|
18
|
+
const rules = ref<string[]>([])
|
|
19
|
+
const btnLoading = ref<BtnLoading>({
|
|
20
|
+
type: 'spinner'
|
|
21
|
+
})
|
|
22
|
+
const themeBtn = ref<ThemeBtn>({})
|
|
23
|
+
const themeInput = ref<ThemeInput>({})
|
|
22
24
|
export const myth = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Apply Padding on all sides of components.
|
|
27
|
+
*/
|
|
28
|
+
// size: computed({
|
|
29
|
+
// get: () => size.value,
|
|
30
|
+
// set: v => (size.value = v)
|
|
31
|
+
// }),
|
|
32
|
+
size,
|
|
33
|
+
setSize (v: ThemeSize) {
|
|
34
|
+
size.value = v
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* Apply Fluid on all sides of containers.
|
|
38
|
+
*/
|
|
39
|
+
fluid,
|
|
40
|
+
setFluid (v: boolean) {
|
|
41
|
+
fluid.value = v
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Components Props.
|
|
45
|
+
*/
|
|
46
|
+
props,
|
|
47
|
+
setProps (values: Partial<PropsContext> | undefined) {
|
|
48
|
+
props.value = values ?? {}
|
|
49
|
+
},
|
|
50
|
+
withProps (values: Partial<PropsContext> | undefined) {
|
|
51
|
+
props.value = extend(!0, {}, props.value, values)
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* Rules keys that can be added to Input Rules as Vue Attr
|
|
55
|
+
*/
|
|
56
|
+
rules,
|
|
57
|
+
setRules (v: string[]) {
|
|
58
|
+
rules.value = v
|
|
59
|
+
},
|
|
60
|
+
withRules (v: string[]) {
|
|
61
|
+
rules.value = [...rules.value, ...v]
|
|
26
62
|
},
|
|
27
|
-
|
|
28
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Default loading q-btn loading slot.
|
|
65
|
+
*/
|
|
66
|
+
// btnLoading: computed({
|
|
67
|
+
// get: () => btnLoading.value,
|
|
68
|
+
// set: v => (btnLoading.value = v)
|
|
69
|
+
// }),
|
|
70
|
+
btnLoading,
|
|
71
|
+
setBtnLoading (v: BtnLoading) {
|
|
72
|
+
btnLoading.value = v
|
|
29
73
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Default Buttons style.
|
|
76
|
+
*/
|
|
77
|
+
themeBtn,
|
|
78
|
+
/**
|
|
79
|
+
* Default Inputs style.
|
|
80
|
+
*/
|
|
81
|
+
themeInput,
|
|
82
|
+
/**
|
|
83
|
+
* Theme Rounded.
|
|
84
|
+
*/
|
|
85
|
+
rounded,
|
|
86
|
+
/**
|
|
87
|
+
* Theme Shadow.
|
|
88
|
+
*/
|
|
89
|
+
shadow
|
|
37
90
|
}
|
package/src/utils/vee-rules.ts
CHANGED
|
@@ -12,7 +12,8 @@ import { patterns } from 'quasar'
|
|
|
12
12
|
const { testPattern } = patterns
|
|
13
13
|
|
|
14
14
|
export const veeRules = {
|
|
15
|
-
float: (v: any) => lodash.isNumber(parseInt(v)) && !isNaN(parseInt(v)) && v?.toString()
|
|
15
|
+
float: (v: any) => lodash.isNumber(parseInt(v)) && !isNaN(parseInt(v)) && v?.toString()
|
|
16
|
+
.split('.')?.length <= 2 && (/(\d)+/g.test(v) && !/[a-zA-Z]/.test(
|
|
16
17
|
v)),
|
|
17
18
|
date: (v: any) => /^-?[\d]+-[0-1]\d-[0-3]\d$/.test(v),
|
|
18
19
|
time: (v: any) => testPattern.time(v),
|