Skip to content

Commit

Permalink
refactor(console): update role-related content and components
Browse files Browse the repository at this point in the history
  • Loading branch information
gao-sun committed Jun 23, 2024
1 parent ca22bc6 commit 1741749
Show file tree
Hide file tree
Showing 86 changed files with 92 additions and 376 deletions.
54 changes: 12 additions & 42 deletions packages/console/src/assets/icons/role-feature.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 0 additions & 13 deletions packages/console/src/assets/icons/user-role-dark.svg

This file was deleted.

13 changes: 0 additions & 13 deletions packages/console/src/assets/icons/user-role.svg

This file was deleted.

6 changes: 3 additions & 3 deletions packages/console/src/components/ItemPreview/UserPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ type Props = {
/**
* Whether to provide a link to user details page. Explicitly set to `false` to hide it.
*/
readonly hasUserDetailsLink?: false;
readonly showLink?: false;
};

/** A component that renders a preview of a user. It's useful for displaying a user in a list. */
function UserPreview({ user, hasUserDetailsLink }: Props) {
function UserPreview({ user, showLink }: Props) {
return (
<ItemPreview
title={getUserTitle(user)}
subtitle={getUserSubtitle(user)}
icon={<UserAvatar size="large" user={user} />}
to={conditional(hasUserDetailsLink !== false && `/users/${user.id}`)}
to={conditional(showLink !== false && `/users/${user.id}`)}
suffix={conditional(user.isSuspended && <SuspendedTag />)}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type OrganizationRole, type RoleType } from '@logto/schemas';
import classNames from 'classnames';

import RoleIcon from '@/assets/icons/role-feature.svg';
import RoleIcon from '@/assets/icons/organization-role-feature.svg';
import MultiSelect, { type Option } from '@/ds-components/Select/MultiSelect';
import useSearchValues from '@/hooks/use-search-values';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,7 @@ function RoleAssignmentModal({ entity, onClose, type, isSkippable }: Props) {
a: <TextLink to="/roles/create" />,
}}
>
{t(
isForUser
? 'user_details.roles.create_user_role_hint'
: 'applications.m2m_role_assignment.role_creation_hint'
)}
{t('roles.role_creation_hint')}
</Trans>
</div>
</ModalLayout>
Expand Down
20 changes: 20 additions & 0 deletions packages/console/src/components/RoleIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Theme } from '@logto/schemas';
import { type ReactNode } from 'react';

import UserRoleIconDark from '@/assets/icons/role-feature-dark.svg';
import UserRoleIcon from '@/assets/icons/role-feature.svg';
import useTheme from '@/hooks/use-theme';

const themeToRoleIcon = Object.freeze({
[Theme.Light]: <UserRoleIcon />,
[Theme.Dark]: <UserRoleIconDark />,
} satisfies Record<Theme, ReactNode>);

/** Render a role icon according to the current theme. */
const RoleIcon = () => {
const theme = useTheme();

return themeToRoleIcon[theme];
};

export default RoleIcon;
2 changes: 1 addition & 1 deletion packages/console/src/components/RolesTransfer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function RolesTransfer({ entityId, type, value, onChange }: Props) {
</Trans>
</InlineNotification>
)}
<FormField title={isM2mRole ? 'roles.assign_m2m_roles' : 'roles.assign_user_roles'}>
<FormField title="roles.assign_roles">
<div className={classNames(transferLayout.container, styles.rolesTransfer)}>
<SourceRolesBox
entityId={entityId}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import type { Application, Role } from '@logto/schemas';
import { RoleType, Theme, roleTypeToKey } from '@logto/schemas';
import { RoleType, roleTypeToKey } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useState } from 'react';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import useSWR from 'swr';

import Delete from '@/assets/icons/delete.svg';
import MachineToMachineRoleIconDark from '@/assets/icons/m2m-role-dark.svg';
import MachineToMachineRoleIcon from '@/assets/icons/m2m-role.svg';
import Plus from '@/assets/icons/plus.svg';
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
import ItemPreview from '@/components/ItemPreview';
import RoleAssignmentModal from '@/components/RoleAssignmentModal';
import RoleIcon from '@/components/RoleIcon';
import { defaultPageSize } from '@/consts';
import Button from '@/ds-components/Button';
import ConfirmModal from '@/ds-components/ConfirmModal';
Expand Down Expand Up @@ -90,17 +89,7 @@ function MachineToMachineApplicationRoles({ application }: Props) {
dataIndex: 'name',
colSpan: 6,
render: ({ id, name }) => (
<ItemPreview
title={name}
to={`/roles/${id}`}
icon={
theme === Theme.Dark ? (
<MachineToMachineRoleIconDark />
) : (
<MachineToMachineRoleIcon />
)
}
/>
<ItemPreview title={name} to={`/roles/${id}`} icon={<RoleIcon />} />
),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Outlet, useLocation, useParams } from 'react-router-dom';
import useSWR, { useSWRConfig } from 'swr';

