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 ? (
+
+ ) : (
+
+
+
+
+
+
+ {formatMessage({ id: getTrad('Roles.name'), defaultMessage: 'Name' })}
+
+ |
+
+
+ {formatMessage({
+ id: getTrad('Roles.descriptions'),
+ defaultMessage: 'Description',
+ })}
+
+ |
+
+
+ {formatMessage({
+ id: getTrad('Roles.users'),
+ defaultMessage: 'Users',
+ })}
+
+ |
+
+
+
+ {roles.map(role => (
+
+
+ {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');
+ }
+};