asb_cloud_front/src/components/factory.ts

122 lines
3.8 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { notification } from 'antd'
import { Dispatch, ReactNode, SetStateAction } from 'react'
import { isDev } from '@utils'
import { getUserToken } from '@utils/storage'
import { ApiError, FileInfoDto } from '@api'
const notificationTypeDictionary = new Map([
['error' , { notifyInstance: notification.error , caption: 'Ошибка' }],
['warning', { notifyInstance: notification.warning, caption: 'Предупреждение' }],
['info' , { notifyInstance: notification.info , caption: 'Инфо' }],
['open' , { notifyInstance: notification.info , caption: '' }],
])
export type NotifyType = 'error' | 'warning' | 'info'
/**
* Вызов оповещений всплывающим окошком.
* @param body string или ReactNode
* @param notifyType для параметра типа. Допустимые значение 'error', 'warning', 'info'
*/
export const notify = (body: ReactNode, notifyType: NotifyType = 'info', other?: any) => {
if (!body) return
const instance = notificationTypeDictionary.get(notifyType) ??
notificationTypeDictionary.get('open')
instance?.notifyInstance({
description: body,
message: instance.caption,
placement: 'bottomRight',
duration: 10,
...other
})
}
type asyncFunction = (...args: any) => Promise<any|void>
export const invokeWebApiWrapperAsync = async (
funcAsync: asyncFunction,
setShowLoader?: Dispatch<SetStateAction<boolean>>,
errorNotifyText?: ReactNode | ((ex: unknown) => ReactNode),
actionName?: string,
) => {
setShowLoader?.(true)
try{
await funcAsync()
} catch (ex) {
if(isDev())
console.error(ex)
if (ex instanceof ApiError && ex.status === 403) {
if (actionName)
notify(`Недостаточно прав для выполнения действия "${actionName}"`, 'error')
else
notify('Недостаточно прав для выполнения действия', 'error')
} else if(errorNotifyText) {
if (typeof errorNotifyText === 'function')
notify(errorNotifyText(ex), 'error')
else notify(errorNotifyText, '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}`)
} catch (error) {
notify(`Не удалось скачать файл ${fileInfo.name} по скважине (${fileInfo.idWell})`, 'error')
console.log(error)
}
}
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`
}