forked from github/plane
style/responsive sidebar (#3505)
* style: added sidebar toggle in all the screens for mobile responsive * chore: close sidebar on click of empty space when opened * chore: setting the sidebar collapsed in smaller screens
This commit is contained in:
parent
9debd81a50
commit
c6d6b9a0e9
@ -0,0 +1,16 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { Menu } from "lucide-react";
|
||||||
|
import { useApplication } from "hooks/store";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
|
export const SidebarHamburgerToggle: FC = observer (() => {
|
||||||
|
const { theme: themStore } = useApplication();
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-7 h-7 rounded flex justify-center items-center bg-custom-background-80 transition-all hover:bg-custom-background-90 cursor-pointer group md:hidden"
|
||||||
|
onClick={() => themStore.toggleSidebar()}
|
||||||
|
>
|
||||||
|
<Menu size={14} className="text-custom-text-200 group-hover:text-custom-text-100 transition-all" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
@ -63,34 +63,27 @@ export const OverviewStatsWidget: React.FC<WidgetProps> = observer((props) => {
|
|||||||
if (!widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
if (!widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full grid grid-cols-4 p-0.5 hover:shadow-custom-shadow-4xl duration-300">
|
<div
|
||||||
{STATS_LIST.map((stat, index) => {
|
className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full grid lg:grid-cols-4 md:grid-cols-2 sm:grid-cols-2 grid-cols-2 p-0.5 hover:shadow-custom-shadow-4xl duration-300
|
||||||
const isFirst = index === 0;
|
[&>div>a>div]:border-r
|
||||||
const isLast = index === STATS_LIST.length - 1;
|
[&>div:last-child>a>div]:border-0
|
||||||
const isMiddle = !isFirst && !isLast;
|
[&>div>a>div]:border-custom-border-200
|
||||||
|
[&>div:nth-child(2)>a>div]:border-0
|
||||||
return (
|
[&>div:nth-child(2)>a>div]:lg:border-r
|
||||||
<div key={stat.key} className="flex relative">
|
"
|
||||||
{!isLast && (
|
|
||||||
<div className="absolute right-0 top-1/2 -translate-y-1/2 h-3/5 w-[0.5px] bg-custom-border-200" />
|
|
||||||
)}
|
|
||||||
<Link
|
|
||||||
href={stat.link}
|
|
||||||
className={cn(
|
|
||||||
`py-4 hover:bg-custom-background-80 duration-300 rounded-[10px] w-full break-words flex flex-col justify-center`,
|
|
||||||
{
|
|
||||||
"pl-11 pr-[4.725rem] mr-0.5": isFirst,
|
|
||||||
"px-[4.725rem] mx-0.5": isMiddle,
|
|
||||||
"px-[4.725rem] ml-0.5": isLast,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
|
{STATS_LIST.map((stat) => (
|
||||||
|
<div className="w-full flex flex-col gap-2 hover:bg-custom-background-80 rounded-[10px]">
|
||||||
|
<Link href={stat.link} className="py-4 duration-300 rounded-[10px] w-full ">
|
||||||
|
<div className={`relative flex justify-center items-center`}>
|
||||||
|
<div>
|
||||||
<h5 className="font-semibold text-xl">{stat.count}</h5>
|
<h5 className="font-semibold text-xl">{stat.count}</h5>
|
||||||
<p className="text-custom-text-300 text-sm xl:text-base">{stat.title}</p>
|
<p className="text-custom-text-300 text-sm xl:text-base">{stat.title}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -17,6 +17,7 @@ import useLocalStorage from "hooks/use-local-storage";
|
|||||||
// components
|
// components
|
||||||
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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, Button, ContrastIcon, CustomMenu } from "@plane/ui";
|
import { Breadcrumbs, Button, ContrastIcon, CustomMenu } from "@plane/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -146,6 +147,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
/>
|
/>
|
||||||
<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="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -9,6 +9,8 @@ import { Breadcrumbs, Button, ContrastIcon } from "@plane/ui";
|
|||||||
// helpers
|
// helpers
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
import { EUserProjectRoles } from "constants/project";
|
import { EUserProjectRoles } from "constants/project";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const CyclesHeader: FC = observer(() => {
|
export const CyclesHeader: FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
@ -30,6 +32,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -7,6 +7,7 @@ import { useLabel, useMember, useUser, useIssues } from "hooks/store";
|
|||||||
// components
|
// components
|
||||||
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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, Button, LayersIcon, PhotoFilterIcon, Tooltip } from "@plane/ui";
|
import { Breadcrumbs, Button, LayersIcon, PhotoFilterIcon, Tooltip } from "@plane/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -106,7 +107,8 @@ 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>
|
<div className="relative flex gap-2">
|
||||||
|
<SidebarHamburgerToggle/>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -17,6 +17,7 @@ import useLocalStorage from "hooks/use-local-storage";
|
|||||||
// components
|
// components
|
||||||
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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, Button, CustomMenu, DiceIcon } from "@plane/ui";
|
import { Breadcrumbs, Button, CustomMenu, DiceIcon } from "@plane/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -149,6 +150,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
/>
|
/>
|
||||||
<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="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -11,6 +11,8 @@ import { renderEmoji } from "helpers/emoji.helper";
|
|||||||
// constants
|
// constants
|
||||||
import { MODULE_VIEW_LAYOUTS } from "constants/module";
|
import { MODULE_VIEW_LAYOUTS } from "constants/module";
|
||||||
import { EUserProjectRoles } from "constants/project";
|
import { EUserProjectRoles } from "constants/project";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const ModulesListHeader: React.FC = observer(() => {
|
export const ModulesListHeader: React.FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
@ -31,6 +33,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -8,6 +8,8 @@ import { useApplication, usePage, useProject } from "hooks/store";
|
|||||||
import { Breadcrumbs, Button } from "@plane/ui";
|
import { Breadcrumbs, Button } from "@plane/ui";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export interface IPagesHeaderProps {
|
export interface IPagesHeaderProps {
|
||||||
showButton?: boolean;
|
showButton?: boolean;
|
||||||
@ -27,6 +29,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -9,6 +9,8 @@ import { Breadcrumbs, Button } from "@plane/ui";
|
|||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
// constants
|
// constants
|
||||||
import { EUserProjectRoles } from "constants/project";
|
import { EUserProjectRoles } from "constants/project";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const PagesHeader = observer(() => {
|
export const PagesHeader = observer(() => {
|
||||||
// router
|
// router
|
||||||
@ -29,6 +31,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -14,6 +14,8 @@ import { ISSUE_DETAILS } from "constants/fetch-keys";
|
|||||||
import { IssueArchiveService } from "services/issue";
|
import { IssueArchiveService } from "services/issue";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
const issueArchiveService = new IssueArchiveService();
|
const issueArchiveService = new IssueArchiveService();
|
||||||
|
|
||||||
@ -39,6 +41,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -10,6 +10,7 @@ import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } f
|
|||||||
import { Breadcrumbs, LayersIcon } from "@plane/ui";
|
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";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
// types
|
// types
|
||||||
@ -70,6 +71,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/>
|
||||||
<div className="block md:hidden">
|
<div className="block md:hidden">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -5,6 +5,7 @@ import { observer } from "mobx-react-lite";
|
|||||||
import { useIssues, useLabel, useMember, useProject, useProjectState } from "hooks/store";
|
import { useIssues, useLabel, useMember, useProject, useProjectState } from "hooks/store";
|
||||||
// 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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, LayersIcon } from "@plane/ui";
|
import { Breadcrumbs, LayersIcon } from "@plane/ui";
|
||||||
// helper
|
// helper
|
||||||
@ -74,6 +75,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -8,6 +8,7 @@ import { useProject } from "hooks/store";
|
|||||||
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
|
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";
|
||||||
// helper
|
// helper
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -12,6 +12,8 @@ import { renderEmoji } from "helpers/emoji.helper";
|
|||||||
import { IssueService } from "services/issue";
|
import { IssueService } from "services/issue";
|
||||||
// constants
|
// constants
|
||||||
import { ISSUE_DETAILS } from "constants/fetch-keys";
|
import { ISSUE_DETAILS } from "constants/fetch-keys";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
// services
|
// services
|
||||||
const issueService = new IssueService();
|
const issueService = new IssueService();
|
||||||
@ -33,6 +35,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -8,6 +8,7 @@ import { useApplication, useLabel, useProject, useProjectState, useUser, useInbo
|
|||||||
// components
|
// components
|
||||||
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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
|
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
|
||||||
// types
|
// types
|
||||||
@ -105,6 +106,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/>
|
||||||
<div className="block md:hidden">
|
<div className="block md:hidden">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -9,6 +9,8 @@ import { renderEmoji } from "helpers/emoji.helper";
|
|||||||
import { useProject, useUser } from "hooks/store";
|
import { useProject, useUser } from "hooks/store";
|
||||||
// constants
|
// constants
|
||||||
import { EUserProjectRoles } from "constants/project";
|
import { EUserProjectRoles } from "constants/project";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export interface IProjectSettingHeader {
|
export interface IProjectSettingHeader {
|
||||||
title: string;
|
title: string;
|
||||||
@ -30,6 +32,7 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
} from "hooks/store";
|
} from "hooks/store";
|
||||||
// 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";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui";
|
import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui";
|
||||||
// helpers
|
// helpers
|
||||||
@ -107,6 +108,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
|||||||
return (
|
return (
|
||||||
<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="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -5,6 +5,7 @@ import { Plus } from "lucide-react";
|
|||||||
import { useApplication, useProject, useUser } from "hooks/store";
|
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";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
// constants
|
// constants
|
||||||
@ -30,6 +31,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -6,6 +6,8 @@ import { useApplication, useProject, useUser } from "hooks/store";
|
|||||||
import { Breadcrumbs, Button } from "@plane/ui";
|
import { Breadcrumbs, Button } from "@plane/ui";
|
||||||
// constants
|
// constants
|
||||||
import { EUserWorkspaceRoles } from "constants/workspace";
|
import { EUserWorkspaceRoles } from "constants/workspace";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const ProjectsHeader = observer(() => {
|
export const ProjectsHeader = observer(() => {
|
||||||
// store hooks
|
// store hooks
|
||||||
@ -23,6 +25,7 @@ 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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs } from "@plane/ui";
|
import { Breadcrumbs } from "@plane/ui";
|
||||||
|
// components
|
||||||
|
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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem type="text" label="Activity Overview" link="/profile" />
|
<Breadcrumbs.BreadcrumbItem type="text" label="Activity Overview" link="/profile" />
|
||||||
|
@ -3,10 +3,12 @@ import { observer } from "mobx-react-lite";
|
|||||||
import { Breadcrumbs, ContrastIcon } from "@plane/ui";
|
import { Breadcrumbs, ContrastIcon } from "@plane/ui";
|
||||||
// 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">
|
||||||
<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 />
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -2,6 +2,8 @@ import { useRouter } from "next/router";
|
|||||||
import { ArrowLeft, BarChart2 } from "lucide-react";
|
import { ArrowLeft, BarChart2 } from "lucide-react";
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs } from "@plane/ui";
|
import { Breadcrumbs } from "@plane/ui";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const WorkspaceAnalyticsHeader = () => {
|
export const WorkspaceAnalyticsHeader = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -12,6 +14,7 @@ export const WorkspaceAnalyticsHeader = () => {
|
|||||||
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`}
|
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 />
|
||||||
<div className="block md:hidden">
|
<div className="block md:hidden">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -8,10 +8,11 @@ import githubWhiteImage from "/public/logos/github-white.png";
|
|||||||
// components
|
// components
|
||||||
import { ProductUpdatesModal } from "components/common";
|
import { ProductUpdatesModal } from "components/common";
|
||||||
import { Breadcrumbs } from "@plane/ui";
|
import { Breadcrumbs } from "@plane/ui";
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export const WorkspaceDashboardHeader = () => {
|
export const WorkspaceDashboardHeader = () => {
|
||||||
const [isProductUpdatesModalOpen, setIsProductUpdatesModalOpen] = useState(false);
|
const [isProductUpdatesModalOpen, setIsProductUpdatesModalOpen] = useState(false);
|
||||||
// theme
|
// hooks
|
||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -19,6 +20,7 @@ export const WorkspaceDashboardHeader = () => {
|
|||||||
<ProductUpdatesModal isOpen={isProductUpdatesModalOpen} setIsOpen={setIsProductUpdatesModalOpen} />
|
<ProductUpdatesModal isOpen={isProductUpdatesModalOpen} setIsOpen={setIsProductUpdatesModalOpen} />
|
||||||
<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 items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
// ui
|
// ui
|
||||||
import { Breadcrumbs } from "@plane/ui";
|
import { Breadcrumbs } from "@plane/ui";
|
||||||
import { Settings } from "lucide-react";
|
import { Settings } from "lucide-react";
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
// components
|
||||||
|
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||||
|
|
||||||
export interface IWorkspaceSettingHeader {
|
export interface IWorkspaceSettingHeader {
|
||||||
title: string;
|
title: string;
|
||||||
@ -22,6 +21,7 @@ export const WorkspaceSettingHeader: FC<IWorkspaceSettingHeader> = observer((pro
|
|||||||
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/>
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
|
@ -131,6 +131,12 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
setLeaveProjectModal(false);
|
setLeaveProjectModal(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleProjectClick = () => {
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
themeStore.toggleSidebar();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false));
|
useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false));
|
||||||
|
|
||||||
if (!project) return null;
|
if (!project) return null;
|
||||||
@ -143,8 +149,7 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`group relative flex w-full items-center rounded-md px-2 py-1 text-custom-sidebar-text-10 hover:bg-custom-sidebar-background-80 ${
|
className={`group relative flex w-full items-center rounded-md px-2 py-1 text-custom-sidebar-text-10 hover:bg-custom-sidebar-background-80 ${snapshot?.isDragging ? "opacity-60" : ""
|
||||||
snapshot?.isDragging ? "opacity-60" : ""
|
|
||||||
} ${isMenuActive ? "!bg-custom-sidebar-background-80" : ""}`}
|
} ${isMenuActive ? "!bg-custom-sidebar-background-80" : ""}`}
|
||||||
>
|
>
|
||||||
{provided && (
|
{provided && (
|
||||||
@ -154,10 +159,8 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`absolute -left-2.5 top-1/2 hidden -translate-y-1/2 rounded p-0.5 text-custom-sidebar-text-400 ${
|
className={`absolute -left-2.5 top-1/2 hidden -translate-y-1/2 rounded p-0.5 text-custom-sidebar-text-400 ${isCollapsed ? "" : "group-hover:!flex"
|
||||||
isCollapsed ? "" : "group-hover:!flex"
|
} ${project.sort_order === null ? "cursor-not-allowed opacity-60" : ""} ${isMenuActive ? "!flex" : ""
|
||||||
} ${project.sort_order === null ? "cursor-not-allowed opacity-60" : ""} ${
|
|
||||||
isMenuActive ? "!flex" : ""
|
|
||||||
}`}
|
}`}
|
||||||
{...provided?.dragHandleProps}
|
{...provided?.dragHandleProps}
|
||||||
>
|
>
|
||||||
@ -169,13 +172,11 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
<Tooltip tooltipContent={`${project.name}`} position="right" className="ml-2" disabled={!isCollapsed}>
|
<Tooltip tooltipContent={`${project.name}`} position="right" className="ml-2" disabled={!isCollapsed}>
|
||||||
<Disclosure.Button
|
<Disclosure.Button
|
||||||
as="div"
|
as="div"
|
||||||
className={`flex flex-grow cursor-pointer select-none items-center truncate text-left text-sm font-medium ${
|
className={`flex flex-grow cursor-pointer select-none items-center truncate text-left text-sm font-medium ${isCollapsed ? "justify-center" : `justify-between`
|
||||||
isCollapsed ? "justify-center" : `justify-between`
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex w-full flex-grow items-center gap-x-2 truncate ${
|
className={`flex w-full flex-grow items-center gap-x-2 truncate ${isCollapsed ? "justify-center" : ""
|
||||||
isCollapsed ? "justify-center" : ""
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{project.emoji ? (
|
{project.emoji ? (
|
||||||
@ -196,8 +197,7 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
{!isCollapsed && (
|
{!isCollapsed && (
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
className={`hidden h-4 w-4 flex-shrink-0 ${open ? "rotate-180" : ""} ${
|
className={`hidden h-4 w-4 flex-shrink-0 ${open ? "rotate-180" : ""} ${isMenuActive ? "!block" : ""
|
||||||
isMenuActive ? "!block" : ""
|
|
||||||
} mb-0.5 text-custom-sidebar-text-400 duration-300 group-hover:!block`}
|
} mb-0.5 text-custom-sidebar-text-400 duration-300 group-hover:!block`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -313,7 +313,7 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link key={item.name} href={item.href}>
|
<Link key={item.name} href={item.href} onClick={handleProjectClick}>
|
||||||
<span className="block w-full">
|
<span className="block w-full">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
tooltipContent={`${project?.name}: ${item.name}`}
|
tooltipContent={`${project?.name}: ${item.name}`}
|
||||||
@ -322,8 +322,7 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
disabled={!isCollapsed}
|
disabled={!isCollapsed}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`group flex items-center gap-2.5 rounded-md px-2 py-1.5 text-xs font-medium outline-none ${
|
className={`group flex items-center gap-2.5 rounded-md px-2 py-1.5 text-xs font-medium outline-none ${router.asPath.includes(item.href)
|
||||||
router.asPath.includes(item.href)
|
|
||||||
? "bg-custom-primary-100/10 text-custom-primary-100"
|
? "bg-custom-primary-100/10 text-custom-primary-100"
|
||||||
: "text-custom-sidebar-text-300 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
: "text-custom-sidebar-text-300 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
||||||
} ${isCollapsed ? "justify-center" : ""}`}
|
} ${isCollapsed ? "justify-center" : ""}`}
|
||||||
|
@ -56,7 +56,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
// store hooks
|
// store hooks
|
||||||
const {
|
const {
|
||||||
theme: { sidebarCollapsed },
|
theme: { sidebarCollapsed, toggleSidebar },
|
||||||
eventTracker: { setTrackElement },
|
eventTracker: { setTrackElement },
|
||||||
} = useApplication();
|
} = useApplication();
|
||||||
const { currentUser, updateCurrentUser, isUserInstanceAdmin, signOut } = useUser();
|
const { currentUser, updateCurrentUser, isUserInstanceAdmin, signOut } = useUser();
|
||||||
@ -86,6 +86,13 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleItemClick = () => {
|
||||||
|
console.log('CLICKED')
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
toggleSidebar();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const workspacesList = Object.values(workspaces ?? {});
|
const workspacesList = Object.values(workspaces ?? {});
|
||||||
|
|
||||||
// TODO: fix workspaces list scroll
|
// TODO: fix workspaces list scroll
|
||||||
@ -96,14 +103,12 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
<>
|
<>
|
||||||
<Menu.Button className="group/menu-button h-full w-full truncate rounded-md text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:outline-none">
|
<Menu.Button className="group/menu-button h-full w-full truncate rounded-md text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:outline-none">
|
||||||
<div
|
<div
|
||||||
className={`flex items-center gap-x-2 truncate rounded p-1 ${
|
className={`flex items-center gap-x-2 truncate rounded p-1 ${sidebarCollapsed ? "justify-center" : "justify-between"
|
||||||
sidebarCollapsed ? "justify-center" : "justify-between"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2 truncate">
|
<div className="flex items-center gap-2 truncate">
|
||||||
<div
|
<div
|
||||||
className={`relative grid h-6 w-6 flex-shrink-0 place-items-center uppercase ${
|
className={`relative grid h-6 w-6 flex-shrink-0 place-items-center uppercase ${!activeWorkspace?.logo && "rounded bg-custom-primary-500 text-white"
|
||||||
!activeWorkspace?.logo && "rounded bg-custom-primary-500 text-white"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{activeWorkspace?.logo && activeWorkspace.logo !== "" ? (
|
{activeWorkspace?.logo && activeWorkspace.logo !== "" ? (
|
||||||
@ -126,8 +131,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
|
|
||||||
{!sidebarCollapsed && (
|
{!sidebarCollapsed && (
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
className={`mx-1 hidden h-4 w-4 flex-shrink-0 group-hover/menu-button:block ${
|
className={`mx-1 hidden h-4 w-4 flex-shrink-0 group-hover/menu-button:block ${open ? "rotate-180" : ""
|
||||||
open ? "rotate-180" : ""
|
|
||||||
} text-custom-sidebar-text-400 duration-300`}
|
} text-custom-sidebar-text-400 duration-300`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -156,7 +160,10 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
<Link
|
<Link
|
||||||
key={workspace.id}
|
key={workspace.id}
|
||||||
href={`/${workspace.slug}`}
|
href={`/${workspace.slug}`}
|
||||||
onClick={() => handleWorkspaceNavigation(workspace)}
|
onClick={() => {
|
||||||
|
handleWorkspaceNavigation(workspace);
|
||||||
|
handleItemClick();
|
||||||
|
}}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
@ -165,8 +172,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
>
|
>
|
||||||
<div className="flex items-center justify-start gap-2.5 truncate">
|
<div className="flex items-center justify-start gap-2.5 truncate">
|
||||||
<span
|
<span
|
||||||
className={`relative flex h-6 w-6 flex-shrink-0 items-center justify-center p-2 text-xs uppercase ${
|
className={`relative flex h-6 w-6 flex-shrink-0 items-center justify-center p-2 text-xs uppercase ${!workspace?.logo && "rounded bg-custom-primary-500 text-white"
|
||||||
!workspace?.logo && "rounded bg-custom-primary-500 text-white"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{workspace?.logo && workspace.logo !== "" ? (
|
{workspace?.logo && workspace.logo !== "" ? (
|
||||||
@ -181,8 +187,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<h5
|
<h5
|
||||||
className={`truncate text-sm font-medium ${
|
className={`truncate text-sm font-medium ${workspaceSlug === workspace.slug ? "" : "text-custom-text-200"
|
||||||
workspaceSlug === workspace.slug ? "" : "text-custom-text-200"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{workspace.name}
|
{workspace.name}
|
||||||
@ -220,8 +225,10 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
Create workspace
|
Create workspace
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Link>
|
</Link>
|
||||||
{userLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link) => (
|
{userLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link, index) => (
|
||||||
<Link key={link.key} href={link.href} className="w-full">
|
<Link key={link.key} href={link.href} className="w-full" onClick={() => {
|
||||||
|
if (index > 0) handleItemClick();
|
||||||
|
}}>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
as="div"
|
as="div"
|
||||||
className="flex items-center gap-2 rounded px-2 py-1 text-sm text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 font-medium"
|
className="flex items-center gap-2 rounded px-2 py-1 text-sm text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 font-medium"
|
||||||
@ -278,7 +285,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
<div className="flex flex-col gap-2.5 pb-2">
|
<div className="flex flex-col gap-2.5 pb-2">
|
||||||
<span className="px-2 text-custom-sidebar-text-200">{currentUser?.email}</span>
|
<span className="px-2 text-custom-sidebar-text-200">{currentUser?.email}</span>
|
||||||
{profileLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link, index) => (
|
{profileLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link, index) => (
|
||||||
<Link key={index} href={link.link}>
|
<Link key={index} href={link.link} onClick={() => { if (index == 0) handleItemClick(); }}>
|
||||||
<Menu.Item key={index} as="div">
|
<Menu.Item key={index} as="div">
|
||||||
<span className="flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-custom-sidebar-background-80">
|
<span className="flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-custom-sidebar-background-80">
|
||||||
<link.icon className="h-4 w-4 stroke-[1.5]" />
|
<link.icon className="h-4 w-4 stroke-[1.5]" />
|
||||||
|
@ -27,12 +27,21 @@ export const WorkspaceSidebarMenu = observer(() => {
|
|||||||
// computed
|
// computed
|
||||||
const workspaceMemberInfo = currentWorkspaceRole || EUserWorkspaceRoles.GUEST;
|
const workspaceMemberInfo = currentWorkspaceRole || EUserWorkspaceRoles.GUEST;
|
||||||
|
|
||||||
|
const handleLinkClick = () => {
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
themeStore.toggleSidebar();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full cursor-pointer space-y-2 p-4">
|
<div className="w-full cursor-pointer space-y-2 p-4">
|
||||||
{SIDEBAR_MENU_ITEMS.map(
|
{SIDEBAR_MENU_ITEMS.map(
|
||||||
(link) =>
|
(link) =>
|
||||||
workspaceMemberInfo >= link.access && (
|
workspaceMemberInfo >= link.access && (
|
||||||
<Link key={link.key} href={`/${workspaceSlug}${link.href}`}>
|
<Link key={link.key}
|
||||||
|
href={`/${workspaceSlug}${link.href}`}
|
||||||
|
onClick={handleLinkClick}
|
||||||
|
>
|
||||||
<span className="block w-full my-1">
|
<span className="block w-full my-1">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
tooltipContent={link.label}
|
tooltipContent={link.label}
|
||||||
@ -41,8 +50,7 @@ export const WorkspaceSidebarMenu = observer(() => {
|
|||||||
disabled={!themeStore?.sidebarCollapsed}
|
disabled={!themeStore?.sidebarCollapsed}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`group flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium outline-none ${
|
className={`group flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium outline-none ${link.highlight(router.asPath, `/${workspaceSlug}`)
|
||||||
link.highlight(router.asPath, `/${workspaceSlug}`)
|
|
||||||
? "bg-custom-primary-100/10 text-custom-primary-100"
|
? "bg-custom-primary-100/10 text-custom-primary-100"
|
||||||
: "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
: "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
||||||
} ${themeStore?.sidebarCollapsed ? "justify-center" : ""}`}
|
} ${themeStore?.sidebarCollapsed ? "justify-center" : ""}`}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FC } from "react";
|
import { FC, useEffect, useRef } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
// components
|
// components
|
||||||
import {
|
import {
|
||||||
@ -10,20 +10,48 @@ import {
|
|||||||
import { ProjectSidebarList } from "components/project";
|
import { ProjectSidebarList } from "components/project";
|
||||||
// hooks
|
// hooks
|
||||||
import { useApplication } from "hooks/store";
|
import { useApplication } from "hooks/store";
|
||||||
|
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||||
|
|
||||||
export interface IAppSidebar { }
|
export interface IAppSidebar { }
|
||||||
|
|
||||||
export const AppSidebar: FC<IAppSidebar> = observer(() => {
|
export const AppSidebar: FC<IAppSidebar> = observer(() => {
|
||||||
// store hooks
|
// store hooks
|
||||||
const { theme: themStore } = useApplication();
|
const { theme: themStore } = useApplication();
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useOutsideClickDetector(ref, () => {
|
||||||
|
if (themStore.sidebarCollapsed === false) {
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
themStore.toggleSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
if (window.innerWidth <= 768) {
|
||||||
|
themStore.toggleSidebar(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
handleResize();
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
};
|
||||||
|
}, [themStore]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300 md:relative ${
|
className={`inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300
|
||||||
themStore?.sidebarCollapsed ? "" : "md:w-[280px]"
|
fixed md:relative
|
||||||
} ${themStore?.sidebarCollapsed ? "left-0" : "-left-full md:left-0"}`}
|
${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
>
|
sm:${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
<div className="flex h-full w-full flex-1 flex-col">
|
md:ml-0 ${themStore.sidebarCollapsed ? 'w-[80px]' : 'w-[280px]'}
|
||||||
|
lg:ml-0 ${themStore.sidebarCollapsed ? 'w-[80px]' : 'w-[280px]'}
|
||||||
|
`} >
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className="flex h-full w-full flex-1 flex-col">
|
||||||
<WorkspaceSidebarDropdown />
|
<WorkspaceSidebarDropdown />
|
||||||
<WorkspaceSidebarQuickAction />
|
<WorkspaceSidebarQuickAction />
|
||||||
<WorkspaceSidebarMenu />
|
<WorkspaceSidebarMenu />
|
||||||
@ -33,3 +61,6 @@ export const AppSidebar: FC<IAppSidebar> = observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user