diff --git a/frontend/src/external/bcanSatchel/actions.ts b/frontend/src/external/bcanSatchel/actions.ts index 8888dc2..721f718 100644 --- a/frontend/src/external/bcanSatchel/actions.ts +++ b/frontend/src/external/bcanSatchel/actions.ts @@ -60,6 +60,11 @@ export const updateYearFilter = action( (yearFilter: number[] | []) => ({ yearFilter }) ); +export const updateSort = action( + "updateSort", + (sort: {header: keyof Grant, asc: boolean}) => ({ sort, }) +); + /** * Append a new grant to the current list of grants. */ diff --git a/frontend/src/external/bcanSatchel/mutators.ts b/frontend/src/external/bcanSatchel/mutators.ts index c316793..c65065d 100644 --- a/frontend/src/external/bcanSatchel/mutators.ts +++ b/frontend/src/external/bcanSatchel/mutators.ts @@ -8,7 +8,8 @@ import { updateStartDateFilter, updateEndDateFilter, updateSearchQuery, updateYearFilter, - setNotifications + setNotifications, + updateSort } from './actions'; import { getAppStore, persistToSessionStorage } from './store'; import { setActiveUsers, setInactiveUsers } from './actions'; @@ -111,3 +112,8 @@ mutator(setNotifications, (actionMessage) => { const store = getAppStore(); store.notifications = actionMessage.notifications; }) + +mutator(updateSort, (actionMessage) => { + const store = getAppStore(); + store.sort = actionMessage.sort; +}) diff --git a/frontend/src/external/bcanSatchel/store.ts b/frontend/src/external/bcanSatchel/store.ts index e4bf40d..4f47952 100644 --- a/frontend/src/external/bcanSatchel/store.ts +++ b/frontend/src/external/bcanSatchel/store.ts @@ -17,6 +17,7 @@ export interface AppState { yearFilter:number[] | []; activeUsers: User[] | []; inactiveUsers: User[] | []; + sort: {header: keyof Grant, asc: boolean} | null; notifications: Notification[]; } @@ -33,7 +34,8 @@ const initialState: AppState = { yearFilter: [], activeUsers: [], inactiveUsers: [], - notifications: [] + notifications: [], + sort: null, }; /** diff --git a/frontend/src/main-page/grants/GrantPage.tsx b/frontend/src/main-page/grants/GrantPage.tsx index 05bc399..4932f16 100644 --- a/frontend/src/main-page/grants/GrantPage.tsx +++ b/frontend/src/main-page/grants/GrantPage.tsx @@ -1,5 +1,5 @@ import "./styles/GrantPage.css"; -import GrantList from "./grant-list/index.tsx"; +import GrantList from "./grant-list/GrantList.tsx"; import AddGrantButton from "./new-grant/AddGrant.tsx"; import GrantSearch from "./filter-bar/GrantSearch.tsx"; diff --git a/frontend/src/main-page/grants/filter-bar/processGrantData.ts b/frontend/src/main-page/grants/filter-bar/processGrantData.ts index 6a8fd6e..744b83b 100644 --- a/frontend/src/main-page/grants/filter-bar/processGrantData.ts +++ b/frontend/src/main-page/grants/filter-bar/processGrantData.ts @@ -7,7 +7,7 @@ import { filterGrants, yearFilterer, statusFilter, - searchFilter + searchFilter, } from "./grantFilters"; import { sortGrants } from "./grantSorter.ts"; import { api } from "../../../api.ts"; @@ -29,7 +29,15 @@ export const fetchGrants = async () => { // contains callbacks for sorting and filtering grants // stores state for list of grants/filter export const ProcessGrantData = () => { - const { allGrants, filterStatus, startDateFilter, endDateFilter, yearFilter, searchQuery } = getAppStore(); + const { + allGrants, + filterStatus, + startDateFilter, + endDateFilter, + yearFilter, + searchQuery, + sort, + } = getAppStore(); // fetch grants on mount if empty useEffect(() => { @@ -37,17 +45,16 @@ export const ProcessGrantData = () => { }, [allGrants.length]); // compute filtered grants dynamically — no useState needed - const filteredGrants = filterGrants(allGrants, [ + const baseFiltered = filterGrants(allGrants, [ statusFilter(filterStatus), dateRangeFilter(startDateFilter, endDateFilter), yearFilterer(yearFilter), - searchFilter(searchQuery) + searchFilter(searchQuery), ]); - // sorting callback - const onSort = (header: keyof Grant, asc: boolean) => { - return sortGrants(filteredGrants, header, asc); - }; + const filteredGrants = sort + ? sortGrants(baseFiltered, sort.header, sort.asc) + : baseFiltered; - return { grants: filteredGrants, onSort }; + return { grants: filteredGrants }; }; diff --git a/frontend/src/main-page/grants/grant-list/GrantLabels.tsx b/frontend/src/main-page/grants/grant-list/GrantLabels.tsx index 344ecbe..bc420f0 100644 --- a/frontend/src/main-page/grants/grant-list/GrantLabels.tsx +++ b/frontend/src/main-page/grants/grant-list/GrantLabels.tsx @@ -1,11 +1,9 @@ -import React from "react"; import "../styles/GrantLabels.css"; import { useState } from "react"; import { Grant } from "../../../../../middle-layer/types/Grant"; +import { updateSort } from "../../../external/bcanSatchel/actions"; -const GrantLabels: React.FC<{ - onSort: (header: keyof Grant, asc: boolean) => void; -}> = ({ onSort }) => { +const GrantLabels = () => { const [labels, setLabels] = useState({ header: "applicationDate", asc: true, @@ -13,7 +11,7 @@ const GrantLabels: React.FC<{ function buttonHandler(header: keyof Grant) { const isAsc = labels.header == header ? !labels.asc : true; - onSort(header, isAsc); + updateSort({header, asc: isAsc}); setLabels({ header: header, asc: isAsc }); } diff --git a/frontend/src/main-page/grants/grant-list/index.tsx b/frontend/src/main-page/grants/grant-list/GrantList.tsx similarity index 84% rename from frontend/src/main-page/grants/grant-list/index.tsx rename to frontend/src/main-page/grants/grant-list/GrantList.tsx index afd9257..4fbf551 100644 --- a/frontend/src/main-page/grants/grant-list/index.tsx +++ b/frontend/src/main-page/grants/grant-list/GrantList.tsx @@ -1,13 +1,14 @@ import "../styles/GrantList.css"; import { observer } from "mobx-react-lite"; import { useState, useEffect } from "react"; -import GrantItem from "./GrantItem.tsx"; -import GrantLabels from "./GrantLabels.tsx"; +import GrantItem from "./GrantItem"; +import GrantLabels from "./GrantLabels"; import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"; import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; -import { ProcessGrantData } from "../filter-bar/processGrantData.ts"; -import NewGrantModal from "../new-grant/NewGrantModal.tsx"; -import { Grant } from "../../../../../middle-layer/types/Grant.ts"; +import { ProcessGrantData } from "../filter-bar/processGrantData"; +import NewGrantModal from "../new-grant/NewGrantModal"; +import { Grant } from "../../../../../middle-layer/types/Grant"; +import { getAppStore } from '../../../external/bcanSatchel/store'; const ITEMS_PER_PAGE = 6; @@ -25,25 +26,20 @@ const GrantList: React.FC = observer( showOnlyMyGrants = false, currentUserEmail, }) => { - const { grants, onSort } = ProcessGrantData(); + const { grants } = ProcessGrantData(); + const {filterStatus} = getAppStore(); const [currentPage, setPage] = useState(1); const [showNewGrantModal, setShowNewGrantModal] = useState(false); // @ts-ignore const [wasGrantSubmitted, setWasGrantSubmitted] = useState(false); - const [sortedGrants, setSortedGrants] = useState(grants); - - // const handleSort = (header: keyof Grant, asc: boolean) => { - // const sorted = onSort(header, asc); - // setSortedGrants(sorted.length > 0 ? sorted : grants); - // }; const displayedGrants = showOnlyMyGrants - ? sortedGrants.filter( + ? grants.filter( (grant: Grant) => grant.bcan_poc?.POC_email?.toLowerCase() === currentUserEmail?.toLowerCase() ) - : sortedGrants; + : grants; useEffect(() => { if (selectedGrantId !== undefined && grants.length > 0) { @@ -57,11 +53,11 @@ const GrantList: React.FC = observer( } } } - }, [selectedGrantId, grants, currentPage, sortedGrants]); + }, [selectedGrantId, grants, currentPage]); useEffect(() => { - setSortedGrants(sortedGrants.length > 0 ? sortedGrants : grants); - }, [grants]); + setPage(1); + },[filterStatus, showOnlyMyGrants]); const count = displayedGrants.length; const startRange = (currentPage - 1) * ITEMS_PER_PAGE; @@ -71,7 +67,7 @@ const GrantList: React.FC = observer( return (
- +
{visibleItems.map((grant) => ( = observer(

{showOnlyMyGrants ? "You currently have no grants assigned as BCAN POC." - : "No grants found>"} + : "No grants found :("}

)}