forked from ddrilling/asb_cloud_front
fa751240ba
* Добавлено игнорирование кода 204 * less перенесён в dev зависимости
132 lines
4.0 KiB
TypeScript
Executable File
132 lines
4.0 KiB
TypeScript
Executable File
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 прочие возможные аргументы уведомления
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
|
||
type asyncFunction = (...args: any) => Promise<any|void>
|
||
|
||
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)
|
||
try{
|
||
await funcAsync()
|
||
} catch (ex) {
|
||
if(isDev())
|
||
console.error(ex)
|
||
if (!parseApiEror(ex, actionName))
|
||
notify(getFunctionalValue(errorNotifyText)(ex), 'error')
|
||
} finally {
|
||
setShowLoader?.(false)
|
||
}
|
||
}
|
||
|
||
export const download = async (url: string, fileName?: string) => {
|
||
const response = await fetch(url, {
|
||
headers: {
|
||
Authorization: `Bearer ${getUserToken()}`
|
||
},
|
||
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'
|
||
)
|
||
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()
|
||
}
|
||
}
|
||
|
||
export const upload = async (url: string, formData: FormData) => {
|
||
const response = await fetch(url, {
|
||
headers: {
|
||
Authorization: `Bearer ${getUserToken()}`
|
||
},
|
||
method: 'Post',
|
||
body: formData,
|
||
})
|
||
return response
|
||
}
|
||
|
||
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) => {
|
||
if(bytes < 1024)
|
||
return `${bytes.toFixed(0)}b`
|
||
if(bytes < 1024 * 1024)
|
||
return `${(bytes / 1024).toFixed(2)}kb`
|
||
else
|
||
return `${(bytes / 1024 / 1024).toFixed(2)}Mb`
|
||
}
|