diff --git a/web/src/components/CompanyFilterDropdown.tsx b/web/src/components/CompanyFilterDropdown.tsx new file mode 100644 index 0000000..958d894 --- /dev/null +++ b/web/src/components/CompanyFilterDropdown.tsx @@ -0,0 +1,50 @@ +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + DropdownMenuCheckboxItem, +} from "./ui/dropdown-menu"; +import { Button } from "./ui/button"; +import { ChevronDown } from "lucide-react"; + +type Props = { + allCompanies: string[]; + selectedCompanies: string[]; + setSelectedCompanies: React.Dispatch>; +}; + +export function CompanyFilterDropdown({ + allCompanies, + selectedCompanies, + setSelectedCompanies, +}: Props) { + function toggleCompany(name: string) { + setSelectedCompanies((prev) => + prev.includes(name) ? prev.filter((n) => n !== name) : [...prev, name], + ); + } + + return ( + + + + + + {allCompanies.map((name) => ( + toggleCompany(name)} + onSelect={(e) => e.preventDefault()} + > + {name} + + ))} + + + ); +} diff --git a/web/src/pages/AllProblems.tsx b/web/src/pages/AllProblems.tsx index 9d793a7..b68a6fd 100644 --- a/web/src/pages/AllProblems.tsx +++ b/web/src/pages/AllProblems.tsx @@ -19,6 +19,7 @@ import { getCompanyColor } from "~/utils/companyColors"; import { cn } from "~/lib/utils"; import { Separator } from "~/components/ui/separator"; import { TagFilterDropdown } from "~/components/TagFilterDropdown"; +import { CompanyFilterDropdown } from "~/components/CompanyFilterDropdown"; ModuleRegistry.registerModules([AllCommunityModule]); @@ -372,6 +373,17 @@ export default function AllProblems() { const [hideCompleted, setHideCompleted] = useState(false); + const [selectedCompanies, setSelectedCompanies] = useState([]); + + // ponytail: compute unique companies from loaded data, no extra query + const allCompanies = useMemo(() => { + const names = new Set(); + for (const p of problems) { + for (const c of p.other_companies) names.add(c); + } + return [...names].sort(); + }, [problems]); + const gridRef = useRef>(null); // fetch @@ -451,11 +463,11 @@ export default function AllProblems() { // AG Grid external filter handles difficulty; quick filter handles search gridRef.current.api.setGridOption("quickFilterText", search); gridRef.current.api.onFilterChanged(); - }, [search, diffFilter, selectedTags, tagMatchMode, hideCompleted]); + }, [search, diffFilter, selectedTags, tagMatchMode, hideCompleted, selectedCompanies]); const isExternalFilterPresent = useCallback(() => { - return diffFilter !== "All" || selectedTags.length > 0 || hideCompleted; - }, [diffFilter, selectedTags, hideCompleted]); + return diffFilter !== "All" || selectedTags.length > 0 || hideCompleted || selectedCompanies.length > 0; + }, [diffFilter, selectedTags, hideCompleted, selectedCompanies]); const doesExternalFilterPass = useCallback( (node: { data?: Problem }) => { @@ -489,9 +501,18 @@ export default function AllProblems() { } } + // Company filter — match any selected company + if (selectedCompanies.length > 0) { + const problemCompanies = problem.other_companies ?? []; + const matchesCompany = selectedCompanies.some((c) => + problemCompanies.includes(c), + ); + if (!matchesCompany) return false; + } + return true; }, - [diffFilter, selectedTags, tagMatchMode, hideCompleted], + [diffFilter, selectedTags, tagMatchMode, hideCompleted, selectedCompanies], ); /* --------------------- Column Defs -------------------- */ @@ -693,6 +714,12 @@ export default function AllProblems() { tagMatchMode={tagMatchMode} setTagMatchMode={setTagMatchMode} /> + +