From 81dc2b659d3ba0bbc9485b2cbb1fe59356e865d9 Mon Sep 17 00:00:00 2001 From: fsimonjetz Date: Mon, 4 Dec 2023 16:52:04 +0100 Subject: [PATCH] Redesign Latest Addition List (#418) * add "latest" parameter * redesign latest transliterations * update latest transliteration test * relocate queryItemOf * update Fragmentarium test * add Record to latest * update snapshot for record * remove deprecated fetchLatestTransliterations * Refactoring * add ResultPageButtons tests * style record display * extend page buttons tests * minor bug fixes * refactoring --- src/common/ResultPageButtons.test.tsx | 57 + src/common/ResultPageButtons.tsx | 62 +- .../TextView.integration.test.ts.snap | 90 +- src/corpus/ui/manuscripts/ManuscriptForm.tsx | 36 +- .../application/FragmentSearchService.test.ts | 9 - .../application/FragmentSearchService.ts | 5 - .../infrastructure/FragmentRepository.test.ts | 9 +- .../infrastructure/FragmentRepository.ts | 6 - .../ui/front-page/Fragmentarium.css | 1 + .../ui/front-page/Fragmentarium.test.tsx | 26 +- .../ui/front-page/Fragmentarium.tsx | 4 +- .../LatestTransliterations.test.tsx | 75 +- .../ui/front-page/LatestTransliterations.tsx | 49 +- .../ui/front-page/Statistics.css | 1 + .../LatestTransliterations.test.tsx.snap | 11620 ++++++++++++++++ src/fragmentarium/ui/info/Record.tsx | 29 +- .../ui/info/ResearchProjects.sass | 6 + .../ui/info/ResearchProjects.tsx | 31 +- .../ui/search/FragmentariumSearch.test.tsx | 11 +- .../ui/search/FragmentariumSearchResult.sass | 13 +- .../ui/search/FragmentariumSearchResult.tsx | 67 +- .../FragmentariumSearch.test.tsx.snap | 26 +- src/query/FragmentQuery.ts | 1 + src/test-support/utils.ts | 10 + 24 files changed, 12010 insertions(+), 234 deletions(-) create mode 100644 src/common/ResultPageButtons.test.tsx create mode 100644 src/fragmentarium/ui/front-page/__snapshots__/LatestTransliterations.test.tsx.snap create mode 100644 src/fragmentarium/ui/info/ResearchProjects.sass diff --git a/src/common/ResultPageButtons.test.tsx b/src/common/ResultPageButtons.test.tsx new file mode 100644 index 000000000..a3e46417c --- /dev/null +++ b/src/common/ResultPageButtons.test.tsx @@ -0,0 +1,57 @@ +import React from 'react' +import { render, screen, act } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import { ResultPageButtons } from './ResultPageButtons' +import { queryItemFactory } from 'test-support/query-item-factory' + +const setActive = jest.fn() + +async function renderPages(numberOfPages: number, active = 0) { + const pages = Array.from({ length: numberOfPages }, () => + queryItemFactory.buildList(3) + ) + await act(async () => { + render( + + ) + }) +} + +describe('ResultPageButtons for few pages', () => { + beforeEach(() => renderPages(3)) + + it('renders pagination buttons correctly', () => { + const pagination = screen.getByLabelText('result-pagination') + expect(pagination).toBeInTheDocument() + expect(screen.getByText('1')).toBeVisible() + expect(screen.getByText('3')).toBeVisible() + expect(screen.queryByText('…')).not.toBeInTheDocument() + }) + + it('triggers setActive when clicking on pagination buttons', () => { + const paginationItem = screen.getByText('1') + userEvent.click(paginationItem) + + expect(setActive).toHaveBeenCalledWith(0) + }) +}) + +describe('ResultPageButtons for many pages', () => { + beforeEach(() => renderPages(15, 4)) + + it('renders pagination buttons correctly', () => { + const pagination = screen.getByLabelText('result-pagination') + expect(pagination).toBeInTheDocument() + expect(screen.getByText('1')).toBeVisible() + expect(screen.getByText('15')).toBeVisible() + expect(screen.getByText('…')).toBeVisible() + }) + + it('shows ellipsis when page 7 is active', () => { + const paginationItem = screen.getByText('7') + userEvent.click(paginationItem) + + expect(setActive).toHaveBeenCalledWith(6) + expect(screen.getByText('…')).toBeVisible() + }) +}) diff --git a/src/common/ResultPageButtons.tsx b/src/common/ResultPageButtons.tsx index e4ab72ca6..148e93d87 100644 --- a/src/common/ResultPageButtons.tsx +++ b/src/common/ResultPageButtons.tsx @@ -1,24 +1,31 @@ import React, { Dispatch, SetStateAction } from 'react' import { CorpusQueryItem, QueryItem } from 'query/QueryResult' import { Col, Row, Pagination } from 'react-bootstrap' -import { createPages } from '../fragmentarium/ui/search/FragmentariumSearchResult' +import _ from 'lodash' -export function ResultPageButtons({ - pages, - active, - setActive, -}: { - pages: (QueryItem | CorpusQueryItem)[][] +function createButtonGroups( + pages: readonly unknown[][], active: number - setActive: (number) => void -}): JSX.Element { - return ( - - - - - +): number[][] { + const pageNumbers = _.range(pages.length) + + if (pages.length <= 10) { + return [pageNumbers] + } + const buttonGroups: number[][] = [] + const showEllipsis1 = active > 5 + const showEllipsis2 = active < pageNumbers.length - 6 + + const activeGroup = pageNumbers.slice( + showEllipsis1 ? active - 3 : 0, + showEllipsis2 ? active + 4 : pageNumbers.length ) + + showEllipsis1 && buttonGroups.push([0]) + buttonGroups.push(activeGroup) + showEllipsis2 && buttonGroups.push(pageNumbers.slice(-1)) + + return buttonGroups } function ResultPagination({ pages, @@ -30,8 +37,12 @@ function ResultPagination({ setActive: Dispatch> }): JSX.Element { return ( - - {createPages(pages, active).map((pages, index) => { + + {createButtonGroups(pages, active).map((pages, index) => { return ( {index > 0 && } @@ -53,3 +64,20 @@ function ResultPagination({ ) } +export function ResultPageButtons({ + pages, + active, + setActive, +}: { + pages: (QueryItem | CorpusQueryItem)[][] + active: number + setActive: (number) => void +}): JSX.Element { + return ( + + + + + + ) +} diff --git a/src/corpus/ui/__snapshots__/TextView.integration.test.ts.snap b/src/corpus/ui/__snapshots__/TextView.integration.test.ts.snap index 042ffb585..24a42f207 100644 --- a/src/corpus/ui/__snapshots__/TextView.integration.test.ts.snap +++ b/src/corpus/ui/__snapshots__/TextView.integration.test.ts.snap @@ -231,19 +231,25 @@ exports[`Chapter Show chapter 1`] = `
- - Cuneiform Artefacts of Iraq in Context - +
  • + + Cuneiform Artefacts of Iraq in Context + +
  • +
    - - Cuneiform Artefacts of Iraq in Context - +
  • + + Cuneiform Artefacts of Iraq in Context + +
  • +
    - - Cuneiform Artefacts of Iraq in Context - +
  • + + Cuneiform Artefacts of Iraq in Context + +
  • +
    - {provenances.map((provenance) => - _.isNil(provenance.parent) ? ( - - ) : ( - - ) - )} + {provenances.map((provenance, index) => ( + + ))} @@ -120,17 +117,12 @@ export default function ManuscriptForm({ value={manuscript.period.name} onChange={handleEnumChange('period', Periods)} > - {periods.map((period) => - _.isNil(period.parent) ? ( - - ) : ( - - ) - )} + {periods.map((period, index) => ( + + ))} diff --git a/src/fragmentarium/application/FragmentSearchService.test.ts b/src/fragmentarium/application/FragmentSearchService.test.ts index 9f59d36e8..936ec1da1 100644 --- a/src/fragmentarium/application/FragmentSearchService.test.ts +++ b/src/fragmentarium/application/FragmentSearchService.test.ts @@ -11,7 +11,6 @@ const fragmentRepository = { random: jest.fn(), interesting: jest.fn(), searchReference: jest.fn(), - fetchLatestTransliterations: jest.fn(), fetchNeedsRevision: jest.fn(), } @@ -33,14 +32,6 @@ const testData: TestData[] = [ null, Promise.resolve([expectedResultStub]) ), - new TestData( - 'fetchLatestTransliterations', - [], - fragmentRepository.fetchLatestTransliterations, - [expectedResultStub], - null, - Promise.resolve([expectedResultStub]) - ), new TestData( 'fetchNeedsRevision', [], diff --git a/src/fragmentarium/application/FragmentSearchService.ts b/src/fragmentarium/application/FragmentSearchService.ts index 848fa2aed..76bde0209 100644 --- a/src/fragmentarium/application/FragmentSearchService.ts +++ b/src/fragmentarium/application/FragmentSearchService.ts @@ -14,7 +14,6 @@ export type FragmentInfosPaginationPromise = Promise export interface FragmentInfoRepository { random(): FragmentInfosPromise interesting(): FragmentInfosPromise - fetchLatestTransliterations(): FragmentInfosPromise fetchNeedsRevision(): FragmentInfosPromise } @@ -51,10 +50,6 @@ export default class FragmentSearchService { }) } - fetchLatestTransliterations(): FragmentInfosPromise { - return this.fragmentRepository.fetchLatestTransliterations() - } - fetchNeedsRevision(): FragmentInfosPromise { return this.fragmentRepository.fetchNeedsRevision() } diff --git a/src/fragmentarium/infrastructure/FragmentRepository.test.ts b/src/fragmentarium/infrastructure/FragmentRepository.test.ts index 483cde21c..d44ff3e86 100644 --- a/src/fragmentarium/infrastructure/FragmentRepository.test.ts +++ b/src/fragmentarium/infrastructure/FragmentRepository.test.ts @@ -168,14 +168,6 @@ const testData: TestData[] = [ ['/fragments?interesting=true', false], Promise.resolve([fragmentInfoDto]) ), - new TestData( - 'fetchLatestTransliterations', - [], - apiClient.fetchJson, - [fragmentInfo], - ['/fragments?latest=true', false], - Promise.resolve([fragmentInfoDto]) - ), new TestData( 'fetchNeedsRevision', [], @@ -392,6 +384,7 @@ const queryTestCases: FragmentQuery[] = [ { bibId: 'foo' }, { bibId: 'foo', pages: '1-2' }, { number: 'X.1' }, + { latest: true }, ] const queryTestData: TestData[] = queryTestCases.map( diff --git a/src/fragmentarium/infrastructure/FragmentRepository.ts b/src/fragmentarium/infrastructure/FragmentRepository.ts index a6038ef48..cfe323e97 100644 --- a/src/fragmentarium/infrastructure/FragmentRepository.ts +++ b/src/fragmentarium/infrastructure/FragmentRepository.ts @@ -174,12 +174,6 @@ class ApiFragmentRepository ) } - fetchLatestTransliterations(): FragmentInfosPromise { - return this._fetch({ latest: true }).then((fragmentInfos) => - fragmentInfos.map(createFragmentInfo) - ) - } - fetchNeedsRevision(): FragmentInfosPromise { return this._fetch({ needsRevision: true }).then((fragmentInfos) => fragmentInfos.map(createFragmentInfo) diff --git a/src/fragmentarium/ui/front-page/Fragmentarium.css b/src/fragmentarium/ui/front-page/Fragmentarium.css index 2aa9ce334..eaad40cc8 100644 --- a/src/fragmentarium/ui/front-page/Fragmentarium.css +++ b/src/fragmentarium/ui/front-page/Fragmentarium.css @@ -1,3 +1,4 @@ .SubsectionHeading--indented { padding-left: 2em; + margin-bottom: 1rem; } diff --git a/src/fragmentarium/ui/front-page/Fragmentarium.test.tsx b/src/fragmentarium/ui/front-page/Fragmentarium.test.tsx index 7d75c2180..2a6d315f6 100644 --- a/src/fragmentarium/ui/front-page/Fragmentarium.test.tsx +++ b/src/fragmentarium/ui/front-page/Fragmentarium.test.tsx @@ -9,11 +9,14 @@ import Fragmentarium from './Fragmentarium' import Promise from 'bluebird' import Bluebird from 'bluebird' import { + fragmentFactory, fragmentInfoFactory, statisticsFactory, } from 'test-support/fragment-fixtures' -import { FragmentInfo } from 'fragmentarium/domain/fragment' +import { Fragment, FragmentInfo } from 'fragmentarium/domain/fragment' import WordService from 'dictionary/application/WordService' +import { queryItemOf } from 'test-support/utils' +import { DictionaryContext } from 'dictionary/ui/dictionary-context' jest.mock('fragmentarium/application/FragmentSearchService') jest.mock('fragmentarium/application/FragmentService') @@ -37,11 +40,13 @@ async function renderFragmentarium() { container = render( - + + + ).container @@ -72,15 +77,16 @@ describe('Statistics', () => { }) describe('Fragment lists', () => { - let latest: FragmentInfo + let latest: Fragment let needsRevision: FragmentInfo beforeEach(async () => { - latest = fragmentInfoFactory.build() + latest = fragmentFactory.build() session = new MemorySession(['read:fragments', 'transliterate:fragments']) - fragmentSearchService.fetchLatestTransliterations.mockReturnValueOnce( - Promise.resolve([latest]) + fragmentService.query.mockReturnValueOnce( + Promise.resolve({ items: [queryItemOf(latest)], matchCountTotal: 0 }) ) + fragmentService.find.mockReturnValueOnce(Promise.resolve(latest)) needsRevision = fragmentInfoFactory.build() fragmentSearchService.fetchNeedsRevision.mockReturnValue( Promise.resolve([needsRevision]) diff --git a/src/fragmentarium/ui/front-page/Fragmentarium.tsx b/src/fragmentarium/ui/front-page/Fragmentarium.tsx index 3a00c4e3b..00fac5197 100644 --- a/src/fragmentarium/ui/front-page/Fragmentarium.tsx +++ b/src/fragmentarium/ui/front-page/Fragmentarium.tsx @@ -57,9 +57,7 @@ function Fragmentarium({ {session.isAllowedToReadFragments() && ( - + )} diff --git a/src/fragmentarium/ui/front-page/LatestTransliterations.test.tsx b/src/fragmentarium/ui/front-page/LatestTransliterations.test.tsx index b94d8e8d2..1ce1ceedb 100644 --- a/src/fragmentarium/ui/front-page/LatestTransliterations.test.tsx +++ b/src/fragmentarium/ui/front-page/LatestTransliterations.test.tsx @@ -1,52 +1,61 @@ import React from 'react' -import _ from 'lodash' import { render, screen } from '@testing-library/react' +import Chance from 'chance' import { MemoryRouter } from 'react-router-dom' import Promise from 'bluebird' import LatestTransliterations from './LatestTransliterations' -import { FragmentInfo } from 'fragmentarium/domain/fragment' -import { fragmentInfoFactory } from 'test-support/fragment-fixtures' +import FragmentService from 'fragmentarium/application/FragmentService' +import { Fragment } from 'fragmentarium/domain/fragment' +import { fragmentFactory } from 'test-support/fragment-fixtures' +import WordService from 'dictionary/application/WordService' +import { DictionaryContext } from 'dictionary/ui/dictionary-context' +import SessionContext from 'auth/SessionContext' +import MemorySession, { Session } from 'auth/Session' +import { queryItemOf } from 'test-support/utils' + +jest.mock('fragmentarium/application/FragmentService') +jest.mock('dictionary/application/WordService') + +const chance = new Chance('latest-test') const numberOfFragments = 2 -const expectedColumns = { - Number: 'number', - Accession: 'accession', - Script: 'script.period.abbreviation', - Description: 'description', -} -let fragmentSearchService let container: HTMLElement -let fragments: FragmentInfo[] +let fragments: Fragment[] +let session: Session + +const fragmentService = new (FragmentService as jest.Mock< + jest.Mocked +>)() +const wordService = new (WordService as jest.Mock>)() beforeEach(async () => { - fragments = fragmentInfoFactory.buildList(numberOfFragments) - fragmentSearchService = { - fetchLatestTransliterations: jest.fn(), - } - fragmentSearchService.fetchLatestTransliterations.mockReturnValueOnce( - Promise.resolve(fragments) + session = new MemorySession(['read:fragments']) + fragments = fragmentFactory.buildList( + numberOfFragments, + {}, + { transient: { chance } } ) + fragmentService.query.mockReturnValueOnce( + Promise.resolve({ + items: fragments.map(queryItemOf), + matchCountTotal: 0, + }) + ) + fragmentService.find + .mockReturnValueOnce(Promise.resolve(fragments[0])) + .mockReturnValueOnce(Promise.resolve(fragments[1])) container = render( - + + + + + ).container await screen.findByText('Latest additions:') }) -test('Columns', () => { - const expectedHeader = _.keys(expectedColumns).join('') - expect(container).toHaveTextContent(expectedHeader) -}) - -test.each(_.range(numberOfFragments))('Fragment %i', (index) => { - const expectedRow = _.values(expectedColumns) - .map((property) => - property - .split('.') - .reduce((object, index) => object[index], fragments[index]) - ) - .join('') - .replace(/\n/g, ' ') - expect(container).toHaveTextContent(expectedRow) +test('Snapshot', () => { + expect(container).toMatchSnapshot() }) diff --git a/src/fragmentarium/ui/front-page/LatestTransliterations.tsx b/src/fragmentarium/ui/front-page/LatestTransliterations.tsx index e0ec16e6f..dee3c771c 100644 --- a/src/fragmentarium/ui/front-page/LatestTransliterations.tsx +++ b/src/fragmentarium/ui/front-page/LatestTransliterations.tsx @@ -1,33 +1,44 @@ import React from 'react' -import FragmentList from 'fragmentarium/ui/FragmentList' import withData from 'http/withData' -import { FragmentInfo } from 'fragmentarium/domain/fragment' -import Promise from 'bluebird' +import FragmentService from 'fragmentarium/application/FragmentService' +import { QueryResult } from 'query/QueryResult' +import { FragmentLines } from '../search/FragmentariumSearchResult' -function LatestTransliterations({ data }: { data: readonly FragmentInfo[] }) { +function LatestTransliterations({ + data, + fragmentService, +}: { + data: QueryResult + fragmentService: FragmentService +}) { return (

    Latest additions:

    - + {data.items.map((fragment, index) => ( + + + + ))}
    ) } export default withData< - unknown, { - fragmentSearchService: { - fetchLatestTransliterations: () => Promise - } + fragmentService: FragmentService + }, + unknown, + QueryResult +>( + ({ data, fragmentService }): JSX.Element => { + return ( + + ) }, - readonly FragmentInfo[] ->(LatestTransliterations, (props) => - props.fragmentSearchService.fetchLatestTransliterations() + (props) => props.fragmentService.query({ latest: true }) ) diff --git a/src/fragmentarium/ui/front-page/Statistics.css b/src/fragmentarium/ui/front-page/Statistics.css index 6a8b56bdd..5d417d21c 100644 --- a/src/fragmentarium/ui/front-page/Statistics.css +++ b/src/fragmentarium/ui/front-page/Statistics.css @@ -1,6 +1,7 @@ .Statistics { font-size: 1.5em; margin-top: 2em; + margin-bottom: 1em; } .Statistics__row { diff --git a/src/fragmentarium/ui/front-page/__snapshots__/LatestTransliterations.test.tsx.snap b/src/fragmentarium/ui/front-page/__snapshots__/LatestTransliterations.test.tsx.snap new file mode 100644 index 000000000..f3f3773cd --- /dev/null +++ b/src/fragmentarium/ui/front-page/__snapshots__/LatestTransliterations.test.tsx.snap @@ -0,0 +1,11620 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Snapshot 1`] = ` +
    +
    +

    + Latest additions: +

    +
    +
    +

    + + tichi.1 + + (Fara) +

    + +

    + Accession no.: + kuljulom.1 +

    +

    + Excavation no.: + noj.1 +

    +
    +
    +
    +
      +
        + + ARCHIVE ➝ Administrative ➝ Lists + +
      +
        + + Other ➝ Fake ➝ Certain + +
      +
    +
    +
    +
      +
    1. + Pistolesi + ( + Transliteration + , + + + ) +
    2. +
    +
    +
    +
    +
    +
    + 1.I.1 SE (3 April 311 BCE) +
    +
    +
    +
    +
    + +
      +
    1. + + Fanti & Carr, 2036: 8970824935538688-3796097900216320 + [ + l. 4'.2., 2. + ] + + (P) + + +
    2. +
    3. + + Hall & Reid, 2089: 7020923936833536-4895425479835648 + [ + l. 4'.2., 3'. + ] + + (P) + + +
    4. +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 1 + + + + + + + + + érin + + + + + + + + + - + + + + + [ + + + + + ( + + + + + + + ŠÁ + + + + + + + + + - + + + + + + + + šà + + + + + + + / + + + + + GÌRI + + + + + + + + + + ) + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + saḫ + + + + + + + + + - + + + + + + + SAḪ + + + + + + + + + + + + + + … + + + + ] + + +
    + 2 + + + + + + + |KUR.KUR| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + / + + + |RA| + + + + + + + + + + + + [ + + + + … + + + + ] + + +
    + 3 + + + + + + + ⸢ + + + + + 1 + + + + v + + + * + + + + ⸣ + + + + + + + + + + + + + + ⸢ + + + x + + ! + + + + ⸣ + + + + + + + + + + + + + + ⸢ + + + X + + ? + + + + ⸣ + + + + + + + + + + + ⸢ + + + :: + + v44 + + + ? + + + + ⸣ + + + + + + + | + + + + + + + + + + [ + + + + + ( + + + + + o + + + + + + ) + + + + + + + + + + + + + + o + + + + + + ] + + + + + +
    + 4 + + + + + + + + + + + + + ⸢ + + + + + kur + + + + ₓ + + + v + + + ! + + + ( + + + + ⸢ + + + KUR + + v + + + ? + + + + ⸣ + + + + ) + + + + ⸣ + + + + + - + + + + + ⸢ + + + + + KÚR + + + + v + + + ? + + + <( + + + + + + kur + + + + + + + + + - + + + + + + + kur + + + + + + + + )> + + + + ⸣ + + + + + +
    + 5 + + + + ° + + + + + + + + + + kur + + + + + + + + + + + + \\ + + + + + + + + + + kur + + + + + + + + + + + + ° + + + + + + + + + + + + + kur + + + + + + + + + - + + + + + ° + + + + + + + kur + + + + + + + + + \\ + + + + + + + kur + + + + + + + + + ° + + + + + - + + + + + + + kur + + + + + + + + + +
    + 6 + + + + + + + + . + + + + + + ⸢ + + + + + + + d + + + + + + + + + + + ⸣ + + + + + + + - + + + + + + + + + kúr + + + + + + + ? + + + + + + + + + . + + + + + + + + d + + + + + + + + + + + + + - + + + + + + + + + RA + + + + + + + ! + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + + k + + + + + + [ + + + + + + u + + + + + + ] + + + + + + r + + + + + + + + + + + + + + . + + + + + + + + + + d + + + + + + + + + ! + + + + + + + + + + + + + + + + + + + + + + + KÚR + + + + + + + ! + + + + + + + + - + + + + + + + + + ra + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + . + + + + + + + + + + k + + + + + + + [ + + + + + + + ur + + + + + + + + + + + + + + + ] + + + + + + + - + + + + + + + + + + + RA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + kúr + + + + + + + + + + + + +
    + 1 + + + + + + + [ + + + + + ( + + + + + + + kur + + + + + + + + + ) + + + + + ] + + + + + - + + + + + [ + + + + + + . + + + + + + + + k + + + + + + ] + + + + + + ur + + + + + + + + + + + + + - + + + + + + [ + + + + + + + + kur + + + + + + + + + + + + + ] + + + + + + + k + + + + + [ + + + + + ur + + + + + + + + + ] + + + + + +
    + 2 + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + . + + + + + + + + d + + + + + + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + + . + + + + + + + + D + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + 3 + + + + + + + |KUR₂.KUR| + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + ra + + + + + + + / + + + ⸢ + + + + + RA + + + + + + + ⸣ + + + + + + - + + + + + + + kúr + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + kur + + + + + ! + + + + + + + + + + + + :. + + + + + + + + + + + + + + + + kur + + + + + + + / + + + ⸢ + + + + + KUR + + + + + + + ⸣ + + + + + + +
    + 4 + + + + + + + |KUR₂.KUR| + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + ra + + + + + + + / + + + ⸢ + + + + + RA + + + + + + + ⸣ + + + + + + - + + + + + + + kúr + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + kur + + + + + ! + + + + + + + + + + + + :. + + + + + + + + + + + + + + + + kur + + + + + + + / + + + ⸢ + + + + + KUR + + + + + + + ⸣ + + + + + + +
    + 5 + + + + + + + < + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + > + + + + + + + + + + + + + + <( + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + )> + + + + + + + + + + + + + + << + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + >> + + + + + + + + + + + + + + + + < + + + + + + + + kur + + + + + + + + + ( + + + + + KUR + + + + + + + ) + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + > + + + + + + + + + + + + + + + + <( + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + )> + + + + + + + + + + + + + + + + << + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + >> + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + <( + + + + + + + kur + + + + + + + + + + + + + - + + + + + + + + + kur + + + + + + + + + + + )> + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + +
    + 6 + + + + [ + + + + + ] + + + + + + + + [ + + + + + + + + + + + ra + + + + + + + + + + + + + + + ] + + +
    + 7 + + + + [ + + + + … + + + + + + + + + + + + + + + + ḫe + + + + + + + + + + + + + - + + + + + + + + + p + + + + + + ] + + + + + + í + + + + + + + + + + + + + +
    + D+3′a–4b + + + + + + + x + + + + + + + + + + + + + + + + + a + + + + + + + + + - + + + + + + • + + + ? + + + + + + +
    + c+1 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + c+2 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + c+3 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + 9 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + n+1 + + + + + + + kur + + + + ? + + + + + + + + + + + + + < + + + + + ḫur + + + + ! + + + + > + + + + + + + + + + + + + + [ + + + + + kur + + + + + - + + + + + ( + + + + + kur + + + + + ) + + + + … + + + + + ] + + + + + + + + + + + + + + ( + + + + + kur + + + + + + ) + + + + + + + + + + + + + + kur + + + + + - + + + + + kur + + + + … + + + + + +
    + n+2 + + + … + + + + + + + + + + … + + + + + + + + + + … + + + + + + + + + + … + + + + + + + + + + … + +
    + g+1 + + + + + + Α + + + + + +
    + g+1 + + + + + + [ + + + + + ⸢ + + + Α + + ? + + + + ⸣ + + + + + ] + + + + + Α + + + + + +
    + g+1 + + + + + + [ + + + + + Α + + ! + + + + + + + + + + + + + o + + + + + … + + + + ] + + + + +
    +
    +
    +
      +
    +
    +
    +
    +
    +

    + + cowjofke.2 + + (Unc) +

    + +

    + Accession no.: + ed.2 +

    +

    + Excavation no.: + pole.2 +

    +
    +
    +
    +
      +
        + + Other ➝ Fake ➝ Certain + +
      +
    +
    +
    +
      +
    1. + No record +
    2. +
    +
    +
    +
    +
    +
    + 1.I.1 SE (3 April 311 BCE) +
    +
    +
    +
    +
    + +
      +
    1. + + Checcucci & Tomlinson, 2025: 4727451873705984-8024100712742912 + [ + l. 3'., 1. + ] + + (C) + + +
    2. +
    +
      +
    1. + + Chirici & Borchi, 2108: 7541452181602304-6009873588289536 + [ + l. 3'., 4'.2. + ] + + (E) + + +
    2. +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 1 + + + + + + + + + érin + + + + + + + + + - + + + + + [ + + + + + ( + + + + + + + ŠÁ + + + + + + + + + - + + + + + + + + šà + + + + + + + / + + + + + GÌRI + + + + + + + + + + ) + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + saḫ + + + + + + + + + - + + + + + + + SAḪ + + + + + + + + + + + + + + … + + + + ] + + +
    + 2 + + + + + + + |KUR.KUR| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + / + + + |RA| + + + + + + + + + + + + [ + + + + … + + + + ] + + +
    + 3 + + + + + + + ⸢ + + + + + 1 + + + + v + + + * + + + + ⸣ + + + + + + + + + + + + + + ⸢ + + + x + + ! + + + + ⸣ + + + + + + + + + + + + + + ⸢ + + + X + + ? + + + + ⸣ + + + + + + + + + + + ⸢ + + + :: + + v44 + + + ? + + + + ⸣ + + + + + + + | + + + + + + + + + + [ + + + + + ( + + + + + o + + + + + + ) + + + + + + + + + + + + + + o + + + + + + ] + + + + + +
    + 4 + + + + + + + + + + + + + ⸢ + + + + + kur + + + + ₓ + + + v + + + ! + + + ( + + + + ⸢ + + + KUR + + v + + + ? + + + + ⸣ + + + + ) + + + + ⸣ + + + + + - + + + + + ⸢ + + + + + KÚR + + + + v + + + ? + + + <( + + + + + + kur + + + + + + + + + - + + + + + + + kur + + + + + + + + )> + + + + ⸣ + + + + + +
    + 5 + + + + ° + + + + + + + + + + kur + + + + + + + + + + + + \\ + + + + + + + + + + kur + + + + + + + + + + + + ° + + + + + + + + + + + + + kur + + + + + + + + + - + + + + + ° + + + + + + + kur + + + + + + + + + \\ + + + + + + + kur + + + + + + + + + ° + + + + + - + + + + + + + kur + + + + + + + + + +
    + 6 + + + + + + + + . + + + + + + ⸢ + + + + + + + d + + + + + + + + + + + ⸣ + + + + + + + - + + + + + + + + + kúr + + + + + + + ? + + + + + + + + + . + + + + + + + + d + + + + + + + + + + + + + - + + + + + + + + + RA + + + + + + + ! + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + + k + + + + + + [ + + + + + + u + + + + + + ] + + + + + + r + + + + + + + + + + + + + + . + + + + + + + + + + d + + + + + + + + + ! + + + + + + + + + + + + + + + + + + + + + + + KÚR + + + + + + + ! + + + + + + + + - + + + + + + + + + ra + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + . + + + + + + + + + + k + + + + + + + [ + + + + + + + ur + + + + + + + + + + + + + + + ] + + + + + + + - + + + + + + + + + + + RA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + kúr + + + + + + + + + + + + +
    + 1 + + + + + + + [ + + + + + ( + + + + + + + kur + + + + + + + + + ) + + + + + ] + + + + + - + + + + + [ + + + + + + . + + + + + + + + k + + + + + + ] + + + + + + ur + + + + + + + + + + + + + - + + + + + + [ + + + + + + + + kur + + + + + + + + + + + + + ] + + + + + + + k + + + + + [ + + + + + ur + + + + + + + + + ] + + + + + +
    + 2 + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + . + + + + + + + + d + + + + + + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + + . + + + + + + + + D + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + 3 + + + + + + + |KUR₂.KUR| + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + ra + + + + + + + / + + + ⸢ + + + + + RA + + + + + + + ⸣ + + + + + + - + + + + + + + kúr + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + kur + + + + + ! + + + + + + + + + + + + :. + + + + + + + + + + + + + + + + kur + + + + + + + / + + + ⸢ + + + + + KUR + + + + + + + ⸣ + + + + + + +
    + 4 + + + + + + + |KUR₂.KUR| + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + + ra + + + + + + + / + + + ⸢ + + + + + RA + + + + + + + ⸣ + + + + + + - + + + + + + + kúr + + + + + + + + + + + + + + + + + + + . + + + + + + + + kur + + + + + + + + + + + + + + + kur + + + + + ! + + + + + + + + + + + + :. + + + + + + + + + + + + + + + + kur + + + + + + + / + + + ⸢ + + + + + KUR + + + + + + + ⸣ + + + + + + +
    + 5 + + + + + + + < + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + > + + + + + + + + + + + + + + <( + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + )> + + + + + + + + + + + + + + << + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + >> + + + + + + + + + + + + + + + + < + + + + + + + + kur + + + + + + + + + ( + + + + + KUR + + + + + + + ) + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + > + + + + + + + + + + + + + + + + <( + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + )> + + + + + + + + + + + + + + + + << + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + >> + + + + + + + + + + + + + + + + + + + KUR + + + + + + + + + <( + + + + + + + kur + + + + + + + + + + + + + - + + + + + + + + + kur + + + + + + + + + + + )> + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + +
    + 6 + + + + [ + + + + + ] + + + + + + + + [ + + + + + + + + + + + ra + + + + + + + + + + + + + + + ] + + +
    + 7 + + + + [ + + + + … + + + + + + + + + + + + + + + + ḫe + + + + + + + + + + + + + - + + + + + + + + + p + + + + + + ] + + + + + + í + + + + + + + + + + + + + +
    + D+3′a–4b + + + + + + + x + + + + + + + + + + + + + + + + + a + + + + + + + + + - + + + + + + • + + + ? + + + + + + +
    + c+1 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + c+2 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + c+3 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + 9 + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + + + + + + + + + + + + kur + + + + + + + + + +
    + n+1 + + + + + + + kur + + + + ? + + + + + + + + + + + + + < + + + + + ḫur + + + + ! + + + + > + + + + + + + + + + + + + + [ + + + + + kur + + + + + - + + + + + ( + + + + + kur + + + + + ) + + + + … + + + + + ] + + + + + + + + + + + + + + ( + + + + + kur + + + + + + ) + + + + + + + + + + + + + + kur + + + + + - + + + + + kur + + + + … + + + + + +
    + n+2 + + + … + + + + + + + + + + … + + + + + + + + + + … + + + + + + + + + + … + + + + + + + + + + … + +
    + g+1 + + + + + + Α + + + + + +
    + g+1 + + + + + + [ + + + + + ⸢ + + + Α + + ? + + + + ⸣ + + + + + ] + + + + + Α + + + + + +
    + g+1 + + + + + + [ + + + + + Α + + ! + + + + + + + + + + + + + o + + + + + … + + + + ] + + + + +
    +
    +
    +
      +
    +
    +
    +
    +
    +`; diff --git a/src/fragmentarium/ui/info/Record.tsx b/src/fragmentarium/ui/info/Record.tsx index 27573e524..2d073ea26 100644 --- a/src/fragmentarium/ui/info/Record.tsx +++ b/src/fragmentarium/ui/info/Record.tsx @@ -4,6 +4,7 @@ import _ from 'lodash' import { DateTime, Interval } from 'luxon' import './Record.css' import { RecordEntry } from 'fragmentarium/domain/RecordEntry' +import classnames from 'classnames' type EntryProps = { entry: RecordEntry @@ -64,16 +65,28 @@ function Record({ return (

    Record

    -
      - {record.map((entry, index) => ( -
    1. - -
    2. - ))} - {_.isEmpty(record) &&
    3. No record
    4. } -
    +
    ) } +export function RecordList({ + record, + className, +}: { + record: readonly RecordEntry[] + className?: string +}): JSX.Element { + return ( +
      + {record.map((entry, index) => ( +
    1. + +
    2. + ))} + {_.isEmpty(record) &&
    3. No record
    4. } +
    + ) +} + export default Record diff --git a/src/fragmentarium/ui/info/ResearchProjects.sass b/src/fragmentarium/ui/info/ResearchProjects.sass new file mode 100644 index 000000000..6f2644833 --- /dev/null +++ b/src/fragmentarium/ui/info/ResearchProjects.sass @@ -0,0 +1,6 @@ +.ResultList + ul + padding: 0 + li + list-style: none + padding-bottom: .5rem diff --git a/src/fragmentarium/ui/info/ResearchProjects.tsx b/src/fragmentarium/ui/info/ResearchProjects.tsx index a919b5dc7..f3fe70dcd 100644 --- a/src/fragmentarium/ui/info/ResearchProjects.tsx +++ b/src/fragmentarium/ui/info/ResearchProjects.tsx @@ -1,7 +1,7 @@ import ExternalLink from 'common/ExternalLink' -import { Fragment } from 'fragmentarium/domain/fragment' import React from 'react' import { ResearchProject } from 'research-projects/researchProject' +import './ResearchProjects.sass' export function ProjectList({ projects, @@ -9,21 +9,22 @@ export function ProjectList({ projects: readonly ResearchProject[] }): JSX.Element { return ( - <> +
      {projects.map((project, index) => ( - - {project.name} - +
    • + + {project.name} + +
    • ))} - +
    ) } diff --git a/src/fragmentarium/ui/search/FragmentariumSearch.test.tsx b/src/fragmentarium/ui/search/FragmentariumSearch.test.tsx index 76fe342a3..811950636 100644 --- a/src/fragmentarium/ui/search/FragmentariumSearch.test.tsx +++ b/src/fragmentarium/ui/search/FragmentariumSearch.test.tsx @@ -13,7 +13,7 @@ import WordService from 'dictionary/application/WordService' import { DictionaryContext } from 'dictionary/ui/dictionary-context' import FragmentService from 'fragmentarium/application/FragmentService' import { FragmentQuery } from 'query/FragmentQuery' -import { CorpusQueryResult, QueryItem, QueryResult } from 'query/QueryResult' +import { CorpusQueryResult, QueryResult } from 'query/QueryResult' import { corpusQueryItemFactory, queryItemFactory, @@ -24,6 +24,7 @@ import { chapterDisplayFactory } from 'test-support/chapter-fixtures' import userEvent from '@testing-library/user-event' import { LineDetails } from 'corpus/domain/line-details' import { lineVariantDisplayFactory } from 'test-support/dictionary-line-fixtures' +import { queryItemOf } from 'test-support/utils' const chance = new Chance('fragmentarium-search-test') @@ -78,14 +79,6 @@ beforeEach(async () => { fragmentService.fetchGenres.mockReturnValueOnce(Promise.resolve([])) }) -function queryItemOf(fragment: Fragment): QueryItem { - return { - museumNumber: fragment.number, - matchingLines: [], - matchCount: 0, - } -} - describe('Search', () => { let fragments: Fragment[] describe('Searching fragments by number', () => { diff --git a/src/fragmentarium/ui/search/FragmentariumSearchResult.sass b/src/fragmentarium/ui/search/FragmentariumSearchResult.sass index 1bbb488a0..8a678dec5 100644 --- a/src/fragmentarium/ui/search/FragmentariumSearchResult.sass +++ b/src/fragmentarium/ui/search/FragmentariumSearchResult.sass @@ -4,12 +4,17 @@ padding: 1em 0 .fragment-result - &__fragment-number - margin-bottom: 0 - &__accession + &__fragment-number, &__accession, &__record margin-bottom: 0 + &__record + .Record__entry + font-size: 80% &__genre ul padding-left: 0 &__project-logos display: flex - justify-content: end \ No newline at end of file + justify-content: start + + ul.ResultList + padding: 0 + margin: 0 diff --git a/src/fragmentarium/ui/search/FragmentariumSearchResult.tsx b/src/fragmentarium/ui/search/FragmentariumSearchResult.tsx index 890e35d08..452e5519b 100644 --- a/src/fragmentarium/ui/search/FragmentariumSearchResult.tsx +++ b/src/fragmentarium/ui/search/FragmentariumSearchResult.tsx @@ -16,31 +16,8 @@ import DateDisplay from 'fragmentarium/ui/info/DateDisplay' import { stringify } from 'query-string' import { ResultPageButtons } from 'common/ResultPageButtons' import { ProjectList } from '../info/ResearchProjects' - -export function createPages( - pages: readonly unknown[][], - active: number -): number[][] { - const pageNumbers = _.range(pages.length) - - if (pages.length <= 10) { - return [pageNumbers] - } - const buttonGroups: number[][] = [] - const showEllipsis1 = active > 5 - const showEllipsis2 = active < pageNumbers.length - 6 - - const activeGroup = pageNumbers.slice( - showEllipsis1 ? active - 3 : 0, - showEllipsis2 ? active + 4 : pageNumbers.length - ) - - showEllipsis1 && buttonGroups.push([0]) - buttonGroups.push(activeGroup) - showEllipsis2 && buttonGroups.push(pageNumbers.slice(-1)) - - return buttonGroups -} +import { RecordList } from 'fragmentarium/ui/info/Record' +import { RecordEntry } from 'fragmentarium/domain/RecordEntry' function ResultPages({ fragments, @@ -93,19 +70,45 @@ function GenresDisplay({ genres }: { genres: Genres }): JSX.Element { ) } -const FragmentLines = withData< + +function TransliterationRecord({ + record, + className, +}: { + record: readonly RecordEntry[] + className?: string +}): JSX.Element { + const latestRecord = _(record) + .filter((record) => record.type === 'Transliteration') + .first() + return ( + + ) +} + +export const FragmentLines = withData< { queryLemmas?: readonly string[] queryItem: QueryItem linesToShow: number + includeLatestRecord?: boolean }, { fragmentService: FragmentService - active: number + active?: number }, Fragment >( - ({ data: fragment, queryLemmas, queryItem, linesToShow }): JSX.Element => { + ({ + data: fragment, + queryLemmas, + queryItem, + linesToShow, + includeLatestRecord, + }): JSX.Element => { const script = fragment.script.period.abbreviation ? ` (${fragment.script.period.abbreviation})` : '' @@ -133,6 +136,14 @@ const FragmentLines = withData< + + {includeLatestRecord && ( + + )} + {fragment?.date && ( diff --git a/src/fragmentarium/ui/search/__snapshots__/FragmentariumSearch.test.tsx.snap b/src/fragmentarium/ui/search/__snapshots__/FragmentariumSearch.test.tsx.snap index e1f4a5925..52b62bb8a 100644 --- a/src/fragmentarium/ui/search/__snapshots__/FragmentariumSearch.test.tsx.snap +++ b/src/fragmentarium/ui/search/__snapshots__/FragmentariumSearch.test.tsx.snap @@ -672,7 +672,9 @@ exports[`Searching fragments by transliteration Displays corpus results when cli class="col" > +
    + > +
      +

    +
    + > +
      +