import { FC, useEffect, useMemo, useState } from "react"; import { observer } from "mobx-react"; import { ChevronLeft } from "lucide-react"; import { IEstimateFormData, TEstimatePointsObject, TEstimateUpdateStageKeys, TEstimateSystemKeys } from "@plane/types"; import { Button, TOAST_TYPE, setToast } from "@plane/ui"; // components import { EModalPosition, EModalWidth, ModalCore } from "@/components/core"; import { EstimateUpdateStageOne, EstimateUpdateStageTwo } from "@/components/estimates"; // constants import { EEstimateSystem } from "@/constants/estimates"; // hooks import { useEstimate, // useProjectEstimates } from "@/hooks/store"; type TUpdateEstimateModal = { workspaceSlug: string; projectId: string; estimateId: string | undefined; isOpen: boolean; handleClose: () => void; }; export const UpdateEstimateModal: FC = observer((props) => { // props const { workspaceSlug, projectId, estimateId, isOpen, handleClose } = props; // hooks const { asJson: currentEstimate, updateEstimate } = useEstimate(estimateId); // states const [estimateEditType, setEstimateEditType] = useState(undefined); const [estimatePoints, setEstimatePoints] = useState(undefined); const handleEstimateEditType = (type: TEstimateUpdateStageKeys) => { if (currentEstimate?.points && currentEstimate?.points.length > 0) { const estimateValidatePoints: TEstimatePointsObject[] = []; currentEstimate?.points.map( (point) => point.key && point.value && estimateValidatePoints.push({ id: point.id, key: point.key, value: point.value }) ); if (estimateValidatePoints.length > 0) { setEstimateEditType(type); setEstimatePoints(estimateValidatePoints); } } }; const handleUpdatePoints = (newPoints: TEstimatePointsObject[] | undefined) => setEstimatePoints(newPoints); useEffect(() => { if (!isOpen) { setEstimateEditType(undefined); setEstimatePoints(undefined); } }, [isOpen]); // derived values const renderEstimateStepsCount = useMemo(() => (estimatePoints ? "2" : "1"), [estimatePoints]); const isNewEstimatePointsToCreate = (estimatePoints || []).filter((point) => point.id === undefined).length > 0 ? true : false; const handleUpdateEstimate = async () => { try { if (!workspaceSlug || !projectId || !estimateId || currentEstimate?.type === undefined) return; const currentEstimatePoints = (estimatePoints || []).filter((point) => point.id === undefined); const currentEstimationType: TEstimateSystemKeys = currentEstimate?.type; const validatedEstimatePoints: TEstimatePointsObject[] = []; if ([EEstimateSystem.POINTS, EEstimateSystem.TIME].includes(currentEstimationType)) { currentEstimatePoints?.map((estimatePoint) => { if ( estimatePoint.value && ((estimatePoint.value != "0" && Number(estimatePoint.value)) || estimatePoint.value === "0") ) validatedEstimatePoints.push(estimatePoint); }); } else { currentEstimatePoints?.map((estimatePoint) => { if (estimatePoint.value) validatedEstimatePoints.push(estimatePoint); }); } if (validatedEstimatePoints.length === currentEstimatePoints?.length) { const payload: IEstimateFormData = { estimate_points: validatedEstimatePoints, }; await updateEstimate(payload); setToast({ type: TOAST_TYPE.SUCCESS, title: "Estimate system created", message: "Created and Enabled successfully", }); handleClose(); } else { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "something went wrong", }); } } catch (error) { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "something went wrong", }); } }; return (
{/* heading */}
{estimateEditType && (
{ setEstimateEditType(undefined); handleUpdatePoints(undefined); }} className="flex-shrink-0 cursor-pointer w-5 h-5 flex justify-center items-center" >
)}
Edit estimate system
Step {renderEstimateStepsCount}/2
{/* estimate steps */}
{!estimateEditType && } {estimateEditType && estimatePoints && ( )}
{isNewEstimatePointsToCreate && ( )}
); });