[SecuritySolution] Create integration link added to Security onboarding page (#187201)

## Summary

Link panel to go to create integrations added. It is a compressed
version of the link card displayed on the integrations page. The
integration creation feature is not enabled by default, to enable the
feature:
```
xpack.integration_assistant.enabled: true
```


![link](2532819e-da6e-4d2f-ab07-45042d6a069f)

When the integrationAssistant plugin is not enabled (default) the link
does not appear.


![no_link](82cc67b1-ce16-4fd8-ad59-f8a4d4cd31fb)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Sergi Massaneda 2024-07-01 13:58:27 +02:00 committed by GitHub
parent 1eb7a5ee0b
commit fc02b21daf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 85 additions and 51 deletions

View file

@ -81,7 +81,7 @@ export const DefaultLayout: React.FC<Props> = memo(
rightColumn={
CreateIntegrationCardButton ? (
<EuiFlexItem grow={false}>
<CreateIntegrationCardButton href={getHref('integration_create')} />
<CreateIntegrationCardButton />
</EuiFlexItem>
) : undefined
}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React from 'react';
import React, { useCallback, useMemo } from 'react';
import {
EuiLink,
EuiPanel,
@ -15,41 +15,53 @@ import {
EuiIcon,
EuiText,
EuiTitle,
useEuiTheme,
useEuiPaddingCSS,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
import integrationsImage from '../../common/images/integrations_light.svg';
import { useKibana } from '../../common/hooks/use_kibana';
const useStyles = () => {
const { euiTheme } = useEuiTheme();
const useStyles = (compressed: boolean) => {
const paddings = useEuiPaddingCSS();
return {
image: css`
width: 160px;
height: 155px;
width: ${compressed ? '140px' : '160px'};
height: ${compressed ? '90px' : '155px'};
object-fit: cover;
object-position: left center;
`,
container: css`
height: 135px;
height: ${compressed ? '80px' : '135px'};
`,
textContainer: css`
height: 100%;
padding: ${euiTheme.size.l} 0 ${euiTheme.size.l} ${euiTheme.size.l};
${compressed ? `${paddings.m.styles}` : `${paddings.l.styles} padding-right: 0;`}
`,
};
};
export interface CreateIntegrationCardButtonProps {
href: string;
compressed?: boolean;
}
export const CreateIntegrationCardButton = React.memo<CreateIntegrationCardButtonProps>(
({ href }) => {
const styles = useStyles();
({ compressed = false }) => {
const { getUrlForApp, navigateToUrl } = useKibana().services.application;
const styles = useStyles(compressed);
const href = useMemo(() => getUrlForApp('integrations', { path: '/create' }), [getUrlForApp]);
const navigate = useCallback(
(ev) => {
ev.preventDefault();
navigateToUrl(href);
},
[href, navigateToUrl]
);
return (
<EuiPanel hasShadow={false} hasBorder paddingSize="none">
<EuiFlexGroup
justifyContent="flexEnd"
justifyContent="spaceBetween"
gutterSize="none"
css={styles.container}
responsive={false}
@ -70,18 +82,26 @@ export const CreateIntegrationCardButton = React.memo<CreateIntegrationCardButto
/>
</h2>
</EuiTitle>
<EuiText size="s">
<FormattedMessage
id="xpack.integrationAssistant.createIntegrationDescription"
defaultMessage="Create a custom one to fit your requirements"
/>
</EuiText>
{!compressed && (
<EuiText size="s">
<FormattedMessage
id="xpack.integrationAssistant.createIntegrationDescription"
defaultMessage="Create a custom one to fit your requirements"
/>
</EuiText>
)}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiLink color="primary" href={href}>
<EuiFlexGroup justifyContent="center" gutterSize="s" responsive={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiLink color="primary" href={href} onClick={navigate}>
<EuiFlexGroup
justifyContent="center"
alignItems="center"
gutterSize={compressed ? 'xs' : 's'}
responsive={false}
>
<EuiFlexItem grow={false}>
<EuiIcon type="plusInCircle" />
<EuiIcon type="plusInCircle" size={compressed ? 's' : 'm'} />
</EuiFlexItem>
<EuiFlexItem>
<FormattedMessage

View file

@ -70,7 +70,8 @@
"dataViewFieldEditor",
"osquery",
"savedObjectsTaggingOss",
"guidedOnboarding"
"guidedOnboarding",
"integrationAssistant"
],
"requiredBundles": [
"esUiShared",

View file

@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
import { LinkButton } from '@kbn/security-solution-navigation/links';
import type { IconType } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPanel, EuiText, EuiTitle } from '@elastic/eui';
import { useKibana } from '../../../../lib/kibana/kibana_react';
import { AddIntegrationsSteps } from '../types';
import { useStepContext } from '../context/step_context';
import { IntegrationsPageName } from './types';
@ -153,32 +154,41 @@ const AddIntegrationPanel: React.FC<{
});
AddIntegrationPanel.displayName = 'AddIntegrationPanel';
export const AddIntegrationButtons: React.FC = React.memo(() => (
<EuiFlexGroup direction="column" className="step-paragraph" gutterSize="m">
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_CLOUD_INTEGRATIONS_TITLE}
description={ADD_CLOUD_INTEGRATIONS_DESCRIPTION}
icon={CloudIntegrationsIcon}
buttonId={IntegrationsPageName.integrationsSecurityCloud}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_EDR_XDR_INTEGRATIONS_TITLE}
description={ADD_EDR_XDR_INTEGRATIONS_DESCRIPTION}
icon={EdrXdrIntegrationsIcon}
buttonId={IntegrationsPageName.integrationsSecurityEdrXrd}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_ALL_INTEGRATIONS_TITLE}
description={ADD_ALL_INTEGRATIONS_DESCRIPTION}
icon="logoSecurity"
buttonId={IntegrationsPageName.integrationsSecurity}
/>
</EuiFlexItem>
</EuiFlexGroup>
));
export const AddIntegrationButtons: React.FC = React.memo(() => {
const { integrationAssistant } = useKibana().services;
const CreateIntegrationCardButton = integrationAssistant?.CreateIntegrationCardButton;
return (
<EuiFlexGroup direction="column" className="step-paragraph" gutterSize="m">
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_CLOUD_INTEGRATIONS_TITLE}
description={ADD_CLOUD_INTEGRATIONS_DESCRIPTION}
icon={CloudIntegrationsIcon}
buttonId={IntegrationsPageName.integrationsSecurityCloud}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_EDR_XDR_INTEGRATIONS_TITLE}
description={ADD_EDR_XDR_INTEGRATIONS_DESCRIPTION}
icon={EdrXdrIntegrationsIcon}
buttonId={IntegrationsPageName.integrationsSecurityEdrXrd}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<AddIntegrationPanel
title={ADD_ALL_INTEGRATIONS_TITLE}
description={ADD_ALL_INTEGRATIONS_DESCRIPTION}
icon="logoSecurity"
buttonId={IntegrationsPageName.integrationsSecurity}
/>
</EuiFlexItem>
{CreateIntegrationCardButton && (
<EuiFlexItem grow={false}>
<CreateIntegrationCardButton compressed />
</EuiFlexItem>
)}
</EuiFlexGroup>
);
});
AddIntegrationButtons.displayName = 'AddIntegrationButtons';

View file

@ -60,6 +60,7 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public';
import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public';
import type { PluginStartContract } from '@kbn/alerting-plugin/public/plugin';
import type { MapsStartApi } from '@kbn/maps-plugin/public';
import type { IntegrationAssistantPluginStart } from '@kbn/integration-assistant-plugin/public';
import type { ResolverPluginSetup } from './resolver/types';
import type { Inspect } from '../common/search_strategy';
import type { Detections } from './detections';
@ -152,6 +153,7 @@ export interface StartPlugins {
savedSearch: SavedSearchPublicPluginStart;
alerting: PluginStartContract;
core: CoreStart;
integrationAssistant?: IntegrationAssistantPluginStart;
}
export interface StartPluginsDependencies extends StartPlugins {

View file

@ -209,5 +209,6 @@
"@kbn/core-analytics-browser",
"@kbn/core-i18n-browser",
"@kbn/core-theme-browser",
"@kbn/integration-assistant-plugin",
]
}