import Delete from '@/assets/icons/delete.svg';
import OrgRoleIcon from '@/assets/icons/role-feature.svg';
import OrgRoleIcon from '@/assets/icons/organization-role-feature.svg';
import DetailsPage from '@/components/DetailsPage';
import DetailsPageHeader from '@/components/DetailsPage/DetailsPageHeader';
import PageMeta from '@/components/PageMeta';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import useSWR from 'swr';

import OrgRoleIcon from '@/assets/icons/organization-role-feature.svg';
import Plus from '@/assets/icons/plus.svg';
import OrgRoleIcon from '@/assets/icons/role-feature.svg';
import RolesEmptyDark from '@/assets/images/roles-empty-dark.svg';
import RolesEmpty from '@/assets/images/roles-empty.svg';
import Breakable from '@/components/Breakable';
Expand Down Expand Up @@ -68,6 +68,14 @@ function OrganizationRoles() {
return <ItemPreview title={name} icon={<ThemedIcon for={OrgRoleIcon} />} to={id} />;
},
},
{
title: <DynamicT forKey="roles.col_type" />,
dataIndex: 'type',
colSpan: 4,
render: ({ type }) => {
return <DynamicT forKey={`roles.type_${roleTypeToKey[type]}`} />;
},
},
{
title: <DynamicT forKey="organization_template.roles.permissions_column" />,
dataIndex: 'scopes',
Expand All @@ -88,14 +96,6 @@ function OrganizationRoles() {
);
},
},
{
title: <DynamicT forKey="organization_template.roles.type_column" />,
dataIndex: 'type',
colSpan: 4,
render: ({ type }) => {
return <DynamicT forKey={`roles.type_${roleTypeToKey[type]}`} />;
},
},
]}
rowClickHandler={({ id }) => {
navigate(id);
Expand Down
15 changes: 3 additions & 12 deletions packages/console/src/pages/RoleDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Role } from '@logto/schemas';
import { Theme, RoleType } from '@logto/schemas';
import { RoleType } from '@logto/schemas';
import classNames from 'classnames';
import { useEffect, useState } from 'react';
import { toast } from 'react-hot-toast';
Expand All @@ -8,12 +8,9 @@ import { Outlet, useLocation, useParams } from 'react-router-dom';
import useSWR, { useSWRConfig } from 'swr';

import Delete from '@/assets/icons/delete.svg';
import MachineToMachineRoleIconDark from '@/assets/icons/m2m-role-dark.svg';
import MachineToMachineRoleIcon from '@/assets/icons/m2m-role.svg';
import UserRoleIconDark from '@/assets/icons/user-role-dark.svg';
import UserRoleIcon from '@/assets/icons/user-role.svg';
import DetailsPage from '@/components/DetailsPage';
import DetailsPageHeader from '@/components/DetailsPage/DetailsPageHeader';
import RoleIcon from '@/components/RoleIcon';
import { RoleDetailsTabs } from '@/consts/page-tabs';
import ConfirmModal from '@/ds-components/ConfirmModal';
import InlineNotification from '@/ds-components/InlineNotification';
Expand All @@ -28,18 +25,12 @@ import useUserPreferences from '@/hooks/use-user-preferences';
import * as styles from './index.module.scss';
import { type RoleDetailsOutletContext } from './types';

const icons = {
[Theme.Light]: { UserIcon: UserRoleIcon, MachineToMachineIcon: MachineToMachineRoleIcon },
[Theme.Dark]: { UserIcon: UserRoleIconDark, MachineToMachineIcon: MachineToMachineRoleIconDark },
};

function RoleDetails() {
const { pathname } = useLocation();
const { id } = useParams();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { navigate } = useTenantPathname();
const theme = useTheme();
const { UserIcon, MachineToMachineIcon } = icons[theme];

const isPageHasTable =
pathname.endsWith(RoleDetailsTabs.Permissions) ||
Expand Down Expand Up @@ -119,7 +110,7 @@ function RoleDetails() {
{data && (
<>
<DetailsPageHeader
icon={isM2mRole ? <MachineToMachineIcon /> : <UserIcon />}
icon={<RoleIcon />}
title={data.name}
primaryTag={t(
isM2mRole ? 'role_details.type_m2m_role_tag' : 'role_details.type_user_role_tag'
Expand Down
22 changes: 3 additions & 19 deletions packages/console/src/pages/Roles/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import { RoleType, roleTypeToKey, type RoleResponse } from '@logto/schemas';
import { Theme } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import useSWR from 'swr';

import MachineToMachineRoleIconDark from '@/assets/icons/m2m-role-dark.svg';
import MachineToMachineRoleIcon from '@/assets/icons/m2m-role.svg';
import Plus from '@/assets/icons/plus.svg';
import UserRoleIconDark from '@/assets/icons/user-role-dark.svg';
import UserRoleIcon from '@/assets/icons/user-role.svg';
import RolesEmptyDark from '@/assets/images/roles-empty-dark.svg';
import RolesEmpty from '@/assets/images/roles-empty.svg';
import Breakable from '@/components/Breakable';
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
import ItemPreview from '@/components/ItemPreview';
import ListPage from '@/components/ListPage';
import RoleIcon from '@/components/RoleIcon';
import { defaultPageSize } from '@/consts';
import Button from '@/ds-components/Button';
import Search from '@/ds-components/Search';
Expand All @@ -36,14 +32,6 @@ const buildDetailsPathname = (id: string) => `${rolesPathname}/${id}`;

const pageSize = defaultPageSize;

const getRoleIcon = (type: RoleType, isDarkMode: boolean) => {
if (type === RoleType.User) {
return isDarkMode ? <UserRoleIconDark /> : <UserRoleIcon />;
}

return isDarkMode ? <MachineToMachineRoleIconDark /> : <MachineToMachineRoleIcon />;
};

function Roles() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { search } = useLocation();
Expand Down Expand Up @@ -96,12 +84,8 @@ function Roles() {
title: t('roles.col_roles'),
dataIndex: 'roles',
colSpan: 5,
render: ({ id, name, type }) => (
<ItemPreview
title={name}
to={buildDetailsPathname(id)}
icon={getRoleIcon(type, theme === Theme.Dark)}
/>
render: ({ id, name }) => (
<ItemPreview title={name} to={buildDetailsPathname(id)} icon={<RoleIcon />} />
),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function Members() {
dataIndex: 'user',
title: t('user'),
colSpan: 4,
render: (user) => <UserPreview user={user} hasUserDetailsLink={false} />,
render: (user) => <UserPreview user={user} showLink={false} />,
},
{
dataIndex: 'roles',
Expand Down
11 changes: 3 additions & 8 deletions packages/console/src/pages/UserDetails/UserRoles/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Role } from '@logto/schemas';
import { RoleType, Theme } from '@logto/schemas';
import { RoleType } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useState } from 'react';
import { toast } from 'react-hot-toast';
Expand All @@ -9,11 +9,10 @@ import useSWR from 'swr';

import Delete from '@/assets/icons/delete.svg';
import Plus from '@/assets/icons/plus.svg';
import UserRoleIconDark from '@/assets/icons/user-role-dark.svg';
import UserRoleIcon from '@/assets/icons/user-role.svg';
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
import ItemPreview from '@/components/ItemPreview';
import RoleAssignmentModal from '@/components/RoleAssignmentModal';
import RoleIcon from '@/components/RoleIcon';
import { defaultPageSize } from '@/consts';
import Button from '@/ds-components/Button';
import ConfirmModal from '@/ds-components/ConfirmModal';
Expand Down Expand Up @@ -92,11 +91,7 @@ function UserRoles() {
dataIndex: 'name',
colSpan: 6,
render: ({ id, name }) => (
<ItemPreview
title={name}
to={`/roles/${id}`}
icon={theme === Theme.Dark ? <UserRoleIconDark /> : <UserRoleIcon />}
/>
<ItemPreview title={name} to={`/roles/${id}`} icon={<RoleIcon />} />
),
},
{
Expand Down
Loading

0 comments on commit 1741749

Please sign in to comment.