From 1eb95d5dfea4f279200267dce84637491d81ab6f Mon Sep 17 00:00:00 2001 From: Ilya Khait Date: Fri, 9 Feb 2024 14:35:06 +0000 Subject: [PATCH] Update & improve --- .../application/DateSelectionState.ts | 3 +- src/chronology/domain/Date.test.ts | 2 +- src/chronology/domain/DateBase.ts | 47 +++---- src/chronology/ui/DateDisplay.tsx | 128 +++++++++--------- .../ui/DateEditor/DateSelectionInput.tsx | 20 +-- .../DateEditor/DatesInTextSelection.test.tsx | 10 +- src/chronology/ui/DateEditor/Eponyms.tsx | 3 +- src/chronology/ui/Kings/Kings.tsx | 10 +- 8 files changed, 116 insertions(+), 107 deletions(-) diff --git a/src/chronology/application/DateSelectionState.ts b/src/chronology/application/DateSelectionState.ts index 22d00a17f..4c187a3f8 100644 --- a/src/chronology/application/DateSelectionState.ts +++ b/src/chronology/application/DateSelectionState.ts @@ -2,7 +2,6 @@ import { MesopotamianDate } from 'chronology/domain/Date' import { EponymDateField, Ur3Calendar } from 'chronology/domain/DateBase' import { KingDateField } from 'chronology/domain/DateBase' import usePromiseEffect from 'common/usePromiseEffect' -import { Eponym } from 'chronology/ui/DateEditor/Eponyms' import { useState } from 'react' import Bluebird from 'bluebird' import { Fragment } from 'fragmentarium/domain/fragment' @@ -74,7 +73,7 @@ interface KingAndEponymDateParams extends KingAndEponymBrokenUncertainParams { king?: KingDateField eponym?: EponymDateField setKing: React.Dispatch> - setEponym: React.Dispatch> + setEponym: React.Dispatch> } interface AdditionalDateStateParams diff --git a/src/chronology/domain/Date.test.ts b/src/chronology/domain/Date.test.ts index e9c73016e..9339b703b 100644 --- a/src/chronology/domain/Date.test.ts +++ b/src/chronology/domain/Date.test.ts @@ -242,7 +242,7 @@ describe('MesopotamianDate', () => { ) expect(date.toString()).toBe( - '1.I.1 Adad-nērārī (II) (NA eponym) (ca. 910 BCE)' + '1.I.1 Adad-nērārī (II) (NA eponym) (ca. 910 BCE PJC)' ) }) diff --git a/src/chronology/domain/DateBase.ts b/src/chronology/domain/DateBase.ts index 320e2c579..2deeca076 100644 --- a/src/chronology/domain/DateBase.ts +++ b/src/chronology/domain/DateBase.ts @@ -47,6 +47,9 @@ export enum Ur3Calendar { UR = 'Ur', } +const calendarToAbbreviation = (calendar: 'Julian' | 'Gregorian'): string => + ({ Julian: 'PJC', Gregorian: 'PGC' }[calendar]) + export class MesopotamianDateBase { year: DateField month: MonthField @@ -98,27 +101,22 @@ export class MesopotamianDateBase { toModernDate(calendar: 'Julian' | 'Gregorian' = 'Julian'): string { const { year, month, day, isApproximate } = this.getDateApproximation() + const dateProps = { + year, + month, + day, + isApproximate, + calendar, + } let julianDate = '' if (this.isSeleucidEraApplicable(year)) { - julianDate = this.seleucidToModernDate({ - year, - month, - day, - isApproximate, - calendar, - }) + julianDate = this.seleucidToModernDate(dateProps) } else if (this.isNabonassarEraApplicable()) { - julianDate = this.getNabonassarEraDate({ - year, - month, - day, - isApproximate, - calendar, - }) + julianDate = this.getNabonassarEraDate(dateProps) } else if (this.isAssyrianDateApplicable()) { - julianDate = this.getAssyrianDate() + julianDate = this.getAssyrianDate({ calendar: 'Julian' }) } else if (this.isKingDateApplicable()) { - julianDate = this.getKingDate(year) + julianDate = this.kingToModernDate({ year, calendar: 'Julian' }) } return julianDate } @@ -139,12 +137,10 @@ export class MesopotamianDateBase { }) } - private getAssyrianDate(): string { - return `ca. ${this.eponym?.date} BCE` - } - - private getKingDate(year: number): string { - return this.kingToModernDate({ year, calendar: 'Julian' }) + private getAssyrianDate({ + calendar = 'Julian', + }: Pick): string { + return `ca. ${this.eponym?.date} BCE ${calendarToAbbreviation(calendar)}` } private getDateApproximation(): { @@ -234,12 +230,13 @@ export class MesopotamianDateBase { year, calendar = 'Julian', }: Pick): string { - const calendarAbbreviation = { Julian: 'PJC', Gregorian: 'PGC' }[calendar] const firstReignYear = this.king?.date?.split('-')[0] return firstReignYear !== undefined && year > 0 - ? `ca. ${parseInt(firstReignYear) - year + 1} BCE ${calendarAbbreviation}` + ? `ca. ${ + parseInt(firstReignYear) - year + 1 + } BCE ${calendarToAbbreviation(calendar)}` : this.king?.date && !['', '?'].includes(this.king?.date) - ? `ca. ${this.king?.date} BCE ${calendarAbbreviation}` + ? `ca. ${this.king?.date} BCE ${calendarToAbbreviation(calendar)}` : '' } diff --git a/src/chronology/ui/DateDisplay.tsx b/src/chronology/ui/DateDisplay.tsx index 5a4d7e83c..e8a6d71e4 100644 --- a/src/chronology/ui/DateDisplay.tsx +++ b/src/chronology/ui/DateDisplay.tsx @@ -1,81 +1,85 @@ -import React, { useState } from 'react' +import React, { useState, ReactElement, Fragment } from 'react' import { MesopotamianDate } from 'chronology/domain/Date' import OverlayTrigger from 'react-bootstrap/OverlayTrigger' import Tooltip from 'react-bootstrap/Tooltip' -type Props = { +interface Props { date: MesopotamianDate } -const DateDisplay: React.FC = ({ date }) => { - const [calendarType, setCalendarType] = useState('PJC') - const toggleCalendar = () => { - setCalendarType(calendarType === 'PJC' ? 'PGC' : 'PJC') - } - - const parsedDate = date.toString() - let seDate = parsedDate - let pjcDate = '' - let pgcDate = '' - let isDateSwitchable = true +const formatDateString = (dateString: string): ReactElement[] => { + return dateString.split('?').map((part, index, array) => ( + + {part} + {index < array.length - 1 && ?} + + )) +} - const match = parsedDate.match(/(.*) \((.*) BCE PJC \| (.*) BCE PGC\)/) - if (match) { - seDate = match[1] - pjcDate = match[2] + ' BCE' - pgcDate = match[3] + ' BCE' - } else { - isDateSwitchable = false - } +const getSwitchableDate = ({ + modernCalendar, + pjcDate, + pgcDate, + tooltipMessage, + toggleCalendar, +}: { + modernCalendar: 'PJC' | 'PGC' + pjcDate: string + pgcDate: string + tooltipMessage: string + toggleCalendar: () => void +}): ReactElement => ( + <> + {' '} + ({modernCalendar === 'PJC' ? pjcDate : pgcDate}{' '} + {tooltipMessage}} + > + + {modernCalendar} + + + ) + +) - const formatSeDate = (seDateString) => { - return seDateString.split('?').map((part, index, array) => ( - - {part} - {index < array.length - 1 && ?} - - )) +const DateDisplay: React.FC = ({ date }): ReactElement => { + const [modernCalendar, setModernCalendar] = useState<'PJC' | 'PGC'>('PJC') + const toggleCalendar = (): void => { + setModernCalendar((prev) => (prev === 'PJC' ? 'PGC' : 'PJC')) } - + const parsedDate: string = date.toString() + const match = parsedDate.match(/(.*) \((.*) BCE PJC \| (.*) BCE PGC\)/) + const dateString = match ? match[1] : parsedDate + const pjcDate = match ? `${match[2]} BCE` : '' + const pgcDate = match ? `${match[3]} BCE` : '' + const isDateSwitchable = Boolean(match) const tooltipMessage = - calendarType === 'PJC' + modernCalendar === 'PJC' ? 'Switch to Proleptic Gregorian Calendar' : 'Switch to Proleptic Julian Calendar' - const renderTooltip = (props) => ( - - {tooltipMessage} - - ) - - function getSwitchableDate(): JSX.Element { - return ( - <> - {' '} - ({calendarType === 'PJC' ? pjcDate : pgcDate}{' '} - - - {calendarType} - - - ) - - ) - } - return (
- {formatSeDate(seDate)} - {isDateSwitchable && getSwitchableDate()} + {formatDateString(dateString)} + {isDateSwitchable && + getSwitchableDate({ + modernCalendar, + pjcDate, + pgcDate, + tooltipMessage, + toggleCalendar, + })}
) } diff --git a/src/chronology/ui/DateEditor/DateSelectionInput.tsx b/src/chronology/ui/DateEditor/DateSelectionInput.tsx index 3384a0322..7c0cf397a 100644 --- a/src/chronology/ui/DateEditor/DateSelectionInput.tsx +++ b/src/chronology/ui/DateEditor/DateSelectionInput.tsx @@ -2,9 +2,13 @@ import React, { useState } from 'react' import _ from 'lodash' import { InputGroup, Form } from 'react-bootstrap' import Select from 'react-select' -import { KingDateField, Ur3Calendar } from 'chronology/domain/DateBase' -import { King, KingField } from 'chronology/ui/Kings/Kings' -import { Eponym, EponymField } from 'chronology/ui/DateEditor/Eponyms' +import { + EponymDateField, + KingDateField, + Ur3Calendar, +} from 'chronology/domain/DateBase' +import { KingField } from 'chronology/ui/Kings/Kings' +import { EponymField } from 'chronology/ui/DateEditor/Eponyms' import getDateConfigs from 'chronology/application/DateSelectionInputConfig' import { InputGroupProps, @@ -37,22 +41,20 @@ type InputGroupsProps = { } export interface DateOptionsProps { - king?: KingDateField | King + king?: KingDateField kingBroken?: boolean kingUncertain?: boolean - eponym?: Eponym + eponym?: EponymDateField eponymBroken?: boolean eponymUncertain?: boolean ur3Calendar?: Ur3Calendar isSeleucidEra: boolean isAssyrianDate: boolean isCalendarFieldDisplayed: boolean - setKing: React.Dispatch< - React.SetStateAction - > + setKing: React.Dispatch> setKingBroken: React.Dispatch> setKingUncertain: React.Dispatch> - setEponym: React.Dispatch> + setEponym: React.Dispatch> setEponymBroken: React.Dispatch> setEponymUncertain: React.Dispatch> setIsSeleucidEra: React.Dispatch> diff --git a/src/chronology/ui/DateEditor/DatesInTextSelection.test.tsx b/src/chronology/ui/DateEditor/DatesInTextSelection.test.tsx index 1d30c27ec..99a778be9 100644 --- a/src/chronology/ui/DateEditor/DatesInTextSelection.test.tsx +++ b/src/chronology/ui/DateEditor/DatesInTextSelection.test.tsx @@ -77,9 +77,11 @@ describe('DatesInTextSelection', () => { ) - expect(screen.getAllByRole('time')[0]).toHaveTextContent( - datesInText[0].toString() - ) + const firstDateString = datesInText[0].toString().includes(' | ') + ? datesInText[0].toString().split(' | ')[0] + ')' + : datesInText[0].toString() + + expect(screen.getAllByRole('time')[0]).toHaveTextContent(firstDateString) const editButton = screen.getAllByLabelText('Edit date button')[0] await act(async () => { fireEvent.click(editButton) @@ -90,7 +92,7 @@ describe('DatesInTextSelection', () => { }) await waitFor(() => expect(mockUpdateDatesInText).toHaveBeenCalledTimes(1)) expect(screen.getAllByRole('time')[0]).not.toHaveTextContent( - datesInText[0].toString() + firstDateString ) }) diff --git a/src/chronology/ui/DateEditor/Eponyms.tsx b/src/chronology/ui/DateEditor/Eponyms.tsx index 7784aa849..d924f36c0 100644 --- a/src/chronology/ui/DateEditor/Eponyms.tsx +++ b/src/chronology/ui/DateEditor/Eponyms.tsx @@ -5,6 +5,7 @@ import _eponymsMiddleAssyrian from 'chronology/domain/EponymsMiddleAssyrian.json import _eponymsOldAssyrian from 'chronology/domain/EponymsOldAssyrian.json' import Select from 'react-select' import _ from 'lodash' +import { EponymDateField } from 'chronology/domain/DateBase' export interface Eponym { readonly date?: string @@ -40,7 +41,7 @@ export function EponymField({ }: { eponym?: Eponym assyrianPhase: 'NA' | 'MA' | 'OA' - setEponym: React.Dispatch> + setEponym: React.Dispatch> }): JSX.Element { return (