Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions frontend/src/external/bcanSatchel/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/external/bcanSatchel/mutators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
updateStartDateFilter, updateEndDateFilter,
updateSearchQuery,
updateYearFilter,
setNotifications
setNotifications,
updateSort
} from './actions';
import { getAppStore, persistToSessionStorage } from './store';
import { setActiveUsers, setInactiveUsers } from './actions';
Expand Down Expand Up @@ -111,3 +112,8 @@ mutator(setNotifications, (actionMessage) => {
const store = getAppStore();
store.notifications = actionMessage.notifications;
})

mutator(updateSort, (actionMessage) => {
const store = getAppStore();
store.sort = actionMessage.sort;
})
4 changes: 3 additions & 1 deletion frontend/src/external/bcanSatchel/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AppState {
yearFilter:number[] | [];
activeUsers: User[] | [];
inactiveUsers: User[] | [];
sort: {header: keyof Grant, asc: boolean} | null;
notifications: Notification[];
}

Expand All @@ -33,7 +34,8 @@ const initialState: AppState = {
yearFilter: [],
activeUsers: [],
inactiveUsers: [],
notifications: []
notifications: [],
sort: null,
};

/**
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/main-page/grants/GrantPage.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
25 changes: 16 additions & 9 deletions frontend/src/main-page/grants/filter-bar/processGrantData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
filterGrants,
yearFilterer,
statusFilter,
searchFilter
searchFilter,
} from "./grantFilters";
import { sortGrants } from "./grantSorter.ts";
import { api } from "../../../api.ts";
Expand All @@ -29,25 +29,32 @@ 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(() => {
if (allGrants.length === 0) fetchGrants();
}, [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 };
};
8 changes: 3 additions & 5 deletions frontend/src/main-page/grants/grant-list/GrantLabels.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
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,
});

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 });
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -25,25 +26,20 @@ const GrantList: React.FC<GrantListProps> = 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) {
Expand All @@ -57,11 +53,11 @@ const GrantList: React.FC<GrantListProps> = 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;
Expand All @@ -71,7 +67,7 @@ const GrantList: React.FC<GrantListProps> = observer(
return (
<div className="paginated-grant-list">
<div className="bg-light-orange rounded-[1.2rem] pt-2">
<GrantLabels onSort={onSort} />
<GrantLabels/>
<div className="grant-list p-4">
{visibleItems.map((grant) => (
<GrantItem key={grant.grantId}
Expand All @@ -82,7 +78,7 @@ const GrantList: React.FC<GrantListProps> = observer(
<p className="text-center text-gray-500 py-6">
{showOnlyMyGrants
? "You currently have no grants assigned as BCAN POC."
: "No grants found>"}
: "No grants found :("}
</p>
)}
</div>
Expand Down