-
Notifications
You must be signed in to change notification settings - Fork 357
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
fix: React Query Events seen
and other optimizations
#10588
fix: React Query Events seen
and other optimizations
#10588
Conversation
@@ -32,7 +32,7 @@ export const EventsLanding = (props: Props) => { | |||
const { emptyMessage, entityId } = props; | |||
const flags = useFlags(); | |||
|
|||
const filter = EVENTS_LIST_FILTER; | |||
const filter = { ...EVENTS_LIST_FILTER }; |
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 was having issues with EVENTS_LIST_FILTER
getting mutated and causing issues elsewhere.
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.
How is it getting mutated??
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.
3 lines down we do
filter['entity.id'] = entityId;
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 is a bug caused by introducing EVENTS_LIST_FILTER. I'm seeing the issue in develop.
Steps to reproduce:
- Go to a Linode details page
- Go to the Activity Feed tab
- Observe the Events Menu is broken
Maybe we can just Object.freeze
EVENTS_LIST_FILTER?
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.
You're right. am thinking doing
let filter = { ...EVENTS_LIST_FILTER };
if (entityId) {
filter = {
...filter,
'entity.id': entityId,
'entity.type': 'linode',
};
}
would be fine, but it won't prevent people from doing that mistake in the future. not sure we can eslint that either. So either that or we don't do this through a sharable const
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.
Don't we have object constants in other places in the app? Maybe a comment would suffice? Otherwise, +1 for Object.freeze
, it's also friendly with Typescript.
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.
A code comment re: the mutation danger and why we're doing this is warranted
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.
So either that or we don't do this through a sharable const
I like the idea of not using a shareable const, but do others object to that?
For now I pushed a comment + Object.freeze
(notificationItem) => notificationItem.showProgress | ||
); | ||
|
||
const showInProgressEventIcon = events?.some(isInProgressEvent); |
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 might not be what we want. I think previously it is being determined by the factory result
if (events && events.length >= 1 && !events[0].seen) { | ||
markEventsAsSeen(events[0].id); |
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.
Only make the POST if the event is not already seen 🧹
<Box> | ||
<Box display="flex" justifyContent="space-between" px={2}> | ||
<Typography variant="h3">Events</Typography> | ||
<LinkButton | ||
onClick={() => { | ||
history.push('/events'); | ||
handleClose(); | ||
}} | ||
> | ||
View all events | ||
</LinkButton> | ||
</Box> | ||
<Divider spacingBottom={0} /> | ||
{data?.pages[0].data.slice(0, 20).map((event) => ( | ||
<RenderEventV2 event={event} key={event.id} onClose={handleClose} /> | ||
))} | ||
</Box> |
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 might be too soon, but just let me know @abailly-akamai . Feels much better from a simplicity standpoint. Needs an empty state and maybe other things..
I went this route because I needed to check events[0].seen
above and eventNotifications
doesn't have seen
exposed. I can revert this is you want to handle this separately
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.
Chances are NotificationMenuV2
won't remain like this after the cleanup/refactor and will be further refactored. This is a fine first step 👍
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.
Should we at least move this Box
into a new component that receives events
?
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'm down unless @abailly-akamai would rather save that for an upcoming PR.
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'll take care of it, no worries. This is still very much in development - I selfishly want to do the cleanup cause it will be so very healing 🤣
return filter; | ||
return { | ||
...filter, | ||
...EVENTS_LIST_FILTER, |
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 excludes profile_update
events when polling because we never use it. This just results in less data over the wire and less cache updates
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 also on the fence about this. On one end we get less cache updates, but those are super cheap. On the other we know how often profile_update
is being called so there's value. Is garbage collection a factor here?
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, I think profile_update
never gets written to the cache so the only benefit here would be less data over the wire
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 excluding it is fine if we never use it
'+order': 'desc', | ||
'+order_by': 'id', |
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.
Just being explicit about what order we want from the API to prevent unexpected breakages
'+order': 'desc', | ||
'+order_by': 'id', |
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.
Just being explicit about what order we want from the API to prevent unexpected breakages
queryClient.setQueriesData<InfiniteData<ResourcePage<Event>>>( | ||
['events', 'infinite'], |
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 is the primary fix for the seen
issue. This now updates all infinite stores rather than just ['events', 'infinite', undefined]
seen
and other optimizations
Coverage Report: ✅ |
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.
✅ seen
bug has been resolved. Tested and found no regressions.
const { dismissNotifications } = useDismissibleNotifications(); | ||
const { data: notifications } = useNotificationsQuery(); | ||
const formattedNotifications = useFormattedNotifications(); | ||
const eventNotifications = useEventNotificationsV2(); |
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 are no longer using this hook anywhere
<Box> | ||
<Box display="flex" justifyContent="space-between" px={2}> | ||
<Typography variant="h3">Events</Typography> | ||
<LinkButton | ||
onClick={() => { | ||
history.push('/events'); | ||
handleClose(); | ||
}} | ||
> | ||
View all events | ||
</LinkButton> | ||
</Box> | ||
<Divider spacingBottom={0} /> | ||
{data?.pages[0].data.slice(0, 20).map((event) => ( | ||
<RenderEventV2 event={event} key={event.id} onClose={handleClose} /> | ||
))} | ||
</Box> |
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.
Should we at least move this Box
into a new component that receives events
?
<LinkButton | ||
onClick={() => { | ||
history.push('/events'); | ||
handleClose(); | ||
}} | ||
> | ||
View all events | ||
</LinkButton> |
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.
Should this be a Link
instead? Also slight visual regression, in develop this is wrapped in a <strong>
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.
Should we at least move this Box into a new component that receives events?
Should this be a Link instead? Also slight visual regression, in develop this is wrapped in a
I will take care of those when I clean up the whole feature once the flag goes away
@@ -32,7 +32,7 @@ export const EventsLanding = (props: Props) => { | |||
const { emptyMessage, entityId } = props; | |||
const flags = useFlags(); | |||
|
|||
const filter = EVENTS_LIST_FILTER; | |||
const filter = { ...EVENTS_LIST_FILTER }; |
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.
Don't we have object constants in other places in the app? Maybe a comment would suffice? Otherwise, +1 for Object.freeze
, it's also friendly with Typescript.
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.
Functionality and optimizations look good with no regressions observed ✅
return filter; | ||
return { | ||
...filter, | ||
...EVENTS_LIST_FILTER, |
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 excluding it is fine if we never use it
@@ -32,7 +32,7 @@ export const EventsLanding = (props: Props) => { | |||
const { emptyMessage, entityId } = props; | |||
const flags = useFlags(); | |||
|
|||
const filter = EVENTS_LIST_FILTER; | |||
const filter = { ...EVENTS_LIST_FILTER }; |
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.
A code comment re: the mutation danger and why we're doing this is warranted
* initial work * don't poll for `profile_update` events * fixes * update unit test * freeze constant, add comment, delete unused code * Added changeset: React Query Events `seen` behavior and other optimizations --------- Co-authored-by: Banks Nussman <[email protected]>
Description 📝
seen
🔧/v4/events
on page loadPOST /v4/account/events/:id/seen
when needed (previously it would make this POST every time the Event Menu was closed even if the event was already seen)profile_update
events from polling because we don't use themPreview 📷
Screen.Recording.2024-06-17.at.5.40.57.PM.mov
How to test 🧪
Prerequisites
Verification steps
As an Author I have considered 🤔