From 41cc95feb039f370f6ad36b42420e701e298ad4a Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Fri, 10 Apr 2026 10:51:10 +0100 Subject: [PATCH 01/19] Create search bar for people table --- .../src/components/user/PeoplePage.tsx | 2 +- .../src/components/user/PeopleTable.tsx | 415 ++++++++++-------- 2 files changed, 233 insertions(+), 184 deletions(-) diff --git a/apps/frontend/src/components/user/PeoplePage.tsx b/apps/frontend/src/components/user/PeoplePage.tsx index d81f9bd603..6e050b27e7 100644 --- a/apps/frontend/src/components/user/PeoplePage.tsx +++ b/apps/frontend/src/components/user/PeoplePage.tsx @@ -31,7 +31,7 @@ export default function PeoplePage() { }} selection={false} showInvitationButtons - search + search={false} onRemove={(user: { id: number }) => api({ toastSuccessMessage: 'User removed successfully!', diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index bd9792012e..ab6db69526 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -7,6 +7,7 @@ import MaterialTableCore, { } from '@material-table/core'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; +import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import { Formik } from 'formik'; import React, { useState, useEffect, useContext } from 'react'; @@ -158,18 +159,17 @@ const PeopleTable = ({ subtractUsers: selectedUsers ? selectedUsers : [], userRole: userRole ? userRole : null, }); - const featureContext = useContext(FeatureContext); const isEmailSearchEnabled = !!featureContext.featuresMap.get( FeatureId.EMAIL_SEARCH )?.isEnabled; const api = useDataApi(); - const [currentPageIds, setCurrentPageIds] = useState([]); const [invitedUsers, setInvitedUsers] = useState([]); const [tableEmails, setTableEmails] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); + const [searchName, setSearchName] = useState(''); const tableRef = React.createRef>(); @@ -186,6 +186,11 @@ const PeopleTable = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [data?.length]); + useEffect(() => { + tableRef.current && tableRef.current.onQueryChange({}); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchParams.get('search')]); + const actionArray = []; action && !selection && @@ -270,7 +275,7 @@ const PeopleTable = ({ : orderBy?.orderDirection == PaginationSortDirection.DESC ? PaginationSortDirection.DESC : undefined, - searchText: tableQuery.search, + searchText: searchParams.get('search'), }) .then(({ users }) => { const filteredData = data @@ -320,210 +325,254 @@ const PeopleTable = ({ } }); + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + setSearchParams((searchParams) => { + if (searchName) { + searchParams.set('search', searchName); + } else { + searchParams.delete('search'); + } + + return searchParams; + }); + } else { + return searchParams; + } + }; + return ( - { - // If there is an email and it has not already been searched - if (values.email && !tableEmails.includes(values.email)) { - const userDetails = await getUserByEmail(values.email, api); - - if (!userDetails) { - setFieldError('email', 'No user found for the given email'); - - return; - } + + { + // If there is an email and it has not already been searched + if (values.email && !tableEmails.includes(values.email)) { + const userDetails = await getUserByEmail(values.email, api); - if (selectedUsers?.includes(userDetails.id)) { - setFieldError('email', 'User has already been added'); + if (!userDetails) { + setFieldError('email', 'No user found for the given email'); - return; - } + return; + } - if (invitedUsers.every((user) => user.id !== userDetails.id)) { - //Add users to the table - setInvitedUsers([userDetails].concat(invitedUsers)); - setTableEmails(tableEmails.concat([values.email])); - setFieldValue('email', ''); - - //If we are selecting multiple users add the user as pre selected. - if (selection) { - setSelectedParticipants?.( - selectedParticipants?.concat([userDetails]) || [] - ); + if (selectedUsers?.includes(userDetails.id)) { + setFieldError('email', 'User has already been added'); + + return; } - setQuery({ - ...query, - subtractUsers: (query.subtractUsers as number[]).concat( - userDetails.id - ), - }); - tableRef.current && tableRef.current.onQueryChange({}); + if (invitedUsers.every((user) => user.id !== userDetails.id)) { + //Add users to the table + setInvitedUsers([userDetails].concat(invitedUsers)); + setTableEmails(tableEmails.concat([values.email])); + setFieldValue('email', ''); + + //If we are selecting multiple users add the user as pre selected. + if (selection) { + setSelectedParticipants?.( + selectedParticipants?.concat([userDetails]) || [] + ); + } + + setQuery({ + ...query, + subtractUsers: (query.subtractUsers as number[]).concat( + userDetails.id + ), + }); + tableRef.current && tableRef.current.onQueryChange({}); + } else { + setFieldError('email', 'Could not add user to Proposal'); + } + } else if (tableEmails.includes(values.email)) { + setFieldError( + 'email', + 'User has already been added, possibly use filter instead' + ); } else { - setFieldError('email', 'Could not add user to Proposal'); + setFieldError('email', 'Please enter a email'); } - } else if (tableEmails.includes(values.email)) { - setFieldError( - 'email', - 'User has already been added, possibly use filter instead' - ); - } else { - setFieldError('email', 'Please enter a email'); - } - }} - > - - - {title} - - } - columns={setSortDirectionOnSortField( - columns ? columns : localColumns, - persistUrlQueryParams ? searchParams.get('sortField') : '', - sortDirection === PaginationSortDirection.ASC - ? PaginationSortDirection.ASC - : sortDirection === PaginationSortDirection.DESC - ? PaginationSortDirection.DESC - : undefined - )} - onSelectionChange={handleColumnSelectionChange} - data={fetchRemoteUsersData} - onPageChange={(page) => { - persistUrlQueryParams && - setSearchParams((searchParams) => { - searchParams.set('page', page.toString()); - - return searchParams; - }); - }} - onRowsPerPageChange={(pageSize) => { - persistUrlQueryParams && - setSearchParams((searchParams) => { - searchParams.set('pageSize', pageSize.toString()); - searchParams.set('page', '0'); - - return searchParams; - }); - }} - onSearchChange={(searchText) => { - persistUrlQueryParams && - setSearchParams((searchParams) => { - if (searchText) { - searchParams.set('search', searchText); - searchParams.set('page', '0'); - } else { - searchParams.delete('search'); - } - - return searchParams; - }); + { - const [orderBy] = orderByCollection; + > + + setSearchName(e.target.value)} + sx={{ + display: 'flex', + alignSelf: 'right', + alignItems: 'right', + maxWidth: '15%', + }} + /> + + + {title} + + } + columns={setSortDirectionOnSortField( + columns ? columns : localColumns, + persistUrlQueryParams ? searchParams.get('sortField') : '', + sortDirection === PaginationSortDirection.ASC + ? PaginationSortDirection.ASC + : sortDirection === PaginationSortDirection.DESC + ? PaginationSortDirection.DESC + : undefined + )} + onSelectionChange={handleColumnSelectionChange} + data={fetchRemoteUsersData} + onPageChange={(page) => { + persistUrlQueryParams && + setSearchParams((searchParams) => { + searchParams.set('page', page.toString()); - if (!orderBy) { + return searchParams; + }); + }} + onRowsPerPageChange={(pageSize) => { persistUrlQueryParams && setSearchParams((searchParams) => { - searchParams.delete('sortField'); - searchParams.delete('sortDirection'); + searchParams.set('pageSize', pageSize.toString()); + searchParams.set('page', '0'); return searchParams; }); - } else { + }} + onSearchChange={(searchText) => { persistUrlQueryParams && setSearchParams((searchParams) => { - searchParams.set('sortField', orderBy.orderByField); - searchParams.set('sortDirection', orderBy.orderDirection); + if (searchText) { + searchParams.set('search', searchText); + searchParams.set('page', '0'); + } else { + searchParams.delete('search'); + } return searchParams; }); - } - }} - options={{ - search: search, - searchText: persistUrlQueryParams - ? searchParams.get('search') || undefined - : undefined, - debounceInterval: 400, - selection: selection, - headerSelectionProps: { - inputProps: { 'aria-label': 'Select All Rows' }, - }, - pageSize: - persistUrlQueryParams && searchParams.get('pageSize') - ? +searchParams.get('pageSize')! + }} + onOrderCollectionChange={(orderByCollection) => { + const [orderBy] = orderByCollection; + + if (!orderBy) { + persistUrlQueryParams && + setSearchParams((searchParams) => { + searchParams.delete('sortField'); + searchParams.delete('sortDirection'); + + return searchParams; + }); + } else { + persistUrlQueryParams && + setSearchParams((searchParams) => { + searchParams.set('sortField', orderBy.orderByField); + searchParams.set('sortDirection', orderBy.orderDirection); + + return searchParams; + }); + } + }} + options={{ + search: search, + searchText: persistUrlQueryParams + ? searchParams.get('search') || undefined : undefined, - initialPage: - persistUrlQueryParams && searchParams.get('page') - ? +searchParams.get('page')! - : 0, - ...mtOptions, - selectionProps: (rowdata: BasicUserDetails) => ({ - inputProps: { - 'aria-label': `${rowdata.firstname}-${rowdata.lastname}-${rowdata.institution}-select`, + debounceInterval: 400, + selection: selection, + headerSelectionProps: { + inputProps: { 'aria-label': 'Select All Rows' }, }, - }), - }} - actions={actionArray} - editable={ - onRemove - ? { - onRowDelete: (oldData) => - new Promise((resolve) => { - resolve(); - (onRemove as FunctionType)(oldData); - }), - isDeletable: (rowData) => { - return getCurrentUser()?.user.id !== rowData.id; - }, - } - : {} - } - localization={{ - body: { emptyDataSourceMessage: 'No Users' }, - toolbar: { - nRowsSelected: '{0} User(s) Selected', - searchPlaceholder: 'Filter found users', - searchTooltip: 'Filter found users', - }, - }} - components={{ - Toolbar: - isEmailSearchEnabled && emailSearch - ? EmailSearchBar - : MTableToolbar, - }} - /> - {showInvitationButtons && ( - - {invitationButtons.map((item: InvitationButtonProps, i) => ( - - ))} - - )} - - + pageSize: + persistUrlQueryParams && searchParams.get('pageSize') + ? +searchParams.get('pageSize')! + : undefined, + initialPage: + persistUrlQueryParams && searchParams.get('page') + ? +searchParams.get('page')! + : 0, + ...mtOptions, + selectionProps: (rowdata: BasicUserDetails) => ({ + inputProps: { + 'aria-label': `${rowdata.firstname}-${rowdata.lastname}-${rowdata.institution}-select`, + }, + }), + }} + actions={actionArray} + editable={ + onRemove + ? { + onRowDelete: (oldData) => + new Promise((resolve) => { + resolve(); + (onRemove as FunctionType)(oldData); + }), + isDeletable: (rowData) => { + return getCurrentUser()?.user.id !== rowData.id; + }, + } + : {} + } + localization={{ + body: { emptyDataSourceMessage: 'No Users' }, + toolbar: { + nRowsSelected: '{0} User(s) Selected', + searchPlaceholder: 'Filter found users', + searchTooltip: 'Filter found users', + }, + }} + components={{ + Toolbar: + isEmailSearchEnabled && emailSearch + ? EmailSearchBar + : MTableToolbar, + }} + /> + {showInvitationButtons && ( + + {invitationButtons.map((item: InvitationButtonProps, i) => ( + + ))} + + )} + + + ); }; From 8aeb77347c2c962bea89692f9afb5a76913afdfb Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Mon, 13 Apr 2026 13:47:02 +0100 Subject: [PATCH 02/19] add styling to search bar --- .../src/components/user/PeopleTable.tsx | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index ab6db69526..e3f81f3ae4 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -5,6 +5,8 @@ import MaterialTableCore, { Query, QueryResult, } from '@material-table/core'; +import SearchIcon from '@mui/icons-material/Search'; +import { Grid, Tooltip } from '@mui/material'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; @@ -405,32 +407,41 @@ const PeopleTable = ({ }, }} > - + + ({ + marginRight: theme.spacing(1), + alignSelf: 'center', + fontSize: 'large', + color: theme.palette.primary.main, + })} + > + setSearchName(e.target.value)} - sx={{ - display: 'flex', - alignSelf: 'right', - alignItems: 'right', - maxWidth: '15%', - }} + sx={(theme) => ({ + flex: 1, + alignSelf: 'center', + maxWidth: 260, + marginRight: theme.spacing(3), + })} /> - + Date: Mon, 13 Apr 2026 14:33:58 +0100 Subject: [PATCH 03/19] remove extra sapcing --- apps/frontend/src/components/user/PeopleTable.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index e3f81f3ae4..2077c3154e 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -413,6 +413,8 @@ const PeopleTable = ({ sx={{ display: 'flex', justifyContent: 'flex-end', + marginTop: '-30px', + marginBottom: '-10px', }} > From 50a4257d4dbf7c718f376eb27b6af52f9c0bc34e Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Wed, 6 May 2026 10:53:30 +0100 Subject: [PATCH 04/19] add e2e test --- apps/e2e/cypress/e2e/peopleTable.cy.ts | 15 +++++++++++++++ apps/frontend/src/components/user/PeopleTable.tsx | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/peopleTable.cy.ts b/apps/e2e/cypress/e2e/peopleTable.cy.ts index 6311ae79ce..44fe95606f 100644 --- a/apps/e2e/cypress/e2e/peopleTable.cy.ts +++ b/apps/e2e/cypress/e2e/peopleTable.cy.ts @@ -140,6 +140,21 @@ context('PageTable component tests', () => { expect(firstTableRowTextAfterSorting).not.equal(element.text()); }); }); + + it('PeopleTable should allow search upon Enter', () => { + const user = initialDBData.users['user1']; + cy.login('officer'); + cy.visit('/People'); + + cy.finishedLoading(); + + cy.get('[data-cy="people-table"]').should('exist'); + + cy.get('[aria-label="people-search"]').type(user.lastName); + cy.get('[aria-label="people-search"]').type('Enter'); + cy.get('[data-cy="people-table"]').find('li:first-child'); + cy.contains(user.firstName); + }); }); describe('PeopleTable component allows swapping between PIs and CoIs', () => { diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index 2077c3154e..741c7d1cb5 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -428,7 +428,7 @@ const PeopleTable = ({ > Date: Thu, 14 May 2026 13:02:34 +0100 Subject: [PATCH 05/19] Add label to TextField for tests --- apps/frontend/src/components/user/PeopleTable.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index 741c7d1cb5..23ad31cf0e 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -429,6 +429,7 @@ const PeopleTable = ({ Date: Thu, 14 May 2026 13:30:06 +0100 Subject: [PATCH 06/19] Add test fix --- apps/e2e/cypress/e2e/peopleTable.cy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/e2e/cypress/e2e/peopleTable.cy.ts b/apps/e2e/cypress/e2e/peopleTable.cy.ts index 44fe95606f..ebc828fc27 100644 --- a/apps/e2e/cypress/e2e/peopleTable.cy.ts +++ b/apps/e2e/cypress/e2e/peopleTable.cy.ts @@ -150,8 +150,8 @@ context('PageTable component tests', () => { cy.get('[data-cy="people-table"]').should('exist'); - cy.get('[aria-label="people-search"]').type(user.lastName); - cy.get('[aria-label="people-search"]').type('Enter'); + cy.get('[data-cy="people-search"]').type(user.lastName); + cy.get('[data-cy="people-search"]').type('Enter'); cy.get('[data-cy="people-table"]').find('li:first-child'); cy.contains(user.firstName); }); From 8a3c34eca62a2883245a865d2a5d5911b128f6fb Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Thu, 14 May 2026 14:09:52 +0100 Subject: [PATCH 07/19] remove test error --- apps/e2e/cypress/e2e/peopleTable.cy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/e2e/cypress/e2e/peopleTable.cy.ts b/apps/e2e/cypress/e2e/peopleTable.cy.ts index ebc828fc27..aa018a87ec 100644 --- a/apps/e2e/cypress/e2e/peopleTable.cy.ts +++ b/apps/e2e/cypress/e2e/peopleTable.cy.ts @@ -152,8 +152,7 @@ context('PageTable component tests', () => { cy.get('[data-cy="people-search"]').type(user.lastName); cy.get('[data-cy="people-search"]').type('Enter'); - cy.get('[data-cy="people-table"]').find('li:first-child'); - cy.contains(user.firstName); + cy.get('[data-cy="people-table"]').contains(user.firstName); }); }); From b5a1580e6711b2b8e2438428e900565aed9012a2 Mon Sep 17 00:00:00 2001 From: Ellen Wright <144028998+ellen-wright@users.noreply.github.com> Date: Thu, 28 May 2026 11:14:54 +0100 Subject: [PATCH 08/19] Add fix for eventlog e2e test --- apps/e2e/cypress/e2e/eventLogs.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/eventLogs.cy.ts b/apps/e2e/cypress/e2e/eventLogs.cy.ts index 8d10d51052..974e337ef8 100644 --- a/apps/e2e/cypress/e2e/eventLogs.cy.ts +++ b/apps/e2e/cypress/e2e/eventLogs.cy.ts @@ -77,7 +77,8 @@ context('Event log tests', () => { cy.finishedLoading(); - cy.get('[aria-label="Search"]').type(user.lastName); + cy.get('[data-cy="people-search"]').type(user.lastName); + cy.get('[data-cy="people-search"]').type('Enter'); cy.contains(user.firstName) .parent() From 0a14cadfe4dd06670da29366e128d9d155fd973b Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Mon, 8 Jun 2026 10:15:03 +0100 Subject: [PATCH 09/19] Change FAP search test for people table --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 1a7ba0e8b8..cc81c7b9d5 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -10,6 +10,7 @@ import initialDBData from '../support/initialDBData'; function searchMuiTableAsync(search: string) { cy.get('[data-cy="co-proposers"] [aria-label="Search"]').type(search); + cy.get('[data-cy="co-proposers"] [aria-label="Search"]').type('Enter'); cy.get('[role="progressbar"]').should('exist'); cy.get('[role="progressbar"]').should('not.exist'); From b06a8f7f18d50c11f1ff511e526b0e279842ef1e Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Wed, 10 Jun 2026 11:16:00 +0100 Subject: [PATCH 10/19] Hide custom search for FAP review modal --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 1 - .../AssignFapMemberToProposalModal.tsx | 1 + .../proposal/PeopleSelectorModal.tsx | 1 + .../src/components/user/PeoplePage.tsx | 1 + .../src/components/user/PeopleTable.tsx | 75 ++++++++++--------- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 5a2691877b..a393eef3c3 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -10,7 +10,6 @@ import initialDBData from '../support/initialDBData'; function searchMuiTableAsync(search: string) { cy.get('[data-cy="co-proposers"] [aria-label="Search"]').type(search); - cy.get('[data-cy="co-proposers"] [aria-label="Search"]').type('Enter'); cy.get('[role="progressbar"]').should('exist'); cy.get('[role="progressbar"]').should('not.exist'); diff --git a/apps/frontend/src/components/fap/Proposals/AssignFapMemberToProposalModal.tsx b/apps/frontend/src/components/fap/Proposals/AssignFapMemberToProposalModal.tsx index e37487edb9..e37c5fe3cc 100644 --- a/apps/frontend/src/components/fap/Proposals/AssignFapMemberToProposalModal.tsx +++ b/apps/frontend/src/components/fap/Proposals/AssignFapMemberToProposalModal.tsx @@ -87,6 +87,7 @@ const AssignFapMemberToProposalModal = ({ isLoading={loadingMembers} columns={columns} search + customSearch={false} onUpdate={(members: FapAssignedMember[]) => assignMembersToFapProposals(members) } diff --git a/apps/frontend/src/components/proposal/PeopleSelectorModal.tsx b/apps/frontend/src/components/proposal/PeopleSelectorModal.tsx index 69c7ebb45d..f25b46ea74 100644 --- a/apps/frontend/src/components/proposal/PeopleSelectorModal.tsx +++ b/apps/frontend/src/components/proposal/PeopleSelectorModal.tsx @@ -68,6 +68,7 @@ const PeopleSelectorModal = ({ invitationUserRole: invitationUserRole || userRole, setPrincipalInvestigator: setPrincipalInvestigator, search: true, + customSearch: false, }; const peopleTablesProps = { diff --git a/apps/frontend/src/components/user/PeoplePage.tsx b/apps/frontend/src/components/user/PeoplePage.tsx index 6e050b27e7..7a5f022034 100644 --- a/apps/frontend/src/components/user/PeoplePage.tsx +++ b/apps/frontend/src/components/user/PeoplePage.tsx @@ -32,6 +32,7 @@ export default function PeoplePage() { selection={false} showInvitationButtons search={false} + customSearch={true} onRemove={(user: { id: number }) => api({ toastSuccessMessage: 'User removed successfully!', diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index 23ad31cf0e..c3ec2d0726 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -64,6 +64,7 @@ type PeopleTableProps = { isFreeAction?: boolean; data?: T[]; search?: boolean; + customSearch?: boolean; onRemove?: FunctionType; onUpdate?: FunctionType; emailInvite?: boolean; @@ -151,6 +152,7 @@ const PeopleTable = ({ mtOptions, onRemove, search, + customSearch, title, persistUrlQueryParams = false, }: PeopleTableProps) => { @@ -407,44 +409,47 @@ const PeopleTable = ({ }, }} > - - - + + ({ + marginRight: theme.spacing(1), + alignSelf: 'center', + fontSize: 'large', + color: theme.palette.primary.main, + })} + > + + setSearchName(e.target.value)} sx={(theme) => ({ - marginRight: theme.spacing(1), + flex: 1, alignSelf: 'center', - fontSize: 'large', - color: theme.palette.primary.main, + maxWidth: 260, + marginRight: theme.spacing(3), })} - > - - setSearchName(e.target.value)} - sx={(theme) => ({ - flex: 1, - alignSelf: 'center', - maxWidth: 260, - marginRight: theme.spacing(3), - })} - /> - + /> + + )} + Date: Wed, 10 Jun 2026 13:29:15 +0100 Subject: [PATCH 11/19] Allow use of both searches --- apps/frontend/src/components/user/PeopleTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/user/PeopleTable.tsx b/apps/frontend/src/components/user/PeopleTable.tsx index c3ec2d0726..024a10b27c 100644 --- a/apps/frontend/src/components/user/PeopleTable.tsx +++ b/apps/frontend/src/components/user/PeopleTable.tsx @@ -279,7 +279,7 @@ const PeopleTable = ({ : orderBy?.orderDirection == PaginationSortDirection.DESC ? PaginationSortDirection.DESC : undefined, - searchText: searchParams.get('search'), + searchText: searchParams.get('search') ?? tableQuery.search, }) .then(({ users }) => { const filteredData = data From 0e5af6e368e3d68205f6e58ea58dcda08e512ceb Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Wed, 10 Jun 2026 13:59:05 +0100 Subject: [PATCH 12/19] Fix FAP people table test --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 400ef93993..4dc88ab38b 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -82,8 +82,11 @@ context('General facility access panel tests', () => { variant: 'success', }); cy.contains('People').click(); + cy.get('[data-cy="people-search"]').type(fapMembers.secretary.lastName); + cy.get('[data-cy="people-search"]').type('Enter'); + cy.get('[role="progressbar"]').should('exist'); + cy.get('[role="progressbar"]').should('not.exist'); - searchMuiTableAsync(fapMembers.secretary.lastName); cy.get('[aria-label="Edit user"]').click(); cy.get('[cy-data="user-page"]').contains('Settings').click(); cy.contains('Add role').click(); From b99a2711343ff6da9c5fc5190bfac53c82a1677e Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Thu, 11 Jun 2026 14:49:09 +0100 Subject: [PATCH 13/19] Add FAP search for new people table search bar for e2e --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 4dc88ab38b..04a7a41791 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -66,7 +66,8 @@ context('General facility access panel tests', () => { this.skip(); } cy.contains('People').click(); - searchMuiTableAsync(fapMembers.chair.lastName); + cy.get('[data-cy="people-search"]').type(fapMembers.chair.lastName); + cy.get('[data-cy="people-search"]').type('Enter'); cy.get('[aria-label="Edit user"]').click(); cy.get('[cy-data="user-page"]').contains('Settings').click(); cy.contains('Add role').click(); From c7879d128f612608c487ca04eec3586d00e24512 Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Fri, 12 Jun 2026 14:07:28 +0100 Subject: [PATCH 14/19] Specify user name in fap e2e test --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 04a7a41791..058aff2d86 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -88,7 +88,11 @@ context('General facility access panel tests', () => { cy.get('[role="progressbar"]').should('exist'); cy.get('[role="progressbar"]').should('not.exist'); - cy.get('[aria-label="Edit user"]').click(); + cy.contains(fapMembers.secretary.lastName) + .parent() + .find('button[aria-label="Edit user"]') + .click(); + cy.get('[cy-data="user-page"]').contains('Settings').click(); cy.contains('Add role').click(); From d3b73ee728b115c11b8c9380a05cabc0220ed391 Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Fri, 12 Jun 2026 14:40:05 +0100 Subject: [PATCH 15/19] Change enter buttton press e2e tests --- apps/e2e/cypress/e2e/eventLogs.cy.ts | 2 +- apps/e2e/cypress/e2e/generalFaps.cy.ts | 4 ++-- apps/e2e/cypress/e2e/peopleTable.cy.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/e2e/cypress/e2e/eventLogs.cy.ts b/apps/e2e/cypress/e2e/eventLogs.cy.ts index badb0ded60..bdfaa04085 100644 --- a/apps/e2e/cypress/e2e/eventLogs.cy.ts +++ b/apps/e2e/cypress/e2e/eventLogs.cy.ts @@ -78,7 +78,7 @@ context('Event log tests', () => { cy.finishedLoading(); cy.get('[data-cy="people-search"]').type(user.lastName); - cy.get('[data-cy="people-search"]').type('Enter'); + cy.realPress('Enter'); cy.contains(user.firstName) .parent() diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 058aff2d86..5fda6f3607 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -67,7 +67,7 @@ context('General facility access panel tests', () => { } cy.contains('People').click(); cy.get('[data-cy="people-search"]').type(fapMembers.chair.lastName); - cy.get('[data-cy="people-search"]').type('Enter'); + cy.realPress('Enter'); cy.get('[aria-label="Edit user"]').click(); cy.get('[cy-data="user-page"]').contains('Settings').click(); cy.contains('Add role').click(); @@ -84,7 +84,7 @@ context('General facility access panel tests', () => { }); cy.contains('People').click(); cy.get('[data-cy="people-search"]').type(fapMembers.secretary.lastName); - cy.get('[data-cy="people-search"]').type('Enter'); + cy.realPress('Enter'); cy.get('[role="progressbar"]').should('exist'); cy.get('[role="progressbar"]').should('not.exist'); diff --git a/apps/e2e/cypress/e2e/peopleTable.cy.ts b/apps/e2e/cypress/e2e/peopleTable.cy.ts index aa018a87ec..566d8730e2 100644 --- a/apps/e2e/cypress/e2e/peopleTable.cy.ts +++ b/apps/e2e/cypress/e2e/peopleTable.cy.ts @@ -151,7 +151,7 @@ context('PageTable component tests', () => { cy.get('[data-cy="people-table"]').should('exist'); cy.get('[data-cy="people-search"]').type(user.lastName); - cy.get('[data-cy="people-search"]').type('Enter'); + cy.realPress('Enter'); cy.get('[data-cy="people-table"]').contains(user.firstName); }); }); From fa1518cafde78ba288d137f17a44c8da91f44314 Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Fri, 12 Jun 2026 15:10:42 +0100 Subject: [PATCH 16/19] Remove unecessary test check --- apps/e2e/cypress/e2e/generalFaps.cy.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/e2e/cypress/e2e/generalFaps.cy.ts b/apps/e2e/cypress/e2e/generalFaps.cy.ts index 5fda6f3607..cf32a97674 100644 --- a/apps/e2e/cypress/e2e/generalFaps.cy.ts +++ b/apps/e2e/cypress/e2e/generalFaps.cy.ts @@ -85,9 +85,6 @@ context('General facility access panel tests', () => { cy.contains('People').click(); cy.get('[data-cy="people-search"]').type(fapMembers.secretary.lastName); cy.realPress('Enter'); - cy.get('[role="progressbar"]').should('exist'); - cy.get('[role="progressbar"]').should('not.exist'); - cy.contains(fapMembers.secretary.lastName) .parent() .find('button[aria-label="Edit user"]') From cc63c77a5d99d34354447629319899489a949d73 Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Tue, 23 Jun 2026 13:44:19 +0100 Subject: [PATCH 17/19] Remove test - check for github actions --- apps/e2e/cypress/e2e/peopleTable.cy.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/apps/e2e/cypress/e2e/peopleTable.cy.ts b/apps/e2e/cypress/e2e/peopleTable.cy.ts index 566d8730e2..6311ae79ce 100644 --- a/apps/e2e/cypress/e2e/peopleTable.cy.ts +++ b/apps/e2e/cypress/e2e/peopleTable.cy.ts @@ -140,20 +140,6 @@ context('PageTable component tests', () => { expect(firstTableRowTextAfterSorting).not.equal(element.text()); }); }); - - it('PeopleTable should allow search upon Enter', () => { - const user = initialDBData.users['user1']; - cy.login('officer'); - cy.visit('/People'); - - cy.finishedLoading(); - - cy.get('[data-cy="people-table"]').should('exist'); - - cy.get('[data-cy="people-search"]').type(user.lastName); - cy.realPress('Enter'); - cy.get('[data-cy="people-table"]').contains(user.firstName); - }); }); describe('PeopleTable component allows swapping between PIs and CoIs', () => { From 910effc39fde670acd59c1d9b6ed8d40acce84d6 Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Tue, 23 Jun 2026 14:35:06 +0100 Subject: [PATCH 18/19] Add wait to eventlog test --- apps/e2e/cypress/e2e/eventLogs.cy.ts | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/apps/e2e/cypress/e2e/eventLogs.cy.ts b/apps/e2e/cypress/e2e/eventLogs.cy.ts index bdfaa04085..d190901040 100644 --- a/apps/e2e/cypress/e2e/eventLogs.cy.ts +++ b/apps/e2e/cypress/e2e/eventLogs.cy.ts @@ -70,35 +70,35 @@ context('Event log tests', () => { lastname: 'Doe', institutionId: 1, email: faker.internet.email(), - }); + }).then(() => { + cy.login('officer'); + cy.visit('/People'); - cy.login('officer'); - cy.visit('/People'); - - cy.finishedLoading(); + cy.finishedLoading(); - cy.get('[data-cy="people-search"]').type(user.lastName); - cy.realPress('Enter'); + cy.get('[data-cy="people-search"]').type(user.lastName); + cy.realPress('Enter'); - cy.contains(user.firstName) - .parent() - .find('button[aria-label="Edit user"]') - .click(); + cy.contains(user.firstName) + .parent() + .find('button[aria-label="Edit user"]') + .click(); - cy.get("[name='firstname']").should('have.value', newFirstName); + cy.get("[name='firstname']").should('have.value', newFirstName); - cy.get('[role="tab"]').contains('Logs').click(); + cy.get('[role="tab"]').contains('Logs').click(); - cy.get('[data-cy="event-logs-table"]').as('eventLogsTable'); - cy.get('@eventLogsTable') - .find('tr[level="0"]') - .last() - .as('eventLogsTableLastRow'); + cy.get('[data-cy="event-logs-table"]').as('eventLogsTable'); + cy.get('@eventLogsTable') + .find('tr[level="0"]') + .last() + .as('eventLogsTableLastRow'); - cy.get('@eventLogsTableLastRow').invoke('text').as('lastRowText'); + cy.get('@eventLogsTableLastRow').invoke('text').as('lastRowText'); - cy.get('@lastRowText').should('contain', 'USER_UPDATED'); - cy.get('@lastRowText').should('contain', updateProfileDate); + cy.get('@lastRowText').should('contain', 'USER_UPDATED'); + cy.get('@lastRowText').should('contain', updateProfileDate); + }); }); it('If user impersonates someone, it reflects in the action logs', () => { From d1e3f4e378a0f297020e0cc4e9770bf26bf1655d Mon Sep 17 00:00:00 2001 From: Ellen Wright Date: Tue, 23 Jun 2026 15:11:51 +0100 Subject: [PATCH 19/19] Edit eventlog test to match people table --- apps/e2e/cypress/e2e/eventLogs.cy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/e2e/cypress/e2e/eventLogs.cy.ts b/apps/e2e/cypress/e2e/eventLogs.cy.ts index d190901040..7f91853293 100644 --- a/apps/e2e/cypress/e2e/eventLogs.cy.ts +++ b/apps/e2e/cypress/e2e/eventLogs.cy.ts @@ -67,7 +67,7 @@ context('Event log tests', () => { id: user.id, firstname: newFirstName, userTitle: 'Dr.', - lastname: 'Doe', + lastname: user.lastName, institutionId: 1, email: faker.internet.email(), }).then(() => { @@ -79,7 +79,7 @@ context('Event log tests', () => { cy.get('[data-cy="people-search"]').type(user.lastName); cy.realPress('Enter'); - cy.contains(user.firstName) + cy.contains(user.lastName) .parent() .find('button[aria-label="Edit user"]') .click();