mirror of
https://github.com/logto-io/logto.git
synced 2025-01-06 20:40:08 -05:00
feat(console): create role (#2822)
This commit is contained in:
parent
6230775a4b
commit
8b18744642
12 changed files with 166 additions and 1 deletions
|
@ -86,6 +86,7 @@ const Main = () => {
|
|||
</Route>
|
||||
<Route path="roles">
|
||||
<Route index element={<Roles />} />
|
||||
<Route path="create" element={<Roles />} />
|
||||
<Route path=":id" element={<RoleDetails />} />
|
||||
</Route>
|
||||
<Route path="settings" element={<Settings />} />
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import type { Role } from '@logto/schemas';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import FormField from '@/components/FormField';
|
||||
import ModalLayout from '@/components/ModalLayout';
|
||||
import TextInput from '@/components/TextInput';
|
||||
import useApi from '@/hooks/use-api';
|
||||
|
||||
export type Props = {
|
||||
onClose: (createdRole?: Role) => void;
|
||||
};
|
||||
|
||||
type CreateRoleFormData = Pick<Role, 'name' | 'description'>;
|
||||
|
||||
const CreateRoleForm = ({ onClose }: Props) => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
formState: { isSubmitting },
|
||||
} = useForm<CreateRoleFormData>();
|
||||
|
||||
const api = useApi();
|
||||
|
||||
const onSubmit = handleSubmit(async (formData) => {
|
||||
if (isSubmitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
const createdRole = await api.post('/api/roles', { json: formData }).json<Role>();
|
||||
onClose(createdRole);
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
title="roles.create_role_title"
|
||||
subtitle="roles.create_role_description"
|
||||
footer={
|
||||
<Button
|
||||
isLoading={isSubmitting}
|
||||
htmlType="submit"
|
||||
title="roles.create_role_button"
|
||||
size="large"
|
||||
type="primary"
|
||||
onClick={onSubmit}
|
||||
/>
|
||||
}
|
||||
onClose={onClose}
|
||||
>
|
||||
<form>
|
||||
<FormField isRequired title="roles.role_name">
|
||||
<TextInput
|
||||
// eslint-disable-next-line jsx-a11y/no-autofocus
|
||||
autoFocus
|
||||
{...register('name', { required: true })}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField title="roles.role_description">
|
||||
<TextInput {...register('description')} />
|
||||
</FormField>
|
||||
</form>
|
||||
</ModalLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateRoleForm;
|
|
@ -0,0 +1,45 @@
|
|||
import type { Role } from '@logto/schemas';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ReactModal from 'react-modal';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
|
||||
import type { Props as CreateRoleFormProps } from '../CreateRoleForm';
|
||||
import CreateRoleForm from '../CreateRoleForm';
|
||||
|
||||
type Props = {
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
const CreateRoleModal = ({ onClose }: Props) => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onCreateFormClose: CreateRoleFormProps['onClose'] = (createdRole?: Role) => {
|
||||
if (createdRole) {
|
||||
// TODO @xiaoyijun open assigning role to users modal
|
||||
navigate(`/roles/${createdRole.id}`, { replace: true });
|
||||
toast.success(t('roles.role_created', { name: createdRole.name }));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen
|
||||
shouldCloseOnEsc
|
||||
className={modalStyles.content}
|
||||
overlayClassName={modalStyles.overlay}
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<CreateRoleForm onClose={onCreateFormClose} />
|
||||
</ReactModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateRoleModal;
|
|
@ -1,6 +1,6 @@
|
|||
import type { Role } from '@logto/schemas';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import Plus from '@/assets/images/plus.svg';
|
||||
|
@ -11,13 +11,17 @@ import Table from '@/components/Table';
|
|||
import type { RequestError } from '@/hooks/use-api';
|
||||
import * as pageStyles from '@/scss/resources.module.scss';
|
||||
|
||||
import CreateRoleModal from './components/CreateRoleModal';
|
||||
|
||||
const rolesPathname = '/roles';
|
||||
const createRolePathname = `${rolesPathname}/create`;
|
||||
const buildDetailsPathname = (id: string) => `${rolesPathname}/${id}`;
|
||||
|
||||
const Roles = () => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const isOnCreatePage = pathname === createRolePathname;
|
||||
const { data: roles, error, mutate } = useSWR<Role[], RequestError>(`/api/roles`);
|
||||
const isLoading = !roles && !error;
|
||||
|
||||
|
@ -71,6 +75,13 @@ const Roles = () => {
|
|||
}}
|
||||
onRetry={async () => mutate(undefined, true)}
|
||||
/>
|
||||
{isOnCreatePage && (
|
||||
<CreateRoleModal
|
||||
onClose={() => {
|
||||
navigate(rolesPathname);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles',
|
||||
role_name: 'Role',
|
||||
role_description: 'Description',
|
||||
create_role_title: 'Create a role',
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.',
|
||||
create_role_button: 'Create role',
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
|
@ -5,6 +5,11 @@ const roles = {
|
|||
create: 'Add Roles', // UNTRANSLATED
|
||||
role_name: 'Role', // UNTRANSLATED
|
||||
role_description: 'Description', // UNTRANSLATED
|
||||
create_role_title: 'Create a role', // UNTRANSLATED
|
||||
create_role_description:
|
||||
'Create and manage Roles for your applications. Roles contain collections of Permissions and can be assigned to Users.', // UNTRANSLATED
|
||||
create_role_button: 'Create role', // UNTRANSLATED
|
||||
role_created: 'The role {{name}} has been successfully created!', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default roles;
|
||||
|
|
Loading…
Reference in a new issue