Skip to content

Commit

Permalink
fix: add datetime input
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Oct 10, 2024
1 parent 3a3274b commit def0b43
Show file tree
Hide file tree
Showing 6 changed files with 480 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/data-workspace/data-entry-cell/entry-field-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
OptionSet,
TrueOnlyCheckbox,
DateInput,
DateTimeInput,
} from '../inputs/index.js'

function InputComponent({ sharedProps, de }) {
Expand Down Expand Up @@ -50,6 +51,9 @@ function InputComponent({ sharedProps, de }) {
case VALUE_TYPES.DATE: {
return <DateInput {...sharedProps} />
}
case VALUE_TYPES.DATETIME: {
return <DateTimeInput {...sharedProps} />
}
default: {
return <GenericInput {...sharedProps} valueType={de.valueType} />
}
Expand Down
1 change: 1 addition & 0 deletions src/data-workspace/final-form-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function FinalFormWrapper({ children, dataValueSet }) {
// TODO: Reinitialize form `onSuccess` of dataValueSets query
// See https://dhis2.atlassian.net/browse/TECH-1357
const [initialValues] = useState(() => createInitialValues(dataValueSet))

return (
<Form
onSubmit={onSubmit}
Expand Down
129 changes: 129 additions & 0 deletions src/data-workspace/inputs/datetime-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import { Button, CalendarInput } from '@dhis2/ui'
import React, { useState } from 'react'
import { useField } from 'react-final-form'
import { useSetDataValueMutation, useUserInfo } from '../../shared/index.js'
import styles from './inputs.module.css'
import { InputPropTypes } from './utils.js'

export const DateTimeInput = ({
cocId,
deId,
disabled,
fieldname,
form,
locked,
onFocus,
onKeyDown,
}) => {
const { data: userInfo } = useUserInfo()
const keyUiLocale = userInfo?.settings?.keyUiLocale

const { systemInfo = {} } = useConfig()
const { calendar = 'gregory' } = systemInfo

const { input, meta } = useField(fieldname, {
subscription: {
value: true,
dirty: true,
valid: true,
data: true,
},
})

const [date, setDate] = useState(input?.value?.substring(0, 10) ?? '')
const [time, setTime] = useState(input?.value?.substring(11, 23) ?? '')

const { mutate } = useSetDataValueMutation({ deId, cocId })

const syncData = (value) => {
mutate(
// Empty values need an empty string
{ value: value || '' },
{
onSuccess: () => {
form.mutators.setFieldData(fieldname, {
lastSyncedValue: value,
})
input.onBlur()
},
}
)
}

const handleChange = ({ date, time }) => {
const dateWithTime = `${date}${time === '' ? '' : 'T' + time}`
input.onChange(dateWithTime)

if (date === '' || time === '') {
return
}

// If this value has changed, sync it to server if valid
if (meta.valid && dateWithTime !== meta.data.lastSyncedValue) {
syncData(dateWithTime)
}
}

const clearValue = () => {
setDate('')
setTime('')
input.onChange('')

// If this value has changed, sync it to server if valid
if (meta.valid && '' !== meta.data.lastSyncedValue) {
syncData('')
}
}

return (
<div
className={styles.dateTimeInput}
onClick={() => {
onFocus()
input.onFocus()
}}
>
<div>
<CalendarInput
{...input}
label={i18n.t('Pick a date and time')}
className={styles.dateInput}
autoComplete="off"
onKeyDown={onKeyDown}
disabled={disabled}
readOnly={locked}
date={date}
calendar={calendar}
onDateSelect={(date) => {
const selectedDate = date?.calendarDateString ?? ''
setDate(selectedDate)
handleChange({ date: selectedDate, time })
}}
locale={keyUiLocale}
/>
</div>
<div>
<input
readOnly={locked}
type="time"
value={time}
onChange={(e) => {
const selectedTime = e?.target?.value ?? ''
setTime(selectedTime)
handleChange({ date, time: selectedTime })
}}
data-test="time-input"
/>
</div>
<div>
<Button small onClick={clearValue}>
{i18n.t('Clear')}
</Button>
</div>
</div>
)
}

DateTimeInput.propTypes = InputPropTypes
Loading

0 comments on commit def0b43

Please sign in to comment.