import { Fragment, useState, ReactElement } from "react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; import { Tab } from "@headlessui/react"; import { TCycleFilters } from "@plane/types"; // hooks import { PageHead } from "@/components/core"; import { CyclesView, CycleCreateUpdateModal, CyclesViewHeader, CycleAppliedFiltersList, ActiveCycleRoot, } from "@/components/cycles"; import CyclesListMobileHeader from "@/components/cycles/cycles-list-mobile-header"; import { EmptyState } from "@/components/empty-state"; import { CyclesHeader } from "@/components/headers"; import { CycleModuleBoardLayout, CycleModuleListLayout, GanttLayoutLoader } from "@/components/ui"; import { CYCLE_TABS_LIST } from "@/constants/cycle"; import { EmptyStateType } from "@/constants/empty-state"; import { calculateTotalFilters } from "@/helpers/filter.helper"; import { useEventTracker, useCycle, useProject, useCycleFilter } from "@/hooks/store"; // layouts import { AppLayout } from "@/layouts/app-layout"; // components // ui // helpers // types import { NextPageWithLayout } from "@/lib/types"; // constants const ProjectCyclesPage: NextPageWithLayout = observer(() => { // states const [createModal, setCreateModal] = useState(false); // store hooks const { setTrackElement } = useEventTracker(); const { currentProjectCycleIds, loader } = useCycle(); const { getProjectById, currentProjectDetails } = useProject(); // router const router = useRouter(); const { workspaceSlug, projectId, peekCycle } = router.query; // cycle filters hook const { clearAllFilters, currentProjectDisplayFilters, currentProjectFilters, updateDisplayFilters, updateFilters } = useCycleFilter(); // derived values const totalCycles = currentProjectCycleIds?.length ?? 0; const project = projectId ? getProjectById(projectId?.toString()) : undefined; const pageTitle = project?.name ? `${project?.name} - Cycles` : undefined; // selected display filters const cycleTab = currentProjectDisplayFilters?.active_tab; const cycleLayout = currentProjectDisplayFilters?.layout ?? "list"; const handleRemoveFilter = (key: keyof TCycleFilters, value: string | null) => { if (!projectId) return; let newValues = currentProjectFilters?.[key] ?? []; if (!value) newValues = []; else newValues = newValues.filter((val) => val !== value); updateFilters(projectId.toString(), { [key]: newValues }); }; if (!workspaceSlug || !projectId) return <>; // No access to cycle if (currentProjectDetails?.cycle_view === false) return (
); if (loader) return ( <> {cycleLayout === "list" && } {cycleLayout === "board" && } {cycleLayout === "gantt" && } ); return ( <>
setCreateModal(false)} /> {totalCycles === 0 ? (
{ setTrackElement("Cycle empty state"); setCreateModal(true); }} />
) : ( i.key == cycleTab)} selectedIndex={CYCLE_TABS_LIST.findIndex((i) => i.key == cycleTab)} onChange={(i) => { if (!projectId) return; const tab = CYCLE_TABS_LIST[i]; if (!tab) return; updateDisplayFilters(projectId.toString(), { active_tab: tab.key, }); }} > {calculateTotalFilters(currentProjectFilters ?? {}) !== 0 && (
clearAllFilters(projectId.toString())} handleRemoveFilter={handleRemoveFilter} />
)}
)}
); }); ProjectCyclesPage.getLayout = function getLayout(page: ReactElement) { return ( } mobileHeader={} withProjectWrapper> {page} ); }; export default ProjectCyclesPage;