mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 18:33:55 +00:00
add delete role
This commit is contained in:
parent
3c5f2d2d1d
commit
f9e98e6d09
@ -1,8 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
// TODO : Temporary baseline alignment
|
||||
const BaselineAlignment = styled.div`
|
||||
padding-top: 3px;
|
||||
`;
|
||||
|
||||
export default BaselineAlignment;
|
||||
@ -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,
|
||||
};
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user