1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

fix: improve users search (#4131)

https://linear.app/unleash/issue/2-1183/improve-users-list-search

This adapts the users list to use the new `useSearch` hook so you can
have a better search that also includes "username" and "email" as
fields. It's also more extensible in case we'd like to add filters in
the future.
This commit is contained in:
Nuno Góis 2023-07-04 08:30:40 +01:00 committed by GitHub
parent 6a3965f57a
commit 95a02158e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,12 +16,7 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { Button, useMediaQuery } from '@mui/material'; import { Button, useMediaQuery } from '@mui/material';
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
import { UserTypeCell } from './UserTypeCell/UserTypeCell'; import { UserTypeCell } from './UserTypeCell/UserTypeCell';
import { import { useFlexLayout, useSortBy, useTable } from 'react-table';
useFlexLayout,
useGlobalFilter,
useSortBy,
useTable,
} from 'react-table';
import { sortTypes } from 'utils/sortTypes'; import { sortTypes } from 'utils/sortTypes';
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell'; import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
@ -35,6 +30,7 @@ import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
import { UserLimitWarning } from './UserLimitWarning/UserLimitWarning'; import { UserLimitWarning } from './UserLimitWarning/UserLimitWarning';
import { RoleCell } from 'component/common/Table/cells/RoleCell/RoleCell'; import { RoleCell } from 'component/common/Table/cells/RoleCell/RoleCell';
import { useSearch } from 'hooks/useSearch';
const UsersList = () => { const UsersList = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -51,6 +47,8 @@ const UsersList = () => {
const [delUser, setDelUser] = useState<IUser>(); const [delUser, setDelUser] = useState<IUser>();
const { planUsers, isBillingUsers } = useUsersPlan(users); const { planUsers, isBillingUsers } = useUsersPlan(users);
const [searchValue, setSearchValue] = useState('');
const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md')); const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
@ -105,7 +103,6 @@ const UsersList = () => {
<UserAvatar user={user} /> <UserAvatar user={user} />
</TextCell> </TextCell>
), ),
disableGlobalFilter: true,
disableSortBy: true, disableSortBy: true,
maxWidth: 80, maxWidth: 80,
}, },
@ -120,6 +117,7 @@ const UsersList = () => {
subtitle={user.email || user.username} subtitle={user.email || user.username}
/> />
), ),
searchable: true,
}, },
{ {
id: 'role', id: 'role',
@ -130,14 +128,12 @@ const UsersList = () => {
Cell: ({ row: { original: user }, value }: any) => ( Cell: ({ row: { original: user }, value }: any) => (
<RoleCell value={value} roleId={user.rootRole} /> <RoleCell value={value} roleId={user.rootRole} />
), ),
disableGlobalFilter: true,
maxWidth: 120, maxWidth: 120,
}, },
{ {
Header: 'Created', Header: 'Created',
accessor: 'createdAt', accessor: 'createdAt',
Cell: DateCell, Cell: DateCell,
disableGlobalFilter: true,
sortType: 'date', sortType: 'date',
width: 120, width: 120,
maxWidth: 120, maxWidth: 120,
@ -153,7 +149,6 @@ const UsersList = () => {
title={date => `Last login: ${date}`} title={date => `Last login: ${date}`}
/> />
), ),
disableGlobalFilter: true,
sortType: 'date', sortType: 'date',
maxWidth: 150, maxWidth: 150,
}, },
@ -165,7 +160,6 @@ const UsersList = () => {
Cell: ({ row: { original: user } }: any) => ( Cell: ({ row: { original: user } }: any) => (
<UserTypeCell value={isBillingUsers && user.paid} /> <UserTypeCell value={isBillingUsers && user.paid} />
), ),
disableGlobalFilter: true,
sortType: 'boolean', sortType: 'boolean',
}, },
{ {
@ -182,9 +176,20 @@ const UsersList = () => {
/> />
), ),
width: 150, width: 150,
disableGlobalFilter: true,
disableSortBy: true, disableSortBy: true,
}, },
// Always hidden -- for search
{
accessor: 'username',
Header: 'Username',
searchable: true,
},
// Always hidden -- for search
{
accessor: 'email',
Header: 'Email',
searchable: true,
},
], ],
[roles, navigate, isBillingUsers] [roles, navigate, isBillingUsers]
); );
@ -196,30 +201,26 @@ const UsersList = () => {
}; };
}, [isBillingUsers]); }, [isBillingUsers]);
const data = isBillingUsers ? planUsers : users; const { data, getSearchText } = useSearch(
columns,
searchValue,
isBillingUsers ? planUsers : users
);
const { const { headerGroups, rows, prepareRow, setHiddenColumns } = useTable(
headerGroups,
rows,
prepareRow,
state: { globalFilter },
setGlobalFilter,
setHiddenColumns,
} = useTable(
{ {
columns: columns as any, columns: columns as any,
data, data,
initialState, initialState,
sortTypes, sortTypes,
autoResetGlobalFilter: false,
autoResetHiddenColumns: false, autoResetHiddenColumns: false,
autoResetSortBy: false, autoResetSortBy: false,
disableSortRemove: true, disableSortRemove: true,
disableMultiSort: true,
defaultColumn: { defaultColumn: {
Cell: TextCell, Cell: TextCell,
}, },
}, },
useGlobalFilter,
useSortBy, useSortBy,
useFlexLayout useFlexLayout
); );
@ -252,8 +253,8 @@ const UsersList = () => {
actions={ actions={
<> <>
<Search <Search
initialValue={globalFilter} initialValue={searchValue}
onChange={setGlobalFilter} onChange={setSearchValue}
/> />
<PageHeader.Divider /> <PageHeader.Divider />
<Button <Button
@ -269,7 +270,7 @@ const UsersList = () => {
} }
> >
<UserLimitWarning /> <UserLimitWarning />
<SearchHighlightProvider value={globalFilter}> <SearchHighlightProvider value={getSearchText(searchValue)}>
<VirtualizedTable <VirtualizedTable
rows={rows} rows={rows}
headerGroups={headerGroups} headerGroups={headerGroups}
@ -280,11 +281,11 @@ const UsersList = () => {
condition={rows.length === 0} condition={rows.length === 0}
show={ show={
<ConditionallyRender <ConditionallyRender
condition={globalFilter?.length > 0} condition={searchValue?.length > 0}
show={ show={
<TablePlaceholder> <TablePlaceholder>
No users found matching &ldquo; No users found matching &ldquo;
{globalFilter} {searchValue}
&rdquo; &rdquo;
</TablePlaceholder> </TablePlaceholder>
} }