plane/web/components/issues/peek-overview/issue-attachments.tsx
2024-03-19 20:08:35 +05:30

112 lines
3.8 KiB
TypeScript

import { useMemo } from "react";
// hooks
import { TOAST_TYPE, setPromiseToast, setToast } from "@plane/ui";
import { IssueAttachmentUpload, IssueAttachmentsList, TAttachmentOperations } from "@/components/issues";
import { useEventTracker, useIssueDetail } from "@/hooks/store";
// components
// ui
type Props = {
disabled: boolean;
issueId: string;
projectId: string;
workspaceSlug: string;
};
export const PeekOverviewIssueAttachments: React.FC<Props> = (props) => {
const { disabled, issueId, projectId, workspaceSlug } = props;
// store hooks
const { captureIssueEvent } = useEventTracker();
const {
attachment: { createAttachment, removeAttachment },
} = useIssueDetail();
const handleAttachmentOperations: TAttachmentOperations = useMemo(
() => ({
create: async (data: FormData) => {
try {
const attachmentUploadPromise = createAttachment(workspaceSlug, projectId, issueId, data);
setPromiseToast(attachmentUploadPromise, {
loading: "Uploading attachment...",
success: {
title: "Attachment uploaded",
message: () => "The attachment has been successfully uploaded",
},
error: {
title: "Attachment not uploaded",
message: () => "The attachment could not be uploaded",
},
});
const res = await attachmentUploadPromise;
captureIssueEvent({
eventName: "Issue attachment added",
payload: { id: issueId, state: "SUCCESS", element: "Issue detail page" },
updates: {
changed_property: "attachment",
change_details: res.id,
},
});
} catch (error) {
captureIssueEvent({
eventName: "Issue attachment added",
payload: { id: issueId, state: "FAILED", element: "Issue detail page" },
});
}
},
remove: async (attachmentId: string) => {
try {
if (!workspaceSlug || !projectId || !issueId) throw new Error("Missing required fields");
await removeAttachment(workspaceSlug, projectId, issueId, attachmentId);
setToast({
message: "The attachment has been successfully removed",
type: TOAST_TYPE.SUCCESS,
title: "Attachment removed",
});
captureIssueEvent({
eventName: "Issue attachment deleted",
payload: { id: issueId, state: "SUCCESS", element: "Issue detail page" },
updates: {
changed_property: "attachment",
change_details: "",
},
});
} catch (error) {
captureIssueEvent({
eventName: "Issue attachment deleted",
payload: { id: issueId, state: "FAILED", element: "Issue detail page" },
updates: {
changed_property: "attachment",
change_details: "",
},
});
setToast({
message: "The Attachment could not be removed",
type: TOAST_TYPE.ERROR,
title: "Attachment not removed",
});
}
},
}),
[workspaceSlug, projectId, issueId, captureIssueEvent, createAttachment, removeAttachment]
);
return (
<div>
<h6 className="text-sm font-medium">Attachments</h6>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-2 mt-3">
<IssueAttachmentUpload
workspaceSlug={workspaceSlug}
disabled={disabled}
handleAttachmentOperations={handleAttachmentOperations}
/>
<IssueAttachmentsList
issueId={issueId}
disabled={disabled}
handleAttachmentOperations={handleAttachmentOperations}
/>
</div>
</div>
);
};