From fed5916907621d3c4bc4ea858399cbddea971fcc Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 18:01:11 +0530 Subject: [PATCH 01/11] [WEB-848] fix: issue with parent child relation not being removed from update issue modal. (#4103) --- web/components/issues/issue-modal/form.tsx | 58 ++++++++++++---------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/web/components/issues/issue-modal/form.tsx b/web/components/issues/issue-modal/form.tsx index 6112a27fea..b581522e6e 100644 --- a/web/components/issues/issue-modal/form.tsx +++ b/web/components/issues/issue-modal/form.tsx @@ -327,32 +327,38 @@ export const IssueFormRoot: FC = observer((props) => { {watch("parent_id") && selectedParentIssue && ( -
-
- - - {selectedParentIssue.project__identifier}-{selectedParentIssue.sequence_id} - - {selectedParentIssue.name.substring(0, 50)} - -
-
+ ( +
+
+ + + {selectedParentIssue.project__identifier}-{selectedParentIssue.sequence_id} + + {selectedParentIssue.name.substring(0, 50)} + +
+
+ )} + /> )}
From 68ebcfd04ee608772d134e806cd6d62fceada080 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 18:02:07 +0530 Subject: [PATCH 02/11] [842] chore: disable comments and reactions in archived issues. (#4101) --- .../issue-activity/activity-comment-root.tsx | 4 ++- .../issue-activity/comments/comment-card.tsx | 6 ++-- .../issue-activity/comments/root.tsx | 4 ++- .../issue-detail/issue-activity/root.tsx | 29 +++++++++------- .../issues/issue-detail/main-content.tsx | 2 +- .../issue-detail/reactions/issue-comment.tsx | 33 ++++++++++++------- .../issues/issue-detail/reactions/issue.tsx | 20 +++++++---- .../issues/peek-overview/issue-detail.tsx | 1 + web/components/issues/peek-overview/view.tsx | 14 ++++++-- 9 files changed, 77 insertions(+), 36 deletions(-) diff --git a/web/components/issues/issue-detail/issue-activity/activity-comment-root.tsx b/web/components/issues/issue-detail/issue-activity/activity-comment-root.tsx index c7842a8db4..17794a618a 100644 --- a/web/components/issues/issue-detail/issue-activity/activity-comment-root.tsx +++ b/web/components/issues/issue-detail/issue-activity/activity-comment-root.tsx @@ -13,10 +13,11 @@ type TIssueActivityCommentRoot = { issueId: string; activityOperations: TActivityOperations; showAccessSpecifier?: boolean; + disabled?: boolean; }; export const IssueActivityCommentRoot: FC = observer((props) => { - const { workspaceSlug, issueId, activityOperations, showAccessSpecifier } = props; + const { workspaceSlug, issueId, activityOperations, showAccessSpecifier, disabled } = props; // hooks const { activity: { getActivityCommentByIssueId }, @@ -37,6 +38,7 @@ export const IssueActivityCommentRoot: FC = observer( activityOperations={activityOperations} ends={index === 0 ? "top" : index === activityComments.length - 1 ? "bottom" : undefined} showAccessSpecifier={showAccessSpecifier} + disabled={disabled} /> ) : activityComment.activity_type === "ACTIVITY" ? ( = (props) => { - const { workspaceSlug, commentId, activityOperations, ends, showAccessSpecifier = false } = props; + const { workspaceSlug, commentId, activityOperations, ends, showAccessSpecifier = false, disabled = false } = props; // hooks const { comment: { getCommentById }, @@ -81,7 +82,7 @@ export const IssueCommentCard: FC = (props) => { commentId={commentId} quickActions={ <> - {currentUser?.id === comment.actor && ( + {!disabled && currentUser?.id === comment.actor && ( setIsEditing(true)} className="flex items-center gap-1"> @@ -184,6 +185,7 @@ export const IssueCommentCard: FC = (props) => { projectId={comment?.project_detail?.id} commentId={comment.id} currentUser={currentUser} + disabled={disabled} />
diff --git a/web/components/issues/issue-detail/issue-activity/comments/root.tsx b/web/components/issues/issue-detail/issue-activity/comments/root.tsx index 52a500a16b..d374da8758 100644 --- a/web/components/issues/issue-detail/issue-activity/comments/root.tsx +++ b/web/components/issues/issue-detail/issue-activity/comments/root.tsx @@ -12,10 +12,11 @@ type TIssueCommentRoot = { issueId: string; activityOperations: TActivityOperations; showAccessSpecifier?: boolean; + disabled?: boolean; }; export const IssueCommentRoot: FC = observer((props) => { - const { workspaceSlug, issueId, activityOperations, showAccessSpecifier } = props; + const { workspaceSlug, issueId, activityOperations, showAccessSpecifier, disabled } = props; // hooks const { comment: { getCommentsByIssueId }, @@ -34,6 +35,7 @@ export const IssueCommentRoot: FC = observer((props) => { ends={index === 0 ? "top" : index === commentIds.length - 1 ? "bottom" : undefined} activityOperations={activityOperations} showAccessSpecifier={showAccessSpecifier} + disabled={disabled} /> ))}
diff --git a/web/components/issues/issue-detail/issue-activity/root.tsx b/web/components/issues/issue-detail/issue-activity/root.tsx index 75c8bfd4cf..1056ecf778 100644 --- a/web/components/issues/issue-detail/issue-activity/root.tsx +++ b/web/components/issues/issue-detail/issue-activity/root.tsx @@ -14,6 +14,7 @@ type TIssueActivity = { workspaceSlug: string; projectId: string; issueId: string; + disabled?: boolean; }; type TActivityTabs = "all" | "activity" | "comments"; @@ -43,7 +44,7 @@ export type TActivityOperations = { }; export const IssueActivity: FC = observer((props) => { - const { workspaceSlug, projectId, issueId } = props; + const { workspaceSlug, projectId, issueId, disabled = false } = props; // hooks const { createComment, updateComment, removeComment } = useIssueDetail(); const { getProjectById } = useProject(); @@ -145,12 +146,15 @@ export const IssueActivity: FC = observer((props) => { issueId={issueId} activityOperations={activityOperations} showAccessSpecifier={project.is_deployed} + disabled={disabled} /> - + {!disabled && ( + + )} ) : activityTab === "activity" ? ( @@ -161,12 +165,15 @@ export const IssueActivity: FC = observer((props) => { issueId={issueId} activityOperations={activityOperations} showAccessSpecifier={project.is_deployed} + disabled={disabled} /> - + {!disabled && ( + + )} )} diff --git a/web/components/issues/issue-detail/main-content.tsx b/web/components/issues/issue-detail/main-content.tsx index 50d168dcaf..241c96109a 100644 --- a/web/components/issues/issue-detail/main-content.tsx +++ b/web/components/issues/issue-detail/main-content.tsx @@ -132,7 +132,7 @@ export const IssueMainContent: React.FC = observer((props) => { disabled={!is_editable} /> - + ); }); diff --git a/web/components/issues/issue-detail/reactions/issue-comment.tsx b/web/components/issues/issue-detail/reactions/issue-comment.tsx index 2925a593d2..5461e35c43 100644 --- a/web/components/issues/issue-detail/reactions/issue-comment.tsx +++ b/web/components/issues/issue-detail/reactions/issue-comment.tsx @@ -3,10 +3,12 @@ import { observer } from "mobx-react-lite"; import { IUser } from "@plane/types"; // components import { TOAST_TYPE, Tooltip, setToast } from "@plane/ui"; +// helper +import { cn } from "@/helpers/common.helper"; import { renderEmoji } from "@/helpers/emoji.helper"; import { formatTextList } from "@/helpers/issue.helper"; +// hooks import { useIssueDetail, useMember } from "@/hooks/store"; -// helper // types import { ReactionSelector } from "./reaction-selector"; @@ -15,10 +17,11 @@ export type TIssueCommentReaction = { projectId: string; commentId: string; currentUser: IUser; + disabled?: boolean; }; export const IssueCommentReaction: FC = observer((props) => { - const { workspaceSlug, projectId, commentId, currentUser } = props; + const { workspaceSlug, projectId, commentId, currentUser, disabled = false } = props; // hooks const { @@ -88,12 +91,14 @@ export const IssueCommentReaction: FC = observer((props) return (
- + {!disabled && ( + + )} {reactionIds && Object.keys(reactionIds || {}).map( @@ -103,11 +108,15 @@ export const IssueCommentReaction: FC = observer((props)
diff --git a/web/components/issues/peek-overview/view.tsx b/web/components/issues/peek-overview/view.tsx index 35925d6cd5..0366fbb61d 100644 --- a/web/components/issues/peek-overview/view.tsx +++ b/web/components/issues/peek-overview/view.tsx @@ -177,7 +177,12 @@ export const IssueView: FC = observer((props) => { disabled={disabled || is_archived} /> - + ) : (
@@ -210,7 +215,12 @@ export const IssueView: FC = observer((props) => { workspaceSlug={workspaceSlug} /> - +
Date: Wed, 3 Apr 2024 18:03:16 +0530 Subject: [PATCH 03/11] [WEB-830] chore: project filter dropdown custom date select option improvement (#4069) * chore: project filter dropdown custom date select option improvement * fix: project filter custom date --- web/components/headers/projects.tsx | 1 + .../project/dropdowns/filters/created-at.tsx | 15 ++++++++++++++- web/helpers/date-time.helper.ts | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/web/components/headers/projects.tsx b/web/components/headers/projects.tsx index 2f502bce59..64c370d17f 100644 --- a/web/components/headers/projects.tsx +++ b/web/components/headers/projects.tsx @@ -57,6 +57,7 @@ export const ProjectsHeader = observer(() => { if (Array.isArray(value)) value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); else { if (filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/project/dropdowns/filters/created-at.tsx b/web/components/project/dropdowns/filters/created-at.tsx index 5a1b75c00b..8992814216 100644 --- a/web/components/project/dropdowns/filters/created-at.tsx +++ b/web/components/project/dropdowns/filters/created-at.tsx @@ -5,6 +5,8 @@ import { DateFilterModal } from "@/components/core"; import { FilterHeader, FilterOption } from "@/components/issues"; // constants import { DATE_BEFORE_FILTER_OPTIONS } from "@/constants/filters"; +// helpers +import { isDate } from "@/helpers/date-time.helper"; type Props = { appliedFilters: string[] | null; @@ -24,6 +26,17 @@ export const FilterCreatedDate: React.FC = observer((props) => { d.name.toLowerCase().includes(searchQuery.toLowerCase()) ); + const isCustomDateSelected = () => { + const isValidDateSelected = appliedFilters?.filter((f) => isDate(f.split(";")[0])) || []; + return isValidDateSelected.length > 0 ? true : false; + }; + const handleCustomDate = () => { + if (isCustomDateSelected()) { + const updateAppliedFilters = appliedFilters?.filter((f) => f.includes("-")) || []; + handleUpdate(updateAppliedFilters); + } else setIsDateFilterModalOpen(true); + }; + return ( <> {isDateFilterModalOpen && ( @@ -52,7 +65,7 @@ export const FilterCreatedDate: React.FC = observer((props) => { multiple /> ))} - setIsDateFilterModalOpen(true)} title="Custom" multiple /> + ) : (

No matches found

diff --git a/web/helpers/date-time.helper.ts b/web/helpers/date-time.helper.ts index 7ca4d49fb1..ba594e6b16 100644 --- a/web/helpers/date-time.helper.ts +++ b/web/helpers/date-time.helper.ts @@ -224,3 +224,7 @@ export const getDate = (date: string | Date | undefined | null): Date | undefine return undefined; } }; +export const isDate = (date: string) => { + const datePattern = /^\d{4}-\d{2}-\d{2}$/; + return datePattern.test(date); +}; From 92fd7b6977d2a70ec1cf3aed487506a0943e2e9d Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:04:35 +0530 Subject: [PATCH 04/11] chore: peek overview remove parent improvement (#4059) --- .../issues/issue-detail/parent-select.tsx | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/web/components/issues/issue-detail/parent-select.tsx b/web/components/issues/issue-detail/parent-select.tsx index b121ddc786..a60131de4b 100644 --- a/web/components/issues/issue-detail/parent-select.tsx +++ b/web/components/issues/issue-detail/parent-select.tsx @@ -4,7 +4,7 @@ import Link from "next/link"; import { Pencil, X } from "lucide-react"; // hooks // components -import { Tooltip } from "@plane/ui"; +import { TOAST_TYPE, Tooltip, setToast } from "@plane/ui"; import { ParentIssuesListModal } from "@/components/issues"; // ui // helpers @@ -30,7 +30,13 @@ export const IssueParentSelect: React.FC = observer((props) const { issue: { getIssueById }, } = useIssueDetail(); - const { isParentIssueModalOpen, toggleParentIssueModal } = useIssueDetail(); + const { + isParentIssueModalOpen, + toggleParentIssueModal, + removeSubIssue, + subIssues: { setSubIssueHelpers }, + } = useIssueDetail(); + // derived values const issue = getIssueById(issueId); const parentIssue = issue?.parent_id ? getIssueById(issue.parent_id) : undefined; @@ -47,6 +53,25 @@ export const IssueParentSelect: React.FC = observer((props) } }; + const handleRemoveSubIssue = async ( + workspaceSlug: string, + projectId: string, + parentIssueId: string, + issueId: string + ) => { + try { + setSubIssueHelpers(parentIssueId, "issue_loader", issueId); + await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); + setSubIssueHelpers(parentIssueId, "issue_loader", issueId); + } catch (error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error", + message: "Something went wrong", + }); + } + }; + if (!issue) return <>; return ( @@ -92,7 +117,7 @@ export const IssueParentSelect: React.FC = observer((props) onClick={(e) => { e.preventDefault(); e.stopPropagation(); - handleParentIssue(null); + handleRemoveSubIssue(workspaceSlug, projectId, parentIssue.id, issueId); }} > From d485446ee2079396ba5303d633bbd4f2dd3749e7 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 18:06:46 +0530 Subject: [PATCH 05/11] [WEB-652] fix: issue activities alignment in dashboard. (#4106) --- web/components/core/activity.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/core/activity.tsx b/web/components/core/activity.tsx index b60152d080..31a796949c 100644 --- a/web/components/core/activity.tsx +++ b/web/components/core/activity.tsx @@ -45,7 +45,7 @@ export const IssueLink = ({ activity }: { activity: IIssueActivity }) => { }`}`} target={activity.issue === null ? "_self" : "_blank"} rel={activity.issue === null ? "" : "noopener noreferrer"} - className="inline-flex items-center gap-1 font-medium text-custom-text-100 hover:underline" + className="font-medium text-custom-text-100 hover:underline" > {`${activity.project_detail.identifier}-${activity.issue_detail.sequence_id}`}{" "} {activity.issue_detail?.name} From 91d85ffed0a0852d666ed5993a1a6c0ddc9703b7 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:07:28 +0530 Subject: [PATCH 06/11] chore: issue block improvement (#4093) --- web/components/issues/issue-layouts/list/block.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/issues/issue-layouts/list/block.tsx b/web/components/issues/issue-layouts/list/block.tsx index ce3e07fdb6..7b3c0fdecd 100644 --- a/web/components/issues/issue-layouts/list/block.tsx +++ b/web/components/issues/issue-layouts/list/block.tsx @@ -53,7 +53,7 @@ export const IssueBlock: React.FC = observer((props: IssueBlock } )} > -
+
{displayProperties && displayProperties?.key && (
From 4c97098218d907cffe8d75a75244d57f6e83f455 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 18:19:34 +0530 Subject: [PATCH 07/11] chore: archival of modules, cycles and issues enhancement. (#4100) --- .../cycles/archived-cycles/modal.tsx | 2 +- web/components/cycles/quick-actions.tsx | 2 +- web/components/cycles/sidebar.tsx | 2 +- web/components/issues/archive-issue-modal.tsx | 9 ++++- web/components/issues/issue-detail/root.tsx | 10 ----- .../quick-action-dropdowns/archived-issue.tsx | 39 ++++++++++++++----- web/components/issues/peek-overview/root.tsx | 14 +------ .../modules/archived-modules/modal.tsx | 2 +- web/components/modules/quick-actions.tsx | 2 +- web/components/modules/sidebar.tsx | 2 +- .../archives/issues/[archivedIssueId].tsx | 11 ++---- 11 files changed, 48 insertions(+), 47 deletions(-) diff --git a/web/components/cycles/archived-cycles/modal.tsx b/web/components/cycles/archived-cycles/modal.tsx index 6e0ddef35b..b613d0de9d 100644 --- a/web/components/cycles/archived-cycles/modal.tsx +++ b/web/components/cycles/archived-cycles/modal.tsx @@ -41,7 +41,7 @@ export const ArchiveCycleModal: React.FC = (props) => { message: "Your archives can be found in project archives.", }); onClose(); - router.push(`/${workspaceSlug}/projects/${projectId}/archives/cycles?peekCycle=${cycleId}`); + router.push(`/${workspaceSlug}/projects/${projectId}/cycles`); }) .catch(() => setToast({ diff --git a/web/components/cycles/quick-actions.tsx b/web/components/cycles/quick-actions.tsx index 215f07beff..bf9aefc879 100644 --- a/web/components/cycles/quick-actions.tsx +++ b/web/components/cycles/quick-actions.tsx @@ -78,7 +78,7 @@ export const CycleQuickActions: React.FC = observer((props) => { title: "Restore success", message: "Your cycle can be found in project cycles.", }); - router.push(`/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}`); + router.push(`/${workspaceSlug}/projects/${projectId}/archives/cycles`); }) .catch(() => setToast({ diff --git a/web/components/cycles/sidebar.tsx b/web/components/cycles/sidebar.tsx index e333564ee7..b72f9fd0d0 100644 --- a/web/components/cycles/sidebar.tsx +++ b/web/components/cycles/sidebar.tsx @@ -129,7 +129,7 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { title: "Restore success", message: "Your cycle can be found in project cycles.", }); - router.push(`/${workspaceSlug.toString()}/projects/${projectId.toString()}/cycles/${cycleId}`); + router.push(`/${workspaceSlug.toString()}/projects/${projectId.toString()}/archives/cycles`); }) .catch(() => setToast({ diff --git a/web/components/issues/archive-issue-modal.tsx b/web/components/issues/archive-issue-modal.tsx index 8ea747ffc7..92bbdc6778 100644 --- a/web/components/issues/archive-issue-modal.tsx +++ b/web/components/issues/archive-issue-modal.tsx @@ -39,7 +39,14 @@ export const ArchiveIssueModal: React.FC = (props) => { setIsArchiving(true); await onSubmit() - .then(() => onClose()) + .then(() => { + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Archive success", + message: "Your archives can be found in project archives.", + }); + onClose(); + }) .catch(() => setToast({ type: TOAST_TYPE.ERROR, diff --git a/web/components/issues/issue-detail/root.tsx b/web/components/issues/issue-detail/root.tsx index 53e8d87071..fdd848a2da 100644 --- a/web/components/issues/issue-detail/root.tsx +++ b/web/components/issues/issue-detail/root.tsx @@ -144,22 +144,12 @@ export const IssueDetailRoot: FC = observer((props) => { archive: async (workspaceSlug: string, projectId: string, issueId: string) => { try { await archiveIssue(workspaceSlug, projectId, issueId); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Issue archived successfully.", - }); captureIssueEvent({ eventName: ISSUE_ARCHIVED, payload: { id: issueId, state: "SUCCESS", element: "Issue details page" }, path: router.asPath, }); } catch (error) { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: "Issue could not be archived. Please try again.", - }); captureIssueEvent({ eventName: ISSUE_ARCHIVED, payload: { id: issueId, state: "FAILED", element: "Issue details page" }, diff --git a/web/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx b/web/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx index d996ee5988..8a49ec9b47 100644 --- a/web/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx +++ b/web/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx @@ -1,22 +1,23 @@ import { useState } from "react"; +import { observer } from "mobx-react"; import { useRouter } from "next/router"; +// icons import { ArchiveRestoreIcon, ExternalLink, Link, Trash2 } from "lucide-react"; -// hooks -import { CustomMenu, TOAST_TYPE, setToast } from "@plane/ui"; - -import { DeleteIssueModal } from "@/components/issues"; // ui +import { CustomMenu, TOAST_TYPE, setToast } from "@plane/ui"; // components +import { DeleteIssueModal } from "@/components/issues"; +// constants import { EIssuesStoreType } from "@/constants/issue"; import { EUserProjectRoles } from "@/constants/project"; -import { copyUrlToClipboard } from "@/helpers/string.helper"; -import { useEventTracker, useIssues, useUser } from "@/hooks/store"; -// components // helpers +import { copyUrlToClipboard } from "@/helpers/string.helper"; +// hooks +import { useEventTracker, useIssues, useUser } from "@/hooks/store"; // types import { IQuickActionProps } from "../list/list-view-types"; -export const ArchivedIssueQuickActions: React.FC = (props) => { +export const ArchivedIssueQuickActions: React.FC = observer((props) => { const { issue, handleDelete, handleRestore, customActionButton, portalElement, readOnly = false } = props; // states const [deleteIssueModal, setDeleteIssueModal] = useState(false); @@ -46,6 +47,24 @@ export const ArchivedIssueQuickActions: React.FC = (props) => message: "Issue link copied to clipboard", }) ); + const handleIssueRestore = async () => { + if (!handleRestore) return; + await handleRestore() + .then(() => { + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Restore success", + message: "Your issue can be found in project issues.", + }); + }) + .catch(() => { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Issue could not be restored. Please try again.", + }); + }); + }; return ( <> @@ -65,7 +84,7 @@ export const ArchivedIssueQuickActions: React.FC = (props) => ellipsis > {isRestoringAllowed && ( - +
Restore @@ -100,4 +119,4 @@ export const ArchivedIssueQuickActions: React.FC = (props) => ); -}; +}); diff --git a/web/components/issues/peek-overview/root.tsx b/web/components/issues/peek-overview/root.tsx index a7f7b23d7a..4d85bd73cd 100644 --- a/web/components/issues/peek-overview/root.tsx +++ b/web/components/issues/peek-overview/root.tsx @@ -135,22 +135,12 @@ export const IssuePeekOverview: FC = observer((props) => { archive: async (workspaceSlug: string, projectId: string, issueId: string) => { try { await archiveIssue(workspaceSlug, projectId, issueId); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Issue archived successfully.", - }); captureIssueEvent({ eventName: ISSUE_ARCHIVED, payload: { id: issueId, state: "SUCCESS", element: "Issue peek-overview" }, path: router.asPath, }); } catch (error) { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: "Issue could not be archived. Please try again.", - }); captureIssueEvent({ eventName: ISSUE_ARCHIVED, payload: { id: issueId, state: "FAILED", element: "Issue peek-overview" }, @@ -163,8 +153,8 @@ export const IssuePeekOverview: FC = observer((props) => { await restoreIssue(workspaceSlug, projectId, issueId); setToast({ type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Issue restored successfully.", + title: "Restore success", + message: "Your issue can be found in project issues.", }); captureIssueEvent({ eventName: ISSUE_RESTORED, diff --git a/web/components/modules/archived-modules/modal.tsx b/web/components/modules/archived-modules/modal.tsx index f922e0ba9c..abfb084f08 100644 --- a/web/components/modules/archived-modules/modal.tsx +++ b/web/components/modules/archived-modules/modal.tsx @@ -41,7 +41,7 @@ export const ArchiveModuleModal: React.FC = (props) => { message: "Your archives can be found in project archives.", }); onClose(); - router.push(`/${workspaceSlug}/projects/${projectId}/archives/modules?peekModule=${moduleId}`); + router.push(`/${workspaceSlug}/projects/${projectId}/modules`); }) .catch(() => setToast({ diff --git a/web/components/modules/quick-actions.tsx b/web/components/modules/quick-actions.tsx index b7972d6124..5decec4ecc 100644 --- a/web/components/modules/quick-actions.tsx +++ b/web/components/modules/quick-actions.tsx @@ -79,7 +79,7 @@ export const ModuleQuickActions: React.FC = observer((props) => { title: "Restore success", message: "Your module can be found in project modules.", }); - router.push(`/${workspaceSlug}/projects/${projectId}/modules/${moduleId}`); + router.push(`/${workspaceSlug}/projects/${projectId}/archives/modules`); }) .catch(() => setToast({ diff --git a/web/components/modules/sidebar.tsx b/web/components/modules/sidebar.tsx index 38618023dc..de6e3d02fd 100644 --- a/web/components/modules/sidebar.tsx +++ b/web/components/modules/sidebar.tsx @@ -227,7 +227,7 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { title: "Restore success", message: "Your module can be found in project modules.", }); - router.push(`/${workspaceSlug}/projects/${projectId}/modules/${moduleId}`); + router.push(`/${workspaceSlug}/projects/${projectId}/archives/modules`); }) .catch(() => setToast({ diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archives/issues/[archivedIssueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archives/issues/[archivedIssueId].tsx index 12b0c83917..0ff7d7fc50 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archives/issues/[archivedIssueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archives/issues/[archivedIssueId].tsx @@ -66,13 +66,8 @@ const ArchivedIssueDetailsPage: NextPageWithLayout = observer(() => { .then(() => { setToast({ type: TOAST_TYPE.SUCCESS, - title: "Success", - message: - issue && - `${getProjectById(issue.project_id) - ?.identifier}-${issue?.sequence_id} is restored successfully under the project ${getProjectById( - issue.project_id - )?.name}`, + title: "Restore success", + message: "Your issue can be found in project issues.", }); router.push(`/${workspaceSlug}/projects/${projectId}/issues/${archivedIssueId}`); }) @@ -80,7 +75,7 @@ const ArchivedIssueDetailsPage: NextPageWithLayout = observer(() => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: "Something went wrong. Please try again.", + message: "Issue could not be restored. Please try again.", }); }) .finally(() => setIsRestoring(false)); From bc0752f7e80ed0b557de81a0426a761d66783e13 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 3 Apr 2024 20:46:19 +0530 Subject: [PATCH 08/11] [WEB-850] chore: calendar layout add existing issue (#4094) * chore: calendar layout add existing issue added in project issue * chore: code refactor --- .../calendar/quick-add-issue-form.tsx | 51 ++++++++----------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx b/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx index 7e17496d48..7f992d8c98 100644 --- a/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx +++ b/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx @@ -82,9 +82,11 @@ export const CalendarQuickAddIssueForm: React.FC = observer((props) => { const [isExistingIssueModalOpen, setIsExistingIssueModalOpen] = useState(false); // derived values const projectDetail = projectId ? getProjectById(projectId.toString()) : null; - const ExistingIssuesListModalPayload = moduleId - ? { module: moduleId.toString(), target_date: "none" } - : { cycle: true, target_date: "none" }; + const ExistingIssuesListModalPayload = addIssuesToView + ? moduleId + ? { module: moduleId.toString(), target_date: "none" } + : { cycle: true, target_date: "none" } + : { target_date: "none" }; const { reset, @@ -234,33 +236,22 @@ export const CalendarQuickAddIssueForm: React.FC = observer((props) => { block: isMenuOpen, })} > - {addIssuesToView ? ( - setIsMenuOpen(true)} - onMenuClose={() => setIsMenuOpen(false)} - className="w-full" - customButtonClassName="w-full" - customButton={ -
- - New Issue -
- } - > - New Issue - Add existing issue -
- ) : ( - - )} + setIsMenuOpen(true)} + onMenuClose={() => setIsMenuOpen(false)} + className="w-full" + customButtonClassName="w-full" + customButton={ +
+ + New Issue +
+ } + > + New Issue + Add existing issue +
)} From e9518ced89d360d8599dd51e1449f78115556705 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 3 Apr 2024 20:49:02 +0530 Subject: [PATCH 09/11] [WEB-756] chore: module and cycle feature toggle validation (#4112) * chore: cycle and module feature issue block validation * chore: cycle and module feature display properties validation * chore: cycle and module feature display filters validation * chore: cycle and module feature project view validation --- web/components/cycles/cycle-mobile-header.tsx | 7 +- web/components/headers/cycle-issues.tsx | 4 ++ web/components/headers/module-issues.tsx | 4 ++ .../headers/project-draft-issues.tsx | 4 ++ web/components/headers/project-issues.tsx | 4 ++ .../headers/project-view-issues.tsx | 4 ++ .../issues/archived-issues-header.tsx | 5 +- .../display-filters-selection.tsx | 23 ++++++- .../display-filters/display-properties.tsx | 47 ++++++++------ .../header/filters/filters-selection.tsx | 17 ++++- .../properties/all-properties.tsx | 64 ++++++++++--------- .../issues/issues-mobile-header.tsx | 4 ++ .../modules/module-mobile-header.tsx | 7 +- web/components/views/form.tsx | 9 ++- 14 files changed, 144 insertions(+), 59 deletions(-) diff --git a/web/components/cycles/cycle-mobile-header.tsx b/web/components/cycles/cycle-mobile-header.tsx index 8c168cbaa0..54a2a31150 100644 --- a/web/components/cycles/cycle-mobile-header.tsx +++ b/web/components/cycles/cycle-mobile-header.tsx @@ -10,7 +10,7 @@ import { CustomMenu } from "@plane/ui"; import { ProjectAnalyticsModal } from "@/components/analytics"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; -import { useIssues, useCycle, useProjectState, useLabel, useMember } from "@/hooks/store"; +import { useIssues, useCycle, useProjectState, useLabel, useMember, useProject } from "@/hooks/store"; export const CycleMobileHeader = () => { const [analyticsModal, setAnalyticsModal] = useState(false); @@ -24,6 +24,7 @@ export const CycleMobileHeader = () => { const { workspaceSlug, projectId, cycleId } = router.query; const cycleDetails = cycleId ? getCycleById(cycleId.toString()) : undefined; // store hooks + const { currentProjectDetails } = useProject(); const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.CYCLE); @@ -151,6 +152,8 @@ export const CycleMobileHeader = () => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
@@ -174,6 +177,8 @@ export const CycleMobileHeader = () => { displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} ignoreGroupedFilters={["cycle"]} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
diff --git a/web/components/headers/cycle-issues.tsx b/web/components/headers/cycle-issues.tsx index 35a646c1c9..e1113910f6 100644 --- a/web/components/headers/cycle-issues.tsx +++ b/web/components/headers/cycle-issues.tsx @@ -250,6 +250,8 @@ export const CycleIssuesHeader: React.FC = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -262,6 +264,8 @@ export const CycleIssuesHeader: React.FC = observer(() => { displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} ignoreGroupedFilters={["cycle"]} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> diff --git a/web/components/headers/module-issues.tsx b/web/components/headers/module-issues.tsx index 59cc2a4295..56da66d2fd 100644 --- a/web/components/headers/module-issues.tsx +++ b/web/components/headers/module-issues.tsx @@ -252,6 +252,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -264,6 +266,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => { displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} ignoreGroupedFilters={["module"]} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
diff --git a/web/components/headers/project-draft-issues.tsx b/web/components/headers/project-draft-issues.tsx index bdfaebc8de..a9f5a93f74 100644 --- a/web/components/headers/project-draft-issues.tsx +++ b/web/components/headers/project-draft-issues.tsx @@ -141,6 +141,8 @@ export const ProjectDraftIssueHeader: FC = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -152,6 +154,8 @@ export const ProjectDraftIssueHeader: FC = observer(() => { handleDisplayFiltersUpdate={handleDisplayFilters} displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
diff --git a/web/components/headers/project-issues.tsx b/web/components/headers/project-issues.tsx index 7c018d5c2f..fd681cc4ad 100644 --- a/web/components/headers/project-issues.tsx +++ b/web/components/headers/project-issues.tsx @@ -192,6 +192,8 @@ export const ProjectIssuesHeader: React.FC = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -203,6 +205,8 @@ export const ProjectIssuesHeader: React.FC = observer(() => { handleDisplayFiltersUpdate={handleDisplayFilters} displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
diff --git a/web/components/headers/project-view-issues.tsx b/web/components/headers/project-view-issues.tsx index 6f545f25b1..27c6e5f9dc 100644 --- a/web/components/headers/project-view-issues.tsx +++ b/web/components/headers/project-view-issues.tsx @@ -210,6 +210,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -221,6 +223,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => { handleDisplayFiltersUpdate={handleDisplayFilters} displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> {canUserCreateIssue && ( diff --git a/web/components/issues/archived-issues-header.tsx b/web/components/issues/archived-issues-header.tsx index cd5aca903c..bf8c373323 100644 --- a/web/components/issues/archived-issues-header.tsx +++ b/web/components/issues/archived-issues-header.tsx @@ -9,13 +9,14 @@ import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/com // constants import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // hooks -import { useIssues, useLabel, useMember, useProjectState } from "@/hooks/store"; +import { useIssues, useLabel, useMember, useProject, useProjectState } from "@/hooks/store"; export const ArchivedIssuesHeader: FC = observer(() => { // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; // store hooks + const { currentProjectDetails } = useProject(); const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.ARCHIVED); @@ -89,6 +90,8 @@ export const ArchivedIssuesHeader: FC = observer(() => { layoutDisplayFiltersOptions={ activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined } + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> diff --git a/web/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx b/web/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx index d270d6a1cc..eb2238a4b9 100644 --- a/web/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx +++ b/web/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx @@ -21,6 +21,8 @@ type Props = { handleDisplayPropertiesUpdate: (updatedDisplayProperties: Partial) => void; layoutDisplayFiltersOptions: ILayoutDisplayFiltersOptions | undefined; ignoreGroupedFilters?: Partial[]; + cycleViewDisabled?: boolean; + moduleViewDisabled?: boolean; }; export const DisplayFiltersSelection: React.FC = observer((props) => { @@ -31,17 +33,32 @@ export const DisplayFiltersSelection: React.FC = observer((props) => { handleDisplayPropertiesUpdate, layoutDisplayFiltersOptions, ignoreGroupedFilters = [], + cycleViewDisabled = false, + moduleViewDisabled = false, } = props; const isDisplayFilterEnabled = (displayFilter: keyof IIssueDisplayFilterOptions) => Object.keys(layoutDisplayFiltersOptions?.display_filters ?? {}).includes(displayFilter); + const computedIgnoreGroupedFilters: Partial[] = []; + if (cycleViewDisabled) { + ignoreGroupedFilters.push("cycle"); + } + if (moduleViewDisabled) { + ignoreGroupedFilters.push("module"); + } + return (
{/* display properties */} {layoutDisplayFiltersOptions?.display_properties && (
- +
)} @@ -56,7 +73,7 @@ export const DisplayFiltersSelection: React.FC = observer((props) => { group_by: val, }) } - ignoreGroupedFilters={ignoreGroupedFilters} + ignoreGroupedFilters={[...ignoreGroupedFilters, ...computedIgnoreGroupedFilters]} />
)} @@ -74,7 +91,7 @@ export const DisplayFiltersSelection: React.FC = observer((props) => { }) } subGroupByOptions={layoutDisplayFiltersOptions?.display_filters.sub_group_by ?? []} - ignoreGroupedFilters={ignoreGroupedFilters} + ignoreGroupedFilters={[...ignoreGroupedFilters, ...computedIgnoreGroupedFilters]} /> )} diff --git a/web/components/issues/issue-layouts/filters/header/display-filters/display-properties.tsx b/web/components/issues/issue-layouts/filters/header/display-filters/display-properties.tsx index 54cb0a439d..aebb8d5cc1 100644 --- a/web/components/issues/issue-layouts/filters/header/display-filters/display-properties.tsx +++ b/web/components/issues/issue-layouts/filters/header/display-filters/display-properties.tsx @@ -10,13 +10,22 @@ import { FilterHeader } from "../helpers/filter-header"; type Props = { displayProperties: IIssueDisplayProperties; handleUpdate: (updatedDisplayProperties: Partial) => void; + cycleViewDisabled?: boolean; + moduleViewDisabled?: boolean; }; export const FilterDisplayProperties: React.FC = observer((props) => { - const { displayProperties, handleUpdate } = props; + const { displayProperties, handleUpdate, cycleViewDisabled = false, moduleViewDisabled = false } = props; const [previewEnabled, setPreviewEnabled] = React.useState(true); + // Filter out "cycle" and "module" keys if cycleViewDisabled or moduleViewDisabled is true + const filteredDisplayProperties = ISSUE_DISPLAY_PROPERTIES.filter((property) => { + if (cycleViewDisabled && property.key === "cycle") return false; + if (moduleViewDisabled && property.key === "modules") return false; + return true; + }); + return ( <> = observer((props) => { /> {previewEnabled && (
- {ISSUE_DISPLAY_PROPERTIES.map((displayProperty) => ( - + {filteredDisplayProperties.map((displayProperty) => ( + <> + + ))}
)} diff --git a/web/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx b/web/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx index 7e6e44ebf2..9220e9fd31 100644 --- a/web/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx +++ b/web/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx @@ -30,10 +30,21 @@ type Props = { labels?: IIssueLabel[] | undefined; memberIds?: string[] | undefined; states?: IState[] | undefined; + cycleViewDisabled?: boolean; + moduleViewDisabled?: boolean; }; export const FilterSelection: React.FC = observer((props) => { - const { filters, handleFiltersUpdate, layoutDisplayFiltersOptions, labels, memberIds, states } = props; + const { + filters, + handleFiltersUpdate, + layoutDisplayFiltersOptions, + labels, + memberIds, + states, + cycleViewDisabled = false, + moduleViewDisabled = false, + } = props; // hooks const { router: { moduleId, cycleId }, @@ -111,7 +122,7 @@ export const FilterSelection: React.FC = observer((props) => { )} {/* cycle */} - {isFilterEnabled("cycle") && !cycleId && ( + {isFilterEnabled("cycle") && !cycleId && !cycleViewDisabled && (
= observer((props) => { )} {/* module */} - {isFilterEnabled("module") && !moduleId && ( + {isFilterEnabled("module") && !moduleId && !moduleViewDisabled && (
= observer((props) => { const { issue, updateIssue, displayProperties, activeLayout, isReadOnly, className } = props; // store hooks + const { getProjectById } = useProject(); const { labelMap } = useLabel(); const { captureIssueEvent } = useEventTracker(); const { @@ -56,6 +57,7 @@ export const IssueProperties: React.FC = observer((props) => { const { areEstimatesEnabledForCurrentProject } = useEstimate(); const { getStateById } = useProjectState(); const { isMobile } = usePlatformOS(); + const projectDetails = getProjectById(issue.project_id); // router const router = useRouter(); const { workspaceSlug } = router.query; @@ -349,36 +351,40 @@ export const IssueProperties: React.FC = observer((props) => { {/* modules */} - -
- -
-
+ {projectDetails?.module_view && ( + +
+ +
+
+ )} {/* cycles */} - -
- -
-
+ {projectDetails?.cycle_view && ( + +
+ +
+
+ )} {/* estimates */} {areEstimatesEnabledForCurrentProject && ( diff --git a/web/components/issues/issues-mobile-header.tsx b/web/components/issues/issues-mobile-header.tsx index 4bc90b686c..de1c088e04 100644 --- a/web/components/issues/issues-mobile-header.tsx +++ b/web/components/issues/issues-mobile-header.tsx @@ -132,6 +132,8 @@ export const IssuesMobileHeader = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
@@ -154,6 +156,8 @@ export const IssuesMobileHeader = observer(() => { handleDisplayFiltersUpdate={handleDisplayFilters} displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} />
diff --git a/web/components/modules/module-mobile-header.tsx b/web/components/modules/module-mobile-header.tsx index 6419b13b08..79486a37cc 100644 --- a/web/components/modules/module-mobile-header.tsx +++ b/web/components/modules/module-mobile-header.tsx @@ -11,12 +11,13 @@ import { ProjectAnalyticsModal } from "@/components/analytics"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; // hooks import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; -import { useIssues, useLabel, useMember, useModule, useProjectState } from "@/hooks/store"; +import { useIssues, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store"; // types // constants export const ModuleMobileHeader = observer(() => { const [analyticsModal, setAnalyticsModal] = useState(false); + const { currentProjectDetails } = useProject(); const { getModuleById } = useModule(); const layouts = [ { key: "list", title: "List", icon: List }, @@ -134,6 +135,8 @@ export const ModuleMobileHeader = observer(() => { labels={projectLabels} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> @@ -157,6 +160,8 @@ export const ModuleMobileHeader = observer(() => { displayProperties={issueFilters?.displayProperties ?? {}} handleDisplayPropertiesUpdate={handleDisplayProperties} ignoreGroupedFilters={["module"]} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> diff --git a/web/components/views/form.tsx b/web/components/views/form.tsx index e758b7938a..a8fa6b87cb 100644 --- a/web/components/views/form.tsx +++ b/web/components/views/form.tsx @@ -6,7 +6,7 @@ import { IProjectView, IIssueFilterOptions } from "@plane/types"; import { Button, Input, TextArea } from "@plane/ui"; import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "@/components/issues"; import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; -import { useLabel, useMember, useProjectState } from "@/hooks/store"; +import { useLabel, useMember, useProject, useProjectState } from "@/hooks/store"; // components // ui // types @@ -27,6 +27,7 @@ const defaultValues: Partial = { export const ProjectViewForm: React.FC = observer((props) => { const { handleFormSubmit, handleClose, data, preLoadedData } = props; // store hooks + const { currentProjectDetails } = useProject(); const { projectStates } = useProjectState(); const { projectLabels } = useLabel(); const { @@ -184,6 +185,8 @@ export const ProjectViewForm: React.FC = observer((props) => { labels={projectLabels ?? undefined} memberIds={projectMemberIds ?? undefined} states={projectStates} + cycleViewDisabled={!currentProjectDetails?.cycle_view} + moduleViewDisabled={!currentProjectDetails?.module_view} /> )} @@ -212,8 +215,8 @@ export const ProjectViewForm: React.FC = observer((props) => { ? "Updating View..." : "Update View" : isSubmitting - ? "Creating View..." - : "Create View"} + ? "Creating View..." + : "Create View"} From 1fb87919418643fe4ac2e05077596445f5765c26 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 20:51:22 +0530 Subject: [PATCH 10/11] chore: increase data dropdown close icon size for consitency. (#4115) --- web/components/dropdowns/date.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/dropdowns/date.tsx b/web/components/dropdowns/date.tsx index e126ec1bde..8e207796d5 100644 --- a/web/components/dropdowns/date.tsx +++ b/web/components/dropdowns/date.tsx @@ -149,7 +149,7 @@ export const DateDropdown: React.FC = (props) => { )} {isClearable && !disabled && isDateSelected && ( { e.stopPropagation(); onChange(null); From 0ab03c963c28807722f00238f2be656167afecb4 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Wed, 3 Apr 2024 20:57:44 +0530 Subject: [PATCH 11/11] [WEB-869] chore: fix assignee and parent ui inconsistency in create issue modal. (#4113) --- web/components/issues/issue-modal/form.tsx | 63 ++++++++++------------ 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/web/components/issues/issue-modal/form.tsx b/web/components/issues/issue-modal/form.tsx index b581522e6e..88d6c38778 100644 --- a/web/components/issues/issue-modal/form.tsx +++ b/web/components/issues/issue-modal/form.tsx @@ -541,7 +541,7 @@ export const IssueFormRoot: FC = observer((props) => { handleFormChange(); }} buttonVariant={value?.length > 0 ? "transparent-without-text" : "border-with-text"} - buttonClassName={value?.length > 0 ? "hover:bg-transparent px-0" : ""} + buttonClassName={value?.length > 0 ? "hover:bg-transparent" : ""} placeholder="Assignees" multiple tabIndex={getTabIndex("assignee_ids")} @@ -663,33 +663,23 @@ export const IssueFormRoot: FC = observer((props) => { )} /> )} - - {watch("parent_id") ? ( -
- - - {selectedParentIssue && - `${selectedParentIssue.project__identifier}- - ${selectedParentIssue.sequence_id}`} - -
- ) : ( -
- - Add parent -
- )} - - } - placement="bottom-start" - tabIndex={getTabIndex("parent_id")} - > - {watch("parent_id") ? ( + {watch("parent_id") ? ( + + + + {selectedParentIssue && + `${selectedParentIssue.project__identifier}-${selectedParentIssue.sequence_id}`} + + + } + placement="bottom-start" + tabIndex={getTabIndex("parent_id")} + > <> setParentIssueListModalOpen(true)}> Change parent issue @@ -704,12 +694,17 @@ export const IssueFormRoot: FC = observer((props) => { Remove parent issue - ) : ( - setParentIssueListModalOpen(true)}> - Select parent Issue - - )} - +
+ ) : ( + + )}