Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated props #9789

Merged
merged 24 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
46b46d5
remove disableNotification from useCheckAuth
adguernier Apr 22, 2024
53afd3c
add an upgrade point for disableNotification param
adguernier Apr 23, 2024
5e7b2f9
remove useless disableNotification in useCheckAuth spec
adguernier Apr 23, 2024
6d8dcbb
remove disableNotification from useLogoutIfAccessDenied
adguernier Apr 23, 2024
9d75076
Apply suggestions from code review
adguernier Apr 23, 2024
c680d51
resource param from useDeleteWithUndoController and useDeleteWithConf…
adguernier Apr 23, 2024
381f939
remove `data` from `CreateControllerResult`
adguernier Apr 24, 2024
9c38cc8
remove `defaultReferenceSource` and `referenceSource` from `useRefere…
adguernier Apr 24, 2024
2288159
remove onError type
adguernier Apr 25, 2024
35522e1
useLocale is no longer deprecated
adguernier Apr 26, 2024
40c0bab
useSetLocale is no longer deprecated
adguernier Apr 26, 2024
e0f6fce
remove deprecated `linkToRecord` helper
adguernier Apr 26, 2024
3b19836
remove deprecated `resolveRedirectTo` helper
adguernier Apr 26, 2024
ba0dbfd
remove deprecated `formClassName` of `FieldProps` and `CommonInputPro…
adguernier Apr 26, 2024
a5cdafa
remove deprecated `PublicFieldProps` interface
adguernier Apr 26, 2024
7761b2a
remove deprecated `InjectedFieldProps` interface
adguernier Apr 26, 2024
8649d33
remove depreacted `rowStyle` prop from `<SimpleList>`
adguernier Apr 26, 2024
bc484a4
fix doc link
adguernier Apr 26, 2024
9376346
remove depreacted `theme` prop from `<ThemeProvider>`
adguernier Apr 26, 2024
72ce3ce
remove depreacted `<PaginationLimit>` component
adguernier Apr 26, 2024
c5c9c0b
Revert "remove depreacted `rowStyle` prop from `<SimpleList>`"
adguernier Apr 29, 2024
57cd6e1
`<SimpleList rowStyle>` is no longer deprecated
adguernier Apr 29, 2024
16b8d53
Merge branch 'next' into chore/remove-deprecated-props
adguernier Apr 30, 2024
e66ec1b
Merge branch 'next' into chore/remove-deprecated-props
djhi May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/Upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,35 @@ The `<InputHelperText>` component no longer accepts a `touched` prop. This prop

If you were using this prop, you can safely remove it.

## `disableNotification` Param of `useCheckAuth` Was Removed
adguernier marked this conversation as resolved.
Show resolved Hide resolved

The `useCheckAuth` hook no longer accepts the deprecated `disableNotification` param. To disabe the notification at the `checkAuth` call, `authProvider.checkAuth()` should return a rejected promise with a `falsy` message:
adguernier marked this conversation as resolved.
Show resolved Hide resolved

```ts
const authProvider: AuthProvider = {
//...
checkAuth: () => Promise.reject({ message: false }),
}
```

## `disableNotification` Param of `useLogoutIfAccessDenied` Was Removed
adguernier marked this conversation as resolved.
Show resolved Hide resolved

The `useLogoutIfAccessDenied` hook no longer accepts the deprecated `disableNotification` param. To disabe the notification at the `checkError` call, `authProvider.checkError()` should return a rejected promise with a `falsy` message:
adguernier marked this conversation as resolved.
Show resolved Hide resolved

```ts
const authProvider: AuthProvider = {
//...
checkError: () => Promise.reject({ message: false }),
}
```

Or the `useLogoutIfAccessDenied` hook could be called with an error param as follows:

```ts
const logoutIfAccessDenied = useLogoutIfAccessDenied();
logoutIfAccessDenied(new Error('Denied'));
```

## Upgrading to v4

