diff --git a/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.module.scss b/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.module.scss index 4f539dcf0..6c344501d 100644 --- a/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.module.scss +++ b/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.module.scss @@ -7,7 +7,7 @@ cursor: pointer; user-select: none; - .name { + .title { flex: 1 1 0; font: var(--font-body-2); @include _.text-ellipsis; diff --git a/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.tsx b/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.tsx index 76bdb7628..5ebc0e5b3 100644 --- a/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.tsx +++ b/packages/console/src/components/RoleUsersTransfer/components/SourceUserItem/index.tsx @@ -5,6 +5,7 @@ import Checkbox from '@/components/Checkbox'; import UserAvatar from '@/components/UserAvatar'; import SuspendedTag from '@/pages/Users/components/SuspendedTag'; import { onKeyDownHandler } from '@/utils/a11y'; +import { getUserTitle } from '@/utils/user'; import * as styles from './index.module.scss'; @@ -36,7 +37,7 @@ function SourceUserItem({ user, isSelected, onSelect }: Props) { }} /> -
{user.name ?? t('users.unnamed')}
+
{getUserTitle(user) ?? t('users.unnamed')}
{user.isSuspended && } ); diff --git a/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.module.scss b/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.module.scss index 3936b3137..5d5c0926f 100644 --- a/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.module.scss +++ b/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.module.scss @@ -12,7 +12,7 @@ align-items: center; overflow: hidden; - .name { + .title { flex: 1 1 0; font: var(--font-body-2); @include _.text-ellipsis; diff --git a/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.tsx b/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.tsx index f95e5afbe..446a50a28 100644 --- a/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.tsx +++ b/packages/console/src/components/RoleUsersTransfer/components/TargetUserItem/index.tsx @@ -5,6 +5,7 @@ import Close from '@/assets/images/close.svg'; import IconButton from '@/components/IconButton'; import UserAvatar from '@/components/UserAvatar'; import SuspendedTag from '@/pages/Users/components/SuspendedTag'; +import { getUserTitle } from '@/utils/user'; import * as styles from './index.module.scss'; @@ -20,7 +21,7 @@ function TargetUserItem({ user, onDelete }: Props) {
-
{user.name ?? t('users.unnamed')}
+
{getUserTitle(user) ?? t('users.unnamed')}
{user.isSuspended && }
{ - const { id, name, isSuspended } = user; + const { id, isSuspended } = user; return ( } + title={getUserTitle(user) ?? t('users.unnamed')} + subtitle={getUserSubtitle(user)} + icon={} to={`/users/${id}`} - size="compact" suffix={conditional(isSuspended && )} /> ); diff --git a/packages/console/src/pages/UserDetails/index.module.scss b/packages/console/src/pages/UserDetails/index.module.scss index 5a36711b4..c062c54f0 100644 --- a/packages/console/src/pages/UserDetails/index.module.scss +++ b/packages/console/src/pages/UserDetails/index.module.scss @@ -26,7 +26,7 @@ } } - .name { + .title { font: var(--font-title-1); color: var(--color-text); } @@ -39,7 +39,7 @@ border-radius: 10px; } - .username { + .subtitle { color: var(--color-text-secondary); font: var(--font-label-2); } diff --git a/packages/console/src/pages/UserDetails/index.tsx b/packages/console/src/pages/UserDetails/index.tsx index 49cc11426..8893e2c93 100644 --- a/packages/console/src/pages/UserDetails/index.tsx +++ b/packages/console/src/pages/UserDetails/index.tsx @@ -26,6 +26,7 @@ import { UserDetailsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; +import { getUserTitle, getUserSubtitle } from '@/utils/user'; import UserAccountInformation from '../../components/UserAccountInformation'; import SuspendedTag from '../Users/components/SuspendedTag'; @@ -53,6 +54,8 @@ function UserDetails() { const api = useApi(); const navigate = useNavigate(); + const userSubtitle = data && getUserSubtitle(data); + useEffect(() => { setIsDeleteFormOpen(false); setIsResetPasswordFormOpen(false); @@ -111,12 +114,12 @@ function UserDetails() {
-
{data.name ?? '-'}
+
{getUserTitle(data) ?? t('users.unnamed')}
{isSuspendedUser && } - {data.username && ( + {userSubtitle && ( <> -
{data.username}
+
{userSubtitle}
)} diff --git a/packages/console/src/pages/Users/index.tsx b/packages/console/src/pages/Users/index.tsx index d2b11b007..3c3f3f58b 100644 --- a/packages/console/src/pages/Users/index.tsx +++ b/packages/console/src/pages/Users/index.tsx @@ -24,6 +24,7 @@ import type { RequestError } from '@/hooks/use-api'; import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher'; import * as resourcesStyles from '@/scss/resources.module.scss'; import { buildUrl, formatSearchKeyword } from '@/utils/url'; +import { getUserTitle, getUserSubtitle } from '@/utils/user'; import CreateForm from './components/CreateForm'; import SuspendedTag from './components/SuspendedTag'; @@ -98,15 +99,14 @@ function Users() { dataIndex: 'name', colSpan: 6, render: (user) => { - const { id, name, isSuspended } = user; + const { id, isSuspended } = user; return ( } + title={getUserTitle(user) ?? t('users.unnamed')} + subtitle={getUserSubtitle(user)} + icon={} to={buildDetailsPathname(id)} - size="compact" suffix={conditional(isSuspended && )} /> ); diff --git a/packages/console/src/utils/user.ts b/packages/console/src/utils/user.ts new file mode 100644 index 000000000..f5b1ecf92 --- /dev/null +++ b/packages/console/src/utils/user.ts @@ -0,0 +1,11 @@ +import { type User } from '@logto/schemas'; +import { conditional } from '@silverhand/essentials'; + +const getUserIdentity = (user: User) => { + const { primaryEmail, primaryPhone, username } = user; + return primaryEmail ?? primaryPhone ?? username; +}; + +export const getUserTitle = (user: User) => user.name ?? getUserIdentity(user); + +export const getUserSubtitle = (user: User) => conditional(user.name && getUserIdentity(user));