From 3c0e7dfb09babd967a0b03404d312fb2e011173d Mon Sep 17 00:00:00 2001 From: amyjchen Date: Tue, 29 Oct 2024 17:12:02 -0700 Subject: [PATCH 1/4] add TableTopBar and use accross all large tables --- src/components/DateRange.tsx | 6 +- src/components/TableTopBar.tsx | 39 +++ src/pages/apps/List.tsx | 153 +++++------- src/pages/groups/Audit.tsx | 430 ++++++++++++++++----------------- src/pages/groups/Expiring.tsx | 409 +++++++++++++++---------------- src/pages/groups/List.tsx | 162 ++++++------- src/pages/requests/List.tsx | 330 ++++++++++++------------- src/pages/roles/Expiring.tsx | 374 ++++++++++++++-------------- src/pages/roles/List.tsx | 159 +++++------- src/pages/tags/List.tsx | 145 +++++------ src/pages/users/Audit.tsx | 385 ++++++++++++++--------------- src/pages/users/List.tsx | 194 +++++++-------- 12 files changed, 1328 insertions(+), 1458 deletions(-) create mode 100644 src/components/TableTopBar.tsx diff --git a/src/components/DateRange.tsx b/src/components/DateRange.tsx index ec22390..a3e7ca0 100644 --- a/src/components/DateRange.tsx +++ b/src/components/DateRange.tsx @@ -91,9 +91,10 @@ function ButtonField(props: ButtonFieldProps) { return ( - + @@ -125,6 +124,7 @@ function ButtonField(props: ButtonFieldProps) { zIndex: '2', top: '0.01%', left: '1%', + transform: 'translateY(-7px)', }}> Ending Date Range diff --git a/src/components/TableTopBar.tsx b/src/components/TableTopBar.tsx new file mode 100644 index 0000000..8f84411 --- /dev/null +++ b/src/components/TableTopBar.tsx @@ -0,0 +1,39 @@ +import {Launch} from '@mui/icons-material'; +import {IconButton, Link, Stack, Typography} from '@mui/material'; + +import * as React from 'react'; +import {useNavigate} from 'react-router-dom'; + +interface TableTopBarProps { + title: string; + link?: string; + children?: React.ReactNode; +} + +export default function TableTopBar({title, link, children}: TableTopBarProps) { + const navigate = useNavigate(); + return ( + + + + {title} + + {link != null && ( + navigate(link)}> + + + )} + + + {children} + + + ); +} diff --git a/src/pages/apps/List.tsx b/src/pages/apps/List.tsx index 8b6f604..3ac5c3e 100644 --- a/src/pages/apps/List.tsx +++ b/src/pages/apps/List.tsx @@ -24,6 +24,7 @@ import CreateUpdateApp from './CreateUpdate'; import {perPage} from '../../helpers'; import {useGetApps} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; export default function ListApps() { const navigate = useNavigate(); @@ -105,96 +106,76 @@ export default function ListApps() { }; return ( - - - - - + + + + + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
+ + + Name + Description + + + + {rows.map((row) => ( + - - Applications - + + {row.name} + - - - - - - - - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> - + + + {(row.description ?? '').length > 115 + ? row.description?.substring(0, 114) + '...' + : row.description ?? ''} + - - Name - Description - - - - {rows.map((row) => ( - - - - {row.name} - - - - - {(row.description ?? '').length > 115 - ? row.description?.substring(0, 114) + '...' - : row.description ?? ''} - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ))} + {emptyRows > 0 && ( + + - -
-
-
+ )} + + + + + + + + ); } diff --git a/src/pages/groups/Audit.tsx b/src/pages/groups/Audit.tsx index 00b1431..46cc6ec 100644 --- a/src/pages/groups/Audit.tsx +++ b/src/pages/groups/Audit.tsx @@ -34,6 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -192,251 +193,228 @@ export default function AuditGroup() { }; return ( - - - - - - - - {(group.deleted_at ?? null) != null ? ( - - {group.name} - - ) : ( - - {group.name} - - )}{' '} - Group Audit - - + + + + Member + Owner + + + Active + Inactive + + x} + options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => { + setSearchInput(newInputValue?.split(';')[0] ?? ''); + }} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + renderOption={(props, option, state) => { + const [displayName, email] = option.split(';'); + return ( +
  • + + + {displayName} + + {email} + + + +
  • + ); + }} + /> +
    + +
    + + + + + User Name + + + User Email + Member or Owner + Direct or via Role + + + Started + + + Added by + + + Ending + + + Removed by + Access Request + Justification + + + + {rows.map((row) => ( + + Object.values(row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at))) + ? palette.highlight.success.main + : palette.highlight.danger.main, + }}> - - Member - Owner - + {(row.user?.deleted_at ?? null) != null ? ( + + {displayUserName(row.user)} + + ) : ( + + {displayUserName(row.user)} + + )} - - - Active - Inactive - + + {(row.user?.deleted_at ?? null) != null ? ( + + {row.user?.email.toLowerCase()} + + ) : ( + + {row.user?.email.toLowerCase()} + + )} - - x} - options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => { - setSearchInput(newInputValue?.split(';')[0] ?? ''); - }} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} - /> + {row.is_owner ? 'Owner' : 'Member'} + + {row.role_group_mapping == null ? ( + + ) : ( + navigate(`/roles/${row.role_group_mapping?.role_group?.name}`)} + /> + )} -
    - - - User Name - + - User Email - Member or Owner - Direct or via Role - - Started - + {(row.created_actor?.deleted_at ?? null) != null ? ( + + {displayUserName(row.created_actor)} + + ) : ( + + {displayUserName(row.created_actor)} + + )} - Added by - - Ending - + - Removed by - Access Request - Justification - - - - {rows.map((row) => ( - - Object.values(row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at))) - ? palette.highlight.success.main - : palette.highlight.danger.main, - }}> - - {(row.user?.deleted_at ?? null) != null ? ( - - {displayUserName(row.user)} - - ) : ( - - {displayUserName(row.user)} - - )} - - - {(row.user?.deleted_at ?? null) != null ? ( - - {row.user?.email.toLowerCase()} - - ) : ( - - {row.user?.email.toLowerCase()} - - )} - - {row.is_owner ? 'Owner' : 'Member'} - - {row.role_group_mapping == null ? ( - - ) : ( - navigate(`/roles/${row.role_group_mapping?.role_group?.name}`)} - /> - )} - - - - - - {(row.created_actor?.deleted_at ?? null) != null ? ( + + {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( + (row.ended_actor?.deleted_at ?? null) != null ? ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} ) : ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} - )} - - - - - - {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( - (row.ended_actor?.deleted_at ?? null) != null ? ( - - {displayUserName(row.ended_actor)} - - ) : ( - - {displayUserName(row.ended_actor)} - - ) - ) : ( - '' - )} - - - {row.access_request != null ? ( - - ) : null} - - - {row.created_reason ? : null} - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ) + ) : ( + '' + )} + + + {row.access_request != null ? ( + + ) : null} + + + {row.created_reason ? : null} + + + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/groups/Expiring.tsx b/src/pages/groups/Expiring.tsx index 58e665d..464c2c2 100644 --- a/src/pages/groups/Expiring.tsx +++ b/src/pages/groups/Expiring.tsx @@ -34,6 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import {displayUserName, perPage} from '../../helpers'; +import TableTopBar from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -205,229 +206,217 @@ export default function ExpiringGroups() { }; return ( - - - - - + + + canManageGroup(currentUser, row.group))} + ownAccess={userId == '@me' || userId == currentUser.id} + /> + + Active + Inactive + + , + }} + /> + x} + options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => { + setSearchInput(newInputValue?.split(';')[0] ?? ''); + }} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + renderOption={(props, option, state) => { + const [displayName, email] = option.split(';'); + return ( +
  • + + + {displayName} + + {email} + + + +
  • + ); + }} + /> +
    +
    + + + + + User Name + + + User Email + Group Name + Member or Owner + + Started + + Added by + + + Ending + + + + + + {rows.map((row) => ( + + dayjs(row.ended_at).isAfter(dayjs()) && dayjs(row.ended_at).isBefore(dayjs().add(7, 'day')) + ? highlight.warning.main + : dayjs(row.ended_at).isBefore(dayjs()) + ? highlight.danger.main + : null, + }}> - - Expiring Groups - + {(row.user?.deleted_at ?? null) != null ? ( + + {displayUserName(row.user)} + + ) : ( + + {displayUserName(row.user)} + + )} - canManageGroup(currentUser, row.group))} - ownAccess={userId == '@me' || userId == currentUser.id} - /> + {(row.user?.deleted_at ?? null) != null ? ( + + {row.user?.email.toLowerCase()} + + ) : ( + + {row.user?.email.toLowerCase()} + + )} - - Active - Inactive - - - - , - }} - /> - - - x} - options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => { - setSearchInput(newInputValue?.split(';')[0] ?? ''); - }} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} - /> + {(row.group?.deleted_at ?? null) != null ? ( + + {row.group?.name ?? ''} + + ) : ( + + {row.group?.name ?? ''} + + )}
    -
    - + {row.is_owner ? 'Owner' : 'Member'} - - User Name - + - User Email - Group Name - Member or Owner - Started + {(row.created_actor?.deleted_at ?? null) != null ? ( + + {displayUserName(row.created_actor)} + + ) : ( + + {displayUserName(row.created_actor)} + + )} - Added by - - - Ending - + + - - - - {rows.map((row) => ( - - dayjs(row.ended_at).isAfter(dayjs()) && dayjs(row.ended_at).isBefore(dayjs().add(7, 'day')) - ? highlight.warning.main - : dayjs(row.ended_at).isBefore(dayjs()) - ? highlight.danger.main - : null, - }}> - - {(row.user?.deleted_at ?? null) != null ? ( - - {displayUserName(row.user)} - - ) : ( - - {displayUserName(row.user)} - - )} - - - {(row.user?.deleted_at ?? null) != null ? ( - - {row.user?.email.toLowerCase()} - - ) : ( - - {row.user?.email.toLowerCase()} - - )} - - - {(row.group?.deleted_at ?? null) != null ? ( - - {row.group?.name ?? ''} - - ) : ( - - {row.group?.name ?? ''} - - )} + {userId == '@me' || currentUser.id == row.user.id ? ( + + - {row.is_owner ? 'Owner' : 'Member'} - - + ) : ownerId == '@me' || canManageGroup(currentUser, row.group) ? ( + + canManageGroup(currentUser, row.group))} select={row.id} /> - - {(row.created_actor?.deleted_at ?? null) != null ? ( - - {displayUserName(row.created_actor)} - - ) : ( - - {displayUserName(row.created_actor)} - - )} - - - - - {userId == '@me' || currentUser.id == row.user.id ? ( - - - - ) : ownerId == '@me' || canManageGroup(currentUser, row.group) ? ( - - canManageGroup(currentUser, row.group))} select={row.id} /> - - ) : ( - - )} - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ) : ( + + )} + + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/groups/List.tsx b/src/pages/groups/List.tsx index 2c269b8..ae4e869 100644 --- a/src/pages/groups/List.tsx +++ b/src/pages/groups/List.tsx @@ -16,13 +16,13 @@ import TableHead from '@mui/material/TableHead'; import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; import TextField from '@mui/material/TextField'; -import Typography from '@mui/material/Typography'; import {useCurrentUser} from '../../authentication'; import CreateUpdateGroup from './CreateUpdate'; import {displayGroupType, perPage} from '../../helpers'; import {useGetGroups} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; export default function ListGroups() { const navigate = useNavigate(); @@ -104,102 +104,82 @@ export default function ListGroups() { }; return ( - - - - - + + + + + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
    + + + Name + Type + Description + + + + {rows.map((row) => ( + - - Groups - + + {row.name} + - + + {displayGroupType(row)} + - - + + + {(row.description?.length ?? 0) > 115 + ? row.description?.substring(0, 114) + '...' ?? '' + : row.description} + - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> - - - - Name - Type - Description - - - {rows.map((row) => ( - - - - {row.name} - - - - - {displayGroupType(row)} - - - - - {(row.description?.length ?? 0) > 115 - ? row.description?.substring(0, 114) + '...' ?? '' - : row.description} - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/requests/List.tsx b/src/pages/requests/List.tsx index e3cddc5..cf5e7c5 100644 --- a/src/pages/requests/List.tsx +++ b/src/pages/requests/List.tsx @@ -27,6 +27,7 @@ import CreateRequest from './Create'; import {useGetRequests} from '../../api/apiComponents'; import {displayUserName, perPage} from '../../helpers'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; dayjs.extend(RelativeTime); @@ -124,189 +125,174 @@ export default function ListRequests() { }; return ( - - - - - + + + + x} + options={searchRows.map( + (row) => + row.id + + ';' + + displayUserName(row.requester) + + ';' + + row.request_ownership + + ';' + + (row.requested_group?.name ?? '') + + ';' + + (row.status ?? '') + + ';' + + displayUserName(row.resolver), + )} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => { + setSearchInput(newInputValue?.split(';')[0] ?? ''); + }} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + renderOption={(props, option, state) => { + const [id, displayName, ownership, group, status, resolver] = option.split(';'); + return ( +
  • + + + + {displayName} {ownership == 'true' ? 'ownership of' : 'membership to'} {group} + + + {status} {status == 'PENDING' || resolver == '' ? '' : 'by ' + resolver} + + + +
  • + ); + }} + /> +
    +
    + + + Requester + Request + Resolver + Status + Created + + + + {rows.map((row) => ( + + row.status == 'APPROVED' + ? highlight.success.main + : row.status == 'REJECTED' + ? highlight.danger.main + : 'inherit', + }}> - - Access Requests - + {(row.requester?.deleted_at ?? null) != null ? ( + + {displayUserName(row.requester)} + + ) : ( + + {displayUserName(row.requester)} + + )} - - - - x} - options={searchRows.map( - (row) => - row.id + - ';' + - displayUserName(row.requester) + - ';' + - row.request_ownership + - ';' + - (row.requested_group?.name ?? '') + - ';' + - (row.status ?? '') + - ';' + - displayUserName(row.resolver), - )} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => { - setSearchInput(newInputValue?.split(';')[0] ?? ''); - }} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - renderOption={(props, option, state) => { - const [id, displayName, ownership, group, status, resolver] = option.split(';'); - return ( -
  • - - - - {displayName} {ownership == 'true' ? 'ownership of' : 'membership to'} {group} - - - {status} {status == 'PENDING' || resolver == '' ? '' : 'by ' + resolver} - - - -
  • - ); - }} - /> -
    -
    - - Requester - Request - Resolver - Status - Created - - - - {rows.map((row) => ( - - row.status == 'APPROVED' - ? highlight.success.main - : row.status == 'REJECTED' - ? highlight.danger.main - : 'inherit', - }}> - - {(row.requester?.deleted_at ?? null) != null ? ( - - {displayUserName(row.requester)} - - ) : ( - - {displayUserName(row.requester)} - - )} - - - {row.request_ownership ? 'Ownership of ' : 'Membership to '} - {(row.requested_group?.deleted_at ?? null) != null ? ( - - {row.requested_group?.name ?? ''} - - ) : ( - - {row.requested_group?.name ?? ''} - - )} - - - {row.resolver == null && row.status != 'PENDING' ? ( - 'Access' - ) : (row.resolver?.deleted_at ?? null) != null ? ( - - {displayUserName(row.resolver)} - - ) : ( - - {displayUserName(row.resolver)} - - )} - - + {row.request_ownership ? 'Ownership of ' : 'Membership to '} + {(row.requested_group?.deleted_at ?? null) != null ? ( + + {row.requested_group?.name ?? ''} + + ) : ( - {row.status} + {row.requested_group?.name ?? ''} - - + )} + + + {row.resolver == null && row.status != 'PENDING' ? ( + 'Access' + ) : (row.resolver?.deleted_at ?? null) != null ? ( + {displayUserName(row.resolver)} + + ) : ( + - {dayjs(row.created_at).startOf('second').fromNow()} + {displayUserName(row.resolver)} - - - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + )} + + + + {row.status} + + + + + {dayjs(row.created_at).startOf('second').fromNow()} + + + + + + + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/roles/Expiring.tsx b/src/pages/roles/Expiring.tsx index 1acbb5b..0c773be 100644 --- a/src/pages/roles/Expiring.tsx +++ b/src/pages/roles/Expiring.tsx @@ -32,6 +32,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import {displayUserName, perPage} from '../../helpers'; +import TableTopBar from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -209,211 +210,198 @@ export default function ExpiringRoless() { }; return ( - - - - - + + + canManageGroup(currentUser, row.group))} /> + + Active + Inactive + + {ownerId ? ( + + + + Default Owner + + + + + All Owned + + + + ) : null} + , + }} + /> + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
    + + + Role Name + + + Group Name + + + Group Type + Member or Owner + + Started + + Added by + + + Ending + + + + + + {rows.map((row) => ( + + dayjs(row.ended_at).isAfter(dayjs()) && dayjs(row.ended_at).isBefore(dayjs().add(7, 'day')) + ? highlight.warning.main + : dayjs(row.ended_at).isBefore(dayjs()) + ? highlight.danger.main + : null, + }}> - - Expiring Roles - + {(row.group?.deleted_at ?? null) != null ? ( + + {row.role_group?.name ?? ''} + + ) : ( + + {row.role_group?.name ?? ''} + + )} - canManageGroup(currentUser, row.group))} /> + {(row.group?.deleted_at ?? null) != null ? ( + + {row.group?.name ?? ''} + + ) : ( + + {row.group?.name ?? ''} + + )} - - Active - Inactive - - - {ownerId ? ( - - - - - Default Owner - - - - - All Owned - - - - - ) : null} - - , - }} - /> - - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> + {row.group?.type == 'okta_group' ? 'Group' : 'app_group' ? 'App Group' : 'Role Group'} - - - Role Name + {row.is_owner ? 'Owner' : 'Member'} - - Group Name - + - Group Type - Member or Owner - Started + {(row.created_actor?.deleted_at ?? null) != null ? ( + + {displayUserName(row.created_actor)} + + ) : ( + + {displayUserName(row.created_actor)} + + )} - Added by - - - Ending - + + - - - - {rows.map((row) => ( - - dayjs(row.ended_at).isAfter(dayjs()) && dayjs(row.ended_at).isBefore(dayjs().add(7, 'day')) - ? highlight.warning.main - : dayjs(row.ended_at).isBefore(dayjs()) - ? highlight.danger.main - : null, - }}> - - {(row.group?.deleted_at ?? null) != null ? ( - - {row.role_group?.name ?? ''} - - ) : ( - - {row.role_group?.name ?? ''} - - )} - - - {(row.group?.deleted_at ?? null) != null ? ( - - {row.group?.name ?? ''} - - ) : ( - - {row.group?.name ?? ''} - - )} - - - {row.group?.type == 'okta_group' ? 'Group' : 'app_group' ? 'App Group' : 'Role Group'} - - {row.is_owner ? 'Owner' : 'Member'} - - + {ownerId == '@me' || canManageGroup(currentUser, row.group) ? ( + + canManageGroup(currentUser, row.group))} select={row.id} /> - - {(row.created_actor?.deleted_at ?? null) != null ? ( - - {displayUserName(row.created_actor)} - - ) : ( - - {displayUserName(row.created_actor)} - - )} - - - - - {ownerId == '@me' || canManageGroup(currentUser, row.group) ? ( - - canManageGroup(currentUser, row.group))} select={row.id} /> - - ) : ( - - )} - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ) : ( + + )} + + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/roles/List.tsx b/src/pages/roles/List.tsx index 8fbbbb5..4c955fb 100644 --- a/src/pages/roles/List.tsx +++ b/src/pages/roles/List.tsx @@ -24,6 +24,7 @@ import CreateUpdateGroup from '../groups/CreateUpdate'; import {perPage} from '../../helpers'; import {useGetRoles} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; export default function ListRoles() { const navigate = useNavigate(); @@ -105,102 +106,76 @@ export default function ListRoles() { }; return ( - - - - - + + + + + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
    + + + Name + Description + + + + {rows.map((row) => ( + - - Roles - + + {row.name} + - - - - - - - - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> - + + + {(row.description?.length ?? 0) > 115 + ? row.description?.substring(0, 114) + '...' ?? '' + : row.description} + - - Name - Description - - - - {rows.map((row) => ( - - - - {row.name} - - - - - {(row.description?.length ?? 0) > 115 - ? row.description?.substring(0, 114) + '...' ?? '' - : row.description} - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/tags/List.tsx b/src/pages/tags/List.tsx index 97a2577..d364ff5 100644 --- a/src/pages/tags/List.tsx +++ b/src/pages/tags/List.tsx @@ -22,6 +22,7 @@ import CreateUpdateTag from './CreateUpdate'; import {perPage} from '../../helpers'; import {useGetTags} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; export default function ListTags() { const navigate = useNavigate(); @@ -103,91 +104,73 @@ export default function ListTags() { }; return ( - - - - - + + + + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
    + + + Name + Description + + + + {rows.map((row) => ( + - - Tags - + + {row.name} + - - - - - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> - + + + {(row.description ?? '').length > 115 + ? row.description?.substring(0, 114) + '...' + : row.description ?? ''} + - - Name - Description - - - - {rows.map((row) => ( - - - - {row.name} - - - - - {(row.description ?? '').length > 115 - ? row.description?.substring(0, 114) + '...' - : row.description ?? ''} - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/users/Audit.tsx b/src/pages/users/Audit.tsx index f3339e0..039167c 100644 --- a/src/pages/users/Audit.tsx +++ b/src/pages/users/Audit.tsx @@ -32,6 +32,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -189,229 +190,205 @@ export default function AuditUser() { }; return ( - - - - - - - - {(user.deleted_at ?? null) != null ? ( - - {displayUserName(user)} - - ) : ( - - {displayUserName(user)} - - )}{' '} - Audit - - + + + + Member + Owner + + + Active + Inactive + + x} + options={searchRows.map((row) => row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + /> + +
    + + + + + Group Name + + + Group Type + Member or Owner + Direct or via Role + + + Started + + + Added by + + + Ending + + + Removed by + Access Request + Justification + + + + {rows.map((row) => ( + + row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at)) + ? highlight.success.main + : highlight.danger.main, + }}> - - Member - Owner - + {(row.group?.deleted_at ?? null) != null ? ( + + {row.group?.name ?? ''} + + ) : ( + + {row.group?.name ?? ''} + + )} - - - Active - Inactive - + + {(row.group?.deleted_at ?? null) != null ? ( + displayGroupType(row.group) + ) : ( + + {displayGroupType(row.group)} + + )} - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> + {row.is_owner ? 'Owner' : 'Member'} + + {row.role_group_mapping == null ? ( + + ) : ( + navigate(`/roles/${row.role_group_mapping?.role_group?.name}`)} + /> + )} - - - - Group Name - + - Group Type - Member or Owner - Direct or via Role - - Started - + {(row.created_actor?.deleted_at ?? null) != null ? ( + + {displayUserName(row.created_actor)} + + ) : ( + + {displayUserName(row.created_actor)} + + )} - Added by - - Ending - + - Removed by - Access Request - Justification - - - - {rows.map((row) => ( - - row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at)) - ? highlight.success.main - : highlight.danger.main, - }}> - - {(row.group?.deleted_at ?? null) != null ? ( - - {row.group?.name ?? ''} - - ) : ( - - {row.group?.name ?? ''} - - )} - - - {(row.group?.deleted_at ?? null) != null ? ( - displayGroupType(row.group) - ) : ( - - {displayGroupType(row.group)} - - )} - - {row.is_owner ? 'Owner' : 'Member'} - - {row.role_group_mapping == null ? ( - - ) : ( - navigate(`/roles/${row.role_group_mapping?.role_group?.name}`)} - /> - )} - - - - - - {(row.created_actor?.deleted_at ?? null) != null ? ( + + {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( + (row.ended_actor?.deleted_at ?? null) != null ? ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} ) : ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} - )} - - - - - - {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( - (row.ended_actor?.deleted_at ?? null) != null ? ( - - {displayUserName(row.ended_actor)} - - ) : ( - - {displayUserName(row.ended_actor)} - - ) - ) : ( - '' - )} - - - {row.access_request != null ? ( - - ) : null} - - - {row.created_reason ? : null} - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ) + ) : ( + '' + )} + + + {row.access_request != null ? ( + + ) : null} + + + {row.created_reason ? : null} + + + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } diff --git a/src/pages/users/List.tsx b/src/pages/users/List.tsx index fb13120..e54ef13 100644 --- a/src/pages/users/List.tsx +++ b/src/pages/users/List.tsx @@ -22,6 +22,8 @@ import {useGetUsers} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import UserAvatar from './UserAvatar'; import {displayUserName, perPage} from '../../helpers'; +import {Stack} from '@mui/material'; +import TableTopBar from '../../components/TableTopBar'; export default function ListUsers() { const navigate = useNavigate(); @@ -102,110 +104,102 @@ export default function ListUsers() { }; return ( - - - - - + + + x} + options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} + onInputChange={(event, newInputValue) => { + setSearchInput(newInputValue?.split(';')[0] ?? ''); + }} + onChange={handleSearchSubmit} + defaultValue={searchQuery} + key={searchQuery} + renderInput={(params) => } + renderOption={(props, option, state) => { + const [displayName, email] = option.split(';'); + return ( +
  • + + + {displayName} + + {email} + + + +
  • + ); + }} + /> +
    +
    + + + + Name + Email + + + + {rows.map((row) => ( + - - Users - + + + - - - x} - options={searchRows.map((row) => displayUserName(row) + ';' + row.email.toLowerCase())} - onInputChange={(event, newInputValue) => { - setSearchInput(newInputValue?.split(';')[0] ?? ''); - }} - onChange={handleSearchSubmit} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} - /> + + + {displayUserName(row)} + + + + + {row.email.toLowerCase()} +
    - - - Name - Email - - - - {rows.map((row) => ( - - - - - - - - - {displayUserName(row)} - - - - - {row.email.toLowerCase()} - - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ))} + {emptyRows > 0 && ( + + - -
    -
    -
    + )} + + + + + + + + ); } From 187d1823352d7881bc306c05e22ccadc3fdc4dbb Mon Sep 17 00:00:00 2001 From: amyjchen Date: Wed, 30 Oct 2024 11:45:07 -0700 Subject: [PATCH 2/4] custom autocomplete component --- src/components/TableTopBar.tsx | 24 ++- src/pages/apps/List.tsx | 10 +- src/pages/groups/Audit.tsx | 13 +- src/pages/groups/Expiring.tsx | 12 +- src/pages/groups/List.tsx | 10 +- src/pages/requests/List.tsx | 10 +- src/pages/roles/Audit.tsx | 329 +++++++++++++++------------------ src/pages/roles/Expiring.tsx | 10 +- src/pages/roles/List.tsx | 10 +- src/pages/tags/List.tsx | 10 +- src/pages/users/Audit.tsx | 10 +- src/pages/users/List.tsx | 11 +- 12 files changed, 194 insertions(+), 265 deletions(-) diff --git a/src/components/TableTopBar.tsx b/src/components/TableTopBar.tsx index 8f84411..548f045 100644 --- a/src/components/TableTopBar.tsx +++ b/src/components/TableTopBar.tsx @@ -1,9 +1,28 @@ import {Launch} from '@mui/icons-material'; -import {IconButton, Link, Stack, Typography} from '@mui/material'; +import {Autocomplete, AutocompleteProps, IconButton, Stack, TextField, Typography} from '@mui/material'; import * as React from 'react'; import {useNavigate} from 'react-router-dom'; +export function TableTopBarAutocomplete({ + defaultValue, + filterOptions = (x) => x, + ...restProps +}: Omit, 'renderInput'>) { + return ( + } + {...restProps} + /> + ); +} + interface TableTopBarProps { title: string; link?: string; @@ -20,6 +39,7 @@ export default function TableTopBar({title, link, children}: TableTopBarProps) { paddingX={2} gap={4} justifyContent="space-between" + flexWrap="wrap" alignItems="flex-end"> @@ -31,7 +51,7 @@ export default function TableTopBar({title, link, children}: TableTopBarProps) { )} - + {children} diff --git a/src/pages/apps/List.tsx b/src/pages/apps/List.tsx index 3ac5c3e..6e92f2d 100644 --- a/src/pages/apps/List.tsx +++ b/src/pages/apps/List.tsx @@ -24,7 +24,7 @@ import CreateUpdateApp from './CreateUpdate'; import {perPage} from '../../helpers'; import {useGetApps} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListApps() { const navigate = useNavigate(); @@ -112,17 +112,11 @@ export default function ListApps() { Tags - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } /> diff --git a/src/pages/groups/Audit.tsx b/src/pages/groups/Audit.tsx index 46cc6ec..39b1b73 100644 --- a/src/pages/groups/Audit.tsx +++ b/src/pages/groups/Audit.tsx @@ -34,7 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -205,23 +205,17 @@ export default function AuditGroup() { ActiveInactive - x} + displayUserName(row) + ';' + row.email.toLowerCase())} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => { setSearchInput(newInputValue?.split(';')[0] ?? ''); }} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } renderOption={(props, option, state) => { const [displayName, email] = option.split(';'); return ( -
  • +
  • {displayName} @@ -235,7 +229,6 @@ export default function AuditGroup() { }} /> -
  • diff --git a/src/pages/groups/Expiring.tsx b/src/pages/groups/Expiring.tsx index 464c2c2..35fcee2 100644 --- a/src/pages/groups/Expiring.tsx +++ b/src/pages/groups/Expiring.tsx @@ -34,7 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import {displayUserName, perPage} from '../../helpers'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -232,23 +232,17 @@ export default function ExpiringGroups() { textField: (textFieldProps) => , }} /> - x} + displayUserName(row) + ';' + row.email.toLowerCase())} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => { setSearchInput(newInputValue?.split(';')[0] ?? ''); }} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } renderOption={(props, option, state) => { const [displayName, email] = option.split(';'); return ( -
  • +
  • {displayName} diff --git a/src/pages/groups/List.tsx b/src/pages/groups/List.tsx index ae4e869..131937e 100644 --- a/src/pages/groups/List.tsx +++ b/src/pages/groups/List.tsx @@ -22,7 +22,7 @@ import CreateUpdateGroup from './CreateUpdate'; import {displayGroupType, perPage} from '../../helpers'; import {useGetGroups} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListGroups() { const navigate = useNavigate(); @@ -110,17 +110,11 @@ export default function ListGroups() { Tags - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } />
  • diff --git a/src/pages/requests/List.tsx b/src/pages/requests/List.tsx index cf5e7c5..153fedc 100644 --- a/src/pages/requests/List.tsx +++ b/src/pages/requests/List.tsx @@ -27,7 +27,7 @@ import CreateRequest from './Create'; import {useGetRequests} from '../../api/apiComponents'; import {displayUserName, perPage} from '../../helpers'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; dayjs.extend(RelativeTime); @@ -128,11 +128,7 @@ export default function ListRequests() { - x} + row.id + @@ -152,8 +148,6 @@ export default function ListRequests() { setSearchInput(newInputValue?.split(';')[0] ?? ''); }} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } renderOption={(props, option, state) => { const [id, displayName, ownership, group, status, resolver] = option.split(';'); return ( diff --git a/src/pages/roles/Audit.tsx b/src/pages/roles/Audit.tsx index ab11885..c832f37 100644 --- a/src/pages/roles/Audit.tsx +++ b/src/pages/roles/Audit.tsx @@ -31,6 +31,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -187,205 +188,173 @@ export default function AuditRole() { }; return ( - - -
    - - + + + + Active + Inactive + + + Member + Owner + + row.name)} + onChange={handleSearchSubmit} + onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} + defaultValue={searchQuery} + /> + +
    + + + + + Group Name + + + Group Type + Member or Owner + + + Started + + + Added by + + + Ending + + + Removed by + Justification + + + + {rows.map((row) => ( + + row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at)) + ? highlight.success.main + : highlight.danger.main, + }}> - - {(role.deleted_at ?? null) != null ? ( - - {role.name} - - ) : ( - - {role.name} - - )}{' '} - Role Audit - + {(row.group?.deleted_at ?? null) != null ? ( + + {row.group?.name ?? ''} + + ) : ( + + {row.group?.name ?? ''} + + )} - - Active - Inactive - - - - - Member - Owner - + {(row.group?.deleted_at ?? null) != null ? ( + displayGroupType(row.group) + ) : ( + + {displayGroupType(row.group)} + + )} - - x} - options={searchRows.map((row) => row.name)} - onChange={handleSearchSubmit} - onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} - defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } - /> - - - + {row.is_owner ? 'Owner' : 'Member'} - - Group Name - + - Group Type - Member or Owner - - Started - + {(row.created_actor?.deleted_at ?? null) != null ? ( + + {displayUserName(row.created_actor)} + + ) : ( + + {displayUserName(row.created_actor)} + + )} - Added by - - Ending - + - Removed by - Justification - - - - {rows.map((row) => ( - - row.ended_at == null || dayjs().isBefore(dayjs(row.ended_at)) - ? highlight.success.main - : highlight.danger.main, - }}> - - {(row.group?.deleted_at ?? null) != null ? ( - - {row.group?.name ?? ''} - - ) : ( - - {row.group?.name ?? ''} - - )} - - - {(row.group?.deleted_at ?? null) != null ? ( - displayGroupType(row.group) - ) : ( - - {displayGroupType(row.group)} - - )} - - {row.is_owner ? 'Owner' : 'Member'} - - - - - {(row.created_actor?.deleted_at ?? null) != null ? ( + + {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( + (row.ended_actor?.deleted_at ?? null) != null ? ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} ) : ( - {displayUserName(row.created_actor)} + {displayUserName(row.ended_actor)} - )} - - - - - - {row.ended_at != null && dayjs().isAfter(dayjs(row.ended_at)) ? ( - (row.ended_actor?.deleted_at ?? null) != null ? ( - - {displayUserName(row.ended_actor)} - - ) : ( - - {displayUserName(row.ended_actor)} - - ) - ) : ( - '' - )} - - - {row.created_reason ? : null} - - - ))} - {emptyRows > 0 && ( - - - - )} - - - - + ) + ) : ( + '' + )} + + {row.created_reason ? : null} + + ))} + {emptyRows > 0 && ( + + - -
    - - + )} + + + + + + + + ); } diff --git a/src/pages/roles/Expiring.tsx b/src/pages/roles/Expiring.tsx index 0c773be..0005a61 100644 --- a/src/pages/roles/Expiring.tsx +++ b/src/pages/roles/Expiring.tsx @@ -32,7 +32,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import {displayUserName, perPage} from '../../helpers'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -252,17 +252,11 @@ export default function ExpiringRoless() { textField: (textFieldProps) => , }} /> - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } /> diff --git a/src/pages/roles/List.tsx b/src/pages/roles/List.tsx index 4c955fb..37607a9 100644 --- a/src/pages/roles/List.tsx +++ b/src/pages/roles/List.tsx @@ -24,7 +24,7 @@ import CreateUpdateGroup from '../groups/CreateUpdate'; import {perPage} from '../../helpers'; import {useGetRoles} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListRoles() { const navigate = useNavigate(); @@ -112,17 +112,11 @@ export default function ListRoles() { Tags - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } />
    diff --git a/src/pages/tags/List.tsx b/src/pages/tags/List.tsx index d364ff5..4e9db00 100644 --- a/src/pages/tags/List.tsx +++ b/src/pages/tags/List.tsx @@ -22,7 +22,7 @@ import CreateUpdateTag from './CreateUpdate'; import {perPage} from '../../helpers'; import {useGetTags} from '../../api/apiComponents'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListTags() { const navigate = useNavigate(); @@ -107,17 +107,11 @@ export default function ListTags() { - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } />
    diff --git a/src/pages/users/Audit.tsx b/src/pages/users/Audit.tsx index 039167c..595fdca 100644 --- a/src/pages/users/Audit.tsx +++ b/src/pages/users/Audit.tsx @@ -32,7 +32,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -202,17 +202,11 @@ export default function AuditUser() { ActiveInactive - x} + row.name)} onChange={handleSearchSubmit} onInputChange={(event, newInputValue) => setSearchInput(newInputValue)} defaultValue={searchQuery} - key={searchQuery} - renderInput={(params) => } />
    diff --git a/src/pages/users/List.tsx b/src/pages/users/List.tsx index e54ef13..0493eb3 100644 --- a/src/pages/users/List.tsx +++ b/src/pages/users/List.tsx @@ -23,7 +23,7 @@ import TablePaginationActions from '../../components/actions/TablePaginationActi import UserAvatar from './UserAvatar'; import {displayUserName, perPage} from '../../helpers'; import {Stack} from '@mui/material'; -import TableTopBar from '../../components/TableTopBar'; +import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListUsers() { const navigate = useNavigate(); @@ -106,11 +106,7 @@ export default function ListUsers() { return ( - x} + displayUserName(row) + ';' + row.email.toLowerCase())} onInputChange={(event, newInputValue) => { setSearchInput(newInputValue?.split(';')[0] ?? ''); @@ -118,11 +114,10 @@ export default function ListUsers() { onChange={handleSearchSubmit} defaultValue={searchQuery} key={searchQuery} - renderInput={(params) => } renderOption={(props, option, state) => { const [displayName, email] = option.split(';'); return ( -
  • +
  • {displayName} From cd471497b85c51bb69589bd01dc6f9be6b56bf77 Mon Sep 17 00:00:00 2001 From: amyjchen Date: Wed, 30 Oct 2024 11:49:37 -0700 Subject: [PATCH 3/4] reusable renderUserOption --- src/components/TableTopBar.tsx | 18 +++++++++++++++++- src/pages/groups/Audit.tsx | 18 ++---------------- src/pages/groups/Expiring.tsx | 18 ++---------------- src/pages/users/List.tsx | 18 ++---------------- 4 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/components/TableTopBar.tsx b/src/components/TableTopBar.tsx index 548f045..1532201 100644 --- a/src/components/TableTopBar.tsx +++ b/src/components/TableTopBar.tsx @@ -1,9 +1,25 @@ import {Launch} from '@mui/icons-material'; -import {Autocomplete, AutocompleteProps, IconButton, Stack, TextField, Typography} from '@mui/material'; +import {Autocomplete, AutocompleteProps, Box, Grid, IconButton, Stack, TextField, Typography} from '@mui/material'; import * as React from 'react'; import {useNavigate} from 'react-router-dom'; +export function renderUserOption(props: React.HTMLAttributes, option: any) { + const [displayName, email] = option.split(';'); + return ( +
  • + + + {displayName} + + {email} + + + +
  • + ); +} + export function TableTopBarAutocomplete({ defaultValue, filterOptions = (x) => x, diff --git a/src/pages/groups/Audit.tsx b/src/pages/groups/Audit.tsx index 39b1b73..4e4369d 100644 --- a/src/pages/groups/Audit.tsx +++ b/src/pages/groups/Audit.tsx @@ -34,7 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import Ending from '../../components/Ending'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; -import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; +import TableTopBar, {renderUserOption, TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'created_at' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -212,21 +212,7 @@ export default function AuditGroup() { setSearchInput(newInputValue?.split(';')[0] ?? ''); }} defaultValue={searchQuery} - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} + renderOption={renderUserOption} />
    diff --git a/src/pages/groups/Expiring.tsx b/src/pages/groups/Expiring.tsx index 35fcee2..3e97b9c 100644 --- a/src/pages/groups/Expiring.tsx +++ b/src/pages/groups/Expiring.tsx @@ -34,7 +34,7 @@ import Loading from '../../components/Loading'; import Started from '../../components/Started'; import TablePaginationActions from '../../components/actions/TablePaginationActions'; import {displayUserName, perPage} from '../../helpers'; -import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; +import TableTopBar, {renderUserOption, TableTopBarAutocomplete} from '../../components/TableTopBar'; type OrderBy = 'moniker' | 'ended_at'; type OrderDirection = 'asc' | 'desc'; @@ -239,21 +239,7 @@ export default function ExpiringGroups() { setSearchInput(newInputValue?.split(';')[0] ?? ''); }} defaultValue={searchQuery} - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} + renderOption={renderUserOption} />
    diff --git a/src/pages/users/List.tsx b/src/pages/users/List.tsx index 0493eb3..20a04c3 100644 --- a/src/pages/users/List.tsx +++ b/src/pages/users/List.tsx @@ -23,7 +23,7 @@ import TablePaginationActions from '../../components/actions/TablePaginationActi import UserAvatar from './UserAvatar'; import {displayUserName, perPage} from '../../helpers'; import {Stack} from '@mui/material'; -import TableTopBar, {TableTopBarAutocomplete} from '../../components/TableTopBar'; +import TableTopBar, {renderUserOption, TableTopBarAutocomplete} from '../../components/TableTopBar'; export default function ListUsers() { const navigate = useNavigate(); @@ -114,21 +114,7 @@ export default function ListUsers() { onChange={handleSearchSubmit} defaultValue={searchQuery} key={searchQuery} - renderOption={(props, option, state) => { - const [displayName, email] = option.split(';'); - return ( -
  • - - - {displayName} - - {email} - - - -
  • - ); - }} + renderOption={renderUserOption} />
    From acdac320ac95b3522a659c5203bfcaca5d2a33dd Mon Sep 17 00:00:00 2001 From: amyjchen Date: Wed, 30 Oct 2024 12:55:28 -0700 Subject: [PATCH 4/4] remove unnecessary div on datepicker --- src/components/DateRange.tsx | 38 +++++++++++++++++------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/components/DateRange.tsx b/src/components/DateRange.tsx index a3e7ca0..c0a76f5 100644 --- a/src/components/DateRange.tsx +++ b/src/components/DateRange.tsx @@ -91,26 +91,24 @@ function ButtonField(props: ButtonFieldProps) { return ( - - - +