Updates to sidebar tree

* Maintain tree open state on route change and return
* Load page tree ancestors and their children when a page is accessed directly
* Show correct breadcrumb path
* Add emoji to breadcrumbs
* Backend api to get page breadcrumbs/ancestors
This commit is contained in:
Philipinho
2024-04-21 16:38:59 +01:00
parent 3e2c13a22e
commit 3462c7fdbc
13 changed files with 348 additions and 116 deletions

View File

@ -15,6 +15,13 @@ import { Link, useParams } from "react-router-dom";
import classes from "./breadcrumb.module.css";
import { SpaceTreeNode } from "@/features/page/tree/types.ts";
function getTitle(name: string, icon: string) {
if (icon) {
return `${icon} ${name}`;
}
return name;
}
export default function Breadcrumb() {
const treeData = useAtomValue(treeDataAtom);
const [breadcrumbNodes, setBreadcrumbNodes] = useState<
@ -48,7 +55,7 @@ export default function Breadcrumb() {
variant="default"
style={{ border: "none" }}
>
<Text truncate="end">{node.name}</Text>
<Text truncate="end">{getTitle(node.name, node.icon)}</Text>
</Button>
</Button.Group>
));
@ -56,6 +63,8 @@ export default function Breadcrumb() {
const getLastNthNode = (n: number) =>
breadcrumbNodes && breadcrumbNodes[breadcrumbNodes.length - n];
// const getTitle = (title: string) => (title?.length > 0 ? title : "untitled");
const getBreadcrumbItems = () => {
if (breadcrumbNodes?.length > 3) {
return [
@ -65,7 +74,7 @@ export default function Breadcrumb() {
underline="never"
key={breadcrumbNodes[0].id}
>
{breadcrumbNodes[0].name}
{getTitle(breadcrumbNodes[0].name, breadcrumbNodes[0].icon)}
</Anchor>,
<Popover
width={250}
@ -89,7 +98,7 @@ export default function Breadcrumb() {
underline="never"
key={getLastNthNode(2)?.id}
>
{getLastNthNode(2)?.name}
{getTitle(getLastNthNode(2)?.name, getLastNthNode(2)?.icon)}
</Anchor>,
<Anchor
component={Link}
@ -97,7 +106,7 @@ export default function Breadcrumb() {
underline="never"
key={getLastNthNode(1)?.id}
>
{getLastNthNode(1)?.name}
{getTitle(getLastNthNode(1)?.name, getLastNthNode(1)?.icon)}
</Anchor>,
];
}
@ -110,7 +119,7 @@ export default function Breadcrumb() {
underline="never"
key={node.id}
>
{node.name}
{getTitle(node.name, node.icon)}
</Anchor>
));
}

View File

@ -1,26 +1,31 @@
.header,
.footer {
@media (max-width: 992px) {
[data-layout='alt'] & {
--_section-right: var(--app-shell-aside-offset, 0px);
}
@media (max-width: 992px) {
[data-layout="alt"] & {
--_section-right: var(--app-shell-aside-offset, 0px);
}
}
}
.aside {
@media (min-width: 993px) {
background: var(--mantine-color-gray-light);
@media (min-width: 993px) {
background: var(--mantine-color-gray-light);
[data-layout='alt'] & {
--_section-top: var(--_section-top, var(--app-shell-header-offset, 0px));
--_section-height: var(
--_section-height,
calc(100dvh - var(--app-shell-header-offset, 0px) - var(--app-shell-footer-offset, 0px))
);
}
[data-layout="alt"] & {
--_section-top: var(--_section-top, var(--app-shell-header-offset, 0px));
--_section-height: var(
--_section-height,
calc(
100dvh - var(--app-shell-header-offset, 0px) -
var(--app-shell-footer-offset, 0px)
)
);
}
}
}
@media (max-width: 48em) {
.navbar {
width: 300px;
}
}

View File

@ -15,7 +15,8 @@ import { useMatchPath } from "@/hooks/use-match-path.tsx";
import React from "react";
export default function Shell({ children }: { children: React.ReactNode }) {
const [mobileOpened, { toggle: toggleMobile }] = useDisclosure();
const [mobileOpened, { toggle: toggleMobile, close: closeMobile }] =
useDisclosure();
const [desktopOpened] = useAtom(desktopSidebarAtom);
const toggleDesktop = useToggleSidebar(desktopSidebarAtom);
const matchPath = useMatchPath();
@ -38,7 +39,7 @@ export default function Shell({ children }: { children: React.ReactNode }) {
}}
padding="md"
>
<AppShell.Header className={classes.header}>
<AppShell.Header className={classes.header} withBorder={false}>
<Group justify="space-between" h="100%" px="md" wrap="nowrap">
<Group
h="100%"
@ -71,7 +72,7 @@ export default function Shell({ children }: { children: React.ReactNode }) {
</Group>
</AppShell.Header>
<AppShell.Navbar>
<AppShell.Navbar className={classes.navbar} withBorder={false}>
<Navbar />
</AppShell.Navbar>