mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
[WEB-700] chore: sidebar hamburger refactor (#3960)
This commit is contained in:
parent
861a1c4132
commit
4a93fdbdb4
@ -109,7 +109,7 @@ export const CycleMobileHeader = () => {
|
||||
onClose={() => setAnalyticsModal(false)}
|
||||
cycleDetails={cycleDetails ?? undefined}
|
||||
/>
|
||||
<div className="flex justify-evenly py-2 border-b border-custom-border-200">
|
||||
<div className="flex justify-evenly py-2 border-b border-custom-border-200 md:hidden bg-custom-background-100">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||
|
52
web/components/cycles/cycles-list-mobile-header.tsx
Normal file
52
web/components/cycles/cycles-list-mobile-header.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { observer } from "mobx-react";
|
||||
// ui
|
||||
import { CustomMenu } from "@plane/ui";
|
||||
// icon
|
||||
import { List } from "lucide-react";
|
||||
// constants
|
||||
import { CYCLE_VIEW_LAYOUTS } from "constants/cycle";
|
||||
// hooks
|
||||
import { useCycleFilter, useProject } from "hooks/store";
|
||||
|
||||
const CyclesListMobileHeader = observer(() => {
|
||||
const { currentProjectDetails } = useProject();
|
||||
// hooks
|
||||
const { updateDisplayFilters } = useCycleFilter();
|
||||
return (
|
||||
<div className="flex justify-center sm:hidden">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-custom-border-200 bg-custom-sidebar-background-100"
|
||||
// placement="bottom-start"
|
||||
customButton={
|
||||
<span className="flex items-center gap-2">
|
||||
<List className="h-4 w-4" />
|
||||
<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>
|
||||
</span>
|
||||
}
|
||||
customButtonClassName="flex flex-grow justify-center items-center text-custom-text-200 text-sm"
|
||||
closeOnSelect
|
||||
>
|
||||
{CYCLE_VIEW_LAYOUTS.map((layout) => {
|
||||
if (layout.key == "gantt") return;
|
||||
return (
|
||||
<CustomMenu.MenuItem
|
||||
key={layout.key}
|
||||
onClick={() => {
|
||||
updateDisplayFilters(currentProjectDetails!.id, {
|
||||
layout: layout.key,
|
||||
});
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<layout.icon className="w-3 h-3" />
|
||||
<div className="text-custom-text-300">{layout.title}</div>
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default CyclesListMobileHeader;
|
@ -9,8 +9,6 @@ import { ArrowRight, Plus, PanelRight } from "lucide-react";
|
||||
import { Breadcrumbs, Button, ContrastIcon, CustomMenu, Tooltip } from "@plane/ui";
|
||||
import { ProjectAnalyticsModal } from "components/analytics";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { CycleMobileHeader } from "components/cycles/cycle-mobile-header";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
@ -159,9 +157,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
cycleDetails={cycleDetails ?? undefined}
|
||||
/>
|
||||
<div className="relative z-[15] w-full items-center gap-x-2 gap-y-4">
|
||||
<div className="flex justify-between border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex justify-between bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<SidebarHamburgerToggle />
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
@ -211,9 +208,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
{issueCount && issueCount > 0 ? (
|
||||
<Tooltip
|
||||
isMobile={isMobile}
|
||||
tooltipContent={`There are ${issueCount} ${
|
||||
issueCount > 1 ? "issues" : "issue"
|
||||
} in this cycle`}
|
||||
tooltipContent={`There are ${issueCount} ${issueCount > 1 ? "issues" : "issue"
|
||||
} in this cycle`}
|
||||
position="bottom"
|
||||
>
|
||||
<span className="cursor-default flex items-center text-center justify-center px-2 flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-semibold rounded-xl">
|
||||
@ -299,9 +295,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
<PanelRight className={cn("w-4 h-4", !isSidebarCollapsed ? "text-[#3E63DD]" : "text-custom-text-200")} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="block sm:block md:hidden">
|
||||
<CycleMobileHeader />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -1,19 +1,15 @@
|
||||
import { FC, useCallback } from "react";
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
import { List, Plus } from "lucide-react";
|
||||
import { Plus } from "lucide-react";
|
||||
// hooks
|
||||
// ui
|
||||
import { Breadcrumbs, Button, ContrastIcon, CustomMenu } from "@plane/ui";
|
||||
import { Breadcrumbs, Button, ContrastIcon } from "@plane/ui";
|
||||
// helpers
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { CYCLE_VIEW_LAYOUTS } from "constants/cycle";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import { useApplication, useEventTracker, useProject, useUser } from "hooks/store";
|
||||
import useLocalStorage from "hooks/use-local-storage";
|
||||
import { TCycleLayoutOptions } from "@plane/types";
|
||||
import { ProjectLogo } from "components/project";
|
||||
|
||||
export const CyclesHeader: FC = observer(() => {
|
||||
@ -33,20 +29,11 @@ export const CyclesHeader: FC = observer(() => {
|
||||
const canUserCreateCycle =
|
||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||
|
||||
const { setValue: setCycleLayout } = useLocalStorage<TCycleLayoutOptions>("cycle_layout", "list");
|
||||
|
||||
const handleCurrentLayout = useCallback(
|
||||
(_layout: TCycleLayoutOptions) => {
|
||||
setCycleLayout(_layout);
|
||||
},
|
||||
[setCycleLayout]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="relative z-10 items-center justify-between gap-x-2 gap-y-4">
|
||||
<div className="flex border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
@ -90,35 +77,6 @@ export const CyclesHeader: FC = observer(() => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-center sm:hidden">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-custom-border-200 bg-custom-sidebar-background-100"
|
||||
// placement="bottom-start"
|
||||
customButton={
|
||||
<span className="flex items-center gap-2">
|
||||
<List className="h-4 w-4" />
|
||||
<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>
|
||||
</span>
|
||||
}
|
||||
customButtonClassName="flex flex-grow justify-center items-center text-custom-text-200 text-sm"
|
||||
closeOnSelect
|
||||
>
|
||||
{CYCLE_VIEW_LAYOUTS.map((layout) => (
|
||||
<CustomMenu.MenuItem
|
||||
key={layout.key}
|
||||
onClick={() => {
|
||||
// handleLayoutChange(ISSUE_LAYOUTS[index].key);
|
||||
handleCurrentLayout(layout.key as TCycleLayoutOptions);
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<layout.icon className="w-3 h-3" />
|
||||
<div className="text-custom-text-300">{layout.title}</div>
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -7,7 +7,6 @@ import { usePlatformOS } from "hooks/use-platform-os";
|
||||
import { List, PlusIcon, Sheet } from "lucide-react";
|
||||
import { Breadcrumbs, Button, LayersIcon, PhotoFilterIcon, Tooltip } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection } from "components/issues";
|
||||
// components
|
||||
import { CreateUpdateWorkspaceViewModal } from "components/workspace";
|
||||
@ -109,9 +108,8 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
|
||||
return (
|
||||
<>
|
||||
<CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} />
|
||||
<div className="relative z-[15] 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-[15] flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="relative flex gap-2">
|
||||
<SidebarHamburgerToggle />
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
@ -137,9 +135,8 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
|
||||
<span>
|
||||
<Tooltip tooltipContent={layout.title} isMobile={isMobile}>
|
||||
<div
|
||||
className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${
|
||||
activeLayout === layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : ""
|
||||
}`}
|
||||
className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${activeLayout === layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : ""
|
||||
}`}
|
||||
>
|
||||
<layout.icon
|
||||
size={14}
|
||||
|
@ -8,9 +8,7 @@ import { ArrowRight, PanelRight, Plus } from "lucide-react";
|
||||
import { Breadcrumbs, Button, CustomMenu, DiceIcon, Tooltip } from "@plane/ui";
|
||||
import { ProjectAnalyticsModal } from "components/analytics";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
|
||||
import { ModuleMobileHeader } from "components/modules/module-mobile-header";
|
||||
import { EIssuesStoreType, EIssueFilterType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import { cn } from "helpers/common.helper";
|
||||
@ -160,9 +158,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
moduleDetails={moduleDetails ?? undefined}
|
||||
/>
|
||||
<div className="relative z-[15] items-center gap-x-2 gap-y-4">
|
||||
<div className="flex justify-between border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex justify-between bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<SidebarHamburgerToggle />
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
@ -211,10 +208,9 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
<p className="truncate">{moduleDetails?.name && moduleDetails.name}</p>
|
||||
{issueCount && issueCount > 0 ? (
|
||||
<Tooltip
|
||||
isMobile={isMobile}
|
||||
tooltipContent={`There are ${issueCount} ${
|
||||
issueCount > 1 ? "issues" : "issue"
|
||||
} in this module`}
|
||||
isMobile={isMobile}
|
||||
tooltipContent={`There are ${issueCount} ${issueCount > 1 ? "issues" : "issue"
|
||||
} in this module`}
|
||||
position="bottom"
|
||||
>
|
||||
<span className="cursor-default flex items-center text-center justify-center px-2 flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-semibold rounded-xl">
|
||||
@ -309,7 +305,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ModuleMobileHeader />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
import { GanttChartSquare, LayoutGrid, List, ListFilter, Plus, Search, X } from "lucide-react";
|
||||
import { ListFilter, Plus, Search, X } from "lucide-react";
|
||||
// hooks
|
||||
import { useApplication, useEventTracker, useMember, useModuleFilter, useProject, useUser } from "hooks/store";
|
||||
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { ProjectLogo } from "components/project";
|
||||
// constants
|
||||
import { MODULE_VIEW_LAYOUTS } from "constants/module";
|
||||
@ -17,7 +16,7 @@ import { usePlatformOS } from "hooks/use-platform-os";
|
||||
import { ModuleFiltersSelection, ModuleOrderByDropdown } from "components/modules";
|
||||
import { FiltersDropdown } from "components/issues";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, Tooltip, DiceIcon, CustomMenu } from "@plane/ui";
|
||||
import { Breadcrumbs, Button, Tooltip, DiceIcon } from "@plane/ui";
|
||||
// helpers
|
||||
import { cn } from "helpers/common.helper";
|
||||
// types
|
||||
@ -89,176 +88,138 @@ export const ModulesListHeader: React.FC = observer(() => {
|
||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<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">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={
|
||||
<BreadcrumbLink
|
||||
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
|
||||
label={currentProjectDetails?.name ?? "Project"}
|
||||
icon={
|
||||
currentProjectDetails && (
|
||||
<span className="grid place-items-center flex-shrink-0 h-4 w-4">
|
||||
<ProjectLogo logo={currentProjectDetails?.logo_props} className="text-sm" />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={<BreadcrumbLink label="Modules" icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />} />}
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center">
|
||||
{!isSearchOpen && (
|
||||
<button
|
||||
type="button"
|
||||
className="-mr-1 p-2 hover:bg-custom-background-80 rounded text-custom-text-400 grid place-items-center"
|
||||
onClick={() => {
|
||||
setIsSearchOpen(true);
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
<Search className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
"ml-auto flex items-center justify-start gap-1 rounded-md border border-transparent bg-custom-background-100 text-custom-text-400 w-0 transition-[width] ease-linear overflow-hidden opacity-0",
|
||||
{
|
||||
"w-64 px-2.5 py-1.5 border-custom-border-200 opacity-100": isSearchOpen,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Search className="h-3.5 w-3.5" />
|
||||
<input
|
||||
ref={inputRef}
|
||||
className="w-full max-w-[234px] border-none bg-transparent text-sm text-custom-text-100 placeholder:text-custom-text-400 focus:outline-none"
|
||||
placeholder="Search"
|
||||
value={searchQuery}
|
||||
onChange={(e) => updateSearchQuery(e.target.value)}
|
||||
onKeyDown={handleInputKeyDown}
|
||||
/>
|
||||
{isSearchOpen && (
|
||||
<button
|
||||
type="button"
|
||||
className="grid place-items-center"
|
||||
onClick={() => {
|
||||
// updateSearchQuery("");
|
||||
setIsSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:flex items-center gap-1 rounded bg-custom-background-80 p-1">
|
||||
{MODULE_VIEW_LAYOUTS.map((layout) => (
|
||||
<Tooltip key={layout.key} tooltipContent={layout.title} isMobile={isMobile}>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100",
|
||||
{
|
||||
"bg-custom-background-100 shadow-custom-shadow-2xs": displayFilters?.layout === layout.key,
|
||||
}
|
||||
)}
|
||||
onClick={() => {
|
||||
if (!projectId) return;
|
||||
updateDisplayFilters(projectId.toString(), { layout: layout.key });
|
||||
}}
|
||||
>
|
||||
<layout.icon
|
||||
strokeWidth={2}
|
||||
className={cn("h-3.5 w-3.5 text-custom-text-200", {
|
||||
"text-custom-text-100": displayFilters?.layout === layout.key,
|
||||
})}
|
||||
/>
|
||||
</button>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
<ModuleOrderByDropdown
|
||||
value={displayFilters?.order_by}
|
||||
onChange={(val) => {
|
||||
if (!projectId || val === displayFilters?.order_by) return;
|
||||
updateDisplayFilters(projectId.toString(), {
|
||||
order_by: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<FiltersDropdown icon={<ListFilter className="h-3 w-3" />} title="Filters" placement="bottom-end">
|
||||
<ModuleFiltersSelection
|
||||
displayFilters={displayFilters ?? {}}
|
||||
filters={filters ?? {}}
|
||||
handleDisplayFiltersUpdate={(val) => {
|
||||
if (!projectId) return;
|
||||
updateDisplayFilters(projectId.toString(), val);
|
||||
}}
|
||||
handleFiltersUpdate={handleFilters}
|
||||
memberIds={workspaceMemberIds ?? undefined}
|
||||
<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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<div>
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={
|
||||
<BreadcrumbLink
|
||||
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
|
||||
label={currentProjectDetails?.name ?? "Project"}
|
||||
icon={
|
||||
currentProjectDetails && (
|
||||
<span className="grid place-items-center flex-shrink-0 h-4 w-4">
|
||||
<ProjectLogo logo={currentProjectDetails?.logo_props} className="text-sm" />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
{canUserCreateModule && (
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
setTrackElement("Modules page");
|
||||
commandPaletteStore.toggleCreateModuleModal(true);
|
||||
}}
|
||||
>
|
||||
<div className="hidden sm:block">Add</div> Module
|
||||
</Button>
|
||||
)}
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={<BreadcrumbLink label="Modules" icon={<DiceIcon className="h-4 w-4 text-custom-text-300" />} />}
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center md:hidden">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-custom-border-200 bg-custom-sidebar-background-100"
|
||||
// placement="bottom-start"
|
||||
customButton={
|
||||
<span className="flex items-center gap-2">
|
||||
{displayFilters?.layout === "gantt" ? (
|
||||
<GanttChartSquare className="w-3 h-3" />
|
||||
) : displayFilters?.layout === "board" ? (
|
||||
<LayoutGrid className="w-3 h-3" />
|
||||
) : (
|
||||
<List className="w-3 h-3" />
|
||||
)}
|
||||
<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>
|
||||
</span>
|
||||
}
|
||||
customButtonClassName="flex flex-grow justify-center items-center text-custom-text-200 text-sm"
|
||||
closeOnSelect
|
||||
>
|
||||
{MODULE_VIEW_LAYOUTS.map((layout) => (
|
||||
<CustomMenu.MenuItem
|
||||
key={layout.key}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center">
|
||||
{!isSearchOpen && (
|
||||
<button
|
||||
type="button"
|
||||
className="-mr-1 p-2 hover:bg-custom-background-80 rounded text-custom-text-400 grid place-items-center"
|
||||
onClick={() => {
|
||||
if (!projectId) return;
|
||||
updateDisplayFilters(projectId.toString(), { layout: layout.key });
|
||||
setIsSearchOpen(true);
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<layout.icon className="w-3 h-3" />
|
||||
<div className="text-custom-text-300">{layout.title}</div>
|
||||
</CustomMenu.MenuItem>
|
||||
<Search className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
"ml-auto flex items-center justify-start gap-1 rounded-md border border-transparent bg-custom-background-100 text-custom-text-400 w-0 transition-[width] ease-linear overflow-hidden opacity-0",
|
||||
{
|
||||
"w-64 px-2.5 py-1.5 border-custom-border-200 opacity-100": isSearchOpen,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Search className="h-3.5 w-3.5" />
|
||||
<input
|
||||
ref={inputRef}
|
||||
className="w-full max-w-[234px] border-none bg-transparent text-sm text-custom-text-100 placeholder:text-custom-text-400 focus:outline-none"
|
||||
placeholder="Search"
|
||||
value={searchQuery}
|
||||
onChange={(e) => updateSearchQuery(e.target.value)}
|
||||
onKeyDown={handleInputKeyDown}
|
||||
/>
|
||||
{isSearchOpen && (
|
||||
<button
|
||||
type="button"
|
||||
className="grid place-items-center"
|
||||
onClick={() => {
|
||||
// updateSearchQuery("");
|
||||
setIsSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:flex items-center gap-1 rounded bg-custom-background-80 p-1">
|
||||
{MODULE_VIEW_LAYOUTS.map((layout) => (
|
||||
<Tooltip key={layout.key} tooltipContent={layout.title} isMobile={isMobile}>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100",
|
||||
{
|
||||
"bg-custom-background-100 shadow-custom-shadow-2xs": displayFilters?.layout === layout.key,
|
||||
}
|
||||
)}
|
||||
onClick={() => {
|
||||
if (!projectId) return;
|
||||
updateDisplayFilters(projectId.toString(), { layout: layout.key });
|
||||
}}
|
||||
>
|
||||
<layout.icon
|
||||
strokeWidth={2}
|
||||
className={cn("h-3.5 w-3.5 text-custom-text-200", {
|
||||
"text-custom-text-100": displayFilters?.layout === layout.key,
|
||||
})}
|
||||
/>
|
||||
</button>
|
||||
</Tooltip>
|
||||
))}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
<ModuleOrderByDropdown
|
||||
value={displayFilters?.order_by}
|
||||
onChange={(val) => {
|
||||
if (!projectId || val === displayFilters?.order_by) return;
|
||||
updateDisplayFilters(projectId.toString(), {
|
||||
order_by: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<FiltersDropdown icon={<ListFilter className="h-3 w-3" />} title="Filters" placement="bottom-end">
|
||||
<ModuleFiltersSelection
|
||||
displayFilters={displayFilters ?? {}}
|
||||
filters={filters ?? {}}
|
||||
handleDisplayFiltersUpdate={(val) => {
|
||||
if (!projectId) return;
|
||||
updateDisplayFilters(projectId.toString(), val);
|
||||
}}
|
||||
handleFiltersUpdate={handleFilters}
|
||||
memberIds={workspaceMemberIds ?? undefined}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
{canUserCreateModule && (
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
setTrackElement("Modules page");
|
||||
commandPaletteStore.toggleCreateModuleModal(true);
|
||||
}}
|
||||
>
|
||||
<div className="hidden sm:block">Add</div> Module
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -7,7 +7,6 @@ import { FileText, Plus } from "lucide-react";
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
// helpers
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
// components
|
||||
import { useApplication, usePage, useProject } from "hooks/store";
|
||||
import { ProjectLogo } from "components/project";
|
||||
@ -28,9 +27,8 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
const pageDetails = usePage(pageId as string);
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -6,7 +6,6 @@ import { FileText, Plus } from "lucide-react";
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
// helpers
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
// constants
|
||||
// components
|
||||
@ -31,9 +30,8 @@ export const PagesHeader = observer(() => {
|
||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -5,7 +5,6 @@ import useSWR from "swr";
|
||||
// hooks
|
||||
import { Breadcrumbs, LayersIcon } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { ISSUE_DETAILS } from "constants/fetch-keys";
|
||||
import { useProject } from "hooks/store";
|
||||
// components
|
||||
@ -40,9 +39,8 @@ export const ProjectArchivedIssueDetailsHeader: FC = observer(() => {
|
||||
);
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
// hooks
|
||||
import { usePlatformOS } from "hooks/use-platform-os";
|
||||
// constants
|
||||
@ -9,7 +8,6 @@ import { usePlatformOS } from "hooks/use-platform-os";
|
||||
import { Breadcrumbs, LayersIcon, Tooltip } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "components/issues";
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
|
||||
// helpers
|
||||
@ -77,20 +75,10 @@ export const ProjectArchivedIssuesHeader: FC = observer(() => {
|
||||
: undefined;
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="block md:hidden">
|
||||
<button
|
||||
type="button"
|
||||
className="grid h-8 w-8 place-items-center rounded border border-custom-border-200"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<ArrowLeft fontSize={14} strokeWidth={2} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={
|
||||
|
@ -6,7 +6,7 @@ import { usePlatformOS } from "hooks/use-platform-os";
|
||||
// components
|
||||
import { Breadcrumbs, LayersIcon, Tooltip } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
|
||||
// ui
|
||||
// helper
|
||||
@ -82,9 +82,8 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
|
||||
: undefined;
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="flex items-center gap-2.5">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -7,7 +7,6 @@ import { Plus } from "lucide-react";
|
||||
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { CreateInboxIssueModal } from "components/inbox";
|
||||
// helper
|
||||
import { useProject } from "hooks/store";
|
||||
@ -23,9 +22,8 @@ export const ProjectInboxHeader: FC = observer(() => {
|
||||
const { currentProjectDetails } = useProject();
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -5,7 +5,6 @@ import { useRouter } from "next/router";
|
||||
import { PanelRight } from "lucide-react";
|
||||
import { Breadcrumbs, LayersIcon } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { cn } from "helpers/common.helper";
|
||||
import { useApplication, useIssueDetail, useProject } from "hooks/store";
|
||||
// ui
|
||||
@ -30,9 +29,8 @@ export const ProjectIssueDetailsHeader: FC = observer(() => {
|
||||
const isSidebarCollapsed = themeStore.issueDetailSidebarCollapsed;
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs onBack={router.back}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -7,9 +7,7 @@ import { usePlatformOS } from "hooks/use-platform-os";
|
||||
import { Breadcrumbs, Button, LayersIcon, Tooltip } from "@plane/ui";
|
||||
import { ProjectAnalyticsModal } from "components/analytics";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
|
||||
import { IssuesMobileHeader } from "components/issues/issues-mobile-header";
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import {
|
||||
@ -117,9 +115,8 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
projectDetails={currentProjectDetails ?? undefined}
|
||||
/>
|
||||
<div className="relative z-[15] items-center gap-x-2 gap-y-4">
|
||||
<div className="flex items-center gap-2 p-4 border-b border-custom-border-200 bg-custom-sidebar-background-100">
|
||||
<div className="flex items-center gap-2 p-4 bg-custom-sidebar-background-100">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="flex items-center gap-2.5">
|
||||
<Breadcrumbs onBack={() => router.back()}>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
@ -231,9 +228,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="block md:hidden">
|
||||
<IssuesMobileHeader />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -5,7 +5,6 @@ import { useRouter } from "next/router";
|
||||
import { Breadcrumbs, CustomMenu } from "@plane/ui";
|
||||
// helper
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { EUserProjectRoles, PROJECT_SETTINGS_LINKS } from "constants/project";
|
||||
// hooks
|
||||
import { useProject, useUser } from "hooks/store";
|
||||
@ -31,8 +30,7 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
|
||||
if (currentProjectRole && currentProjectRole <= EUserProjectRoles.VIEWER) return null;
|
||||
|
||||
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">
|
||||
<SidebarHamburgerToggle />
|
||||
<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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<div>
|
||||
<div className="z-50">
|
||||
|
@ -8,7 +8,6 @@ import { Plus } from "lucide-react";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
|
||||
// helpers
|
||||
// types
|
||||
@ -128,9 +127,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||
|
||||
return (
|
||||
<div className="relative z-[15] 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-[15] flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<SidebarHamburgerToggle />
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
|
@ -5,7 +5,6 @@ import { Plus } from "lucide-react";
|
||||
// components
|
||||
import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
// helpers
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
// constants
|
||||
@ -30,9 +29,8 @@ export const ProjectViewsHeader: React.FC = observer(() => {
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -6,7 +6,6 @@ import { useApplication, useEventTracker, useMember, useProject, useProjectFilte
|
||||
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
// ui
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
// helpers
|
||||
@ -77,9 +76,8 @@ export const ProjectsHeader = observer(() => {
|
||||
};
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -7,7 +7,6 @@ import { ChevronDown, PanelRight } from "lucide-react";
|
||||
import { Breadcrumbs, CustomMenu } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
// components
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { PROFILE_ADMINS_TAB, PROFILE_VIEWER_TAB } from "constants/profile";
|
||||
import { cn } from "helpers/common.helper";
|
||||
import { useApplication, useUser } from "hooks/store";
|
||||
@ -35,9 +34,8 @@ export const UserProfileHeader: FC<TUserProfileHeader> = observer((props) => {
|
||||
const { theme: themStore } = useApplication();
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="flex justify-between w-full">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -3,13 +3,11 @@ import { observer } from "mobx-react-lite";
|
||||
import { Crown } from "lucide-react";
|
||||
import { Breadcrumbs, ContrastIcon } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
// icons
|
||||
|
||||
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 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="flex items-center gap-2">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -6,7 +6,6 @@ import { BarChart2, PanelRight } from "lucide-react";
|
||||
import { Breadcrumbs } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { cn } from "helpers/common.helper";
|
||||
import { useApplication } from "hooks/store";
|
||||
|
||||
@ -34,10 +33,9 @@ export const WorkspaceAnalyticsHeader = observer(() => {
|
||||
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`}
|
||||
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 bg-custom-sidebar-background-100 p-4`}
|
||||
>
|
||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -8,7 +8,6 @@ import githubWhiteImage from "/public/logos/github-white.png";
|
||||
// components
|
||||
import { Breadcrumbs } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
// constants
|
||||
import { CHANGELOG_REDIRECTED, GITHUB_REDIRECTED } from "constants/event-tracker";
|
||||
import { useEventTracker } from "hooks/store";
|
||||
@ -20,9 +19,8 @@ export const WorkspaceDashboardHeader = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative z-[15] 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-[15] flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 bg-custom-sidebar-background-100 p-4">
|
||||
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -7,7 +7,6 @@ import { Breadcrumbs, CustomMenu } from "@plane/ui";
|
||||
// hooks
|
||||
// components
|
||||
import { BreadcrumbLink } from "components/common";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
import { WORKSPACE_SETTINGS_LINKS } from "constants/workspace";
|
||||
|
||||
export interface IWorkspaceSettingHeader {
|
||||
@ -23,7 +22,6 @@ export const WorkspaceSettingHeader: FC<IWorkspaceSettingHeader> = observer((pro
|
||||
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="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||
<SidebarHamburgerToggle />
|
||||
<div>
|
||||
<Breadcrumbs>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import router from "next/router";
|
||||
import { observer } from "mobx-react";
|
||||
// components
|
||||
import { Calendar, ChevronDown, Kanban, List } from "lucide-react";
|
||||
import { CustomMenu } from "@plane/ui";
|
||||
@ -13,7 +14,7 @@ import { useIssues, useLabel, useMember, useProject, useProjectState } from "hoo
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "./issue-layouts";
|
||||
|
||||
export const IssuesMobileHeader = () => {
|
||||
export const IssuesMobileHeader = observer(() => {
|
||||
const layouts = [
|
||||
{ key: "list", title: "List", icon: List },
|
||||
{ key: "kanban", title: "Kanban", icon: Kanban },
|
||||
@ -87,7 +88,7 @@ export const IssuesMobileHeader = () => {
|
||||
onClose={() => setAnalyticsModal(false)}
|
||||
projectDetails={currentProjectDetails ?? undefined}
|
||||
/>
|
||||
<div className="flex justify-evenly border-b border-custom-border-200 py-2">
|
||||
<div className="flex justify-evenly border-b border-custom-border-200 py-2 z-[13] bg-custom-background-100">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-sm text-custom-text-200"
|
||||
@ -164,4 +165,4 @@ export const IssuesMobileHeader = () => {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
40
web/components/modules/moduels-list-mobile-header.tsx
Normal file
40
web/components/modules/moduels-list-mobile-header.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { CustomMenu } from "@plane/ui";
|
||||
import { MODULE_VIEW_LAYOUTS } from "constants/module";
|
||||
import { useModuleFilter, useProject } from "hooks/store";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
const ModulesListMobileHeader = observer(() => {
|
||||
const { currentProjectDetails } = useProject();
|
||||
const { updateDisplayFilters } = useModuleFilter();
|
||||
|
||||
return (
|
||||
<div className="flex justify-center md:hidden">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-custom-border-200 bg-custom-sidebar-background-100"
|
||||
// placement="bottom-start"
|
||||
customButton={<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>}
|
||||
customButtonClassName="flex flex-grow justify-center items-center text-custom-text-200 text-sm"
|
||||
closeOnSelect
|
||||
>
|
||||
{MODULE_VIEW_LAYOUTS.map((layout) => {
|
||||
if (layout.key == "gantt") return;
|
||||
return (
|
||||
<CustomMenu.MenuItem
|
||||
key={layout.key}
|
||||
onClick={() => {
|
||||
updateDisplayFilters(currentProjectDetails!.id.toString(), { layout: layout.key });
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<layout.icon className="w-3 h-3" />
|
||||
<div className="text-custom-text-300">{layout.title}</div>
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default ModulesListMobileHeader;
|
@ -1,14 +1,21 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import router from "next/router";
|
||||
// icons
|
||||
import { Calendar, ChevronDown, Kanban, List } from "lucide-react";
|
||||
// ui
|
||||
import { CustomMenu } from "@plane/ui";
|
||||
// components
|
||||
import { ProjectAnalyticsModal } from "components/analytics";
|
||||
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "components/issues";
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "constants/issue";
|
||||
// hooks
|
||||
import { useIssues, useLabel, useMember, useModule, useProjectState } from "hooks/store";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
// constants
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "constants/issue";
|
||||
|
||||
export const ModuleMobileHeader = () => {
|
||||
export const ModuleMobileHeader = observer(() => {
|
||||
const [analyticsModal, setAnalyticsModal] = useState(false);
|
||||
const { getModuleById } = useModule();
|
||||
const layouts = [
|
||||
@ -83,7 +90,7 @@ export const ModuleMobileHeader = () => {
|
||||
onClose={() => setAnalyticsModal(false)}
|
||||
moduleDetails={moduleDetails ?? undefined}
|
||||
/>
|
||||
<div className="flex justify-evenly border-b border-custom-border-200 py-2">
|
||||
<div className="flex justify-evenly border-b border-custom-border-200 bg-custom-background-100 py-2">
|
||||
<CustomMenu
|
||||
maxHeight={"md"}
|
||||
className="flex flex-grow justify-center text-sm text-custom-text-200"
|
||||
@ -161,4 +168,4 @@ export const ModuleMobileHeader = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { FC, ReactNode } from "react";
|
||||
// layouts
|
||||
import { observer } from "mobx-react-lite";
|
||||
import useSWR from "swr";
|
||||
import { CommandPalette } from "components/command-palette";
|
||||
import { EIssuesStoreType } from "constants/issue";
|
||||
import { useIssues } from "hooks/store/use-issues";
|
||||
import { UserAuthWrapper, WorkspaceAuthWrapper, ProjectAuthWrapper } from "layouts/auth-layout";
|
||||
// components
|
||||
import { AppSidebar } from "./sidebar";
|
||||
import { SidebarHamburgerToggle } from "components/core/sidebar/sidebar-menu-hamburger-toggle";
|
||||
|
||||
export interface IAppLayout {
|
||||
children: ReactNode;
|
||||
header: ReactNode;
|
||||
withProjectWrapper?: boolean;
|
||||
mobileHeader?: ReactNode;
|
||||
}
|
||||
|
||||
export const AppLayout: FC<IAppLayout> = observer((props) => {
|
||||
const { children, header, withProjectWrapper = false } = props;
|
||||
const { children, header, withProjectWrapper = false, mobileHeader } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -26,7 +25,15 @@ export const AppLayout: FC<IAppLayout> = observer((props) => {
|
||||
<div className="relative flex h-screen w-full overflow-hidden">
|
||||
<AppSidebar />
|
||||
<main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100">
|
||||
{header}
|
||||
<div className="z-[15]">
|
||||
<div className="flex items-center w-full border-b border-custom-border-200 z-10">
|
||||
<div className="pl-5 py-4 bg-custom-sidebar-background-100 block md:hidden">
|
||||
<SidebarHamburgerToggle />
|
||||
</div>
|
||||
<div className="w-full">{header}</div>
|
||||
</div>
|
||||
{mobileHeader && mobileHeader}
|
||||
</div>
|
||||
<div className="h-full w-full overflow-hidden">
|
||||
<div className="relative h-full w-full overflow-x-hidden overflow-y-scroll">
|
||||
{withProjectWrapper ? <ProjectAuthWrapper>{children}</ProjectAuthWrapper> : <>{children}</>}
|
||||
|
@ -17,6 +17,7 @@ import { AppLayout } from "layouts/app-layout";
|
||||
// assets
|
||||
import { NextPageWithLayout } from "lib/types";
|
||||
import emptyCycle from "public/empty-state/cycle.svg";
|
||||
import { CycleMobileHeader } from "components/cycles/cycle-mobile-header";
|
||||
// types
|
||||
|
||||
const CycleDetailPage: NextPageWithLayout = observer(() => {
|
||||
@ -85,7 +86,7 @@ const CycleDetailPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
CycleDetailPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<CycleIssuesHeader />} withProjectWrapper>
|
||||
<AppLayout header={<CycleIssuesHeader />} mobileHeader={<CycleMobileHeader />} withProjectWrapper>
|
||||
{page}
|
||||
</AppLayout>
|
||||
);
|
||||
|
@ -27,6 +27,7 @@ import { TCycleFilters } from "@plane/types";
|
||||
// constants
|
||||
import { CYCLE_TABS_LIST } from "constants/cycle";
|
||||
import { EmptyStateType } from "constants/empty-state";
|
||||
import CyclesListMobileHeader from "components/cycles/cycles-list-mobile-header";
|
||||
|
||||
const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
||||
// states
|
||||
@ -137,7 +138,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
ProjectCyclesPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<CyclesHeader />} withProjectWrapper>
|
||||
<AppLayout header={<CyclesHeader />} mobileHeader={<CyclesListMobileHeader />} withProjectWrapper>
|
||||
{page}
|
||||
</AppLayout>
|
||||
);
|
||||
|
@ -10,6 +10,7 @@ import { ProjectLayoutRoot } from "components/issues";
|
||||
import { useProject } from "hooks/store";
|
||||
import { AppLayout } from "layouts/app-layout";
|
||||
import { NextPageWithLayout } from "lib/types";
|
||||
import { IssuesMobileHeader } from "components/issues/issues-mobile-header";
|
||||
// layouts
|
||||
// hooks
|
||||
|
||||
@ -42,7 +43,7 @@ const ProjectIssuesPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
ProjectIssuesPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<ProjectIssuesHeader />} withProjectWrapper>
|
||||
<AppLayout header={<ProjectIssuesHeader />} mobileHeader={<IssuesMobileHeader/>} withProjectWrapper>
|
||||
{page}
|
||||
</AppLayout>
|
||||
);
|
||||
|
@ -16,6 +16,7 @@ import { AppLayout } from "layouts/app-layout";
|
||||
// assets
|
||||
import { NextPageWithLayout } from "lib/types";
|
||||
import emptyModule from "public/empty-state/module.svg";
|
||||
import { ModuleMobileHeader } from "components/modules/module-mobile-header";
|
||||
// types
|
||||
|
||||
const ModuleIssuesPage: NextPageWithLayout = observer(() => {
|
||||
@ -83,7 +84,7 @@ const ModuleIssuesPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
ModuleIssuesPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<ModuleIssuesHeader />} withProjectWrapper>
|
||||
<AppLayout header={<ModuleIssuesHeader />} mobileHeader={<ModuleMobileHeader/>} withProjectWrapper>
|
||||
{page}
|
||||
</AppLayout>
|
||||
);
|
||||
|
@ -13,6 +13,7 @@ import { AppLayout } from "layouts/app-layout";
|
||||
import { NextPageWithLayout } from "lib/types";
|
||||
import { calculateTotalFilters } from "helpers/filter.helper";
|
||||
import { TModuleFilters } from "@plane/types";
|
||||
import ModulesListMobileHeader from "components/modules/moduels-list-mobile-header";
|
||||
|
||||
const ProjectModulesPage: NextPageWithLayout = observer(() => {
|
||||
const router = useRouter();
|
||||
@ -59,7 +60,7 @@ const ProjectModulesPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
ProjectModulesPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<ModulesListHeader />} withProjectWrapper>
|
||||
<AppLayout header={<ModulesListHeader />} mobileHeader={<ModulesListMobileHeader/>} withProjectWrapper>
|
||||
{page}
|
||||
</AppLayout>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user