Skip to content

Commit

Permalink
#3024: Make all-day logic more obvious in report form
Browse files Browse the repository at this point in the history
Add allDay and fullWidth props to DatePicker in order to provide needed
functionality for all-day events.
  • Loading branch information
ysf-simsoft committed Jun 17, 2020
1 parent 4cf1c39 commit cfa3e26
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 41 deletions.
24 changes: 16 additions & 8 deletions client/src/components/CustomDateInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,21 @@ const CustomDateInput = ({
withTime,
value,
onChange,
onBlur
onBlur,
fullWidth,
allDay
}) => {
const inputRef = useRef()
const rightElement = showIcon && CalendarIcon(inputRef.current)
const width = 8 + (showIcon ? 3 : 0) + (withTime ? 3 : 0)
const style = { width: `${width}em`, fontSize: "1.1em" }
const dateFormats = withTime
? Settings.dateFormats.forms.input.withTime
: Settings.dateFormats.forms.input.date
const style = { width: fullWidth ? "100%" : `${width}em`, fontSize: "1.1em" }
const dateFormats =
withTime && !allDay
? Settings.dateFormats.forms.input.withTime
: Settings.dateFormats.forms.input.date
const inputFormat = dateFormats[0]
const timePickerProps = !withTime
? {}
? undefined
: {
precision: TimePrecision.MINUTE,
selectAllOnFocus: true
Expand Down Expand Up @@ -70,6 +73,7 @@ const CustomDateInput = ({
timePickerProps={timePickerProps}
popoverProps={{ usePortal: false }}
disabled={disabled}
fill={fullWidth}
/>
)
}
Expand All @@ -84,12 +88,16 @@ CustomDateInput.propTypes = {
PropTypes.instanceOf(Date)
]),
onChange: PropTypes.func,
onBlur: PropTypes.func
onBlur: PropTypes.func,
fullWidth: PropTypes.bool,
allDay: PropTypes.bool
}
CustomDateInput.defaultProps = {
disabled: false,
showIcon: true,
withTime: false
withTime: false,
fullWidth: false,
allDay: true
}

export default CustomDateInput
2 changes: 1 addition & 1 deletion client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fieldset.danger {
}

#duration {
width: 10em;
width: 100%;
}

.shortcut-list {
Expand Down
149 changes: 118 additions & 31 deletions client/src/pages/reports/EngagementDateFormPartial.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Checkbox } from "@blueprintjs/core"
import CustomDateInput from "components/CustomDateInput"
import * as FieldHelper from "components/FieldHelper"
import { FastField } from "formik"
import { FastField, Field } from "formik"
import { Report } from "models"
import moment from "moment"
import PropTypes from "prop-types"
import React from "react"
import { HelpBlock } from "react-bootstrap"
import React, { useEffect, useState } from "react"
import { Col, ControlLabel, FormGroup, HelpBlock } from "react-bootstrap"
import Settings from "settings"

