diff --git a/src/apps/work/src/pages/budget-approvals/BudgetApprovalsPage/BudgetApprovalsPage.tsx b/src/apps/work/src/pages/budget-approvals/BudgetApprovalsPage/BudgetApprovalsPage.tsx index 94c2662a9..8066cc7a9 100644 --- a/src/apps/work/src/pages/budget-approvals/BudgetApprovalsPage/BudgetApprovalsPage.tsx +++ b/src/apps/work/src/pages/budget-approvals/BudgetApprovalsPage/BudgetApprovalsPage.tsx @@ -6,8 +6,8 @@ import { useState, } from 'react' import { Link } from 'react-router-dom' +import Select, { SingleValue } from 'react-select' -import { TableLoading } from '~/apps/admin/src/lib' import { PageWrapper } from '~/apps/review/src/lib' import { IconOutline } from '~/libs/ui' @@ -33,6 +33,11 @@ import { import styles from './BudgetApprovalsPage.module.scss' +interface ProjectOption { + label: string + value: string +} + function normalizeSearchValue(value: string): string { return value .trim() @@ -70,7 +75,7 @@ export const BudgetApprovalsPage: FC = () => { }: WorkAppContextModel = useContext(WorkAppContext) const [challengeNameSearch, setChallengeNameSearch] = useState('') - const [projectNameSearch, setProjectNameSearch] = useState('') + const [selectedProjectId, setSelectedProjectId] = useState('') const [page, setPage] = useState(1) const [perPage, setPerPage] = useState(PAGE_SIZE) @@ -85,6 +90,7 @@ export const BudgetApprovalsPage: FC = () => { name: normalizeSearchValue(challengeNameSearch) || undefined, page, perPage, + projectId: selectedProjectId || undefined, sortBy: 'updated', sortOrder: 'desc', status: CHALLENGE_STATUS.DRAFT, @@ -111,14 +117,19 @@ export const BudgetApprovalsPage: FC = () => { return map }, [projectsResult.projects]) - const accessibleProjectIds = useMemo( - () => new Set(projectsResult.projects.map(project => String(project.id || ''))), + const projectOptions = useMemo( + () => projectsResult.projects + .filter(project => !!project.id) + .map(project => ({ + label: project.name || String(project.id), + value: String(project.id), + })), [projectsResult.projects], ) - const normalizedProjectNameSearch = useMemo( - () => normalizeSearchValue(projectNameSearch), - [projectNameSearch], + const selectedProjectOption = useMemo( + () => projectOptions.find(opt => opt.value === selectedProjectId) ?? undefined, + [projectOptions, selectedProjectId], ) const filteredChallenges = useMemo( @@ -126,33 +137,9 @@ export const BudgetApprovalsPage: FC = () => { .filter(challenge => { const projectId = getProjectId(challenge) - if (!projectId) { - return false - } - - if (isAdmin) { - return true - } - - return accessibleProjectIds.has(projectId) - }) - .filter(challenge => { - if (!normalizedProjectNameSearch) { - return true - } - - const projectName = getProjectName(projectMap, getProjectId(challenge)) - - return normalizeSearchValue(projectName) - .includes(normalizedProjectNameSearch) + return !!projectId }), - [ - accessibleProjectIds, - challengesResult.challenges, - isAdmin, - normalizedProjectNameSearch, - projectMap, - ], + [challengesResult.challenges], ) function handleChallengeNameSearch(event: ChangeEvent): void { @@ -160,8 +147,8 @@ export const BudgetApprovalsPage: FC = () => { setPage(1) } - function handleProjectNameSearch(event: ChangeEvent): void { - setProjectNameSearch(event.target.value) + function handleProjectSelect(option: SingleValue): void { + setSelectedProjectId(option?.value ?? '') setPage(1) } @@ -174,10 +161,6 @@ export const BudgetApprovalsPage: FC = () => { setPage(1) } - if (challengesResult.isLoading || (!isAdmin && projectsResult.isLoading)) { - return - } - const errorMessage = challengesResult.error?.message || projectsResult.error?.message const totalPendingApprovals = challengesResult.metadata.total ?? 0 const shouldShowPagination = !errorMessage && totalPendingApprovals > 0 @@ -193,14 +176,17 @@ export const BudgetApprovalsPage: FC = () => {
- - Project +