From cb4d294608a976aec94aba8c0b5486c2dd148200 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Tue, 1 Aug 2023 12:24:34 +0530 Subject: [PATCH] style: sidebar projects design (#1736) * chore: disclosure menu for sidebar projects * fix: projects list spacing * style: new design --- apps/app/components/project/sidebar-list.tsx | 225 +++++++++++++----- .../project/single-sidebar-project.tsx | 46 ++-- .../app/components/workspace/sidebar-menu.tsx | 2 +- apps/app/hooks/use-profile-issues.tsx | 2 - apps/app/hooks/use-user.tsx | 1 - apps/app/types/projects.d.ts | 2 +- 6 files changed, 187 insertions(+), 91 deletions(-) diff --git a/apps/app/components/project/sidebar-list.tsx b/apps/app/components/project/sidebar-list.tsx index 5a35d5625..eab2206b1 100644 --- a/apps/app/components/project/sidebar-list.tsx +++ b/apps/app/components/project/sidebar-list.tsx @@ -5,6 +5,8 @@ import { mutate } from "swr"; // react-beautiful-dnd import { DragDropContext, Draggable, DropResult, Droppable } from "react-beautiful-dnd"; +// headless ui +import { Disclosure } from "@headlessui/react"; // hooks import useToast from "hooks/use-toast"; import useTheme from "hooks/use-theme"; @@ -15,6 +17,7 @@ import { DeleteProjectModal, SingleSidebarProject } from "components/project"; // services import projectService from "services/project.service"; // icons +import { Icon } from "components/ui"; import { PlusIcon } from "@heroicons/react/24/outline"; // helpers import { copyTextToClipboard } from "helpers/string.helper"; @@ -30,7 +33,7 @@ export const ProjectSidebarList: FC = () => { // router const router = useRouter(); - const { workspaceSlug } = router.query; + const { workspaceSlug, projectId } = router.query; const { user } = useUserAuth(); @@ -38,15 +41,18 @@ export const ProjectSidebarList: FC = () => { const { setToastAlert } = useToast(); const { projects: allProjects } = useProjects(); + + const joinedProjects = allProjects?.filter((p) => p.sort_order); const favoriteProjects = allProjects?.filter((p) => p.is_favorite); + const otherProjects = allProjects?.filter((p) => p.sort_order === null); - const orderedAllProjects = allProjects - ? orderArrayBy(allProjects, "sort_order", "ascending") - : []; + const orderedJoinedProjects: IProject[] | undefined = joinedProjects + ? orderArrayBy(joinedProjects, "sort_order", "ascending") + : undefined; - const orderedFavProjects = favoriteProjects + const orderedFavProjects: IProject[] | undefined = favoriteProjects ? orderArrayBy(favoriteProjects, "sort_order", "ascending") - : []; + : undefined; const handleDeleteProject = (project: IProject) => { setProjectToDelete(project); @@ -69,22 +75,25 @@ export const ProjectSidebarList: FC = () => { const { source, destination, draggableId } = result; if (!destination || !workspaceSlug) return; + if (source.index === destination.index) return; - const projectList = - destination.droppableId === "all-projects" ? orderedAllProjects : orderedFavProjects; + const projectsList = + (destination.droppableId === "joined-projects" + ? orderedJoinedProjects + : orderedFavProjects) ?? []; - let updatedSortOrder = projectList[source.index].sort_order; - if (destination.index === 0) { - updatedSortOrder = projectList[0].sort_order - 1000; - } else if (destination.index === projectList.length - 1) { - updatedSortOrder = projectList[projectList.length - 1].sort_order + 1000; - } else { - const destinationSortingOrder = projectList[destination.index].sort_order; + let updatedSortOrder = projectsList[source.index].sort_order; + + if (destination.index === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000; + else if (destination.index === projectsList.length - 1) + updatedSortOrder = (projectsList[projectsList.length - 1].sort_order as number) + 1000; + else { + const destinationSortingOrder = projectsList[destination.index].sort_order as number; const relativeDestinationSortingOrder = source.index < destination.index - ? projectList[destination.index + 1].sort_order - : projectList[destination.index - 1].sort_order; + ? (projectsList[destination.index + 1].sort_order as number) + : (projectsList[destination.index - 1].sort_order as number); updatedSortOrder = Math.round( (destinationSortingOrder + relativeDestinationSortingOrder) / 2 @@ -121,76 +130,162 @@ export const ProjectSidebarList: FC = () => { data={projectToDelete} user={user} /> -
+
{(provided) => (
{orderedFavProjects && orderedFavProjects.length > 0 && ( -
- {!sidebarCollapse && ( -
- Favorites -
- )} - {orderedFavProjects.map((project, index) => ( - - {(provided, snapshot) => ( -
- handleDeleteProject(project)} - handleCopyText={() => handleCopyText(project.id)} - shortContextMenu + p.id === projectId) ? true : false + } + > + {({ open }) => ( + <> + {!sidebarCollapse && ( + + Favorites + -
+ )} -
- ))} - {provided.placeholder} -
+ + {orderedFavProjects.map((project, index) => ( + + {(provided, snapshot) => ( +
+ handleDeleteProject(project)} + handleCopyText={() => handleCopyText(project.id)} + shortContextMenu + /> +
+ )} +
+ ))} +
+ {provided.placeholder} + + )} + )}
)}
- + {(provided) => (
- {orderedAllProjects && orderedAllProjects.length > 0 && ( -
- {!sidebarCollapse && ( -
Projects
- )} - {orderedAllProjects.map((project, index) => ( - - {(provided, snapshot) => ( -
- handleDeleteProject(project)} - handleCopyText={() => handleCopyText(project.id)} + {orderedJoinedProjects && orderedJoinedProjects.length > 0 && ( + p.id === projectId) + ? true + : false + } + > + {({ open }) => ( + <> + {!sidebarCollapse && ( + + Projects + -
+ )} -
- ))} - {provided.placeholder} -
+ + {orderedJoinedProjects.map((project, index) => ( + + {(provided, snapshot) => ( +
+ handleDeleteProject(project)} + handleCopyText={() => handleCopyText(project.id)} + /> +
+ )} +
+ ))} +
+ {provided.placeholder} + + )} + )}
)}
+ {otherProjects && otherProjects.length > 0 && ( + p.id === projectId) ? true : false} + > + {({ open }) => ( + <> + {!sidebarCollapse && ( + + Other Projects + + + )} + + {otherProjects?.map((project, index) => ( + handleDeleteProject(project)} + handleCopyText={() => handleCopyText(project.id)} + shortContextMenu + /> + ))} + + + )} + + )} {allProjects && allProjects.length === 0 && ( + {provided && ( + + )}
@@ -184,21 +186,23 @@ export const SingleSidebarProject: React.FC = ({ open ? "" : "text-custom-sidebar-text-200" }`} > - {truncateText(project?.name, 14)} + {truncateText(project.name, 15)}

)}
{!sidebarCollapse && ( )}
{!sidebarCollapse && ( - + {!shortContextMenu && ( diff --git a/apps/app/components/workspace/sidebar-menu.tsx b/apps/app/components/workspace/sidebar-menu.tsx index 629a7b3a1..6a2d94cb1 100644 --- a/apps/app/components/workspace/sidebar-menu.tsx +++ b/apps/app/components/workspace/sidebar-menu.tsx @@ -47,7 +47,7 @@ export const WorkspaceSidebarMenu = () => { const { collapsed: sidebarCollapse } = useTheme(); return ( -
+
{workspaceLinks(workspaceSlug as string).map((link, index) => { const isActive = link.name === "Settings" diff --git a/apps/app/hooks/use-profile-issues.tsx b/apps/app/hooks/use-profile-issues.tsx index 82b7a2ad7..850886462 100644 --- a/apps/app/hooks/use-profile-issues.tsx +++ b/apps/app/hooks/use-profile-issues.tsx @@ -58,8 +58,6 @@ const useProfileIssues = (workspaceSlug: string | undefined, userId: string | un : null ); - console.log(memberRole); - const groupedIssues: | { [key: string]: IIssue[]; diff --git a/apps/app/hooks/use-user.tsx b/apps/app/hooks/use-user.tsx index f5186a273..f9b6e36d8 100644 --- a/apps/app/hooks/use-user.tsx +++ b/apps/app/hooks/use-user.tsx @@ -18,7 +18,6 @@ export default function useUser({ redirectTo = "", redirectIfFound = false, opti ); const user = error ? undefined : data; - // console.log("useUser", user); useEffect(() => { // if no redirect needed, just return (example: already on /dashboard) diff --git a/apps/app/types/projects.d.ts b/apps/app/types/projects.d.ts index 6ea201391..2274e3d22 100644 --- a/apps/app/types/projects.d.ts +++ b/apps/app/types/projects.d.ts @@ -45,7 +45,7 @@ export interface IProject { network: number; page_view: boolean; project_lead: IUserLite | string | null; - sort_order: number; + sort_order: number | null; slug: string; total_cycles: number; total_members: number;