0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

feat(console): create organization role ()

This commit is contained in:
Xiao Yijun 2024-04-03 22:40:53 +08:00 committed by GitHub
parent d6cd67be76
commit 6ed7ab5ef9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 279 additions and 71 deletions
packages
console/src/pages/OrganizationTemplate/OrganizationRoles
phrases/src/locales
de/translation/admin-console
en/translation/admin-console
es/translation/admin-console
fr/translation/admin-console
it/translation/admin-console
ja/translation/admin-console
ko/translation/admin-console
pl-pl/translation/admin-console
pt-br/translation/admin-console
pt-pt/translation/admin-console
ru/translation/admin-console
tr-tr/translation/admin-console
zh-cn/translation/admin-console
zh-hk/translation/admin-console
zh-tw/translation/admin-console

View file

@ -0,0 +1,86 @@
import { type OrganizationRole } from '@logto/schemas';
import { useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import ReactModal from 'react-modal';
import Button from '@/ds-components/Button';
import FormField from '@/ds-components/FormField';
import ModalLayout from '@/ds-components/ModalLayout';
import TextInput from '@/ds-components/TextInput';
import useApi from '@/hooks/use-api';
import * as modalStyles from '@/scss/modal.module.scss';
import { trySubmitSafe } from '@/utils/form';
type FormData = Pick<OrganizationRole, 'name' | 'description'>;
type Props = {
onClose: (createdOrganizationRole?: OrganizationRole) => void;
};
function CreateOrganizationRoleModal({ onClose }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const {
register,
formState: { errors, isSubmitting },
handleSubmit,
} = useForm<FormData>();
const api = useApi();
const submit = handleSubmit(
trySubmitSafe(async (formData) => {
const createdData = await api
.post('api/organization-roles', { json: formData })
.json<OrganizationRole>();
toast.success(
t('organization_template.roles.create_modal.created', { name: createdData.name })
);
onClose(createdData);
})
);
return (
<ReactModal
isOpen
className={modalStyles.content}
overlayClassName={modalStyles.overlay}
onRequestClose={() => {
onClose();
}}
>
<ModalLayout
title="organization_template.roles.create_modal.title"
footer={
<Button
type="primary"
title="organization_template.roles.create_modal.create"
isLoading={isSubmitting}
onClick={submit}
/>
}
onClose={onClose}
>
<FormField isRequired title="organization_template.roles.create_modal.name_field">
<TextInput
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
placeholder="viewer"
error={Boolean(errors.name)}
{...register('name', { required: true })}
/>
</FormField>
<FormField title="organization_template.permissions.description_field_name">
<TextInput
placeholder={t('organization_role_details.general.description_field_placeholder')}
error={Boolean(errors.description)}
{...register('description')}
/>
</FormField>
</ModalLayout>
</ReactModal>
);
}
export default CreateOrganizationRoleModal;

View file

@ -1,4 +1,5 @@
import { type OrganizationRoleWithScopes } from '@logto/schemas';
import { useState } from 'react';
import useSWR from 'swr';
import Plus from '@/assets/icons/plus.svg';
@ -20,6 +21,7 @@ import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import { buildUrl } from '@/utils/url';
import CreateOrganizationRoleModal from './CreateOrganizationRoleModal';
import * as styles from './index.module.scss';
function OrganizationRoles() {
@ -41,88 +43,103 @@ function OrganizationRoles() {
const [orgRoles, totalCount] = data ?? [];
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
return (
<Table
rowGroups={[{ key: 'organizationRoles', data: orgRoles }]}
rowIndexKey="id"
columns={[
{
title: <DynamicT forKey="organization_template.roles.role_column" />,
dataIndex: 'name',
colSpan: 4,
render: ({ id, name }) => {
return <ItemPreview title={name} icon={<ThemedIcon for={OrgRoleIcon} />} to={id} />;
<>
<Table
rowGroups={[{ key: 'organizationRoles', data: orgRoles }]}
rowIndexKey="id"
columns={[
{
title: <DynamicT forKey="organization_template.roles.role_column" />,
dataIndex: 'name',
colSpan: 4,
render: ({ id, name }) => {
return <ItemPreview title={name} icon={<ThemedIcon for={OrgRoleIcon} />} to={id} />;
},
},
},
{
title: <DynamicT forKey="organization_template.roles.permissions_column" />,
dataIndex: 'scopes',
colSpan: 12,
render: ({ scopes }) => {
return scopes.length === 0 ? (
'-'
) : (
<div className={styles.permissions}>
{scopes.map(({ id, name }) => (
<Tag key={id} variant="cell">
<Breakable>{name}</Breakable>
</Tag>
))}
</div>
);
{
title: <DynamicT forKey="organization_template.roles.permissions_column" />,
dataIndex: 'scopes',
colSpan: 12,
render: ({ scopes }) => {
return scopes.length === 0 ? (
'-'
) : (
<div className={styles.permissions}>
{scopes.map(({ id, name }) => (
<Tag key={id} variant="cell">
<Breakable>{name}</Breakable>
</Tag>
))}
</div>
);
},
},
},
]}
rowClickHandler={({ id }) => {
navigate(id);
}}
filter={
<div className={styles.filter}>
<Button
title="organization_template.roles.create_title"
type="primary"
icon={<Plus />}
onClick={() => {
// Todo @xiaoyijun implment create org role
}}
/>
</div>
}
placeholder={
<TablePlaceholder
image={<RolesEmpty />}
imageDark={<RolesEmptyDark />}
title="organization_template.roles.placeholder_title"
description="organization_template.roles.placeholder_description"
learnMoreLink={{
href: getDocumentationUrl(organizationRoleLink),
targetBlank: 'noopener',
}}
action={
]}
rowClickHandler={({ id }) => {
navigate(id);
}}
filter={
<div className={styles.filter}>
<Button
title="organization_template.roles.create_title"
type="primary"
size="large"
icon={<Plus />}
onClick={() => {
// Todo @xiaoyijun implment create org role
setIsCreateModalOpen(true);
}}
/>
}
</div>
}
placeholder={
<TablePlaceholder
image={<RolesEmpty />}
imageDark={<RolesEmptyDark />}
title="organization_template.roles.placeholder_title"
description="organization_template.roles.placeholder_description"
learnMoreLink={{
href: getDocumentationUrl(organizationRoleLink),
targetBlank: 'noopener',
}}
action={
<Button
title="organization_template.roles.create_title"
type="primary"
size="large"
icon={<Plus />}
onClick={() => {
setIsCreateModalOpen(true);
}}
/>
}
/>
}
pagination={{
page,
totalCount,
pageSize: defaultPageSize,
onChange: (page) => {
updateSearchParameters({ page });
},
}}
isLoading={isLoading}
errorMessage={error?.body?.message ?? error?.message}
onRetry={async () => mutate(undefined, true)}
/>
{isCreateModalOpen && (
<CreateOrganizationRoleModal
onClose={(createdRole) => {
setIsCreateModalOpen(false);
if (createdRole) {
void mutate();
navigate(createdRole.id);
}
}}
/>
}
pagination={{
page,
totalCount,
pageSize: defaultPageSize,
onChange: (page) => {
updateSearchParameters({ page });
},
}}
isLoading={isLoading}
errorMessage={error?.body?.message ?? error?.message}
onRetry={async () => mutate(undefined, true)}
/>
)}
</>
);
}

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Organisationsrolle',
placeholder_description:
'Eine Organisationsrolle ist eine Gruppierung von Berechtigungen, die Benutzern zugewiesen werden können. Die Berechtigungen müssen aus den vordefinierten Organisationsberechtigungen stammen.',
create_modal: {
title: 'Rolle der Organisation erstellen',
create: 'Rolle erstellen',
name_field: 'Rollenname',
description_field: 'Beschreibung',
created: 'Die Organisationsrolle {{name}} wurde erfolgreich erstellt.',
},
},
permissions: {
tab_name: 'Org Berechtigungen',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Organization role',
placeholder_description:
'Organization role is a grouping of permissions that can be assigned to users. The permissions must come from the predefined organization permissions.',
create_modal: {
title: 'Create organization role',
create: 'Create role',
name_field: 'Role name',
description_field: 'Description',
created: 'Organization role {{name}} has been successfully created.',
},
},
permissions: {
tab_name: 'Organization permissions',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Rol de organización',
placeholder_description:
'El rol de organización es un agrupamiento de permisos que se pueden asignar a los usuarios. Los permisos deben provenir de los permisos de organización predefinidos.',
create_modal: {
title: 'Crear rol de organización',
create: 'Crear rol',
name_field: 'Nombre del rol',
description_field: 'Descripción',
created: 'El rol de organización {{name}} se ha creado correctamente.',
},
},
permissions: {
tab_name: 'Permisos de org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Rôle dorganisation',
placeholder_description:
'Un rôle dorganisation est un groupement de permissions qui peuvent être attribuées aux utilisateurs. Les permissions doivent provenir des permissions dorganisation prédéfinies.',
create_modal: {
title: "Créer un rôle d'organisation",
create: 'Créer un rôle',
name_field: 'Nom du rôle',
description_field: 'Description',
created: "Le rôle d'organisation {{name}} a été créé avec succès.",
},
},
permissions: {
tab_name: 'Permissions org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Ruolo di organizzazione',
placeholder_description:
'Il ruolo di organizzazione è un raggruppamento di permessi che possono essere assegnati agli utenti. I permessi devono provenire dai permessi di organizzazione predefiniti.',
create_modal: {
title: "Crea ruolo dell'organizzazione",
create: 'Crea ruolo',
name_field: 'Nome del ruolo',
description_field: 'Descrizione',
created: "Il ruolo dell'organizzazione {{name}} è stato creato con successo.",
},
},
permissions: {
tab_name: 'Permessi org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: '組織の役割',
placeholder_description:
'組織の役割は、ユーザーに割り当てることができる権限のグループです。権限は、事前に定義された組織の権限から来なければなりません。',
create_modal: {
title: '組織の役割を作成する',
create: '役割を作成する',
name_field: '役割名',
description_field: '説明',
created: '組織の役割{{name}}が正常に作成されました。',
},
},
permissions: {
tab_name: '組織の権限',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: '조직 역할',
placeholder_description:
'조직 역할은 사용자에게 할당될 수 있는 권한의 그룹입니다. 권한은 미리 정의된 조직 권한에서 와야 합니다.',
create_modal: {
title: '조직 역할 만들기',
create: '역할 만들기',
name_field: '역할 이름',
description_field: '설명',
created: '조직 역할 {{name}}이(가) 성공적으로 만들어졌습니다.',
},
},
permissions: {
tab_name: '조직 권한',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Rola organizacyjna',
placeholder_description:
'Rola organizacyjna to grupowanie uprawnień, które można przypisać użytkownikom. Uprawnienia muszą pochodzić z wcześniej zdefiniowanych uprawnień organizacyjnych.',
create_modal: {
title: 'Utwórz rolę organizacji',
create: 'Utwórz rolę',
name_field: 'Nazwa roli',
description_field: 'Opis',
created: 'Rola organizacji {{name}} została pomyślnie utworzona.',
},
},
permissions: {
tab_name: 'Uprawnienia org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Papel da organização',
placeholder_description:
'Papel da organização é um agrupamento de permissões que podem ser atribuídas aos usuários. As permissões devem vir das permissões organizacionais predefinidas.',
create_modal: {
title: 'Criar função da organização',
create: 'Criar função',
name_field: 'Nome da função',
description_field: 'Descrição',
created: 'A função da organização {{name}} foi criada com sucesso.',
},
},
permissions: {
tab_name: 'Permissões da org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Papel da organização',
placeholder_description:
'O papel da organização é um agrupamento de permissões que podem ser atribuídas a utilizadores. As permissões devem provir das permissões organizacionais predefinidas.',
create_modal: {
title: 'Criar função da organização',
create: 'Criar função',
name_field: 'Nome da função',
description_field: 'Descrição',
created: 'A função da organização {{name}} foi criada com sucesso.',
},
},
permissions: {
tab_name: 'Permissões da org',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Роль организации',
placeholder_description:
'Роль организации - это группировка разрешений, которые могут быть назначены пользователям. Разрешения должны происходить из предопределенных разрешений организации.',
create_modal: {
title: 'Создать роль организации',
create: 'Создать роль',
name_field: 'Название роли',
description_field: 'Описание',
created: 'Роль организации {{name}} успешно создана.',
},
},
permissions: {
tab_name: 'Разрешения орг',

View file

@ -11,6 +11,13 @@ const organization_template = {
placeholder_title: 'Organizasyon rolü',
placeholder_description:
'Organizasyon rolü, kullanıcılara atanabilecek izinlerin bir gruplamasıdır. İzinler, önceden belirlenmiş organizasyon izinlerinden gelmelidir.',
create_modal: {
title: 'Kuruluş rolü oluştur',
create: 'Rol oluştur',
name_field: 'Rol adı',
description_field: 'Açıklama',
created: 'Kuruluş rolü {{name}} başarıyla oluşturuldu.',
},
},
permissions: {
tab_name: 'Org izinleri',

View file

@ -10,6 +10,13 @@ const organization_template = {
permissions_column: '权限',
placeholder_title: '组织角色',
placeholder_description: '组织角色是一组可以分配给用户的权限。权限必须来自预定义的组织权限。',
create_modal: {
title: '创建组织角色',
create: '创建角色',
name_field: '角色名称',
description_field: '描述',
created: '成功创建组织角色 {{name}}。',
},
},
permissions: {
tab_name: '组织权限',

View file

@ -10,6 +10,13 @@ const organization_template = {
permissions_column: '權限',
placeholder_title: '組織角色',
placeholder_description: '組織角色是一組可以分配給用戶的權限。權限必須來自預定義的組織權限。',
create_modal: {
title: '建立組織角色',
create: '建立角色',
name_field: '角色名稱',
description_field: '描述',
created: '成功建立組織角色 {{name}}。',
},
},
permissions: {
tab_name: '組織權限',

View file

@ -10,6 +10,13 @@ const organization_template = {
permissions_column: '權限',
placeholder_title: '組織角色',
placeholder_description: '組織角色是一組可以分配給使用者的權限。權限必須來自預定義的組織權限。',
create_modal: {
title: '建立組織角色',
create: '建立角色',
name_field: '角色名稱',
description_field: '描述',
created: '成功建立組織角色 {{name}}。',
},
},
permissions: {
tab_name: '組織權限',