Skip to content

Commit

Permalink
[Security Solution][Endpoint] Fix UI inconsistency between isolation …
Browse files Browse the repository at this point in the history
…forms and remove display of Pending isolation statuses (#106118)

* comment out UI display of pending isolation statuses and associated tests
* Change un-isolate form to use `EuiForm` and `EuiFormRow`
* Fix: move component `displayName` to file that has that component's src
  • Loading branch information
paul-tavares committed Jul 19, 2021
1 parent fc49ae1 commit 879b1a4
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ describe('when using the EndpointHostIsolationStatus component', () => {
expect(getByTestId('test').textContent).toBe('Isolated');
});

it.each([
// FIXME: un-skip when we bring back the pending isolation statuses
it.skip.each([
['Isolating', { pendingIsolate: 2 }],
['Releasing', { pendingUnIsolate: 2 }],
['4 actions pending', { isIsolated: true, pendingUnIsolate: 2, pendingIsolate: 2 }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/

import React, { memo, useMemo } from 'react';
import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiTextColor, EuiToolTip } from '@elastic/eui';
import { EuiBadge } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useTestIdGenerator } from '../../../../management/components/hooks/use_test_id_generator';
// import { useTestIdGenerator } from '../../../../management/components/hooks/use_test_id_generator';

export interface EndpointHostIsolationStatusProps {
isIsolated: boolean;
Expand All @@ -25,94 +25,114 @@ export interface EndpointHostIsolationStatusProps {
* (`null` is returned)
*/
export const EndpointHostIsolationStatus = memo<EndpointHostIsolationStatusProps>(
({ isIsolated, pendingIsolate = 0, pendingUnIsolate = 0, 'data-test-subj': dataTestSubj }) => {
const getTestId = useTestIdGenerator(dataTestSubj);
({
isIsolated,
/* pendingIsolate = 0, pendingUnIsolate = 0,*/ 'data-test-subj': dataTestSubj,
}) => {
// const getTestId = useTestIdGenerator(dataTestSubj);

return useMemo(() => {
// If nothing is pending and host is not currently isolated, then render nothing
if (!isIsolated && !pendingIsolate && !pendingUnIsolate) {
if (!isIsolated) {
return null;
}
// if (!isIsolated && !pendingIsolate && !pendingUnIsolate) {
// return null;
// }

// If nothing is pending, but host is isolated, then show isolation badge
if (!pendingIsolate && !pendingUnIsolate) {
return (
<EuiBadge color="hollow" data-test-subj={dataTestSubj}>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.isolated"
defaultMessage="Isolated"
/>
</EuiBadge>
);
}

// If there are multiple types of pending isolation actions, then show count of actions with tooltip that displays breakdown
if (pendingIsolate && pendingUnIsolate) {
return (
<EuiBadge color="hollow" data-test-subj={dataTestSubj}>
<EuiToolTip
display="block"
anchorClassName="eui-textTruncate"
content={
<div data-test-subj={getTestId('tooltipContent')}>
<div>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingActions"
defaultMessage="Pending actions:"
/>
</div>
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
<EuiFlexItem grow>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingIsolate"
defaultMessage="Isolate"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>{pendingIsolate}</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingUnIsolate"
defaultMessage="Release"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>{pendingUnIsolate}</EuiFlexItem>
</EuiFlexGroup>
</div>
}
>
<EuiTextColor color="subdued" data-test-subj={getTestId('pending')}>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.multiplePendingActions"
defaultMessage="{count} actions pending"
values={{ count: pendingIsolate + pendingUnIsolate }}
/>
</EuiTextColor>
</EuiToolTip>
</EuiBadge>
);
}

// Show 'pending [un]isolate' depending on what's pending
return (
<EuiBadge color="hollow" data-test-subj={dataTestSubj}>
<EuiTextColor color="subdued" data-test-subj={getTestId('pending')}>
{pendingIsolate ? (
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.isIsolating"
defaultMessage="Isolating"
/>
) : (
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.isUnIsolating"
defaultMessage="Releasing"
/>
)}
</EuiTextColor>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolationStatus.isolated"
defaultMessage="Isolated"
/>
</EuiBadge>
);
}, [dataTestSubj, getTestId, isIsolated, pendingIsolate, pendingUnIsolate]);

// If nothing is pending and host is not currently isolated, then render nothing
// if (!isIsolated && !pendingIsolate && !pendingUnIsolate) {
// return null;
// }
//
// // If nothing is pending, but host is isolated, then show isolation badge
// if (!pendingIsolate && !pendingUnIsolate) {
// return (
// <EuiBadge color="hollow" data-test-subj={dataTestSubj}>
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.isolated"
// defaultMessage="Isolated"
// />
// </EuiBadge>
// );
// }
//
// // If there are multiple types of pending isolation actions, then show count of actions with tooltip that displays breakdown
// if (pendingIsolate && pendingUnIsolate) {
// return (
// <EuiBadge color="hollow" data-test-subj={dataTestSubj}>
// <EuiToolTip
// display="block"
// anchorClassName="eui-textTruncate"
// content={
// <div data-test-subj={getTestId('tooltipContent')}>
// <div>
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingActions"
// defaultMessage="Pending actions:"
// />
// </div>
// <EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
// <EuiFlexItem grow>
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingIsolate"
// defaultMessage="Isolate"
// />
// </EuiFlexItem>
// <EuiFlexItem grow={false}>{pendingIsolate}</EuiFlexItem>
// </EuiFlexGroup>
// <EuiFlexGroup gutterSize="none">
// <EuiFlexItem grow>
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingUnIsolate"
// defaultMessage="Release"
// />
// </EuiFlexItem>
// <EuiFlexItem grow={false}>{pendingUnIsolate}</EuiFlexItem>
// </EuiFlexGroup>
// </div>
// }
// >
// <EuiTextColor color="subdued" data-test-subj={getTestId('pending')}>
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.multiplePendingActions"
// defaultMessage="{count} actions pending"
// values={{ count: pendingIsolate + pendingUnIsolate }}
// />
// </EuiTextColor>
// </EuiToolTip>
// </EuiBadge>
// );
// }
//
// // Show 'pending [un]isolate' depending on what's pending
// return (
// <EuiBadge color="hollow" data-test-subj={dataTestSubj}>
// <EuiTextColor color="subdued" data-test-subj={getTestId('pending')}>
// {pendingIsolate ? (
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.isIsolating"
// defaultMessage="Isolating"
// />
// ) : (
// <FormattedMessage
// id="xpack.securitySolution.endpoint.hostIsolationStatus.isUnIsolating"
// defaultMessage="Releasing"
// />
// )}
// </EuiTextColor>
// </EuiBadge>
// );
}, [dataTestSubj, isIsolated /* , getTestId , pendingIsolate, pendingUnIsolate*/]);
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiForm,
EuiFormRow,
EuiText,
EuiTextArea,
EuiTitle,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { CANCEL, COMMENT, COMMENT_PLACEHOLDER, CONFIRM, UNISOLATE, ISOLATED } from './translations';
Expand All @@ -30,50 +30,49 @@ export const EndpointUnisolateForm = memo<EndpointIsolatedFormProps>(
);

return (
<>
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolation.unIsolateThisHost"
defaultMessage="{hostName} is currently {isolated}. Are you sure you want to {unisolate} this host?"
values={{
hostName: <b>{hostName}</b>,
isolated: <b>{ISOLATED}</b>,
unisolate: <b>{UNISOLATE}</b>,
}}
/>{' '}
{messageAppend}
</p>
</EuiText>
<EuiForm>
<EuiFormRow fullWidth>
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolation.unIsolateThisHost"
defaultMessage="{hostName} is currently {isolated}. Are you sure you want to {unisolate} this host?"
values={{
hostName: <b>{hostName}</b>,
isolated: <b>{ISOLATED}</b>,
unisolate: <b>{UNISOLATE}</b>,
}}
/>{' '}
{messageAppend}
</p>
</EuiText>
</EuiFormRow>

<EuiSpacer size="m" />
<EuiFormRow label={COMMENT} fullWidth>
<EuiTextArea
data-test-subj="host_isolation_comment"
fullWidth
placeholder={COMMENT_PLACEHOLDER}
value={comment}
onChange={handleCommentChange}
/>
</EuiFormRow>

<EuiTitle size="xs">
<h4>{COMMENT}</h4>
</EuiTitle>
<EuiTextArea
data-test-subj="host_isolation_comment"
fullWidth
placeholder={COMMENT_PLACEHOLDER}
value={comment}
onChange={handleCommentChange}
/>

<EuiSpacer size="m" />

<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onCancel} disabled={isLoading}>
{CANCEL}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill onClick={onConfirm} disabled={isLoading} isLoading={isLoading}>
{CONFIRM}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</>
<EuiFormRow fullWidth>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onCancel} disabled={isLoading}>
{CANCEL}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill onClick={onConfirm} disabled={isLoading} isLoading={isLoading}>
{CONFIRM}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFormRow>
</EuiForm>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ export const ContextMenuItemNavByRouter = memo<ContextMenuItemNavByRouterProps>(
);
}
);

ContextMenuItemNavByRouter.displayName = 'EuiContextMenuItemNavByRouter';
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ describe('When using the EndpointAgentStatus component', () => {
expect(renderResult.getByTestId('rowHostStatus').textContent).toEqual(expectedLabel);
});

describe('and host is isolated or pending isolation', () => {
// FIXME: un-skip test once Islation pending statuses are supported
describe.skip('and host is isolated or pending isolation', () => {
beforeEach(async () => {
// Ensure pending action api sets pending action for the test endpoint metadata
const pendingActionsResponseProvider = httpMocks.responseProvider.pendingActions.getMockImplementation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,3 @@ export const TableRowActions = memo<TableRowActionProps>(({ endpointMetadata })
);
});
TableRowActions.displayName = 'EndpointTableRowActions';

ContextMenuItemNavByRouter.displayName = 'EuiContextMenuItemNavByRouter';
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ describe('EndpointOverview Component', () => {
expect(findData.at(3).text()).toEqual('HealthyIsolated');
});

test.each([
// FIXME: un-skip once pending isolation status are supported again
test.skip.each([
['isolate', 'Isolating'],
['unisolate', 'Releasing'],
])('it shows pending %s status', (action, expectedLabel) => {
Expand Down

0 comments on commit 879b1a4

Please sign in to comment.