import React, { useEffect, useState } from "react"; // next import { useRouter } from "next/router"; import dynamic from "next/dynamic"; // swr import { mutate } from "swr"; // react hook form import { Controller, useForm } from "react-hook-form"; // fetching keys import { PROJECT_ISSUES_DETAILS, PROJECT_ISSUES_LIST, CYCLE_ISSUES, USER_ISSUE, } from "constants/fetch-keys"; // headless import { Dialog, Menu, Transition } from "@headlessui/react"; // services import issuesServices from "lib/services/issues.services"; // hooks import useUser from "lib/hooks/useUser"; import useToast from "lib/hooks/useToast"; // ui import { Button, Input, TextArea } from "ui"; // commons import { renderDateFormat, cosineSimilarity } from "constants/common"; // components import SelectState from "./SelectState"; import SelectCycles from "./SelectCycles"; import SelectLabels from "./SelectLabels"; import SelectProject from "./SelectProject"; import SelectPriority from "./SelectPriority"; import SelectAssignee from "./SelectAssignee"; import SelectParent from "./SelectParentIssue"; import CreateUpdateStateModal from "components/project/issues/BoardView/state/CreateUpdateStateModal"; import CreateUpdateCycleModal from "components/project/cycles/CreateUpdateCyclesModal"; // types import type { IIssue, IssueResponse, CycleIssueResponse } from "types"; import { EllipsisHorizontalIcon } from "@heroicons/react/24/outline"; type Props = { isOpen: boolean; setIsOpen: React.Dispatch>; projectId?: string; data?: IIssue; prePopulateData?: Partial; isUpdatingSingleIssue?: boolean; }; const defaultValues: Partial = { project: "", name: "", // description: "", state: "", sprints: null, priority: null, labels_list: [], }; const CreateUpdateIssuesModal: React.FC = ({ isOpen, setIsOpen, data, projectId, prePopulateData, isUpdatingSingleIssue = false, }) => { const [isCycleModalOpen, setIsCycleModalOpen] = useState(false); const [isStateModalOpen, setIsStateModalOpen] = useState(false); const [parentIssueListModalOpen, setParentIssueListModalOpen] = useState(false); const [mostSimilarIssue, setMostSimilarIssue] = useState(); // const [issueDescriptionValue, setIssueDescriptionValue] = useState(""); // const handleDescriptionChange: any = (value: any) => { // console.log(value); // setIssueDescriptionValue(value); // }; const RichTextEditor = dynamic(() => import("components/lexical/editor"), { ssr: false, }); const router = useRouter(); const handleClose = () => { setIsOpen(false); if (data) { resetForm(); } }; const { activeWorkspace, activeProject, user, issues } = useUser(); const { setToastAlert } = useToast(); const { register, formState: { errors, isSubmitting }, handleSubmit, reset, setError, control, watch, } = useForm({ defaultValues, }); const resetForm = () => { const timeout = setTimeout(() => { reset(defaultValues); clearTimeout(timeout); }, 500); }; const addIssueToSprint = async (issueId: string, sprintId: string, issueDetail: IIssue) => { if (!activeWorkspace || !activeProject) return; await issuesServices .addIssueToSprint(activeWorkspace.slug, activeProject.id, sprintId, { issue: issueId, }) .then((res) => { mutate( CYCLE_ISSUES(sprintId), (prevData) => { const targetResponse = prevData?.find((t) => t.cycle === sprintId); if (targetResponse) { targetResponse.issue_details = issueDetail; return prevData; } else { return [ ...(prevData ?? []), { cycle: sprintId, issue_details: issueDetail, } as CycleIssueResponse, ]; } }, false ); if (isUpdatingSingleIssue) { mutate( PROJECT_ISSUES_DETAILS, (prevData) => ({ ...(prevData as IIssue), sprints: sprintId }), false ); } else mutate( PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id), (prevData) => { return { ...(prevData as IssueResponse), results: (prevData?.results ?? []).map((issue) => { if (issue.id === res.id) return { ...issue, sprints: sprintId }; return issue; }), }; }, false ); setToastAlert({ title: "Success", type: "success", message: "Issue added to cycle successfully", }); }) .catch((err) => { console.log(err); }); }; const onSubmit = async (formData: IIssue) => { if (!activeWorkspace || !activeProject) return; const payload: Partial = { ...formData, target_date: formData.target_date ? renderDateFormat(formData.target_date ?? "") : null, }; if (!data) { await issuesServices .createIssues(activeWorkspace.slug, activeProject.id, payload) .then(async (res) => { console.log(res); mutate(PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id)); if (formData.sprints && formData.sprints !== null) { await addIssueToSprint(res.id, formData.sprints, formData); } handleClose(); resetForm(); setToastAlert({ title: "Success", type: "success", message: `Issue ${data ? "updated" : "created"} successfully`, }); if (formData.assignees_list.some((assignee) => assignee === user?.id)) { mutate(USER_ISSUE); } }) .catch((err) => { Object.keys(err).map((key) => { setError(key as keyof IIssue, { message: err[key].join(", ") }); }); }); } else { await issuesServices .updateIssue(activeWorkspace.slug, activeProject.id, data.id, payload) .then(async (res) => { console.log(res); if (isUpdatingSingleIssue) { mutate(PROJECT_ISSUES_DETAILS, (prevData) => ({ ...prevData, ...res }), false); } else mutate( PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id), (prevData) => { return { ...(prevData as IssueResponse), results: (prevData?.results ?? []).map((issue) => { if (issue.id === res.id) return { ...issue, ...res }; return issue; }), }; }, false ); if (formData.sprints && formData.sprints !== null) { await addIssueToSprint(res.id, formData.sprints, formData); } handleClose(); resetForm(); setToastAlert({ title: "Success", type: "success", message: "Issue updated successfully", }); }) .catch((err) => { Object.keys(err).map((key) => { setError(key as keyof IIssue, { message: err[key].join(", ") }); }); }); } }; useEffect(() => { if (data) setIsOpen(true); }, [data, setIsOpen]); useEffect(() => { reset({ ...defaultValues, ...watch(), ...data, project: activeProject?.id ?? projectId, ...prePopulateData, }); }, [data, prePopulateData, reset, projectId, activeProject, isOpen, watch]); useEffect(() => { return () => setMostSimilarIssue(undefined); }, []); // console.log(watch("parent")); return ( <> {activeProject && ( <> setIsStateModalOpen(false)} projectId={activeProject?.id} /> )}

{data ? "Update" : "Create"} Issue