mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
[WEB-4632] fix: sidebar item refactored #7539
This commit is contained in:
@@ -1,71 +1,9 @@
|
|||||||
"use client";
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { IWorkspaceSidebarNavigationItem } from "@plane/constants";
|
||||||
import Link from "next/link";
|
import { SidebarItemBase } from "@/components/workspace/sidebar/sidebar-item";
|
||||||
import { useParams, usePathname } from "next/navigation";
|
|
||||||
// plane imports
|
|
||||||
import { EUserPermissionsLevel, IWorkspaceSidebarNavigationItem } from "@plane/constants";
|
|
||||||
import { useTranslation } from "@plane/i18n";
|
|
||||||
// components
|
|
||||||
import { SidebarNavItem } from "@/components/sidebar";
|
|
||||||
import { NotificationAppSidebarOption } from "@/components/workspace-notifications";
|
|
||||||
// hooks
|
|
||||||
import { useAppTheme, useUser, useUserPermissions, useWorkspace } from "@/hooks/store";
|
|
||||||
// local imports
|
|
||||||
import { getSidebarNavigationItemIcon } from "./helper";
|
|
||||||
|
|
||||||
type TSidebarItemProps = {
|
type Props = {
|
||||||
item: IWorkspaceSidebarNavigationItem;
|
item: IWorkspaceSidebarNavigationItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SidebarItem: FC<TSidebarItemProps> = observer((props) => {
|
export const SidebarItem: FC<Props> = ({ item }) => <SidebarItemBase item={item} />;
|
||||||
const { item } = props;
|
|
||||||
const { t } = useTranslation();
|
|
||||||
// nextjs hooks
|
|
||||||
const pathname = usePathname();
|
|
||||||
const { workspaceSlug } = useParams();
|
|
||||||
const { allowPermissions } = useUserPermissions();
|
|
||||||
const { getNavigationPreferences } = useWorkspace();
|
|
||||||
const { data } = useUser();
|
|
||||||
|
|
||||||
// store hooks
|
|
||||||
const { toggleSidebar, isExtendedSidebarOpened, toggleExtendedSidebar } = useAppTheme();
|
|
||||||
|
|
||||||
const handleLinkClick = () => {
|
|
||||||
if (window.innerWidth < 768) {
|
|
||||||
toggleSidebar();
|
|
||||||
}
|
|
||||||
if (isExtendedSidebarOpened) toggleExtendedSidebar(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const staticItems = ["home", "inbox", "pi-chat", "projects", "your_work"];
|
|
||||||
|
|
||||||
if (!allowPermissions(item.access as any, EUserPermissionsLevel.WORKSPACE, workspaceSlug.toString())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemHref =
|
|
||||||
item.key === "your_work"
|
|
||||||
? `/${workspaceSlug.toString()}${item.href}/${data?.id}`
|
|
||||||
: `/${workspaceSlug.toString()}${item.href}`;
|
|
||||||
|
|
||||||
const isActive = itemHref === pathname;
|
|
||||||
|
|
||||||
const sidebarPreference = getNavigationPreferences(workspaceSlug.toString());
|
|
||||||
const isPinned = sidebarPreference?.[item.key]?.is_pinned;
|
|
||||||
if (!isPinned && !staticItems.includes(item.key)) return null;
|
|
||||||
|
|
||||||
const icon = getSidebarNavigationItemIcon(item.key);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link href={itemHref} onClick={() => handleLinkClick()}>
|
|
||||||
<SidebarNavItem isActive={isActive}>
|
|
||||||
<div className="flex items-center gap-1.5 py-[1px]">
|
|
||||||
{icon}
|
|
||||||
<p className="text-sm leading-5 font-medium">{t(item.labelTranslationKey)}</p>
|
|
||||||
</div>
|
|
||||||
{item.key === "inbox" && <NotificationAppSidebarOption workspaceSlug={workspaceSlug?.toString()} />}
|
|
||||||
</SidebarNavItem>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|||||||
60
apps/web/core/components/workspace/sidebar/sidebar-item.tsx
Normal file
60
apps/web/core/components/workspace/sidebar/sidebar-item.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// SidebarItemBase.tsx
|
||||||
|
"use client";
|
||||||
|
import { FC, ReactNode } from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useParams, usePathname } from "next/navigation";
|
||||||
|
import { EUserPermissionsLevel, IWorkspaceSidebarNavigationItem } from "@plane/constants";
|
||||||
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import { SidebarNavItem } from "@/components/sidebar";
|
||||||
|
import { NotificationAppSidebarOption } from "@/components/workspace-notifications";
|
||||||
|
import { useAppTheme, useUser, useUserPermissions, useWorkspace } from "@/hooks/store";
|
||||||
|
import { getSidebarNavigationItemIcon } from "@/plane-web/components/workspace";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
item: IWorkspaceSidebarNavigationItem;
|
||||||
|
additionalRender?: (itemKey: string, workspaceSlug: string) => ReactNode;
|
||||||
|
additionalStaticItems?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SidebarItemBase: FC<Props> = observer(({ item, additionalRender, additionalStaticItems }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const pathname = usePathname();
|
||||||
|
const { workspaceSlug } = useParams();
|
||||||
|
const { allowPermissions } = useUserPermissions();
|
||||||
|
const { getNavigationPreferences } = useWorkspace();
|
||||||
|
const { data } = useUser();
|
||||||
|
|
||||||
|
const { toggleSidebar, isExtendedSidebarOpened, toggleExtendedSidebar } = useAppTheme();
|
||||||
|
|
||||||
|
const handleLinkClick = () => {
|
||||||
|
if (window.innerWidth < 768) toggleSidebar();
|
||||||
|
if (isExtendedSidebarOpened) toggleExtendedSidebar(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const staticItems = ["home", "inbox", "pi_chat", "projects", "your_work", ...(additionalStaticItems || [])];
|
||||||
|
const slug = workspaceSlug?.toString() || "";
|
||||||
|
|
||||||
|
if (!allowPermissions(item.access as any, EUserPermissionsLevel.WORKSPACE, slug)) return null;
|
||||||
|
|
||||||
|
const sidebarPreference = getNavigationPreferences(slug);
|
||||||
|
const isPinned = sidebarPreference?.[item.key]?.is_pinned;
|
||||||
|
if (!isPinned && !staticItems.includes(item.key)) return null;
|
||||||
|
|
||||||
|
const itemHref = item.key === "your_work" ? `/${slug}${item.href}${data?.id}/` : `/${slug}${item.href}`;
|
||||||
|
const isActive = itemHref === pathname;
|
||||||
|
const icon = getSidebarNavigationItemIcon(item.key);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link href={itemHref} onClick={handleLinkClick}>
|
||||||
|
<SidebarNavItem isActive={isActive}>
|
||||||
|
<div className="flex items-center gap-1.5 py-[1px]">
|
||||||
|
{icon}
|
||||||
|
<p className="text-sm leading-5 font-medium">{t(item.labelTranslationKey)}</p>
|
||||||
|
</div>
|
||||||
|
{item.key === "inbox" && <NotificationAppSidebarOption workspaceSlug={slug} />}
|
||||||
|
{additionalRender?.(item.key, slug)}
|
||||||
|
</SidebarNavItem>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user