-
Notifications
You must be signed in to change notification settings - Fork 14
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
2808: Add a filter by date option to events #2898
base: main
Are you sure you want to change the base?
Conversation
…ts by from and to date
…hanging color when opening calendar
…lendarRangeModal + CustomDatePicker for native
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, thank you for your PR, looks pretty nice already! Nice work 🎉
I just reviewed and tested native so far and everything works and looks as expected. I will review web
once the comments have been addressed (I think the PR is quite huge, perhaps it would be better to merge it one by one and split up the PR, if possible).
I have a few remarks regarding coding style and complexity. If you feel like I misunderstood something or your solution makes more sense, please tell.
General changes that would be a good addition:
- Use DateTime to avoid manual parsing and formatting as well as validating
- Clicking next to the date picker could/should close it for better UX
- If you delete a slash in the date picker, you can't readd it (since the keyboard only shows numbers). A better choice would perhaps be to implement fields for day, month, and year separately, so you can only edit either one at a time. Not sure if this is an optimal solution though, so if you have any other ideas let me know.
Keep in mind that I did not mention every occurrence of things that could be improved, please apply the suggestions to other parts in the code, too.
release-notes/unreleased/2808-Add-a-filter-by-date-option-to-events.yml
Outdated
Show resolved
Hide resolved
Some thoughts on the behavior:
One more general question: |
Sadly I just realized we have another problem. A lot of our events are recurring, i.e. happening multiple times, for example every week. Our filtering should reflect that and include events that have recurrences in the selected time period. This might not be that easy, so perhaps we should do that in a separate PR. Has to be done before this is good to go though sadly :/ |
I think it can be done by modifying the filter maybe using rrule.between() event.date has |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes and trying to make it work with our recurring events. I still see two problems though (which were also the reasons why I said I'd rather do this in a separate PR):
- if the filters are set, only recurrences that are within that time period should be shown
- this only works if one of the first MAX_DATE_RECURRENCES is in the selected time period. If it is a later recurrence, this won't work. You'd therefore need to adjust the
recurrences
function to accept start/end date values
Furthermore, there are some warnings regarding code complexity still, please try to adjust your code to address those.
… for Code-Climate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing, great work! Thank you so much for all the work 🎉
Code Climate has analyzed commit ab81a63 and detected 4 issues on this pull request. Here's the issue category breakdown:
The test coverage on the diff in this pull request is 58.3% (50% is the threshold). This pull request will bring the total coverage in the repository to 73.8%. View more on Code Climate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not really happy with this solution, because:
-
When a user only wants to specify a end date, and clicks on the calendar of the "to" input field, a "from" date is selected nevertheless. This is not how this should work intuitively.
-
When selecting a "from" date from the date picker and entering the "to" date with a text input, it will not work.
-
When selecting a "from" date for the date picker, i cannot click "ok" in the calendar and if i close the calendar the date is not in the input field.
-
When using the input field, the and entering the date by keyboard, when i entered two digits for "dd" it should automatically go to the "mm" input, as on a smartphone it is quite annoying to click on the next section, which is very small.
As the library you use, does not really fit our needs of selecting a range, is there any reason to not use e.g. this library? https://www.npmjs.com/package/react-native-ui-datepicker
const DatePicker = ({ title, date, setDate, error, modalOpen, setModalOpen }: DatePickerProps): ReactElement => { | ||
const [inputDay, setInputDay] = useState(date?.toFormat('dd')) | ||
const [inputMonth, setInputMonth] = useState(date?.toFormat('MM')) | ||
const [inputYear, setInputYear] = useState(date?.toFormat('yyyy')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is not very good, to have separate state for day, month and year. This leads to
- unnecessary re-renders
- allows invalid dates to be entered, like 31.02.2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is not very good, to have separate state for day, month and year. This leads to
1. unnecessary re-renders
Tbh I don't think there is a difference between separate states or single state for the date here. If one value is changed, there is a rerender. It does not matter if we change a single state multiple times or a multi state multiple times.
2. allows invalid dates to be entered, like 31.02.2024
It is never completely preventable that no invalid date is entered, for example by copy and paste. If it is correctly handled/validated, I don't see a reason why that has to be a problem.
Good find, I think these things should be addressed. I think this is only the case for native, right? I think you should be able to just adjust the day marking handling and some other logic though, I am pretty sure there is no need to switch the library because of this. |
Why use a library that does not fit our needs, if there are libraries that we can just use out of the box? |
Why do you think that this library does not fit our need? I think it does pretty much exactly what we need it to do, i.e. being able to select and mark dates. We just have to slightly adjust how when we set start and end dates 🤔 |
I actually tried to use this library but it has issues with RTL languages the will get switched up like this and we tried to solve it and non worked ... |
I will dismiss my review as "changes requested" here, as I am on vacation and do not want to block this. @bahaaTuffaha Thanks for explaining why the other library was not an option and good work in general with this PR, the UI looks pretty nice and looking forward to have this feature in Integreat 🚀 |
Do not want to block this during my vacation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, thank you for all your work on this already!
I only managed to do a somewhat superficial review, and only of the native parts, but I have found a few more things that could do some work.
I put in the dates 1.10.2024 - 24.10.2024 and got dates from 25.10.2024 - 6.11.2024
Edit: I have since realized that those are recurring events. That's cool but we need to show them with the dates that are during the selected period.
-
I find the interactions in the CalendarRangeModal confusing. My expectations from the way other date pickers work would be that the calendar closes when I chose an end date. There are a few other behaviors that I don't expect but I think they would all be covered by closing the calendar when the second date is selected.
-
I get the following warning in my console: WARN (ADVICE) "fit-content" is not a valid dimension. Dimensions must be a number, "auto", or a string suffixed with "%".
-
The inputs for with
'dd'
,'mm'
and'yyyy'
do absolutely nothing when I tap on them in emulated iOS, don't even give me an error message. -
If I enter e.g. 01.11.2024 into the start date, then tap somewhere else, then try to edit the day of the start date again, nothing I type is accepted until I first delete the number that is in there already.
I would suggest maybe taking an hour or two and looking at this with fresh eyes and trying to do your own code review. I find it often helps me to improve my own code when I have to understand it after not having looked at it in a while.
justify-content: ${props => (props.theme.contentDirection === 'rtl' ? 'flex-start' : 'flex-end')}; | ||
flex-direction: ${props => (props.theme.contentDirection === 'rtl' ? 'row-reverse' : 'row')}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ This does seem odd, I would expect the combination of these two lines to do nothing since the positioning is turned around twice?
value={inputDay} | ||
/> | ||
<Text>.</Text> | ||
<Input |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 I think the inputs could be pulled into a separate component to improve legibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think that the inputs could be pulled into a separate component to improve legibility. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 Thank you for always writing tests immediately! I think this is a good place to expand on some tests :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added 3 more but I couldn't get the .focus()
or fireEvent.focus()
working to test backspace jumping or even jumping forward from day to the month when its entered.
When this is merged, we should make a note in this thread that it will be deployed to production the Monday after the next |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, we're getting there! I have a few more general comments:
- As you already noticed, you haven't dealt with the animation yet, and I think it would also be nice to have one in the web.
- While I agree that we should show recurring events in the filtered list, we definitely need to show them with the date that is within that time frame, or show in some other way why these events are shown even though the filter should be hiding them.
- In native, I still find the interactions in the CalendarRangeModal confusing. My expectations from the way other date pickers work would be that the calendar closes when I chose an end date. There are a few other behaviors that I don't expect but I think they would all be covered by closing the calendar when the second date is selected.
- I like your solution for dealing with someone opening an input field a second time, very nice! But I think we still need a better solution for people putting in invalid formats. I think we should let them enter what they want and validate on blur. I would expect a number that is too high to be turned into the maximum possible number, and otherwise invalid dates to either be blanked or get a red outline and an explaining text. I guess an error would be ideal but it’s also more work to add an error behavior for something that, realistically speaking, won’t be happening all that much.
padding: 5px 14px; | ||
` | ||
|
||
const OPACITY_DISABLED = 0.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙃 OPACITY_DISABLED
sounds to me like it should be a boolean of whether the opacity is disabled. Since this is supposed to be the opacity of a disabled button, I would say it should be called DISABLED_OPACITY
.
|
||
const textButtonStyles = { | ||
container: { | ||
height: 40, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ The height can go directly into the StyledTextButton
if (tempStartDate && currentInput === 'from' && tempEndDate == null) { | ||
setStartDate(tempStartDate) | ||
} else if (tempStartDate && currentInput === 'to' && tempEndDate == null) { | ||
setEndDate(tempStartDate) | ||
} else if (tempStartDate && tempEndDate) { | ||
setStartDate(tempStartDate) | ||
setEndDate(tempEndDate) | ||
} | ||
setTempStartDate(null) | ||
setTempEndDate(null) | ||
closeModal() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 I think this entire block could do with being pulled into a well-named function. Maybe also refactor it a little bit while you're at it, first thing I see: the lines 122 and 124 are almost the same, you could have
- one if statement with the shared parts and
- in the then part a ternary operator to decide which date should be set.
type='clear' | ||
disabled={ | ||
(tempStartDate === null && tempEndDate === null) || | ||
Boolean(tempStartDate && tempEndDate && tempStartDate > tempEndDate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙃 We usually use !!
to type cast something into a boolean :)
setTempStartDate(startDate) | ||
setTempEndDate(endDate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Why are you setting these temporary values as you're closing the modal? Wouldn't they be filled in correctly anyway with the next opening?
|
||
const DateSection = styled.div` | ||
display: flex; | ||
flex-direction: row; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 That's the default direction, we don't need it
|
||
const StyledButton = styled(Button)` | ||
display: flex; | ||
flex-direction: row; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 Same here
|
||
const ResetFilterText = ({ startDate, endDate }: ResetFilterTextProps) => { | ||
const { t } = useTranslation('events') | ||
const title = `${t('resetFilter')} ${startDate?.toLocal().toFormat('dd.MM.yyyy') ?? '∞'} - ${endDate?.toLocal().toFormat('dd.MM.yyyy') ?? '∞'}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const title = `${t('resetFilter')} ${startDate?.toLocal().toFormat('dd.MM.yyyy') ?? '∞'} - ${endDate?.toLocal().toFormat('dd.MM.yyyy') ?? '∞'}` | |
const title = `${t('resetFilter')} ${startDate?.toLocaleString({ day: '2-digit', month: '2-digit', year: 'numeric' } ?? '∞'} - ${endDate?.toLocaleString({ day: '2-digit', month: '2-digit', year: 'numeric' } ?? '∞'}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, that's not a title, that's a text :)
|
||
const StyledButton = styled(Button)` | ||
display: flex; | ||
flex-direction: row; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also unnecessary :)
toggle, | ||
setToggleDateFilter, | ||
}: { | ||
toggle: boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙃 As discussed in the native part, I find this naming confusing
Short description
Filtering events by date
Proposed changes
For web:
CustomDatePicker
and usedInput type='date'
as date picker.For native:
CustomDatePicker
used react-native TextInput and IconButton to show calendar modal.Shared:
Side effects
None.
Resolved issues
Fixes: #2808