Skip to content

Commit

Permalink
Update & improve
Browse files Browse the repository at this point in the history
  • Loading branch information
khoidt committed Feb 9, 2024
1 parent c1559bf commit 1eb95d5
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 107 deletions.
3 changes: 1 addition & 2 deletions src/chronology/application/DateSelectionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -74,7 +73,7 @@ interface KingAndEponymDateParams extends KingAndEponymBrokenUncertainParams {
king?: KingDateField
eponym?: EponymDateField
setKing: React.Dispatch<React.SetStateAction<KingDateField | undefined>>
setEponym: React.Dispatch<React.SetStateAction<Eponym | undefined>>
setEponym: React.Dispatch<React.SetStateAction<EponymDateField | undefined>>
}

interface AdditionalDateStateParams
Expand Down
2 changes: 1 addition & 1 deletion src/chronology/domain/Date.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)'
)
})

Expand Down
47 changes: 22 additions & 25 deletions src/chronology/domain/DateBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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<DateProps, 'calendar'>): string {
return `ca. ${this.eponym?.date} BCE ${calendarToAbbreviation(calendar)}`
}

private getDateApproximation(): {
Expand Down Expand Up @@ -234,12 +230,13 @@ export class MesopotamianDateBase {
year,
calendar = 'Julian',
}: Pick<DateProps, 'year' | 'calendar'>): 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)}`
: ''
}

Expand Down
128 changes: 66 additions & 62 deletions src/chronology/ui/DateDisplay.tsx
Original file line number Diff line number Diff line change
@@ -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<Props> = ({ 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) => (
<Fragment key={index}>
{part}
{index < array.length - 1 && <sup>?</sup>}
</Fragment>
))
}

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}{' '}
<OverlayTrigger
placement="bottom"
overlay={<Tooltip id="button-tooltip">{tooltipMessage}</Tooltip>}
>
<span
onClick={toggleCalendar}
role="button"
tabIndex={0}
style={{
textDecoration: 'underline',
textDecorationStyle: 'dotted',
cursor: 'pointer',
}}
>
{modernCalendar}
</span>
</OverlayTrigger>
)
</>
)

const formatSeDate = (seDateString) => {
return seDateString.split('?').map((part, index, array) => (
<React.Fragment key={index}>
{part}
{index < array.length - 1 && <sup>?</sup>}
</React.Fragment>
))
const DateDisplay: React.FC<Props> = ({ 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) => (
<Tooltip id="button-tooltip" {...props}>
{tooltipMessage}
</Tooltip>
)

function getSwitchableDate(): JSX.Element {
return (
<>
{' '}
({calendarType === 'PJC' ? pjcDate : pgcDate}{' '}
<OverlayTrigger placement="top" overlay={renderTooltip}>
<span
onClick={toggleCalendar}
role="button"
tabIndex={0}
style={{
textDecoration: 'underline',
textDecorationStyle: 'dotted',
cursor: 'pointer',
}}
>
{calendarType}
</span>
</OverlayTrigger>
)
</>
)
}

return (
<div className="mesopotamian-date-display" role="time">
{formatSeDate(seDate)}
{isDateSwitchable && getSwitchableDate()}
{formatDateString(dateString)}
{isDateSwitchable &&
getSwitchableDate({
modernCalendar,
pjcDate,
pgcDate,
tooltipMessage,
toggleCalendar,
})}
</div>
)
}
Expand Down
20 changes: 11 additions & 9 deletions src/chronology/ui/DateEditor/DateSelectionInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<KingDateField | King | undefined>
>
setKing: React.Dispatch<React.SetStateAction<KingDateField | undefined>>
setKingBroken: React.Dispatch<React.SetStateAction<boolean>>
setKingUncertain: React.Dispatch<React.SetStateAction<boolean>>
setEponym: React.Dispatch<React.SetStateAction<Eponym | undefined>>
setEponym: React.Dispatch<React.SetStateAction<EponymDateField | undefined>>
setEponymBroken: React.Dispatch<React.SetStateAction<boolean>>
setEponymUncertain: React.Dispatch<React.SetStateAction<boolean>>
setIsSeleucidEra: React.Dispatch<React.SetStateAction<boolean>>
Expand Down
10 changes: 6 additions & 4 deletions src/chronology/ui/DateEditor/DatesInTextSelection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ describe('DatesInTextSelection', () => {
</SessionContext.Provider>
)

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)
Expand All @@ -90,7 +92,7 @@ describe('DatesInTextSelection', () => {
})
await waitFor(() => expect(mockUpdateDatesInText).toHaveBeenCalledTimes(1))
expect(screen.getAllByRole('time')[0]).not.toHaveTextContent(
datesInText[0].toString()
firstDateString
)
})

Expand Down
3 changes: 2 additions & 1 deletion src/chronology/ui/DateEditor/Eponyms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -40,7 +41,7 @@ export function EponymField({
}: {
eponym?: Eponym
assyrianPhase: 'NA' | 'MA' | 'OA'
setEponym: React.Dispatch<React.SetStateAction<Eponym | undefined>>
setEponym: React.Dispatch<React.SetStateAction<EponymDateField | undefined>>
}): JSX.Element {
return (
<Select
Expand Down
10 changes: 7 additions & 3 deletions src/chronology/ui/Kings/Kings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function KingField({
setIsCalenderFieldDisplayed,
}: {
king?: King | KingDateField
setKing: React.Dispatch<React.SetStateAction<King | undefined>>
setKing: React.Dispatch<React.SetStateAction<KingDateField | undefined>>
setIsCalenderFieldDisplayed?: React.Dispatch<React.SetStateAction<boolean>>
}): JSX.Element {
return (
Expand All @@ -65,7 +65,7 @@ export function KingField({

const onKingFieldChange = (
option: ValueType<{ label: string; value: King }, false>,
setKing: React.Dispatch<React.SetStateAction<King | undefined>>,
setKing: React.Dispatch<React.SetStateAction<KingDateField | undefined>>,
setIsCalenderFieldDisplayed?: React.Dispatch<React.SetStateAction<boolean>>
): void => {
setKing(option?.value)
Expand Down Expand Up @@ -95,7 +95,11 @@ function getKingOptions(): Array<{ label: string; value: King }> {
}

function getCurrentKingOption(
king?: King
king?: King | KingDateField
): { label: string; value: King } | undefined {
if (king && ('isBroken' in king || 'isUncertain' in king)) {
const { isBroken, isUncertain, ..._king } = king
king = _king
}
return kingOptions.find((kingOption) => _.isEqual(kingOption.value, king))
}

0 comments on commit 1eb95d5

Please sign in to comment.