chore: breadcrumb component improvement (#3537)

* chore: breadcrumb component improvement

* chore: code refactor
This commit is contained in:
Anmol Singh Bhatia 2024-02-01 18:13:30 +05:30 committed by GitHub
parent 7d08a57be6
commit 67cf1785b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 480 additions and 323 deletions

View File

@ -2,8 +2,6 @@ import * as React from "react";
// icons // icons
import { ChevronRight } from "lucide-react"; import { ChevronRight } from "lucide-react";
// components
import { Tooltip } from "../tooltip";
type BreadcrumbsProps = { type BreadcrumbsProps = {
children: any; children: any;
@ -25,42 +23,11 @@ const Breadcrumbs = ({ children }: BreadcrumbsProps) => (
type Props = { type Props = {
type?: "text" | "component"; type?: "text" | "component";
component?: React.ReactNode; component?: React.ReactNode;
label?: string; link?: JSX.Element;
icon?: React.ReactNode;
link?: string;
}; };
const BreadcrumbItem: React.FC<Props> = (props) => { const BreadcrumbItem: React.FC<Props> = (props) => {
const { type = "text", component, label, icon, link } = props; const { type = "text", component, link } = props;
return ( return <>{type != "text" ? <div className="flex items-center space-x-2">{component}</div> : link}</>;
<>
{type != "text" ? (
<div className="flex items-center space-x-2">{component}</div>
) : (
<Tooltip tooltipContent={label} position="bottom">
<li className="flex items-center space-x-2">
<div className="flex flex-wrap items-center gap-2.5">
{link ? (
<a
className="flex items-center gap-1 text-sm font-medium text-custom-text-300 hover:text-custom-text-100"
href={link}
>
{icon && (
<div className="flex h-5 w-5 items-center justify-center overflow-hidden !text-[1rem]">{icon}</div>
)}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</a>
) : (
<div className="flex cursor-default items-center gap-1 text-sm font-medium text-custom-text-100">
{icon && <div className="flex h-5 w-5 items-center justify-center overflow-hidden">{icon}</div>}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</div>
)}
</div>
</li>
</Tooltip>
)}
</>
);
}; };
Breadcrumbs.BreadcrumbItem = BreadcrumbItem; Breadcrumbs.BreadcrumbItem = BreadcrumbItem;

View File

@ -0,0 +1,36 @@
import { Tooltip } from "@plane/ui";
import Link from "next/link";
type Props = {
label?: string;
href?: string;
icon?: React.ReactNode | undefined;
};
export const BreadcrumbLink: React.FC<Props> = (props) => {
const { href, label, icon } = props;
return (
<Tooltip tooltipContent={label} position="bottom">
<li className="flex items-center space-x-2">
<div className="flex flex-wrap items-center gap-2.5">
{href ? (
<Link
className="flex items-center gap-1 text-sm font-medium text-custom-text-300 hover:text-custom-text-100"
href={href}
>
{icon && (
<div className="flex h-5 w-5 items-center justify-center overflow-hidden !text-[1rem]">{icon}</div>
)}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</Link>
) : (
<div className="flex cursor-default items-center gap-1 text-sm font-medium text-custom-text-100">
{icon && <div className="flex h-5 w-5 items-center justify-center overflow-hidden">{icon}</div>}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</div>
)}
</div>
</li>
</Tooltip>
);
};

View File

@ -1,3 +1,4 @@
export * from "./product-updates-modal"; export * from "./product-updates-modal";
export * from "./empty-state"; export * from "./empty-state";
export * from "./latest-feature-block"; export * from "./latest-feature-block";
export * from "./breadcrumb-link";

View File

@ -18,6 +18,7 @@ import useLocalStorage from "hooks/use-local-storage";
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
import { ProjectAnalyticsModal } from "components/analytics"; import { ProjectAnalyticsModal } from "components/analytics";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, Button, ContrastIcon, CustomMenu } from "@plane/ui"; import { Breadcrumbs, Button, ContrastIcon, CustomMenu } from "@plane/ui";
// icons // icons
@ -151,25 +152,33 @@ export const CycleIssuesHeader: React.FC = observer(() => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="flex h-4 w-4 items-center justify-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="flex h-4 w-4 items-center justify-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<ContrastIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Cycles" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${projectId}/cycles`} label="Cycles"
href={`/${workspaceSlug}/projects/${projectId}/cycles`}
icon={<ContrastIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="component" type="component"

View File

@ -11,6 +11,7 @@ import { renderEmoji } from "helpers/emoji.helper";
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export const CyclesHeader: FC = observer(() => { export const CyclesHeader: FC = observer(() => {
// router // router
@ -32,29 +33,32 @@ export const CyclesHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
) : currentProjectDetails?.icon_prop ? ( icon={
renderEmoji(currentProjectDetails.icon_prop) currentProjectDetails?.emoji ? (
) : ( renderEmoji(currentProjectDetails.emoji)
<span className="flex h-4 w-4 items-center justify-center rounded bg-gray-700 uppercase text-white"> ) : currentProjectDetails?.icon_prop ? (
{currentProjectDetails?.name.charAt(0)} renderEmoji(currentProjectDetails.icon_prop)
</span> ) : (
) <span className="flex h-4 w-4 items-center justify-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<ContrastIcon className="h-4 w-4 text-custom-text-300" />} link={<BreadcrumbLink label="Cycles" icon={<ContrastIcon className="h-4 w-4 text-custom-text-300" />} />}
label="Cycles"
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -8,6 +8,7 @@ import { useLabel, useMember, useUser, useIssues } from "hooks/store";
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection } from "components/issues";
import { CreateUpdateWorkspaceViewModal } from "components/workspace"; import { CreateUpdateWorkspaceViewModal } from "components/workspace";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, Button, LayersIcon, PhotoFilterIcon, Tooltip } from "@plane/ui"; import { Breadcrumbs, Button, LayersIcon, PhotoFilterIcon, Tooltip } from "@plane/ui";
// icons // icons
@ -108,18 +109,22 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
<CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} /> <CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} />
<div className="relative z-10 flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="relative flex gap-2"> <div className="relative flex gap-2">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
activeLayout === "spreadsheet" ? ( <BreadcrumbLink
<LayersIcon className="h-4 w-4 text-custom-text-300" /> label={`All ${activeLayout === "spreadsheet" ? "Issues" : "Views"}`}
) : ( icon={
<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" /> activeLayout === "spreadsheet" ? (
) <LayersIcon className="h-4 w-4 text-custom-text-300" />
) : (
<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />
)
}
/>
} }
label={`All ${activeLayout === "spreadsheet" ? "Issues" : "Views"}`}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -18,6 +18,7 @@ import useLocalStorage from "hooks/use-local-storage";
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
import { ProjectAnalyticsModal } from "components/analytics"; import { ProjectAnalyticsModal } from "components/analytics";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, Button, CustomMenu, DiceIcon } from "@plane/ui"; import { Breadcrumbs, Button, CustomMenu, DiceIcon } from "@plane/ui";
// icons // icons
@ -154,25 +155,33 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Modules" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${projectId}/modules`} href={`/${workspaceSlug}/projects/${projectId}/modules`}
label="Modules"
icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="component" type="component"

View File

@ -13,6 +13,7 @@ import { MODULE_VIEW_LAYOUTS } from "constants/module";
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export const ModulesListHeader: React.FC = observer(() => { export const ModulesListHeader: React.FC = observer(() => {
// router // router
@ -33,29 +34,32 @@ export const ModulesListHeader: React.FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( icon={
renderEmoji(currentProjectDetails.icon_prop) currentProjectDetails?.emoji ? (
) : ( renderEmoji(currentProjectDetails.emoji)
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> ) : currentProjectDetails?.icon_prop ? (
{currentProjectDetails?.name.charAt(0)} renderEmoji(currentProjectDetails.icon_prop)
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />} link={<BreadcrumbLink label="Modules" icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />} />}
label="Modules"
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -10,6 +10,7 @@ import { Breadcrumbs, Button } from "@plane/ui";
import { renderEmoji } from "helpers/emoji.helper"; import { renderEmoji } from "helpers/emoji.helper";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export interface IPagesHeaderProps { export interface IPagesHeaderProps {
showButton?: boolean; showButton?: boolean;
@ -29,35 +30,47 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( icon={
renderEmoji(currentProjectDetails.icon_prop) currentProjectDetails?.emoji ? (
) : ( renderEmoji(currentProjectDetails.emoji)
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> ) : currentProjectDetails?.icon_prop ? (
{currentProjectDetails?.name.charAt(0)} renderEmoji(currentProjectDetails.icon_prop)
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<FileText className="h-4 w-4 text-custom-text-300" />} link={
label="Pages" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/pages`} href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/pages`}
label="Pages"
icon={<FileText className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<FileText className="h-4 w-4 text-custom-text-300" />} link={
label={pageDetails?.name ?? "Page"} <BreadcrumbLink
label={pageDetails?.name ?? "Page"}
icon={<FileText className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -11,6 +11,7 @@ import { renderEmoji } from "helpers/emoji.helper";
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export const PagesHeader = observer(() => { export const PagesHeader = observer(() => {
// router // router
@ -31,29 +32,32 @@ export const PagesHeader = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( icon={
renderEmoji(currentProjectDetails.icon_prop) currentProjectDetails?.emoji ? (
) : ( renderEmoji(currentProjectDetails.emoji)
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> ) : currentProjectDetails?.icon_prop ? (
{currentProjectDetails?.name.charAt(0)} renderEmoji(currentProjectDetails.icon_prop)
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<FileText className="h-4 w-4 text-custom-text-300" />} link={<BreadcrumbLink label="Pages" icon={<FileText className="h-4 w-4 text-custom-text-300" />} />}
label="Pages"
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -1,12 +1,13 @@
// components // components
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
import { BreadcrumbLink } from "components/common";
export const ProfilePreferencesHeader = () => ( export const ProfilePreferencesHeader = () => (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem type="text" label="My Profile Preferences" /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink label="My Profile Preferences" />} />
</Breadcrumbs> </Breadcrumbs>
</div> </div>
</div> </div>

View File

@ -2,6 +2,7 @@ import { FC } from "react";
// ui // ui
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
import { Settings } from "lucide-react"; import { Settings } from "lucide-react";
import { BreadcrumbLink } from "components/common";
interface IProfileSettingHeader { interface IProfileSettingHeader {
title: string; title: string;
@ -17,11 +18,15 @@ export const ProfileSettingsHeader: FC<IProfileSettingHeader> = (props) => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label="My Profile" link={
icon={<Settings className="h-4 w-4 text-custom-text-300" />} <BreadcrumbLink
link="/profile" href="/profile"
label="My Profile"
icon={<Settings className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem type="text" label={title} /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink label={title} />} />
</Breadcrumbs> </Breadcrumbs>
</div> </div>
</div> </div>

View File

@ -16,6 +16,7 @@ import { IssueArchiveService } from "services/issue";
import { renderEmoji } from "helpers/emoji.helper"; import { renderEmoji } from "helpers/emoji.helper";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
const issueArchiveService = new IssueArchiveService(); const issueArchiveService = new IssueArchiveService();
@ -41,37 +42,50 @@ export const ProjectArchivedIssueDetailsHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects`}
) : currentProjectDetails?.icon_prop ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Archived Issues" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${projectId}/archived-issues`} href={`/${workspaceSlug}/projects/${projectId}/archived-issues`}
label="Archived Issues"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={ link={
`${getProjectById(issueDetails?.project_id || "")?.identifier}-${issueDetails?.sequence_id}` ?? "..." <BreadcrumbLink
label={
`${getProjectById(issueDetails?.project_id || "")?.identifier}-${issueDetails?.sequence_id}` ??
"..."
}
/>
} }
/> />
</Breadcrumbs> </Breadcrumbs>

View File

@ -11,6 +11,7 @@ import { Breadcrumbs, LayersIcon } from "@plane/ui";
// components // components
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "components/issues"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "components/issues";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// helpers // helpers
import { renderEmoji } from "helpers/emoji.helper"; import { renderEmoji } from "helpers/emoji.helper";
// types // types
@ -71,7 +72,7 @@ export const ProjectArchivedIssuesHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-14 w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-14 w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div className="block md:hidden"> <div className="block md:hidden">
<button <button
type="button" type="button"
@ -85,25 +86,33 @@ export const ProjectArchivedIssuesHeader: FC = observer(() => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects`}
) : currentProjectDetails?.icon_prop ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Archived Issues" <BreadcrumbLink
label="Archived Issues"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -6,6 +6,7 @@ import { useIssues, useLabel, useMember, useProject, useProjectState } from "hoo
// components // components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, LayersIcon } from "@plane/ui"; import { Breadcrumbs, LayersIcon } from "@plane/ui";
// helper // helper
@ -75,30 +76,35 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects`}
) : currentProjectDetails?.icon_prop ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Draft Issues" <BreadcrumbLink label="Inbox Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -9,6 +9,7 @@ import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
// components // components
import { CreateInboxIssueModal } from "components/inbox"; import { CreateInboxIssueModal } from "components/inbox";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// helper // helper
import { renderEmoji } from "helpers/emoji.helper"; import { renderEmoji } from "helpers/emoji.helper";
@ -24,30 +25,35 @@ export const ProjectInboxHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects`}
) : currentProjectDetails?.icon_prop ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Inbox Issues" <BreadcrumbLink label="Inbox Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -14,6 +14,7 @@ import { IssueService } from "services/issue";
import { ISSUE_DETAILS } from "constants/fetch-keys"; import { ISSUE_DETAILS } from "constants/fetch-keys";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// services // services
const issueService = new IssueService(); const issueService = new IssueService();
@ -35,37 +36,50 @@ export const ProjectIssueDetailsHeader: FC = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails?.emoji ? ( <BreadcrumbLink
renderEmoji(currentProjectDetails.emoji) href={`/${workspaceSlug}/projects`}
) : currentProjectDetails?.icon_prop ? ( label={currentProjectDetails?.name ?? "Project"}
renderEmoji(currentProjectDetails.icon_prop) icon={
) : ( currentProjectDetails?.emoji ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> renderEmoji(currentProjectDetails.emoji)
{currentProjectDetails?.name.charAt(0)} ) : currentProjectDetails?.icon_prop ? (
</span> renderEmoji(currentProjectDetails.icon_prop)
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Issues" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${projectId}/issues`} href={`/${workspaceSlug}/projects/${projectId}/issues`}
label="Issues"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={ link={
`${getProjectById(issueDetails?.project_id || "")?.identifier}-${issueDetails?.sequence_id}` ?? "..." <BreadcrumbLink
label={
`${getProjectById(issueDetails?.project_id || "")?.identifier}-${issueDetails?.sequence_id}` ??
"..."
}
/>
} }
/> />
</Breadcrumbs> </Breadcrumbs>

View File

@ -9,6 +9,7 @@ import { useApplication, useLabel, useProject, useProjectState, useUser, useInbo
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
import { ProjectAnalyticsModal } from "components/analytics"; import { ProjectAnalyticsModal } from "components/analytics";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui"; import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
// types // types
@ -106,7 +107,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
/> />
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div className="block md:hidden"> <div className="block md:hidden">
<button <button
type="button" type="button"
@ -120,35 +121,38 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={ link={
currentProjectDetails ? ( <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects`}
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase"> label={currentProjectDetails?.name ?? "Project"}
{renderEmoji(currentProjectDetails.emoji)} icon={
</span> currentProjectDetails ? (
) : currentProjectDetails?.icon_prop ? ( currentProjectDetails?.emoji ? (
<div className="grid h-7 w-7 flex-shrink-0 place-items-center"> <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
{renderEmoji(currentProjectDetails.icon_prop)} {renderEmoji(currentProjectDetails.emoji)}
</div> </span>
) : ( ) : currentProjectDetails?.icon_prop ? (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> <div className="grid h-7 w-7 flex-shrink-0 place-items-center">
{currentProjectDetails?.name.charAt(0)} {renderEmoji(currentProjectDetails.icon_prop)}
</span> </div>
) ) : (
) : ( <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase"> {currentProjectDetails?.name.charAt(0)}
<Briefcase className="h-4 w-4" /> </span>
</span> )
) ) : (
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
<Briefcase className="h-4 w-4" />
</span>
)
}
/>
} }
label={currentProjectDetails?.name ?? "Project"}
link={`/${workspaceSlug}/projects`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} link={<BreadcrumbLink label="Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />}
label="Issues"
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -11,6 +11,7 @@ import { useProject, useUser } from "hooks/store";
import { EUserProjectRoles, PROJECT_SETTINGS_LINKS } from "constants/project"; import { EUserProjectRoles, PROJECT_SETTINGS_LINKS } from "constants/project";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export interface IProjectSettingHeader { export interface IProjectSettingHeader {
title: string; title: string;
@ -38,22 +39,26 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
renderEmoji(currentProjectDetails.emoji) label={currentProjectDetails?.name ?? "Project"}
) : currentProjectDetails?.icon_prop ? ( icon={
renderEmoji(currentProjectDetails.icon_prop) currentProjectDetails?.emoji ? (
) : ( renderEmoji(currentProjectDetails.emoji)
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> ) : currentProjectDetails?.icon_prop ? (
{currentProjectDetails?.name.charAt(0)} renderEmoji(currentProjectDetails.icon_prop)
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<div className="hidden sm:hidden md:block lg:block"> <div className="hidden sm:hidden md:block lg:block">
<Breadcrumbs.BreadcrumbItem type="text" label={title} /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink label={title} />} />
</div> </div>
</Breadcrumbs> </Breadcrumbs>
</div> </div>
@ -62,13 +67,18 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
className="flex-shrink-0 block sm:block md:hidden lg:hidden" className="flex-shrink-0 block sm:block md:hidden lg:hidden"
maxHeight="lg" maxHeight="lg"
customButton={ customButton={
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">{title}</span> <span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">
{title}
</span>
} }
placement="bottom-start" placement="bottom-start"
closeOnSelect closeOnSelect
> >
{PROJECT_SETTINGS_LINKS.map((item) => ( {PROJECT_SETTINGS_LINKS.map((item) => (
<CustomMenu.MenuItem key={item.key} onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}${item.href}`)}> <CustomMenu.MenuItem
key={item.key}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}${item.href}`)}
>
{item.label} {item.label}
</CustomMenu.MenuItem> </CustomMenu.MenuItem>
))} ))}

View File

@ -17,6 +17,7 @@ import {
// components // components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// ui // ui
import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui"; import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui";
// helpers // helpers
@ -112,29 +113,37 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase"> label={currentProjectDetails?.name ?? "Project"}
{renderEmoji(currentProjectDetails.emoji)} icon={
</span> currentProjectDetails?.emoji ? (
) : currentProjectDetails?.icon_prop ? ( <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
<div className="grid h-7 w-7 flex-shrink-0 place-items-center"> {renderEmoji(currentProjectDetails.emoji)}
{renderEmoji(currentProjectDetails.icon_prop)} </span>
</div> ) : currentProjectDetails?.icon_prop ? (
) : ( <div className="grid h-7 w-7 flex-shrink-0 place-items-center">
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> {renderEmoji(currentProjectDetails.icon_prop)}
{currentProjectDetails?.name.charAt(0)} </div>
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Views" <BreadcrumbLink
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/views`} href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/views`}
label="Views"
icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="component" type="component"

View File

@ -6,6 +6,7 @@ import { useApplication, useProject, useUser } from "hooks/store";
// components // components
import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui"; import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
// helpers // helpers
import { renderEmoji } from "helpers/emoji.helper"; import { renderEmoji } from "helpers/emoji.helper";
// constants // constants
@ -31,33 +32,38 @@ export const ProjectViewsHeader: React.FC = observer(() => {
<> <>
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label={currentProjectDetails?.name ?? "Project"} link={
icon={ <BreadcrumbLink
currentProjectDetails?.emoji ? ( href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase"> label={currentProjectDetails?.name ?? "Project"}
{renderEmoji(currentProjectDetails.emoji)} icon={
</span> currentProjectDetails?.emoji ? (
) : currentProjectDetails?.icon_prop ? ( <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
<div className="grid h-7 w-7 flex-shrink-0 place-items-center"> {renderEmoji(currentProjectDetails.emoji)}
{renderEmoji(currentProjectDetails.icon_prop)} </span>
</div> ) : currentProjectDetails?.icon_prop ? (
) : ( <div className="grid h-7 w-7 flex-shrink-0 place-items-center">
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white"> {renderEmoji(currentProjectDetails.icon_prop)}
{currentProjectDetails?.name.charAt(0)} </div>
</span> ) : (
) <span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
{currentProjectDetails?.name.charAt(0)}
</span>
)
}
/>
} }
link={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
/> />
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />} link={
label="Views" <BreadcrumbLink label="Views" icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />} />
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -8,6 +8,7 @@ import { Breadcrumbs, Button } from "@plane/ui";
import { EUserWorkspaceRoles } from "constants/workspace"; import { EUserWorkspaceRoles } from "constants/workspace";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export const ProjectsHeader = observer(() => { export const ProjectsHeader = observer(() => {
// store hooks // store hooks
@ -25,13 +26,12 @@ export const ProjectsHeader = observer(() => {
return ( return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<Briefcase className="h-4 w-4 text-custom-text-300" />} link={<BreadcrumbLink label="Projects" icon={<Briefcase className="h-4 w-4 text-custom-text-300" />} />}
label="Projects"
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -1,15 +1,16 @@
// ui // ui
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
import { BreadcrumbLink } from "components/common";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
export const UserProfileHeader = () => ( export const UserProfileHeader = () => (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap"> <div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle/> <SidebarHamburgerToggle />
<div> <div>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem type="text" label="Activity Overview" link="/profile" /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink href="/profile" label="Activity Overview" />} />
</Breadcrumbs> </Breadcrumbs>
</div> </div>
</div> </div>

View File

@ -1,9 +1,10 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// ui // ui
import { Breadcrumbs, ContrastIcon } from "@plane/ui"; import { Breadcrumbs, ContrastIcon } from "@plane/ui";
import { BreadcrumbLink } from "components/common";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
// icons // icons
import { Crown } from "lucide-react"; import { Crown } from "lucide-react";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
export const WorkspaceActiveCycleHeader = observer(() => ( export const WorkspaceActiveCycleHeader = observer(() => (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4"> <div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
@ -13,8 +14,12 @@ export const WorkspaceActiveCycleHeader = observer(() => (
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<ContrastIcon className="h-4 w-4 text-custom-text-300 rotate-180" />} link={
label="Active Cycles" <BreadcrumbLink
label="Active Cycles"
icon={<ContrastIcon className="h-4 w-4 text-custom-text-300 rotate-180" />}
/>
}
/> />
</Breadcrumbs> </Breadcrumbs>
<Crown className="h-3.5 w-3.5 text-amber-400" /> <Crown className="h-3.5 w-3.5 text-amber-400" />

View File

@ -4,6 +4,7 @@ import { ArrowLeft, BarChart2 } from "lucide-react";
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { BreadcrumbLink } from "components/common";
export const WorkspaceAnalyticsHeader = () => { export const WorkspaceAnalyticsHeader = () => {
const router = useRouter(); const router = useRouter();
@ -28,8 +29,9 @@ export const WorkspaceAnalyticsHeader = () => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<BarChart2 className="h-4 w-4 text-custom-text-300" />} link={
label="Analytics" <BreadcrumbLink label="Analytics" icon={<BarChart2 className="h-4 w-4 text-custom-text-300" />} />
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -6,7 +6,7 @@ import { useTheme } from "next-themes";
import githubBlackImage from "/public/logos/github-black.png"; import githubBlackImage from "/public/logos/github-black.png";
import githubWhiteImage from "/public/logos/github-white.png"; import githubWhiteImage from "/public/logos/github-white.png";
// components // components
import { ProductUpdatesModal } from "components/common"; import { BreadcrumbLink, ProductUpdatesModal } from "components/common";
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
@ -25,8 +25,9 @@ export const WorkspaceDashboardHeader = () => {
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<LayoutGrid className="h-4 w-4 text-custom-text-300" />} link={
label="Dashboard" <BreadcrumbLink label="Dashboard" icon={<LayoutGrid className="h-4 w-4 text-custom-text-300" />} />
}
/> />
</Breadcrumbs> </Breadcrumbs>
</div> </div>

View File

@ -8,6 +8,7 @@ import { observer } from "mobx-react-lite";
// components // components
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle"; import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
import { WORKSPACE_SETTINGS_LINKS } from "constants/workspace"; import { WORKSPACE_SETTINGS_LINKS } from "constants/workspace";
import { BreadcrumbLink } from "components/common";
export interface IWorkspaceSettingHeader { export interface IWorkspaceSettingHeader {
title: string; title: string;
@ -27,12 +28,16 @@ export const WorkspaceSettingHeader: FC<IWorkspaceSettingHeader> = observer((pro
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
label="Settings" link={
icon={<Settings className="h-4 w-4 text-custom-text-300" />} <BreadcrumbLink
link={`/${workspaceSlug}/settings`} href={`/${workspaceSlug}/settings`}
label="Settings"
icon={<Settings className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<div className="hidden sm:hidden md:block lg:block"> <div className="hidden sm:hidden md:block lg:block">
<Breadcrumbs.BreadcrumbItem type="text" label={title} /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink label={title} />} />
</div> </div>
</Breadcrumbs> </Breadcrumbs>
</div> </div>
@ -40,7 +45,9 @@ export const WorkspaceSettingHeader: FC<IWorkspaceSettingHeader> = observer((pro
className="flex-shrink-0 block sm:block md:hidden lg:hidden" className="flex-shrink-0 block sm:block md:hidden lg:hidden"
maxHeight="lg" maxHeight="lg"
customButton={ customButton={
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">{title}</span> <span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">
{title}
</span>
} }
placement="bottom-start" placement="bottom-start"
closeOnSelect closeOnSelect

View File

@ -5,6 +5,7 @@ import { observer } from "mobx-react-lite";
import { Breadcrumbs } from "@plane/ui"; import { Breadcrumbs } from "@plane/ui";
// icons // icons
import { Settings } from "lucide-react"; import { Settings } from "lucide-react";
import { BreadcrumbLink } from "components/common";
export interface IInstanceAdminHeader { export interface IInstanceAdminHeader {
title?: string; title?: string;
@ -21,11 +22,15 @@ export const InstanceAdminHeader: FC<IInstanceAdminHeader> = observer((props) =>
<Breadcrumbs> <Breadcrumbs>
<Breadcrumbs.BreadcrumbItem <Breadcrumbs.BreadcrumbItem
type="text" type="text"
icon={<Settings className="h-4 w-4 text-custom-text-300" />} link={
label="Settings" <BreadcrumbLink
link="/god-mode" href="/god-mode"
label="Settings"
icon={<Settings className="h-4 w-4 text-custom-text-300" />}
/>
}
/> />
<Breadcrumbs.BreadcrumbItem type="text" label={title} /> <Breadcrumbs.BreadcrumbItem type="text" link={<BreadcrumbLink label={title} />} />
</Breadcrumbs> </Breadcrumbs>
</div> </div>
)} )}