mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-01-26 01:21:04 +00:00
Add a fallback in case the user has no name (#320)
* Fix redirect link to event streaming docs * Fallback to a user id in case user has no name
This commit is contained in:
@@ -121,7 +121,7 @@ function UserOverview({ user }: Props) {
|
||||
/>
|
||||
)}
|
||||
|
||||
<Breadcrumbs.Item label={user.name} active />
|
||||
<Breadcrumbs.Item label={user.name || user.id} active />
|
||||
</Breadcrumbs>
|
||||
|
||||
<div className={"flex justify-between max-w-6xl"}>
|
||||
@@ -138,7 +138,9 @@ function UserOverview({ user }: Props) {
|
||||
}
|
||||
: {
|
||||
color: user?.name
|
||||
? generateColorFromString(user?.name || "System User")
|
||||
? generateColorFromString(
|
||||
user?.name || user?.id || "System User",
|
||||
)
|
||||
: "#808080",
|
||||
}
|
||||
}
|
||||
@@ -146,10 +148,12 @@ function UserOverview({ user }: Props) {
|
||||
{user.is_service_user ? (
|
||||
<IconSettings2 size={16} />
|
||||
) : (
|
||||
user?.name?.charAt(0)
|
||||
user?.name?.charAt(0) || user?.id?.charAt(0)
|
||||
)}
|
||||
</div>
|
||||
<h1 className={"flex items-center gap-3"}>{user.name}</h1>
|
||||
<h1 className={"flex items-center gap-3"}>
|
||||
{user.name || user.id}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"flex gap-4"}>
|
||||
@@ -256,10 +260,10 @@ function UserInformationCard({ user }: { user: User }) {
|
||||
label={
|
||||
<>
|
||||
<User2 size={16} />
|
||||
Name
|
||||
{user.name ? "Name" : "User ID"}
|
||||
</>
|
||||
}
|
||||
value={user.name}
|
||||
value={user.name || user.id}
|
||||
/>
|
||||
|
||||
{!isServiceUser && (
|
||||
@@ -270,7 +274,7 @@ function UserInformationCard({ user }: { user: User }) {
|
||||
E-Mail
|
||||
</>
|
||||
}
|
||||
value={user.email}
|
||||
value={user.email || "-"}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ export const UserAvatar = ({ size = "default" }: Props) => {
|
||||
)}
|
||||
style={{
|
||||
color: user?.name
|
||||
? generateColorFromString(user?.name || "System User")
|
||||
? generateColorFromString(user?.name || user?.id || "System User")
|
||||
: "#808080",
|
||||
}}
|
||||
>
|
||||
{user?.name?.charAt(0)}
|
||||
{user?.name?.charAt(0) || user?.id?.charAt(0)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -314,8 +314,7 @@ export default function ActivityDescription({ event }: Props) {
|
||||
return (
|
||||
<div className={"inline"}>
|
||||
User <Value>{event.meta.username}</Value>{" "}
|
||||
<Value>{event.meta.email}</Value>
|
||||
was deleted
|
||||
<Value>{event.meta.email}</Value> was deleted
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -454,7 +453,7 @@ function Value({
|
||||
return children ? (
|
||||
<span
|
||||
className={cn(
|
||||
"text-nb-gray-200 inline font-medium bg-nb-gray-900 py-[3px] text-[12px] px-[5px] border border-nb-gray-800 rounded-[4px]",
|
||||
"text-nb-gray-200 inline font-medium bg-nb-gray-900 py-[3px] text-[11px] px-[5px] border border-nb-gray-800 rounded-[4px]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -61,23 +61,25 @@ export const ActivityEntryRow = ({ event }: { event: ActivityEvent }) => {
|
||||
}
|
||||
style={{
|
||||
color: user?.name
|
||||
? generateColorFromString(user?.name || "System User")
|
||||
? generateColorFromString(
|
||||
user?.name || user?.id || "System User",
|
||||
)
|
||||
: "#808080",
|
||||
}}
|
||||
>
|
||||
{!user?.name && <Cog size={12} />}
|
||||
{user?.name?.charAt(0)}
|
||||
{!user?.name && !user?.id && <Cog size={12} />}
|
||||
{user?.name?.charAt(0) || user?.id?.charAt(0)}
|
||||
</div>
|
||||
|
||||
<span className={"text-sm text-nb-gray-200"}>
|
||||
<TextWithTooltip text={user?.name || "System"} maxChars={20} />
|
||||
</span>
|
||||
<span className={"text-sm text-nb-gray-400 font-light"}>
|
||||
<TextWithTooltip
|
||||
text={user?.email || "NetBird"}
|
||||
text={user?.name || user?.id || "System"}
|
||||
maxChars={20}
|
||||
/>
|
||||
</span>
|
||||
<span className={"text-sm text-nb-gray-400 font-light"}>
|
||||
<TextWithTooltip text={user?.email || ""} maxChars={20} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -91,11 +93,15 @@ export const ActivityEntryRow = ({ event }: { event: ActivityEvent }) => {
|
||||
|
||||
<Card
|
||||
className={
|
||||
"w-full relative bg-nb-gray-925 text-sm text-nb-gray-300 flex flex-col px-4 pt-3 pb-4"
|
||||
"w-full relative bg-nb-gray-925 text-sm text-nb-gray-300 flex flex-col px-4 pt-3 pb-3"
|
||||
}
|
||||
>
|
||||
<div className={"flex gap-4"}>
|
||||
<div className={"flex items-center mt-2 text-nb-gray-300 text-sm"}>
|
||||
<div
|
||||
className={
|
||||
"flex items-center text-nb-gray-300 text-sm leading-[2]"
|
||||
}
|
||||
>
|
||||
<ActivityDescription event={event} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,13 +88,18 @@ export function ActivityUserSelector({
|
||||
style={{
|
||||
color: selectedUser?.name
|
||||
? generateColorFromString(
|
||||
selectedUser?.name || "System User",
|
||||
selectedUser?.name ||
|
||||
selectedUser?.id ||
|
||||
"System User",
|
||||
)
|
||||
: "#808080",
|
||||
}}
|
||||
>
|
||||
{!selectedUser?.name && <Cog size={12} />}
|
||||
{selectedUser?.name?.charAt(0)}
|
||||
{selectedUser?.email === "NetBird" ? (
|
||||
<Cog size={12} />
|
||||
) : (
|
||||
selectedUser?.name?.charAt(0) || selectedUser?.id?.charAt(0)
|
||||
)}
|
||||
</div>
|
||||
<div className={"flex items-center gap-2"}>
|
||||
<TextWithTooltip
|
||||
@@ -203,10 +208,14 @@ export function ActivityUserSelector({
|
||||
</CommandItem>
|
||||
|
||||
{users.map((user) => {
|
||||
const searchValue =
|
||||
user.email === "NetBird"
|
||||
? "NetBird System"
|
||||
: user.name + " " + user.id + " " + user.email;
|
||||
return (
|
||||
<CommandItem
|
||||
key={user.id}
|
||||
value={user.name + " " + user.id}
|
||||
value={searchValue}
|
||||
className={"py-1 px-2"}
|
||||
onSelect={() => {
|
||||
toggle(user.email);
|
||||
@@ -222,19 +231,26 @@ export function ActivityUserSelector({
|
||||
style={{
|
||||
color: user?.name
|
||||
? generateColorFromString(
|
||||
user?.name || "System User",
|
||||
user?.name || user?.id || "System User",
|
||||
)
|
||||
: "#808080",
|
||||
}}
|
||||
>
|
||||
{!user?.name && <Cog size={14} />}
|
||||
{user?.name?.charAt(0)}
|
||||
{user?.email === "NetBird" ? (
|
||||
<Cog size={14} />
|
||||
) : (
|
||||
user?.name?.charAt(0) || user?.id?.charAt(0)
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={"flex flex-col text-xs"}>
|
||||
<span className={" text-nb-gray-200"}>
|
||||
<TextWithTooltip
|
||||
text={user?.name || "System"}
|
||||
text={
|
||||
user?.email === "NetBird"
|
||||
? "System"
|
||||
: user?.name || user?.id
|
||||
}
|
||||
maxChars={20}
|
||||
/>
|
||||
</span>
|
||||
|
||||
@@ -88,7 +88,7 @@ export default function ServiceUsersTable({ users, isLoading }: Props) {
|
||||
<>
|
||||
<DataTable
|
||||
isLoading={isLoading}
|
||||
text={"Network Routes"}
|
||||
text={"Service Users"}
|
||||
sorting={sorting}
|
||||
setSorting={setSorting}
|
||||
columns={ServiceUsersTableColumns}
|
||||
|
||||
@@ -123,7 +123,7 @@ export default function UsersTable({ users, isLoading }: Props) {
|
||||
<>
|
||||
<DataTable
|
||||
isLoading={isLoading}
|
||||
text={"Network Routes"}
|
||||
text={"Users"}
|
||||
sorting={sorting}
|
||||
setSorting={setSorting}
|
||||
columns={UsersTableColumns}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function ServiceUserNameCell({ user }: Props) {
|
||||
</div>
|
||||
<div className={"flex flex-col justify-center"}>
|
||||
<span className={cn("text-base font-medium flex items-center gap-3")}>
|
||||
{user.name}
|
||||
{user.name || user.id}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,8 +18,9 @@ export default function UserActionCell({ user, serviceUser = false }: Props) {
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
const deleteRule = async () => {
|
||||
const name = user.name || "User";
|
||||
notify({
|
||||
title: user.name + "deleted",
|
||||
title: name + "deleted",
|
||||
description: "User was successfully deleted.",
|
||||
promise: userRequest.del("", `/${user.id}`).then(() => {
|
||||
mutate(`/users?service_user=${serviceUser}`);
|
||||
@@ -29,8 +30,9 @@ export default function UserActionCell({ user, serviceUser = false }: Props) {
|
||||
};
|
||||
|
||||
const openConfirm = async () => {
|
||||
const name = user.name || "User";
|
||||
const choice = await confirm({
|
||||
title: `Delete '${user.name}'?`,
|
||||
title: `Delete '${name}'?`,
|
||||
description:
|
||||
"Deleting this user will remove their devices and remove dashboard access. This action cannot be undone.",
|
||||
confirmText: "Delete",
|
||||
|
||||
@@ -20,12 +20,12 @@ export default function UserBlockCell({ user, isUserPage = false }: Props) {
|
||||
const disabled = user.is_current || user.role === "owner";
|
||||
|
||||
const update = async (blocked: boolean) => {
|
||||
const name = user.name || "User";
|
||||
|
||||
notify({
|
||||
title: blocked ? "User blocked" : "User unblocked",
|
||||
description:
|
||||
user.name +
|
||||
" was successfully " +
|
||||
(blocked ? "blocked." : "unblocked."),
|
||||
name + " was successfully " + (blocked ? "blocked." : "unblocked."),
|
||||
promise: userRequest
|
||||
.put(
|
||||
{
|
||||
|
||||
@@ -18,12 +18,12 @@ export default function UserNameCell({ user }: Props) {
|
||||
}
|
||||
style={{
|
||||
color: user?.name
|
||||
? generateColorFromString(user?.name || "System User")
|
||||
? generateColorFromString(user?.name || user?.id || "System User")
|
||||
: "#808080",
|
||||
}}
|
||||
>
|
||||
{!user?.name && <Cog size={12} />}
|
||||
{user?.name?.charAt(0)}
|
||||
{!user?.name && !user?.id && <Cog size={12} />}
|
||||
{user?.name?.charAt(0) || user?.id?.charAt(0)}
|
||||
{(status == "invited" || status == "blocked") && (
|
||||
<div
|
||||
className={cn(
|
||||
@@ -39,7 +39,7 @@ export default function UserNameCell({ user }: Props) {
|
||||
</div>
|
||||
<div className={"flex flex-col justify-center"}>
|
||||
<span className={cn("text-base font-medium flex items-center gap-3")}>
|
||||
{user.name}
|
||||
{user.name || user.id}
|
||||
{isCurrent && (
|
||||
<span
|
||||
className={
|
||||
|
||||
Reference in New Issue
Block a user