plane/web/components/issues/peek-overview/root.tsx
Aaryan Khandelwal 539c7a3455 refactor: issue peek overview (#3001)
* refactor: peek overview components

* fix: issue reactions

* chore: update comment types

* fix: access sepcifier value

* chore: remove unused vars

* fix: build errors

* build-error: build error resolved

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
2023-12-07 19:59:35 +05:30

171 lines
5.8 KiB
TypeScript

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 } from "types";
// constants
import { EUserWorkspaceRoles } from "constants/workspace";
interface IIssuePeekOverview {
workspaceSlug: string;
projectId: string;
issueId: string;
handleIssue: (issue: Partial<IIssue>) => void;
isArchived?: boolean;
children?: ReactNode;
}
export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
const { workspaceSlug, projectId, issueId, handleIssue, children, isArchived = false } = props;
const router = useRouter();
const { peekIssueId } = router.query;
const {
user: { currentProjectRole },
issue: { removeIssueFromStructure },
issueDetail: {
createIssueComment,
updateIssueComment,
removeIssueComment,
creationIssueCommentReaction,
removeIssueCommentReaction,
createIssueReaction,
removeIssueReaction,
createIssueSubscription,
removeIssueSubscription,
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<HTMLButtonElement>) => {
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<IIssue>) => {
if (handleIssue) {
await handleIssue(_data);
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 handleDeleteIssue = async () => {
if (isArchived) await deleteArchivedIssue(workspaceSlug, projectId, issue!);
else removeIssueFromStructure(workspaceSlug, projectId, issue!);
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 (
<Fragment>
<IssueView
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
issue={issue}
isLoading={isLoading}
isArchived={isArchived}
handleCopyText={handleCopyText}
redirectToIssueDetail={redirectToIssueDetail}
issueUpdate={issueUpdate}
issueReactionCreate={issueReactionCreate}
issueReactionRemove={issueReactionRemove}
issueCommentCreate={issueCommentCreate}
issueCommentUpdate={issueCommentUpdate}
issueCommentRemove={issueCommentRemove}
issueCommentReactionCreate={issueCommentReactionCreate}
issueCommentReactionRemove={issueCommentReactionRemove}
issueSubscriptionCreate={issueSubscriptionCreate}
issueSubscriptionRemove={issueSubscriptionRemove}
handleDeleteIssue={handleDeleteIssue}
disableUserActions={[5, 10].includes(userRole)}
showCommentAccessSpecifier={currentProjectDetails?.is_deployed}
>
{children}
</IssueView>
</Fragment>
);
});