asb_cloud_front/src/components/factory.ts
goodmice fa751240ba * Добавлена страница скачивания файлов, кнопки скачивания изменены на ссылки
* Добавлено игнорирование кода 204
* less перенесён в dev зависимости
2022-06-29 16:45:38 +05:00

132 lines
4.0 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 { 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`
}