diff --git a/modules/core/src/web/hooks/use-unsaved-changes-notifier/use-unsaved-changes-notifier.tsx b/modules/core/src/web/hooks/use-unsaved-changes-notifier/use-unsaved-changes-notifier.tsx index 96fdd395..f8701642 100644 --- a/modules/core/src/web/hooks/use-unsaved-changes-notifier/use-unsaved-changes-notifier.tsx +++ b/modules/core/src/web/hooks/use-unsaved-changes-notifier/use-unsaved-changes-notifier.tsx @@ -1,5 +1,6 @@ import { createContext, useCallback, useContext, useEffect, useState } from "react"; import { UNSAFE_NavigationContext, useBeforeUnload, useBlocker } from "react-router-dom"; + import { UnsavedChangesDialog } from "./components"; type ContextValue = { @@ -88,11 +89,10 @@ export function UnsavedChangesProvider({ }; }, [blocker, requestConfirm]); - return ( {children} - + ); } diff --git a/modules/core/src/web/lib/data-source/axios/create-axios-data-source.ts b/modules/core/src/web/lib/data-source/axios/create-axios-data-source.ts index 980209e4..2b8c4326 100644 --- a/modules/core/src/web/lib/data-source/axios/create-axios-data-source.ts +++ b/modules/core/src/web/lib/data-source/axios/create-axios-data-source.ts @@ -1,99 +1,100 @@ -import type { AxiosInstance } from "axios"; +import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"; import type { ICustomParams, IDataSource } from "../datasource.interface"; import { defaultAxiosRequestConfig } from "./create-axios-instance"; -/** - * Crea un DataSource basado en Axios. - * @param client Instancia de Axios que se utilizará para las peticiones HTTP. - * @returns Un objeto que implementa la interfaz IDataSource. - * @throws Error si la instancia de Axios no es válida o no tiene la configuración necesaria. - * @example - * const axiosInstance = createAxiosInstance({ - * baseURL: "https://api.example.com", - * getAccessToken: () => localStorage.getItem("accessToken"), - * onAuthError: () => { - * console.error("Error de autenticación"); - * // Manejar el error de autenticación, por ejemplo, redirigir al login - * }, - * }); - * const dataSource = createAxiosDataSource(axiosInstance); - * - */ - export const createAxiosDataSource = (client: AxiosInstance): IDataSource => { - // Validaciones de la instancia de Axios if (!client) { throw new Error("[Axios] Se esperaba una instancia de Axios."); } - if (!(client as AxiosInstance).getUri) { + if (!client.getUri || typeof client.getUri !== "function") { throw new Error("[Axios] La instancia proporcionada no es una instancia de Axios válida."); } - if (typeof (client as AxiosInstance).getUri !== "function") { - throw new Error("[Axios] La instancia proporcionada no tiene el método getUri."); - } - - if (typeof (client as AxiosInstance).getUri() !== "string") { + if (typeof client.getUri() !== "string") { throw new Error("[Axios] baseURL no está definido en esta instancia."); } return { - getBaseUrl: () => (client as AxiosInstance).getUri(), + getBaseUrl: () => client.getUri(), - getList: async (resource: string, params?: Record): Promise => { - const { signal, ...rest } = params as any; // en 'rest' puede venir el "criteria". + getList: async (resource: string, params?: Record): Promise => { + const { signal, ...rest } = (params ?? {}) as Record & { + signal?: AbortSignal; + }; - const res = await (client as AxiosInstance).get(resource, { signal, params: rest }); - return res.data; - }, + const res = await client.get(resource, { + signal, + params: rest, + }); - getOne: async (resource: string, id: string | number, params?: Record) => { - const res = await (client as AxiosInstance).get(`${resource}/${id}`, params); return res.data; }, - getMany: async (resource: string, ids: Array): Promise => { - const res = await (client as AxiosInstance).get(`${resource}`, { params: { ids } }); - return res.data; - }, - - createOne: async ( - resource: string, - data: Partial, - params?: Record - ): Promise => { - const res = await (client as AxiosInstance).post(resource, data, params); - return res.data; - }, - - updateOne: async ( - resource: string, - id: string | number, - data: Partial, - params?: Record - ) => { - const res = await (client as AxiosInstance).put(`${resource}/${id}`, data, params); - return res.data; - }, - - deleteOne: async ( + getOne: async ( resource: string, id: string | number, params?: Record - ) => { - await (client as AxiosInstance).delete(`${resource}/${id}`, params); + ): Promise => { + const res = await client.get(`${resource}/${id}`, params); + return res.data; }, - custom: async (customParams: ICustomParams) => { + getMany: async (resource: string, ids: Array): Promise => { + const res = await client.get(resource, { + params: { ids }, + }); + + return res.data; + }, + + createOne: async ( + resource: string, + data: TData, + params?: Record + ): Promise => { + const res = await client.post, TData>( + resource, + data, + params as AxiosRequestConfig + ); + + return res.data; + }, + + updateOne: async ( + resource: string, + id: string | number, + data: TData, + params?: Record + ): Promise => { + const res = await client.put, TData>( + `${resource}/${id}`, + data, + params as AxiosRequestConfig + ); + + return res.data; + }, + + deleteOne: async ( + resource: string, + id: string | number, + params?: Record + ): Promise => { + const res = await client.delete(`${resource}/${id}`, params); + return res.data; + }, + + custom: async (customParams: ICustomParams): Promise => { const { url, path, method, responseType, headers, signal, data, ...payload } = customParams; - const requestUrl = path ? `${(client as AxiosInstance).getUri()}/${path}` : url; + const requestUrl = path ? `${client.getUri()}/${path}` : url; if (!requestUrl) throw new Error('"url" or "path" param is missing'); - const config = { + const config: AxiosRequestConfig = { url: requestUrl, method, responseType, @@ -103,32 +104,27 @@ export const createAxiosDataSource = (client: AxiosInstance): IDataSource => { headers, }; - let customResponse; + let customResponse: AxiosResponse; switch (method) { case "put": case "post": case "patch": - customResponse = await (client as AxiosInstance).request({ + customResponse = await client.request, TData>({ ...config, data, }); break; case "delete": - customResponse = await (client as AxiosInstance).delete(requestUrl, { - responseType, - headers, - ...payload, + customResponse = await client.delete, TData>(requestUrl, { + ...config, }); break; default: - customResponse = await (client as AxiosInstance).get(requestUrl, { - responseType, - signal, - headers, - ...payload, + customResponse = await client.get, TData>(requestUrl, { + ...config, }); break; } diff --git a/modules/core/src/web/lib/data-source/datasource.interface.ts b/modules/core/src/web/lib/data-source/datasource.interface.ts index aeb6a3f8..d2d93405 100644 --- a/modules/core/src/web/lib/data-source/datasource.interface.ts +++ b/modules/core/src/web/lib/data-source/datasource.interface.ts @@ -1,34 +1,32 @@ -import type { ResponseType } from "axios"; +import type { AxiosRequestConfig, ResponseType } from "axios"; -export interface ICustomParams { +export interface ICustomParams { url?: string; path?: string; method: "get" | "delete" | "head" | "options" | "post" | "put" | "patch"; signal?: AbortSignal; responseType?: ResponseType; - headers?: { - [key: string]: unknown; - }; + headers?: AxiosRequestConfig["headers"]; + data: T; [key: string]: unknown; } export interface IDataSource { getBaseUrl(): string; - getList(resource: string, params?: Record): Promise; - getOne(resource: string, id: string | number, params?: Record): Promise; - getMany(resource: string, ids: Array): Promise; - createOne(resource: string, data: Partial, params?: Record): Promise; - updateOne( + getList(resource: string, params?: Record): Promise; + getOne(resource: string, id: string | number, params?: Record): Promise; + getMany(resource: string, ids: Array): Promise; + createOne(resource: string, data: TData, params?: Record): Promise; + updateOne( resource: string, id: string | number, - data: Partial, + data: TData, params?: Record - ): Promise; - deleteOne( + ): Promise; + deleteOne( resource: string, id: string | number, params?: Record - ): Promise; - - custom: (customParams: ICustomParams) => Promise; + ): Promise; + custom(customParams: ICustomParams): Promise; }