const futureEngagementHint = (
Expand All @@ -13,6 +15,109 @@ const futureEngagementHint = (
</HelpBlock>
)

function isStartOfDay(date) {
return date && moment(date).isSame(moment(date).startOf("day"))
}

const EngagementDatePartialFormWithDuration = ({
setFieldValue,
setFieldTouched,
validateFieldDebounced,
initialValues,
edit,
values
}) => {
const [isAllDay, setIsAllDay] = useState(true)
useEffect(() => {
if (!edit || !initialValues.engagementDate) {
setIsAllDay(true)
} else if (!isStartOfDay(initialValues.engagementDate)) {
setIsAllDay(false)
} else {
setIsAllDay(initialValues?.duration === null)
}
}, [edit, initialValues, validateFieldDebounced])

return (
<FormGroup>
<Col sm={2} componentClass={ControlLabel}>
Engagement planning
</Col>
<Col lg={2} md={3} style={{ marginLeft: "15px" }}>
<Field
name="engagementDate"
component={FieldHelper.SpecialField}
onChange={value => {
setFieldTouched("engagementDate", true, false) // onBlur doesn't work when selecting a date
setFieldValue("engagementDate", value, true)
if (!value) {
setIsAllDay(true)
} else if (!isStartOfDay(value)) {
setIsAllDay(false)
}
}}
onBlur={() => setFieldTouched("engagementDate")}
widget={
<CustomDateInput
id="engagementDate"
withTime
fullWidth
allDay={isAllDay}
/>
}
vertical
>
{Report.isFuture(values.engagementDate) && futureEngagementHint}
</Field>
</Col>
<Col sm={2} style={{ marginLeft: "15px" }}>
<Field
name="duration"
label="Duration (minutes)"
component={FieldHelper.InputField}
onChange={event => {
setFieldTouched("duration", true, false)
setFieldValue("duration", event.target.value, false)
validateFieldDebounced("duration")
setIsAllDay(false)
}}
vertical
disabled={isAllDay}
/>
</Col>
<Col sm={2} style={{ marginTop: "2.2em" }}>
<Checkbox
checked={isAllDay}
label="All Day"
onChange={e => {
setIsAllDay(e.target.checked)
if (e.target.checked) {
setFieldValue("duration", null, true)
validateFieldDebounced("duration")
if (values.engagementDate) {
setFieldValue(
"engagementDate",
moment(values.engagementDate).startOf("day").toDate(),
false
)
}
}
}}
/>
</Col>
</FormGroup>
)
}

EngagementDatePartialFormWithDuration.propTypes = {
setFieldValue: PropTypes.func.isRequired,
setFieldTouched: PropTypes.func.isRequired,
validateFieldDebounced: PropTypes.func.isRequired,
values: PropTypes.object.isRequired,
initialValues: PropTypes.instanceOf(Report).isRequired,
edit: PropTypes.bool.isRequired
}

const EngagementDateFormPartial = ({
setFieldValue,
setFieldTouched,
Expand All @@ -27,10 +132,9 @@ const EngagementDateFormPartial = ({
name="engagementDate"
component={FieldHelper.SpecialField}
onChange={value => {
setFieldTouched("engagementDate", true, false) // onBlur doesn't work when selecting a date
setFieldValue("engagementDate", value, true)
const val = value ? moment(value).startOf("day").toDate() : null
setFieldValue("engagementDate", val, true)
}}
onBlur={() => setFieldTouched("engagementDate")}
widget={<CustomDateInput id="engagementDate" />}
>
{Report.isFuture(values.engagementDate) && futureEngagementHint}
Expand All @@ -39,31 +143,14 @@ const EngagementDateFormPartial = ({
}

return (
<>
<FastField
name="engagementDate"
component={FieldHelper.SpecialField}
onChange={value => {
setFieldTouched("engagementDate", true, false) // onBlur doesn't work when selecting a date
setFieldValue("engagementDate", value, true)
}}
onBlur={() => setFieldTouched("engagementDate")}
widget={<CustomDateInput id="engagementDate" withTime />}
>
{Report.isFuture(values.engagementDate) && futureEngagementHint}
</FastField>

<FastField
name="duration"
label="Duration (minutes)"
component={FieldHelper.InputField}
onChange={event => {
setFieldTouched("duration", true, false)
setFieldValue("duration", event.target.value, false)
validateFieldDebounced("duration")
}}
/>
</>
<EngagementDatePartialFormWithDuration
setFieldValue={setFieldValue}
setFieldTouched={setFieldTouched}
validateFieldDebounced={validateFieldDebounced}
values={values}
initialValues={initialValues}
edit={edit}
/>
)
}

Expand Down
2 changes: 1 addition & 1 deletion client/tests/e2e/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ test.serial(
)

await $input.sendKeys("user input")
await $input.sendKeys(t.context.Key.TAB) // fire blur event
await $searchBarInput.click() // fire blur event
t.false(
_includes(await $fieldGroup.getAttribute("class"), warningClass),
`After typing in ${fieldName} field, warning state goes away`
Expand Down

0 comments on commit cfa3e26

Please sign in to comment.