0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

refactor(console): add management api access flag for role options (#5918)

This commit is contained in:
Xiao Yijun 2024-05-27 11:26:25 +08:00 committed by GitHub
parent 07fdd8557c
commit 20bf55be30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 184 additions and 15 deletions

View file

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.33325 2.49834C1.33325 2.03863 1.33325 1.80878 1.42239 1.62377C1.50095 1.46073 1.62729 1.32254 1.78636 1.22567C1.96686 1.11575 2.20684 1.08312 2.6868 1.01787L9.53187 0.0871994C10.1532 0.00272261 10.4639 -0.0395158 10.7053 0.0496673C10.9172 0.127956 11.0941 0.273307 11.2059 0.461088C11.3333 0.675001 11.3333 0.972559 11.3333 1.56767V14.4323C11.3333 15.0274 11.3333 15.325 11.2059 15.5389C11.0941 15.7267 10.9172 15.872 10.7053 15.9503C10.4639 16.0395 10.1532 15.9973 9.53189 15.9128L9.53187 15.9128L2.6868 14.9821C2.20684 14.9169 1.96686 14.8842 1.78636 14.7743C1.62729 14.6775 1.50095 14.5393 1.42239 14.3762C1.33325 14.1912 1.33325 13.9614 1.33325 13.5017V2.49834ZM8.66659 6.83595C8.66659 6.69596 8.66659 6.62596 8.69009 6.57064C8.7108 6.52191 8.74401 6.4812 8.78547 6.4537C8.83256 6.42248 8.89482 6.41615 9.01934 6.40347H9.01935L9.57692 6.34672C9.72364 6.33179 9.79699 6.32432 9.85363 6.35172C9.90339 6.37578 9.94451 6.41782 9.97042 6.47113C9.99992 6.5318 9.99992 6.61426 9.99992 6.7792V9.2208C9.99992 9.38574 9.99992 9.4682 9.97042 9.52888C9.94451 9.58218 9.90339 9.62422 9.85363 9.64828C9.79699 9.67568 9.72364 9.66821 9.57692 9.65328L9.01935 9.59653C8.89482 9.58385 8.83256 9.57752 8.78547 9.5463C8.74401 9.5188 8.7108 9.47809 8.69009 9.42936C8.66659 9.37404 8.66659 9.30404 8.66659 9.16405V6.83595ZM13.2147 1.66667H12.3333V14.6667H13.2147C13.7229 14.6667 13.977 14.6667 14.1711 14.5675C14.3419 14.4802 14.4807 14.341 14.5677 14.1698C14.6666 13.9751 14.6666 13.7203 14.6666 13.2107V3.12267C14.6666 2.61302 14.6666 2.3582 14.5677 2.16354C14.4807 1.99231 14.3419 1.8531 14.1711 1.76585C13.977 1.66667 13.7229 1.66667 13.2147 1.66667Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -10,9 +10,18 @@
@include _.text-ellipsis;
}
// Todo @xiaoyijun Remove this `count` style together with the dev feature flag
.count {
flex-shrink: 0;
margin-left: _.unit(2);
color: var(--color-text-secondary);
}
.flag {
flex-shrink: 0;
margin-left: _.unit(2);
color: var(--color-text-secondary);
display: flex;
align-items: center;
}
}

View file

