From 061061cd31514871a0dda87fa443cd8044771703 Mon Sep 17 00:00:00 2001 From: Donkie Date: Fri, 14 Jul 2023 14:19:03 +0200 Subject: [PATCH] Client: Added custom data provider Similar to the simple REST provider, but supports any query parameters. --- client/src/App.tsx | 2 +- client/src/components/dataProvider.ts | 146 ++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 client/src/components/dataProvider.ts diff --git a/client/src/App.tsx b/client/src/App.tsx index b9eee3e..244c364 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -15,7 +15,7 @@ import routerBindings, { NavigateToResource, UnsavedChangesNotifier, } from "@refinedev/react-router-v6"; -import dataProvider from "@refinedev/simple-rest"; +import dataProvider from "./components/dataProvider"; import { useTranslation } from "react-i18next"; import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom"; import { Header } from "./components/header"; diff --git a/client/src/components/dataProvider.ts b/client/src/components/dataProvider.ts new file mode 100644 index 0000000..c88ed91 --- /dev/null +++ b/client/src/components/dataProvider.ts @@ -0,0 +1,146 @@ +import { AxiosInstance } from "axios"; +import { stringify } from "query-string"; +import { DataProvider } from "@refinedev/core"; +import { axiosInstance } from "@refinedev/simple-rest"; + +type MethodTypes = "get" | "delete" | "head" | "options"; +type MethodTypesWithBody = "post" | "put" | "patch"; + +const dataProvider = ( + apiUrl: string, + httpClient: AxiosInstance = axiosInstance, +): Omit< + Required, + "createMany" | "updateMany" | "deleteMany" +> => ({ + getList: async ({ resource, meta }) => { + const url = `${apiUrl}/${resource}`; + + const { headers: headersFromMeta, method, queryParams } = meta ?? {}; + const requestMethod = (method as MethodTypes) ?? "get"; + + const { data } = await httpClient[requestMethod]( + `${url}`, + { + headers: headersFromMeta, + params: queryParams, + }, + ); + + return { + data, + total: data.length, + }; + }, + + getMany: async () => { + throw new Error("getMany not implemented"); + }, + + create: async ({ resource, variables, meta }) => { + const url = `${apiUrl}/${resource}`; + + const { headers, method } = meta ?? {}; + const requestMethod = (method as MethodTypesWithBody) ?? "post"; + + const { data } = await httpClient[requestMethod](url, variables, { + headers, + }); + + return { + data, + }; + }, + + update: async ({ resource, id, variables, meta }) => { + const url = `${apiUrl}/${resource}/${id}`; + + const { headers, method } = meta ?? {}; + const requestMethod = (method as MethodTypesWithBody) ?? "patch"; + + const { data } = await httpClient[requestMethod](url, variables, { + headers, + }); + + return { + data, + }; + }, + + getOne: async ({ resource, id, meta }) => { + const url = `${apiUrl}/${resource}/${id}`; + + const { headers, method } = meta ?? {}; + const requestMethod = (method as MethodTypes) ?? "get"; + + const { data } = await httpClient[requestMethod](url, { headers }); + + return { + data, + }; + }, + + deleteOne: async ({ resource, id, variables, meta }) => { + const url = `${apiUrl}/${resource}/${id}`; + + const { headers, method } = meta ?? {}; + const requestMethod = (method as MethodTypesWithBody) ?? "delete"; + + const { data } = await httpClient[requestMethod](url, { + data: variables, + headers, + }); + + return { + data, + }; + }, + + getApiUrl: () => { + return apiUrl; + }, + + custom: async ({ + url, + method, + payload, + query, + headers, + }) => { + let requestUrl = `${url}?`; + + if (query) { + requestUrl = `${requestUrl}&${stringify(query)}`; + } + + if (headers) { + httpClient.defaults.headers = { + ...httpClient.defaults.headers, + ...headers, + }; + } + + let axiosResponse; + switch (method) { + case "put": + case "post": + case "patch": + axiosResponse = await httpClient[method](url, payload); + break; + case "delete": + axiosResponse = await httpClient.delete(url, { + data: payload, + }); + break; + default: + axiosResponse = await httpClient.get(requestUrl); + break; + } + + const { data } = axiosResponse; + + return Promise.resolve({ data }); + }, +}); + +export default dataProvider;