import { FC, Fragment, ReactNode, useCallback, useEffect } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // hooks import useToast from "hooks/use-toast"; // components import { IssueView } from "components/issues"; // helpers import { copyUrlToClipboard } from "helpers/string.helper"; // types import { IIssue, IIssueLink } from "types"; import { EIssueActions } from "../issue-layouts/types"; // constants import { EUserWorkspaceRoles } from "constants/workspace"; interface IIssuePeekOverview { workspaceSlug: string; projectId: string; issueId: string; handleIssue: (issue: Partial, action: EIssueActions) => Promise; isArchived?: boolean; children?: ReactNode; } export const IssuePeekOverview: FC = observer((props) => { const { workspaceSlug, projectId, issueId, handleIssue, children, isArchived = false } = props; const router = useRouter(); const { peekIssueId } = router.query; const { user: { currentProjectRole }, issueDetail: { createIssueComment, updateIssueComment, removeIssueComment, creationIssueCommentReaction, removeIssueCommentReaction, createIssueReaction, removeIssueReaction, createIssueSubscription, removeIssueSubscription, createIssueLink, updateIssueLink, deleteIssueLink, getIssue, loader, fetchPeekIssueDetails, setPeekId, fetchIssueActivity, }, archivedIssueDetail: { getIssue: getArchivedIssue, loader: archivedIssueLoader, fetchPeekIssueDetails: fetchArchivedPeekIssueDetails, }, archivedIssues: { deleteArchivedIssue }, project: { currentProjectDetails }, } = useMobxStore(); const { setToastAlert } = useToast(); const fetchIssueDetail = useCallback(async () => { if (workspaceSlug && projectId && peekIssueId) { if (isArchived) await fetchArchivedPeekIssueDetails(workspaceSlug, projectId, peekIssueId as string); else await fetchPeekIssueDetails(workspaceSlug, projectId, peekIssueId as string); } }, [fetchArchivedPeekIssueDetails, fetchPeekIssueDetails, workspaceSlug, projectId, peekIssueId, isArchived]); useEffect(() => { fetchIssueDetail(); }, [workspaceSlug, projectId, peekIssueId, fetchIssueDetail]); const handleCopyText = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); copyUrlToClipboard( `${workspaceSlug}/projects/${projectId}/${isArchived ? "archived-issues" : "issues"}/${peekIssueId}` ).then(() => { setToastAlert({ type: "success", title: "Link Copied!", message: "Issue link copied to clipboard.", }); }); }; const redirectToIssueDetail = () => { router.push({ pathname: `/${workspaceSlug}/projects/${projectId}/${isArchived ? "archived-issues" : "issues"}/${issueId}`, }); }; const issue = isArchived ? getArchivedIssue : getIssue; const isLoading = isArchived ? archivedIssueLoader : loader; const issueUpdate = async (_data: Partial) => { if (handleIssue) { await handleIssue(_data, EIssueActions.UPDATE); fetchIssueActivity(workspaceSlug, projectId, issueId); } }; const issueReactionCreate = (reaction: string) => createIssueReaction(workspaceSlug, projectId, issueId, reaction); const issueReactionRemove = (reaction: string) => removeIssueReaction(workspaceSlug, projectId, issueId, reaction); const issueCommentCreate = (comment: any) => createIssueComment(workspaceSlug, projectId, issueId, comment); const issueCommentUpdate = (comment: any) => updateIssueComment(workspaceSlug, projectId, issueId, comment?.id, comment); const issueCommentRemove = (commentId: string) => removeIssueComment(workspaceSlug, projectId, issueId, commentId); const issueCommentReactionCreate = (commentId: string, reaction: string) => creationIssueCommentReaction(workspaceSlug, projectId, issueId, commentId, reaction); const issueCommentReactionRemove = (commentId: string, reaction: string) => removeIssueCommentReaction(workspaceSlug, projectId, issueId, commentId, reaction); const issueSubscriptionCreate = () => createIssueSubscription(workspaceSlug, projectId, issueId); const issueSubscriptionRemove = () => removeIssueSubscription(workspaceSlug, projectId, issueId); const issueLinkCreate = (formData: IIssueLink) => createIssueLink(workspaceSlug, projectId, issueId, formData); const issueLinkUpdate = (formData: IIssueLink, linkId: string) => updateIssueLink(workspaceSlug, projectId, issueId, linkId, formData); const issueLinkDelete = (linkId: string) => deleteIssueLink(workspaceSlug, projectId, issueId, linkId); const handleDeleteIssue = async () => { if (isArchived) await deleteArchivedIssue(workspaceSlug, projectId, issue!); else await handleIssue(issue!, EIssueActions.DELETE); const { query } = router; if (query.peekIssueId) { setPeekId(null); delete query.peekIssueId; delete query.peekProjectId; router.push({ pathname: router.pathname, query: { ...query }, }); } }; const userRole = currentProjectRole ?? EUserWorkspaceRoles.GUEST; return ( {children} ); });