diff --git a/frontend/__tests__/unit/components/SnapshotReleaseSection.test.tsx b/frontend/__tests__/unit/components/SnapshotReleaseSection.test.tsx new file mode 100644 index 0000000000..269fad7a76 --- /dev/null +++ b/frontend/__tests__/unit/components/SnapshotReleaseSection.test.tsx @@ -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() + + const items = screen.getAllByText(/Release v/) + expect(items.length).toBe(MAX_RELEASES_TO_SHOW) + }) + + it('renders all releases when showAll is true', () => { + render() + + 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() + expect(screen.getByRole('button', { name: 'show all' })).toBeInTheDocument() + }) + + it('button has label `show less` for releases > MAX_RELEASES_TO_SHOW', () => { + render() + expect(screen.getByRole('button', { name: 'show less' })).toBeInTheDocument() + }) +}) diff --git a/frontend/src/app/community/snapshots/[id]/page.tsx b/frontend/src/app/community/snapshots/[id]/page.tsx index 5da0304710..9ca852d5fd 100644 --- a/frontend/src/app/community/snapshots/[id]/page.tsx +++ b/frontend/src/app/community/snapshots/[id]/page.tsx @@ -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' @@ -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, @@ -29,6 +31,9 @@ const SnapshotDetailsPage: React.FC = () => { }) const snapshot = data?.snapshot + useEffect(() => { + setShowAllReleases(false) + }, [snapshot]) useEffect(() => { if (graphQLRequestError) { @@ -183,21 +188,13 @@ const SnapshotDetailsPage: React.FC = () => {

New Releases

-
- {snapshot.newReleases.map((release, index) => { - return ( - - ) - })} -
+ { + setShowAllReleases((p) => !p)} + /> + } )} diff --git a/frontend/src/components/SnapshotReleaseSection.tsx b/frontend/src/components/SnapshotReleaseSection.tsx new file mode 100644 index 0000000000..e1bf6c60cb --- /dev/null +++ b/frontend/src/components/SnapshotReleaseSection.tsx @@ -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 ( + <> +
+ {visibleReleases.map((release, index) => { + return ( + + ) + })} +
+ {releases.length > MAX_RELEASES_TO_SHOW && ( +
+ +
+ )} + + ) +} diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index 01b90cad6d..9316925e29 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -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',