@ -1,5 +1,11 @@
import { RoleType, type RoleResponse } from '@logto/schemas';
import { RoleType, type ScopeResponse, isManagementApi, type RoleResponse } from '@logto/schemas';
import { useTranslation } from 'react-i18next';
import useSWR from 'swr';
import ManagementApiAccessFlag from '@/assets/icons/management-api-access.svg';
import { isDevFeaturesEnabled } from '@/consts/env';
import DynamicT from '@/ds-components/DynamicT';
import { Tooltip } from '@/ds-components/Tip';
import * as styles from './index.module.scss';
@ -9,19 +15,36 @@ type Props = {
function RoleInformation({ role }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { id, name, type, usersCount, applicationsCount } = role;
const { data } = useSWR<ScopeResponse[]>(
// Todo @xiaoyijun remove dev feature flag
isDevFeaturesEnabled && type === RoleType.MachineToMachine && `api/roles/${id}/scopes`
);
const { name, type, usersCount, applicationsCount } = role;
const withManagementApiFlag = data?.some(({ resource: { indicator } }) =>
isManagementApi(indicator)
);
return (
<div className={styles.container}>
<div className={styles.name}>{name}</div>
<div className={styles.count}>
(
{type === RoleType.User
? t('user_details.roles.assigned_user_count', { value: usersCount })
: t('application_details.roles.assigned_app_count', { value: applicationsCount })}
)
</div>
{!isDevFeaturesEnabled && (
<div className={styles.count}>
(
{type === RoleType.User
? t('user_details.roles.assigned_user_count', { value: usersCount })
: t('application_details.roles.assigned_app_count', { value: applicationsCount })}
)
</div>
)}
{withManagementApiFlag && (
<Tooltip
anchorClassName={styles.flag}
content={<DynamicT forKey="roles.with_management_api_access_tip" />}
>
<ManagementApiAccessFlag />
</Tooltip>
)}
</div>
);
}

View file

@ -1,3 +1,9 @@
.rolesTransfer {
height: 360px;
}
.flagIcon {
color: var(--color-text-secondary);
// Align the flag icon with the text bottom to make it look centered visually
vertical-align: text-bottom;
}

View file

@ -1,6 +1,12 @@
import type { RoleResponse, RoleType } from '@logto/schemas';
import { type RoleResponse, RoleType } from '@logto/schemas';
import classNames from 'classnames';
import { Trans, useTranslation } from 'react-i18next';
import ManagementApiAccessFlag from '@/assets/icons/management-api-access.svg';
import { isDevFeaturesEnabled } from '@/consts/env';
import FormField from '@/ds-components/FormField';
import InlineNotification from '@/ds-components/InlineNotification';
import useUserPreferences from '@/hooks/use-user-preferences';
import * as transferLayout from '@/scss/transfer.module.scss';
import SourceRolesBox from './SourceRolesBox';
@ -15,11 +21,52 @@ type Props = {
};
function RolesTransfer({ entityId, type, value, onChange }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const isM2mRole = type === RoleType.MachineToMachine;
const {
data: { roleWithManagementApiAccessNotificationAcknowledged },
update,
isLoaded,
} = useUserPreferences();
// Default to true if configs is not loaded to avoid page flickering
const notificationAcknowledged = isLoaded
? Boolean(roleWithManagementApiAccessNotificationAcknowledged)
: true;
return (
<div className={classNames(transferLayout.container, styles.rolesTransfer)}>
<SourceRolesBox entityId={entityId} type={type} selectedRoles={value} onChange={onChange} />
<div className={transferLayout.verticalBar} />
<TargetRolesBox selectedRoles={value} onChange={onChange} />
<div>
{/* Todo @xiaoyijun remove dev feature flag */}
{isDevFeaturesEnabled && isM2mRole && !notificationAcknowledged && (
<InlineNotification
action="general.got_it"
onClick={() => {
void update({
roleWithManagementApiAccessNotificationAcknowledged: true,
});
}}
>
<Trans
components={{
flag: <ManagementApiAccessFlag className={styles.flagIcon} />,
}}
>
{t('roles.management_api_access_notification')}
</Trans>
</InlineNotification>
)}
<FormField title={isM2mRole ? 'roles.assign_m2m_roles' : 'roles.assign_user_roles'}>
<div className={classNames(transferLayout.container, styles.rolesTransfer)}>
<SourceRolesBox
entityId={entityId}
type={type}
selectedRoles={value}
onChange={onChange}
/>
<div className={transferLayout.verticalBar} />
<TargetRolesBox selectedRoles={value} onChange={onChange} />
</div>
</FormField>
</div>
);
}

View file

@ -4,6 +4,5 @@ const isProduction = process.env.NODE_ENV === 'production';
export const isCloud = yes(process.env.IS_CLOUD);
export const adminEndpoint = process.env.ADMIN_ENDPOINT;
// eslint-disable-next-line import/no-unused-modules
export const isDevFeaturesEnabled =
!isProduction || yes(process.env.DEV_FEATURES_ENABLED) || yes(process.env.INTEGRATION_TEST);

View file

@ -17,6 +17,7 @@ const userPreferencesGuard = z.object({
experienceNoticeConfirmed: z.boolean().optional(),
connectorSieNoticeConfirmed: z.boolean().optional(),
managementApiAcknowledged: z.boolean().optional(),
roleWithManagementApiAccessNotificationAcknowledged: z.boolean().optional(),
});
type UserPreferences = z.infer<typeof userPreferencesGuard>;

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Rollen',
placeholder_description:
'Rollen sind eine Gruppierung von Berechtigungen, die Benutzern zugewiesen werden können. Stellen Sie sicher, dass Sie zuerst Berechtigungen hinzufügen, bevor Sie Rollen erstellen.',
assign_user_roles: 'Benutzerrollen zuweisen',
assign_m2m_roles: 'Maschinenrollen zuweisen',
management_api_access_notification:
'Für den Zugriff auf die Logto-Verwaltungs-API wählen Sie Rollen mit Verwaltungs-API-Berechtigungen <flag/> aus.',
with_management_api_access_tip:
'Diese Maschinenrollen umfassen Berechtigungen für die Logto-Verwaltungs-API',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Roles',
placeholder_description:
'Roles are a grouping of permissions that can be assigned to users. Be sure to add permission first before create roles.',
assign_user_roles: 'Assign user roles',
assign_m2m_roles: 'Assign machine-to-machine roles',
management_api_access_notification:
'For Logto Management API access, select roles with management API permissions <flag/>.',
with_management_api_access_tip:
'This machine-to-machine role includes Logto management API permissions',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Roles',
placeholder_description:
'Los roles son un grupo de permisos que se pueden asignar a los usuarios. Asegúrese de agregar permisos antes de crear roles.',
assign_user_roles: 'Asignar roles de usuario',
assign_m2m_roles: 'Asignar roles de máquina a máquina',
management_api_access_notification:
'Para acceder a la API de gestión de Logto, seleccione roles con permisos de API de gestión <flag/>.',
with_management_api_access_tip:
'Este rol de máquina a máquina incluye permisos para la API de gestión de Logto',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Rôles',
placeholder_description:
"Les rôles sont un regroupement d'autorisations qui peuvent être assignées aux utilisateurs. Assurez-vous d'ajouter d'abord des autorisations avant de créer des rôles.",
assign_user_roles: 'Attribuer des rôles utilisateur',
assign_m2m_roles: 'Attribuer des rôles machine à machine',
management_api_access_notification:
"Pour accéder à l'API de gestion de Logto, sélectionnez des rôles avec les autorisations de l'API de gestion <flag/>.",
with_management_api_access_tip:
"Ce rôle machine à machine inclut les autorisations de l'API de gestion de Logto",
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Ruoli',
placeholder_description:
'I ruoli sono un raggruppamento di autorizzazioni che possono essere assegnati agli utenti. Assicurati di aggiungere le autorizzazioni prima di creare i ruoli.',
assign_user_roles: 'Assegna ruoli utente',
assign_m2m_roles: 'Assegna ruoli da macchina a macchina',
management_api_access_notification:
"Per accedere all'API di gestione di Logto, seleziona ruoli con autorizzazioni API di gestione <flag/>.",
with_management_api_access_tip:
"Questo ruolo da macchina a macchina include autorizzazioni per l'API di gestione di Logto",
};
export default Object.freeze(roles);

