From af8606c9414d7b9f06ed3ebfb41d7cde10e6fd72 Mon Sep 17 00:00:00 2001 From: Xavilien Date: Thu, 15 Feb 2024 22:59:13 -0500 Subject: [PATCH] Department filter search (#135) * Add search to department filter * Fix warning * Use query length instead of searchOn * Use query length instead of searchOn * Backspace key deletes items * Fixed spacebar issue * Remove unused imports * Added tab autofill * Fix lint issues --- frontend/src/app/filters.ts | 5 ++ .../components/filters/DepartmentFilter.tsx | 62 ++++++++++++++----- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/filters.ts b/frontend/src/app/filters.ts index 17d59ff..c90bac7 100644 --- a/frontend/src/app/filters.ts +++ b/frontend/src/app/filters.ts @@ -7,6 +7,7 @@ export interface FiltersState { departments: { active: boolean; names: string[]; + query: string; }; units: { active: boolean; @@ -28,6 +29,7 @@ const initialState: FiltersState = { departments: { active: false, names: [], + query: "", }, units: { active: false, @@ -73,6 +75,9 @@ export const filtersSlice = createSlice({ updateDepartments: (state, action: PayloadAction) => { state.departments.names = action.payload; }, + updateDepartmentsQuery: (state, action: PayloadAction) => { + state.departments.query = action.payload; + }, updateSemestersActive: (state, action: PayloadAction) => { state.semesters.active = action.payload; }, diff --git a/frontend/src/components/filters/DepartmentFilter.tsx b/frontend/src/components/filters/DepartmentFilter.tsx index ab275fb..d89e576 100644 --- a/frontend/src/components/filters/DepartmentFilter.tsx +++ b/frontend/src/components/filters/DepartmentFilter.tsx @@ -4,14 +4,14 @@ import { CheckIcon } from "@heroicons/react/20/solid"; import { useAppDispatch, useAppSelector } from "../../app/hooks"; import { filtersSlice } from "../../app/filters"; import { throttledFilter } from "../../app/store"; -import { Listbox } from "@headlessui/react"; +import { Combobox } from "@headlessui/react"; import { classNames, getDepartmentByName } from "../../app/utils"; import { DEPARTMENTS } from "../../app/constants"; const DepartmentFilter = () => { const dispatch = useAppDispatch(); - const { active, names } = useAppSelector( + const { active, names, query } = useAppSelector( (state) => state.filters.departments ); @@ -26,10 +26,18 @@ const DepartmentFilter = () => { throttledFilter(); }; + const searchDepartments = (department: { name: string, shortName: string, prefix: string }) => { + const searchTerm = query.toLowerCase(); + + return department.name.toLowerCase().includes(searchTerm) || + department.shortName.toLowerCase().includes(searchTerm) || + department.prefix.toLowerCase().includes(searchTerm); + } + return (
- - + +
{ />
Department -
- - + + + {names.length === 0 ? ( - None + query.length === 0 && None ) : ( names.map((department) => ( { )) )} + dispatch(filtersSlice.actions.updateDepartmentsQuery(e.target.value))} + onKeyDown={(e : React.KeyboardEvent) => { + if (e.key === "Backspace" && query.length === 0 && names.length > 0) { + deleteDepartment(names[names.length - 1]); + } else if (e.key === " ") { + dispatch(filtersSlice.actions.updateDepartmentsQuery(query + " science")); + } else if (e.key === "Tab") { + const department = DEPARTMENTS.filter(searchDepartments)[0].name; + if (!names.includes(department)) { + setDepartments(names.concat([department])); + } + } + }} + onKeyUp={(e : React.KeyboardEvent) => { + if (e.key === " ") { + e.preventDefault(); + } + }} + /> - +
- - {DEPARTMENTS.map(({ name, prefix }) => ( - + {DEPARTMENTS.filter(searchDepartments).map(({ name, prefix }) => ( + { )} )} - + ))} - +
-
+
); };