Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EDSC-4125: Recurring temporal slider doesn't work #1841

Merged
merged 23 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5807349
EDSC-4125 GranuleFilter DatePicker improvements
daniel-zamora Nov 21, 2024
cb0ae66
EDSC-4125 prevents InputRange request spam
daniel-zamora Nov 26, 2024
eecde65
EDSC-4125 some fixes to datepicker
daniel-zamora Nov 26, 2024
934be2f
EDSC-4125 some fixes to recurring granule filter
daniel-zamora Nov 26, 2024
a7e2cd3
EDSC-4125 adds test cases for updated date picker logic
daniel-zamora Dec 3, 2024
adf2891
EDSC-4125 some test fixes
daniel-zamora Dec 3, 2024
b09d3cd
EDSC-4125 test fixes
daniel-zamora Dec 3, 2024
99b1c0c
EDSC-4125 cleanup
daniel-zamora Dec 4, 2024
9b5018d
EDSC-4125 fixes collection temporal pickers
daniel-zamora Dec 16, 2024
2790abc
EDSC-4076 slight refactor
daniel-zamora Dec 16, 2024
aa9ca87
EDSC-4076 slight refactor
daniel-zamora Dec 16, 2024
7e4bdb8
EDSC-4125 adds temporal dropdown test for recurring
daniel-zamora Dec 17, 2024
12c3e6b
EDSC-4125 test fixes
daniel-zamora Dec 18, 2024
0e4b652
EDSC-4125 pr comments
daniel-zamora Dec 18, 2024
24fa898
EDSC-4125 adds mockdate to datepicker test
daniel-zamora Jan 8, 2025
c5256df
EDSC-4125 handles unset date cases
daniel-zamora Jan 8, 2025
409974f
EDSC-4125 test fixes
daniel-zamora Jan 8, 2025
a18c063
EDSC-4125 utc time zone test fixes
daniel-zamora Jan 9, 2025
281886f
EDSC-4125 test fix test
daniel-zamora Jan 13, 2025
105ef55
EDSC-4125 changes display value in datepicker, updates tests
daniel-zamora Jan 24, 2025
118854f
EDSC-4125 granule filter fix
daniel-zamora Jan 24, 2025
9101855
EDSC-4125 granule filters form fixes
daniel-zamora Jan 27, 2025
486700a
EDSC-4125 pr comments
daniel-zamora Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
EDSC-4125 test fixes
  • Loading branch information
daniel-zamora committed Jan 24, 2025
commit b09d3cdbfb3f13f6c13fa9f8ae006c1573b359fb
31 changes: 26 additions & 5 deletions static/src/js/components/Datepicker/Datepicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ import Datetime from 'react-datetime'

import './Datepicker.scss'

