Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import { ReleasesSection } from 'components/SnapshotReleaseSection'
import { MAX_RELEASES_TO_SHOW } from 'utils/constants'

describe('ReleasesSection', () => {
const mockReleases = Array.from({ length: MAX_RELEASES_TO_SHOW + 1 }, (_, i) => ({
id: `release-${i}`,
name: `Release v${i}`,
publishedAt: new Date().toISOString(),
tagName: `v${i}`,
}))

it('renders only MAX_RELEASES_TO_SHOW items when showAll is false', () => {
render(<ReleasesSection releases={mockReleases} showAll={false} onToggle={jest.fn()} />)

const items = screen.getAllByText(/Release v/)
expect(items.length).toBe(MAX_RELEASES_TO_SHOW)
})

it('renders all releases when showAll is true', () => {
render(<ReleasesSection releases={mockReleases} showAll={true} onToggle={jest.fn()} />)

const items = screen.getAllByText(/Release v/)
expect(items.length).toBe(MAX_RELEASES_TO_SHOW + 1)
})

it('button has label `show all` for releases > MAX_RELEASES_TO_SHOW', () => {
render(<ReleasesSection releases={mockReleases} showAll={false} onToggle={jest.fn()} />)
expect(screen.getByRole('button', { name: 'show all' })).toBeInTheDocument()
})

it('button has label `show less` for releases > MAX_RELEASES_TO_SHOW', () => {
render(<ReleasesSection releases={mockReleases} showAll={true} onToggle={jest.fn()} />)
expect(screen.getByRole('button', { name: 'show less' })).toBeInTheDocument()
})
})
31 changes: 14 additions & 17 deletions frontend/src/app/community/snapshots/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'
import { useQuery } from '@apollo/client/react'
import { useRouter, useParams } from 'next/navigation'
import React, { useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import { FaCalendar, FaRightToBracket } from 'react-icons/fa6'
import { handleAppError, ErrorDisplay } from 'app/global-error'
import { GetSnapshotDetailsDocument } from 'types/__generated__/snapshotQueries.generated'
Expand All @@ -14,12 +14,14 @@ import { getFilteredIcons, handleSocialUrls } from 'utils/utility'
import Card from 'components/Card'
import ChapterMapWrapper from 'components/ChapterMapWrapper'
import LoadingSpinner from 'components/LoadingSpinner'
import Release from 'components/Release'
import { ReleasesSection } from 'components/SnapshotReleaseSection'

const SnapshotDetailsPage: React.FC = () => {
const { id: snapshotKey } = useParams<{ id: string }>()
const router = useRouter()

const [showAllReleases, setShowAllReleases] = useState(false)

const {
data,
error: graphQLRequestError,
Expand All @@ -29,6 +31,9 @@ const SnapshotDetailsPage: React.FC = () => {
})

const snapshot = data?.snapshot
useEffect(() => {
setShowAllReleases(false)
}, [snapshot])
Comment thread
devnchill marked this conversation as resolved.

useEffect(() => {
if (graphQLRequestError) {
Expand Down Expand Up @@ -183,21 +188,13 @@ const SnapshotDetailsPage: React.FC = () => {
<h2 className="mb-4 text-2xl font-semibold text-gray-700 dark:text-gray-200">
New Releases
</h2>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{snapshot.newReleases.map((release, index) => {
return (
<Release
key={
release.id ||
`${release.tagName}-${release.repositoryName ?? 'unknown'}-${index}`
}
release={release as unknown as ReleaseType}
showAvatar={true}
index={index}
/>
)
})}
</div>
{
<ReleasesSection
releases={snapshot.newReleases as ReleaseType[]}
showAll={showAllReleases}
onToggle={() => setShowAllReleases((p) => !p)}
/>
}
</div>
)}
</div>
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/components/SnapshotReleaseSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { MAX_RELEASES_TO_SHOW } from 'utils/constants'
import Release from 'components/Release'
import type { Release as ReleaseType } from 'types/release'

type ReleasesSectionProps = {
releases: ReleaseType[]
showAll: boolean
onToggle: () => void
}

export const ReleasesSection = ({ releases, showAll, onToggle }: ReleasesSectionProps) => {
const showButton = {
label: showAll ? 'show less' : 'show all',
classname:
'dark:hover:text-white rounded-md border-1 font-light border-blue-400 p-2 text-blue-400 hover:bg-blue-500 hover:text-white',
}

const visibleReleases = showAll ? releases : releases.slice(0, MAX_RELEASES_TO_SHOW)
return (
<>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{visibleReleases.map((release, index) => {
return (
<Release
key={
release.id || `${release.tagName}-${release.repositoryName ?? 'unknown'}-${index}`
}
release={release as unknown as ReleaseType}
showAvatar={true}
index={index}
/>
)
})}
</div>
{releases.length > MAX_RELEASES_TO_SHOW && (
<div className="flex w-full justify-center">
<button className={showButton.classname} type="button" onClick={onToggle}>
{showButton.label}
</button>
</div>
)}
</>
)
}
2 changes: 2 additions & 0 deletions frontend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ export const themeToggleTooltip = {

export const desktopViewMinWidth = 768

export const MAX_RELEASES_TO_SHOW = 9

export const userAuthStatus = {
AUTHENTICATED: 'authenticated',
LOADING: 'loading',
Expand Down