Skip to content

Commit

Permalink
Implement basic filtering in UsersView
Browse files Browse the repository at this point in the history
Unfortunately this still seems to be a bit buggy: Clearing the filter
text causes a bunch of duplicate key errors, even though it is unclear
whether the issue is with `useAsyncList` or NextUI's internal table
rendering.
  • Loading branch information
fwcd committed Oct 7, 2024
1 parent 5817371 commit 3c5a32c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/screens/home/admin/UsersView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { InView } from 'react-intersection-observer';
export function UsersView() {
const auth = useContext(AuthContext);

const [searchQuery, setSearchQuery] = useState('');
const [isLoading, setLoading] = useState(false);
const [needsMore, setNeedsMore] = useState(false);
const [hasMore, setHasMore] = useState(false);
Expand All @@ -39,7 +38,7 @@ export function UsersView() {
column: 'id',
direction: 'ascending',
},
async load({ cursor, sortDescriptor }) {
async load({ cursor, sortDescriptor, filterText }) {
try {
if (cursor !== undefined) {
setLoading(false);
Expand All @@ -50,6 +49,12 @@ export function UsersView() {
await auth.getAllUsers({
page,
perPage: 50,
filter: filterText
? {
key: 'username',
text: filterText,
}
: undefined,
sorting: sortDescriptor.column
? {
key: sortDescriptor.column,
Expand Down Expand Up @@ -84,7 +89,10 @@ export function UsersView() {
title="Users"
toolbar={
<div className="flex flex-row gap-4">
<SearchBar placeholder="Search users..." setQuery={setSearchQuery} />
<SearchBar
placeholder="Search users..."
setQuery={users.setFilterText}
/>
<Tooltip content="Add user" color="success">
<Button
isIconOnly
Expand Down
14 changes: 14 additions & 0 deletions src/utils/filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface Filter {
key: string | number;
text: string;
}

/** Filters elements according to the given filter. */
export function filtered<T>(elements: T[], filter: Filter): T[] {
const filterText = filter.text.toLowerCase();
return elements.filter((element: any) => {
const value = element[filter.key];
const json = JSON.stringify(value).toLowerCase();
return json.includes(filterText);
});
}
5 changes: 5 additions & 0 deletions src/utils/pagination.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Filter, filtered } from '@luna/utils/filter';
import { sorted, Sorting } from '@luna/utils/sort';

export interface Pagination {
page: number;
perPage: number;
filter?: Filter;
sorting?: Sorting;
}

Expand All @@ -14,6 +16,9 @@ export function slicePage<T>(elements: T[], pagination?: Pagination): T[] {
if (pagination === undefined) {
return elements;
}
if (pagination.filter) {
elements = filtered(elements, pagination.filter);
}
if (pagination.sorting) {
elements = sorted(elements, pagination.sorting);
}
Expand Down

0 comments on commit 3c5a32c

Please sign in to comment.