* refactor: migrate admin icons to @makeplane/propel Replace confirmed icon symbols in apps/admin with their audited @makeplane/propel/icons targets, merging into the imports the six already-migrated files declared. Unresolved symbols (Menu, BrainCog) and the LucideIcon type stay on lucide-react. Lucide size props become explicit width/height. Loader keeps its LoaderIcon alias so the call site is unchanged. apps/admin already declared @makeplane/propel, so no dependency change was needed. * fix: restore Settings breadcrumb label after icon rename The migration's identifier rename also rewrote the string literal, so the breadcrumb displayed the icon component name instead of the label.
99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
import { Fragment } from "react";
|
|
import { observer } from "mobx-react";
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
// icons
|
|
import { Menu } from "lucide-react";
|
|
import { SettingsOutline } from "@makeplane/propel/icons";
|
|
// plane internal packages
|
|
import {
|
|
Breadcrumb,
|
|
BreadcrumbItem,
|
|
BreadcrumbLink,
|
|
BreadcrumbList,
|
|
BreadcrumbSeparator,
|
|
} from "@makeplane/propel/components/breadcrumb";
|
|
// hooks
|
|
import { useTheme } from "@/hooks/store";
|
|
// local imports
|
|
import { CORE_HEADER_SEGMENT_LABELS } from "./core";
|
|
import { EXTENDED_HEADER_SEGMENT_LABELS } from "./extended";
|
|
|
|
export const HamburgerToggle = observer(function HamburgerToggle() {
|
|
const { isSidebarCollapsed, toggleSidebar } = useTheme();
|
|
return (
|
|
<button
|
|
type="button"
|
|
aria-label="Toggle sidebar"
|
|
className="group flex size-7 cursor-pointer items-center justify-center rounded-sm bg-layer-1 transition-all hover:bg-layer-1-hover md:hidden"
|
|
onClick={() => toggleSidebar(!isSidebarCollapsed)}
|
|
>
|
|
<Menu size={14} className="text-secondary transition-all group-hover:text-primary" />
|
|
</button>
|
|
);
|
|
});
|
|
|
|
const HEADER_SEGMENT_LABELS = {
|
|
...CORE_HEADER_SEGMENT_LABELS,
|
|
...EXTENDED_HEADER_SEGMENT_LABELS,
|
|
};
|
|
|
|
// Function to dynamically generate breadcrumb items based on pathname
|
|
const generateBreadcrumbItems = (pathname: string) => {
|
|
const pathSegments = pathname.split("/").slice(1); // removing the first empty string.
|
|
pathSegments.pop();
|
|
|
|
let currentUrl = "";
|
|
const breadcrumbItems = pathSegments.map((segment) => {
|
|
currentUrl += "/" + segment;
|
|
return {
|
|
title: HEADER_SEGMENT_LABELS[segment] ?? segment.toUpperCase(),
|
|
href: currentUrl,
|
|
};
|
|
});
|
|
return breadcrumbItems;
|
|
};
|
|
|
|
export const AdminHeader = observer(function AdminHeader() {
|
|
const pathName = usePathname();
|
|
|
|
const breadcrumbItems = generateBreadcrumbItems(pathName || "");
|
|
|
|
return (
|
|
<div className="relative z-10 flex h-header w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-subtle bg-surface-1 p-4">
|
|
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
|
<HamburgerToggle />
|
|
<div>
|
|
<Breadcrumb aria-label="Breadcrumb">
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink
|
|
label="Settings"
|
|
icon={<SettingsOutline className="h-4 w-4 text-tertiary" />}
|
|
render={<Link href="/general/" />}
|
|
/>
|
|
</BreadcrumbItem>
|
|
{breadcrumbItems.map(
|
|
(item) =>
|
|
item.title && (
|
|
<Fragment key={item.title}>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink label={item.title} render={<Link href={item.href} />} />
|
|
</BreadcrumbItem>
|
|
</Fragment>
|
|
)
|
|
)}
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|