Skip to content

Commit

Permalink
Publish components/v0.1.1 - pass ApiBaseUrl as config
Browse files Browse the repository at this point in the history
see #60
  • Loading branch information
severo committed Nov 22, 2024
1 parent 3c397a7 commit a8fc119
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 23 deletions.
4 changes: 2 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hyparam/components",
"version": "0.1.0",
"version": "0.1.1",
"description": "React components for hyparam apps",
"keywords": [
"component",
Expand Down Expand Up @@ -38,7 +38,7 @@
"test": "vitest run"
},
"dependencies": {
"@hyparam/utils": "0.1.0",
"@hyparam/utils": "0.1.1",
"hightable": "0.6.3",
"hyparquet": "1.5.0",
"hyparquet-compressors": "0.1.4"
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import Page from './Page.js'

export default function App() {
interface AppProps {
apiBaseUrl: string
}

export default function App(props: AppProps) {
return (
<Page />
<Page {...props} />
)
}
11 changes: 5 additions & 6 deletions packages/components/src/Folder.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FileMetadata, FolderKey, cn, getFileDate, getFileDateShort, getFileSize, listFiles } from '@hyparam/utils'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import Layout, { Spinner } from './Layout.js'

interface FolderProps {
Expand All @@ -13,21 +13,20 @@ export default function Folder({ folderKey }: FolderProps) {
// State to hold file listing
const [files, setFiles] = useState<FileMetadata[]>()
const [error, setError] = useState<Error>()
const listRef = useRef<HTMLUListElement>(null)

// Folder path from url
const { prefix } = folderKey
const { prefix, listFilesUrl } = folderKey
const path = prefix.split('/')

// Fetch files on component mount
useEffect(() => {
listFiles(prefix)
listFiles(listFilesUrl)
.then(setFiles)
.catch((error: unknown) => {
setFiles([])
setError(error instanceof Error ? error : new Error(`Failed to fetch files - ${error}`))
})
}, [prefix])
}, [listFilesUrl])

const fileUrl = useCallback((file: FileMetadata) => {
return prefix ? `/files?key=${prefix}/${file.key}` : `/files?key=${file.key}`
Expand All @@ -43,7 +42,7 @@ export default function Folder({ folderKey }: FolderProps) {
</div>
</nav>

{files && files.length > 0 && <ul className='file-list' ref={listRef}>
{files && files.length > 0 && <ul className='file-list'>
{files.map((file, index) =>
<li key={index}>
<a href={fileUrl(file)}>
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import Cell from './Cell.js'
import File from './File.js'
import Folder from './Folder.js'

export default function Page() {
interface PageProps {
apiBaseUrl: string
}

export default function Page({ apiBaseUrl }: PageProps) {
const search = new URLSearchParams(location.search)
const key = search.get('key')
if (Array.isArray(key)) throw new Error('key must be a string')

const parsedKey = parseKey(key)
const parsedKey = parseKey(key, { apiBaseUrl } )

// row, col from url
const row = search.get('row')
Expand Down
4 changes: 2 additions & 2 deletions packages/components/test/File.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ global.fetch = vi.fn(() => Promise.resolve({ text: vi.fn() } as unknown as Respo

describe('File Component', () => {
it('renders a local file path', async () => {
const parsedKey = parseKey('folder/subfolder/test.txt')
const parsedKey = parseKey('folder/subfolder/test.txt', { apiBaseUrl: 'http://localhost:3000' })
assert(parsedKey.kind === 'file')

const { getByText } = await act(() => render(
Expand All @@ -34,7 +34,7 @@ describe('File Component', () => {
})

it('renders correct breadcrumbs for nested folders', async () => {
const parsedKey = parseKey('folder1/folder2/folder3/test.txt')
const parsedKey = parseKey('folder1/folder2/folder3/test.txt', { apiBaseUrl: 'http://localhost:3000' })
assert(parsedKey.kind === 'file')
const { getAllByRole } = await act(() => render(
<File parsedKey={parsedKey} />,
Expand Down
10 changes: 5 additions & 5 deletions packages/components/test/Folder.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ const mockFiles: FileMetadata[] = [
describe('Folder Component', () => {
it('fetches file data and displays files on mount', async () => {
vi.mocked(listFiles).mockResolvedValueOnce(mockFiles)
const folderKey = parseKey('')
const folderKey = parseKey('', { apiBaseUrl: 'http://localhost:3000' })
assert(folderKey.kind === 'folder')
const { findByText, getByText } = render(<Folder folderKey={folderKey} />)

await waitFor(() => {expect(listFiles).toHaveBeenCalledWith('')})
await waitFor(() => {expect(listFiles).toHaveBeenCalledWith('http://localhost:3000/api/store/list?prefix=')})

const folderLink = await findByText('folder1/')
expect(folderLink.closest('a')?.getAttribute('href')).toBe('/files?key=folder1/')
Expand All @@ -46,7 +46,7 @@ describe('Folder Component', () => {

it('displays the spinner while loading', () => {
vi.mocked(listFiles).mockReturnValue(new Promise(() => []))
const folderKey = parseKey('test-prefix/')
const folderKey = parseKey('test-prefix/', { apiBaseUrl: 'http://localhost:3000' })
assert(folderKey.kind === 'folder')
const { container } = render(<Folder folderKey={folderKey} />)
expect(container.querySelector('.spinner')).toBeDefined()
Expand All @@ -55,7 +55,7 @@ describe('Folder Component', () => {
it('handles file listing errors', async () => {
const errorMessage = 'Failed to fetch'
vi.mocked(listFiles).mockRejectedValue(new Error(errorMessage))
const folderKey = parseKey('test-prefix/')
const folderKey = parseKey('test-prefix/', { apiBaseUrl: 'http://localhost:3000' })
assert(folderKey.kind === 'folder')
const { findByText, queryByText } = render(<Folder folderKey={folderKey} />)

Expand All @@ -68,7 +68,7 @@ describe('Folder Component', () => {

it('renders breadcrumbs correctly', async () => {
vi.mocked(listFiles).mockResolvedValue(mockFiles)
const folderKey = parseKey('subdir1/subdir2/')
const folderKey = parseKey('subdir1/subdir2/', { apiBaseUrl: 'http://localhost:3000' })
assert(folderKey.kind === 'folder')
const { findByText, getByText } = render(<Folder folderKey={folderKey} />)
await waitFor(() => { expect(listFiles).toHaveBeenCalled() })
Expand Down
6 changes: 4 additions & 2 deletions packages/components/test/viewers/ImageView.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FileKey, parseKey } from '@hyparam/utils'
import { parseKey } from '@hyparam/utils'
import { render } from '@testing-library/react'
import { strict as assert } from 'assert'
import React from 'react'
import { describe, expect, it, vi } from 'vitest'
import ImageView from '../../src/viewers/ImageView.js'
Expand All @@ -13,7 +14,8 @@ describe('ImageView Component', () => {
arrayBuffer: () => Promise.resolve(body),
headers: new Map([['content-length', body.byteLength]]),
} as unknown as Response)
const parsedKey = parseKey('test.png') as FileKey
const parsedKey = parseKey('test.png', { apiBaseUrl: 'http://localhost:3000' })
assert(parsedKey.kind === 'file')

const { findByRole, findByText } = render(
<ImageView parsedKey={parsedKey} setError={console.error} />,
Expand Down
6 changes: 4 additions & 2 deletions packages/components/test/viewers/MarkdownView.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FileKey, parseKey } from '@hyparam/utils'
import { parseKey } from '@hyparam/utils'
import { render } from '@testing-library/react'
import { strict as assert } from 'assert'
import React from 'react'
import { describe, expect, it, vi } from 'vitest'
import MarkdownView from '../../src/viewers/MarkdownView.js'
Expand All @@ -13,7 +14,8 @@ describe('MarkdownView Component', () => {
text: () => Promise.resolve(text),
headers: new Map([['content-length', text.length]]),
} as unknown as Response)
const parsedKey = parseKey('test.md') as FileKey
const parsedKey = parseKey('test.md', { apiBaseUrl: 'http://localhost:3000' })
assert(parsedKey.kind === 'file')

const { findByText } = render(
<MarkdownView parsedKey={parsedKey} setError={console.error} />,
Expand Down

0 comments on commit a8fc119

Please sign in to comment.