diff --git a/src/components/Breadcrumb/Breadcrumb.stories.tsx b/src/components/Breadcrumb/Breadcrumb.stories.tsx index 5cdf50c1..92873b5f 100644 --- a/src/components/Breadcrumb/Breadcrumb.stories.tsx +++ b/src/components/Breadcrumb/Breadcrumb.stories.tsx @@ -19,13 +19,15 @@ export const Default: Story = { { text: 'part1/', sourceId: '/part1/' }, { text: 'part2/', sourceId: '/part1/part2/' }, ], - versions: { - label: 'Branches', - versions: [ - { label: 'master', sourceId: '/part1/part2/file.txt' }, - { label: 'dev', sourceId: '/part1/part2/file.txt?branch=dev' }, - { label: 'refs/convert/parquet', sourceId: '/part1/part2/file.txt?branch=refs/convert/parquet' }, - ], + fetchVersions: () => { + return Promise.resolve({ + label: 'Branches', + versions: [ + { label: 'master', sourceId: '/part1/part2/file.txt' }, + { label: 'dev', sourceId: '/part1/part2/file.txt?branch=dev' }, + { label: 'refs/convert/parquet', sourceId: '/part1/part2/file.txt?branch=refs/convert/parquet' }, + ], + }) }, }, }, diff --git a/src/components/Breadcrumb/Breadcrumb.test.tsx b/src/components/Breadcrumb/Breadcrumb.test.tsx index 9723af52..dafb75e3 100644 --- a/src/components/Breadcrumb/Breadcrumb.test.tsx +++ b/src/components/Breadcrumb/Breadcrumb.test.tsx @@ -28,15 +28,17 @@ describe('Breadcrumb Component', () => { expect(subdir2Link.closest('a')?.getAttribute('href')).toBe('/files?key=subdir1/subdir2/') }) - it('handles versions correctly', () => { + it('handles versions correctly', async () => { const source = getHyperparamSource('subdir1/subdir2/', { endpoint }) assert(source !== undefined) - source.versions = { - label: 'Versions', - versions: [ - { label: 'v1.0', sourceId: 'v1.0' }, - { label: 'v2.0', sourceId: 'v2.0' }, - ], + source.fetchVersions = () => { + return Promise.resolve({ + label: 'Versions', + versions: [ + { label: 'v1.0', sourceId: 'v1.0' }, + { label: 'v2.0', sourceId: 'v2.0' }, + ], + }) } const config: Config = { @@ -44,11 +46,11 @@ describe('Breadcrumb Component', () => { getSourceRouteUrl: ({ sourceId }) => `/files?key=${sourceId}`, }, } - const { getByText, getAllByRole } = render( + const { findByText, getAllByRole } = render( ) - const versionsLabel = getByText('Versions') + const versionsLabel = await findByText('Versions') expect(versionsLabel).toBeDefined() const versionLinks = getAllByRole('menuitem') expect(versionLinks.length).toBe(2) diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx index 60c87350..4e691812 100644 --- a/src/components/Breadcrumb/Breadcrumb.tsx +++ b/src/components/Breadcrumb/Breadcrumb.tsx @@ -1,6 +1,7 @@ import type { ReactNode } from 'react' +import { useEffect, useState } from 'react' import { useConfig } from '../../hooks/useConfig.js' -import type { Source } from '../../lib/sources/types.js' +import type { Source, VersionsData } from '../../lib/sources/types.js' import { cn } from '../../lib/utils.js' import Dropdown from '../Dropdown/Dropdown.js' import styles from './Breadcrumb.module.css' @@ -12,9 +13,21 @@ interface BreadcrumbProps { function Versions({ source }: { source: Source }) { const { routes, customClass } = useConfig() + const [versionsData, setVersionsData] = useState(undefined) - if (!source.versions) return null - const { label, versions } = source.versions + useEffect(() => { + source.fetchVersions?.().then( + (nextVersionData) => { + setVersionsData(nextVersionData) + } + ).catch((error: unknown) => { + console.error('Error fetching versions:', error) + setVersionsData(undefined) + }) + }, [source]) + + if (!versionsData) return null + const { label, versions } = versionsData return {versions.map(({ label, sourceId }) => { @@ -40,7 +53,7 @@ export default function Breadcrumb({ source, children }: BreadcrumbProps) { {part.text} )} - {source.versions && } + {source.fetchVersions && } {children} } diff --git a/src/lib/sources/types.ts b/src/lib/sources/types.ts index 1d342348..146e4ef6 100644 --- a/src/lib/sources/types.ts +++ b/src/lib/sources/types.ts @@ -27,7 +27,7 @@ export interface VersionsData { interface BaseSource { sourceId: string sourceParts: SourcePart[] - versions?: VersionsData + fetchVersions?: () => Promise } export interface FileSource extends BaseSource {