Skip to content

Commit

Permalink
[Security Solution][Endpoint][Admin] Endpoint List UI update (#106568) (
Browse files Browse the repository at this point in the history
#108241)

Co-authored-by: Candace Park <56409205+parkiino@users.noreply.github.com>
  • Loading branch information
kibanamachine and parkiino authored Aug 11, 2021
1 parent cef07e0 commit e9e5e63
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ export const SecuritySolutionTemplateWrapper: React.FC<SecuritySolutionPageWrapp
getTimelineShowStatus(state, TimelineId.active)
);

/* StyledKibanaPageTemplate is a styled EuiPageTemplate. Security solution currently passes the header and page content as the children of StyledKibanaPageTemplate, as opposed to using the pageHeader prop, which may account for any style discrepancies, such as the bottom border not extending the full width of the page, between EuiPageTemplate and the security solution pages.
*/

return (
<StyledKibanaPageTemplate
$isTimelineBottomBarVisible={isTimelineBottomBarVisible}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,61 @@
* 2.0.
*/

import React, { FC, memo } from 'react';
import { EuiPanel, CommonProps } from '@elastic/eui';
import styled from 'styled-components';
import React, { FC, memo, useMemo } from 'react';
import {
CommonProps,
EuiPageHeader,
EuiFlexGroup,
EuiFlexItem,
EuiTitle,
EuiSpacer,
} from '@elastic/eui';
import { SecurityPageName } from '../../../common/constants';
import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper';
import { HeaderPage } from '../../common/components/header_page';
import { SpyRoute } from '../../common/utils/route/spy_routes';
import { BETA_BADGE_LABEL } from '../common/translations';

/** Ensure that all flyouts z-index in Administation area show the flyout header */
const EuiPanelStyled = styled(EuiPanel)`
.euiFlyout {
z-index: ${({ theme }) => theme.eui.euiZNavigation + 1};
}
`;

interface AdministrationListPageProps {
beta: boolean;
title: React.ReactNode;
subtitle: React.ReactNode;
actions?: React.ReactNode;
headerBackComponent?: React.ReactNode;
}

export const AdministrationListPage: FC<AdministrationListPageProps & CommonProps> = memo(
({ beta, title, subtitle, actions, children, headerBackComponent, ...otherProps }) => {
const badgeOptions = !beta ? undefined : { beta: true, text: BETA_BADGE_LABEL };
({ title, subtitle, actions, children, headerBackComponent, ...otherProps }) => {
const header = useMemo(() => {
return (
<EuiFlexGroup direction="column" gutterSize="none" alignItems="flexStart">
<EuiFlexItem grow={false}>
{headerBackComponent && <>{headerBackComponent}</>}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiTitle size="l">
<span data-test-subj="header-page-title">{title}</span>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
);
}, [headerBackComponent, title]);

return (
<SecuritySolutionPageWrapper noTimeline {...otherProps}>
<HeaderPage
hideSourcerer={true}
title={title}
subtitle={subtitle}
backComponent={headerBackComponent}
badgeOptions={badgeOptions}
>
{actions}
</HeaderPage>
const description = useMemo(() => {
return <span data-test-subj="header-panel-subtitle">{subtitle}</span>;
}, [subtitle]);

<EuiPanelStyled hasBorder>{children}</EuiPanelStyled>
return (
<>
<EuiPageHeader
pageTitle={header}
description={description}
bottomBorder={true}
rightSideItems={[actions]}
restrictWidth={false}
{...otherProps}
/>
<EuiSpacer size="l" />
{children}

<SpyRoute pageName={SecurityPageName.administration} />
</SecuritySolutionPageWrapper>
</>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const AdminSearchBar = memo(() => {
timeHistory={timeHistory}
onQuerySubmit={onQuerySubmit}
isLoading={false}
iconType="search"
showFilterBar={false}
showDatePicker={false}
showQueryBar={true}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
HostStatus,
} from '../../../../../common/endpoint/types';
import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data';
import { POLICY_STATUS_TO_TEXT } from './host_constants';
import { POLICY_STATUS_TO_HEALTH_COLOR, POLICY_STATUS_TO_TEXT } from './host_constants';
import { mockPolicyResultList } from '../../policy/store/test_mock_utils';
import { getEndpointDetailsPath } from '../../../common/routing';
import { KibanaServices, useKibana, useToasts } from '../../../../common/lib/kibana';
Expand Down Expand Up @@ -337,7 +337,7 @@ describe('when on the endpoint list page', () => {
await middlewareSpy.waitForAction('serverReturnedEndpointList');
});
const total = await renderResult.findByTestId('endpointListTableTotal');
expect(total.textContent).toEqual('5 Hosts');
expect(total.textContent).toEqual('Showing 5 endpoints');
});
it('should display correct status', async () => {
const renderResult = render();
Expand Down Expand Up @@ -380,18 +380,14 @@ describe('when on the endpoint list page', () => {
const policyStatuses = await renderResult.findAllByTestId('rowPolicyStatus');

policyStatuses.forEach((status, index) => {
const policyStatusToRGBColor: Array<[string, string]> = [
['Success', 'background-color: rgb(109, 204, 177);'],
['Warning', 'background-color: rgb(241, 216, 111);'],
['Failure', 'background-color: rgb(255, 126, 98);'],
['Unsupported', 'background-color: rgb(211, 218, 230);'],
];
const policyStatusStyleMap: ReadonlyMap<string, string> = new Map<string, string>(
policyStatusToRGBColor
);
const expectedStatusColor: string = policyStatusStyleMap.get(status.textContent!) ?? '';
expect(status.textContent).toEqual(POLICY_STATUS_TO_TEXT[generatedPolicyStatuses[index]]);
expect(status.getAttribute('style')).toMatch(expectedStatusColor);
expect(
status.querySelector(
`[data-euiicon-type][color=${
POLICY_STATUS_TO_HEALTH_COLOR[generatedPolicyStatuses[index]]
}]`
)
).not.toBeNull();
});
});

Expand Down
Loading

0 comments on commit e9e5e63

Please sign in to comment.