add delete role

This commit is contained in:
Mark Kaylor 2021-09-10 09:49:08 +02:00
parent 3c5f2d2d1d
commit f9e98e6d09
4 changed files with 165 additions and 56 deletions

View File

@ -1,8 +0,0 @@
import styled from 'styled-components';
// TODO : Temporary baseline alignment
const BaselineAlignment = styled.div`
padding-top: 3px;
`;
export default BaselineAlignment;

View File

@ -0,0 +1,99 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { IconButton, Tbody, Text, Tr, Td, Row } from '@strapi/parts';
import { EditIcon, DeleteIcon } from '@strapi/icons';
import { CheckPermissions } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { getTrad } from '../../../../utils';
import pluginId from '../../../../pluginId';
const TableBody = ({
sortedRoles,
canDelete,
permissions,
setRoleToDelete,
setShowConfirmDelete,
showConfirmDelete,
}) => {
const { formatMessage } = useIntl();
const { push } = useHistory();
const checkCanDeleteRole = useCallback(
role => {
return canDelete && !['public', 'authenticated'].includes(role.type);
},
[canDelete]
);
const handleClickDelete = id => {
setRoleToDelete(id);
setShowConfirmDelete(!showConfirmDelete);
};
const handleClickEdit = id => {
push(`/settings/${pluginId}/roles/${id}`);
};
return (
<Tbody>
{sortedRoles?.map(role => (
<Tr key={role.name}>
<Td width="20%">
<Text>{role.name}</Text>
</Td>
<Td width="50%">
<Text>{role.description}</Text>
</Td>
<Td width="30%">
<Text>
{`${role.nb_users} ${formatMessage({
id: getTrad('Roles.users'),
defaultMessage: 'users',
}).toLowerCase()}`}
</Text>
</Td>
<Td>
<Row>
<CheckPermissions permissions={permissions.updateRole}>
<IconButton
onClick={() => handleClickEdit(role.id)}
noBorder
icon={<EditIcon />}
label="Edit"
/>
</CheckPermissions>
{checkCanDeleteRole(role) && (
<CheckPermissions permissions={permissions.deleteRole}>
<IconButton
onClick={() => handleClickDelete(role.id)}
noBorder
icon={<DeleteIcon />}
label="Delete"
/>
</CheckPermissions>
)}
</Row>
</Td>
</Tr>
))}
</Tbody>
);
};
export default TableBody;
TableBody.defaultProps = {
canDelete: false,
showConfirmDelete: false,
};
TableBody.propTypes = {
permissions: PropTypes.object.isRequired,
setRoleToDelete: PropTypes.func.isRequired,
setShowConfirmDelete: PropTypes.func.isRequired,
sortedRoles: PropTypes.array.isRequired,
canDelete: PropTypes.bool,
showConfirmDelete: PropTypes.bool,
};

View File

