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 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 export const invokeWebApiWrapperAsync = async ( funcAsync: asyncFunction, setShowLoader?: Dispatch>, errorNotifyText?: FunctionalValue, 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 { 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}`) } 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` }