diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/index.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/index.js index 89c9f591b1..9707c15d51 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/index.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/index.js @@ -1,10 +1,33 @@ import React from 'react'; -import { Button, HeaderLayout, Layout, Main } from '@strapi/parts'; -import { AddIcon } from '@strapi/icons'; +import { + Button, + ContentLayout, + HeaderLayout, + IconButton, + Layout, + Main, + Table, + Tbody, + Text, + Tr, + Td, + Thead, + Th, + TableLabel, +} from '@strapi/parts'; +import { AddIcon, EditIcon } from '@strapi/icons'; import { useIntl } from 'react-intl'; -import { useTracking, SettingsPageTitle, CheckPermissions } from '@strapi/helper-plugin'; +import { + useTracking, + SettingsPageTitle, + CheckPermissions, + LoadingIndicatorPage, + useNotification, +} from '@strapi/helper-plugin'; import { useHistory } from 'react-router-dom'; +import { useQuery } from 'react-query'; +import { fetchData } from './utils/api'; import { getTrad } from '../../../utils'; import pluginId from '../../../pluginId'; import permissions from '../../../permissions'; @@ -13,6 +36,15 @@ const RoleListPage = () => { const { trackUsage } = useTracking(); const { formatMessage } = useIntl(); const { push } = useHistory(); + const toggleNotification = useNotification(); + + const { + isLoading: isLoadingForData, + data: { roles }, + isFetching, + } = useQuery('get-roles', () => fetchData(toggleNotification), { initialData: {} }); + + const isLoading = isLoadingForData || isFetching; const handleNewRoleClick = () => { trackUsage('willCreateRole'); @@ -24,6 +56,10 @@ const RoleListPage = () => { defaultMessage: 'Roles', }); + const handleClickEdit = id => { + push(`/settings/${pluginId}/roles/${id}`); + }; + return ( @@ -55,6 +91,64 @@ const RoleListPage = () => { } /> + {isLoading ? ( + + ) : ( + + + + + + + + + + + {roles.map(role => ( + + + + + + + ))} + +
+ + {formatMessage({ id: getTrad('Roles.name'), defaultMessage: 'Name' })} + + + + {formatMessage({ + id: getTrad('Roles.descriptions'), + defaultMessage: 'Description', + })} + + + + {formatMessage({ + id: getTrad('Roles.users'), + defaultMessage: 'Users', + })} + +
+ {role.name} + + {role.description} + + {role.nb_users} users + + + handleClickEdit(role.id)} + noBorder + icon={} + label="Edit" + /> + +
+
+ )}
); diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js index 580b2cdf49..52dc4b0498 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js @@ -1,9 +1,11 @@ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { IntlProvider } from 'react-intl'; +import { QueryClient, QueryClientProvider } from 'react-query'; import { ThemeProvider, lightTheme } from '@strapi/parts'; import RoleListPage from '../index'; +import server from './server'; jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), @@ -19,15 +21,35 @@ jest.mock('react-router-dom', () => ({ }), })); +const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}); + const App = ( - - - + + + + + ); describe('Admin | containers | RoleListPage', () => { + beforeAll(() => server.listen()); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterEach(() => server.resetHandlers()); + + afterAll(() => server.close()); + it('renders and matches the snapshot', () => { const { container: { firstChild }, @@ -110,6 +132,41 @@ describe('Admin | containers | RoleListPage', () => { outline: none; } + .c11 { + border: 0; + -webkit-clip: rect(0 0 0 0); + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + } + + .c12 { + -webkit-animation: gzYjWD 1s infinite linear; + animation: gzYjWD 1s infinite linear; + } + + .c10 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-pack: space-around; + -webkit-justify-content: space-around; + -ms-flex-pack: space-around; + justify-content: space-around; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + } +
@@ -152,9 +209,44 @@ describe('Admin | containers | RoleListPage', () => {

+
+
+
+ Loading content. +
+ +
+
`); }); + + it('should show a loader when fetching data', () => { + render(App); + + expect(screen.getByTestId('loader')).toBeInTheDocument(); + }); + + it('should show a list of roles', async () => { + render(App); + + await waitFor(() => { + expect(screen.getByText('Authenticated')).toBeInTheDocument(); + expect(screen.getByText('Public')).toBeInTheDocument(); + }); + }); }); diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js new file mode 100644 index 0000000000..4fc68e8050 --- /dev/null +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js @@ -0,0 +1,33 @@ +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; + +const handlers = [ + rest.get('*/roles', (req, res, ctx) => { + return res( + ctx.delay(1000), + ctx.status(200), + ctx.json({ + roles: [ + { + id: 1, + name: 'Authenticated', + description: 'Default role given to authenticated user.', + type: 'authenticated', + nb_users: 0, + }, + { + id: 2, + name: 'Public', + description: 'Default role given to unauthenticated user.', + type: 'public', + nb_users: 0, + }, + ], + }) + ); + }), +]; + +const server = setupServer(...handlers); + +export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js new file mode 100644 index 0000000000..251d6acb66 --- /dev/null +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js @@ -0,0 +1,17 @@ +import { getRequestURL, axiosInstance } from '../../../../utils'; + +// eslint-disable-next-line import/prefer-default-export +export const fetchData = async toggleNotification => { + try { + const { data } = await axiosInstance.get(getRequestURL('roles')); + + return data; + } catch (err) { + toggleNotification({ + type: 'warning', + message: { id: 'notification.error' }, + }); + + throw new Error('error'); + } +};