View file

@ -31,6 +31,11 @@ const roles = {
placeholder_title: 'ロール',
placeholder_description:
'ロールは、ユーザーに割り当てられる権限のグループです。ロールを作成する前に、まず権限を追加してください。',
assign_user_roles: 'ユーザー役割を割り当てる',
assign_m2m_roles: 'マシン間役割を割り当てる',
management_api_access_notification:
'Logto管理APIへのアクセスには、管理API権限を持つ役割を選択してください<flag/>。',
with_management_api_access_tip: 'このマシン間役割には、Logto管理APIのアクセス権が含まれています',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,11 @@ const roles = {
placeholder_title: '역할',
placeholder_description:
'역할은 사용자에게 할당할 수 있는 권한의 모임이에요. 역할을 만들기 전에 먼저 권한을 추가해야 해요.',
assign_user_roles: '사용자 역할 할당',
assign_m2m_roles: '기계 간 역할 할당',
management_api_access_notification:
'Logto 관리 API 액세스를 위해 관리 API 권한이있는 역할을 선택하십시오 <flag/>.',
with_management_api_access_tip: '이 기계 간 역할에는 Logto 관리 API 권한이 포함되어 있습니다',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Role',
placeholder_description:
'Role są grupowaniem uprawnień, które mogą być przypisywane użytkownikom. Upewnij się, że najpierw dodasz uprawnienie, zanim utworzysz role.',
assign_user_roles: 'Przypisz role użytkownika',
assign_m2m_roles: 'Przypisz role od maszyny do maszyny',
management_api_access_notification:
'Aby uzyskać dostęp do interfejsu API zarządzania Logto, wybierz role z uprawnieniami do interfejsu API zarządzania <flag/>.',
with_management_api_access_tip:
'Ta rola maszyny do maszyny zawiera uprawnienia do interfejsu API zarządzania Logto',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Funções',
placeholder_description:
'As funções são um agrupamento de permissões que podem ser atribuídas a usuários. Certifique-se de adicionar as permissões antes de criar funções.',
assign_user_roles: 'Atribuir funções de usuário',
assign_m2m_roles: 'Atribuir funções de máquina para máquina',
management_api_access_notification:
'Para acessar a API de gerenciamento do Logto, selecione funções com permissões de API de gerenciamento <flag/>.',
with_management_api_access_tip:
'Esta função de máquina para máquina inclui permissões para a API de gerenciamento do Logto',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Papéis',
placeholder_description:
'Os papéis são um agrupamento de permissões que podem ser atribuídas a utilizadores. Certifique-se de adicionar permissões antes de criar papéis.',
assign_user_roles: 'Atribuir funções de utilizador',
assign_m2m_roles: 'Atribuir funções de máquina para máquina',
management_api_access_notification:
'Para aceder à API de gestão do Logto, selecione funções com permissões de API de gestão <flag/>.',
with_management_api_access_tip:
'Esta função de máquina para máquina inclui permissões para a API de gestão do Logto',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,12 @@ const roles = {
placeholder_title: 'Роли',
placeholder_description:
'Роли являются группировкой разрешений, которые могут быть назначены пользователям. Необходимо добавить разрешения, прежде чем создать роли.',
assign_user_roles: 'Назначить роли пользователя',
assign_m2m_roles: 'Назначить роли от машины к машине',
management_api_access_notification:
'Для доступа к API управления Logto выберите роли с разрешениями API управления <flag/>.',
with_management_api_access_tip:
'Эта роль от машины к машине включает разрешения для API управления Logto',
};
export default Object.freeze(roles);

View file

@ -31,6 +31,11 @@ const roles = {
placeholder_title: 'Roller',
placeholder_description:
'Roller, kullanıcılara atanabilecek izinlerin gruplandırmasıdır. Rolleri oluşturmadan önce izin eklediğinizden emin olun.',
assign_user_roles: 'Kullanıcı rolleri atayın',
assign_m2m_roles: 'Makine ile makine rolleri atayın',
management_api_access_notification:
'Logto Yönetim API erişimi için yönetim API izinleri olan rolleri seçin <flag/>.',
with_management_api_access_tip: 'Bu makine ile makine rolü, Logto yönetim API izinlerini içerir',
};
export default Object.freeze(roles);

View file

@ -29,6 +29,10 @@ const roles = {
search: '按角色名称、描述或 ID 搜索',
placeholder_title: '角色',
placeholder_description: '角色是可以分配给用户的权限分组。在创建角色之前,请确保先添加权限。',
assign_user_roles: '分配用户角色',
assign_m2m_roles: '分配机器到机器角色',
management_api_access_notification: '要访问Logto管理API请选择具有管理API权限的角色<flag/>。',
with_management_api_access_tip: '此机器到机器角色包括Logto管理API权限',
};
export default Object.freeze(roles);

View file

@ -29,6 +29,10 @@ const roles = {
search: '按角色名稱、描述或 ID 搜索',
placeholder_title: '角色',
placeholder_description: '角色是可以分配給用戶的權限分組。在創建角色之前,請確保先添加權限。',
assign_user_roles: '分配使用者角色',
assign_m2m_roles: '分配機器對機器角色',
management_api_access_notification: '要訪問Logto管理API請選擇具有管理API權限的角色<flag/>。',
with_management_api_access_tip: '此機器對機器角色包含Logto管理API權限',
};
export default Object.freeze(roles);

View file

@ -29,6 +29,10 @@ const roles = {
search: '按角色名稱、描述或 ID 搜尋',
placeholder_title: '角色',
placeholder_description: '角色是可以分配給使用者的權限分組。在建立角色之前,請確保先新增權限。',
assign_user_roles: '分配使用者角色',
assign_m2m_roles: '分配機器對機器角色',
management_api_access_notification: '要訪問Logto管理API請選擇具有管理API權限的角色<flag/>。',
with_management_api_access_tip: '此機器對機器角色包含Logto管理API權限',
};
export default Object.freeze(roles);