mirror of
https://github.com/Shadowfita/docmost.git
synced 2025-11-14 16:51:07 +10:00
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:
@ -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>
|
||||
));
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user