From b116c7fd8b87e4cea090d0e24bc924e81eae56c4 Mon Sep 17 00:00:00 2001 From: Maina Wycliffe Date: Tue, 14 Nov 2023 14:37:36 +0300 Subject: [PATCH 1/3] fix: fix user action dropdown not being shown correctly Closes #1498 --- src/components/UserList/index.tsx | 62 ++++++++++++++++++------------- src/pages/UsersPage.tsx | 4 +- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/components/UserList/index.tsx b/src/components/UserList/index.tsx index 765809136..6a7ab9138 100644 --- a/src/components/UserList/index.tsx +++ b/src/components/UserList/index.tsx @@ -8,8 +8,10 @@ import { tables } from "../../context/UserAccessContext/permissions"; import { withAccessCheck } from "../AccessCheck/AccessCheck"; import { DataTable } from "../DataTable"; import { IconButton } from "../IconButton"; -import { Menu } from "../Menu"; import { Age } from "../../ui/Age"; +import { Menu } from "@headlessui/react"; +import { DotsVerticalIcon } from "@heroicons/react/solid"; +import { Float } from "@headlessui-float/react"; type UserListProps = { data: any[]; @@ -84,31 +86,39 @@ function ActionMenu({ deleteUser }: { deleteUser: () => void }) { return withAccessCheck(
- - - { - deleteUser(); - }} - > - + + + + + { + deleteUser(); }} - icon={ - + <> + + } /> - } - /> - Delete - - + Delete + + + +
, tables.identities, @@ -132,11 +142,11 @@ export function UserList({ const result = await hasResourceAccess(tables.identities, "write"); setCanDeleteUser(result); })(); - }, [roles]); + }, [hasResourceAccess, roles]); const columns = useMemo(() => { return getColumns(deleteUser, canDeleteUser); - }, [canDeleteUser]); + }, [canDeleteUser, deleteUser]); return (
diff --git a/src/pages/UsersPage.tsx b/src/pages/UsersPage.tsx index d8422cf24..184275d0f 100644 --- a/src/pages/UsersPage.tsx +++ b/src/pages/UsersPage.tsx @@ -112,7 +112,9 @@ export function UsersPage() { title={ Users + + Users + ]} /> } From 626879a6bf039399dbdda81bca220c647dea3750 Mon Sep 17 00:00:00 2001 From: Maina Wycliffe Date: Tue, 14 Nov 2023 14:52:04 +0300 Subject: [PATCH 2/3] refactor: switch to react query for fetching user data --- src/pages/UsersPage.tsx | 66 +++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/pages/UsersPage.tsx b/src/pages/UsersPage.tsx index 184275d0f..af6e04f4c 100644 --- a/src/pages/UsersPage.tsx +++ b/src/pages/UsersPage.tsx @@ -1,12 +1,16 @@ -import { useEffect, useRef, useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { useRef, useState } from "react"; import { ImUserPlus } from "react-icons/im"; +import { MdAdminPanelSettings } from "react-icons/md"; import { + deleteUser, getRegisteredUsers, inviteUser, - deleteUser, updateUserRole } from "../api/services/users"; import { Modal } from "../components"; +import { AccessCheck } from "../components/AccessCheck/AccessCheck"; +import { BreadcrumbNav, BreadcrumbRoot } from "../components/BreadcrumbNav"; import { ConfirmationPromptDialog } from "../components/Dialogs/ConfirmationPromptDialog"; import { Head } from "../components/Head/Head"; import { @@ -14,29 +18,35 @@ import { InviteUserFormValue } from "../components/InviteUserForm/InviteUserForm"; import { SearchLayout } from "../components/Layout"; -import { toastError, toastSuccess } from "../components/Toast/toast"; -import { UserList } from "../components/UserList"; -import { useLoader } from "../hooks"; -import { BreadcrumbNav, BreadcrumbRoot } from "../components/BreadcrumbNav"; -import { MdAdminPanelSettings } from "react-icons/md"; import { ManageUserRoleValue, ManageUserRoles } from "../components/ManageUserRoles/ManageUserRoles"; -import { AccessCheck } from "../components/AccessCheck/AccessCheck"; +import { toastError, toastSuccess } from "../components/Toast/toast"; +import { UserList } from "../components/UserList"; import { tables } from "../context/UserAccessContext/permissions"; -import { RegisteredUser } from "../api/types/users"; export function UsersPage() { - const [users, setUsers] = useState([]); const [openDeleteConfirmDialog, setOpenDeleteConfirmDialog] = useState(false); const [deletedUserId, setDeletedUserId] = useState(); const [isOpen, setIsOpen] = useState(false); const [openRoleManageModal, setOpenRoleManageModal] = useState(false); - const { loading, setLoading, idle } = useLoader(); const containerRef = useRef(null); + const { + isLoading, + data: users = [], + refetch + } = useQuery({ + queryKey: ["users", "list", "settings"], + queryFn: () => getRegisteredUsers(), + select: (data) => { + return data.data || []; + }, + cacheTime: 0 + }); + const onSubmit = async (val: InviteUserFormValue) => { try { await inviteUser({ @@ -44,7 +54,6 @@ export function UsersPage() { lastName: val.lastName, email: val.email }); - const users: RegisteredUser[] = await fetchUsersList(); const userId = users.find((item) => item.email === val.email)?.id; if (userId) { await updateUserRole(userId, [val.role]); @@ -52,7 +61,7 @@ export function UsersPage() { const userName = `${val.firstName} ${val.lastName}`; toastSuccess(`${userName} invited successfully`); setIsOpen(false); - fetchUsersList(); + refetch(); } catch (ex) { toastError(ex as any); } @@ -64,33 +73,19 @@ export function UsersPage() { const user = users.find((item) => item.id === val.userId); toastSuccess(`${user!.name} role updated successfully`); setOpenRoleManageModal(false); - fetchUsersList(); + refetch(); } catch (ex) { toastError(ex as any); } }; - async function fetchUsersList() { - let users: RegisteredUser[] = []; - setLoading(true); - try { - const { data } = await getRegisteredUsers(); - users = data || []; - setUsers(data || []); - } catch (ex) { - toastError(ex as any); - } - setLoading(false); - return users; - } - async function deleteUserAction(userId: string | undefined) { if (!userId) { return; } try { const { data } = await deleteUser(userId); - fetchUsersList(); + refetch(); if (data) { toastSuccess(`user deleted successfully`); } @@ -100,11 +95,6 @@ export function UsersPage() { setOpenDeleteConfirmDialog(false); } - useEffect(() => { - fetchUsersList(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - return ( <> @@ -118,11 +108,9 @@ export function UsersPage() { ]} /> } - onRefresh={() => { - fetchUsersList(); - }} + onRefresh={refetch} contentClass="p-0 h-full" - loading={loading} + loading={isLoading} >
Date: Tue, 14 Nov 2023 14:52:52 +0300 Subject: [PATCH 3/3] fix: fix issue where it would attempt to create existing user --- src/pages/UsersPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/UsersPage.tsx b/src/pages/UsersPage.tsx index af6e04f4c..5e63a6a58 100644 --- a/src/pages/UsersPage.tsx +++ b/src/pages/UsersPage.tsx @@ -57,6 +57,7 @@ export function UsersPage() { const userId = users.find((item) => item.email === val.email)?.id; if (userId) { await updateUserRole(userId, [val.role]); + return; } const userName = `${val.firstName} ${val.lastName}`; toastSuccess(`${userName} invited successfully`);