plane/web/components/issues/peek-overview/layout.tsx
Aaryan Khandelwal daa3094911
chore: update issue detail store to handle peek overview (#2237)
* chore: dynamic position dropdown (#2138)

* chore: dynamic position state dropdown for issue view

* style: state select dropdown styling

* fix: state icon attribute names

* chore: state select dynamic dropdown

* chore: member select dynamic dropdown

* chore: label select dynamic dropdown

* chore: priority select dynamic dropdown

* chore: label select dropdown improvement

* refactor: state dropdown location

* chore: dropdown improvement and code refactor

* chore: dynamic dropdown hook type added

---------

Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>

* fix: fields not getting selected in the create issue form (#2212)

* fix: hydration error and draft issue workflow

* fix: build error

* fix: properties getting de-selected after create, module & cycle not getting auto-select on the form

* fix: display layout, props being updated directly

* chore: sub issues count in individual issue (#2221)

* Implemented nested issues in the sub issues section in issue detail page (#2233)

* feat: subissues infinte level

* feat: updated UI for sub issues

* feat: subissues new ui and nested sub issues in issue detail

* chore: removed repeated code

* refactor: product updates modal layout (#2225)

* fix: handle no issues in custom analytics (#2226)

* fix: activity label color (#2227)

* fix: profile issues layout switch (#2228)

* chore: update service imports

* chore: update issue detail store to handle peek overview

---------

Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com>
Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com>
Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com>
Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2023-09-21 17:50:43 +05:30

192 lines
6.6 KiB
TypeScript

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { mutate } from "swr";
// mobx
import { observer } from "mobx-react-lite";
import { useMobxStore } from "lib/mobx/store-provider";
// headless ui
import { Dialog, Transition } from "@headlessui/react";
// hooks
import useUser from "hooks/use-user";
// components
import { DeleteIssueModal, FullScreenPeekView, SidePeekView } from "components/issues";
// types
import { IIssue } from "types";
// fetch-keys
import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
type Props = {
handleMutation: () => void;
projectId: string;
readOnly: boolean;
workspaceSlug: string;
};
export type TPeekOverviewModes = "side" | "modal" | "full";
export const IssuePeekOverview: React.FC<Props> = observer(({ handleMutation, projectId, readOnly, workspaceSlug }) => {
const [isSidePeekOpen, setIsSidePeekOpen] = useState(false);
const [isModalPeekOpen, setIsModalPeekOpen] = useState(false);
const [peekOverviewMode, setPeekOverviewMode] = useState<TPeekOverviewModes>("side");
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
const router = useRouter();
const { peekIssue } = router.query;
const { issueDetail: issueDetailStore } = useMobxStore();
const { deleteIssue, fetchIssueDetails, issues, updateIssue } = issueDetailStore;
const issue = issues[peekIssue?.toString() ?? ""];
const { user } = useUser();
const handleClose = () => {
const { query } = router;
delete query.peekIssue;
router.push({
pathname: router.pathname,
query: { ...query },
});
};
const handleUpdateIssue = async (formData: Partial<IIssue>) => {
if (!issue || !user) return;
await updateIssue(workspaceSlug, projectId, issue.id, formData, user);
mutate(PROJECT_ISSUES_ACTIVITY(issue.id));
handleMutation();
};
const handleDeleteIssue = async () => {
if (!issue || !user) return;
await deleteIssue(workspaceSlug, projectId, issue.id, user);
handleMutation();
handleClose();
};
useEffect(() => {
if (!peekIssue) return;
fetchIssueDetails(workspaceSlug, projectId, peekIssue.toString());
}, [fetchIssueDetails, peekIssue, projectId, workspaceSlug]);
useEffect(() => {
if (peekIssue) {
if (peekOverviewMode === "side") {
setIsSidePeekOpen(true);
setIsModalPeekOpen(false);
} else {
setIsModalPeekOpen(true);
setIsSidePeekOpen(false);
}
} else {
setIsSidePeekOpen(false);
setIsModalPeekOpen(false);
}
}, [peekIssue, peekOverviewMode]);
return (
<>
<DeleteIssueModal
isOpen={deleteIssueModal}
handleClose={() => setDeleteIssueModal(false)}
data={issue ? { ...issue } : null}
onSubmit={handleDeleteIssue}
user={user}
/>
<Transition.Root appear show={isSidePeekOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={handleClose}>
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
<Transition.Child
as={React.Fragment}
enter="transition-transform duration-300"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition-transform duration-200"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="fixed z-20 bg-custom-background-100 top-0 right-0 h-full w-1/2 shadow-custom-shadow-md">
<SidePeekView
handleClose={handleClose}
handleDeleteIssue={() => setDeleteIssueModal(true)}
handleUpdateIssue={handleUpdateIssue}
issue={issue}
mode={peekOverviewMode}
readOnly={readOnly}
setMode={(mode) => setPeekOverviewMode(mode)}
workspaceSlug={workspaceSlug}
/>
</Dialog.Panel>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
<Transition.Root appear show={isModalPeekOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={handleClose}>
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-custom-backdrop bg-opacity-50 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Panel>
<div
className={`fixed z-20 bg-custom-background-100 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-lg shadow-custom-shadow-xl transition-all duration-300 ${
peekOverviewMode === "modal" ? "h-[70%] w-3/5" : "h-[95%] w-[95%]"
}`}
>
{peekOverviewMode === "modal" && (
<SidePeekView
handleClose={handleClose}
handleDeleteIssue={() => setDeleteIssueModal(true)}
handleUpdateIssue={handleUpdateIssue}
issue={issue}
mode={peekOverviewMode}
readOnly={readOnly}
setMode={(mode) => setPeekOverviewMode(mode)}
workspaceSlug={workspaceSlug}
/>
)}
{peekOverviewMode === "full" && (
<FullScreenPeekView
handleClose={handleClose}
handleDeleteIssue={() => setDeleteIssueModal(true)}
handleUpdateIssue={handleUpdateIssue}
issue={issue}
mode={peekOverviewMode}
readOnly={readOnly}
setMode={(mode) => setPeekOverviewMode(mode)}
workspaceSlug={workspaceSlug}
/>
)}
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
</>
);
});