-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Security Solution][Resolver] Resolver query panel load more #79160
[Security Solution][Resolver] Resolver query panel load more #79160
Conversation
737c82e
to
532332d
Compare
const nextState: DataState = { | ||
...state, | ||
nodeEventsInCategory: { | ||
nodeID: '', |
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 not following the logic 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.
You're spreading in state.nodeEventsInCategory
. You shouldn't need to add their nullish fields. What TS error are you getting?
I think the code here needs to be removed: |
52f4d19
to
bef65d3
Compare
Pinging @elastic/endpoint-app-team (Feature:Resolver) |
} else if (action.type === 'userRequestedAdditionalRelatedEvents') { | ||
const nodeEventsInCategory = state.data.nodeEventsInCategory; | ||
if (nodeEventsInCategory !== undefined) { | ||
api.dispatch({ |
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.
Can we do away with this action? The state should already know that loading is happening. Also, the initial request for data doesn't fire any action like this.
const handleLoadMore = useCallback(() => { | ||
dispatch({ | ||
type: 'userRequestedAdditionalRelatedEvents', | ||
payload: {}, |
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.
Can you remove the payload here.
{hasMore && ( | ||
<EuiFlexItem grow={false}> | ||
<EuiButton color={'primary'} size="s" fill onClick={handleLoadMore} isLoading={isLoading}> | ||
{'Load More Data'} |
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.
Can you wrap this in i18n
.
@@ -50,7 +52,7 @@ export function dataAccessLayerFactory( | |||
after?: string | |||
): Promise<ResolverPaginatedEvents> { | |||
return context.services.http.post('/api/endpoint/resolver/events', { | |||
query: { afterEvent: after }, | |||
query: { afterEvent: after, limit: relatedEventsPaginationSize }, |
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.
Maybe this should be specified on the BE as the 'default' instead of specifying it here. That way we don't have two places defining this value.
(event) => event.event?.category === category | ||
); | ||
if (after === undefined) { | ||
events = eventsOfCategory.slice(0, relatedEventsPaginationSize); |
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 don't think this mock should reference relatedEventsPaginationSize
. I think you could redefine this here const relatedEventsPaginationSize = 25
. I think you even use any arbitrary number you want. Is there some reason I'm missing?
() => | ||
simulator().testSubject('resolver:panel:node-events-in-category:event-link').length | ||
) | ||
).toYieldEqualTo(30); |
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 test says 31 but this checks for 30. can you correct the test message?
() => simulator().testSubject('resolver:nodeEventsInCategory:loadMore').length | ||
) | ||
).toYieldEqualTo(0); | ||
await expect( |
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.
can you combine this expect with the one above it?
iconType="alert" | ||
data-test-subj="resolver:nodeEventsInCategory:error" | ||
> | ||
<p>{'An error occurred when fetching the events.'}</p> |
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.
Can you put this in i18n
?
<NodeEventList eventCategory={eventCategory} nodeID={nodeID} events={events} /> | ||
{hasError ? ( | ||
<EuiCallOut | ||
title="Unable to load 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.
Can you put this in i18n
?
@@ -207,7 +254,7 @@ const NodeEventsInCategoryBreadcrumbs = memo(function ({ | |||
text: ( | |||
<FormattedMessage | |||
id="xpack.securitySolution.endpoint.resolver.panel.relatedEventList.numberOfEvents" | |||
values={{ totalCount: eventCount }} | |||
values={{ totalCount: eventCount || '0' }} |
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.
Can you instead hide this text when the event count hasn't loaded yet? Showing 0
during loading could be strange if the request is slow to come back.
for (let i = 0; i < eventsToGenerate; i++) { | ||
const newEvent = mockEndpointEvent({ | ||
entityID: originID, | ||
eventID: 'test', |
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.
Maybe make the eventID
something like test-${i}
in case we want to interact with the individual events on a page-by-page basis in the test we can, and verify the right event shows up at the right time
}, | ||
}); | ||
} | ||
} else if (newParams.panelView === 'eventDetail') { |
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
return ( | ||
<> | ||
{eventCount === undefined || processEvent === null ? ( | ||
{isLoading || processEvent === null ? ( |
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
)} | ||
color="danger" | ||
iconType="alert" | ||
data-test-subj="resolver:nodeEventsInCategory:error" |
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.
doesn't really matter (nit?). I think we're hyphenating these node-events-in-category
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 add follow up ticket
<EuiSpacer size="l" /> | ||
<NodeEventList eventCategory={eventCategory} nodeID={nodeID} events={events} /> | ||
{hasError ? ( | ||
<EuiCallOut |
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.
Maybe we migrate this to panel_content_error
and expand from this to error, 404, and loading
component to be used in the graph itself and the panel like @oatkiller suggested a while back
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 tested it, looks good. Nice work! 💪
💚 Build SucceededMetrics [docs]async chunks size
History
To update your PR or re-run it, just comment with: |
* master: (85 commits) Refactor attribute service (elastic#78414) [APM] Add default message to alerts. (elastic#78930) [Discover] Modify columns and sort when switching index pattern (elastic#74336) Document ts project references setup (elastic#78586) build all ts refs in single kbn:bootstrap (elastic#79438) [TSVB] Allow string fields on value count aggregation (elastic#79267) [SECURITY SOLUTION] Investigate EQL signal in timeline (elastic#79049) [Fleet] Add loading spinner to page headers (elastic#79568) [Security Solution][Resolver] Resolver query panel load more (elastic#79160) Add type row to monitor detail page. (elastic#79556) Remove license refresh from setup (elastic#79518) [docker] add reporting fonts (elastic#74806) [SECURITY_SOLUTION][ENDPOINT] Add info about trusted apps to the page subtitle + create flyout (elastic#79558) Trim Hash value before validating it (elastic#79545) Warn users when security is not configured (elastic#78545) update copy styling (elastic#79313) Update dependency @elastic/charts to v23.1.1 (elastic#78459) Introduce geo-threshold alerts (elastic#76285) elastic#76920 Show base breadcrumb when there is an error booting the app (elastic#79571) remove react-intl from kibana and keep it inside only i18n package (elastic#78956) ...
Summary
This pr adds a load more feature to the events by type panel view of resolver. When a user clicks into the events by type panel, either from the graph directly or by drilling down, a request is made for the first 25 events in a category. If there are >25 total events, a cursor field is provided, a base64 encoded string of the id and timestamp of event 25, which is then provided in the next request for the 2nd page. Each response is appended to the list of events in the UI each time a user selects the "Load More Data" button. Once a response comes back without the nextEvent cursor, the button is hidden. An error message is shown for either the initial or paginated requests.
Checklist
Delete any items that are not applicable to this PR.
For maintainers