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

TAN-2973 Replace old date range picker #9907

Merged
merged 42 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5a61246
Comment out unnecessary props old date range picker
luucvanderzee Oct 4, 2024
90ad995
Move DateRange type to shared folder
luucvanderzee Oct 4, 2024
e379735
Scaffold some stuff (WIP)
luucvanderzee Oct 4, 2024
c64933f
Create shared ClickOutsideContainer
luucvanderzee Oct 4, 2024
a982bd3
Create input and story
luucvanderzee Oct 4, 2024
f054271
Add Calendar (WIP)
luucvanderzee Oct 4, 2024
d490a26
Fix font size issue in Calendar
luucvanderzee Oct 4, 2024
c598f47
Fix bug when trying to deselect date range
luucvanderzee Oct 4, 2024
d826eef
Add start and end month
luucvanderzee Oct 4, 2024
1fc8c5c
Add default month
luucvanderzee Oct 4, 2024
9a9d445
Replace old DateRangePicker in most places
luucvanderzee Oct 4, 2024
09ef6e1
_
luucvanderzee Oct 4, 2024
f7cf8c9
Merge branch 'master' into replace-date-range-picker
luucvanderzee Oct 20, 2024
356ae41
Make behavior date range picker more similar to phase one
luucvanderzee Oct 20, 2024
18887e0
Add disabled prop + story
luucvanderzee Oct 20, 2024
3544186
Replace TimeControl
luucvanderzee Oct 20, 2024
9de3c2a
Merge branch 'master' into replace-date-range-picker
luucvanderzee Dec 24, 2024
f5c8acd
Put back start month
luucvanderzee Dec 24, 2024
d664a43
Fix old usage of getStartMonth
luucvanderzee Dec 24, 2024
335c04e
Fix bug in Calendar
luucvanderzee Dec 24, 2024
a3d6439
Allow selecting start and end of range individually
luucvanderzee Dec 24, 2024
41bf228
Calculate next selection mode
luucvanderzee Dec 24, 2024
5fae54e
Add tests for new behavior
luucvanderzee Dec 24, 2024
0f7cc4c
Tweak spacing
luucvanderzee Dec 24, 2024
81ad8c9
Make it possible to clear dates
luucvanderzee Dec 24, 2024
c59309d
_
luucvanderzee Dec 24, 2024
b8a2a37
_
luucvanderzee Dec 24, 2024
5ba7168
_
luucvanderzee Dec 24, 2024
cc80601
_
luucvanderzee Dec 24, 2024
4490f1c
Translations updated by CI (extract-intl)
Dec 24, 2024
eb78309
_
luucvanderzee Dec 24, 2024
ab449a2
_
luucvanderzee Dec 24, 2024
377577c
_
luucvanderzee Dec 24, 2024
653e5e7
_
luucvanderzee Dec 24, 2024
174de70
Fix report builder date select
luucvanderzee Dec 24, 2024
cb56f7b
Handle date strings with time embedded
luucvanderzee Dec 24, 2024
827fc3e
Only allow one or two months
luucvanderzee Dec 24, 2024
c8c8cbb
Fix test
luucvanderzee Dec 27, 2024
ffddad8
Add changes from other branch
luucvanderzee Jan 3, 2025
b9548fb
Improve contrast issue
luucvanderzee Jan 3, 2025
7d3ba30
Update front/app/utils/dateUtils.ts
luucvanderzee Jan 7, 2025
5dfc427
Update front/app/utils/dateUtils.ts
luucvanderzee Jan 7, 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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import styled from 'styled-components';

import useLocale from 'hooks/useLocale';

import { userTimezone } from 'utils/dateUtils';

import { getLocale } from '../../_shared/locales';
import { Props } from '../typings';

