Skip to content

Commit

Permalink
[Security Solution][Endpoint] New endpoint policy response UI and fle…
Browse files Browse the repository at this point in the history
…et UI for integrations in agent details page (elastic#133405)
  • Loading branch information
dasansol92 authored and Muhammad Ibragimov committed Jun 7, 2022
1 parent 8604512 commit 9e35071
Show file tree
Hide file tree
Showing 10 changed files with 518 additions and 318 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* 2.0.
*/

import React, { memo, useMemo } from 'react';
import type { EuiBasicTableProps } from '@elastic/eui';
import React, { memo, useMemo, useState } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
Expand All @@ -15,25 +14,40 @@ import {
EuiTitle,
EuiToolTip,
EuiPanel,
EuiButtonIcon,
EuiBasicTable,
EuiSpacer,
EuiText,
EuiTreeView,
EuiBadge,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import styled from 'styled-components';

import type { Agent, AgentPolicy, PackagePolicy, PackagePolicyInput } from '../../../../../types';
import type { Agent, AgentPolicy, PackagePolicy } from '../../../../../types';
import { useLink, useUIExtension } from '../../../../../hooks';
import { ExtensionWrapper, PackageIcon } from '../../../../../components';

import { displayInputType, getLogsQueryByInputType } from './input_type_utils';

const StyledEuiAccordion = styled(EuiAccordion)`
.ingest-integration-title-button {
padding: ${(props) => props.theme.eui.paddingSizes.m};
.euiAccordion__button {
width: 90%;
}
.euiAccordion__triggerWrapper {
padding-left: ${(props) => props.theme.eui.paddingSizes.m};
}
&.euiAccordion-isOpen {
.euiAccordion__childWrapper {
padding: ${(props) => props.theme.eui.paddingSizes.m};
padding-top: 0px;
}
}
&.euiAccordion-isOpen .ingest-integration-title-button {
border-bottom: 1px solid ${(props) => props.theme.eui.euiColorLightShade};
.ingest-integration-title-button {
padding: ${(props) => props.theme.eui.paddingSizes.s};
}
.euiTableRow:last-child .euiTableRowCell {
Expand All @@ -43,6 +57,14 @@ const StyledEuiAccordion = styled(EuiAccordion)`
.euiIEFlexWrapFix {
min-width: 0;
}
.euiAccordion__buttonContent {
width: 100%;
}
`;

const StyledEuiLink = styled(EuiLink)`
font-size: ${(props) => props.theme.eui.euiFontSizeS};
`;

const CollapsablePanel: React.FC<{ id: string; title: React.ReactNode }> = ({
Expand All @@ -54,7 +76,7 @@ const CollapsablePanel: React.FC<{ id: string; title: React.ReactNode }> = ({
<EuiPanel paddingSize="none">
<StyledEuiAccordion
id={id}
arrowDisplay="right"
arrowDisplay="left"
buttonClassName="ingest-integration-title-button"
buttonContent={title}
>
Expand All @@ -70,55 +92,75 @@ export const AgentDetailsIntegration: React.FunctionComponent<{
packagePolicy: PackagePolicy;
}> = memo(({ agent, agentPolicy, packagePolicy }) => {
const { getHref } = useLink();
const theme = useEuiTheme();

const [showNeedsAttentionBadge, setShowNeedsAttentionBadge] = useState(false);
const extensionView = useUIExtension(
packagePolicy.package?.name ?? '',
'package-policy-response'
);

const inputs = useMemo(() => {
return packagePolicy.inputs.filter((input) => input.enabled);
}, [packagePolicy.inputs]);
const policyResponseExtensionView = useMemo(() => {
return (
extensionView && (
<ExtensionWrapper>
<extensionView.Component
agent={agent}
onShowNeedsAttentionBadge={setShowNeedsAttentionBadge}
/>
</ExtensionWrapper>
)
);
}, [agent, extensionView]);

const columns: EuiBasicTableProps<PackagePolicyInput>['columns'] = [
const inputItems = [
{
field: 'type',
width: '100%',
name: i18n.translate('xpack.fleet.agentDetailsIntegrations.inputTypeLabel', {
defaultMessage: 'Input',
}),
render: (inputType: string) => {
return displayInputType(inputType);
},
},
{
align: 'right',
name: i18n.translate('xpack.fleet.agentDetailsIntegrations.actionsLabel', {
defaultMessage: 'Actions',
}),
field: 'type',
width: 'auto',
render: (inputType: string) => {
return (
<EuiToolTip
content={i18n.translate('xpack.fleet.agentDetailsIntegrations.viewLogsButton', {
defaultMessage: 'View logs',
})}
>
<EuiButtonIcon
href={getHref('agent_details', {
agentId: agent.id,
tabId: 'logs',
logQuery: getLogsQueryByInputType(inputType),
})}
iconType="editorAlignLeft"
aria-label={i18n.translate('xpack.fleet.agentDetailsIntegrations.viewLogsButton', {
defaultMessage: 'View logs',
})}
/>
</EuiToolTip>
);
},
label: (
<EuiText size="s">
<FormattedMessage
id="xpack.fleet.agentDetailsIntegrations.inputsTypeLabel"
defaultMessage="Inputs"
/>
</EuiText>
),
id: 'inputs',
children: packagePolicy.inputs.reduce(
(acc: Array<{ label: JSX.Element; id: string }>, current) => {
if (current.enabled) {
return [
...acc,
{
label: (
<EuiToolTip
content={i18n.translate('xpack.fleet.agentDetailsIntegrations.viewLogsButton', {
defaultMessage: 'View logs',
})}
>
<StyledEuiLink
href={getHref('agent_details', {
agentId: agent.id,
tabId: 'logs',
logQuery: getLogsQueryByInputType(current.type),
})}
aria-label={i18n.translate(
'xpack.fleet.agentDetailsIntegrations.viewLogsButton',
{
defaultMessage: 'View logs',
}
)}
>
{displayInputType(current.type)}
</StyledEuiLink>
</EuiToolTip>
),
id: current.type,
},
];
}
return acc;
},
[]
),
},
];

Expand All @@ -128,7 +170,7 @@ export const AgentDetailsIntegration: React.FunctionComponent<{
title={
<EuiTitle size="xs">
<h3>
<EuiFlexGroup gutterSize="s">
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
{packagePolicy.package ? (
<PackageIcon
Expand All @@ -153,17 +195,29 @@ export const AgentDetailsIntegration: React.FunctionComponent<{
{packagePolicy.name}
</EuiLink>
</EuiFlexItem>
{showNeedsAttentionBadge && (
<EuiFlexItem grow={false}>
<EuiBadge color={theme.euiTheme.colors.danger} iconType="alert" iconSide="left">
<FormattedMessage
id="xpack.fleet.agentDetailsIntegrations.needsAttention.label"
defaultMessage="Needs attention"
/>
</EuiBadge>
</EuiFlexItem>
)}
</EuiFlexGroup>
</h3>
</EuiTitle>
}
>
<EuiBasicTable<PackagePolicyInput> tableLayout="auto" items={inputs} columns={columns} />
{extensionView && (
<ExtensionWrapper>
<extensionView.Component endpointId={agent.id} />
</ExtensionWrapper>
)}
<EuiTreeView
items={inputItems}
showExpansionArrows
aria-label="inputsTreeView"
aria-labelledby="inputsTreeView"
/>
{policyResponseExtensionView}
<EuiSpacer />
</CollapsablePanel>
);
});
Expand Down
8 changes: 5 additions & 3 deletions x-pack/plugins/fleet/public/types/ui_extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import type { EuiStepProps } from '@elastic/eui';
import type { ComponentType, LazyExoticComponent } from 'react';

import type { NewPackagePolicy, PackageInfo, PackagePolicy } from '.';
import type { Agent, NewPackagePolicy, PackageInfo, PackagePolicy } from '.';

/** Register a Fleet UI extension */
export type UIExtensionRegistrationCallback = (extensionPoint: UIExtensionPoint) => void;
Expand Down Expand Up @@ -54,8 +54,10 @@ export type PackagePolicyResponseExtensionComponent =
ComponentType<PackagePolicyResponseExtensionComponentProps>;

export interface PackagePolicyResponseExtensionComponentProps {
/** The current host id to retrieve response from */
endpointId: string;
/** The current agent to retrieve response from */
agent: Agent;
/** A callback function to set the `needs attention` state */
onShowNeedsAttentionBadge?: (val: boolean) => void;
}

/** Extension point registration contract for Integration Policy Edit views */
Expand Down
Loading

0 comments on commit 9e35071

Please sign in to comment.