/**
* Component representing the Datepicker. Used to make some of the customizations
* that should be passed down to the react-datetime component
* @extends PureComponent
* @param {Object} props - The props passed into the component.
* @param {String} props.id - A unique id
* @param {String} props.format - A string temporal format
* @param {Function} props.isValidDate - Callback function to determine if a date is valid
* @param {Function} props.onBlur - Callback function to call when the field is blurred
* @param {Function} props.onChange - Callback function to call when the field is changed
* @param {Function} props.onClearClick - Callback function to call when the clear button is clicked
* @param {Function} props.onTodayClick - Callback function to call when the today button is clicked
* @param {Node} props.picker - A ref for the datepicker
* @param {String} props.size - String representing the bootstrap size
* @param {String} props.value - The value to be used in the input
* @param {String} props.viewMode - The default view mode for the picker
*/
class Datepicker extends PureComponent {
constructor(props) {
super(props)
Expand All @@ -13,11 +30,11 @@ class Datepicker extends PureComponent {
componentDidMount() {
const { onTodayClick, onClearClick } = this.props

// Use containerRef instead of findDOMNode
// Add a custom set of "Today" and "Clear" buttons and insert them into the picker
const container = this.containerRef.current?.querySelector('.rdtPicker')
if (!container) return

// Add custom buttons
// Container to hold custom buttons
const buttonContainer = document.createElement('div')
buttonContainer.classList.add('datetime__buttons')
container.appendChild(buttonContainer)
Expand Down Expand Up @@ -45,9 +62,11 @@ class Datepicker extends PureComponent {
this.setupNavigationHandlers(container)
}

componentDidUpdate() {
const { viewMode: previousViewMode, viewMode, picker } = this.props
if (previousViewMode !== viewMode) {
componentDidUpdate(prevProps) {
const { viewMode, picker } = this.props

// If the viewMode has changed, navigate to the new viewMode
if (prevProps.viewMode !== viewMode) {
picker.current.navigate(viewMode)
}
}
Expand Down Expand Up @@ -176,6 +195,8 @@ class Datepicker extends PureComponent {
viewMode
} = this.props

// React-datetime does not clear out the input field when a empty string is received. When
// the value is an empty string, the value is manually set on the input via `inputProps`.
const conditionalInputProps = !value ? { value: '' } : {}

const onKeyDown = (event) => {
Expand Down
41 changes: 26 additions & 15 deletions static/src/js/components/Datepicker/__tests__/Datepicker.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import React from 'react'
import {
act,
render,
screen
screen,
waitFor
} from '@testing-library/react'

import userEvent from '@testing-library/user-event'
Expand Down Expand Up @@ -112,7 +113,7 @@ describe('Datepicker component', () => {
await user.type(datePickerInput, '1')
})

expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(1)
expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(2)
expect(requestAnimationFrameSpy).toHaveBeenCalledWith(expect.any(Function))

expect(closeCalendarSpy).toHaveBeenCalledTimes(1)
Expand Down Expand Up @@ -285,13 +286,19 @@ describe('Datepicker component', () => {
await user.click(juneCell)

// Get fresh references after entering days view
const [currentPrevNav, currentMonthSwitch, currentNextNav] = screen.getAllByRole('columnheader')
const [currentPrevNav, currentMonthSwitch, currentNextNav] = screen
.getAllByRole('columnheader')
.filter((header) => header.className.includes('rdtPrev')
|| header.className.includes('rdtSwitch')
|| header.className.includes('rdtNext'))

// June state in days view
expect(currentMonthSwitch).toHaveTextContent('June')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).toBeVisible()
expect(currentNextNav).toBeVisible()
await waitFor(() => {
expect(currentMonthSwitch).toHaveTextContent('June')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).toBeVisible()
expect(currentNextNav).toBeVisible()
})

// Navigate to January using prev nav
await user.click(currentPrevNav) // May
Expand All @@ -301,10 +308,12 @@ describe('Datepicker component', () => {
await user.click(currentPrevNav) // January

// January state in days view
expect(currentMonthSwitch).toHaveTextContent('January')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).not.toBeVisible() // Hidden in January
expect(currentNextNav).toBeVisible()
await waitFor(() => {
expect(currentMonthSwitch).toHaveTextContent('January')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).not.toBeVisible() // Hidden in January
expect(currentNextNav).toBeVisible()
})

// Navigate to December using next nav
await user.click(currentNextNav) // February
Expand All @@ -320,10 +329,12 @@ describe('Datepicker component', () => {
await user.click(currentNextNav) // December

// December state in days view
expect(currentMonthSwitch).toHaveTextContent('December')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).toBeVisible()
expect(currentNextNav).not.toBeVisible() // Hidden in December
await waitFor(() => {
expect(currentMonthSwitch).toHaveTextContent('December')
expect(currentMonthSwitch).not.toHaveTextContent('2024')
expect(currentPrevNav).toBeVisible()
expect(currentNextNav).not.toBeVisible() // Hidden in December
})
})
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ export const GranuleFiltersForm = (props) => {
}

setFieldValue('temporal.recurringDayStart', startDate.dayOfYear())
// Use the start year to calculate the end day of year. This avoids leap years potentially causing day mismatches
setFieldValue('temporal.recurringDayEnd', endDate.year(startDate.year()).dayOfYear())
}
}
Expand Down Expand Up @@ -526,7 +527,7 @@ export const GranuleFiltersForm = (props) => {
const endDate = moment(newTemporal.endDate).utc()

if (startDate.year() === endDate.year()) {
// Only set start year to minimum year, keeping month/day from selected date
// Preserve original month/day while setting to minimum year
startDate.year(minDate.year())
setFieldValue('temporal.startDate', startDate.toISOString())
}
Expand Down Expand Up @@ -557,7 +558,7 @@ export const GranuleFiltersForm = (props) => {
const startDate = moment(newTemporal.startDate).utc()

if (startDate.year() === endDate.year()) {
// Only set start year to minimum year, keeping month/day from startDate
// Preserve original month/day while setting to minimum year
startDate.year(minDate.year())
setFieldValue('temporal.startDate', startDate.toISOString())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1607,7 +1607,7 @@ describe('GranuleFiltersForm component', () => {
// Verify start date was NOT adjusted since years are different
expect(setFieldValue).not.toHaveBeenCalledWith(
'temporal.startDate',
expect.stringContaining('1970')
expect.stringContaining('1960')
)
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,9 @@ describe('TemporalSelection component', () => {
expect(props.onSubmitEnd).toBeCalledTimes(1)
})

test('calls setFieldValue on onChange and onChangeRecurring only on onChangeComplete for the year range slider', () => {
test('onChangeRecurring is only called when input is complete on InputRange', () => {
const { enzymeWrapper, props } = setup()

// Set up component with required props for showing the slider
enzymeWrapper.setProps({
temporal: {
startDate: '2019-01-01T00:00:00.000Z',
Expand All @@ -164,10 +163,8 @@ describe('TemporalSelection component', () => {
onChangeRecurring: props.onChangeRecurring
})

// Find the InputRange component
const inputRange = enzymeWrapper.find('InputRange')

// Simulate onChange
inputRange.prop('onChange')({
min: 2018,
max: 2021
Expand All @@ -188,7 +185,6 @@ describe('TemporalSelection component', () => {
// Verify onChangeRecurring was not called during onChange
expect(props.onChangeRecurring).not.toHaveBeenCalled()

// Simulate onChangeComplete
inputRange.prop('onChangeComplete')({
min: 2018,
max: 2021
Expand Down