From 88caa798a9336e16541681fd4e2cfadbad35432a Mon Sep 17 00:00:00 2001
From: Kevin Logan <56395104+kevinlog@users.noreply.github.com>
Date: Mon, 14 Sep 2020 20:59:21 -0400
Subject: [PATCH] [SECURITY_SOLUTION] Task/hostname policy response ux updates
(#76444)
---
.../components/formatted_date/index.tsx | 18 +++++++++
.../pages/endpoint_hosts/store/selectors.ts | 6 +++
.../view/details/endpoint_details.tsx | 6 +--
.../endpoint_hosts/view/details/index.tsx | 12 +++++-
.../pages/endpoint_hosts/view/index.test.tsx | 4 +-
.../pages/endpoint_hosts/view/index.tsx | 40 ++++++++++++-------
.../apps/endpoint/endpoint_list.ts | 16 ++++----
7 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx
index 687d2a36da610..38c2a8583f7e9 100644
--- a/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx
@@ -22,6 +22,24 @@ export const PreferenceFormattedDate = React.memo<{ dateFormat?: string; value:
PreferenceFormattedDate.displayName = 'PreferenceFormattedDate';
+export const PreferenceFormattedDateFromPrimitive = ({
+ value,
+}: {
+ value?: string | number | null;
+}) => {
+ if (value == null) {
+ return getOrEmptyTagFromValue(value);
+ }
+ const maybeDate = getMaybeDate(value);
+ if (!maybeDate.isValid()) {
+ return getOrEmptyTagFromValue(value);
+ }
+ const date = maybeDate.toDate();
+ return ;
+};
+
+PreferenceFormattedDateFromPrimitive.displayName = 'PreferenceFormattedDateFromPrimitive';
+
/**
* This function may be passed to `Array.find()` to locate the `P1DT`
* configuration (sub) setting, a string array that contains two entries
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts
index 852bc9791fc90..a3eee8063d6f7 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts
@@ -72,6 +72,12 @@ export const patternsError = (state: Immutable) => state.patterns
const detailsPolicyAppliedResponse = (state: Immutable) =>
state.policyResponse && state.policyResponse.Endpoint.policy.applied;
+/**
+ * Returns the policy response timestamp from the endpoint after a user modifies a policy.
+ */
+export const policyResponseTimestamp = (state: Immutable) =>
+ state.policyResponse && state.policyResponse['@timestamp'];
+
/**
* Returns the response configurations from the endpoint after a user modifies a policy.
*/
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx
index b76b7e51b2c1b..47f4fbb8830ae 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx
@@ -125,7 +125,7 @@ export const EndpointDetails = memo(({ details }: { details: HostMetadata }) =>
return [
{
title: i18n.translate('xpack.securitySolution.endpoint.details.policy', {
- defaultMessage: 'Integration',
+ defaultMessage: 'Integration Policy',
}),
description: (
<>
@@ -140,7 +140,7 @@ export const EndpointDetails = memo(({ details }: { details: HostMetadata }) =>
},
{
title: i18n.translate('xpack.securitySolution.endpoint.details.policyStatus', {
- defaultMessage: 'Configuration response',
+ defaultMessage: 'Policy Response',
}),
description: (
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx
index a37ddd0bd61d9..43d3b39474fc7 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx
@@ -32,6 +32,7 @@ import {
policyResponseFailedOrWarningActionCount,
policyResponseError,
policyResponseLoading,
+ policyResponseTimestamp,
} from '../../store/selectors';
import { EndpointDetails } from './endpoint_details';
import { PolicyResponse } from './policy_response';
@@ -41,6 +42,7 @@ import { useNavigateByRouterEventHandler } from '../../../../../common/hooks/end
import { getEndpointListPath } from '../../../../common/routing';
import { SecurityPageName } from '../../../../../app/types';
import { useFormatUrl } from '../../../../../common/components/link_to';
+import { PreferenceFormattedDateFromPrimitive } from '../../../../../common/components/formatted_date';
export const EndpointDetailsFlyout = memo(() => {
const history = useHistory();
@@ -122,6 +124,7 @@ const PolicyResponseFlyoutPanel = memo<{
const loading = useEndpointSelector(policyResponseLoading);
const error = useEndpointSelector(policyResponseError);
const { formatUrl } = useFormatUrl(SecurityPageName.administration);
+ const responseTimestamp = useEndpointSelector(policyResponseTimestamp);
const [detailsUri, detailsRoutePath] = useMemo(
() => [
formatUrl(
@@ -161,16 +164,21 @@ const PolicyResponseFlyoutPanel = memo<{
+
+
+
+
+
{error && (
}
/>
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx
index 14167f25d5b90..2bdf17b806079 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx
@@ -510,7 +510,7 @@ describe('when on the list page', () => {
const renderResult = await renderAndWaitForData();
const linkToReassign = await renderResult.findByTestId('endpointDetailsLinkToIngest');
expect(linkToReassign).not.toBeNull();
- expect(linkToReassign.textContent).toEqual('Reassign Configuration');
+ expect(linkToReassign.textContent).toEqual('Reassign Policy');
expect(linkToReassign.getAttribute('href')).toEqual(
`/app/ingestManager#/fleet/agents/${agentId}/activity?openReassignFlyout=true`
);
@@ -572,7 +572,7 @@ describe('when on the list page', () => {
it('should include the sub-panel title', async () => {
expect(
(await renderResult.findByTestId('endpointDetailsPolicyResponseFlyoutTitle')).textContent
- ).toBe('Configuration Response');
+ ).toBe('Policy Response');
});
it('should show a configuration section for each protection', async () => {
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx
index 166f1660bf3d6..ecee2bee0c58b 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx
@@ -270,17 +270,20 @@ export const EndpointList = () => {
);
const toRouteUrl = formatUrl(toRoutePath);
return (
-
+
+
+
);
},
},
{
field: 'host_status',
+ width: '9%',
name: i18n.translate('xpack.securitySolution.endpoint.list.hostStatus', {
defaultMessage: 'Agent Status',
}),
@@ -303,27 +306,31 @@ export const EndpointList = () => {
},
{
field: 'metadata.Endpoint.policy.applied',
+ width: '15%',
name: i18n.translate('xpack.securitySolution.endpoint.list.policy', {
- defaultMessage: 'Integration',
+ defaultMessage: 'Integration Policy',
}),
truncateText: true,
// eslint-disable-next-line react/display-name
render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied']) => {
return (
-
- {policy.name}
-
+
+
+ {policy.name}
+
+
);
},
},
{
field: 'metadata.Endpoint.policy.applied',
+ width: '9%',
name: i18n.translate('xpack.securitySolution.endpoint.list.policyStatus', {
- defaultMessage: 'Configuration Status',
+ defaultMessage: 'Policy Status',
}),
render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied'], item: HostInfo) => {
const toRoutePath = getEndpointDetailsPath({
@@ -350,6 +357,7 @@ export const EndpointList = () => {
},
{
field: 'metadata.host.os.name',
+ width: '10%',
name: i18n.translate('xpack.securitySolution.endpoint.list.os', {
defaultMessage: 'Operating System',
}),
@@ -375,6 +383,7 @@ export const EndpointList = () => {
},
{
field: 'metadata.agent.version',
+ width: '5%',
name: i18n.translate('xpack.securitySolution.endpoint.list.endpointVersion', {
defaultMessage: 'Version',
}),
@@ -394,6 +403,7 @@ export const EndpointList = () => {
},
{
field: '',
+ width: '5%',
name: i18n.translate('xpack.securitySolution.endpoint.list.actions', {
defaultMessage: 'Actions',
}),
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts
index b0b8d14108004..7485e5db20478 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts
@@ -22,8 +22,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
[
'Hostname',
'Agent Status',
- 'Integration',
- 'Configuration Status',
+ 'Integration Policy',
+ 'Policy Status',
'Operating System',
'IP Address',
'Version',
@@ -188,8 +188,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
'OS',
'Last Seen',
'Alerts',
- 'Integration',
- 'Configuration Status',
+ 'Integration Policy',
+ 'Policy Status',
'IP Address',
'Hostname',
'Sensor Version',
@@ -236,8 +236,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
[
'Hostname',
'Agent Status',
- 'Integration',
- 'Configuration Status',
+ 'Integration Policy',
+ 'Policy Status',
'Operating System',
'IP Address',
'Version',
@@ -267,8 +267,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
[
'Hostname',
'Agent Status',
- 'Integration',
- 'Configuration Status',
+ 'Integration Policy',
+ 'Policy Status',
'Operating System',
'IP Address',
'Version',