UNPKG

@elastic-suite/gally-admin-components

Version:
136 lines (122 loc) 3.88 kB
import { useCallback, useMemo } from 'react' import { useRouter } from 'next/router' import { IError, IHydraMember, IMainContext, IResource, IResourceOperations, Method, contentTypeHeader, getApiUrl, getResource, updatePropertiesAccordingToPath, } from '@elastic-suite/gally-admin-shared' import { selectApi, useAppSelector } from '../store' import { useApiFetch } from './useApi' export function useResource( resourceName: string, mainContext: IMainContext = IMainContext.GRID ): IResource { const api = useAppSelector(selectApi) const { asPath } = useRouter() const pathWithoutQueryString = useMemo(() => asPath?.split('?')[0], [asPath]) return useMemo(() => { const resource = getResource(api, resourceName) return { ...resource, supportedProperty: resource?.supportedProperty instanceof Array ? resource?.supportedProperty.map((field) => updatePropertiesAccordingToPath( field, pathWithoutQueryString, mainContext ) ) : resource?.supportedProperty ? [ updatePropertiesAccordingToPath( resource.supportedProperty, pathWithoutQueryString, mainContext ), ] : resource?.supportedProperty, } }, [api, pathWithoutQueryString, mainContext, resourceName]) } export function useResourceOperations<T extends IHydraMember>( resource: IResource ): IResourceOperations<T> { const { supportedOperation } = resource const fetchApi = useApiFetch() const apiUrl = getApiUrl(resource.url) const update = useCallback( (id: string | number, item: Partial<T>): Promise<T | IError> => fetchApi<T>(`${apiUrl}/${id}`, undefined, { body: JSON.stringify(item), method: Method.PATCH, headers: { [contentTypeHeader]: 'application/merge-patch+json' }, }), [apiUrl, fetchApi] ) const create = useCallback( (item: Omit<T, 'id' | '@id' | '@type'>): Promise<T | IError> => { // Check if item is FormData (file upload) const isFormData = item instanceof FormData const requestOptions: RequestInit = { body: isFormData ? item : JSON.stringify(item), method: Method.POST, headers: { [contentTypeHeader]: isFormData ? '' : 'application/ld+json', }, } return fetchApi(apiUrl, undefined, requestOptions) }, [apiUrl, fetchApi] ) const replace = useCallback( (item: Partial<T>): Promise<T | IError> => fetchApi(`${apiUrl}/${item.id}`, undefined, { body: JSON.stringify(item), method: Method.PUT, }), [apiUrl, fetchApi] ) const remove = useCallback( (id: string | number): Promise<T | IError> => fetchApi(`${apiUrl}/${id}`, undefined, { method: Method.DELETE, }), [apiUrl, fetchApi] ) return useMemo( () => supportedOperation.reduce<IResourceOperations<T>>((acc, operation) => { if (typeof operation['@type'] === 'string') { acc.update = update } else if ( operation['@type'] instanceof Array && operation['@type'].length === 2 && typeof operation['@type'][1] === 'string' ) { if ( operation['@type'][1].indexOf('//schema.org/CreateAction') !== -1 ) { acc.create = create } else if ( operation['@type'][1].indexOf('//schema.org/ReplaceAction') !== -1 ) { acc.replace = replace } else if ( operation['@type'][1].indexOf('//schema.org/DeleteAction') !== -1 ) { acc.remove = remove } } return acc }, {}), [create, remove, replace, supportedOperation, update] ) }