UNPKG

@mythpe/js-helpers

Version:

Library of plugins & shortcuts that use JavaScript, also includes the Vue3 plugin with quasar apps

316 lines (308 loc) 11.3 kB
/* * MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved. * Email: mythpe@gmail.com * Mobile: +966590470092 * Website: https://www.4myth.com * Github: https://github.com/mythpe */ import { AxiosInstance, AxiosRequestConfig } from 'axios' import lodash from 'lodash' import { openURL, scroll } from 'quasar' import { ConfigType, DownloadFromResponse, DownloadFromResponseCode, HelpersStubSchema, ParamsType, UrlType } from '../types' import { nextTick } from 'vue' export const Helpers = { appendArray (formData: FormData, values: File | Blob | Record<string, any> | any, name?: string | null | undefined) { let value: never | any if ((values instanceof File || values instanceof Blob) && name) { const _name = values instanceof File ? values.name : name formData.append(name, values, _name) } else { for (const key in values) { value = values[key] if (value !== null && value !== undefined && typeof value === 'object') { const k = name ? name + '[' + key + ']' : key if (lodash.isArray(value) && value.length < 1) { formData.append(`${key}`, '') } else { this.appendArray(formData, value, k) } } else { if (value === !0) { value = 1 } if (value === false) { value = 0 } if (value === null || value === undefined) { value = '' // console.log('null----', name,key, value) } // if (value !== undefined) { if (name) { formData.append(name + '[' + key + ']', value) } else { formData.append(key, value) } // } } } } return formData }, Stub (baseUrl: UrlType, axios: () => AxiosInstance): HelpersStubSchema { const makeUrl = Helpers.StubUrl(baseUrl) return { async index (config?: ConfigType) { const u = makeUrl() return axios().get(u, config) // return typeof config === 'boolean' ? u : axios().get(u, config) }, async staticIndex (config?: ConfigType) { const u = `Static${baseUrl ? `/${baseUrl}` : ''}` return axios().get(u, config) // config = config || {} // config.params = { // page: 1, // itemsPerPage: -1, // ...(config.params ?? {}) // } // return axios().get(u, config) }, async export (data?: ParamsType, config?: AxiosRequestConfig) { return axios().post(makeUrl('Export'), data, config) }, async store (data?: ParamsType, config?: AxiosRequestConfig) { const u = makeUrl() // if (typeof data === 'boolean') { // return u // } const formData = new FormData() data && Helpers.appendArray(formData, data) return axios().post(u, formData, config) }, async show (id: UrlType, config?: AxiosRequestConfig) { const u = makeUrl(id) return axios().get(u, config) // return typeof id === 'boolean' ? u : axios().get(u, config) }, async staticShow (id: UrlType, config?: AxiosRequestConfig) { // const m = baseUrl ? baseUrl.toString().split('/').pop() : '' // const u = 'Static' + (m ? `/${m}` : '') + `/${id}` const u = `Static${baseUrl ? `/${baseUrl}` : ''}` + `/${id}` // if (typeof id === 'boolean') { // return u // } return axios().get(u, config) }, async update (id: UrlType, data?: ParamsType, config?: AxiosRequestConfig) { const u = makeUrl(id) // if (typeof id === 'boolean') { // return u // } const formData = new FormData() formData.append('_method', 'put') data && Helpers.appendArray(formData, data) return axios().post(u, formData, config) }, async destroy (id: UrlType, config?: AxiosRequestConfig) { const u = makeUrl(id) return axios().delete(u, config) // return typeof id === 'boolean' ? u : axios().delete(u, config) }, async destroyAll (ids?: UrlType[], config?: AxiosRequestConfig) { const u = makeUrl('DestroyAll') return axios().post(u, { ids: (ids || []) }, config) }, getUploadAttachmentsUrl: (id: UrlType) => makeUrl(`${id}/Attachment/Upload`), async uploadAttachments (id: UrlType, data: Record<string, any>, config?: AxiosRequestConfig) { const _url = makeUrl(`${id}/Attachment/Upload`) return axios().post(_url, data, config) }, async deleteAttachment (id: UrlType, fileId: string | number, config?: AxiosRequestConfig) { const _url = makeUrl(`${id}/Attachment/${fileId}/Delete`) return axios().delete(_url, config) }, async updateAttachment (id: UrlType, fileId: string | number, data: Record<string, any>, config?: AxiosRequestConfig) { const _url = makeUrl(`${id}/Attachment/${fileId}/Update`) return axios().post(_url, data, config) } } }, StubUrl: (group?: UrlType): ((segments?: UrlType, parent?: UrlType) => string) => ( segments?: UrlType, parent?: UrlType ): string => ((parent ?? '') + (parent && group ? '/' : '')) + (group ?? '') + ((group && segments ? '/' : '') + (segments ?? '')), findBy (search: any, value: any, column: string | number = 'id') { return lodash.find(search, (e: any) => lodash.isPlainObject(e) ? e[column] === value : e === value) }, // queryStringify: (v: never) => new URLSearchParams(qs.stringify(v, { // arrayFormat: 'indices' // // encodeValuesOnly: true, // // encode: false, // })), /** * Open unique window popup of application * * @param url * @param reject * @param windowFeatures */ openWindow <F extends (...args: any[]) => any>(url: string, reject?: F, windowFeatures?: object) { return openURL(url, reject, windowFeatures) }, /** * Customized helper to download blob from axios response * @param response * @param callback */ downloadFromResponse (response: any, callback?: ((url: string, response: any) => void)) { return new Promise<DownloadFromResponse>((resolve, reject) => { const rejectPromise = (e?: { code: DownloadFromResponseCode }) => reject(e ?? { status: !1, code: 'unknown' }) const resolvePromise = (response: DownloadFromResponse['response']) => resolve({ status: !0, response }) try { if (!response) { rejectPromise({ code: 'no_response' }) return } if (response?.data?.data?.url) { const url = response?.data?.data?.url if (callback) { callback(url, response) resolvePromise(response) return } const elm = document.createElement('a') elm.setAttribute('href', url) elm.setAttribute('target', '_blank') document.body.appendChild(elm) elm.click() resolvePromise(response) return } const name = (response.headers['content-disposition'] || '').split('filename=').pop().replace(/^"+|"+$/g, '') if (!name) { rejectPromise({ code: 'no_file_name' }) return } const file = new Blob([response.data]) const fileURL = window.URL.createObjectURL(file) const fileLink = document.createElement('a') if (!fileLink || !fileURL) { rejectPromise({ code: 'no_file_url' }) return } fileLink.href = fileURL fileLink.setAttribute('download', name) document.body.appendChild(fileLink) fileLink.click() resolvePromise(response) setTimeout(() => { try { document.body.removeChild(fileLink) URL.revokeObjectURL(fileURL) } catch (e: any) { console.log(e) if (e?.message) { alert(e.message) } } }, 3000) } catch (e: any) { console.log(e) rejectPromise(e) } }) }, async scrollToElement (el: HTMLElement | string, opt?: { target?: HTMLElement | string, duration?: number; }) { await nextTick() const { getScrollTarget, setVerticalScrollPosition, getVerticalScrollPosition } = scroll const scrollTo = typeof el === 'string' ? document.querySelector(el) as HTMLElement : el if (!scrollTo) { return } await nextTick() const { target: t } = opt || {} const targetSelector = typeof t === 'string' ? document.querySelector(t) as HTMLElement : t const target = getScrollTarget(scrollTo, targetSelector || window.document.documentElement) // console.log(targetSelector, target) // let offset = 0 // try { // let parent = scrollTo // do { // // console.log(parent.getBoundingClientRect().top) // offset += parent?.offsetTop || 0 // parent = parent.offsetParent as HTMLElement // } while (parent?.offsetParent) // } catch (e) { // offset = scrollTo?.offsetTop || 0 // } // offset = scrollTo.getBoundingClientRect().top const current = getVerticalScrollPosition(target) // console.log(current, target) // const offset = scrollTo.getBoundingClientRect().top const duration = opt?.duration || 1000 let offset = 0 let parent = scrollTo try { do { offset = parent.getBoundingClientRect().top if (offset === 0 && !parent.parentElement) { offset = parent.scrollTop break } else if (offset !== 0 && parent.parentElement) { break } parent = parent.parentElement as HTMLElement } while (parent) } catch (e) { console.log(e) offset = scrollTo?.offsetTop || 0 } // console.log(offset, parent, current) // const position = offset // if (offset > current) { // position = (current - offset) + current // } else if (offset < current) { // position = current + offset // } // console.log({ // target, // scrollTo, // position, // offset, // current // }) setVerticalScrollPosition(target, (offset + current) - 100, duration) }, async scrollToElementFromErrors (errors?: Partial<Record<string, string[] | string | null | undefined>>, elm?: any, target?: any) { if (!errors) { return } for (const [name, value] of Object.entries(errors)) { const val = value && Array.isArray(value) ? value[0] : value if (val?.toString?.()?.length) { if (!elm) { const selector = `[data-input-name='${name}']` const e = document.querySelector(selector) as HTMLElement // console.log(e) await this.scrollToElement(e || `[name='${name}']`, { target }) } else { await this.scrollToElement(elm, { target }) } break } } }, makeUrl (path: string) { path = path || '' if (path.slice(0, 1) === '/') { path = path.slice(1) } if (window) { const l = window.location return `${l.protocol}//${l.host}/${path}` } return `//${path}` } } export default {}