"use client"; import { FC, useEffect, useMemo, useState } from "react"; import { observer } from "mobx-react"; import { ChevronLeft } from "lucide-react"; import { IEstimateFormData, TEstimateSystemKeys, TEstimatePointsObject } from "@plane/types"; import { Button, TOAST_TYPE, setToast } from "@plane/ui"; // components import { EModalPosition, EModalWidth, ModalCore } from "@/components/core"; import { EstimateCreateStageOne, EstimatePointCreateRoot } from "@/components/estimates"; // hooks import { useProjectEstimates } from "@/hooks/store"; // plane web constants import { EEstimateSystem, ESTIMATE_SYSTEMS } from "@/plane-web/constants/estimates"; type TCreateEstimateModal = { workspaceSlug: string; projectId: string; isOpen: boolean; handleClose: () => void; }; export const CreateEstimateModal: FC = observer((props) => { // props const { workspaceSlug, projectId, isOpen, handleClose } = props; // hooks const { createEstimate } = useProjectEstimates(); // states const [estimateSystem, setEstimateSystem] = useState(EEstimateSystem.POINTS); const [estimatePoints, setEstimatePoints] = useState(undefined); const [estimatePointCreate, setEstimatePointCreate] = useState(undefined); const [estimatePointCreateError, setEstimatePointCreateError] = useState([]); const [buttonLoader, setButtonLoader] = useState(false); const handleUpdatePoints = (newPoints: TEstimatePointsObject[] | undefined) => setEstimatePoints(newPoints); useEffect(() => { if (isOpen) { setEstimateSystem(EEstimateSystem.POINTS); setEstimatePoints(undefined); } }, [isOpen]); const handleCreateEstimate = async () => { setEstimatePointCreateError([]); if (estimatePointCreate === undefined || estimatePointCreate?.length === 0) { try { if (!workspaceSlug || !projectId || !estimatePoints) return; setButtonLoader(true); const payload: IEstimateFormData = { estimate: { name: ESTIMATE_SYSTEMS[estimateSystem]?.name, type: estimateSystem, last_used: true, }, estimate_points: estimatePoints, }; await createEstimate(workspaceSlug, projectId, payload); setButtonLoader(false); setToast({ type: TOAST_TYPE.SUCCESS, title: "Estimate created", message: "A new estimate has been added in your project.", }); handleClose(); } catch (error) { setButtonLoader(false); setToast({ type: TOAST_TYPE.ERROR, title: "Estimate creation failed", message: "We were unable to create the new estimate, please try again.", }); } } else { setEstimatePointCreateError(estimatePointCreate.map((point) => point.key)); } }; // derived values const renderEstimateStepsCount = useMemo(() => (estimatePoints ? "2" : "1"), [estimatePoints]); return (
{/* heading */}
{estimatePoints && (
{ setEstimateSystem(EEstimateSystem.POINTS); handleUpdatePoints(undefined); }} className="flex-shrink-0 cursor-pointer w-5 h-5 flex justify-center items-center" >
)}
New estimate system
Step {renderEstimateStepsCount} of 2
{/* estimate steps */}
{!estimatePoints && ( handleUpdatePoints(ESTIMATE_SYSTEMS[estimateSystem].templates[templateType].values) } /> )} {estimatePoints && ( { setEstimatePointCreateError([]); setEstimatePointCreate(value); }} estimatePointCreateError={estimatePointCreateError} /> )} {estimatePointCreateError.length > 0 && (
Estimate points can't be empty. Enter a value in each field or remove those you don't have values for.
)}
{estimatePoints && ( )}
); });