If you are on react-admin v3, follow the [Upgrading to v4](https://marmelab.com/react-admin/doc/4.16/Upgrade.html) guide before upgrading to v5.
32 changes: 2 additions & 30 deletions packages/ra-core/src/auth/useCheckAuth.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,18 @@ const TestComponent = ({
params,
logoutOnFailure,
redirectTo,
disableNotification,
}: {
params?: any;
logoutOnFailure?: boolean;
redirectTo?: string;
disableNotification?: boolean;
}) => {
const [authenticated, setAuthenticated] = useState(true);
const checkAuth = useCheckAuth();
useEffect(() => {
checkAuth(params, logoutOnFailure, redirectTo, disableNotification)
checkAuth(params, logoutOnFailure, redirectTo)
.then(() => setAuthenticated(true))
.catch(() => setAuthenticated(false));
}, [params, logoutOnFailure, redirectTo, disableNotification, checkAuth]);
}, [params, logoutOnFailure, redirectTo, checkAuth]);
return <div>{authenticated ? 'authenticated' : 'not authenticated'}</div>;
};

Expand Down Expand Up @@ -132,32 +130,6 @@ describe('useCheckAuth', () => {
});
});

it('should logout without showing a notification when disableNotification is true', async () => {
let location: Location;
render(
<TestMemoryRouter
initialEntries={['/']}
locationCallback={l => {
location = l;
}}
>
<AuthContext.Provider value={authProvider}>
<QueryClientProvider client={queryClient}>
<TestComponent
params={{ token: false }}
disableNotification
/>
</QueryClientProvider>
</AuthContext.Provider>
</TestMemoryRouter>
);
await waitFor(() => {
expect(notify).toHaveBeenCalledTimes(0);
expect(screen.queryByText('authenticated')).toBeNull();
expect(location.pathname).toBe('/login');
});
});

