diff --git a/webui/src/app/(atlas)/[entry]/folders/[path].tsx b/webui/src/app/(atlas)/[entry]/folders/[path].tsx index 4fa74c2..6011370 100644 --- a/webui/src/app/(atlas)/[entry]/folders/[path].tsx +++ b/webui/src/app/(atlas)/[entry]/folders/[path].tsx @@ -1,21 +1,18 @@ 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'; import { BundleGraph } from '~/components/BundleGraph'; +import { BundleSelectForm } from '~/components/BundleSelectForm'; +import { ModuleFiltersForm } from '~/components/ModuleFilterForm'; import { StateInfo } from '~/components/StateInfo'; -import { EntrySelectForm } from '~/components/forms/EntrySelect'; -import { ModuleFiltersForm } from '~/components/forms/ModuleFilter'; 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 }>(); @@ -27,11 +24,11 @@ export default function FolderPage() { return ( - + - + {!!modules.data && } @@ -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 ; -} - function FolderSummary({ data }: { data: ModuleGraphResponse }) { return (
diff --git a/webui/src/app/(atlas)/[entry]/index.tsx b/webui/src/app/(atlas)/[entry]/index.tsx index cfc894f..e7a50c7 100644 --- a/webui/src/app/(atlas)/[entry]/index.tsx +++ b/webui/src/app/(atlas)/[entry]/index.tsx @@ -2,9 +2,9 @@ import { keepPreviousData, useQuery } from '@tanstack/react-query'; import type { ModuleGraphResponse } from '~/app/--/entries/[entry]/modules/graph+api'; import { BundleGraph } from '~/components/BundleGraph'; +import { BundleSelectForm } from '~/components/BundleSelectForm'; +import { ModuleFiltersForm } from '~/components/ModuleFilterForm'; import { StateInfo } from '~/components/StateInfo'; -import { EntrySelectForm } from '~/components/forms/EntrySelect'; -import { ModuleFiltersForm } from '~/components/forms/ModuleFilter'; import { EntryDeltaToast, useEntry } from '~/providers/entries'; import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout'; import { Spinner } from '~/ui/Spinner'; @@ -22,7 +22,7 @@ export default function BundlePage() { return ( - + diff --git a/webui/src/app/(atlas)/[entry]/modules/[path].tsx b/webui/src/app/(atlas)/[entry]/modules/[path].tsx index 0029db3..14e0991 100644 --- a/webui/src/app/(atlas)/[entry]/modules/[path].tsx +++ b/webui/src/app/(atlas)/[entry]/modules/[path].tsx @@ -1,17 +1,16 @@ 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'; import { ModuleCode } from '~/components/ModuleCode'; import { StateInfo } from '~/components/StateInfo'; -import { EntrySelectForm } from '~/components/forms/EntrySelect'; import { EntryDeltaToast, useEntry } from '~/providers/entries'; 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'; @@ -23,11 +22,11 @@ export default function ModulePage() { return ( - + - + {!!module.data && } @@ -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 ; -} - function ModuleSummary({ module, platform, diff --git a/webui/src/components/BreadcrumbLinks.tsx b/webui/src/components/BreadcrumbLinks.tsx index 93a5df0..7c1abad 100644 --- a/webui/src/components/BreadcrumbLinks.tsx +++ b/webui/src/components/BreadcrumbLinks.tsx @@ -1,5 +1,5 @@ import { Link } from 'expo-router'; -import { ComponentProps, Fragment } from 'react'; +import { ComponentProps, Fragment, useMemo } from 'react'; import { Breadcrumb, @@ -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['href']; - }[]; + entry: PartialAtlasEntry; + path: string; }; export function BreadcrumbLinks(props: BreadcrumbLinksProps) { + const links = useMemo(() => getBreadcrumbLinks(props), [props.entry.id, props.path]); + return ( Bundle - {props.links.map((link, index) => ( + {links.map((link, index) => ( @@ -53,3 +54,30 @@ export function BreadcrumbLinks(props: BreadcrumbLinksProps) { ); } + +type BreadcrumbLinkItem = { + label: string; + href?: ComponentProps['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; + }); +} diff --git a/webui/src/components/forms/EntrySelect.tsx b/webui/src/components/BundleSelectForm.tsx similarity index 98% rename from webui/src/components/forms/EntrySelect.tsx rename to webui/src/components/BundleSelectForm.tsx index e9445ad..744c187 100644 --- a/webui/src/components/forms/EntrySelect.tsx +++ b/webui/src/components/BundleSelectForm.tsx @@ -11,7 +11,7 @@ import { Button } from '~/ui/Button'; import { Tag } from '~/ui/Tag'; import { relativeEntryPath } from '~/utils/entry'; -export function EntrySelectForm() { +export function BundleSelectForm() { const router = useRouter(); const { entry, entries } = useEntry(); diff --git a/webui/src/components/forms/ModuleFilter.tsx b/webui/src/components/ModuleFilterForm.tsx similarity index 100% rename from webui/src/components/forms/ModuleFilter.tsx rename to webui/src/components/ModuleFilterForm.tsx diff --git a/webui/src/utils/entry.ts b/webui/src/utils/entry.ts index 2b2964f..d023a75 100644 --- a/webui/src/utils/entry.ts +++ b/webui/src/utils/entry.ts @@ -1,6 +1,3 @@ -import { ComponentProps } from 'react'; - -import { BreadcrumbLinks } from '~/components/BreadcrumbLinks'; import { PartialAtlasEntry } from '~core/data/types'; /** @@ -10,31 +7,3 @@ import { PartialAtlasEntry } from '~core/data/types'; export function relativeEntryPath(entry: Pick, 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, - absolutePath: string -) { - const relativePath = relativeEntryPath(entry, absolutePath); - - return relativePath.split('/').map((label, index, breadcrumbs) => { - const isLastSegment = index === breadcrumbs.length - 1; - const breadcrumb: ComponentProps['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; - }); -}