feat: improvement org member list (#13859)

* fix: sticky action bar and align checkbox

* feat: make teams filterable and clickable, total members

* fix: update members count

---------

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
This commit is contained in:
Amit Sharma
2024-03-05 11:09:14 +00:00
committed by GitHub
co-authored by sean-brydon Udit Takkar
parent e39bf37f91
commit 01ac2e640a
3 changed files with 23 additions and 12 deletions
@@ -110,6 +110,7 @@ function reducer(state: State, action: Action): State {
export function UserListTable() {
const { data: session } = useSession();
const { data: currentMembership } = trpc.viewer.organizations.listCurrent.useQuery();
const { data: teams } = trpc.viewer.organizations.getTeams.useQuery();
const tableContainerRef = useRef<HTMLDivElement>(null);
const [state, dispatch] = useReducer(reducer, initialState);
const { t } = useLocale();
@@ -126,6 +127,7 @@ export function UserListTable() {
}
);
const totalDBRowCount = data?.pages?.[0]?.meta?.totalRowCount ?? 0;
const adminOrOwner = currentMembership?.user.role === "ADMIN" || currentMembership?.user.role === "OWNER";
const domain = orgBranding?.fullDomain ?? WEBAPP_URL;
@@ -160,7 +162,7 @@ export function UserListTable() {
{
id: "member",
accessorFn: (data) => data.email,
header: "Member",
header: `Member (${totalDBRowCount})`,
cell: ({ row }) => {
const { username, email } = row.original;
return (
@@ -210,8 +212,9 @@ export function UserListTable() {
},
{
id: "teams",
accessorFn: (data) => data.teams.map((team) => team.name),
header: "Teams",
cell: ({ row }) => {
cell: ({ row, table }) => {
const { teams, accepted, email, username } = row.original;
// TODO: Implement click to filter
return (
@@ -226,13 +229,22 @@ export function UserListTable() {
</Badge>
)}
{teams.map((team) => (
<Badge key={team.id} variant="gray">
<Badge
key={team.id}
variant="gray"
onClick={() => {
table.getColumn("teams")?.setFilterValue([team.name]);
}}>
{team.name}
</Badge>
))}
</div>
);
},
filterFn: (rows, _, filterValue: string[]) => {
const teamNames = rows.original.teams.map((team) => team.name);
return filterValue.some((value: string) => teamNames.includes(value));
},
},
{
id: "actions",
@@ -262,11 +274,10 @@ export function UserListTable() {
];
return cols;
}, [session?.user.id, adminOrOwner, dispatch, domain]);
}, [session?.user.id, adminOrOwner, dispatch, domain, totalDBRowCount]);
//we must flatten the array of arrays from the useInfiniteQuery hook
const flatData = useMemo(() => data?.pages?.flatMap((page) => page.rows) ?? [], [data]) as User[];
const totalDBRowCount = data?.pages?.[0]?.meta?.totalRowCount ?? 0;
const totalFetched = flatData.length;
//called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table
@@ -342,6 +353,11 @@ export function UserListTable() {
{ label: "Member", value: "MEMBER" },
],
},
{
tableAccessor: "teams",
title: "Teams",
options: teams ? teams.map((team) => ({ label: team.name, value: team.name })) : [],
},
]}
/>