Skip to content

Commit

Permalink
Merge pull request #16791 from strapi/chore/refactor-use-models-hook
Browse files Browse the repository at this point in the history
Chore: Refactor useModels to use react-query rather than useReducer
  • Loading branch information
gu-stav committed May 22, 2023
2 parents 141d367 + 59a4651 commit e1dcf25
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 252 deletions.
25 changes: 25 additions & 0 deletions docs/docs/docs/01-core/content-manager/hooks/use-content-types.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: useContentTypes
description: API reference for the useContentTypes hook in Strapi's Content Manager
tags:
- content-manager
- hooks
- fetch
- content-types
- components
---

An abstraction around `react-query` to fetch content-types and components. It returns the raw API response
for components. `collectionTypes` and `singleTypes` are filtered by `isDisplayed=true`.

## Usage

```jsx
import { useContentTypes } from 'path/to/hooks';

const MyComponent = () => {
const { isLoading, collectionTypes, singleTypes, components } = useContentTypes();

return (/* ... */);
};
```
2 changes: 1 addition & 1 deletion packages/core/admin/admin/src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as useConfigurations } from './useConfigurations';
export { default as useModels } from './useModels';
export { useContentTypes } from './useContentTypes';
export { default as useFetchPermissionsLayout } from './useFetchPermissionsLayout';
export { default as useFetchRole } from './useFetchRole';
export { default as useMenu } from './useMenu';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const useContentTypes = jest.fn().mockReturnValue({
isLoading: false,
components: [],
collectionTypes: [],
singleTypes: [],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useContentTypes';
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import * as React from 'react';
import { setupServer } from 'msw/node';
import { rest } from 'msw';
import { renderHook, waitFor } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import { QueryClient, QueryClientProvider } from 'react-query';

import { useContentTypes } from '../useContentTypes';

jest.mock('@strapi/helper-plugin', () => ({
...jest.requireActual('@strapi/helper-plugin'),
useNotification: jest.fn().mockReturnValue(jest.fn),
}));

const server = setupServer(
rest.get('*/content-manager/content-types', (req, res, ctx) =>
res(
ctx.json({
data: [
{
uid: 'admin::collectionType',
isDisplayed: true,
apiID: 'permission',
kind: 'collectionType',
},

{
uid: 'admin::collectionTypeNotDispalyed',
isDisplayed: false,
apiID: 'permission',
kind: 'collectionType',
},

{
uid: 'admin::singleType',
isDisplayed: true,
kind: 'singleType',
},

{
uid: 'admin::singleTypeNotDispalyed',
isDisplayed: false,
kind: 'singleType',
},
],
})
)
),
rest.get('*/content-manager/components', (req, res, ctx) =>
res(
ctx.json({
data: [
{
uid: 'basic.relation',
isDisplayed: true,
apiID: 'relation',
category: 'basic',
info: {
displayName: 'Relation',
},
options: {},
attributes: {
id: {
type: 'integer',
},
categories: {
type: 'relation',
relation: 'oneToMany',
target: 'api::category.category',
targetModel: 'api::category.category',
relationType: 'oneToMany',
},
},
},
],
})
)
)
);

const setup = () =>
renderHook(() => useContentTypes(), {
wrapper({ children }) {
const client = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});

return (
<QueryClientProvider client={client}>
<IntlProvider locale="en" messages={{}}>
{children}
</IntlProvider>
,
</QueryClientProvider>
);
},
});

describe('useContentTypes', () => {
beforeAll(() => {
server.listen();
});

afterAll(() => {
server.close();
});

test('fetches models and content-types', async () => {
const { result } = setup();

expect(result.current.isLoading).toBe(true);

expect(result.current.components).toStrictEqual([]);
expect(result.current.singleTypes).toStrictEqual([]);
expect(result.current.collectionTypes).toStrictEqual([]);

await waitFor(() => expect(result.current.isLoading).toBe(false));

expect(result.current.components).toStrictEqual(
expect.arrayContaining([
expect.objectContaining({
uid: 'basic.relation',
}),
])
);

expect(result.current.collectionTypes).toStrictEqual([
expect.objectContaining({
uid: 'admin::collectionType',
}),
]);

expect(result.current.singleTypes).toStrictEqual([
expect.objectContaining({
uid: 'admin::singleType',
}),
]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useAPIErrorHandler, useFetchClient, useNotification } from '@strapi/helper-plugin';
import { useQueries } from 'react-query';

export function useContentTypes() {
const { get } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const toggleNotification = useNotification();
const queries = useQueries(
['components', 'content-types'].map((type) => {
return {
queryKey: ['content-manager', type],
async queryFn() {
const {
data: { data },
} = await get(`/content-manager/${type}`);

return data;
},
onError(error) {
toggleNotification({
type: 'warning',
message: formatAPIError(error),
});
},
};
})
);

const [components, contentTypes] = queries;
const isLoading = components.isLoading || contentTypes.isLoading;

const collectionTypes = (contentTypes?.data ?? []).filter(
(contentType) => contentType.kind === 'collectionType' && contentType.isDisplayed
);
const singleTypes = (contentTypes?.data ?? []).filter(
(contentType) => contentType.kind !== 'collectionType' && contentType.isDisplayed
);

return {
isLoading,
components: components?.data ?? [],
collectionTypes,
singleTypes,
};
}
58 changes: 0 additions & 58 deletions packages/core/admin/admin/src/hooks/useModels/index.js

This file was deleted.

45 changes: 0 additions & 45 deletions packages/core/admin/admin/src/hooks/useModels/reducer.js

This file was deleted.

Loading

0 comments on commit e1dcf25

Please sign in to comment.