From 32d08570e7172e4ac8e3be5222a500988afc7381 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:33:58 +0530 Subject: [PATCH] chore: peek overview for issue view and my issue view (#2172) * chore: peak overview for issue view and my issue view * fix: profile issue peak overview mutation fix * chore: code refactor * fix: image prefix url fix --- space/components/accounts/sign-in.tsx | 2 +- space/pages/onboarding/index.tsx | 2 +- web/components/core/views/all-views.tsx | 16 +- .../core/views/board-view/all-boards.tsx | 34 +++++ .../core/views/board-view/single-board.tsx | 5 +- .../core/views/board-view/single-issue.tsx | 40 +++-- .../core/views/calendar-view/calendar.tsx | 140 ++++++++++-------- .../core/views/calendar-view/single-issue.tsx | 46 +++--- .../core/views/gantt-chart-view/index.tsx | 14 +- web/components/core/views/issues-view.tsx | 3 +- .../core/views/list-view/all-lists.tsx | 33 +++++ .../core/views/list-view/single-issue.tsx | 48 ++++-- .../core/views/list-view/single-list.tsx | 3 + .../gantt-chart/cycle-issues-layout.tsx | 50 ++++--- web/components/issues/form.tsx | 9 +- web/components/issues/gantt-chart/blocks.tsx | 24 ++- web/components/issues/gantt-chart/layout.tsx | 50 ++++--- .../issues/my-issues/my-issues-view.tsx | 2 +- .../gantt-chart/module-issues-layout.tsx | 50 ++++--- web/components/views/gantt-chart.tsx | 48 +++--- web/hooks/use-calendar-issues-view.tsx | 15 +- 21 files changed, 417 insertions(+), 217 deletions(-) diff --git a/space/components/accounts/sign-in.tsx b/space/components/accounts/sign-in.tsx index ed55f7697..d2f1a1206 100644 --- a/space/components/accounts/sign-in.tsx +++ b/space/components/accounts/sign-in.tsx @@ -13,7 +13,7 @@ import useToast from "hooks/use-toast"; // components import { EmailPasswordForm, GithubLoginButton, GoogleLoginButton, EmailCodeForm } from "components/accounts"; // images -const imagePrefix = process.env.NEXT_PUBLIC_DEPLOY_WITH_NGINX ? "/spaces/" : ""; +const imagePrefix = process.env.NEXT_PUBLIC_DEPLOY_WITH_NGINX ? "/spaces" : ""; export const SignInView = observer(() => { const { user: userStore } = useMobxStore(); diff --git a/space/pages/onboarding/index.tsx b/space/pages/onboarding/index.tsx index e7ed35222..491146410 100644 --- a/space/pages/onboarding/index.tsx +++ b/space/pages/onboarding/index.tsx @@ -5,7 +5,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; // components import { OnBoardingForm } from "components/accounts/onboarding-form"; -const imagePrefix = process.env.NEXT_PUBLIC_DEPLOY_WITH_NGINX ? "/spaces/" : ""; +const imagePrefix = process.env.NEXT_PUBLIC_DEPLOY_WITH_NGINX ? "/spaces" : ""; const OnBoardingPage = () => { const { user: userStore } = useMobxStore(); diff --git a/web/components/core/views/all-views.tsx b/web/components/core/views/all-views.tsx index 3b95ed863..750c1a552 100644 --- a/web/components/core/views/all-views.tsx +++ b/web/components/core/views/all-views.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import React, { useCallback, useState } from "react"; import { useRouter } from "next/router"; @@ -77,6 +77,8 @@ export const AllViews: React.FC = ({ const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId } = router.query; + const [myIssueProjectId, setMyIssueProjectId] = useState(null); + const { user } = useUser(); const { memberRole } = useProjectMyMembership(); @@ -90,6 +92,10 @@ export const AllViews: React.FC = ({ ); const states = getStatesList(stateGroups); + const handleMyIssueOpen = (issue: IIssue) => { + setMyIssueProjectId(issue.project); + }; + const handleTrashBox = useCallback( (isDragging: boolean) => { if (isDragging && !trashBox) setTrashBox(true); @@ -128,6 +134,8 @@ export const AllViews: React.FC = ({ handleIssueAction={handleIssueAction} openIssuesListModal={cycleId || moduleId ? openIssuesListModal : null} removeIssue={removeIssue} + myIssueProjectId={myIssueProjectId} + handleMyIssueOpen={handleMyIssueOpen} disableUserActions={disableUserActions} disableAddIssueOption={disableAddIssueOption} user={user} @@ -143,6 +151,8 @@ export const AllViews: React.FC = ({ handleIssueAction={handleIssueAction} handleTrashBox={handleTrashBox} openIssuesListModal={cycleId || moduleId ? openIssuesListModal : null} + myIssueProjectId={myIssueProjectId} + handleMyIssueOpen={handleMyIssueOpen} removeIssue={removeIssue} states={states} user={user} @@ -166,7 +176,9 @@ export const AllViews: React.FC = ({ userAuth={memberRole} /> ) : ( - displayFilters?.layout === "gantt_chart" && + displayFilters?.layout === "gantt_chart" && ( + + ) )} ) : router.pathname.includes("archived-issues") ? ( diff --git a/web/components/core/views/board-view/all-boards.tsx b/web/components/core/views/board-view/all-boards.tsx index 0d5a4534e..ca0dd59a2 100644 --- a/web/components/core/views/board-view/all-boards.tsx +++ b/web/components/core/views/board-view/all-boards.tsx @@ -1,5 +1,12 @@ +import { useRouter } from "next/router"; + +//hook +import useMyIssues from "hooks/my-issues/use-my-issues"; +import useIssuesView from "hooks/use-issues-view"; +import useProfileIssues from "hooks/use-profile-issues"; // components import { SingleBoard } from "components/core/views/board-view/single-board"; +import { IssuePeekOverview } from "components/issues"; // icons import { StateGroupIcon } from "components/icons"; // helpers @@ -16,6 +23,8 @@ type Props = { handleTrashBox: (isDragging: boolean) => void; openIssuesListModal?: (() => void) | null; removeIssue: ((bridgeId: string, issueId: string) => void) | null; + myIssueProjectId?: string | null; + handleMyIssueOpen?: (issue: IIssue) => void; states: IState[] | undefined; user: ICurrentUserResponse | undefined; userAuth: UserAuth; @@ -30,16 +39,40 @@ export const AllBoards: React.FC = ({ handleIssueAction, handleTrashBox, openIssuesListModal, + myIssueProjectId, + handleMyIssueOpen, removeIssue, states, user, userAuth, viewProps, }) => { + const router = useRouter(); + const { workspaceSlug, projectId, userId } = router.query; + + const isProfileIssue = + router.pathname.includes("assigned") || + router.pathname.includes("created") || + router.pathname.includes("subscribed"); + + const isMyIssue = router.pathname.includes("my-issues"); + + const { mutateIssues } = useIssuesView(); + const { mutateMyIssues } = useMyIssues(workspaceSlug?.toString()); + const { mutateProfileIssues } = useProfileIssues(workspaceSlug?.toString(), userId?.toString()); + const { displayFilters, groupedIssues } = viewProps; return ( <> + + isMyIssue ? mutateMyIssues() : isProfileIssue ? mutateProfileIssues() : mutateIssues() + } + projectId={myIssueProjectId ? myIssueProjectId : projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} + /> {groupedIssues ? (
{Object.keys(groupedIssues).map((singleGroup, index) => { @@ -63,6 +96,7 @@ export const AllBoards: React.FC = ({ handleIssueAction={handleIssueAction} handleTrashBox={handleTrashBox} openIssuesListModal={openIssuesListModal ?? null} + handleMyIssueOpen={handleMyIssueOpen} removeIssue={removeIssue} user={user} userAuth={userAuth} diff --git a/web/components/core/views/board-view/single-board.tsx b/web/components/core/views/board-view/single-board.tsx index fcc3a56bf..5b87f8aba 100644 --- a/web/components/core/views/board-view/single-board.tsx +++ b/web/components/core/views/board-view/single-board.tsx @@ -26,6 +26,7 @@ type Props = { handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; handleTrashBox: (isDragging: boolean) => void; openIssuesListModal?: (() => void) | null; + handleMyIssueOpen?: (issue: IIssue) => void; removeIssue: ((bridgeId: string, issueId: string) => void) | null; user: ICurrentUserResponse | undefined; userAuth: UserAuth; @@ -42,6 +43,7 @@ export const SingleBoard: React.FC = ({ handleIssueAction, handleTrashBox, openIssuesListModal, + handleMyIssueOpen, removeIssue, user, userAuth, @@ -50,7 +52,7 @@ export const SingleBoard: React.FC = ({ // collapse/expand const [isCollapsed, setIsCollapsed] = useState(true); - const { displayFilters, groupedIssues, properties } = viewProps; + const { displayFilters, groupedIssues } = viewProps; const router = useRouter(); const { cycleId, moduleId } = router.query; @@ -135,6 +137,7 @@ export const SingleBoard: React.FC = ({ makeIssueCopy={() => handleIssueAction(issue, "copy")} handleDeleteIssue={() => handleIssueAction(issue, "delete")} handleTrashBox={handleTrashBox} + handleMyIssueOpen={handleMyIssueOpen} removeIssue={() => { if (removeIssue && issue.bridge_id) removeIssue(issue.bridge_id, issue.id); diff --git a/web/components/core/views/board-view/single-issue.tsx b/web/components/core/views/board-view/single-issue.tsx index dc750babe..ffd4747d9 100644 --- a/web/components/core/views/board-view/single-issue.tsx +++ b/web/components/core/views/board-view/single-issue.tsx @@ -1,6 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; -import Link from "next/link"; import { useRouter } from "next/router"; import { mutate } from "swr"; @@ -58,6 +57,7 @@ type Props = { index: number; editIssue: () => void; makeIssueCopy: () => void; + handleMyIssueOpen?: (issue: IIssue) => void; removeIssue?: (() => void) | null; handleDeleteIssue: (issue: IIssue) => void; handleTrashBox: (isDragging: boolean) => void; @@ -75,6 +75,7 @@ export const SingleBoardIssue: React.FC = ({ index, editIssue, makeIssueCopy, + handleMyIssueOpen, removeIssue, groupTitle, handleDeleteIssue, @@ -187,6 +188,17 @@ export const SingleBoardIssue: React.FC = ({ useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false)); + const openPeekOverview = () => { + const { query } = router; + + if (handleMyIssueOpen) handleMyIssueOpen(issue); + + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: issue.id }, + }); + }; + const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions; return ( @@ -286,16 +298,22 @@ export const SingleBoardIssue: React.FC = ({ )}
)} - - - {properties.key && ( -
- {issue.project_detail.identifier}-{issue.sequence_id} -
- )} -
{issue.name}
-
- + +
+ {properties.key && ( +
+ {issue.project_detail.identifier}-{issue.sequence_id} +
+ )} + +
+
= ({ const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; - const { calendarIssues, params, displayFilters, setDisplayFilters } = useCalendarIssuesView(); + const { calendarIssues, mutateIssues, params, displayFilters, setDisplayFilters } = + useCalendarIssuesView(); const totalDate = eachDayOfInterval({ start: calendarDates.startDate, @@ -170,75 +172,85 @@ export const CalendarView: React.FC = ({ const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions; - return calendarIssues ? ( -
- -
- + return ( + <> + mutateIssues()} + projectId={projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} + /> + {calendarIssues ? ( +
+ +
+ -
- {weeks.map((date, index) => (
- - {isMonthlyView - ? formatDate(date, "eee").substring(0, 3) - : formatDate(date, "eee")} - - {!isMonthlyView && {formatDate(date, "d")}} + {weeks.map((date, index) => ( +
+ + {isMonthlyView + ? formatDate(date, "eee").substring(0, 3) + : formatDate(date, "eee")} + + {!isMonthlyView && {formatDate(date, "d")}} +
+ ))}
- ))} -
-
- {currentViewDaysData.map((date, index) => ( - - ))} -
+
+ {currentViewDaysData.map((date, index) => ( + + ))} +
+
+
- -
- ) : ( -
- -
+ ) : ( +
+ +
+ )} + ); }; diff --git a/web/components/core/views/calendar-view/single-issue.tsx b/web/components/core/views/calendar-view/single-issue.tsx index f6c1cc2f7..3db571c99 100644 --- a/web/components/core/views/calendar-view/single-issue.tsx +++ b/web/components/core/views/calendar-view/single-issue.tsx @@ -1,6 +1,5 @@ import React, { useCallback } from "react"; -import Link from "next/link"; import { useRouter } from "next/router"; import { mutate } from "swr"; @@ -158,6 +157,15 @@ export const SingleCalendarIssue: React.FC = ({ ? Object.values(properties).some((value) => value === true) : false; + const openPeekOverview = () => { + const { query } = router; + + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: issue.id }, + }); + }; + return (
= ({
)} - - - {properties.key && ( - - - {issue.project_detail?.identifier}-{issue.sequence_id} - - - )} - - {truncateText(issue.name, 25)} + + + {displayProperties && (
{properties.priority && ( diff --git a/web/components/core/views/gantt-chart-view/index.tsx b/web/components/core/views/gantt-chart-view/index.tsx index a881cb7aa..2cd10f95f 100644 --- a/web/components/core/views/gantt-chart-view/index.tsx +++ b/web/components/core/views/gantt-chart-view/index.tsx @@ -6,20 +6,24 @@ import { IssueGanttChartView } from "components/issues"; import { ModuleIssuesGanttChartView } from "components/modules"; import { ViewIssuesGanttChartView } from "components/views"; -export const GanttChartView = () => { +type Props = { + disableUserActions: boolean; +}; + +export const GanttChartView: React.FC = ({ disableUserActions }) => { const router = useRouter(); const { cycleId, moduleId, viewId } = router.query; return ( <> {cycleId ? ( - + ) : moduleId ? ( - + ) : viewId ? ( - + ) : ( - + )} ); diff --git a/web/components/core/views/issues-view.tsx b/web/components/core/views/issues-view.tsx index b4dd665dd..e0e7e8c94 100644 --- a/web/components/core/views/issues-view.tsx +++ b/web/components/core/views/issues-view.tsx @@ -19,7 +19,7 @@ import useIssuesProperties from "hooks/use-issue-properties"; import useProjectMembers from "hooks/use-project-members"; // components import { FiltersList, AllViews } from "components/core"; -import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; +import { CreateUpdateIssueModal, DeleteIssueModal, IssuePeekOverview } from "components/issues"; import { CreateUpdateViewModal } from "components/views"; // ui import { PrimaryButton, SecondaryButton } from "components/ui"; @@ -462,6 +462,7 @@ export const IssuesView: React.FC = ({ data={issueToDelete} user={user} /> + {areFiltersApplied && ( <>
diff --git a/web/components/core/views/list-view/all-lists.tsx b/web/components/core/views/list-view/all-lists.tsx index 282e27755..bb0a7c0fb 100644 --- a/web/components/core/views/list-view/all-lists.tsx +++ b/web/components/core/views/list-view/all-lists.tsx @@ -1,5 +1,12 @@ +import { useRouter } from "next/router"; + +// hooks +import useMyIssues from "hooks/my-issues/use-my-issues"; +import useIssuesView from "hooks/use-issues-view"; +import useProfileIssues from "hooks/use-profile-issues"; // components import { SingleList } from "components/core/views/list-view/single-list"; +import { IssuePeekOverview } from "components/issues"; // types import { ICurrentUserResponse, IIssue, IIssueViewProps, IState, UserAuth } from "types"; @@ -9,6 +16,8 @@ type Props = { addIssueToGroup: (groupTitle: string) => void; handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; openIssuesListModal?: (() => void) | null; + myIssueProjectId?: string | null; + handleMyIssueOpen?: (issue: IIssue) => void; removeIssue: ((bridgeId: string, issueId: string) => void) | null; disableUserActions: boolean; disableAddIssueOption?: boolean; @@ -23,16 +32,39 @@ export const AllLists: React.FC = ({ disableUserActions, disableAddIssueOption = false, openIssuesListModal, + handleMyIssueOpen, + myIssueProjectId, removeIssue, states, user, userAuth, viewProps, }) => { + const router = useRouter(); + const { workspaceSlug, projectId, userId } = router.query; + + const isProfileIssue = + router.pathname.includes("assigned") || + router.pathname.includes("created") || + router.pathname.includes("subscribed"); + + const isMyIssue = router.pathname.includes("my-issues"); + const { mutateIssues } = useIssuesView(); + const { mutateMyIssues } = useMyIssues(workspaceSlug?.toString()); + const { mutateProfileIssues } = useProfileIssues(workspaceSlug?.toString(), userId?.toString()); + const { displayFilters, groupedIssues } = viewProps; return ( <> + + isMyIssue ? mutateMyIssues() : isProfileIssue ? mutateProfileIssues() : mutateIssues() + } + projectId={myIssueProjectId ? myIssueProjectId : projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} + /> {groupedIssues && (
{Object.keys(groupedIssues).map((singleGroup) => { @@ -51,6 +83,7 @@ export const AllLists: React.FC = ({ currentState={currentState} addIssueToGroup={() => addIssueToGroup(singleGroup)} handleIssueAction={handleIssueAction} + handleMyIssueOpen={handleMyIssueOpen} openIssuesListModal={openIssuesListModal} removeIssue={removeIssue} disableUserActions={disableUserActions} diff --git a/web/components/core/views/list-view/single-issue.tsx b/web/components/core/views/list-view/single-issue.tsx index 1e5d551c3..ab5c080ca 100644 --- a/web/components/core/views/list-view/single-issue.tsx +++ b/web/components/core/views/list-view/single-issue.tsx @@ -61,6 +61,7 @@ type Props = { makeIssueCopy: () => void; removeIssue?: (() => void) | null; handleDeleteIssue: (issue: IIssue) => void; + handleMyIssueOpen?: (issue: IIssue) => void; disableUserActions: boolean; user: ICurrentUserResponse | undefined; userAuth: UserAuth; @@ -76,6 +77,7 @@ export const SingleListIssue: React.FC = ({ removeIssue, groupTitle, handleDeleteIssue, + handleMyIssueOpen, disableUserActions, user, userAuth, @@ -178,6 +180,16 @@ export const SingleListIssue: React.FC = ({ ? `/${workspaceSlug}/projects/${issue.project}/archived-issues/${issue.id}` : `/${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`; + const openPeekOverview = (issue: IIssue) => { + const { query } = router; + + if (handleMyIssueOpen) handleMyIssueOpen(issue); + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: issue.id }, + }); + }; + const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions || isArchivedIssues; @@ -220,23 +232,27 @@ export const SingleListIssue: React.FC = ({ }} >
void; handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; openIssuesListModal?: (() => void) | null; + handleMyIssueOpen?: (issue: IIssue) => void; removeIssue: ((bridgeId: string, issueId: string) => void) | null; disableUserActions: boolean; disableAddIssueOption?: boolean; @@ -55,6 +56,7 @@ export const SingleList: React.FC = ({ addIssueToGroup, handleIssueAction, openIssuesListModal, + handleMyIssueOpen, removeIssue, disableUserActions, disableAddIssueOption = false, @@ -251,6 +253,7 @@ export const SingleList: React.FC = ({ editIssue={() => handleIssueAction(issue, "edit")} makeIssueCopy={() => handleIssueAction(issue, "copy")} handleDeleteIssue={() => handleIssueAction(issue, "delete")} + handleMyIssueOpen={handleMyIssueOpen} removeIssue={() => { if (removeIssue !== null && issue.bridge_id) removeIssue(issue.bridge_id, issue.id); diff --git a/web/components/cycles/gantt-chart/cycle-issues-layout.tsx b/web/components/cycles/gantt-chart/cycle-issues-layout.tsx index 1c78da096..b70b16f03 100644 --- a/web/components/cycles/gantt-chart/cycle-issues-layout.tsx +++ b/web/components/cycles/gantt-chart/cycle-issues-layout.tsx @@ -8,11 +8,15 @@ import { updateGanttIssue } from "components/gantt-chart/hooks/block-update"; import useProjectDetails from "hooks/use-project-details"; // components import { GanttChartRoot, renderIssueBlocksStructure } from "components/gantt-chart"; -import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; +import { IssueGanttBlock, IssueGanttSidebarBlock, IssuePeekOverview } from "components/issues"; // types import { IIssue } from "types"; -export const CycleIssuesGanttChartView = () => { +type Props = { + disableUserActions: boolean; +}; + +export const CycleIssuesGanttChartView: React.FC = ({ disableUserActions }) => { const router = useRouter(); const { workspaceSlug, projectId, cycleId } = router.query; @@ -30,23 +34,31 @@ export const CycleIssuesGanttChartView = () => { const isAllowed = projectDetails?.member_role === 20 || projectDetails?.member_role === 15; return ( -
- - updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) - } - SidebarBlockRender={IssueGanttSidebarBlock} - BlockRender={IssueGanttBlock} - enableBlockLeftResize={isAllowed} - enableBlockRightResize={isAllowed} - enableBlockMove={isAllowed} - enableReorder={displayFilters.order_by === "sort_order" && isAllowed} - bottomSpacing + <> + mutateGanttIssues()} + projectId={projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} /> -
+
+ + updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) + } + SidebarBlockRender={IssueGanttSidebarBlock} + BlockRender={IssueGanttBlock} + enableBlockLeftResize={isAllowed} + enableBlockRightResize={isAllowed} + enableBlockMove={isAllowed} + enableReorder={displayFilters.order_by === "sort_order" && isAllowed} + bottomSpacing + /> +
+ ); }; diff --git a/web/components/issues/form.tsx b/web/components/issues/form.tsx index 177155f10..ae8a01896 100644 --- a/web/components/issues/form.tsx +++ b/web/components/issues/form.tsx @@ -23,14 +23,7 @@ import { import { CreateStateModal } from "components/states"; import { CreateLabelModal } from "components/labels"; // ui -import { - CustomMenu, - Input, - Loader, - PrimaryButton, - SecondaryButton, - ToggleSwitch, -} from "components/ui"; +import { CustomMenu, Input, PrimaryButton, SecondaryButton, ToggleSwitch } from "components/ui"; import { TipTapEditor } from "components/tiptap"; // icons import { SparklesIcon, XMarkIcon } from "@heroicons/react/24/outline"; diff --git a/web/components/issues/gantt-chart/blocks.tsx b/web/components/issues/gantt-chart/blocks.tsx index 0834e3e79..ef4919780 100644 --- a/web/components/issues/gantt-chart/blocks.tsx +++ b/web/components/issues/gantt-chart/blocks.tsx @@ -11,13 +11,21 @@ import { IIssue } from "types"; export const IssueGanttBlock = ({ data }: { data: IIssue }) => { const router = useRouter(); - const { workspaceSlug } = router.query; + + const openPeekOverview = () => { + const { query } = router; + + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: data.id }, + }); + }; return (
router.push(`/${workspaceSlug}/projects/${data?.project}/issues/${data?.id}`)} + onClick={openPeekOverview} >
{ // rendering issues on gantt sidebar export const IssueGanttSidebarBlock = ({ data }: { data: IIssue }) => { const router = useRouter(); - const { workspaceSlug } = router.query; const duration = findTotalDaysInRange(data?.start_date ?? "", data?.target_date ?? "", true); + const openPeekOverview = () => { + const { query } = router; + + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: data.id }, + }); + }; + return (
router.push(`/${workspaceSlug}/projects/${data?.project}/issues/${data?.id}`)} + onClick={openPeekOverview} >
diff --git a/web/components/issues/gantt-chart/layout.tsx b/web/components/issues/gantt-chart/layout.tsx index a78319a4b..ed4cd3d70 100644 --- a/web/components/issues/gantt-chart/layout.tsx +++ b/web/components/issues/gantt-chart/layout.tsx @@ -8,11 +8,15 @@ import { updateGanttIssue } from "components/gantt-chart/hooks/block-update"; import useProjectDetails from "hooks/use-project-details"; // components import { GanttChartRoot, renderIssueBlocksStructure } from "components/gantt-chart"; -import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; +import { IssueGanttBlock, IssueGanttSidebarBlock, IssuePeekOverview } from "components/issues"; // types import { IIssue } from "types"; -export const IssueGanttChartView = () => { +type Props = { + disableUserActions: boolean; +}; + +export const IssueGanttChartView: React.FC = ({ disableUserActions }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -29,23 +33,31 @@ export const IssueGanttChartView = () => { const isAllowed = projectDetails?.member_role === 20 || projectDetails?.member_role === 15; return ( -
- - updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) - } - BlockRender={IssueGanttBlock} - SidebarBlockRender={IssueGanttSidebarBlock} - enableBlockLeftResize={isAllowed} - enableBlockRightResize={isAllowed} - enableBlockMove={isAllowed} - enableReorder={displayFilters.order_by === "sort_order" && isAllowed} - bottomSpacing + <> + mutateGanttIssues()} + projectId={projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} /> -
+
+ + updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) + } + BlockRender={IssueGanttBlock} + SidebarBlockRender={IssueGanttSidebarBlock} + enableBlockLeftResize={isAllowed} + enableBlockRightResize={isAllowed} + enableBlockMove={isAllowed} + enableReorder={displayFilters.order_by === "sort_order" && isAllowed} + bottomSpacing + /> +
+ ); }; diff --git a/web/components/issues/my-issues/my-issues-view.tsx b/web/components/issues/my-issues/my-issues-view.tsx index 81a456079..7dc5c8d20 100644 --- a/web/components/issues/my-issues/my-issues-view.tsx +++ b/web/components/issues/my-issues/my-issues-view.tsx @@ -57,7 +57,7 @@ export const MyIssuesView: React.FC = ({ const { user } = useUserAuth(); const { groupedIssues, mutateMyIssues, isEmpty, params } = useMyIssues(workspaceSlug?.toString()); - const { filters, setFilters, displayFilters, setDisplayFilters, properties } = useMyIssuesFilters( + const { filters, setFilters, displayFilters, properties } = useMyIssuesFilters( workspaceSlug?.toString() ); diff --git a/web/components/modules/gantt-chart/module-issues-layout.tsx b/web/components/modules/gantt-chart/module-issues-layout.tsx index ca8aae527..c7bef4b26 100644 --- a/web/components/modules/gantt-chart/module-issues-layout.tsx +++ b/web/components/modules/gantt-chart/module-issues-layout.tsx @@ -1,5 +1,3 @@ -import { FC } from "react"; - import { useRouter } from "next/router"; // hooks @@ -10,13 +8,13 @@ import { updateGanttIssue } from "components/gantt-chart/hooks/block-update"; import useProjectDetails from "hooks/use-project-details"; // components import { GanttChartRoot, renderIssueBlocksStructure } from "components/gantt-chart"; -import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; +import { IssueGanttBlock, IssueGanttSidebarBlock, IssuePeekOverview } from "components/issues"; // types import { IIssue } from "types"; -type Props = {}; +type Props = { disableUserActions: boolean }; -export const ModuleIssuesGanttChartView: FC = ({}) => { +export const ModuleIssuesGanttChartView: React.FC = ({ disableUserActions }) => { const router = useRouter(); const { workspaceSlug, projectId, moduleId } = router.query; @@ -34,23 +32,31 @@ export const ModuleIssuesGanttChartView: FC = ({}) => { const isAllowed = projectDetails?.member_role === 20 || projectDetails?.member_role === 15; return ( -
- - updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) - } - SidebarBlockRender={IssueGanttSidebarBlock} - BlockRender={IssueGanttBlock} - enableBlockLeftResize={isAllowed} - enableBlockRightResize={isAllowed} - enableBlockMove={isAllowed} - enableReorder={displayFilters.order_by === "sort_order" && isAllowed} - bottomSpacing + <> + mutateGanttIssues()} + projectId={projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} /> -
+
+ + updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) + } + SidebarBlockRender={IssueGanttSidebarBlock} + BlockRender={IssueGanttBlock} + enableBlockLeftResize={isAllowed} + enableBlockRightResize={isAllowed} + enableBlockMove={isAllowed} + enableReorder={displayFilters.order_by === "sort_order" && isAllowed} + bottomSpacing + /> +
+ ); }; diff --git a/web/components/views/gantt-chart.tsx b/web/components/views/gantt-chart.tsx index b25f034cd..6f43a32e6 100644 --- a/web/components/views/gantt-chart.tsx +++ b/web/components/views/gantt-chart.tsx @@ -1,5 +1,3 @@ -import { FC } from "react"; - import { useRouter } from "next/router"; // hooks @@ -9,13 +7,13 @@ import { updateGanttIssue } from "components/gantt-chart/hooks/block-update"; import useProjectDetails from "hooks/use-project-details"; // components import { GanttChartRoot, renderIssueBlocksStructure } from "components/gantt-chart"; -import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; +import { IssueGanttBlock, IssueGanttSidebarBlock, IssuePeekOverview } from "components/issues"; // types import { IIssue } from "types"; -type Props = {}; +type Props = { disableUserActions: boolean }; -export const ViewIssuesGanttChartView: FC = ({}) => { +export const ViewIssuesGanttChartView: React.FC = ({ disableUserActions }) => { const router = useRouter(); const { workspaceSlug, projectId, viewId } = router.query; @@ -31,22 +29,30 @@ export const ViewIssuesGanttChartView: FC = ({}) => { const isAllowed = projectDetails?.member_role === 20 || projectDetails?.member_role === 15; return ( -
- - updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) - } - SidebarBlockRender={IssueGanttSidebarBlock} - BlockRender={IssueGanttBlock} - enableBlockLeftResize={isAllowed} - enableBlockRightResize={isAllowed} - enableBlockMove={isAllowed} - enableReorder={isAllowed} + <> + mutateGanttIssues()} + projectId={projectId?.toString() ?? ""} + workspaceSlug={workspaceSlug?.toString() ?? ""} + readOnly={disableUserActions} /> -
+
+ + updateGanttIssue(block, payload, mutateGanttIssues, user, workspaceSlug?.toString()) + } + SidebarBlockRender={IssueGanttSidebarBlock} + BlockRender={IssueGanttBlock} + enableBlockLeftResize={isAllowed} + enableBlockRightResize={isAllowed} + enableBlockMove={isAllowed} + enableReorder={isAllowed} + /> +
+ ); }; diff --git a/web/hooks/use-calendar-issues-view.tsx b/web/hooks/use-calendar-issues-view.tsx index 362cd741f..289aed2ac 100644 --- a/web/hooks/use-calendar-issues-view.tsx +++ b/web/hooks/use-calendar-issues-view.tsx @@ -44,7 +44,7 @@ const useCalendarIssuesView = () => { target_date: displayFilters?.calendar_date_range, }; - const { data: projectCalendarIssues } = useSWR( + const { data: projectCalendarIssues, mutate: mutateProjectCalendarIssues } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params) : null, @@ -54,7 +54,7 @@ const useCalendarIssuesView = () => { : null ); - const { data: cycleCalendarIssues } = useSWR( + const { data: cycleCalendarIssues, mutate: mutateCycleCalendarIssues } = useSWR( workspaceSlug && projectId && cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) : null, @@ -69,7 +69,7 @@ const useCalendarIssuesView = () => { : null ); - const { data: moduleCalendarIssues } = useSWR( + const { data: moduleCalendarIssues, mutate: mutateModuleCalendarIssues } = useSWR( workspaceSlug && projectId && moduleId ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) : null, @@ -84,7 +84,7 @@ const useCalendarIssuesView = () => { : null ); - const { data: viewCalendarIssues } = useSWR( + const { data: viewCalendarIssues, mutate: mutateViewCalendarIssues } = useSWR( workspaceSlug && projectId && viewId && params ? VIEW_ISSUES(viewId.toString(), params) : null, workspaceSlug && projectId && viewId && params ? () => @@ -104,6 +104,13 @@ const useCalendarIssuesView = () => { displayFilters, setDisplayFilters, calendarIssues: calendarIssues ?? [], + mutateIssues: cycleId + ? mutateCycleCalendarIssues + : moduleId + ? mutateModuleCalendarIssues + : viewId + ? mutateViewCalendarIssues + : mutateProjectCalendarIssues, filters, setFilters, params,