UNPKG

@elastic-suite/gally-admin-components

Version:
99 lines (90 loc) 2.36 kB
import { Dispatch, SetStateAction, useCallback, useEffect, useState, } from 'react' import Router from 'next/router' import { useTranslation } from 'next-i18next' import { AuthError, IFetch, IGraphqlApi, ILoadResource, LoadStatus, fetchGraphql, isError, storageRemove, tokenStorageKey, } from '@elastic-suite/gally-admin-shared' import { useLog } from './useLog' export function useApiGraphql(secure = true): IGraphqlApi { const { i18n } = useTranslation('common') const log = useLog() const { t } = useTranslation('alert') return useCallback( async <T extends object>( query: string, variables?: Record<string, unknown>, options?: RequestInit ) => { try { const json = await fetchGraphql<T>( i18n.language, query, variables, options, secure ) return json } catch (error) { if (secure && error instanceof AuthError) { storageRemove(tokenStorageKey) Router.push('/login') log(t('Expired JWT Token')) } else { log(error) } return { error } } }, [i18n.language, log, secure, t] ) } export function useGraphqlApi<T extends object>( query: string, variables?: Record<string, unknown>, options?: RequestInit, conditions = true ): [IFetch<T>, Dispatch<SetStateAction<T>>, ILoadResource] { const graphqlApi = useApiGraphql() const [response, setResponse] = useState<IFetch<T>>({ status: LoadStatus.IDLE, }) const updateResponse = useCallback((data: SetStateAction<T>): void => { setResponse((prevState) => ({ ...prevState, data: data instanceof Function ? data(prevState.data) : data, })) }, []) const load = useCallback(() => { if (conditions) { setResponse((prevState) => ({ data: prevState.data, status: LoadStatus.LOADING, })) graphqlApi<T>(query, variables, options).then((json) => { if (isError(json)) { setResponse({ error: json.error, status: LoadStatus.FAILED }) } else { setResponse({ data: json, status: LoadStatus.SUCCEEDED }) } }) } }, [conditions, graphqlApi, options, query, variables]) useEffect(() => { load() }, [load]) return [response, updateResponse, load] }