From 24dd718963b44590fd328fd475635ea0f9c7aa86 Mon Sep 17 00:00:00 2001 From: vamsikrishnamathala Date: Thu, 10 Jul 2025 21:42:01 +0530 Subject: [PATCH 1/2] fix: full screen mode for analytics, work items peek and timeline chart --- .../[workspaceSlug]/(projects)/layout.tsx | 1 + .../analytics/work-items/modal/index.tsx | 80 +++--- .../components/gantt-chart/chart/root.tsx | 7 +- .../components/issues/peek-overview/view.tsx | 269 +++++++++--------- 4 files changed, 179 insertions(+), 178 deletions(-) diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/layout.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/layout.tsx index 860242dc5bf..2a29a72c768 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/layout.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/layout.tsx @@ -11,6 +11,7 @@ export default function WorkspaceLayout({ children }: { children: React.ReactNod
+
diff --git a/apps/web/core/components/analytics/work-items/modal/index.tsx b/apps/web/core/components/analytics/work-items/modal/index.tsx index 292dc1be5e0..7e5f877818f 100644 --- a/apps/web/core/components/analytics/work-items/modal/index.tsx +++ b/apps/web/core/components/analytics/work-items/modal/index.tsx @@ -1,8 +1,9 @@ import React, { useEffect, useState } from "react"; import { observer } from "mobx-react"; -import { Dialog, Transition } from "@headlessui/react"; // plane package imports +import { createPortal } from "react-dom"; import { ICycle, IModule, IProject } from "@plane/types"; +import { cn } from "@plane/utils"; import { useAnalytics } from "@/hooks/store"; // plane web components import { WorkItemsModalMainContent } from "./content"; @@ -23,6 +24,7 @@ export const WorkItemsModal: React.FC = observer((props) => { const [fullScreen, setFullScreen] = useState(false); const handleClose = () => { + setFullScreen(false); onClose(); }; @@ -30,50 +32,38 @@ export const WorkItemsModal: React.FC = observer((props) => { updateIsEpic(isEpic ?? false); }, [isEpic, updateIsEpic]); - return ( - - - +
+
-
- -
-
- - -
-
-
-
- -
-
+ + +
+
+
); + + return fullScreen ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content; }); diff --git a/apps/web/core/components/gantt-chart/chart/root.tsx b/apps/web/core/components/gantt-chart/chart/root.tsx index e10a1f73e0f..b6ce2c8082b 100644 --- a/apps/web/core/components/gantt-chart/chart/root.tsx +++ b/apps/web/core/components/gantt-chart/chart/root.tsx @@ -1,4 +1,5 @@ import { FC, useEffect, useState } from "react"; +import { createPortal } from "react-dom"; import { observer } from "mobx-react"; // plane imports // components @@ -176,10 +177,10 @@ export const ChartViewRoot: FC = observer((props) => { scrollContainer.scrollLeft = scrollWidth; }; - return ( + const content = (
@@ -217,4 +218,6 @@ export const ChartViewRoot: FC = observer((props) => { />
); + + return fullScreenMode ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content; }); diff --git a/apps/web/core/components/issues/peek-overview/view.tsx b/apps/web/core/components/issues/peek-overview/view.tsx index c30a40fb54c..ad6ed384786 100644 --- a/apps/web/core/components/issues/peek-overview/view.tsx +++ b/apps/web/core/components/issues/peek-overview/view.tsx @@ -23,6 +23,7 @@ import useKeypress from "@/hooks/use-keypress"; import usePeekOverviewOutsideClickDetector from "@/hooks/use-peek-overview-outside-click"; // store hooks import { IssueActivity } from "../issue-detail/issue-activity"; +import { createPortal } from "react-dom"; interface IIssueView { workspaceSlug: string; @@ -108,15 +109,149 @@ export const IssueView: FC = observer((props) => { const peekOverviewIssueClassName = cn( !embedIssue - ? "fixed z-20 flex flex-col overflow-hidden rounded border border-custom-border-200 bg-custom-background-100 transition-all duration-300" + ? "fixed z-[25] flex flex-col overflow-hidden rounded border border-custom-border-200 bg-custom-background-100 transition-all duration-300" : `w-full h-full`, !embedIssue && { "bottom-0 right-0 top-0 w-full md:w-[50%] border-0 border-l": peekMode === "side-peek", "size-5/6 top-[8.33%] left-[8.33%]": peekMode === "modal", - "inset-0 m-4": peekMode === "full-screen", + "inset-0 m-4 absolute": peekMode === "full-screen", } ); + const shouldUsePortal = !embedIssue && peekMode === "full-screen"; + + const content = ( +
+ {issueId && ( +
+ {isError ? ( +
+ +
+ ) : ( + isLoading && + )} + {!isLoading && !isError && issue && ( + <> + {/* header */} + setPeekMode(value)} + removeRoutePeekId={removeRoutePeekId} + toggleDeleteIssueModal={toggleDeleteIssueModal} + toggleArchiveIssueModal={toggleArchiveIssueModal} + handleRestoreIssue={handleRestore} + isArchived={is_archived} + issueId={issueId} + workspaceSlug={workspaceSlug} + projectId={projectId} + isSubmitting={isSubmitting} + disabled={disabled} + embedIssue={embedIssue} + /> + {/* content */} +
+ {["side-peek", "modal"].includes(peekMode) ? ( +
+ setIsSubmitting(value)} + /> + +
+ +
+ + + + +
+ ) : ( +
+
+
+ setIsSubmitting(value)} + /> + +
+ +
+ + +
+
+
+ +
+
+ )} +
+ + )} +
+ )} +
+ ); + return ( <> {issue && !is_archived && ( @@ -142,135 +277,7 @@ export const IssueView: FC = observer((props) => { /> )} -
- {issueId && ( -
- {isError ? ( -
- -
- ) : ( - isLoading && - )} - {!isLoading && !isError && issue && ( - <> - {/* header */} - setPeekMode(value)} - removeRoutePeekId={removeRoutePeekId} - toggleDeleteIssueModal={toggleDeleteIssueModal} - toggleArchiveIssueModal={toggleArchiveIssueModal} - handleRestoreIssue={handleRestore} - isArchived={is_archived} - issueId={issueId} - workspaceSlug={workspaceSlug} - projectId={projectId} - isSubmitting={isSubmitting} - disabled={disabled} - embedIssue={embedIssue} - /> - {/* content */} -
- {["side-peek", "modal"].includes(peekMode) ? ( -
- setIsSubmitting(value)} - /> - -
- -
- - - - -
- ) : ( -
-
-
- setIsSubmitting(value)} - /> - -
- -
- - -
-
-
- -
-
- )} -
- - )} -
- )} -
+ {shouldUsePortal ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content} ); }); From 725c9a0523b621f91b885025585af5d3c24fa1dc Mon Sep 17 00:00:00 2001 From: vamsikrishnamathala Date: Fri, 11 Jul 2025 11:45:02 +0530 Subject: [PATCH 2/2] chore: added null check for portal elements --- apps/web/core/components/analytics/work-items/modal/index.tsx | 4 +++- apps/web/core/components/gantt-chart/chart/root.tsx | 4 +++- apps/web/core/components/issues/peek-overview/view.tsx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/web/core/components/analytics/work-items/modal/index.tsx b/apps/web/core/components/analytics/work-items/modal/index.tsx index 7e5f877818f..06d09aa1e9b 100644 --- a/apps/web/core/components/analytics/work-items/modal/index.tsx +++ b/apps/web/core/components/analytics/work-items/modal/index.tsx @@ -32,6 +32,8 @@ export const WorkItemsModal: React.FC = observer((props) => { updateIsEpic(isEpic ?? false); }, [isEpic, updateIsEpic]); + const portalContainer = document.getElementById("full-screen-portal") as HTMLElement; + if (!isOpen) return null; const content = ( @@ -65,5 +67,5 @@ export const WorkItemsModal: React.FC = observer((props) => { ); - return fullScreen ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content; + return fullScreen && portalContainer ? createPortal(content, portalContainer) : content; }); diff --git a/apps/web/core/components/gantt-chart/chart/root.tsx b/apps/web/core/components/gantt-chart/chart/root.tsx index b6ce2c8082b..11bc0ee5469 100644 --- a/apps/web/core/components/gantt-chart/chart/root.tsx +++ b/apps/web/core/components/gantt-chart/chart/root.tsx @@ -177,6 +177,8 @@ export const ChartViewRoot: FC = observer((props) => { scrollContainer.scrollLeft = scrollWidth; }; + const portalContainer = document.getElementById("full-screen-portal") as HTMLElement; + const content = (
= observer((props) => {
); - return fullScreenMode ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content; + return fullScreenMode && portalContainer ? createPortal(content, portalContainer) : content; }); diff --git a/apps/web/core/components/issues/peek-overview/view.tsx b/apps/web/core/components/issues/peek-overview/view.tsx index ad6ed384786..8e2c1e20072 100644 --- a/apps/web/core/components/issues/peek-overview/view.tsx +++ b/apps/web/core/components/issues/peek-overview/view.tsx @@ -120,6 +120,8 @@ export const IssueView: FC = observer((props) => { const shouldUsePortal = !embedIssue && peekMode === "full-screen"; + const portalContainer = document.getElementById("full-screen-portal") as HTMLElement; + const content = (
{issueId && ( @@ -277,7 +279,7 @@ export const IssueView: FC = observer((props) => { /> )} - {shouldUsePortal ? createPortal(content, document.getElementById("full-screen-portal") as HTMLElement) : content} + {shouldUsePortal && portalContainer ? createPortal(content, portalContainer) : content} ); });