@ -1,15 +1,11 @@
import React, { useMemo } from 'react';
import React, { useMemo, useState } from 'react';
import {
Button,
HeaderLayout,
IconButton,
Layout,
Main,
Table,
Tbody,
Text,
Tr,
Td,
Thead,
Th,
TableLabel,
@ -18,8 +14,7 @@ import {
ActionLayout,
VisuallyHidden,
} from '@strapi/parts';
import { AddIcon, EditIcon } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { AddIcon } from '@strapi/icons';
import {
useTracking,
SettingsPageTitle,
@ -31,15 +26,18 @@ import {
Search,
useQueryParams,
EmptyStateLayout,
ConfirmDialog,
} from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { useQuery } from 'react-query';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import matchSorter from 'match-sorter';
import { fetchData } from './utils/api';
import { fetchData, deleteData } from './utils/api';
import { getTrad } from '../../../utils';
import pluginId from '../../../pluginId';
import permissions from '../../../permissions';
import TableBody from './components/TableBody';
const RoleListPage = () => {
const { trackUsage } = useTracking();
@ -49,6 +47,11 @@ const RoleListPage = () => {
const { notifyStatus } = useNotifyAT();
const [{ query }] = useQueryParams();
const _q = query?._q || '';
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
const [roleToDelete, setRoleToDelete] = useState();
const queryClient = useQueryClient();
const updatePermissions = useMemo(() => {
return {
@ -61,7 +64,7 @@ const RoleListPage = () => {
const {
isLoading: isLoadingForPermissions,
allowedActions: { canRead },
allowedActions: { canRead, canDelete },
} = useRBAC(updatePermissions);
const {
@ -80,13 +83,8 @@ const RoleListPage = () => {
push(`/settings/${pluginId}/roles/new`);
};
const pageTitle = formatMessage({
id: getTrad('HeaderNav.link.roles'),
defaultMessage: 'Roles',
});
const handleClickEdit = id => {
push(`/settings/${pluginId}/roles/${id}`);
const handleShowConfirmDelete = () => {
setShowConfirmDelete(!showConfirmDelete);
};
const emptyLayout = {
@ -100,6 +98,34 @@ const RoleListPage = () => {
},
};
const pageTitle = formatMessage({
id: getTrad('HeaderNav.link.roles'),
defaultMessage: 'Roles',
});
const deleteMutation = useMutation(id => deleteData(id), {
onSuccess: async () => {
await queryClient.invalidateQueries('get-roles');
},
onError: err => {
if (err?.response?.data?.data) {
toggleNotification({ type: 'warning', message: err.response.data.data });
} else {
toggleNotification({
type: 'warning',
message: { id: 'notification.error', defaultMessage: 'An error occured' },
});
}
},
});
const handleConfirmDelete = async () => {
setIsConfirmButtonLoading(true);
await deleteMutation.mutateAsync(roleToDelete);
setShowConfirmDelete(!showConfirmDelete);
setIsConfirmButtonLoading(false);
};
const sortedRoles = matchSorter(roles || [], _q, { keys: ['name', 'description'] });
const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';
@ -131,7 +157,7 @@ const RoleListPage = () => {
}
/>
<ContentLayout>
<ActionLayout withPadding={false} startActions={<Search />} />
<ActionLayout withPadding={false} startActions={<Search label="search" />} />
{!canRead && <NoPermissions />}
{(isLoading || isLoadingForPermissions) && <LoadingIndicatorPage />}
{canRead && sortedRoles && sortedRoles?.length ? (
@ -169,41 +195,25 @@ const RoleListPage = () => {
</Th>
</Tr>
</Thead>
<Tbody>
{sortedRoles?.map(role => (
<Tr key={role.name}>
<Td width="20%">
<Text label="name">{role.name}</Text>
</Td>
<Td width="50%">
<Text label="description">{role.description}</Text>
</Td>
<Td width="30%">
<Text label="users">
{`${role.nb_users} ${formatMessage({
id: getTrad('Roles.users'),
defaultMessage: 'users',
}).toLowerCase()}`}
</Text>
</Td>
<Td>
<CheckPermissions permissions={permissions.updateRole}>
<IconButton
onClick={() => handleClickEdit(role.id)}
noBorder
icon={<EditIcon />}
label="Edit"
/>
</CheckPermissions>
</Td>
</Tr>
))}
</Tbody>
<TableBody
sortedRoles={sortedRoles}
canDelete={canDelete}
permissions={permissions}
setRoleToDelete={setRoleToDelete}
setShowConfirmDelete={setShowConfirmDelete}
showConfirmDelete={showConfirmDelete}
/>
</Table>
) : (
<EmptyStateLayout content={emptyLayout[emptyContent]} />
)}
</ContentLayout>
<ConfirmDialog
isConfirmButtonLoading={isConfirmButtonLoading}
onConfirm={handleConfirmDelete}
onToggleDialog={handleShowConfirmDelete}
isOpen={showConfirmDelete}
/>
</Main>
</Layout>
);

View File

@ -15,3 +15,11 @@ export const fetchData = async (toggleNotification, notifyStatus) => {
throw new Error('error');
}
};
export const deleteData = async id => {
try {
await axiosInstance.delete(`${getRequestURL('roles')}/${id}`);
} catch (error) {
console.log('error', error);
}
};