From a7ecfade984def02e84441036a62bbe90ba8a6a6 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:56:33 +0530 Subject: [PATCH] [WEB-1920] dev: app sidebar revamp (#5150) * chore: user activity icon added * dev: sidebar navigation component added * chore: dashboard constant file updated * chore: unread notification indicator position * chore: app sidebar project section * chore: app sidebar User and Workspace section updated * chore: notification to inbox transition * chore: code refactor * chore: code refactor --- packages/ui/src/icons/index.ts | 1 + packages/ui/src/icons/user-activity-icon.tsx | 21 ++++++ web/core/components/sidebar/index.ts | 1 + .../components/sidebar/sidebar-navigation.tsx | 29 ++++++++ .../notification-app-sidebar-option.tsx | 2 +- .../sidebar/filters/menu/root.tsx | 2 +- .../sidebar/header/root.tsx | 8 +-- .../components/workspace/sidebar/dropdown.tsx | 39 +++------- .../workspace/sidebar/projects-list-item.tsx | 54 +++++++------- .../workspace/sidebar/projects-list.tsx | 14 ++-- .../workspace/sidebar/user-menu.tsx | 68 +++++++++--------- .../workspace/sidebar/workspace-menu.tsx | 71 +++++++++---------- web/core/constants/dashboard.ts | 44 ++++++------ 13 files changed, 187 insertions(+), 167 deletions(-) create mode 100644 packages/ui/src/icons/user-activity-icon.tsx create mode 100644 web/core/components/sidebar/index.ts create mode 100644 web/core/components/sidebar/sidebar-navigation.tsx diff --git a/packages/ui/src/icons/index.ts b/packages/ui/src/icons/index.ts index 31b6e74869..b186150295 100644 --- a/packages/ui/src/icons/index.ts +++ b/packages/ui/src/icons/index.ts @@ -23,3 +23,4 @@ export * from "./transfer-icon"; export * from "./info-icon"; export * from "./dropdown-icon"; export * from "./intake"; +export * from "./user-activity-icon"; diff --git a/packages/ui/src/icons/user-activity-icon.tsx b/packages/ui/src/icons/user-activity-icon.tsx new file mode 100644 index 0000000000..9a8e691fd1 --- /dev/null +++ b/packages/ui/src/icons/user-activity-icon.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; + +import { ISvgIcons } from "./type"; + +export const UserActivityIcon: React.FC = ({ className = "text-current", ...rest }) => ( + + + + + +); diff --git a/web/core/components/sidebar/index.ts b/web/core/components/sidebar/index.ts new file mode 100644 index 0000000000..b2e6f7602d --- /dev/null +++ b/web/core/components/sidebar/index.ts @@ -0,0 +1 @@ +export * from "./sidebar-navigation"; \ No newline at end of file diff --git a/web/core/components/sidebar/sidebar-navigation.tsx b/web/core/components/sidebar/sidebar-navigation.tsx new file mode 100644 index 0000000000..f31a93c9c3 --- /dev/null +++ b/web/core/components/sidebar/sidebar-navigation.tsx @@ -0,0 +1,29 @@ +"use client"; +import React, { FC } from "react"; +// helpers +import { cn } from "@/helpers/common.helper"; + +type TSidebarNavItem = { + className?: string; + isActive?: boolean; + children?: React.ReactNode; +}; + +export const SidebarNavItem: FC = (props) => { + const { className, isActive, children } = props; + return ( +
+ {children} +
+ ); +}; diff --git a/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx b/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx index cfffe1265c..443169910f 100644 --- a/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx +++ b/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx @@ -34,7 +34,7 @@ export const NotificationAppSidebarOption: FC = o if (totalNotifications <= 0) return <>; if (isSidebarCollapsed) - return
; + return
; return (
diff --git a/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx b/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx index 09f8427d35..751ef84469 100644 --- a/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx +++ b/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx @@ -19,7 +19,7 @@ export const NotificationFilter: FC = observer(() => { +
diff --git a/web/core/components/workspace-notifications/sidebar/header/root.tsx b/web/core/components/workspace-notifications/sidebar/header/root.tsx index 5804c18370..dd6a36cf87 100644 --- a/web/core/components/workspace-notifications/sidebar/header/root.tsx +++ b/web/core/components/workspace-notifications/sidebar/header/root.tsx @@ -2,7 +2,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; -import { Bell } from "lucide-react"; +import { Inbox } from "lucide-react"; import { Breadcrumbs } from "@plane/ui"; // components import { BreadcrumbLink } from "@/components/common"; @@ -27,11 +27,7 @@ export const NotificationSidebarHeader: FC = observe } - disableTooltip - /> + } disableTooltip /> } /> diff --git a/web/core/components/workspace/sidebar/dropdown.tsx b/web/core/components/workspace/sidebar/dropdown.tsx index 3d4995784c..5319d8500e 100644 --- a/web/core/components/workspace/sidebar/dropdown.tsx +++ b/web/core/components/workspace/sidebar/dropdown.tsx @@ -6,7 +6,7 @@ import Link from "next/link"; import { useParams } from "next/navigation"; import { usePopper } from "react-popper"; // icons -import { Activity, Check, ChevronDown, LogOut, Mails, PlusSquare, Settings } from "lucide-react"; +import { Check, ChevronDown, LogOut, Mails, PlusSquare, Settings } from "lucide-react"; // ui import { Menu, Transition } from "@headlessui/react"; // types @@ -34,19 +34,6 @@ const userLinks = (workspaceSlug: string) => [ }, ]; -const profileLinks = (workspaceSlug: string, userId: string) => [ - { - name: "My activity", - icon: Activity, - link: `/${workspaceSlug}/profile/${userId}`, - }, - { - name: "Settings", - icon: Settings, - link: "/profile", - }, -]; - export const SidebarDropdown = observer(() => { // router params const { workspaceSlug } = useParams(); @@ -285,22 +272,14 @@ export const SidebarDropdown = observer(() => { >
{currentUser?.email} - {profileLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link, index) => ( - { - if (index == 0) handleItemClick(); - }} - > - - - - {link.name} - - - - ))} + + + + + Settings + + +
[ href: `/${workspaceSlug}/projects/${projectId}/inbox`, Icon: Intake, }, - { - name: "Settings", - href: `/${workspaceSlug}/projects/${projectId}/settings`, - Icon: Settings, - }, ]; export const SidebarProjectsListItem: React.FC = observer((props) => { @@ -467,7 +463,7 @@ export const SidebarProjectsListItem: React.FC = observer((props) => { leaveFrom="transform scale-100 opacity-100" leaveTo="transform scale-95 opacity-0" > - + {navigation(workspaceSlug?.toString(), project?.id).map((item) => { if ( (item.name === "Cycles" && !project.cycle_view) || @@ -479,31 +475,29 @@ export const SidebarProjectsListItem: React.FC = observer((props) => { return; return ( - - -
+ + - - {!isSidebarCollapsed && {item.name}} -
-
- +
+ + {!isSidebarCollapsed && {item.name}} +
+ + + ); })}
diff --git a/web/core/components/workspace/sidebar/projects-list.tsx b/web/core/components/workspace/sidebar/projects-list.tsx index f1009589a8..578039e2cf 100644 --- a/web/core/components/workspace/sidebar/projects-list.tsx +++ b/web/core/components/workspace/sidebar/projects-list.tsx @@ -153,7 +153,7 @@ export const SidebarProjectsList: FC = observer(() => { { key: "favorite", type: "FAVORITES", - title: "Favorites", + title: "FAVORITES", icon: Star, projects: favoriteProjects, isOpen: isFavoriteProjectsListOpen, @@ -161,7 +161,7 @@ export const SidebarProjectsList: FC = observer(() => { { key: "all", type: "JOINED", - title: "My projects", + title: "MY PROJECTS", icon: Briefcase, projects: joinedProjects, isOpen: isAllProjectsListOpen, @@ -217,7 +217,13 @@ export const SidebarProjectsList: FC = observer(() => { position="right" disabled={!isCollapsed} > - {isCollapsed ? : section.title} + <> + {isCollapsed ? ( + + ) : ( + {section.title} + )} + {!isCollapsed && ( @@ -264,7 +270,7 @@ export const SidebarProjectsList: FC = observer(() => { {section.isOpen && ( { const { isMobile } = usePlatformOS(); const { membership: { currentWorkspaceRole }, + data: currentUser, } = useUser(); // router params const { workspaceSlug } = useParams(); @@ -42,48 +43,47 @@ export const SidebarUserMenu = observer(() => { }); }; + const notificationIndicatorElement = ( + + ); + return (
{SIDEBAR_USER_MENU_ITEMS.map( (link) => workspaceMemberInfo >= link.access && ( - handleLinkClick(link.key)}> - + handleLinkClick(link.key)} > -
- - - - {!sidebarCollapsed &&

{link.label}

} - {link.key === "notifications" && ( - - )} -
-
- +
+ + {!sidebarCollapsed &&

{link.label}

} +
+ {link.key === "notifications" && notificationIndicatorElement} + + + ) )}
diff --git a/web/core/components/workspace/sidebar/workspace-menu.tsx b/web/core/components/workspace/sidebar/workspace-menu.tsx index 15df1c70a7..edf5617a44 100644 --- a/web/core/components/workspace/sidebar/workspace-menu.tsx +++ b/web/core/components/workspace/sidebar/workspace-menu.tsx @@ -8,6 +8,8 @@ import { ChevronRight } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; // ui import { Tooltip } from "@plane/ui"; +// components +import { SidebarNavItem } from "@/components/sidebar"; // constants import { SIDEBAR_WORKSPACE_MENU_ITEMS } from "@/constants/dashboard"; import { SIDEBAR_CLICKED } from "@/constants/event-tracker"; @@ -53,15 +55,21 @@ export const SidebarWorkspaceMenu = observer(() => { if (sidebarCollapsed) toggleWorkspaceMenu(true); }, [sidebarCollapsed, toggleWorkspaceMenu]); + const indicatorElement = ( +
+ +
+ ); + return ( {!sidebarCollapsed && ( toggleWorkspaceMenu(!isWorkspaceMenuOpen)} > - Workspace + WORKSPACE { {isWorkspaceMenuOpen && ( { {SIDEBAR_WORKSPACE_MENU_ITEMS.map( (link) => workspaceMemberInfo >= link.access && ( - handleLinkClick(link.key)} - className="block" + tooltipContent={link.label} + position="right" + className="ml-2" + disabled={!sidebarCollapsed} + isMobile={isMobile} > - -
handleLinkClick(link.key)}> + -
- - - +
+ {!sidebarCollapsed &&

{link.label}

}
- {!sidebarCollapsed && link.key === "active-cycles" && ( -
- -
- )} -
- - + {!sidebarCollapsed && link.key === "active-cycles" && indicatorElement} +
+ + ) )} diff --git a/web/core/constants/dashboard.ts b/web/core/constants/dashboard.ts index 8ffc6f38e4..907a0ace13 100644 --- a/web/core/constants/dashboard.ts +++ b/web/core/constants/dashboard.ts @@ -2,11 +2,11 @@ import { linearGradientDef } from "@nivo/core"; // icons -import { BarChart2, Bell, Briefcase, CheckCircle, Home, Settings } from "lucide-react"; +import { BarChart2, Briefcase, Home, Inbox, Layers } from "lucide-react"; // types import { TIssuesListTypes, TStateGroups } from "@plane/types"; // ui -import { ContrastIcon } from "@plane/ui"; +import { ContrastIcon, UserActivityIcon } from "@plane/ui"; import { Props } from "@/components/icons/types"; // assets import CompletedIssuesDark from "@/public/empty-state/dashboard/dark/completed-issues.svg"; @@ -259,14 +259,6 @@ export const SIDEBAR_WORKSPACE_MENU_ITEMS: { highlight: (pathname: string, baseUrl: string) => boolean; Icon: React.FC; }[] = [ - { - key: "all-issues", - label: "All Issues", - href: `/workspace-views/all-issues`, - access: EUserWorkspaceRoles.GUEST, - highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/workspace-views/`), - Icon: CheckCircle, - }, { key: "projects", label: "Projects", @@ -275,9 +267,17 @@ export const SIDEBAR_WORKSPACE_MENU_ITEMS: { highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/projects/`, Icon: Briefcase, }, + { + key: "all-issues", + label: "Views", + href: `/workspace-views/all-issues`, + access: EUserWorkspaceRoles.GUEST, + highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/workspace-views/`), + Icon: Layers, + }, { key: "active-cycles", - label: "Active Cycles", + label: "Cycles", href: `/active-cycles`, access: EUserWorkspaceRoles.GUEST, highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/active-cycles/`, @@ -291,14 +291,6 @@ export const SIDEBAR_WORKSPACE_MENU_ITEMS: { highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/analytics/`), Icon: BarChart2, }, - { - key: "settings", - label: "Settings", - href: `/settings`, - access: EUserWorkspaceRoles.GUEST, - highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/settings/`), - Icon: Settings, - }, ]; export const SIDEBAR_USER_MENU_ITEMS: { @@ -317,12 +309,20 @@ export const SIDEBAR_USER_MENU_ITEMS: { highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/`, Icon: Home, }, + { + key: "my-work", + label: "My Work", + href: "/profile", + access: EUserWorkspaceRoles.GUEST, + highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/profile/`), + Icon: UserActivityIcon, + }, { key: "notifications", - label: "Notifications", + label: "Inbox", href: `/notifications`, access: EUserWorkspaceRoles.GUEST, - highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/notifications`, - Icon: Bell, + highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/notifications/`), + Icon: Inbox, }, ];