-
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
[Endpoint] add policy details route #59951
[Endpoint] add policy details route #59951
Conversation
@@ -43,3 +44,24 @@ export const policyListMiddlewareFactory: MiddlewareFactory<PolicyListState> = c | |||
} | |||
}; | |||
}; | |||
|
|||
export const policyDetailsMiddlewareFactory: MiddlewareFactory<PolicyDetailsState> = coreStart => { |
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.
@paul-tavares @parkiino @oatkiller was thinking that we'll keep all state separate from the overall policy list since Policy Details will be it's own route and page.
ManagementList
keeps the details
in state under the overall list data because it's a flyout and a query param:
Currently, I have PolicyDetails separate in state:
If we agree that we should keep PolicyDetails
separate in state, then I'll go ahead and break out all of this code to be in its own files, etc. Let me know your thoughts otherwise.
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 would say 'go w/ it'. Typescript should make refactoring things like this a lot simpler.
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 that makes sense too, since it's its own page
|
||
export const selectPolicyItems = (state: PolicyListState) => state.policyItems; | ||
|
||
export const selectPolicyDetails = (state: PolicyDetailsState) => state.policyItem; | ||
|
||
export const selectPolicyIdFromParams: (state: PolicyDetailsState) => string = createSelector( |
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 gets the job done right now, we should break out the location
state to another location in state as discussed in previous threads by @paul-tavares and @peluja1012
https://github.com/elastic/kibana/pull/58308/files#r385053154
Then we could also put selectors like this in a more generic place
items: PolicyData[]; | ||
} | ||
|
||
let savedFakePolicyData: SavedFakePolicyData = { items: [] }; |
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.
hacky stuff for the fake data, just wanna maintain the random set of data so I can use ids from the URL to find a Policy record
}; | ||
} | ||
|
||
if (action.type === 'userChangedUrl') { |
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.
It's also probably time to break this cycle and put location in a more generic place in state
x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/selectors.ts
Show resolved
Hide resolved
export const getFakeDatasourceApiResponse = async (page: number, pageSize: number) => { | ||
await new Promise(resolve => setTimeout(resolve, 500)); | ||
|
||
// Emulates the API response - see PR: | ||
// https://github.com/elastic/kibana/pull/56567/files#diff-431549a8739efe0c56763f164c32caeeR25 | ||
return { | ||
const policyData = { | ||
items: Array.from({ length: pageSize }, (x, i) => ({ |
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 extract the iterator function here to a top-level function generateSinglePolicyData(name)
and then you can use it in getFakeDatasourceDetailsApiResponse()
without the hackery 😃 ?
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 know I can do that, I was mostly using the hackery to so that when I click on a Policy name, the same name will show up on the Policy details (from the same dataset). I'll adjust the code though so that this isn't so hacky.
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.
Ahh. Ok. In that case, then maybe tie the id
to the name in the generator? (instead of random strings, maybe use the pageNumber
+ pageSize
to get consistent results?
If too much trouble, then just leave it as it - it is "fake" 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.
made to be less hacky now :)
// Emulates the API response - see PR: | ||
// https://github.com/elastic/kibana/pull/56567/files#diff-431549a8739efe0c56763f164c32caeeR25 | ||
|
||
if (savedFakePolicyData.items) { |
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.
If you extract that function above that generate a single Policy, then here you can use it like:
return {
...generateSinglePolicyData('some name');
...{ id }
}
import { selectPolicyDetails } from '../../store/policy_details/selectors'; | ||
|
||
export const PolicyDetails = React.memo(() => { | ||
usePageId('policyDetailsPage'); |
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 are using this anymore (@peluja1012 right?).
I know Policy List has it, but the PR I was working (currently on hold) removes use of this hook in favor of userNavigagtedToPage
store action that is dispatched every time the URL 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.
removed, following a similar method as management and alerts lists now
@@ -84,6 +85,10 @@ const renderFormattedNumber = (value: number, _item: PolicyData) => ( | |||
</TruncateText> | |||
); | |||
|
|||
const renderPolicyNameLink = (value: string, _item: PolicyData) => { | |||
return <Link to={`/policy/${_item.id}`}>{value + ' '}</Link>; |
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 use EuiLink
. Can use the onClick
event along with react-router-dom
useHistory()
to to push the route and then ev.preventDefault()
.
From your last PR, @oatkiller had suggested a generic method/hook?
that we could add to our /lib/
and then re-use with Eui Components that act like navigation links. Maybe its time to add it to our code base.
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.
@paul-tavares using EuiLink now. I tried implementing the hook, but haven't quite gotten it to work yet. I created this ticket last week: https://github.com/elastic/endpoint-app-team/issues/230
I can take that on next and isolate the effort and update all Links. Are you OK with that?
@@ -337,7 +337,7 @@ export type ResolverEvent = EndpointEvent | LegacyEndpointEvent; | |||
/** | |||
* The PageId type is used for the payload when firing userNavigatedToPage actions | |||
*/ | |||
export type PageId = 'alertsPage' | 'managementPage' | 'policyListPage'; | |||
export type PageId = 'alertsPage' | 'managementPage' | 'policyListPage' | 'policyDetailsPage'; |
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 you need this - see comment further below
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.
removed
e6703ab
to
ddff980
Compare
Pinging @elastic/endpoint-management (Team:Endpoint Management) |
Pinging @elastic/endpoint-app-team (Feature:Endpoint) |
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.
LGTM
Thanks for the changes
|
||
return ( | ||
<EuiLink | ||
onClick={(event: React.MouseEvent) => { |
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 also add href
so that user can open in new window/tab or copy url. maybe on next 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.
@paul-tavares I implemented this locally, looks like EuiLink
doesn't accept both href
and onClick
We'll have to revisit that, I'll talk with EUI team
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.
oh yeah - I remember hitting that recently in ingest. Fortunately, I ended up not needing it there since that project is using hash router.
/cc me on the discussion with EUI if you remember
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.
yeah i had to do something like this for the endpoint list, which i put right above the eui component
// eslint-disable-next-line @elastic/eui/href-or-on-click
); | ||
}; | ||
|
||
const renderPolicyNameLink = (value: string, _item: PolicyData) => { |
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 noticed this in Paul's code too, what does the _item
do?
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.
it gives you access to the all of the data that the table columns are based on, in this case the PolicyData
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.
to expand on @parkiino 's comment. The confusion might be in that in my commit I was actually NOT using the item
data (thus why I named it with a _
), but needed to define the parameter in order to get around a TS error - thread here (slack EUI channel) for reference
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.
@kevinlog do you remember when i had that type error on the endpoint details pr? Is this another way to solve that?
* Policy list store state | ||
*/ | ||
export interface PolicyDetailsState { | ||
/** Array of policy items */ |
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.
Is is supposed to be an array of PolicyData
or a single one?
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 single one, you caught my c/p. Corrected.
if (policyItem) { | ||
return <span data-test-subj="policyDetailsName">{policyItem.name}</span>; | ||
} else { | ||
return <span data-test-subj="policyDetailsNotFound">Policy Not Found</span>; |
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 should i18n this message
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.
good call, done
💛 Build succeeded, but was flaky
Test FailuresKibana Pipeline / kibana-xpack-agent / X-Pack Alerting API Integration Tests.x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts·ts.alerting api integration security and spaces enabled Alerting alerts space_1_all at space1 should schedule task, run alert and schedule actions when appropriateStandard Out
Stack Trace
History
To update your PR or re-run it, just comment with: |
Friendly reminder: Looks like this PR hasn’t been backported yet. |
Friendly reminder: Looks like this PR hasn’t been backported yet. |
1 similar comment
Friendly reminder: Looks like this PR hasn’t been backported yet. |
Summary
Implements https://github.com/elastic/endpoint-app-team/issues/245'
Adds the policy details route. It currently operates on fake data that will take any ID passed in and create a Policy details page with a title. This is meant to be a starting point so that we can start building forms for the Policy details page.
The functional tests are light as we aren't dealing with real data now. We just navigate to the page and verify that it loads.
There are also some issues that need to be addressed regarding URLs and routing. I listed them at the bottom and will take them on next. I'd like to merge this so that we can continue development on the Policy forms. I'll address the debt in parallel.
https://github.com/elastic/endpoint-app-team/issues/269
https://github.com/elastic/endpoint-app-team/issues/230
https://github.com/elastic/endpoint-app-team/issues/268
Checklist
Delete any items that are not applicable to this PR.
For maintainers