diff --git a/src/App.test.ts b/src/App.test.ts
index aeefed8e9..c82e6b93d 100644
--- a/src/App.test.ts
+++ b/src/App.test.ts
@@ -1,6 +1,6 @@
import AppDriver from 'test-support/AppDriver'
import FakeApi from 'test-support/FakeApi'
-import { statisticsFactory } from 'test-support/fragment-fixtures'
+import { statisticsFactory } from 'test-support/fragment-data-fixtures'
import { tabIds as aboutTabIds } from 'about/ui/about'
test.each([
diff --git a/src/chronology/ui/DateEditor/DateSelectionInput.test.tsx b/src/chronology/ui/DateEditor/DateSelectionInput.test.tsx
index 97bc1141a..03ce73cc7 100644
--- a/src/chronology/ui/DateEditor/DateSelectionInput.test.tsx
+++ b/src/chronology/ui/DateEditor/DateSelectionInput.test.tsx
@@ -141,15 +141,15 @@ describe('Date Input Groups', () => {
})
)
const yearInput = screen.getByLabelText('Year')
- const yearBrokenSwitch = screen.getByLabelText('Year-Broken')
- const yearUncertainSwitch = screen.getByLabelText('Year-Uncertain')
+ const yearBrokenSwitch = screen.getByTestId('year-broken-switch')
+ const yearUncertainSwitch = screen.getByTestId('year-uncertain-switch')
const monthInput = screen.getByLabelText('Month')
const monthIntercalaryCheckbox = screen.getByLabelText('Intercalary')
- const monthBrokenSwitch = screen.getByLabelText('Month-Broken')
- const monthUncertainSwitch = screen.getByLabelText('Month-Uncertain')
+ const monthBrokenSwitch = screen.getByTestId('month-broken-switch')
+ const monthUncertainSwitch = screen.getByTestId('month-uncertain-switch')
const dayInput = screen.getByLabelText('Day')
- const dayBrokenSwitch = screen.getByLabelText('Day-Broken')
- const dayUncertainSwitch = screen.getByLabelText('Day-Uncertain')
+ const dayBrokenSwitch = screen.getByTestId('day-broken-switch')
+ const dayUncertainSwitch = screen.getByTestId('day-uncertain-switch')
expect(yearInput).toBeInTheDocument()
expect(yearBrokenSwitch).toBeInTheDocument()
diff --git a/src/chronology/ui/DateEditor/DateSelectionInput.tsx b/src/chronology/ui/DateEditor/DateSelectionInput.tsx
index 2923c66b8..a49c72969 100644
--- a/src/chronology/ui/DateEditor/DateSelectionInput.tsx
+++ b/src/chronology/ui/DateEditor/DateSelectionInput.tsx
@@ -13,8 +13,8 @@ import getDateConfigs from 'chronology/application/DateSelectionInputConfig'
import {
InputGroupProps,
RadioButton,
- getBrokenAndUncertainSwitches,
} from 'chronology/ui/DateEditor/DateSelectionInputBase'
+import { BrokenAndUncertainSwitches } from 'common/BrokenAndUncertain'
type InputGroupsProps = {
yearValue: string
@@ -93,13 +93,15 @@ function getKingEponymSelect(
? EponymField({ ...props, assyrianPhase })
: KingField(props)}
- {getBrokenAndUncertainSwitches({
- name,
- isBroken: props[`${name}Broken`] ?? false,
- isUncertain: props[`${name}Uncertain`] ?? false,
- setBroken: props[`set${_.capitalize(name)}Broken`],
- setUncertain: props[`set${_.capitalize(name)}Uncertain`],
- })}
+
>
@@ -195,13 +197,15 @@ function getDateInputGroup({
checked={isIntercalary}
/>
)}
- {getBrokenAndUncertainSwitches({
- name,
- isBroken,
- isUncertain,
- setBroken,
- setUncertain,
- })}
+
)
}
diff --git a/src/chronology/ui/DateEditor/DateSelectionInputBase.tsx b/src/chronology/ui/DateEditor/DateSelectionInputBase.tsx
index 147320804..53101d090 100644
--- a/src/chronology/ui/DateEditor/DateSelectionInputBase.tsx
+++ b/src/chronology/ui/DateEditor/DateSelectionInputBase.tsx
@@ -1,15 +1,7 @@
+import { BrokenUncertainProps } from 'common/BrokenAndUncertain'
import React from 'react'
-import _ from 'lodash'
import { Form } from 'react-bootstrap'
-export interface BrokenUncertainProps {
- name: string
- isBroken: boolean
- isUncertain: boolean
- setBroken: React.Dispatch>
- setUncertain: React.Dispatch>
-}
-
export interface InputGroupProps extends BrokenUncertainProps {
value: string
isIntercalary?: boolean
@@ -42,30 +34,3 @@ export const RadioButton = ({
onChange={onChange}
/>
)
-
-export function getBrokenAndUncertainSwitches({
- name,
- isBroken,
- isUncertain,
- setBroken,
- setUncertain,
-}: BrokenUncertainProps): JSX.Element {
- return (
- <>
- setBroken(event.target.checked)}
- checked={isBroken}
- />
- setUncertain(event.target.checked)}
- checked={isUncertain}
- />
- >
- )
-}
diff --git a/src/common/BrokenAndUncertain.tsx b/src/common/BrokenAndUncertain.tsx
new file mode 100644
index 000000000..87d404356
--- /dev/null
+++ b/src/common/BrokenAndUncertain.tsx
@@ -0,0 +1,45 @@
+import React from 'react'
+import { Form } from 'react-bootstrap'
+
+export interface BrokenUncertainProps {
+ name: string
+ isBroken?: boolean
+ isUncertain?: boolean
+ setBroken:
+ | React.Dispatch>
+ | ((isBroken: boolean) => void)
+ setUncertain:
+ | React.Dispatch>
+ | ((isUncertain: boolean) => void)
+}
+
+export function BrokenAndUncertainSwitches({
+ name,
+ isBroken = false,
+ isUncertain = false,
+ setBroken,
+ setUncertain,
+}: BrokenUncertainProps): JSX.Element {
+ return (
+ <>
+ setBroken(event.target.checked)}
+ checked={isBroken}
+ />
+ setUncertain(event.target.checked)}
+ checked={isUncertain}
+ />
+ >
+ )
+}
diff --git a/src/fragmentarium/application/FindspotService.test.ts b/src/fragmentarium/application/FindspotService.test.ts
index 18704766c..fecb7673b 100644
--- a/src/fragmentarium/application/FindspotService.test.ts
+++ b/src/fragmentarium/application/FindspotService.test.ts
@@ -1,4 +1,4 @@
-import { findspotFactory } from 'test-support/fragment-fixtures'
+import { findspotFactory } from 'test-support/fragment-data-fixtures'
import { FindspotService } from './FindspotService'
import { testDelegation, TestData } from 'test-support/utils'
diff --git a/src/fragmentarium/application/FragmentService.test.ts b/src/fragmentarium/application/FragmentService.test.ts
index fd5cb4ae3..32ad19813 100644
--- a/src/fragmentarium/application/FragmentService.test.ts
+++ b/src/fragmentarium/application/FragmentService.test.ts
@@ -17,10 +17,10 @@ import LemmatizationFactory from './LemmatizationFactory'
import BibliographyService from 'bibliography/application/BibliographyService'
import WordRepository from 'dictionary/infrastructure/WordRepository'
import {
- archaeologyFactory,
fragmentFactory,
manuscriptAttestationFactory,
} from 'test-support/fragment-fixtures'
+import { archaeologyFactory } from 'test-support/fragment-data-fixtures'
import {
bibliographyEntryFactory,
referenceFactory,
@@ -58,15 +58,17 @@ const fragmentRepository = {
updateIntroduction: jest.fn(),
updateNotes: jest.fn(),
updateLemmatization: jest.fn(),
- fetchGenres: jest.fn(),
- fetchProvenances: jest.fn(),
updateGenres: jest.fn(),
updateScript: jest.fn(),
updateDate: jest.fn(),
updateDatesInText: jest.fn(),
+ fetchGenres: jest.fn(),
+ fetchProvenances: jest.fn(),
fetchPeriods: jest.fn(),
+ fetchColophonNames: jest.fn(),
updateReferences: jest.fn(),
updateArchaeology: jest.fn(),
+ updateColophon: jest.fn(),
folioPager: jest.fn(),
fragmentPager: jest.fn(),
findLemmas: jest.fn(),
@@ -199,6 +201,7 @@ describe('methods returning fragment', () => {
let fragment: Fragment
let result: Fragment
let genreResult: string[][]
+ let colophonNamesResult: string[]
const genreOptions = [['ARCHIVE', 'Administrative']]
const genres: Genres = Genres.fromJson([
{
@@ -206,6 +209,7 @@ describe('methods returning fragment', () => {
uncertain: false,
},
])
+ const colophonNamesOptions = [['Humbaba', 'Enkidu']]
const date: MesopotamianDate = MesopotamianDate.fromJson({
year: { value: '1' },
month: { value: '1' },
@@ -373,6 +377,19 @@ describe('methods returning fragment', () => {
expect(fragmentRepository.fetchGenres).toHaveBeenCalled())
})
+ describe('fetch colophon names', () => {
+ beforeEach(async () => {
+ fragmentRepository.fetchColophonNames.mockReturnValue(
+ Promise.resolve(colophonNamesOptions)
+ )
+ colophonNamesResult = await fragmentService.fetchColophonNames('u')
+ })
+ test('returns names', () =>
+ expect(colophonNamesResult).toEqual(colophonNamesOptions))
+ test('calls repository with correct parameters', () =>
+ expect(fragmentRepository.fetchColophonNames).toHaveBeenCalled())
+ })
+
describe('update genre', () => {
let expectedFragment: Fragment
diff --git a/src/fragmentarium/application/FragmentService.ts b/src/fragmentarium/application/FragmentService.ts
index 817e076eb..6db58245e 100644
--- a/src/fragmentarium/application/FragmentService.ts
+++ b/src/fragmentarium/application/FragmentService.ts
@@ -26,6 +26,7 @@ import { FragmentQuery } from 'query/FragmentQuery'
import { MesopotamianDate } from 'chronology/domain/Date'
import { FragmentAfoRegisterQueryResult, QueryResult } from 'query/QueryResult'
import { ArchaeologyDto } from 'fragmentarium/domain/archaeologyDtos'
+import { Colophon } from 'fragmentarium/domain/Colophon'
export type ThumbnailSize = 'small' | 'medium' | 'large'
@@ -65,6 +66,7 @@ export interface FragmentRepository {
fetchGenres(): Bluebird
fetchProvenances(): Bluebird
fetchPeriods(): Bluebird
+ fetchColophonNames(query: string): Bluebird
updateGenres(number: string, genres: Genres): Bluebird
updateScript(number: string, script: Script): Bluebird
updateDate(number: string, date: MesopotamianDate): Bluebird
@@ -90,6 +92,7 @@ export interface FragmentRepository {
number: string,
archaeology: ArchaeologyDto
): Bluebird
+ updateColophon(number: string, colophon: Colophon): Bluebird
folioPager(folio: Folio, fragmentNumber: string): Bluebird
fragmentPager(fragmentNumber: string): Bluebird
findLemmas(lemma: string, isNormalized: boolean): Bluebird
@@ -184,6 +187,7 @@ export class FragmentService {
fetchGenres(): Bluebird {
return this.fragmentRepository.fetchGenres()
}
+
fetchProvenances(): Bluebird {
return this.fragmentRepository.fetchProvenances()
}
@@ -192,6 +196,10 @@ export class FragmentService {
return this.fragmentRepository.fetchPeriods()
}
+ fetchColophonNames(query: string): Bluebird {
+ return this.fragmentRepository.fetchColophonNames(query)
+ }
+
listAllFragments(): Bluebird {
return this.fragmentRepository.listAllFragments()
}
@@ -262,6 +270,12 @@ export class FragmentService {
.then((fragment: Fragment) => this.injectReferences(fragment))
}
+ updateColophon(number: string, colophon: Colophon): Bluebird {
+ return this.fragmentRepository
+ .updateColophon(number, colophon)
+ .then((fragment: Fragment) => this.injectReferences(fragment))
+ }
+
findInCorpus(number: string): Bluebird> {
return this.fragmentRepository.findInCorpus(number)
}
diff --git a/src/fragmentarium/domain/Colophon.test.ts b/src/fragmentarium/domain/Colophon.test.ts
new file mode 100644
index 000000000..7629465a8
--- /dev/null
+++ b/src/fragmentarium/domain/Colophon.test.ts
@@ -0,0 +1,113 @@
+import {
+ Colophon,
+ IndividualAttestation,
+ ColophonStatus,
+ ColophonOwnership,
+ ColophonType,
+ IndividualType,
+} from 'fragmentarium/domain/Colophon'
+
+describe('Colophon', () => {
+ describe('constructor', () => {
+ it('should initialize with empty values if no arguments provided', () => {
+ const colophon = new Colophon({})
+ expect(colophon.colophonStatus).toBeUndefined()
+ expect(colophon.colophonOwnership).toBeUndefined()
+ expect(colophon.colophonTypes).toBeUndefined()
+ expect(colophon.originalFrom).toBeUndefined()
+ expect(colophon.writtenIn).toBeUndefined()
+ expect(colophon.notesToScribalProcess).toBeUndefined()
+ expect(colophon.individuals).toBeUndefined()
+ })
+
+ it('should properly assign values', () => {
+ const colophon = new Colophon({
+ colophonStatus: ColophonStatus.Yes,
+ colophonOwnership: ColophonOwnership.Library,
+ colophonTypes: [ColophonType.AsbA],
+ originalFrom: { value: 'Babylon', isBroken: false },
+ writtenIn: { value: 'Assyria', isUncertain: true },
+ notesToScribalProcess: 'Detailed notes',
+ individuals: [
+ new IndividualAttestation({ name: { value: 'John Doe' } }),
+ ],
+ })
+
+ expect(colophon.colophonStatus).toEqual(ColophonStatus.Yes)
+ expect(colophon.colophonOwnership).toEqual(ColophonOwnership.Library)
+ expect(colophon.colophonTypes).toEqual([ColophonType.AsbA])
+ expect(colophon.originalFrom?.value).toEqual('Babylon')
+ expect(colophon.writtenIn?.isUncertain).toBeTruthy()
+ expect(colophon.notesToScribalProcess).toEqual('Detailed notes')
+ expect(colophon.individuals?.length).toEqual(1)
+ if (colophon.individuals) {
+ expect(colophon.individuals[0]?.name?.value).toEqual('John Doe')
+ }
+ })
+ })
+
+ describe('fromJson', () => {
+ it('should create an instance from a DTO', () => {
+ const colophonDto = {
+ colophonStatus: ColophonStatus.Yes,
+ colophonOwnership: ColophonOwnership.Private,
+ colophonTypes: [ColophonType.AsbE],
+ originalFrom: { value: 'Babylon', isBroken: false },
+ writtenIn: { value: 'Assur', isUncertain: true },
+ notesToScribalProcess: 'Notes here',
+ individuals: [{ name: { value: 'Jane Doe', isUncertain: true } }],
+ }
+
+ const colophon = Colophon.fromJson(colophonDto)
+
+ expect(colophon.colophonStatus).toEqual(ColophonStatus.Yes)
+ expect(colophon.colophonOwnership).toEqual(ColophonOwnership.Private)
+ expect(colophon.colophonTypes).toEqual([ColophonType.AsbE])
+ expect(colophon.originalFrom?.value).toEqual('Babylon')
+ expect(colophon.writtenIn?.value).toEqual('Assur')
+ expect(colophon.notesToScribalProcess).toEqual('Notes here')
+ expect(colophon.individuals?.length).toEqual(1)
+ if (colophon.individuals) {
+ expect(colophon.individuals[0].name?.value).toEqual('Jane Doe')
+ }
+ })
+ })
+})
+
+describe('IndividualAttestation', () => {
+ it('should correctly initialize properties', () => {
+ const attestation = new IndividualAttestation({
+ name: { value: 'John Doe', isBroken: true },
+ type: { value: IndividualType.Owner },
+ })
+
+ expect(attestation.name?.value).toEqual('John Doe')
+ expect(attestation.name?.isBroken).toBeTruthy()
+ expect(attestation.type?.value).toEqual(IndividualType.Owner)
+ })
+
+ it('should update name field properly', () => {
+ let attestation = new IndividualAttestation({
+ name: { value: 'Initial Name' },
+ })
+ attestation = attestation.setNameField('name', { value: 'Updated Name' })
+ expect(attestation.name?.value).toEqual('Updated Name')
+ })
+
+ it('should update type field properly', () => {
+ let individual = new IndividualAttestation({
+ type: { value: IndividualType.Scribe },
+ })
+ individual = individual.setTypeField({ value: IndividualType.Owner })
+ expect(individual.type?.value).toEqual(IndividualType.Owner)
+ })
+
+ it('should format toString output correctly', () => {
+ const attestation = new IndividualAttestation({
+ type: { value: IndividualType.Scribe },
+ name: { value: 'John Doe' },
+ sonOf: { value: 'John Senior' },
+ })
+ expect(attestation.toString()).toEqual('Scribe: John Doe, s. John Senior')
+ })
+})
diff --git a/src/fragmentarium/domain/Colophon.ts b/src/fragmentarium/domain/Colophon.ts
new file mode 100644
index 000000000..a15a2651e
--- /dev/null
+++ b/src/fragmentarium/domain/Colophon.ts
@@ -0,0 +1,220 @@
+import produce, { Draft, castDraft, immerable } from 'immer'
+
+export enum ColophonStatus {
+ Yes = 'Yes',
+ No = 'No',
+ Broken = 'Broken',
+ OnlyColophon = 'Only Colophon',
+}
+
+export enum ColophonType {
+ AsbA = 'Asb a',
+ AsbB = 'Asb b',
+ AsbC = 'Asb c',
+ AsbD = 'Asb d',
+ AsbE = 'Asb e',
+ AsbF = 'Asb f',
+ AsbG = 'Asb g BAK 321',
+ AsbH = 'Asb h',
+ AsbI = 'Asb i',
+ AsbK = 'Asb k',
+ AsbL = 'Asb l',
+ AsbM = 'Asb m',
+ AsbN = 'Asb n',
+ AsbO = 'Asb o',
+ AsbP = 'Asb p',
+ AsbQ = 'Asb q',
+ AsbRS = 'Asb r/s',
+ AsbT = 'Asb t',
+ AsbU = 'Asb u',
+ AsbV = 'Asb v',
+ AsbW = 'Asb w',
+ AsbUnclear = 'Asb Unclear',
+ NzkBAK293 = 'Nzk BAK 293',
+ NzkBAK294 = 'Nzk BAK 294',
+ NzkBAK295 = 'Nzk BAK 295',
+ NzkBAK296 = 'Nzk BAK 296',
+ NzkBAK297 = 'Nzk BAK 297',
+}
+
+export enum ColophonOwnership {
+ Library = 'Library',
+ Private = 'Private',
+ Individual = 'Individual',
+}
+
+export enum IndividualType {
+ Owner = 'Owner',
+ Scribe = 'Scribe',
+ Other = 'Other',
+}
+
+export interface NameAttestation {
+ readonly value?: string
+ readonly isBroken?: boolean
+ readonly isUncertain?: boolean
+}
+
+export interface ProvenanceAttestation {
+ readonly value?: string
+ readonly isBroken?: boolean
+ readonly isUncertain?: boolean
+}
+
+export interface IndividualTypeAttestation {
+ readonly value?: IndividualType
+ readonly isBroken?: boolean
+ readonly isUncertain?: boolean
+}
+
+export interface IndividualAttestationDto {
+ readonly name?: NameAttestation
+ readonly sonOf?: NameAttestation
+ readonly grandsonOf?: NameAttestation
+ readonly family?: NameAttestation
+ readonly nativeOf?: ProvenanceAttestation
+ readonly type?: IndividualTypeAttestation
+}
+
+export class IndividualAttestation {
+ readonly [immerable] = true
+ readonly name?: NameAttestation
+ readonly sonOf?: NameAttestation
+ readonly grandsonOf?: NameAttestation
+ readonly family?: NameAttestation
+ readonly nativeOf?: ProvenanceAttestation
+ readonly type?: IndividualTypeAttestation
+
+ constructor({
+ name,
+ sonOf,
+ grandsonOf,
+ family,
+ nativeOf,
+ type,
+ }: {
+ readonly name?: NameAttestation
+ readonly sonOf?: NameAttestation
+ readonly grandsonOf?: NameAttestation
+ readonly family?: NameAttestation
+ readonly nativeOf?: ProvenanceAttestation
+ readonly type?: IndividualTypeAttestation
+ }) {
+ this.name = name
+ this.sonOf = sonOf
+ this.grandsonOf = grandsonOf
+ this.family = family
+ this.nativeOf = nativeOf
+ this.type = type
+ }
+
+ setNameField(
+ field: 'name' | 'sonOf' | 'grandsonOf' | 'family',
+ name?: NameAttestation
+ ): IndividualAttestation {
+ return produce(this, (draft: Draft) => {
+ draft[field] = castDraft(name)
+ })
+ }
+
+ setTypeField(type?: IndividualTypeAttestation): IndividualAttestation {
+ return produce(this, (draft: Draft) => {
+ draft.type = castDraft(type)
+ })
+ }
+
+ setNativeOf(provenance?: ProvenanceAttestation): IndividualAttestation {
+ return produce(this, (draft: Draft) => {
+ draft.nativeOf = castDraft(provenance)
+ })
+ }
+
+ toString(): string {
+ return `${this.typeString}${[
+ this.nameString,
+ this.sonOfString,
+ this.grandsonOfString,
+ this.familyString,
+ this.nativeOfString,
+ ]
+ .filter((value) => value !== '')
+ .join(', ')}`
+ }
+
+ private get typeString(): string {
+ return this?.type?.value ? `${this.type.value}: ` : ''
+ }
+ private get nameString(): string {
+ return this?.name?.value ?? ''
+ }
+
+ private get sonOfString(): string {
+ return this?.sonOf?.value ? `s. ${this.sonOf.value}` : ''
+ }
+ private get grandsonOfString(): string {
+ return this?.grandsonOf?.value ? `gs. ${this.grandsonOf.value}` : ''
+ }
+
+ private get familyString(): string {
+ return this?.family?.value ? `f. ${this.family.value}` : ''
+ }
+
+ private get nativeOfString(): string {
+ return this?.nativeOf?.value ? `n. ${this.nativeOf.value}` : ''
+ }
+}
+
+export interface ColophonDto {
+ readonly colophonStatus?: ColophonStatus
+ readonly colophonOwnership?: ColophonOwnership
+ readonly colophonTypes?: ColophonType[]
+ readonly originalFrom?: ProvenanceAttestation
+ readonly writtenIn?: ProvenanceAttestation
+ readonly notesToScribalProcess?: string
+ readonly individuals?: IndividualAttestationDto[]
+}
+
+export class Colophon {
+ readonly colophonStatus?: ColophonStatus
+ readonly colophonOwnership?: ColophonOwnership
+ readonly colophonTypes?: ColophonType[]
+ readonly originalFrom?: ProvenanceAttestation
+ readonly writtenIn?: ProvenanceAttestation
+ readonly notesToScribalProcess?: string
+ readonly individuals?: IndividualAttestation[]
+
+ constructor({
+ colophonStatus,
+ colophonOwnership,
+ colophonTypes,
+ originalFrom,
+ writtenIn,
+ notesToScribalProcess,
+ individuals,
+ }: {
+ readonly colophonStatus?: ColophonStatus
+ readonly colophonOwnership?: ColophonOwnership
+ readonly colophonTypes?: ColophonType[]
+ readonly originalFrom?: ProvenanceAttestation
+ readonly writtenIn?: ProvenanceAttestation
+ readonly notesToScribalProcess?: string
+ readonly individuals?: IndividualAttestation[]
+ }) {
+ this.colophonStatus = colophonStatus
+ this.colophonOwnership = colophonOwnership
+ this.colophonTypes = colophonTypes
+ this.originalFrom = originalFrom
+ this.writtenIn = writtenIn
+ this.notesToScribalProcess = notesToScribalProcess
+ this.individuals = individuals
+ }
+
+ static fromJson(colophonDto: ColophonDto): Colophon {
+ return new Colophon({
+ ...colophonDto,
+ individuals: colophonDto?.individuals?.map(
+ (indiviual) => new IndividualAttestation(indiviual)
+ ),
+ })
+ }
+}
diff --git a/src/fragmentarium/domain/FragmentDtos.ts b/src/fragmentarium/domain/FragmentDtos.ts
index 020c66d60..453a6547b 100644
--- a/src/fragmentarium/domain/FragmentDtos.ts
+++ b/src/fragmentarium/domain/FragmentDtos.ts
@@ -10,6 +10,7 @@ import {
} from 'chronology/domain/DateParameters'
import { ArchaeologyDto } from './archaeologyDtos'
import { MuseumKey } from './museum'
+import { ColophonDto } from 'fragmentarium/domain/Colophon'
interface MeasureDto {
value?: number
@@ -118,4 +119,5 @@ export default interface FragmentDto {
archaeology?: Omit & {
excavationNumber?: MuseumNumber
}
+ colophon?: ColophonDto
}
diff --git a/src/fragmentarium/domain/archaeology.test.ts b/src/fragmentarium/domain/archaeology.test.ts
index 457cd0057..17e8cccbd 100644
--- a/src/fragmentarium/domain/archaeology.test.ts
+++ b/src/fragmentarium/domain/archaeology.test.ts
@@ -3,7 +3,7 @@ import {
archaeologyFactory,
dateRangeFactory,
findspotFactory,
-} from 'test-support/fragment-fixtures'
+} from 'test-support/fragment-data-fixtures'
import {
BuildingType,
Findspot,
diff --git a/src/fragmentarium/domain/fragment.ts b/src/fragmentarium/domain/fragment.ts
index 0fbb8bfd1..10b949435 100644
--- a/src/fragmentarium/domain/fragment.ts
+++ b/src/fragmentarium/domain/fragment.ts
@@ -19,6 +19,7 @@ import { RecordEntry } from './RecordEntry'
import { ResearchProject } from 'research-projects/researchProject'
import { MesopotamianDate } from 'chronology/domain/Date'
import { Archaeology } from './archaeology'
+import { Colophon } from 'fragmentarium/domain/Colophon'
export interface FragmentInfo {
readonly number: string
@@ -76,6 +77,36 @@ export interface ScriptDto {
readonly uncertain: boolean
}
+interface FragmentProps {
+ number: string
+ accession: string
+ publication: string
+ joins: Joins
+ description: string
+ measures: Measures
+ collection: string
+ legacyScript: string
+ folios: ReadonlyArray
+ record: ReadonlyArray
+ text: Text
+ notes: Notes
+ museum: Museum
+ references: ReadonlyArray
+ uncuratedReferences?: ReadonlyArray | null
+ traditionalReferences: readonly string[]
+ atf: string
+ hasPhoto: boolean
+ genres: Genres
+ introduction: Introduction
+ script: Script
+ externalNumbers: ExternalNumbers
+ projects: ReadonlyArray
+ date?: MesopotamianDate
+ datesInText?: ReadonlyArray
+ archaeology?: Archaeology
+ colophon?: Colophon
+}
+
export class Fragment {
readonly [immerable] = true
@@ -105,91 +136,39 @@ export class Fragment {
readonly projects: ReadonlyArray,
readonly date?: MesopotamianDate,
readonly datesInText?: ReadonlyArray,
- readonly archaeology?: Archaeology
+ readonly archaeology?: Archaeology,
+ readonly colophon?: Colophon
) {}
- static create({
- number,
- accession,
- publication,
- joins,
- description,
- measures,
- collection,
- legacyScript,
- folios,
- record,
- text,
- notes,
- museum,
- references,
- uncuratedReferences,
- traditionalReferences,
- atf,
- hasPhoto,
- genres,
- introduction,
- script,
- externalNumbers,
- projects,
- date,
- datesInText,
- archaeology,
- }: {
- number: string
- accession: string
- publication: string
- joins: Joins
- description: string
- measures: Measures
- collection: string
- legacyScript: string
- folios: ReadonlyArray
- record: ReadonlyArray
- text: Text
- notes: Notes
- museum: Museum
- references: ReadonlyArray
- uncuratedReferences?: ReadonlyArray | null
- traditionalReferences: readonly string[]
- atf: string
- hasPhoto: boolean
- genres: Genres
- introduction: Introduction
- script: Script
- externalNumbers: ExternalNumbers
- projects: ReadonlyArray
- date?: MesopotamianDate
- datesInText?: ReadonlyArray
- archaeology?: Archaeology
- }): Fragment {
+ static create(props: FragmentProps): Fragment {
return new Fragment(
- number,
- accession,
- publication,
- joins,
- description,
- measures,
- collection,
- legacyScript,
- folios,
- record,
- text,
- notes,
- museum,
- references,
- uncuratedReferences ?? null,
- traditionalReferences,
- atf,
- hasPhoto,
- genres,
- introduction,
- script,
- externalNumbers,
- projects,
- date,
- datesInText,
- archaeology
+ props.number,
+ props.accession,
+ props.publication,
+ props.joins,
+ props.description,
+ props.measures,
+ props.collection,
+ props.legacyScript,
+ props.folios,
+ props.record,
+ props.text,
+ props.notes,
+ props.museum,
+ props.references,
+ props?.uncuratedReferences ?? null,
+ props.traditionalReferences,
+ props.atf,
+ props.hasPhoto,
+ props.genres,
+ props.introduction,
+ props.script,
+ props.externalNumbers,
+ props.projects,
+ props.date,
+ props.datesInText,
+ props.archaeology,
+ props.colophon
)
}
diff --git a/src/fragmentarium/infrastructure/FindspotRepository.test.ts b/src/fragmentarium/infrastructure/FindspotRepository.test.ts
index 374905926..edd524cd3 100644
--- a/src/fragmentarium/infrastructure/FindspotRepository.test.ts
+++ b/src/fragmentarium/infrastructure/FindspotRepository.test.ts
@@ -1,4 +1,4 @@
-import { findspotFactory } from 'test-support/fragment-fixtures'
+import { findspotFactory } from 'test-support/fragment-data-fixtures'
import { ApiFindspotRepository } from './FindspotRepository'
import { testDelegation, TestData } from 'test-support/utils'
import { toFindspotDto } from 'fragmentarium/domain/archaeologyDtos'
diff --git a/src/fragmentarium/infrastructure/FragmentRepository.test.ts b/src/fragmentarium/infrastructure/FragmentRepository.test.ts
index 8619d3aa9..482f8e1d0 100644
--- a/src/fragmentarium/infrastructure/FragmentRepository.test.ts
+++ b/src/fragmentarium/infrastructure/FragmentRepository.test.ts
@@ -12,7 +12,7 @@ import { queryItemFactory } from 'test-support/query-item-factory'
import { museumNumberToString } from 'fragmentarium/domain/MuseumNumber'
import { Genre, Genres } from 'fragmentarium/domain/Genres'
import { mesopotamianDateFactory } from 'test-support/date-fixtures'
-import { archaeologyFactory } from 'test-support/fragment-fixtures'
+import { archaeologyFactory } from 'test-support/fragment-data-fixtures'
import { FragmentInfo, FragmentInfoDto } from 'fragmentarium/domain/fragment'
const apiClient = {
diff --git a/src/fragmentarium/infrastructure/FragmentRepository.ts b/src/fragmentarium/infrastructure/FragmentRepository.ts
index 28b3069b1..93efd2bb2 100644
--- a/src/fragmentarium/infrastructure/FragmentRepository.ts
+++ b/src/fragmentarium/infrastructure/FragmentRepository.ts
@@ -52,6 +52,7 @@ import { MesopotamianDate } from 'chronology/domain/Date'
import { ArchaeologyDto } from 'fragmentarium/domain/archaeologyDtos'
import { createArchaeology } from 'fragmentarium/domain/archaeologyDtos'
import { JsonApiClient } from 'index'
+import { Colophon } from 'fragmentarium/domain/Colophon'
export function createScript(dto: ScriptDto): Script {
return {
@@ -110,6 +111,7 @@ function createFragment(dto: FragmentDto): Fragment {
archaeology: dto.archaeology
? createArchaeology(dto.archaeology)
: undefined,
+ colophon: dto.colophon ? Colophon.fromJson(dto.colophon) : undefined,
})
}
@@ -197,10 +199,18 @@ class ApiFragmentRepository
fetchGenres(): Promise {
return this.apiClient.fetchJson('/genres', false)
}
+
fetchProvenances(): Promise {
return this.apiClient.fetchJson('/provenances', false)
}
+ fetchColophonNames(query: string): Promise {
+ return this.apiClient.fetchJson(
+ `/fragments/colophon-names?${stringify({ query })}`,
+ false
+ )
+ }
+
fetchPeriods(): Promise {
return this.apiClient.fetchJson('/periods', false)
}
@@ -297,6 +307,13 @@ class ApiFragmentRepository
.then(createFragment)
}
+ updateColophon(number: string, colophon: Colophon): Promise {
+ const path = createFragmentPath(number, 'colophon')
+ return this.apiClient
+ .postJson(path, { colophon: colophon })
+ .then(createFragment)
+ }
+
folioPager(folio: Folio, number: string): Promise {
return this.apiClient.fetchJson(
`/fragments/${encodeURIComponent(number)}/pager/${encodeURIComponent(
diff --git a/src/fragmentarium/infrastructure/ImageRepository.test.ts b/src/fragmentarium/infrastructure/ImageRepository.test.ts
index 28e63a946..5fd10eb7d 100644
--- a/src/fragmentarium/infrastructure/ImageRepository.test.ts
+++ b/src/fragmentarium/infrastructure/ImageRepository.test.ts
@@ -1,7 +1,7 @@
import Promise from 'bluebird'
import ApiImageRepository from './ImageRepository'
import Folio from 'fragmentarium/domain/Folio'
-import { folioFactory } from 'test-support/fragment-fixtures'
+import { folioFactory } from 'test-support/fragment-data-fixtures'
import { ThumbnailSize } from 'fragmentarium/application/FragmentService'
import { ApiError } from 'http/ApiClient'
diff --git a/src/fragmentarium/ui/ProvenanceSearchForm.tsx b/src/fragmentarium/ui/ProvenanceSearchForm.tsx
index 80ab2b3ad..df9494957 100644
--- a/src/fragmentarium/ui/ProvenanceSearchForm.tsx
+++ b/src/fragmentarium/ui/ProvenanceSearchForm.tsx
@@ -8,11 +8,12 @@ export default withData<
{
onChange: (value: string | null) => void
value?: string | null
+ placeholder?: string
},
{ fragmentService: FragmentService },
ReadonlyArray>
>(
- ({ data, value, onChange }) => {
+ ({ data, value, placeholder, onChange }) => {
const options = data.map((site) => ({
value: site.join(' '),
label: site.join(' '),
@@ -22,7 +23,7 @@ export default withData<
return (