import { useCallback, useRef, useState } from "react"; import { observer } from "mobx-react"; import { Tab } from "@headlessui/react"; import { ListFilter, Search, X } from "lucide-react"; // hooks import { useCycleFilter } from "hooks/store"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // components import { CycleFiltersSelection } from "components/cycles"; import { FiltersDropdown } from "components/issues"; // ui import { Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; // types import { TCycleFilters } from "@plane/types"; // constants import { CYCLE_TABS_LIST, CYCLE_VIEW_LAYOUTS } from "constants/cycle"; type Props = { projectId: string; }; export const CyclesViewHeader: React.FC = observer((props) => { const { projectId } = props; // states const [isSearchOpen, setIsSearchOpen] = useState(false); // refs const inputRef = useRef(null); // hooks const { currentProjectDisplayFilters, currentProjectFilters, searchQuery, updateDisplayFilters, updateFilters, updateSearchQuery, } = useCycleFilter(); // outside click detector hook useOutsideClickDetector(inputRef, () => { if (isSearchOpen && searchQuery.trim() === "") setIsSearchOpen(false); }); const handleFilters = useCallback( (key: keyof TCycleFilters, value: string | string[]) => { const newValues = currentProjectFilters?.[key] ?? []; if (Array.isArray(value)) value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); }); else { if (currentProjectFilters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); else newValues.push(value); } updateFilters(projectId, { [key]: newValues }); }, [currentProjectFilters, projectId, updateFilters] ); const handleInputKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Escape") { if (searchQuery && searchQuery.trim() !== "") updateSearchQuery(""); else setIsSearchOpen(false); } }; return (
{CYCLE_TABS_LIST.map((tab) => ( `border-b-2 p-4 text-sm font-medium outline-none ${ selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent" }` } > {tab.name} ))} {currentProjectDisplayFilters?.active_tab !== "active" && (
{!isSearchOpen && ( )}
updateSearchQuery(e.target.value)} onKeyDown={handleInputKeyDown} /> {isSearchOpen && ( )}
} title="Filters" placement="bottom-end">
{CYCLE_VIEW_LAYOUTS.map((layout) => ( ))}
)}
); });