From 548e95c7e0549bfbe31a94eb968000864fd42a98 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:11:07 +0530 Subject: [PATCH] fix: bug fixes (#2581) * fix: module sidebar fix for kanban layout * chore: cycle & module sidebar improvement * chore: join project content updated * chore: project empty state header fix * chore: create project modal dropdown consistency * chore: list view group header overlapping issue fix * chore: popover code refactor * chore: module sidebar fix for cycle kanban view * chore: add existing issue option added in module empty state * chore: add existing issue option added in cycle empty state --- .../src/icons/cycle/circle-dot-full-icon.tsx | 13 ++- web/components/common/empty-state.tsx | 12 ++- web/components/cycles/sidebar.tsx | 80 +++++++++---------- web/components/headers/projects.tsx | 24 +++--- .../issue-layouts/empty-states/cycle.tsx | 15 +++- .../issue-layouts/empty-states/module.tsx | 16 +++- .../issue-layouts/roots/cycle-layout-root.tsx | 8 +- .../roots/module-layout-root.tsx | 8 +- .../issues/sidebar-select/label.tsx | 64 +++++++-------- web/components/modules/sidebar.tsx | 31 ++++--- .../project/create-project-modal.tsx | 4 +- web/components/project/join-project-modal.tsx | 3 +- web/components/workspace/member-select.tsx | 2 +- .../projects/[projectId]/cycles/[cycleId].tsx | 52 +++++++----- .../[projectId]/modules/[moduleId].tsx | 54 ++++++++----- 15 files changed, 229 insertions(+), 157 deletions(-) diff --git a/packages/ui/src/icons/cycle/circle-dot-full-icon.tsx b/packages/ui/src/icons/cycle/circle-dot-full-icon.tsx index 0a2c46e99..53ea05906 100644 --- a/packages/ui/src/icons/cycle/circle-dot-full-icon.tsx +++ b/packages/ui/src/icons/cycle/circle-dot-full-icon.tsx @@ -7,14 +7,19 @@ export const CircleDotFullIcon: React.FC = ({ ...rest }) => ( - + ); diff --git a/web/components/common/empty-state.tsx b/web/components/common/empty-state.tsx index 149d76540..e749600ae 100644 --- a/web/components/common/empty-state.tsx +++ b/web/components/common/empty-state.tsx @@ -3,7 +3,7 @@ import React from "react"; import Image from "next/image"; // ui -import { PrimaryButton } from "components/ui"; +import { Button } from "@plane/ui"; type Props = { title: string; @@ -33,10 +33,14 @@ export const EmptyState: React.FC = ({ {description &&

{description}

}
{primaryButton && ( - - {primaryButton.icon} + )} {secondaryButton}
diff --git a/web/components/cycles/sidebar.tsx b/web/components/cycles/sidebar.tsx index 68ed29f16..5d0f47b51 100644 --- a/web/components/cycles/sidebar.tsx +++ b/web/components/cycles/sidebar.tsx @@ -383,41 +383,39 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { - {({}) => ( - <> - - {areYearsEqual ? renderShortDate(endDate, "_ _") : renderShortMonthDate(endDate, "_ _")} - + <> + + {areYearsEqual ? renderShortDate(endDate, "_ _") : renderShortMonthDate(endDate, "_ _")} + - - - { - if (val) { - handleEndDateChange(val); - } - }} - startDate={watch("start_date") ? `${watch("start_date")}` : null} - endDate={watch("end_date") ? `${watch("end_date")}` : null} - minDate={new Date(`${watch("start_date")}`)} - selectsEnd - /> - - - - )} + + + { + if (val) { + handleEndDateChange(val); + } + }} + startDate={watch("start_date") ? `${watch("start_date")}` : null} + endDate={watch("end_date") ? `${watch("end_date")}` : null} + minDate={new Date(`${watch("start_date")}`)} + selectsEnd + /> + + + @@ -459,7 +457,10 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { {({ open }) => (
-
+
Progress
@@ -473,12 +474,7 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { "" )} {isStartValid && isEndValid ? ( - - +
-
+
diff --git a/web/components/headers/projects.tsx b/web/components/headers/projects.tsx index 30aba09ea..453eb38c8 100644 --- a/web/components/headers/projects.tsx +++ b/web/components/headers/projects.tsx @@ -10,10 +10,14 @@ import { observer } from "mobx-react-lite"; export const ProjectsHeader = observer(() => { const router = useRouter(); + const { workspaceSlug } = router.query; + // store const { project: projectStore, workspace: workspaceStore } = useMobxStore(); const currentWorkspace = workspaceStore.currentWorkspace; + const projectsList = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : []; + return (
{
-
- - projectStore.setSearchQuery(e.target.value)} - placeholder="Search" - /> -
+ {projectsList?.length > 0 && ( +
+ + projectStore.setSearchQuery(e.target.value)} + placeholder="Search" + /> +
+ )} + } />
); diff --git a/web/components/issues/issue-layouts/empty-states/module.tsx b/web/components/issues/issue-layouts/empty-states/module.tsx index 830fde1ff..a71be523f 100644 --- a/web/components/issues/issue-layouts/empty-states/module.tsx +++ b/web/components/issues/issue-layouts/empty-states/module.tsx @@ -1,10 +1,15 @@ import { PlusIcon } from "lucide-react"; // components import { EmptyState } from "components/common"; +import { Button } from "@plane/ui"; // assets import emptyIssue from "public/empty-state/issue.svg"; -export const ModuleEmptyState: React.FC = () => ( +type Props = { + openIssuesListModal: () => void; +}; + +export const ModuleEmptyState: React.FC = ({ openIssuesListModal }) => (
( document.dispatchEvent(e); }, }} + secondaryButton={ + + } />
); diff --git a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx index ffe78f3d8..8658dbd30 100644 --- a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx @@ -18,7 +18,11 @@ import { TransferIssues, TransferIssuesModal } from "components/cycles"; // helpers import { getDateRangeStatus } from "helpers/date-time.helper"; -export const CycleLayoutRoot: React.FC = observer(() => { +type Props = { + openIssuesListModal: () => void; +}; + +export const CycleLayoutRoot: React.FC = observer(({ openIssuesListModal }) => { const [transferIssuesModal, setTransferIssuesModal] = useState(false); const router = useRouter(); @@ -60,7 +64,7 @@ export const CycleLayoutRoot: React.FC = observer(() => { {cycleStatus === "completed" && setTransferIssuesModal(true)} />} {(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( - + ) : (
{activeLayout === "list" ? ( diff --git a/web/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/components/issues/issue-layouts/roots/module-layout-root.tsx index ff7867c3d..705c4ad02 100644 --- a/web/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -16,7 +16,11 @@ import { ModuleSpreadsheetLayout, } from "components/issues"; -export const ModuleLayoutRoot: React.FC = observer(() => { +type Props = { + openIssuesListModal: () => void; +}; + +export const ModuleLayoutRoot: React.FC = observer(({ openIssuesListModal }) => { const router = useRouter(); const { workspaceSlug, projectId, moduleId } = router.query as { workspaceSlug: string; @@ -53,7 +57,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
{(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( - + ) : (
{activeLayout === "list" ? ( diff --git a/web/components/issues/sidebar-select/label.tsx b/web/components/issues/sidebar-select/label.tsx index 4f9bdf5ea..6cd0cff2a 100644 --- a/web/components/issues/sidebar-select/label.tsx +++ b/web/components/issues/sidebar-select/label.tsx @@ -239,40 +239,38 @@ export const SidebarLabelSelect: React.FC = ({
- {({}) => ( - <> - - {watch("color") && watch("color") !== "" && ( - - )} - + <> + + {watch("color") && watch("color") !== "" && ( + + )} + - - - ( - onChange(value.hex)} /> - )} - /> - - - - )} + + + ( + onChange(value.hex)} /> + )} + /> + + +
= observer((props) => { {({ open }) => (
-
+
Progress
@@ -341,12 +344,7 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { "" )} {isStartValid && isEndValid ? ( - - +
-
+
@@ -415,20 +413,21 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { {({ open }) => (
-
+
Links
- - +
-
+
diff --git a/web/components/project/create-project-modal.tsx b/web/components/project/create-project-modal.tsx index 772b632ff..e16224c6a 100644 --- a/web/components/project/create-project-modal.tsx +++ b/web/components/project/create-project-modal.tsx @@ -330,9 +330,9 @@ export const CreateProjectModal: FC = observer((props) => { +
{currentNetwork ? ( <> diff --git a/web/components/project/join-project-modal.tsx b/web/components/project/join-project-modal.tsx index ef6874db9..b6a212eb7 100644 --- a/web/components/project/join-project-modal.tsx +++ b/web/components/project/join-project-modal.tsx @@ -68,7 +68,8 @@ export const JoinProjectModal: React.FC = (props) => { Join Project?

- Are you sure you want to join {project?.name}? + Are you sure you want to join the project {project?.name}? + Please click the 'Join Project' button below to continue.

diff --git a/web/components/workspace/member-select.tsx b/web/components/workspace/member-select.tsx index 4e73b1b67..3ba1cbd89 100644 --- a/web/components/workspace/member-select.tsx +++ b/web/components/workspace/member-select.tsx @@ -74,7 +74,7 @@ export const WorkspaceMemberSelect: FC = (props) => { type="button" className={`flex items-center justify-between gap-1 w-full text-xs ${ disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80" - } `} + }`} > {label} diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx index e96038b7f..a5a0e922b 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx @@ -3,8 +3,12 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; +// services +import { IssueService } from "services/issue"; // hooks import useLocalStorage from "hooks/use-local-storage"; +import useUser from "hooks/use-user"; +import useToast from "hooks/use-toast"; // layouts import { AppLayout } from "layouts/app-layout"; // components @@ -16,6 +20,10 @@ import { CycleLayoutRoot } from "components/issues/issue-layouts"; import { EmptyState } from "components/common"; // assets import emptyCycle from "public/empty-state/cycle.svg"; +// types +import { ISearchIssueResponse } from "types"; + +const issueService = new IssueService(); const SingleCycle: React.FC = () => { const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false); @@ -25,6 +33,10 @@ const SingleCycle: React.FC = () => { const { cycle: cycleStore } = useMobxStore(); + const { user } = useUser(); + + const { setToastAlert } = useToast(); + const { setValue, storedValue } = useLocalStorage("cycle_sidebar_collapsed", "false"); const isSidebarCollapsed = storedValue ? (storedValue === "true" ? true : false) : false; @@ -40,23 +52,27 @@ const SingleCycle: React.FC = () => { }; // TODO: add this function to bulk add issues to cycle - // const handleAddIssuesToCycle = async (data: ISearchIssueResponse[]) => { - // if (!workspaceSlug || !projectId) return; + const handleAddIssuesToCycle = async (data: ISearchIssueResponse[]) => { + if (!workspaceSlug || !projectId) return; - // const payload = { - // issues: data.map((i) => i.id), - // }; + const payload = { + issues: data.map((i) => i.id), + }; - // await issueService - // .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload, user) - // .catch(() => { - // setToastAlert({ - // type: "error", - // title: "Error!", - // message: "Selected issues could not be added to the cycle. Please try again.", - // }); - // }); - // }; + await issueService + .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload, user) + .catch(() => { + setToastAlert({ + type: "error", + title: "Error!", + message: "Selected issues could not be added to the cycle. Please try again.", + }); + }); + }; + + const openIssuesListModal = () => { + setCycleIssuesListModal(true); + }; return ( } withProjectWrapper> @@ -65,7 +81,7 @@ const SingleCycle: React.FC = () => { isOpen={cycleIssuesListModal} handleClose={() => setCycleIssuesListModal(false)} searchParams={{ cycle: true }} - handleOnSubmit={async () => {}} + handleOnSubmit={handleAddIssuesToCycle} /> {error ? ( { ) : ( <>
-
- +
+
{cycleId && !isSidebarCollapsed && (
{ const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false); @@ -27,6 +35,10 @@ const ModuleIssuesPage: NextPage = () => { const { module: moduleStore } = useMobxStore(); + const { user } = useUser(); + + const { setToastAlert } = useToast(); + const { setValue, storedValue } = useLocalStorage("module_sidebar_collapsed", "false"); const isSidebarCollapsed = storedValue ? (storedValue === "true" ? true : false) : false; @@ -38,27 +50,27 @@ const ModuleIssuesPage: NextPage = () => { ); // TODO: add this function to bulk add issues to cycle - // const handleAddIssuesToModule = async (data: ISearchIssueResponse[]) => { - // if (!workspaceSlug || !projectId) return; + const handleAddIssuesToModule = async (data: ISearchIssueResponse[]) => { + if (!workspaceSlug || !projectId) return; - // const payload = { - // issues: data.map((i) => i.id), - // }; + const payload = { + issues: data.map((i) => i.id), + }; - // await moduleService - // .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user) - // .catch(() => - // setToastAlert({ - // type: "error", - // title: "Error!", - // message: "Selected issues could not be added to the module. Please try again.", - // }) - // ); - // }; + await moduleService + .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user) + .catch(() => + setToastAlert({ + type: "error", + title: "Error!", + message: "Selected issues could not be added to the module. Please try again.", + }) + ); + }; - // const openIssuesListModal = () => { - // setModuleIssuesListModal(true); - // }; + const openIssuesListModal = () => { + setModuleIssuesListModal(true); + }; const toggleSidebar = () => { setValue(`${!isSidebarCollapsed}`); @@ -72,7 +84,7 @@ const ModuleIssuesPage: NextPage = () => { isOpen={moduleIssuesListModal} handleClose={() => setModuleIssuesListModal(false)} searchParams={{ module: true }} - handleOnSubmit={async () => {}} + handleOnSubmit={handleAddIssuesToModule} /> {error ? ( { /> ) : (
-
- +
+
{moduleId && !isSidebarCollapsed && (