it('should logout without showing a notification when authProvider returns error with message false', async () => {
let location: Location;
render(
Expand Down
16 changes: 3 additions & 13 deletions packages/ra-core/src/auth/useCheckAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,7 @@ export const useCheckAuth = (): CheckAuth => {
);

const checkAuth = useCallback(
(
params: any = {},
logoutOnFailure = true,
redirectTo = loginUrl,
disableNotification = false
) =>
(params: any = {}, logoutOnFailure = true, redirectTo = loginUrl) =>
authProvider.checkAuth(params).catch(error => {
if (logoutOnFailure) {
logout(
Expand All @@ -66,9 +61,7 @@ export const useCheckAuth = (): CheckAuth => {
? error.redirectTo
: redirectTo
);
const shouldSkipNotify =
disableNotification ||
(error && error.message === false);
const shouldSkipNotify = error && error.message === false;
!shouldSkipNotify &&
notify(
getErrorMessage(error, 'ra.auth.auth_check_error'),
Expand All @@ -92,16 +85,13 @@ const checkAuthWithoutAuthProvider = () => Promise.resolve();
* @param {Object} params The parameters to pass to the authProvider
* @param {boolean} logoutOnFailure Whether the user should be logged out if the authProvider fails to authenticate them. True by default.
* @param {string} redirectTo The login form url. Defaults to '/login'
* @param {boolean} disableNotification Avoid showing a notification after the user is logged out. false by default.
*
* @return {Promise} Resolved to the authProvider response if the user passes the check, or rejected with an error otherwise
*/
export type CheckAuth = (
params?: any,
logoutOnFailure?: boolean,
redirectTo?: string,
/** @deprecated to disable the notification, authProvider.checkAuth() should return an object with an error property set to true */
disableNotification?: boolean
redirectTo?: string
) => Promise<any>;

const getErrorMessage = (error, defaultMessage) =>
Expand Down
59 changes: 20 additions & 39 deletions packages/ra-core/src/auth/useLogoutIfAccessDenied.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,12 @@ const authProvider: AuthProvider = {
getPermissions: () => Promise.reject('bad method'),
};

const TestComponent = ({
error,
disableNotification,
}: {
error?: any;
disableNotification?: boolean;
}) => {
const TestComponent = ({ error }: { error?: any }) => {
const [loggedOut, setLoggedOut] = useSafeSetState(false);
const logoutIfAccessDenied = useLogoutIfAccessDenied();
useEffect(() => {
logoutIfAccessDenied(error, disableNotification).then(setLoggedOut);
}, [error, disableNotification, logoutIfAccessDenied, setLoggedOut]);
logoutIfAccessDenied(error).then(setLoggedOut);
}, [error, logoutIfAccessDenied, setLoggedOut]);
return <div>{loggedOut ? '' : 'logged in'}</div>;
};

Expand Down Expand Up @@ -169,28 +163,6 @@ describe('useLogoutIfAccessDenied', () => {
expect(screen.queryByText('logged in')).toBeNull();
});

it('should logout without showing a notification if disableAuthentication is true', async () => {
render(
<Route
path="/"
element={
<TestComponent
error={new Error('denied')}
disableNotification
/>
}
/>,
{
wrapper: TestWrapper,
}
);
await waitFor(() => {
expect(authProvider.logout).toHaveBeenCalledTimes(1);
expect(notify).toHaveBeenCalledTimes(0);
expect(screen.queryByText('logged in')).toBeNull();
});
});

it('should logout without showing a notification if authProvider returns error with message false', async () => {
render(
<TestMemoryRouter>
Expand All @@ -203,14 +175,7 @@ describe('useLogoutIfAccessDenied', () => {
}}
>
<Routes>
<Route
path="/"
element={
<>
<TestComponent />
</>
}
/>
<Route path="/" element={<TestComponent />} />
</Routes>
</AuthContext.Provider>
</TestMemoryRouter>
Expand All @@ -222,6 +187,22 @@ describe('useLogoutIfAccessDenied', () => {
});
});

it('should logout without showing a notification if it has been called with error param', async () => {
render(
<Route
path="/"
element={<TestComponent error={new Error('Error')} />}
/>,
{
wrapper: TestWrapper,
}
);
await waitFor(() => {
expect(authProvider.logout).toHaveBeenCalledTimes(0);
expect(notify).toHaveBeenCalledTimes(0);
});
});

it('should notify if passed an error with a message that makes the authProvider throw', async () => {
render(
<Route
Expand Down
11 changes: 2 additions & 9 deletions packages/ra-core/src/auth/useLogoutIfAccessDenied.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ const useLogoutIfAccessDenied = (): LogoutIfAccessDenied => {
const notify = useNotify();
const navigate = useNavigate();
const logoutIfAccessDenied = useCallback(
(error?: any, disableNotification?: boolean) =>
(error?: any) =>
authProvider
.checkError(error)
.then(() => false)
.catch(async e => {
const logoutUser = e?.logoutUser ?? true;

//manual debounce
if (timer) {
// side effects already triggered in this tick, exit
Expand All @@ -68,7 +67,6 @@ const useLogoutIfAccessDenied = (): LogoutIfAccessDenied => {
: undefined;

const shouldNotify = !(
disableNotification ||
(e && e.message === false) ||
(error && error.message === false) ||
redirectTo?.startsWith('http')
Expand Down Expand Up @@ -127,15 +125,10 @@ const logoutIfAccessDeniedWithoutProvider = () => Promise.resolve(false);
* If the authProvider rejects the call, logs the user out and shows a logged out notification.
*
* @param {Error} error An Error object (usually returned by the dataProvider)
* @param {boolean} disableNotification Avoid showing a notification after the user is logged out. false by default.
*
* @return {Promise} Resolved to true if there was a logout, false otherwise
*/
type LogoutIfAccessDenied = (
error?: any,
/** @deprecated to disable the notification, authProvider.checkAuth() should return an object with an error property set to true */
disableNotification?: boolean
) => Promise<boolean>;
type LogoutIfAccessDenied = (error?: any) => Promise<boolean>;

const getErrorMessage = (error, defaultMessage) =>
typeof error === 'string'
Expand Down