diff --git a/src/components/Admin/dataProvider.ts b/src/components/Admin/dataProvider.ts index c5a71589..4651b5e2 100644 --- a/src/components/Admin/dataProvider.ts +++ b/src/components/Admin/dataProvider.ts @@ -1,4 +1,4 @@ -import axios from 'axios' +import axios, {AxiosError, AxiosResponse} from 'axios' import {stringify} from 'querystring' import {DataProvider, RaRecord} from 'react-admin' // TODO: BE chysta search, filter, pagination a sort. ked to bude ready, @@ -26,6 +26,14 @@ const dynamicSort = (key: string, order: string) => { } } +/* field errors by mali byt zachytene uz FE validaciou, dumpujem do 'Nastala neznáma chyba' */ +const parseError = (response: any) => { + if (typeof response === 'undefined') return 'Nastala neznáma chyba' + if (typeof response.detail !== 'undefined') return response.detail + if (response.non_field_errors?.constructor.name === 'Array') return response.non_field_errors.join('\n') + return 'Nastala neznáma chyba' +} + const apiUrl = '/api' // skopirovane a dost upravene z https://github.com/bmihelac/ra-data-django-rest-framework/blob/master/src/index.ts @@ -38,72 +46,87 @@ export const dataProvider: DataProvider = { // ...getOrderingQuery(params.sort), } const stringifiedQuery = stringify(query) - const {data} = await axios.get(`${apiUrl}/${resource}${stringifiedQuery ? `/?${stringifiedQuery}` : ''}`) - - // client-side filter - let filteredData = data - if (params.filter) { - const {q: search, ...rest} = params.filter - if (search) { - // vyhladava to filter string vo vsetkych fieldoch kazdeho recordu - // - bohuzial tie fieldy su casto len IDcka inych modelov, tak nic moc :D - filteredData = data.filter((record: RaRecord) => { - const matches = Object.values(record).some((value) => { - return value && JSON.stringify(value).toLowerCase().includes(search.toLowerCase()) - }) - return matches - }) - } - if (rest) { - filteredData = filteredData.filter((record: RaRecord) => { - return Object.entries(rest).every(([key, value]) => { - if (!value) return true - return record[key] === value + try { + const {data} = await axios.get(`${apiUrl}/${resource}${stringifiedQuery ? `/?${stringifiedQuery}` : ''}`) + + // client-side filter + let filteredData = data + if (params.filter) { + const {q: search, ...rest} = params.filter + if (search) { + // vyhladava to filter string vo vsetkych fieldoch kazdeho recordu + // - bohuzial tie fieldy su casto len IDcka inych modelov, tak nic moc :D + filteredData = data.filter((record: RaRecord) => { + const matches = Object.values(record).some((value) => { + return value && JSON.stringify(value).toLowerCase().includes(search.toLowerCase()) + }) + return matches }) - }) + } + + if (rest) { + filteredData = filteredData.filter((record: RaRecord) => { + return Object.entries(rest).every(([key, value]) => { + if (!value) return true + return record[key] === value + }) + }) + } } - } - // client-side sort - if (params.sort) { - const {field, order} = params.sort + // client-side sort + if (params.sort) { + const {field, order} = params.sort - filteredData.sort(dynamicSort(field, order)) - } + filteredData.sort(dynamicSort(field, order)) + } - // client-side pagination - let pagedData = filteredData - if (params.pagination) { - const {page, perPage} = params.pagination - pagedData = filteredData.slice((page - 1) * perPage, page * perPage) - } + // client-side pagination + let pagedData = filteredData + if (params.pagination) { + const {page, perPage} = params.pagination + pagedData = filteredData.slice((page - 1) * perPage, page * perPage) + } - return { - data: pagedData, - total: filteredData.length, + return { + data: pagedData, + total: filteredData.length, + } + } catch (e) { + throw new Error(parseError((e as AxiosError).response?.data)) } }, getOne: async (resource, params) => { - const {data} = await axios.get(`${apiUrl}/${resource}/${params.id}`) - - return {data} + try { + const {data} = await axios.get(`${apiUrl}/${resource}/${params.id}`) + return {data} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, getMany: async (resource, params) => { - const data = await Promise.all(params.ids.map((id) => axios.get(`${apiUrl}/${resource}/${id}`))) - - return {data: data.map(({data}) => data)} + try { + const data = await Promise.all(params.ids.map((id) => axios.get(`${apiUrl}/${resource}/${id}`))) + return {data: data.map(({data}) => data)} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, // TODO: ak budeme pouzivat tuto funkciu, upravime podla getList (pagination, sort, filter). uprimne este neviem, pri com sa pouziva getManyReference: async (resource, params) => { const query = { [params.target]: params.id, } - const {data} = await axios.get(`${apiUrl}/${resource}/?${stringify(query)}`) - return { - data: data, - total: data.length, + try { + const {data} = await axios.get(`${apiUrl}/${resource}/?${stringify(query)}`) + return { + data: data, + total: data.length, + } + } catch (e: any) { + throw new Error(parseError(e.response.data)) } }, update: async (resource, params) => { @@ -113,32 +136,47 @@ export const dataProvider: DataProvider = { // ked existuju formData, ktore sme do recordu pridali v `transform` v `MyEdit`, pouzijeme tie const body = formData ?? input - const {data} = await axios.patch(`${apiUrl}/${resource}/${id}`, body) - - return {data} + try { + const {data} = await axios.patch(`${apiUrl}/${resource}/${id}`, body) + return {data} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, updateMany: async (resource, params) => { - const data = await Promise.all(params.ids.map((id) => axios.patch(`${apiUrl}/${resource}/${id}`, params.data))) - - return {data: data.map(({data}) => data)} + try { + const data = await Promise.all(params.ids.map((id) => axios.patch(`${apiUrl}/${resource}/${id}`, params.data))) + return {data: data.map(({data}) => data)} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, create: async (resource, params) => { const {formData, ...input} = params.data const body = formData ?? input - const {data} = await axios.post(`${apiUrl}/${resource}`, body) - - return {data} + try { + const {data} = await axios.post(`${apiUrl}/${resource}`, body) + return {data} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, delete: async (resource, params) => { - const {data} = await axios.delete(`${apiUrl}/${resource}/${params.id}`) - - return {data} + try { + const {data} = await axios.delete(`${apiUrl}/${resource}/${params.id}`) + return {data} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, deleteMany: async (resource, params) => { - const data = await Promise.all(params.ids.map((id) => axios.delete(`${apiUrl}/${resource}/${id}`))) - - return {data: data.map(({data}) => data.id)} + try { + const data = await Promise.all(params.ids.map((id) => axios.delete(`${apiUrl}/${resource}/${id}`))) + return {data: data.map(({data}) => data.id)} + } catch (e: any) { + throw new Error(parseError(e.response.data)) + } }, }