mirror of
https://github.com/strapi/strapi.git
synced 2025-11-10 07:10:11 +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 {
|
import {
|
||||||
Button,
|
Button,
|
||||||
HeaderLayout,
|
HeaderLayout,
|
||||||
IconButton,
|
|
||||||
Layout,
|
Layout,
|
||||||
Main,
|
Main,
|
||||||
Table,
|
Table,
|
||||||
Tbody,
|
|
||||||
Text,
|
|
||||||
Tr,
|
Tr,
|
||||||
Td,
|
|
||||||
Thead,
|
Thead,
|
||||||
Th,
|
Th,
|
||||||
TableLabel,
|
TableLabel,
|
||||||
@ -18,8 +14,7 @@ import {
|
|||||||
ActionLayout,
|
ActionLayout,
|
||||||
VisuallyHidden,
|
VisuallyHidden,
|
||||||
} from '@strapi/parts';
|
} from '@strapi/parts';
|
||||||
import { AddIcon, EditIcon } from '@strapi/icons';
|
import { AddIcon } from '@strapi/icons';
|
||||||
import { useIntl } from 'react-intl';
|
|
||||||
import {
|
import {
|
||||||
useTracking,
|
useTracking,
|
||||||
SettingsPageTitle,
|
SettingsPageTitle,
|
||||||
@ -31,15 +26,18 @@ import {
|
|||||||
Search,
|
Search,
|
||||||
useQueryParams,
|
useQueryParams,
|
||||||
EmptyStateLayout,
|
EmptyStateLayout,
|
||||||
|
ConfirmDialog,
|
||||||
} from '@strapi/helper-plugin';
|
} from '@strapi/helper-plugin';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useQuery } from 'react-query';
|
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||||
import matchSorter from 'match-sorter';
|
import matchSorter from 'match-sorter';
|
||||||
|
|
||||||
import { fetchData } from './utils/api';
|
import { fetchData, deleteData } from './utils/api';
|
||||||
import { getTrad } from '../../../utils';
|
import { getTrad } from '../../../utils';
|
||||||
import pluginId from '../../../pluginId';
|
import pluginId from '../../../pluginId';
|
||||||
import permissions from '../../../permissions';
|
import permissions from '../../../permissions';
|
||||||
|
import TableBody from './components/TableBody';
|
||||||
|
|
||||||
const RoleListPage = () => {
|
const RoleListPage = () => {
|
||||||
const { trackUsage } = useTracking();
|
const { trackUsage } = useTracking();
|
||||||
@ -49,6 +47,11 @@ const RoleListPage = () => {
|
|||||||
const { notifyStatus } = useNotifyAT();
|
const { notifyStatus } = useNotifyAT();
|
||||||
const [{ query }] = useQueryParams();
|
const [{ query }] = useQueryParams();
|
||||||
const _q = query?._q || '';
|
const _q = query?._q || '';
|
||||||
|
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
||||||
|
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
|
||||||
|
const [roleToDelete, setRoleToDelete] = useState();
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const updatePermissions = useMemo(() => {
|
const updatePermissions = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -61,7 +64,7 @@ const RoleListPage = () => {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading: isLoadingForPermissions,
|
isLoading: isLoadingForPermissions,
|
||||||
allowedActions: { canRead },
|
allowedActions: { canRead, canDelete },
|
||||||
} = useRBAC(updatePermissions);
|
} = useRBAC(updatePermissions);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -80,13 +83,8 @@ const RoleListPage = () => {
|
|||||||
push(`/settings/${pluginId}/roles/new`);
|
push(`/settings/${pluginId}/roles/new`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageTitle = formatMessage({
|
const handleShowConfirmDelete = () => {
|
||||||
id: getTrad('HeaderNav.link.roles'),
|
setShowConfirmDelete(!showConfirmDelete);
|
||||||
defaultMessage: 'Roles',
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleClickEdit = id => {
|
|
||||||
push(`/settings/${pluginId}/roles/${id}`);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const emptyLayout = {
|
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 sortedRoles = matchSorter(roles || [], _q, { keys: ['name', 'description'] });
|
||||||
const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';
|
const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';
|
||||||
|
|
||||||
@ -131,7 +157,7 @@ const RoleListPage = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<ContentLayout>
|
<ContentLayout>
|
||||||
<ActionLayout withPadding={false} startActions={<Search />} />
|
<ActionLayout withPadding={false} startActions={<Search label="search" />} />
|
||||||
{!canRead && <NoPermissions />}
|
{!canRead && <NoPermissions />}
|
||||||
{(isLoading || isLoadingForPermissions) && <LoadingIndicatorPage />}
|
{(isLoading || isLoadingForPermissions) && <LoadingIndicatorPage />}
|
||||||
{canRead && sortedRoles && sortedRoles?.length ? (
|
{canRead && sortedRoles && sortedRoles?.length ? (
|
||||||
@ -169,41 +195,25 @@ const RoleListPage = () => {
|
|||||||
</Th>
|
</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<TableBody
|
||||||
{sortedRoles?.map(role => (
|
sortedRoles={sortedRoles}
|
||||||
<Tr key={role.name}>
|
canDelete={canDelete}
|
||||||
<Td width="20%">
|
permissions={permissions}
|
||||||
<Text label="name">{role.name}</Text>
|
setRoleToDelete={setRoleToDelete}
|
||||||
</Td>
|
setShowConfirmDelete={setShowConfirmDelete}
|
||||||
<Td width="50%">
|
showConfirmDelete={showConfirmDelete}
|
||||||
<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>
|
|
||||||
</Table>
|
</Table>
|
||||||
) : (
|
) : (
|
||||||
<EmptyStateLayout content={emptyLayout[emptyContent]} />
|
<EmptyStateLayout content={emptyLayout[emptyContent]} />
|
||||||
)}
|
)}
|
||||||
</ContentLayout>
|
</ContentLayout>
|
||||||
|
<ConfirmDialog
|
||||||
|
isConfirmButtonLoading={isConfirmButtonLoading}
|
||||||
|
onConfirm={handleConfirmDelete}
|
||||||
|
onToggleDialog={handleShowConfirmDelete}
|
||||||
|
isOpen={showConfirmDelete}
|
||||||
|
/>
|
||||||
</Main>
|
</Main>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -15,3 +15,11 @@ export const fetchData = async (toggleNotification, notifyStatus) => {
|
|||||||
throw new Error('error');
|
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