import { IListResponse_DTO, INITIAL_PAGE_INDEX, INITIAL_PAGE_SIZE } from "@shared/contexts"; import { getApiAuthorization as getApiAuthLib } from "../api"; import { ICreateOneDataProviderParams, ICustomDataProviderParam, IDataSource, IDownloadPDFDataProviderParams, IDownloadPDFDataProviderResponse, IFilterItemDataProviderParam, IGetListDataProviderParams, IGetOneDataProviderParams, IPaginationDataProviderParam, IRemoveOneDataProviderParams, ISortItemDataProviderParam, IUpdateOneDataProviderParams, IUploadFileDataProviderParam, } from "../hooks/useDataSource/DataSource"; import { createAxiosInstance, defaultAxiosRequestConfig } from "./axiosInstance"; export const createAxiosDataProvider = ( apiUrl: string, httpClient = createAxiosInstance() ): IDataSource => ({ name: () => "AxiosDataProvider", getApiUrl: () => apiUrl, getApiAuthorization: getApiAuthLib, getList: async (params: IGetListDataProviderParams): Promise> => { const { resource, quickSearchTerm, pagination, filters = [], sort = [] } = params; const url = `${apiUrl}/${resource}`; const urlParams = new URLSearchParams(); const { page, limit } = extractPaginationParams(pagination); urlParams.append("page", String(page)); urlParams.append("limit", String(limit)); const generatedSort = extractSortParams(sort); if (generatedSort.length) { urlParams.append("$sort_by", generatedSort.join(",")); } const queryQuickSearch = generateQuickSearch(quickSearchTerm, filters); if (queryQuickSearch.length) { urlParams.append("q", queryQuickSearch.join(",")); } const queryFilters = extractFilterParams(filters); if (queryFilters.length) { urlParams.append("$filters", queryFilters.join(",")); } const response = await httpClient.request>({ url: `${url}?${urlParams.toString()}`, method: "GET", }); return response.data; }, getOne: async (params: IGetOneDataProviderParams): Promise => { const { resource, id } = params; const response = await httpClient.request({ url: `${apiUrl}/${resource}/${id}`, method: "GET", }); return response.data; }, /*saveOne: async (params: ISaveOneDataProviderParams

): Promise => { const { resource, data, id } = params; console.log(params); const result = await httpClient.request({ url: `${apiUrl}/${resource}/${id}`, method: "PUT", data, }); return result.data; },*/ createOne: async (params: ICreateOneDataProviderParams

): Promise => { const { resource, data } = params; const response = await httpClient.request({ url: `${apiUrl}/${resource}`, method: "POST", data, }); return response.data; }, updateOne: async (params: IUpdateOneDataProviderParams

): Promise => { const { resource, data, id } = params; const response = await httpClient.request({ url: `${apiUrl}/${resource}/${id}`, method: "PUT", data, }); return response.data; }, removeOne: async (params: IRemoveOneDataProviderParams) => { const { resource, id } = params; await httpClient.request({ url: `${apiUrl}/${resource}/${id}`, method: "DELETE", }); return; }, uploadFile: async (params: IUploadFileDataProviderParam): Promise => { const { path, file, key, onUploadProgress } = params; const url = `${apiUrl}/${path}`; const formData = new FormData(); formData.append(key || "file", file); console.log(file); const response = await httpClient.post(url, formData, { headers: { "Content-Type": "multipart/form-data", }, onUploadProgress, }); return response.data; }, downloadPDF: async ( params: IDownloadPDFDataProviderParams ): Promise => { const { url, config } = params; const response = await httpClient.get(url, { responseType: "arraybuffer", // Esto es necesario para recibir los datos en formato ArrayBuffer ...config, }); // Extraer el nombre del archivo de la cabecera Content-Disposition const contentDisposition = response.headers["content-disposition"]; let filename: string = "downloaded-file.pdf"; // Valor por defecto si no se encuentra el nombre en la cabecera if (contentDisposition) { const match = contentDisposition.match(/filename="?(.+)"?/); if (match && match[1]) { filename = match[1]; } } // Crear un Blob con los datos descargados const filedata = new Blob([response.data], { type: "application/pdf" }); return { filename, filedata, }; }, custom: async (params: ICustomDataProviderParam): Promise => { const { url, path, method, responseType, headers, signal, data, ...payload } = params; let requestUrl: string; if (path) { requestUrl = `${apiUrl}/${path}`; } else if (url) { requestUrl = url; } else { throw new Error('"url" or "path" param is missing'); } console.log(apiUrl, path, url, requestUrl.toString()); // Preparar la respuesta personalizada let customResponse; // Configurar opciones comunes para la petición const config = { url: requestUrl.toString(), method, responseType, signal, ...payload, ...defaultAxiosRequestConfig, }; switch (method) { case "put": case "post": case "patch": customResponse = await httpClient.request({ ...config, data, }); break; case "delete": customResponse = await httpClient.delete(requestUrl.toString(), { responseType, headers, ...payload, }); break; default: customResponse = await httpClient.get(requestUrl.toString(), { responseType, signal, headers, ...payload, }); break; } return customResponse.data; }, /*getMany: async ({ resource }) => { const { body } = await httpClient.request({ url: `${apiUrl}/${resource}`, method: "GET", //...defaultRequestConfig, }); return body; },*/ /*create: async ({ resource, values }) => { const url = `${apiUrl}/${resource}`; const { body } = await httpClient.post(url, values, defaultRequestConfig); return body; },*/ /*createMany: async ({ resource, values }) => { const response = await Promise.all( values.map(async (param) => { const { body } = await httpClient.post( `${apiUrl}/${resource}`, param //defaultRequestConfig, ); return body; }) ); return response; },*/ /*update: async ({ resource, id, values }) => { const url = `${apiUrl}/${resource}/${id}`; const { body } = await httpClient.patch(url, values, defaultRequestConfig); return body; },*/ /*updateMany: async ({ resource, ids, values }) => { const response = await Promise.all( ids.map(async (id) => { const { body } = await httpClient.patch( `${apiUrl}/${resource}/${id}`, values //defaultRequestConfig, ); return body; }) ); return response; },*/ // removeMany: async ({ resource, ids }) => { // const url = `${apiUrl}/${resource}/bulk-delete`; // const { body } = await httpClient.request({ // url, // method: "PATCH", // data: { // ids, // }, // //defaultRequestConfig, // }); // return body; // }, // upload: async ({ resource, file, onUploadProgress }) => { // const url = `${apiUrl}/${resource}`; // const options = { // //...defaultRequestConfig, // onUploadProgress, // headers: { // //...defaultRequestConfig.headers, // "Content-Type": "multipart/form-data", // }, // }; // const formData = new FormData(); // formData.append("file", file); // const { body } = await httpClient.post(url, formData, options); // return body; // }, /*uploadMany: async ({ resource, values }) => { const url = `${apiUrl}/${resource}`; const options = { //...defaultRequestConfig, headers: { ...defaultRequestConfig.headers, 'Content-Type': 'multipart/form-data' } }; const response = await Promise.all( values.map(async (value) => { const { body } = await httpClient.post( url, value, options ); return body; }), ); return response; },*/ /*custom: async ({ url, method, filters, sort, payload, query, headers }) => { let requestUrl = `${url}?`; if (sort) { const generatedSort = extractSortParams(sort); if (generatedSort) { const { _sort, _order } = generatedSort; const sortQuery = { _sort: _sort.join(","), _order: _order.join(","), }; requestUrl = `${requestUrl}&${queryString.stringify(sortQuery)}`; } } if (filters) { const filterQuery = extractFilterParams(filters); requestUrl = `${requestUrl}&${queryString.stringify(filterQuery)}`; } if (query) { requestUrl = `${requestUrl}&${queryString.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 "remove": axiosResponse = await httpClient.delete(url); break; default: axiosResponse = await httpClient.get(requestUrl); break; } const { data } = axiosResponse; return Promise.resolve({ data }); },*/ }); const extractSortParams = (sort: ISortItemDataProviderParam[] = []) => sort.map(({ field, order }) => `${order === "DESC" ? "-" : "+"}${field}`); const extractFilterParams = (filters: IFilterItemDataProviderParam[] = []) => filters .filter(({ field }) => field !== "q") .map(({ field, operator, value }) => `${field}[${operator}]${value}`); const generateQuickSearch = ( quickSearchTerm: string[] = [], filters: IFilterItemDataProviderParam[] = [] ) => filters.find(({ field }) => field === "q")?.value ? [filters.find(({ field }) => field === "q")!.value] : quickSearchTerm; const extractPaginationParams = (pagination?: IPaginationDataProviderParam) => { const { pageIndex = INITIAL_PAGE_INDEX, pageSize = INITIAL_PAGE_SIZE } = pagination || {}; return { page: pageIndex, limit: pageSize, }; };