asb_cloud_front/src/components/factory.ts

132 lines
4.0 KiB
TypeScript
Raw Normal View History

import { notification } from 'antd'
import { ArgsProps } from 'antd/lib/notification'
import { Dispatch, ReactNode, SetStateAction } from 'react'
import { FunctionalValue, getFunctionalValue, isDev } from '@utils'
import { getUserToken } from '@utils'
import { ApiError, FileInfoDto } from '@api'
export type NotifyType = 'error' | 'warning' | 'info'
const notifyTypes: Record<NotifyType | 'defualt', ArgsProps & { instance: (args: ArgsProps) => void }> = {
error: { instance: notification.error, message: 'Ошибка' },
warning: { instance: notification.warning, message: 'Предупреждение' },
info: { instance: notification.info, message: 'Инфо' },
defualt: { instance: notification.info, message: '' },
}
/**
* Вызов оповещений всплывающим окошком.
* @param body string или ReactNode
* @param notifyType для параметра типа. Допустимые значение 'error', 'warning', 'info'
* @param other прочие возможные аргументы уведомления
2021-07-30 16:13:26 +05:00
*/
export const notify = (body?: ReactNode, notifyType: NotifyType = 'info', other?: ArgsProps) => {
if (!body) return
const instance = notifyTypes[notifyType] ?? notifyTypes.defualt
instance?.instance({
description: body,
placement: 'bottomRight',
duration: 10,
...instance,
...other
})
2021-08-13 14:46:22 +05:00
}
type asyncFunction = (...args: any) => Promise<any|void>
2021-08-13 14:46:22 +05:00
const parseApiEror = (err: unknown, actionName?: string) => {
if (!(err instanceof ApiError)) return false
switch (err.status) {
case 403:
if (actionName)
notify(`Недостаточно прав для выполнения действия "${actionName}"`, 'error')
else
notify('Недостаточно прав для выполнения действия', 'error')
return true
case 204: return true
default: return false
}
}
export const invokeWebApiWrapperAsync = async (
funcAsync: asyncFunction,
setShowLoader?: Dispatch<SetStateAction<boolean>>,
errorNotifyText?: FunctionalValue<ReactNode, [unknown]>,
actionName?: string,
) => {
setShowLoader?.(true)
2021-08-13 14:46:22 +05:00
try{
await funcAsync()
} catch (ex) {
if(isDev())
console.error(ex)
if (!parseApiEror(ex, actionName))
notify(getFunctionalValue(errorNotifyText)(ex), 'error')
} finally {
setShowLoader?.(false)
2021-08-13 14:46:22 +05:00
}
2021-08-17 10:46:10 +05:00
}
export const download = async (url: string, fileName?: string) => {
2021-08-17 10:46:10 +05:00
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${getUserToken()}`
2021-08-17 10:46:10 +05:00
},
method: 'Get'
})
if(response.status !== 200)
throw response
const requestFileName = decodeURI(
fileName
?? response.headers.get('content-disposition')?.split(';').pop()?.split(`'`).pop()
?? url.replace('\\','/').split('/').pop()
?? 'file'
)
2021-08-17 10:46:10 +05:00
const blob = await response.blob()
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = (e) => {
const a = document.createElement('a')
a.href = (e.target?.result?.toString() ?? '')
a.download = requestFileName
document.body.appendChild(a) // we need to append the element to the dom -> otherwise it will not work in firefox
a.click()
a.remove()
}
2021-08-17 10:46:10 +05:00
}
export const upload = async (url: string, formData: FormData) => {
const response = await fetch(url, {
2021-08-17 10:46:10 +05:00
headers: {
Authorization: `Bearer ${getUserToken()}`
2021-08-17 10:46:10 +05:00
},
method: 'Post',
body: formData,
})
2021-10-11 13:41:54 +05:00
return response
2021-08-31 12:30:44 +05:00
}
export const downloadFile = async (fileInfo: FileInfoDto) => {
try {
await download(`/api/well/${fileInfo.idWell}/files/${fileInfo.id}`)
return true
} catch (error) {
notify(`Не удалось скачать файл "${fileInfo.name}" по скважине №${fileInfo.idWell}`, 'error')
console.log(error)
return false
}
}
export const formatBytes = (bytes: number) => {
2021-08-31 12:30:44 +05:00
if(bytes < 1024)
return `${bytes.toFixed(0)}b`
if(bytes < 1024 * 1024)
return `${(bytes / 1024).toFixed(2)}kb`
2021-08-31 12:30:44 +05:00
else
return `${(bytes / 1024 / 1024).toFixed(2)}Mb`
2021-09-23 14:18:46 +05:00
}