-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add filtering by text/role/status, sorting, pagination, collection pr…
…efs (#367) * Add filtering by text/role/status, sorting, pagination, collection prefs via collection hooks * Fix prettier sgs * Fix more prettier sgs * One more prettier error * Change select->multi, add searching by composite name, three columns filter * Fix prettiers * Fix text filter * More prettiers * More prettiers * Merge main, resolve conflicts * Merge main conflicts again * Add day checkins to default visible columns * More prettiers * More prettiers * Add icons to status filter * Prettier run everything * fix: type error --------- Co-authored-by: Sam Der <[email protected]>
- Loading branch information
1 parent
9a1d8e1
commit f4407d3
Showing
4 changed files
with
356 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
apps/site/src/app/admin/participants/components/ParticipantsFilters.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { Dispatch, SetStateAction } from "react"; | ||
|
||
import FormField from "@cloudscape-design/components/form-field"; | ||
import { IconProps } from "@cloudscape-design/components/icon"; | ||
import Multiselect, { | ||
MultiselectProps, | ||
} from "@cloudscape-design/components/multiselect"; | ||
import SpaceBetween from "@cloudscape-design/components/space-between"; | ||
import TextFilter, { | ||
TextFilterProps, | ||
} from "@cloudscape-design/components/text-filter"; | ||
|
||
import { | ||
Decision, | ||
PostAcceptedStatus, | ||
ReviewStatus, | ||
Status, | ||
} from "@/lib/admin/useApplicant"; | ||
import { StatusLabels } from "../../applicants/components/ApplicantStatus"; | ||
import type { Options } from "./ParticipantsTable"; | ||
|
||
interface ParticipantsFiltersProps { | ||
filteredItemsCount: number | undefined; | ||
filterProps: TextFilterProps; | ||
roles: Options; | ||
selectedRoles: Options; | ||
setSelectedRoles: Dispatch<SetStateAction<Options>>; | ||
statuses: Options; | ||
selectedStatuses: Options; | ||
setSelectedStatuses: Dispatch<SetStateAction<Options>>; | ||
} | ||
|
||
const StatusIcons: Record<Status, IconProps.Name> = { | ||
[ReviewStatus.pending]: "status-pending", | ||
[ReviewStatus.reviewed]: "status-in-progress", | ||
[ReviewStatus.released]: "status-positive", | ||
[Decision.accepted]: "status-positive", | ||
[Decision.rejected]: "status-pending", | ||
[Decision.waitlisted]: "status-negative", | ||
[PostAcceptedStatus.signed]: "status-in-progress", | ||
[PostAcceptedStatus.confirmed]: "status-positive", | ||
[PostAcceptedStatus.attending]: "status-positive", | ||
[PostAcceptedStatus.void]: "status-negative", | ||
}; | ||
|
||
const statusOption = (status: MultiselectProps.Option) => { | ||
if (status.value === undefined) { | ||
throw Error(); | ||
} | ||
return { | ||
label: StatusLabels[status.value as Status], | ||
value: status.value, | ||
iconName: StatusIcons[status.value as Status], | ||
}; | ||
}; | ||
|
||
function ParticipantsFilters({ | ||
filteredItemsCount, | ||
filterProps, | ||
roles, | ||
selectedRoles, | ||
setSelectedRoles, | ||
statuses, | ||
selectedStatuses, | ||
setSelectedStatuses, | ||
}: ParticipantsFiltersProps) { | ||
return ( | ||
<SpaceBetween size="l" direction="horizontal"> | ||
<div style={{ marginTop: "24px" }}> | ||
<TextFilter | ||
{...filterProps} | ||
countText={ | ||
filteredItemsCount === 1 | ||
? "1 participant" | ||
: `${filteredItemsCount} participants` | ||
} | ||
filteringAriaLabel="Filter participants" | ||
filteringPlaceholder="Search participants" | ||
/> | ||
</div> | ||
<FormField label="Role"> | ||
<Multiselect | ||
data-testid="role-filter" | ||
placeholder="Filter by role" | ||
options={roles} | ||
selectedAriaLabel="Selected" | ||
selectedOptions={selectedRoles} | ||
onChange={(event) => setSelectedRoles(event.detail.selectedOptions)} | ||
expandToViewport={true} | ||
/> | ||
</FormField> | ||
<FormField label="Status"> | ||
<Multiselect | ||
data-testid="status-filter" | ||
placeholder="Filter by status" | ||
options={statuses.map(statusOption)} | ||
selectedAriaLabel="Selected" | ||
selectedOptions={selectedStatuses} | ||
onChange={(event) => | ||
setSelectedStatuses(event.detail.selectedOptions) | ||
} | ||
expandToViewport={true} | ||
/> | ||
</FormField> | ||
</SpaceBetween> | ||
); | ||
} | ||
|
||
export default ParticipantsFilters; |
Oops, something went wrong.