import { notification } from 'antd' import { Dispatch, ReactNode, SetStateAction } from 'react' import { ApiError, FileInfoDto } from '@api' import { getUserToken } from '@utils/storage' const notificationTypeDictionary = new Map([ ['error' , { notifyInstance: notification.error , caption: 'Ошибка' }], ['warning', { notifyInstance: notification.warning, caption: 'Предупреждение' }], ['info' , { notifyInstance: notification.info , caption: 'Инфо' }], ['open' , { notifyInstance: notification.info , caption: '' }], ]) /** * Вызов оповещений всплывающим окошком. * @param body string или ReactNode * @param notifyType для параметра типа. Допустимые значение 'error', 'warning', 'info' */ export const notify = (body: ReactNode, notifyType: string = '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 export const invokeWebApiWrapperAsync = async ( funcAsync: asyncFunction, setShowLoader?: Dispatch>, errorNotifyText?: ReactNode | ((ex: unknown) => ReactNode), actionName?: string, ) => { setShowLoader?.(true) try{ await funcAsync() } catch (ex) { if(process.env.NODE_ENV === 'development') 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` }