-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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][Expandable flyout] add multi flyout support to kbn-expandable-flyout package #176457
[Security Solution][Expandable flyout] add multi flyout support to kbn-expandable-flyout package #176457
Conversation
Pinging @elastic/security-threat-hunting-investigations (Team:Threat Hunting:Investigations) |
c26b8eb
to
81d0d75
Compare
1bdcee4
to
60055ac
Compare
i'm confused why we have the url key get reflected in state, wouldn't you either have 1 url key per provider, thus defeating the purpose because each flyout has it's own provider/redux store, or all flyouts using the same url key with 1 store would overwrite each others state? seems like it would maybe make more sense to have the url_key be a prop of the component, and only 1 provider is ever in the DOM at a time no? |
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.
Desk tested this PR. Works great 🚀 . I tested back and forward buttons and well and flyout is working perfectly. Only one observation I have is when flyout is closed, eventFlyout
key remains in the url as undefined ( eventFlyout=()
).
I understand that is why you were asking about deleting a search param.
Apart from desk testing, I had below suggestions and questions.
x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx
Show resolved
Hide resolved
@@ -45,12 +45,16 @@ describe('ExpandableFlyout', () => { | |||
|
|||
it('should render right section', () => { |
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.
Could you please add unit tests suite which simulate opening/closing of single/multiple flyouts ( separately and together) and assert corresponding storage/url changes.
I think the package tests are very important to make sure it is handling all the cases consumers are going to use it for.
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 sure I understand here. There should always be a single flyout per provider (as mentioned in the README) so what other tests could I add 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.
Okay i understand. Initially, I was taken aback with the design of having one provider per flyout, since I assumed from the redux state that there will be multiple flyout handled by one provider. But in your other comment you have stated that end goal is to have one provider for all flyouts, I think then these tests will be required. For this PR, this comment can be ignored.
Thanks
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.
Now I'm even more confused! There is currently a single instance of a flyout per expandable flyout provider and this is not going to change. If you're talking about this comment, I said the goal it NOT to have one provider only.
I feel like we might be talking about a different provider level (expandable flyout provider vs internal context provider vs redux provider). To be super clear, this is what we should have:
<ExpandableFlyoutProvider>
<SingleFlyout />
</ ExpandableFlyoutProvider>
I see that I could add test to check that memory mode doesn't store anything in the url and that url mode indeed stores things in the url.
Though testing multiple providers for multiple flyouts seem more some UI integration test than unit tests no? Can I watch the changes to the url if I'm only rendering a single component in Jest?
import { urlChangedAction } from './actions'; | ||
|
||
export type ExpandableFlyoutStorageMode = 'memory' | 'url'; | ||
|
||
/** | ||
* Dispatches actions when url state changes and initializes the state when the app is loaded with flyout url parameters | ||
*/ | ||
const UrlSynchronizer = () => { |
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.
nit
: Since this component is not rendering anything. Do you think it can only be a hook and taken out of this file completely?
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.
Additionaly, there seem to be no test for this file. Could you please add those?
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 we can change this to a hook because we need to conditionally render it (look line 96 of the file).
I can extract it though and write some tests for it!
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 finally decided against extracting it, but I have added unit 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 don't think we can change this to a hook because we need to conditionally render it (look line 96 of the file).
I think that is more of a design question. It can simply be made into a hook by passing needSync : boolean
as a parameter to useUrlSync
and then run effects based on that. I still think that it is more suitable as hook.
But It is only nit
from my side so please go ahead with what you think is good. Thanks for making other changes.
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 still not sure how I would be able to do this. Let me ping on on Slack
60055ac
to
1a11d7c
Compare
@@ -20,8 +20,16 @@ export interface State { | |||
/** | |||
* Panels to render in the preview section | |||
*/ | |||
preview: FlyoutPanelProps[]; | |||
preview: FlyoutPanelProps[] | undefined; |
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, now that we are storing state in redux, consider updating the type of FlyoutPanelProps
to be serializable (line)
export interface FlyoutPanelProps {
...
/**
* Any parameters necessary for the initial requests within the flyout
*/
params?: Record<string, unknown>;
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.
yup I'm going to have to think about how to do that, I'll do it in a follow up PR!
@@ -16,6 +15,8 @@ import { useQueryTimelineByIdOnUrlChange } from './timeline/use_query_timeline_b | |||
import { useInitFlyoutFromUrlParam } from './flyout/use_init_flyout_url_param'; | |||
import { useSyncFlyoutUrlParam } from './flyout/use_sync_flyout_url_param'; | |||
|
|||
export const EXPANDABLE_FLYOUT_URL_KEY = 'eventFlyout' as 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.
maybe detailsFlyout
is more suitable?
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.
yes, I'll leave that to the next PR though, this one is just about adding support to multiple flyouts
@@ -9,17 +9,20 @@ | |||
import { Provider as ReduxProvider } from 'react-redux'; | |||
import { configureStore } from '@reduxjs/toolkit'; | |||
import React, { FC, PropsWithChildren } from 'react'; |
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.
@PhilippeOberti , I would recommend renaming folder to mock
for clarity.
preview: undefined, | ||
}); | ||
expect(mockSet).toHaveBeenCalled(); | ||
}); |
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.
Do you think it should have one more use case where if url is changed, then it should also trigger redux state change?
For example, if a url visits are page with &urlKey=(...)
, it should modify redux state to expand the flyout.
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 making all the needed changes. LGTM 🚀
Approving with couple of very small comments/suggestions. Thank you.
c381eb4
to
ef874b3
Compare
…ackage to support multiple flyout opened at the same time
ef874b3
to
cf0dc68
Compare
💛 Build succeeded, but was flaky
Failed CI StepsTest FailuresMetrics [docs]Module Count
Public APIs missing comments
Async chunks
History
To update your PR or re-run it, just comment with: |
…n-expandable-flyout package (elastic#176457) (cherry picked from commit a2cb03b)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…n-expandable-flyout package (elastic#176457)
## Summary This PR enables Timeline to have its own expandable flyout, independent from the Security Solution app level flyout. This previous [PR](#176457) added support to the `kbn-expandable-flyout` package to be able to show multiple flyout at the same time. This PR focuses on: - changing the location where we use the `<ExpandableFlyoutProvider>` to wrap only the Security Solution pages. instead of the entire Security Solution application - wrapping `Timeline` with its own `<ExpandableFlyoutProvider>` - opening the new expandable flyout from timeline for alerts, users and host!! ### Notes - the new expandable flyout opened from `Timeline` is saved in the url under a new `timelineFlyout` parameter. The other Security Solution flyout stays saved under `eventFlyout` so both can be displayed at the same time - introduced a new feature flag called `expandableTimelineFlyoutEnabled`, enabled to `false` by default. The code uses this flag in combination with the already existing `securitySolution:enableExpandableFlyout` advanced settings to toggle on/off the expandable flyout in `Timeline` I had to make a small change to the timeline `z-index` value, from its hardcoded value of `1000` to now `1001`. At the same time I'm setting the `z-index` of the `eventFlyout` to `1000` and the `z-index` of the `timelineFlyout` to `1002`. Finally, I changed the `z-index` of all the other flyouts opened from the `Take action` button in the footer (like _Add to new case_, _Add rule exception_...) to `1003`. This was the only way to get the order correct after page refresh, and also work in Serverless which has a different top level layout (for the top bar and the left navigation panel). ### Testing Make sure you have the flag turned on in your `kibana.yml` file: `xpack.securitySolution.enableExperimental: ['expandableTimelineFlyoutEnabled']` While the code changes are pretty minimal, emphasize should be done on testing: - verify that the non-timeline expandable flyout behavior hasn't changed (in the Explore, Rule Preview, Alerts pages...) - verify the advanced settings correctly toggles on and off the expandable flyout for both the Security Solution app and Timeline - verify the expandable flyout correctly shows up in Timeline on all the pages where Timeline is present - verify both flyout can be shown at the same time - verify refreshing the page reloads correctly all flyouts open - verify copying the url or using the Share Alert button at the top can be correctly reopened in another tab ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### TODO - [x] fix unit tests - [ ] fix e2e tests - [x] figure out how to fix the UI in serverless (the flyout is currently behind the left navigation) Before change: https://github.com/elastic/kibana/assets/17276605/3b89f87f-d1fa-4635-8ff7-855795eb3796 After change: https://github.com/elastic/kibana/assets/17276605/6b341f11-054c-4885-b496-006f37b8d572 Serverless https://github.com/elastic/kibana/assets/17276605/df414140-31df-4941-869e-c177cfedd805 elastic/security-team#7464 Details of file changed in [the comment below](#177087 (comment))
Summary
This PR primarily makes a change to the
kbn-expandable-flyout
. The goal is to allow multiple expandable flyout to be rendered at the same time (our use case right now is to have a flyout for the alerts page and another flyout for timeline).Notes: for the sake of keeping the PR small, it does NOT implement multiple flyout in the Security Solution codebase. This will come in a follow up PR.
These are the changes:
urlKey
props that developer have to pass when wanting to use the expandable flyout. This will be used as a url parameter to save the state of the flyout in the url. I also removed thestorage
props as it is now redundanturlKey
the storage is done in the url. This makes more sense as theurlKey
would be necessary in that case{ [urlKey: string] : {left, right, preview} }
, so we can store multiple flyouts at the same timepreview
panels toundefined
instead of[]
to make the url look a bit cleaner when we close preview panels or the entire flyout (previously we still have something likepreview:()
after closing)No UI changes should be visible.
A follow up PR will focus on updating the code in the
Security Solution
plugin, to focus on having multiple flyouts.What to test
Checklist
https://github.com/elastic/security-team/issues/7464