Chore: Dissolve useFetchRole

This commit is contained in:
Gustav Hansen 2023-08-11 15:37:53 +02:00
parent f4ba1601a6
commit 6f37fbb69e
5 changed files with 30 additions and 195 deletions

View File

@ -1,64 +0,0 @@
import { useCallback, useEffect, useReducer, useRef } from 'react';
import { useFetchClient, useNotification } from '@strapi/helper-plugin';
import reducer, { initialState } from './reducer';
// TODO: Refactor to use react-query
export const useFetchRole = (id) => {
const [state, dispatch] = useReducer(reducer, initialState);
const toggleNotification = useNotification();
const isMounted = useRef(null);
const { get } = useFetchClient();
useEffect(() => {
isMounted.current = true;
if (id) {
fetchRole(id);
} else {
dispatch({
type: 'GET_DATA_SUCCEEDED',
role: {},
});
}
return () => (isMounted.current = false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id]);
const fetchRole = async (roleId) => {
try {
const {
data: { role },
} = await get(`/users-permissions/roles/${roleId}`);
// Prevent updating state on an unmounted component
if (isMounted.current) {
dispatch({
type: 'GET_DATA_SUCCEEDED',
role,
});
}
} catch (err) {
console.error(err);
dispatch({
type: 'GET_DATA_ERROR',
});
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
}
};
const handleSubmitSucceeded = useCallback((data) => {
dispatch({
type: 'ON_SUBMIT_SUCCEEDED',
...data,
});
}, []);
return { ...state, onSubmitSucceeded: handleSubmitSucceeded };
};

View File

@ -1,31 +0,0 @@
/* eslint-disable consistent-return */
import produce from 'immer';
export const initialState = {
role: {},
isLoading: true,
};
const reducer = (state, action) =>
produce(state, (draftState) => {
switch (action.type) {
case 'GET_DATA_SUCCEEDED': {
draftState.role = action.role;
draftState.isLoading = false;
break;
}
case 'GET_DATA_ERROR': {
draftState.isLoading = false;
break;
}
case 'ON_SUBMIT_SUCCEEDED': {
draftState.role.name = action.name;
draftState.role.description = action.description;
break;
}
default:
return draftState;
}
});
export default reducer;

View File

@ -1,90 +0,0 @@
import reducer from '../reducer';
describe('USERS PERMISSIONS | HOOKS | useFetchRole | reducer', () => {
describe('DEFAULT_ACTION', () => {
it('should return the initialState', () => {
const state = {
test: true,
};
expect(reducer(state, {})).toEqual(state);
});
});
describe('GET_DATA_ERROR', () => {
it('should set isLoading to false is an error occured', () => {
const action = {
type: 'GET_DATA_ERROR',
};
const initialState = {
role: {},
isLoading: true,
};
const expected = {
role: {},
isLoading: false,
};
expect(reducer(initialState, action)).toEqual(expected);
});
});
describe('GET_DATA_SUCCEEDED', () => {
it('should return the state with the data', () => {
const action = {
type: 'GET_DATA_SUCCEEDED',
role: {
id: 1,
name: 'Authenticated',
description: 'This is the Authenticated role',
permissions: {},
},
};
const initialState = {
role: {},
isLoading: true,
};
const expected = {
role: {
id: 1,
name: 'Authenticated',
description: 'This is the Authenticated role',
permissions: {},
},
isLoading: false,
};
expect(reducer(initialState, action)).toEqual(expected);
});
});
describe('ON_SUBMIT_SUCCEEDED', () => {
it("should set the role's name and description correctly", () => {
const state = {
role: {
id: 1,
name: 'Authenticated',
description: 'This is the Authenticated role',
permissions: {},
},
};
const action = {
type: 'ON_SUBMIT_SUCCEEDED',
name: 'Public',
description: 'test',
};
const expected = {
role: {
id: 1,
name: 'Public',
description: 'test',
permissions: {},
},
};
expect(reducer(state, action)).toEqual(expected);
});
});
});

View File

@ -22,17 +22,21 @@ export const usePlugins = () => {
{
queryKey: ['users-permissions', 'permissions'],
async queryFn() {
const res = await get(`/users-permissions/permissions`);
const {
data: { permissions },
} = await get(`/users-permissions/permissions`);
return res.data.permissions;
return permissions;
},
},
{
queryKey: ['users-permissions', 'routes'],
async queryFn() {
const res = await get(`/users-permissions/routes`);
const {
data: { routes },
} = await get(`/users-permissions/routes`);
return res.data.routes;
return routes;
},
},
]);
@ -62,8 +66,12 @@ export const usePlugins = () => {
const isLoading = isLoadingPermissions || isLoadingRoutes;
return {
// TODO: these return values need to be memoized, otherwise
// they will create infinite rendering loops when used as
// effect dependencies
permissions: permissions ? cleanPermissions(permissions) : {},
routes: routes ?? {},
getData: refetchQueries,
isLoading,
};

View File

@ -13,23 +13,22 @@ import {
Grid,
} from '@strapi/design-system';
import {
useFetchClient,
useOverlayBlocker,
SettingsPageTitle,
LoadingIndicatorPage,
Form,
useAPIErrorHandler,
useFetchClient,
useNotification,
Link,
} from '@strapi/helper-plugin';
import { ArrowLeft, Check } from '@strapi/icons';
import { Formik } from 'formik';
import { useIntl } from 'react-intl';
import { useMutation } from 'react-query';
import { useQuery, useMutation } from 'react-query';
import { useRouteMatch } from 'react-router-dom';
import UsersPermissions from '../../../components/UsersPermissions';
import { useFetchRole } from '../../../hooks/useFetchRole';
import { usePlugins } from '../../../hooks/usePlugins';
import getTrad from '../../../utils/getTrad';
import { createRoleSchema } from '../constants';
@ -41,8 +40,21 @@ export const EditPage = () => {
const {
params: { id },
} = useRouteMatch(`/settings/users-permissions/roles/:id`);
const { get } = useFetchClient();
const { isLoading: isLoadingPlugins, routes } = usePlugins();
const { role, onSubmitSucceeded, isLoading: isLoadingRole } = useFetchRole(id);
const {
data: role,
isLoading: isLoadingRole,
refetch: refetchRole,
} = useQuery(['users-permissions', 'role', id], async () => {
// TODO: why doesn't this endpoint follow the admin API conventions?
const {
data: { role },
} = await get(`/users-permissions/roles/${id}`);
return role;
});
const permissionsRef = React.useRef();
const { put } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
@ -54,7 +66,7 @@ export const EditPage = () => {
});
},
onSuccess(data) {
async onSuccess() {
toggleNotification({
type: 'success',
message: {
@ -63,7 +75,7 @@ export const EditPage = () => {
},
});
onSubmitSucceeded({ name: data.name, description: data.description });
await refetchRole();
},
});