fix(ui): reset member table filters per team and index org members once

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
ryan 2026-09-11 01:52:24 +00:00
parent a9bd86b371
commit f61e204a72
4 changed files with 26 additions and 5 deletions

View file

@ -121,8 +121,8 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
return <div className="p-4">Organization not found</div>;
}
const orgMemberFor = (record: Member) =>
record.user_id != null ? (orgData.members || []).find((m) => m.user_id === record.user_id) : undefined;
const orgMemberById = new Map((orgData.members || []).map((m) => [m.user_id, m]));
const orgMemberFor = (record: Member) => (record.user_id != null ? orgMemberById.get(record.user_id) : undefined);
const orgExtraColumns: MemberTableColumn[] = [
{
@ -252,6 +252,7 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
<TabsContent keepMounted={hasVisited("members")} value="members" className="pt-4">
<div className="space-y-4">
<MemberTable
key={orgData.organization_id}
members={(orgData.members || []).map((m) => ({
role: m.user_role || "",
user_id: m.user_id,

View file

@ -96,8 +96,6 @@ function derivePinning<TData, TValue>(columns: ColumnDef<TData, TValue>[]): Colu
return { left: collect("left"), right: collect("right") };
}
// TanStack's default drops a column from global search when the first row's value is not a
// string or number, which silently hides sparse columns; an explicit opt-in overrides that.
function columnCanGlobalFilter<TData>(firstRow: TData | undefined, column: Column<TData, unknown>): boolean {
if (column.columnDef.enableGlobalFilter === true) return true;
if (firstRow === undefined || column.accessorFn === undefined) return false;

View file

@ -1,4 +1,4 @@
import { screen, within } from "@testing-library/react";
import { fireEvent, screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { renderWithProviders } from "../../../tests/test-utils";
@ -168,6 +168,27 @@ describe("TeamMembersComponent", () => {
expect(table).toHaveTextContent("admin");
});
it("clears the member search when a different team is shown", () => {
const props = {
canEditTeam: false,
handleMemberDelete: mockHandleMemberDelete,
setSelectedEditMember: mockSetSelectedEditMember,
setIsEditMemberModalVisible: mockSetIsEditMemberModalVisible,
setIsAddMemberModalVisible: mockSetIsAddMemberModalVisible,
};
const { rerender } = renderWithProviders(<TeamMembersComponent teamData={createMockTeamData()} {...props} />);
fireEvent.change(screen.getByTestId("datatable-search"), { target: { value: "user2" } });
expect(screen.queryByText("user1@test.com")).not.toBeInTheDocument();
const otherTeam = createMockTeamData({ team_id: "team-456" });
rerender(<TeamMembersComponent teamData={otherTeam} {...props} />);
expect(screen.getByTestId("datatable-search")).toHaveValue("");
expect(screen.getAllByText("user1@test.com").length).toBeGreaterThanOrEqual(1);
expect(screen.getAllByText("user2@test.com").length).toBeGreaterThanOrEqual(1);
});
it("should render Add Member button", () => {
renderWithProviders(
<TeamMembersComponent

View file

@ -187,6 +187,7 @@ export default function TeamMemberTab({
return (
<MemberTable
key={teamData.team_id}
members={teamData.team_info.members_with_roles}
canEdit={canEditTeam}
onEdit={(record) => {