Skip to content

Commit

Permalink
fix: convert iso dates in calendar input
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Oct 11, 2024
1 parent e51472c commit dc8e9c6
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 40 deletions.
32 changes: 27 additions & 5 deletions src/data-workspace/inputs/date-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { useConfig } from '@dhis2/app-runtime'
import { CalendarInput } from '@dhis2/ui'
import React from 'react'
import { useField } from 'react-final-form'
import { useSetDataValueMutation, useUserInfo } from '../../shared/index.js'
import {
useSetDataValueMutation,
useUserInfo,
convertFromIso8601ToString,
convertToIso8601ToString,
} from '../../shared/index.js'
import styles from './inputs.module.css'
import { InputPropTypes } from './utils.js'

Expand Down Expand Up @@ -42,6 +47,7 @@ export const DateInput = ({
form.mutators.setFieldData(fieldname, {
lastSyncedValue: value,
})
input.onBlur()
},
}
)
Expand All @@ -55,19 +61,35 @@ export const DateInput = ({
}

return (
<div onClick={onFocus}>
<div
onClick={() => {
onFocus()
input.onFocus()
}}
className={styles.dateInputContainer}
>
<CalendarInput
{...input}
className={styles.dateInput}
autoComplete="off"
onKeyDown={onKeyDown}
disabled={disabled}
readOnly={locked}
date={input.value}
date={
input?.value
? convertFromIso8601ToString(input.value, calendar)
: ''
}
calendar={calendar}
onDateSelect={(date) => {
input.onChange(date ? date?.calendarDateString : '')
handleChange(date ? date?.calendarDateString : '')
const selectedDate = date?.calendarDateString
? convertToIso8601ToString(
date?.calendarDateString,
calendar
)
: ''
input.onChange(selectedDate)
handleChange(selectedDate)
}}
locale={keyUiLocale}
clearable
Expand Down
121 changes: 91 additions & 30 deletions src/data-workspace/inputs/date-input.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useConfig } from '@dhis2/app-runtime'
import { ReactFinalForm } from '@dhis2/ui'
import userEvent from '@testing-library/user-event'
import PropTypes from 'prop-types'
import React from 'react'
import { useSetDataValueMutation, useUserInfo } from '../../shared/index.js'
import { render } from '../../test-utils/index.js'
import { FinalFormWrapper } from '../final-form-wrapper.js'
import { DateInput } from './date-input.js'

jest.mock('../../shared/use-user-info/use-user-info.js', () => ({
Expand All @@ -22,12 +23,33 @@ jest.mock('@dhis2/app-runtime', () => {
}
})

const DE = 'rkAZZFGFEQ7'
const COC = 'HllvX50cXC0'

const { Form } = ReactFinalForm

const FormWrapper = ({ initialValues, children }) => (
<Form
onSubmit={() => {}}
initialValues={initialValues}
subscriptions={{}}
keepDirtyOnReinitialize
>
{() => children}
</Form>
)

FormWrapper.propTypes = {
children: PropTypes.node,
initialValues: PropTypes.object,
}

describe('date input field', () => {
const props = {
cocId: 'HllvX50cXC0',
deId: 'rkAZZFGFEQ7',
cocId: COC,
deId: DE,
disabled: undefined,
fieldname: 'rkAZZFGFEQ7.HllvX50cXC0',
fieldname: `${DE}.${COC}`,
form: {},
locked: false,
onFocus: jest.fn(),
Expand Down Expand Up @@ -65,13 +87,9 @@ describe('date input field', () => {
})

const { getByText, getByRole, getByTestId, queryByTestId } = render(
<FinalFormWrapper
onSubmit={() => jest.fn()}
initialValues={{}}
keepDirtyOnReinitialize
>
<FormWrapper initialValues={{}}>
<DateInput {...props} />
</FinalFormWrapper>
</FormWrapper>
)
const calendarInputLabel = getByText('Pick a date')
const calendarInput = getByRole('textbox')
Expand Down Expand Up @@ -114,13 +132,9 @@ describe('date input field', () => {
})

const { getByText, getByRole, getByTestId, getByLabelText } = render(
<FinalFormWrapper
onSubmit={() => jest.fn()}
initialValues={{}}
keepDirtyOnReinitialize
>
<FormWrapper initialValues={{}}>
<DateInput {...props} />
</FinalFormWrapper>
</FormWrapper>
)

const calendarInput = getByRole('textbox')
Expand Down Expand Up @@ -161,19 +175,30 @@ describe('date input field', () => {
expect(mutate.mock.calls[1][0]).toHaveProperty('value', '2024-07-18')
})

it('populates the persisted date on load', async () => {
useConfig.mockReturnValue({
systemInfo: { calendar: 'gregorian' },
})

const { getByRole } = render(
<FormWrapper initialValues={{ [DE]: { [COC]: '2021-04-22' } }}>
<DateInput {...props} />
</FormWrapper>
)

const calendarInput = getByRole('textbox')
expect(calendarInput.value).toBe('2021-04-22')
})

it('renders system set calendar, i.e. nepali', async () => {
useConfig.mockReturnValue({
systemInfo: { calendar: 'nepali' },
})

const { getByText, getByRole } = render(
<FinalFormWrapper
onSubmit={() => jest.fn()}
initialValues={{}}
keepDirtyOnReinitialize
>
<FormWrapper initialValues={{}}>
<DateInput {...props} />
</FinalFormWrapper>
</FormWrapper>
)

const calendarInput = getByRole('textbox')
Expand All @@ -187,7 +212,27 @@ describe('date input field', () => {
expect(calendarInput.value).toBe('2081-04-10')
// check that mutate function was called
expect(mutate.mock.calls).toHaveLength(1)
expect(mutate.mock.calls[0][0]).toHaveProperty('value', '2081-04-10')
expect(mutate.mock.calls[0][0]).toHaveProperty('value', '2024-07-25')
})

it('populates the nepali equivalent of the persisted ISO date', async () => {
jest.setSystemTime(new Date('2024-07-25T09:05:00.000Z'))

useConfig.mockReturnValue({
systemInfo: { calendar: 'nepali' },
})

// 2021-04-22 ISO = 2078-01-09 nepali
const { getByRole } = render(
<FormWrapper
initialValues={{ [DE]: { [COC]: '2021-04-22T13:17' } }}
>
<DateInput {...props} />
</FormWrapper>
)

const calendarInput = getByRole('textbox')
expect(calendarInput.value).toBe('2078-01-09')
})

it('renders system set calendar, i.e. ethiopian', async () => {
Expand All @@ -196,13 +241,9 @@ describe('date input field', () => {
})

const { getByText, getByRole } = render(
<FinalFormWrapper
onSubmit={() => jest.fn()}
initialValues={{}}
keepDirtyOnReinitialize
>
<FormWrapper initialValues={{}}>
<DateInput {...props} />
</FinalFormWrapper>
</FormWrapper>
)

const calendarInput = getByRole('textbox')
Expand All @@ -216,6 +257,26 @@ describe('date input field', () => {
expect(calendarInput.value).toBe('2016-11-18')
// check that mutate function was called
expect(mutate.mock.calls).toHaveLength(1)
expect(mutate.mock.calls[0][0]).toHaveProperty('value', '2016-11-18')
expect(mutate.mock.calls[0][0]).toHaveProperty('value', '2024-07-25')
})

it('populates the ethiopian equivalent of the persisted ISO date', async () => {
jest.setSystemTime(new Date('2024-07-25T09:05:00.000Z'))

useConfig.mockReturnValue({
systemInfo: { calendar: 'ethiopian' },
})

// 2021-04-22 ISO = 2013-08-14 ethiopian
const { getByRole } = render(
<FormWrapper
initialValues={{ [DE]: { [COC]: '2021-04-22T13:17' } }}
>
<DateInput {...props} />
</FormWrapper>
)

const calendarInput = getByRole('textbox')
expect(calendarInput.value).toBe('2013-08-14')
})
})
4 changes: 2 additions & 2 deletions src/data-workspace/inputs/datetime-input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ FormWrapper.propTypes = {

describe('date input field', () => {
const props = {
cocId: DE,
deId: COC,
cocId: COC,
deId: DE,
disabled: undefined,
fieldname: `${DE}.${COC}`,
form: {},
Expand Down
6 changes: 3 additions & 3 deletions src/data-workspace/inputs/inputs.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@
border: none;
}

.dateTimeInput {
margin-inline: var(--spacers-dp4);
.dateInputContainer {
padding: var(--spacers-dp8);
}

.dateTimeInput {
padding-block: var(--spacers-dp4);
padding: var(--spacers-dp4);
}

.timeLabel {
Expand Down

0 comments on commit dc8e9c6

Please sign in to comment.