diff --git a/app/components/AnalystDashboard/AllDashboard.tsx b/app/components/AnalystDashboard/AllDashboard.tsx index d9e448a531..a638fea508 100644 --- a/app/components/AnalystDashboard/AllDashboard.tsx +++ b/app/components/AnalystDashboard/AllDashboard.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable react/jsx-pascal-case */ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { graphql, useFragment } from 'react-relay'; import styled from 'styled-components'; import cookie from 'js-cookie'; @@ -18,6 +18,7 @@ import { MRT_ToggleDensePaddingButton, MRT_ToggleFullScreenButton, MRT_ShowHideColumnsButton, + MRT_FilterFns, } from 'material-react-table'; import RowCount from 'components/Table/RowCount'; @@ -302,6 +303,10 @@ const AllDashboardTable: React.FC = ({ query }) => { const [showColumnFilters, setShowColumnFilters] = useState(false); const [sorting, setSorting] = useState([]); + const [expanded, setExpanded] = useState({}); + const [globalFilter, setGlobalFilter] = useState(null); + + const expandedRowsRef = useRef({}); const [columnSizing, setColumnSizing] = useState({ 'mrt-row-expand': 40, @@ -442,6 +447,11 @@ const AllDashboardTable: React.FC = ({ query }) => { } }, [visibilityPreference]); + useEffect(() => { + setExpanded(globalFilter ? expandedRowsRef.current : {}); + expandedRowsRef.current = {}; + }, [globalFilter]); + const state = { showGlobalFilter: true, columnFilters, @@ -450,6 +460,20 @@ const AllDashboardTable: React.FC = ({ query }) => { showColumnFilters, sorting, columnSizing, + expanded, + globalFilter, + }; + + const customGlobalFilter = (row, id, filterValue, filterMeta) => { + const defaultMatch = MRT_FilterFns.fuzzy(row, id, filterValue, filterMeta); + const communitiesString = row.original.communities + ?.map((item) => item.geoName) + .join(',') + ?.toLowerCase(); + const detailsMatch = communitiesString?.includes(filterValue.toLowerCase()); + expandedRowsRef.current[row.id] = detailsMatch; + + return defaultMatch || detailsMatch; }; const getCommunities = (application) => { @@ -689,8 +713,16 @@ const AllDashboardTable: React.FC = ({ query }) => { filterFns: { filterNumber, statusFilter, + customGlobalFilter, + }, + renderDetailPanel: ({ row }) => ( + + ), + globalFilterFn: 'customGlobalFilter', + onGlobalFilterChange: setGlobalFilter, + onExpandedChange: (expanded) => { + setExpanded(expanded); }, - renderDetailPanel: ({ row }) => , renderToolbarInternalActions: ({ table }) => ( diff --git a/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx b/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx index 5c4eeb4ed4..cf4552b057 100644 --- a/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx +++ b/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx @@ -2,6 +2,7 @@ import styled from 'styled-components'; interface Props { row: any; + filterValue: string; } const StyledMapLink = styled.a` @@ -17,7 +18,36 @@ const StyledSpan = styled.span` display: block; `; -const AllDashboardDetailPanel: React.FC = ({ row }) => { +const StyledHighlightSpan = styled.span` + background-color: ${(props) => props.theme.color.primaryYellow}; +`; + +const HighlightFilterMatch = ({ text, filterValue }) => { + if (!filterValue) return text; + + const normalizedFilterValue = filterValue.replace(/\s+/g, '').toLowerCase(); + const normalizedText = text.replace(/\s+/g, '').toLowerCase(); + + const matchIndex = normalizedText.indexOf(normalizedFilterValue); + + if (matchIndex === -1) { + return text; + } + + const beforeMatch = text.slice(0, matchIndex); + const match = text.slice(matchIndex, matchIndex + filterValue.length); + const afterMatch = text.slice(matchIndex + filterValue.length); + + return ( + <> + {beforeMatch} + {match} + {afterMatch} + + ); +}; + +const AllDashboardDetailPanel: React.FC = ({ row, filterValue }) => { const communities = (row.original.communities as any[]) || []; return ( <> @@ -30,7 +60,10 @@ const AllDashboardDetailPanel: React.FC = ({ row }) => { target="_blank" rel="noopener noreferrer" > - {item.geoName} + {index < communities.length - 1 && ', '} diff --git a/app/components/Table/ClearFilters.tsx b/app/components/Table/ClearFilters.tsx index 34780c31e9..a2f0bc7c58 100644 --- a/app/components/Table/ClearFilters.tsx +++ b/app/components/Table/ClearFilters.tsx @@ -19,6 +19,7 @@ const ClearFilters: React.FC = ({ const clearFilters = () => { table.resetColumnFilters(); table.setColumnFilters(defaultFilters); + table.setGlobalFilter(''); }; const isTableFiltersPresent = @@ -29,9 +30,15 @@ const ClearFilters: React.FC = ({ filters.filter((f) => f.id === 'program' && (f.value as any[]).length < 3) .length > 0; + const isGlobalFilterPresent = table.getState().globalFilter !== ''; + return (