mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: do less calculation on users page (#4801)
* Do less calculation on users page * Handle missing usernames
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useActor, useMachine } from "@xstate/react"
|
||||
import { User } from "api/typesGenerated"
|
||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog"
|
||||
import { getPaginationContext } from "components/PaginationWidget/utils"
|
||||
import { usePermissions } from "hooks/usePermissions"
|
||||
@@ -22,6 +23,9 @@ export const Language = {
|
||||
activateDialogMessagePrefix: "Do you want to activate the user",
|
||||
}
|
||||
|
||||
const getSelectedUser = (id: string, users?: User[]) =>
|
||||
users?.find((u) => u.id === id)
|
||||
|
||||
export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
const xServices = useContext(XServiceContext)
|
||||
const navigate = useNavigate()
|
||||
@@ -40,18 +44,14 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
const {
|
||||
users,
|
||||
getUsersError,
|
||||
userIdToDelete,
|
||||
userIdToSuspend,
|
||||
userIdToActivate,
|
||||
usernameToDelete,
|
||||
usernameToSuspend,
|
||||
usernameToActivate,
|
||||
userIdToResetPassword,
|
||||
newUserPassword,
|
||||
paginationRef,
|
||||
} = usersState.context
|
||||
|
||||
const userToBeSuspended = users?.find((u) => u.id === userIdToSuspend)
|
||||
const userToBeDeleted = users?.find((u) => u.id === userIdToDelete)
|
||||
const userToBeActivated = users?.find((u) => u.id === userIdToActivate)
|
||||
const userToResetPassword = users?.find((u) => u.id === userIdToResetPassword)
|
||||
const { updateUsers: canEditUsers } = usePermissions()
|
||||
const [rolesState, rolesSend] = useActor(xServices.siteRolesXService)
|
||||
const { roles } = rolesState.context
|
||||
@@ -88,13 +88,25 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
)
|
||||
}}
|
||||
onDeleteUser={(user) => {
|
||||
usersSend({ type: "DELETE_USER", userId: user.id })
|
||||
usersSend({
|
||||
type: "DELETE_USER",
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
})
|
||||
}}
|
||||
onSuspendUser={(user) => {
|
||||
usersSend({ type: "SUSPEND_USER", userId: user.id })
|
||||
usersSend({
|
||||
type: "SUSPEND_USER",
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
})
|
||||
}}
|
||||
onActivateUser={(user) => {
|
||||
usersSend({ type: "ACTIVATE_USER", userId: user.id })
|
||||
usersSend({
|
||||
type: "ACTIVATE_USER",
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
})
|
||||
}}
|
||||
onResetUserPassword={(user) => {
|
||||
usersSend({ type: "RESET_USER_PASSWORD", userId: user.id })
|
||||
@@ -117,25 +129,29 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
paginationRef={paginationRef}
|
||||
/>
|
||||
|
||||
{userToBeDeleted && (
|
||||
<DeleteDialog
|
||||
isOpen={usersState.matches("confirmUserDeletion")}
|
||||
confirmLoading={usersState.matches("deletingUser")}
|
||||
name={userToBeDeleted.username}
|
||||
entity="user"
|
||||
onConfirm={() => {
|
||||
usersSend("CONFIRM_USER_DELETE")
|
||||
}}
|
||||
onCancel={() => {
|
||||
usersSend("CANCEL_USER_DELETE")
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<DeleteDialog
|
||||
isOpen={
|
||||
usersState.matches("confirmUserDeletion") ||
|
||||
usersState.matches("deletingUser")
|
||||
}
|
||||
confirmLoading={usersState.matches("deletingUser")}
|
||||
name={usernameToDelete ?? ""}
|
||||
entity="user"
|
||||
onConfirm={() => {
|
||||
usersSend("CONFIRM_USER_DELETE")
|
||||
}}
|
||||
onCancel={() => {
|
||||
usersSend("CANCEL_USER_DELETE")
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
type="delete"
|
||||
hideCancel={false}
|
||||
open={usersState.matches("confirmUserSuspension")}
|
||||
open={
|
||||
usersState.matches("confirmUserSuspension") ||
|
||||
usersState.matches("suspendingUser")
|
||||
}
|
||||
confirmLoading={usersState.matches("suspendingUser")}
|
||||
title={Language.suspendDialogTitle}
|
||||
confirmText={Language.suspendDialogAction}
|
||||
@@ -147,8 +163,9 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
}}
|
||||
description={
|
||||
<>
|
||||
{Language.suspendDialogMessagePrefix}{" "}
|
||||
<strong>{userToBeSuspended?.username}</strong>?
|
||||
{Language.suspendDialogMessagePrefix}
|
||||
{usernameToSuspend && " "}
|
||||
<strong>{usernameToSuspend ?? ""}</strong>?
|
||||
</>
|
||||
}
|
||||
/>
|
||||
@@ -156,7 +173,10 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
<ConfirmDialog
|
||||
type="success"
|
||||
hideCancel={false}
|
||||
open={usersState.matches("confirmUserActivation")}
|
||||
open={
|
||||
usersState.matches("confirmUserActivation") ||
|
||||
usersState.matches("activatingUser")
|
||||
}
|
||||
confirmLoading={usersState.matches("activatingUser")}
|
||||
title={Language.activateDialogTitle}
|
||||
confirmText={Language.activateDialogAction}
|
||||
@@ -168,24 +188,30 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
|
||||
}}
|
||||
description={
|
||||
<>
|
||||
{Language.activateDialogMessagePrefix}{" "}
|
||||
<strong>{userToBeActivated?.username}</strong>?
|
||||
{Language.activateDialogMessagePrefix}
|
||||
{usernameToActivate && " "}
|
||||
<strong>{usernameToActivate ?? ""}</strong>?
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<ResetPasswordDialog
|
||||
loading={usersState.matches("resettingUserPassword")}
|
||||
user={userToResetPassword}
|
||||
newPassword={newUserPassword}
|
||||
open={usersState.matches("confirmUserPasswordReset")}
|
||||
onClose={() => {
|
||||
usersSend("CANCEL_USER_PASSWORD_RESET")
|
||||
}}
|
||||
onConfirm={() => {
|
||||
usersSend("CONFIRM_USER_PASSWORD_RESET")
|
||||
}}
|
||||
/>
|
||||
{userIdToResetPassword && (
|
||||
<ResetPasswordDialog
|
||||
open={
|
||||
usersState.matches("confirmUserPasswordReset") ||
|
||||
usersState.matches("resettingUserPassword")
|
||||
}
|
||||
loading={usersState.matches("resettingUserPassword")}
|
||||
user={getSelectedUser(userIdToResetPassword, users)}
|
||||
newPassword={newUserPassword}
|
||||
onClose={() => {
|
||||
usersSend("CANCEL_USER_PASSWORD_RESET")
|
||||
}}
|
||||
onConfirm={() => {
|
||||
usersSend("CONFIRM_USER_PASSWORD_RESET")
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,12 +38,15 @@ export interface UsersContext {
|
||||
getUsersError?: Error | unknown
|
||||
// Suspend user
|
||||
userIdToSuspend?: TypesGen.User["id"]
|
||||
usernameToSuspend?: TypesGen.User["username"]
|
||||
suspendUserError?: Error | unknown
|
||||
// Delete user
|
||||
userIdToDelete?: TypesGen.User["id"]
|
||||
usernameToDelete?: TypesGen.User["username"]
|
||||
deleteUserError?: Error | unknown
|
||||
// Activate user
|
||||
userIdToActivate?: TypesGen.User["id"]
|
||||
usernameToActivate?: TypesGen.User["username"]
|
||||
activateUserError?: Error | unknown
|
||||
// Reset user password
|
||||
userIdToResetPassword?: TypesGen.User["id"]
|
||||
@@ -59,15 +62,27 @@ export interface UsersContext {
|
||||
export type UsersEvent =
|
||||
| { type: "GET_USERS"; query?: string }
|
||||
// Suspend events
|
||||
| { type: "SUSPEND_USER"; userId: TypesGen.User["id"] }
|
||||
| {
|
||||
type: "SUSPEND_USER"
|
||||
userId: TypesGen.User["id"]
|
||||
username: TypesGen.User["username"]
|
||||
}
|
||||
| { type: "CONFIRM_USER_SUSPENSION" }
|
||||
| { type: "CANCEL_USER_SUSPENSION" }
|
||||
// Delete events
|
||||
| { type: "DELETE_USER"; userId: TypesGen.User["id"] }
|
||||
| {
|
||||
type: "DELETE_USER"
|
||||
userId: TypesGen.User["id"]
|
||||
username: TypesGen.User["username"]
|
||||
}
|
||||
| { type: "CONFIRM_USER_DELETE" }
|
||||
| { type: "CANCEL_USER_DELETE" }
|
||||
// Activate events
|
||||
| { type: "ACTIVATE_USER"; userId: TypesGen.User["id"] }
|
||||
| {
|
||||
type: "ACTIVATE_USER"
|
||||
userId: TypesGen.User["id"]
|
||||
username: TypesGen.User["username"]
|
||||
}
|
||||
| { type: "CONFIRM_USER_ACTIVATION" }
|
||||
| { type: "CANCEL_USER_ACTIVATION" }
|
||||
// Reset password events
|
||||
@@ -152,18 +167,19 @@ export const usersMachine =
|
||||
tags: "loading",
|
||||
},
|
||||
idle: {
|
||||
entry: "clearSelectedUser",
|
||||
on: {
|
||||
SUSPEND_USER: {
|
||||
target: "confirmUserSuspension",
|
||||
actions: "assignUserIdToSuspend",
|
||||
actions: "assignUserToSuspend",
|
||||
},
|
||||
DELETE_USER: {
|
||||
target: "confirmUserDeletion",
|
||||
actions: "assignUserIdToDelete",
|
||||
actions: "assignUserToDelete",
|
||||
},
|
||||
ACTIVATE_USER: {
|
||||
target: "confirmUserActivation",
|
||||
actions: "assignUserIdToActivate",
|
||||
actions: "assignUserToActivate",
|
||||
},
|
||||
RESET_USER_PASSWORD: {
|
||||
target: "confirmUserPasswordReset",
|
||||
@@ -391,6 +407,16 @@ export const usersMachine =
|
||||
},
|
||||
|
||||
actions: {
|
||||
clearSelectedUser: assign({
|
||||
userIdToSuspend: (_) => undefined,
|
||||
usernameToSuspend: (_) => undefined,
|
||||
userIdToDelete: (_) => undefined,
|
||||
usernameToDelete: (_) => undefined,
|
||||
userIdToActivate: (_) => undefined,
|
||||
usernameToActivate: (_) => undefined,
|
||||
userIdToResetPassword: (_) => undefined,
|
||||
userIdToUpdateRoles: (_) => undefined,
|
||||
}),
|
||||
assignUsers: assign({
|
||||
users: (_, event) => event.data,
|
||||
}),
|
||||
@@ -400,14 +426,17 @@ export const usersMachine =
|
||||
assignGetUsersError: assign({
|
||||
getUsersError: (_, event) => event.data,
|
||||
}),
|
||||
assignUserIdToSuspend: assign({
|
||||
assignUserToSuspend: assign({
|
||||
userIdToSuspend: (_, event) => event.userId,
|
||||
usernameToSuspend: (_, event) => event.username,
|
||||
}),
|
||||
assignUserIdToDelete: assign({
|
||||
assignUserToDelete: assign({
|
||||
userIdToDelete: (_, event) => event.userId,
|
||||
usernameToDelete: (_, event) => event.username,
|
||||
}),
|
||||
assignUserIdToActivate: assign({
|
||||
assignUserToActivate: assign({
|
||||
userIdToActivate: (_, event) => event.userId,
|
||||
usernameToActivate: (_, event) => event.username,
|
||||
}),
|
||||
assignUserIdToResetPassword: assign({
|
||||
userIdToResetPassword: (_, event) => event.userId,
|
||||
|
||||
Reference in New Issue
Block a user