diff --git a/.changeset/breezy-wolves-nail.md b/.changeset/breezy-wolves-nail.md new file mode 100644 index 000000000000..01bd149d090a --- /dev/null +++ b/.changeset/breezy-wolves-nail.md @@ -0,0 +1,45 @@ +--- +"@refinedev/chakra-ui": minor +"@refinedev/mantine": minor +"@refinedev/antd": minor +"@refinedev/core": minor +"@refinedev/mui": minor +--- + +feat: added new prop called `mutationVariables` to ``. #6431 +From now on, you can pass additional parameters to the `authProvider` methods using the `mutationVariables` prop of the `` component. + +```tsx +import { AuthPage } from "@refinedev/antd"; // or "@refinedev/chakra-ui", "@refinedev/mantine", "@refinedev/mui" + +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + +[Resolves #6431](https://github.com/refinedev/refine/issues/6431) diff --git a/documentation/docs/authentication/components/auth-page/index.md b/documentation/docs/authentication/components/auth-page/index.md index e5863f9211da..5c5d18b610b6 100644 --- a/documentation/docs/authentication/components/auth-page/index.md +++ b/documentation/docs/authentication/components/auth-page/index.md @@ -748,6 +748,41 @@ const MyLoginPage = () => { }; ``` +### mutationVariables + +`mutationVariables` is used to pass additional variables to the `authProvider` methods. + +```tsx +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + ## API Reference ### Properties diff --git a/documentation/docs/ui-integrations/ant-design/components/auth-page/index.md b/documentation/docs/ui-integrations/ant-design/components/auth-page/index.md index fe4ee1e5897d..7c1ef69787d7 100644 --- a/documentation/docs/ui-integrations/ant-design/components/auth-page/index.md +++ b/documentation/docs/ui-integrations/ant-design/components/auth-page/index.md @@ -892,6 +892,41 @@ const MyLoginPage = () => { }; ``` +### mutationVariables + +`mutationVariables` is used to pass additional variables to the `authProvider` methods. + +```tsx +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + ## FAQ ### How can I remove the default title and logo ? diff --git a/documentation/docs/ui-integrations/chakra-ui/components/auth-page/index.md b/documentation/docs/ui-integrations/chakra-ui/components/auth-page/index.md index 5132fc94cc71..a6ab6061d74a 100644 --- a/documentation/docs/ui-integrations/chakra-ui/components/auth-page/index.md +++ b/documentation/docs/ui-integrations/chakra-ui/components/auth-page/index.md @@ -878,6 +878,41 @@ const MyLoginPage = () => { }; ``` +### mutationVariables + +`mutationVariables` is used to pass additional variables to the `authProvider` methods. + +```tsx +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + ## API Reference ### Properties diff --git a/documentation/docs/ui-integrations/mantine/components/auth-page/index.md b/documentation/docs/ui-integrations/mantine/components/auth-page/index.md index 68f5fa020581..d0b361cccbf5 100644 --- a/documentation/docs/ui-integrations/mantine/components/auth-page/index.md +++ b/documentation/docs/ui-integrations/mantine/components/auth-page/index.md @@ -911,6 +911,41 @@ const MyLoginPage = () => { }; ``` +### mutationVariables + +`mutationVariables` is used to pass additional variables to the `authProvider` methods. + +```tsx +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + ## API Reference ### Properties diff --git a/documentation/docs/ui-integrations/material-ui/components/auth-page/index.md b/documentation/docs/ui-integrations/material-ui/components/auth-page/index.md index 73ab43d81de1..262887691f0d 100644 --- a/documentation/docs/ui-integrations/material-ui/components/auth-page/index.md +++ b/documentation/docs/ui-integrations/material-ui/components/auth-page/index.md @@ -967,6 +967,43 @@ const MyLoginPage = () => { }; ``` +### mutationVariables + +`mutationVariables` is used to pass additional variables to the `authProvider` methods. + +```tsx +import { AuthPage } from "@refinedev/mui"; + +const MyLoginPage = () => { + return ( + + ); +}; + +// all mutation methods are supported. +const authProvider = { + login: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + register: async ({ foo, xyz, ...otherProps }) => { + console.log(foo); // bar + console.log(xyz); // abc + // ... + }, + // ... +}; +``` + ## API Reference ### Properties diff --git a/packages/antd/src/components/pages/auth/components/forgotPassword/index.tsx b/packages/antd/src/components/pages/auth/components/forgotPassword/index.tsx index 410869b89ae6..872108960203 100644 --- a/packages/antd/src/components/pages/auth/components/forgotPassword/index.tsx +++ b/packages/antd/src/components/pages/auth/components/forgotPassword/index.tsx @@ -52,6 +52,7 @@ export const ForgotPasswordPage: React.FC = ({ renderContent, formProps, title, + mutationVariables, }) => { const { token } = theme.useToken(); const [form] = Form.useForm(); @@ -104,7 +105,9 @@ export const ForgotPasswordPage: React.FC = ({ layout="vertical" form={form} - onFinish={(values) => forgotPassword(values)} + onFinish={(values) => + forgotPassword({ ...values, ...mutationVariables }) + } requiredMark={false} {...formProps} > diff --git a/packages/antd/src/components/pages/auth/components/login/index.tsx b/packages/antd/src/components/pages/auth/components/login/index.tsx index 6c6c1a571159..5b1ba2ddffc1 100644 --- a/packages/antd/src/components/pages/auth/components/login/index.tsx +++ b/packages/antd/src/components/pages/auth/components/login/index.tsx @@ -50,6 +50,7 @@ export const LoginPage: React.FC = ({ formProps, title, hideForm, + mutationVariables, }) => { const { token } = theme.useToken(); const [form] = Form.useForm(); @@ -111,6 +112,7 @@ export const LoginPage: React.FC = ({ }} onClick={() => login({ + ...mutationVariables, providerName: provider.name, }) } @@ -152,7 +154,7 @@ export const LoginPage: React.FC = ({ layout="vertical" form={form} - onFinish={(values) => login(values)} + onFinish={(values) => login({ ...values, ...mutationVariables })} requiredMark={false} initialValues={{ remember: false, diff --git a/packages/antd/src/components/pages/auth/components/register/index.tsx b/packages/antd/src/components/pages/auth/components/register/index.tsx index b36c9d84b9b5..97ee6b797bf9 100644 --- a/packages/antd/src/components/pages/auth/components/register/index.tsx +++ b/packages/antd/src/components/pages/auth/components/register/index.tsx @@ -47,6 +47,7 @@ export const RegisterPage: React.FC = ({ formProps, title, hideForm, + mutationVariables, }) => { const { token } = theme.useToken(); const [form] = Form.useForm(); @@ -108,6 +109,7 @@ export const RegisterPage: React.FC = ({ }} onClick={() => register({ + ...mutationVariables, providerName: provider.name, }) } @@ -152,7 +154,7 @@ export const RegisterPage: React.FC = ({ layout="vertical" form={form} - onFinish={(values) => register(values)} + onFinish={(values) => register({ ...mutationVariables, ...values })} requiredMark={false} {...formProps} > diff --git a/packages/antd/src/components/pages/auth/components/updatePassword/index.tsx b/packages/antd/src/components/pages/auth/components/updatePassword/index.tsx index 57de8359212c..67adc2c85675 100644 --- a/packages/antd/src/components/pages/auth/components/updatePassword/index.tsx +++ b/packages/antd/src/components/pages/auth/components/updatePassword/index.tsx @@ -46,6 +46,7 @@ export const UpdatePasswordPage: React.FC = ({ renderContent, formProps, title, + mutationVariables, }) => { const { token } = theme.useToken(); const [form] = Form.useForm(); @@ -96,7 +97,9 @@ export const UpdatePasswordPage: React.FC = ({ layout="vertical" form={form} - onFinish={(values) => updatePassword(values)} + onFinish={(values) => + updatePassword({ ...values, ...mutationVariables }) + } requiredMark={false} {...formProps} > diff --git a/packages/chakra-ui/src/components/pages/auth/components/forgotPassword/index.tsx b/packages/chakra-ui/src/components/pages/auth/components/forgotPassword/index.tsx index a5d12b4cc6a6..5d36290d798d 100644 --- a/packages/chakra-ui/src/components/pages/auth/components/forgotPassword/index.tsx +++ b/packages/chakra-ui/src/components/pages/auth/components/forgotPassword/index.tsx @@ -41,6 +41,7 @@ export const ForgotPasswordPage: React.FC = ({ renderContent, formProps, title, + mutationVariables, }) => { const { onSubmit, ...useFormProps } = formProps || {}; const { mutate } = useForgotPassword(); @@ -99,7 +100,7 @@ export const ForgotPasswordPage: React.FC = ({ return onSubmit(data); } - return mutate(data); + return mutate({ ...mutationVariables, ...data }); })} > diff --git a/packages/chakra-ui/src/components/pages/auth/components/login/index.tsx b/packages/chakra-ui/src/components/pages/auth/components/login/index.tsx index 3036f1143dc6..66dae23af881 100644 --- a/packages/chakra-ui/src/components/pages/auth/components/login/index.tsx +++ b/packages/chakra-ui/src/components/pages/auth/components/login/index.tsx @@ -51,6 +51,7 @@ export const LoginPage: React.FC = ({ formProps, title, hideForm, + mutationVariables, }) => { const { onSubmit, ...useFormProps } = formProps || {}; @@ -86,6 +87,7 @@ export const LoginPage: React.FC = ({ fontSize="sm" onClick={() => login({ + ...mutationVariables, providerName: provider.name, }) } @@ -142,7 +144,7 @@ export const LoginPage: React.FC = ({ return onSubmit(data); } - return login(data); + return login({ ...mutationVariables, ...data }); })} > diff --git a/packages/chakra-ui/src/components/pages/auth/components/register/index.tsx b/packages/chakra-ui/src/components/pages/auth/components/register/index.tsx index 69c489d79dce..9e734310518f 100644 --- a/packages/chakra-ui/src/components/pages/auth/components/register/index.tsx +++ b/packages/chakra-ui/src/components/pages/auth/components/register/index.tsx @@ -46,6 +46,7 @@ export const RegisterPage: React.FC = ({ formProps, title, hideForm, + mutationVariables, }) => { const { onSubmit, ...useFormProps } = formProps || {}; @@ -80,6 +81,7 @@ export const RegisterPage: React.FC = ({ leftIcon={<>{provider?.icon}} onClick={() => mutate({ + ...mutationVariables, providerName: provider.name, }) } @@ -136,7 +138,7 @@ export const RegisterPage: React.FC = ({ return onSubmit(data); } - return mutate(data); + return mutate({ ...mutationVariables, ...data }); })} > diff --git a/packages/chakra-ui/src/components/pages/auth/components/updatePassword/index.tsx b/packages/chakra-ui/src/components/pages/auth/components/updatePassword/index.tsx index 7afdbdfd6015..0262aa847bed 100644 --- a/packages/chakra-ui/src/components/pages/auth/components/updatePassword/index.tsx +++ b/packages/chakra-ui/src/components/pages/auth/components/updatePassword/index.tsx @@ -37,6 +37,7 @@ export const UpdatePasswordPage: React.FC = ({ renderContent, formProps, title, + mutationVariables, }) => { const { onSubmit, ...useFormProps } = formProps || {}; const translate = useTranslate(); @@ -92,7 +93,7 @@ export const UpdatePasswordPage: React.FC = ({ return onSubmit(data); } - return mutate(data); + return mutate({ ...mutationVariables, ...data }); })} > diff --git a/packages/core/src/components/pages/auth/components/forgotPassword/index.spec.tsx b/packages/core/src/components/pages/auth/components/forgotPassword/index.spec.tsx index 5c6d9a8860ae..4ff7ca762c29 100644 --- a/packages/core/src/components/pages/auth/components/forgotPassword/index.spec.tsx +++ b/packages/core/src/components/pages/auth/components/forgotPassword/index.spec.tsx @@ -168,4 +168,43 @@ describe("Auth Page Forgot Password", () => { {}, ); }); + + it("should should accept 'mutationVariables'", async () => { + const forgotPasswordMock = jest.fn().mockResolvedValue({ success: true }); + + const { getByRole, getByLabelText } = render( + , + { + wrapper: TestWrapper({ + authProvider: { + ...mockAuthProvider, + forgotPassword: forgotPasswordMock, + }, + }), + }, + ); + + fireEvent.change(getByLabelText(/email/i), { + target: { value: "demo@refine.dev" }, + }); + + fireEvent.click( + getByRole("button", { + name: /reset/i, + }), + ); + + await waitFor(() => { + expect(forgotPasswordMock).toHaveBeenCalledWith({ + foo: "bar", + xyz: "abc", + email: "demo@refine.dev", + }); + }); + }); }); diff --git a/packages/core/src/components/pages/auth/components/forgotPassword/index.tsx b/packages/core/src/components/pages/auth/components/forgotPassword/index.tsx index e7e1a4fd6dfd..90e7277e611a 100644 --- a/packages/core/src/components/pages/auth/components/forgotPassword/index.tsx +++ b/packages/core/src/components/pages/auth/components/forgotPassword/index.tsx @@ -27,6 +27,7 @@ export const ForgotPasswordPage: React.FC = ({ renderContent, formProps, title = undefined, + mutationVariables, }) => { const translate = useTranslate(); const routerType = useRouterType(); @@ -53,7 +54,7 @@ export const ForgotPasswordPage: React.FC = ({
{ e.preventDefault(); - forgotPassword({ email }); + forgotPassword({ ...mutationVariables, email }); }} {...formProps} > diff --git a/packages/core/src/components/pages/auth/components/login/index.spec.tsx b/packages/core/src/components/pages/auth/components/login/index.spec.tsx index 22e72c38e022..7ea0c89313f4 100644 --- a/packages/core/src/components/pages/auth/components/login/index.spec.tsx +++ b/packages/core/src/components/pages/auth/components/login/index.spec.tsx @@ -346,4 +346,49 @@ describe("Auth Page Login", () => { ).toHaveAttribute("href", "/forgot-password"); } }); + + it("should should accept 'mutationVariables'", async () => { + const loginMock = jest.fn().mockResolvedValue({ success: true }); + + const { getByRole, getByLabelText } = render( + , + { + wrapper: TestWrapper({ + authProvider: { + ...mockAuthProvider, + login: loginMock, + }, + }), + }, + ); + + fireEvent.change(getByLabelText(/email/i), { + target: { value: "demo@refine.dev" }, + }); + + fireEvent.change(getByLabelText(/password/i), { + target: { value: "demo" }, + }); + + fireEvent.click( + getByRole("button", { + name: /sign in/i, + }), + ); + + await waitFor(() => { + expect(loginMock).toHaveBeenCalledWith({ + foo: "bar", + xyz: "abc", + email: "demo@refine.dev", + password: "demo", + remember: false, + }); + }); + }); }); diff --git a/packages/core/src/components/pages/auth/components/login/index.tsx b/packages/core/src/components/pages/auth/components/login/index.tsx index 2a50ad4ea8a4..9aa6b65d783c 100644 --- a/packages/core/src/components/pages/auth/components/login/index.tsx +++ b/packages/core/src/components/pages/auth/components/login/index.tsx @@ -25,6 +25,7 @@ export const LoginPage: React.FC = ({ formProps, title = undefined, hideForm, + mutationVariables, }) => { const routerType = useRouterType(); const Link = useLink(); @@ -62,6 +63,7 @@ export const LoginPage: React.FC = ({