All files / src/features/Settings/Team/hooks useListTeamMembersV2.tsx

0% Statements 0/28
0% Branches 0/8
0% Functions 0/9
0% Lines 0/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                                                                                                                                                                                       
// useListTeamMembersV2.ts
import { useMemo, useRef, useState } from "react";
import { useGetCurrentMerchantId } from "@hooks/common";
import { useAppSelector } from "@redux/hooks";
import { sorting as sortingReducer } from "@redux/slices/fundraisers";
import { selectQueryString } from "@redux/slices/search";
import { QKEY_LIST_TEAM_MEMBERS } from "@constants/queryKeys";
import { useTeamPermissions } from "features/Permissions/AccessControl/hooks";
import useCheckPAH from "@hooks/common/useCheckPAH";
import { usePahReassignmentStatus } from "@hooks/common/usePahReassignmentStatus";
import { useInfiniteQuery } from "react-query";
import { teamMembersInfiniteQueryFunction } from "./teamMembersInfiniteQueryFunction";
import { ROWS_PER_PAGE } from "@hooks/common/usePagination";
import { MemberData } from "@customTypes/team.member";
import {
  buildInvitedPahRow,
  excludeInvitedPah,
} from "../helpers/pahReassignmentRows";
 
const useListTeamMembersV2 = () => {
  const { merchantId } = useGetCurrentMerchantId();
  const sorting = useAppSelector(sortingReducer);
  const searchQuery = useAppSelector((state) =>
    selectQueryString(state, QKEY_LIST_TEAM_MEMBERS),
  );
  const { isListAllowed } = useTeamPermissions();
 
  const { owner, isLoading: isOwnerLoading } = useCheckPAH(isListAllowed);
  const { reassignment } = usePahReassignmentStatus(isListAllowed);
 
  const {
    data,
    fetchNextPage,
    isLoading,
    isFetching,
    isFetchingNextPage,
    hasNextPage,
  } = useInfiniteQuery(
    [QKEY_LIST_TEAM_MEMBERS, merchantId, sorting, searchQuery],
    teamMembersInfiniteQueryFunction({
      merchantId,
      sorting,
      searchQuery,
      memberStatus: "",
      rowsPerPage: ROWS_PER_PAGE,
    }),
    {
      getNextPageParam: (lastPage) => lastPage.nextCursor,
      enabled: Boolean(merchantId),
    },
  );
 
  const allData = data?.pages.map((page: any) => page.data).flat() ?? [];
 
  const members = useMemo(
    () => allData.filter((row: any) => row.roleName !== "owner"),
    [allData],
  );
 
  // GB-21472: while a reassignment is pending, surface the invited new PAH in
  // the Primary Account Holder section (with an "Invitation Sent" status) and
  // keep them out of the Members list — otherwise they show as their previous
  // role (e.g. Administrator).
  const visibleMembers = useMemo(
    () => excludeInvitedPah(members, reassignment),
    [members, reassignment],
  );
 
  const pahRows = useMemo(
    () =>
      [buildInvitedPahRow(reassignment, members), owner].filter(
        Boolean,
      ) as MemberData[],
    [reassignment, members, owner],
  );
 
  const [page, setPage] = useState(1);
  const pageRef = useRef(1);
 
  const handlePageChange = () => {
    if (!isFetchingNextPage && hasNextPage) {
      const newPage = pageRef.current + 1;
      fetchNextPage();
      pageRef.current = newPage;
      setPage(newPage);
    }
  };
 
  return {
    data,
    owner,
    isLoading,
    isFetching,
    isFetchingNextPage,
    hasNextPage,
    page,
    setPageDispatcher: setPage,
    handlePageChange,
    allRows: allData,
    members: visibleMembers,
    pahRows,
    reassignment,
    // Keep the total in step with the rows actually rendered: the invited PAH is
    // moved out of Members into the PAH section, so drop it from the count
    // (otherwise pagination over-counts by the excluded row). GB-21472.
    totalRows: Math.max(
      0,
      (data?.pages?.[0]?.total ?? 0) - (members.length - visibleMembers.length),
    ),
    searchQuery,
    isOwnerLoading,
  };
};
 
export default useListTeamMembersV2;