Expand Down Expand Up @@ -144,7 +146,6 @@ const Calendar = ({
defaultMonth,
onUpdateRange,
}: Props) => {
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const startMonth = getStartMonth({
startMonth: _startMonth,
selectedRange,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { differenceInDays, addDays } from 'date-fns';

import { DateRange, ClosedDateRange } from '../../typings';
import { DateRange } from 'components/admin/DatePickers/_shared/typings';

import { ClosedDateRange } from '../../typings';

import { rangesValid } from './rangesValid';
import { allAreClosedDateRanges } from './utils';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { addYears } from 'date-fns';

import { DateRange } from '../../typings';
import { DateRange } from 'components/admin/DatePickers/_shared/typings';

interface GetStartMonthProps {
startMonth?: Date;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { addDays, isSameDay } from 'date-fns';

import { ClosedDateRange, DateRange } from '../../typings';
import { DateRange } from 'components/admin/DatePickers/_shared/typings';

import { ClosedDateRange } from '../../typings';

import { rangesValid } from './rangesValid';
import { isClosedDateRange } from './utils';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { differenceInDays } from 'date-fns';

import { DateRange, ClosedDateRange } from '../../typings';
import { DateRange } from 'components/admin/DatePickers/_shared/typings';

import { ClosedDateRange } from '../../typings';

import { allAreClosedDateRanges, isClosedDateRange } from './utils';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DateRange, ClosedDateRange } from '../../typings';
import { DateRange } from '../../../_shared/typings';
import { ClosedDateRange } from '../../typings';

export const isClosedDateRange = (range: DateRange): range is ClosedDateRange =>
!!range.to;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState } from 'react';

import { DateRange } from '../_shared/typings';

import { patchDisabledRanges } from './patchDisabledRanges';
import { DateRange } from './typings';

import DatePhasePicker from '.';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { useIntl } from 'utils/cl-intl';

import InputContainer from '../_shared/InputContainer';
import sharedMessages from '../_shared/messages';
import { DateRange } from '../_shared/typings';

import messages from './messages';
import { DateRange } from './typings';

interface Props {
selectedRange: Partial<DateRange>;
Expand Down
17 changes: 6 additions & 11 deletions front/app/components/admin/DatePickers/DatePhasePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState } from 'react';

import { Tooltip, Box } from '@citizenlab/cl2-component-library';
import styled from 'styled-components';

import ClickOutside from 'utils/containers/clickOutside';
import ClickOutsideContainer from '../_shared/ClickOutsideContainer';

import Calendar from './Calendar';
import Input from './Input';
Expand All @@ -12,13 +11,6 @@ import { Props } from './typings';

const WIDTH = '620px';

const StyledClickOutside = styled(ClickOutside)`
div.tippy-box {
max-width: ${WIDTH} !important;
padding: 8px;
}
`;

const DatePhasePicker = ({
selectedRange,
disabledRanges = [],
Expand All @@ -35,7 +27,10 @@ const DatePhasePicker = ({
);

return (
<StyledClickOutside onClickOutside={() => setCalendarOpen(false)}>
<ClickOutsideContainer
width={WIDTH}
onClickOutside={() => setCalendarOpen(false)}
>
<Tooltip
content={
<Box width={WIDTH}>
Expand All @@ -59,7 +54,7 @@ const DatePhasePicker = ({
onClick={() => setCalendarOpen((open) => !open)}
/>
</Tooltip>
</StyledClickOutside>
</ClickOutsideContainer>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DateRange } from './typings';
import { DateRange } from '../_shared/typings';

export const isSelectedRangeOpenEnded = (
{ from, to }: Partial<DateRange>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { addDays } from 'date-fns';

import { DateRange } from './typings';
import { DateRange } from '../_shared/typings';

/**
* Utility to handle the case where the last disabled range is open,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
export type DateRange = {
from: Date;
to?: Date;
};
import { DateRange } from '../_shared/typings';

export type ClosedDateRange = {
from: Date;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import React from 'react';

import { Box, colors, Button } from '@citizenlab/cl2-component-library';
import { DayPicker, PropsBase } from 'react-day-picker';
import 'react-day-picker/style.css';
import styled from 'styled-components';

import useLocale from 'hooks/useLocale';

import { useIntl } from 'utils/cl-intl';

import { getEndMonth } from '../../_shared/getStartEndMonth';
import { getLocale } from '../../_shared/locales';
import { CalendarProps } from '../typings';

import messages from './messages';
import { getNextSelectionMode } from './utils/getNextSelectionMode';
import { getUpdatedRange } from './utils/getUpdatedRange';

const DayPickerStyles = styled.div`
.rdp-root {
--rdp-accent-color: ${colors.teal700};
--rdp-accent-background-color: ${colors.teal100};
}

.rdp-selected > button.rdp-day_button {
font-size: 14px;
font-weight: normal;
}
`;

const Calendar = ({
selectedRange,
startMonth: _startMonth,
endMonth: _endMonth,
defaultMonth,
disabled,
selectionMode,
numberOfMonths = 2,
onUpdateRange,
onUpdateSelectionMode,
}: CalendarProps) => {
const locale = useLocale();
const { formatMessage } = useIntl();

const startMonth = _startMonth ?? new Date(1900, 0);
const endMonth = getEndMonth({
endMonth: _endMonth,
selectedDate: selectedRange.to,
});

const handleDayClick: PropsBase['onDayClick'] = (day: Date) => {
if (!selectionMode) return; // Should not be possible in practice

const nextRange = getUpdatedRange({
selectedRange,
selectionMode,
clickedDate: day,
});

onUpdateRange(nextRange);

const nextSelectionMode = getNextSelectionMode({
selectionMode,
selectedRange: nextRange,
});

onUpdateSelectionMode(nextSelectionMode);
};

return (
<DayPickerStyles>
<DayPicker
mode="range"
numberOfMonths={numberOfMonths}
captionLayout="dropdown"
locale={getLocale(locale)}
startMonth={startMonth}
endMonth={endMonth}
defaultMonth={defaultMonth}
selected={{ from: selectedRange.from, to: selectedRange.to }}
disabled={disabled}
onDayClick={handleDayClick}
// This NOOP is necessary because otherwise the
// DayPicker will rely on its internal state to manage the selected
// range rather than being controlled by our state.
onSelect={NOOP}
footer={
<Box mt="12px" w="100%" display="flex">
{selectedRange.from && (
<Button
buttonStyle="text"
size="s"
w="auto"
pl="0px"
ml="8px"
onClick={() => {
onUpdateRange({ from: undefined, to: selectedRange.to });
}}
>
{formatMessage(messages.clearStartDate)}
</Button>
)}
{selectedRange.to && (
<Button
buttonStyle="text"
size="s"
w="auto"
pl="0px"
ml="8px"
onClick={() => {
onUpdateRange({ from: selectedRange.from, to: undefined });
}}
>
{formatMessage(messages.clearEndDate)}
</Button>
)}
</Box>
}
/>
</DayPickerStyles>
);
};

const NOOP = () => {};

export default Calendar;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineMessages } from 'react-intl';

export default defineMessages({
clearStartDate: {
id: 'app.components.admin.DatePickers.DateRangePicker.Calendar.clearStartDate',
defaultMessage: 'Clear start date',
},
clearEndDate: {
id: 'app.components.admin.DatePickers.DateRangePicker.Calendar.clearEndDate',
defaultMessage: 'Clear end date',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DateRange } from 'components/admin/DatePickers/_shared/typings';

import { SelectionMode } from '../../typings';

interface GetNextSelectionModeParams {
selectedRange: Partial<DateRange>;
selectionMode: SelectionMode;
}

export const getNextSelectionMode = ({
selectedRange,
selectionMode,
}: GetNextSelectionModeParams) => {
if (selectedRange.from && !selectedRange.to) {
return 'to';
}

if (!selectedRange.from && selectedRange.to) {
return 'from';
}

return selectionMode;
};
Loading