Skip to content

Commit

Permalink
refactor(webui): simplify breadcrumb links from path
Browse files Browse the repository at this point in the history
  • Loading branch information
byCedric committed Apr 19, 2024
1 parent 983f1c2 commit f91ebae
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 56 deletions.
10 changes: 1 addition & 9 deletions webui/src/app/(atlas)/[entry]/folders/[path].tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { keepPreviousData, useQuery } from '@tanstack/react-query';
import { useLocalSearchParams } from 'expo-router';
import { useMemo } from 'react';

import type { ModuleGraphResponse } from '~/app/--/entries/[entry]/modules/graph+api';
import { BreadcrumbLinks } from '~/components/BreadcrumbLinks';
Expand All @@ -12,10 +11,8 @@ import { EntryDeltaToast, useEntry } from '~/providers/entries';
import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout';
import { Tag } from '~/ui/Tag';
import { fetchApi } from '~/utils/api';
import { breadcrumbsForPath } from '~/utils/entry';
import { type ModuleFilters, useModuleFilters, moduleFiltersToParams } from '~/utils/filters';
import { formatFileSize } from '~/utils/formatString';
import { type PartialAtlasEntry } from '~core/data/types';

export default function FolderPage() {
const { path: absolutePath } = useLocalSearchParams<{ path: string }>();
Expand All @@ -31,7 +28,7 @@ export default function FolderPage() {
</LayoutNavigation>
<LayoutHeader>
<LayoutTitle>
<FolderTitle entry={entry} folderPath={absolutePath!} />
<BreadcrumbLinks entry={entry} path={absolutePath!} />
{!!modules.data && <FolderSummary data={modules.data} />}
</LayoutTitle>
<ModuleFiltersForm disableNodeModules />
Expand All @@ -54,11 +51,6 @@ export default function FolderPage() {
);
}

function FolderTitle({ entry, folderPath }: { entry: PartialAtlasEntry; folderPath: string }) {
const links = useMemo(() => breadcrumbsForPath(entry, folderPath), [entry, folderPath]);
return <BreadcrumbLinks entryId={entry.id} links={links} />;
}

function FolderSummary({ data }: { data: ModuleGraphResponse }) {
return (
<div className="font-sm text-secondary">
Expand Down
10 changes: 2 additions & 8 deletions webui/src/app/(atlas)/[entry]/modules/[path].tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useQuery } from '@tanstack/react-query';
import { Link, useLocalSearchParams } from 'expo-router';
import { useMemo } from 'react';

import { BreadcrumbLinks } from '~/components/BreadcrumbLinks';
import { BundleSelectForm } from '~/components/BundleSelectForm';
Expand All @@ -11,7 +10,7 @@ import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout
import { Skeleton } from '~/ui/Skeleton';
import { Tag } from '~/ui/Tag';
import { fetchApi } from '~/utils/api';
import { breadcrumbsForPath, relativeEntryPath } from '~/utils/entry';
import { relativeEntryPath } from '~/utils/entry';
import { formatFileSize } from '~/utils/formatString';
import { type PartialAtlasEntry, type AtlasModule } from '~core/data/types';

Expand All @@ -27,7 +26,7 @@ export default function ModulePage() {
</LayoutNavigation>
<LayoutHeader>
<LayoutTitle>
<ModuleTitle entry={entry} modulePath={absolutePath!} />
<BreadcrumbLinks entry={entry} path={absolutePath!} />
{!!module.data && <ModuleSummary platform={entry?.platform} module={module.data} />}
</LayoutTitle>
</LayoutHeader>
Expand Down Expand Up @@ -69,11 +68,6 @@ export default function ModulePage() {
);
}

function ModuleTitle({ entry, modulePath }: { entry: PartialAtlasEntry; modulePath: string }) {
const links = useMemo(() => breadcrumbsForPath(entry, modulePath), [entry, modulePath]);
return <BreadcrumbLinks entryId={entry.id} links={links} />;
}

function ModuleSummary({
module,
platform,
Expand Down
44 changes: 36 additions & 8 deletions webui/src/components/BreadcrumbLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Link } from 'expo-router';
import { ComponentProps, Fragment } from 'react';
import { ComponentProps, Fragment, useMemo } from 'react';

import {
Breadcrumb,
Expand All @@ -9,28 +9,29 @@ import {
BreadcrumbPage,
BreadcrumbSeparator,
} from '~/ui/Breadcrumb';
import { relativeEntryPath } from '~/utils/entry';
import { type PartialAtlasEntry } from '~core/data/types';

type BreadcrumbLinksProps = {
entryId: string;
links: {
label: string;
href?: ComponentProps<typeof Link>['href'];
}[];
entry: PartialAtlasEntry;
path: string;
};

export function BreadcrumbLinks(props: BreadcrumbLinksProps) {
const links = useMemo(() => getBreadcrumbLinks(props), [props.entry.id, props.path]);

return (
<Breadcrumb>
<BreadcrumbList className="mr-8">
<BreadcrumbLink asChild>
<Link
className="text-lg font-bold text-default underline-offset-4 hover:underline"
href={{ pathname: '/(atlas)/[entry]/', params: { entry: props.entryId } }}
href={{ pathname: '/(atlas)/[entry]/', params: { entry: props.entry.id } }}
>
Bundle
</Link>
</BreadcrumbLink>
{props.links.map((link, index) => (
{links.map((link, index) => (
<Fragment key={`link-${index}`}>
<BreadcrumbSeparator className="text-secondary" />
<BreadcrumbItem>
Expand All @@ -53,3 +54,30 @@ export function BreadcrumbLinks(props: BreadcrumbLinksProps) {
</Breadcrumb>
);
}

type BreadcrumbLinkItem = {
label: string;
href?: ComponentProps<typeof Link>['href'];
};

function getBreadcrumbLinks(props: BreadcrumbLinksProps): BreadcrumbLinkItem[] {
const relativePath = relativeEntryPath(props.entry, props.path);

return relativePath.split('/').map((label, index, breadcrumbs) => {
const isLastSegment = index === breadcrumbs.length - 1;
const breadcrumb: BreadcrumbLinkItem = { label };

// NOTE(cedric): a bit of a workaround to avoid linking the module page, might need to change this
if (!isLastSegment || !label.includes('.')) {
breadcrumb.href = {
pathname: '/(atlas)/[entry]/folders/[path]',
params: {
entry: props.entry.id,
path: `${props.entry.projectRoot}/${breadcrumbs.slice(0, index + 1).join('/')}`,
},
};
}

return breadcrumb;
});
}
31 changes: 0 additions & 31 deletions webui/src/utils/entry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { ComponentProps } from 'react';

import { BreadcrumbLinks } from '~/components/BreadcrumbLinks';
import { PartialAtlasEntry } from '~core/data/types';

/**
Expand All @@ -10,31 +7,3 @@ import { PartialAtlasEntry } from '~core/data/types';
export function relativeEntryPath(entry: Pick<PartialAtlasEntry, 'projectRoot'>, path: string) {
return path.replace(entry.projectRoot + '/', '');
}

/**
* Create a list of breadcrumbs, including label and possible links, for a given path.
*/
export function breadcrumbsForPath(
entry: Pick<PartialAtlasEntry, 'id' | 'projectRoot'>,
absolutePath: string
) {
const relativePath = relativeEntryPath(entry, absolutePath);

return relativePath.split('/').map((label, index, breadcrumbs) => {
const isLastSegment = index === breadcrumbs.length - 1;
const breadcrumb: ComponentProps<typeof BreadcrumbLinks>['links'][0] = { label };

// NOTE(cedric): a bit of a workaround to avoid linking the module page, might need to change this
if (!isLastSegment || !label.includes('.')) {
breadcrumb.href = {
pathname: '/(atlas)/[entry]/folders/[path]',
params: {
entry: entry.id,
path: `${entry.projectRoot}/${breadcrumbs.slice(0, index + 1).join('/')}`,
},
};
}

return breadcrumb;
});
}

0 comments on commit f91ebae

Please sign in to comment.