forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request elastic#9 from agusruidiazgd/feat/onboarding_hub_n…
…ew_cards Onboarding hub new cards content
- Loading branch information
Showing
48 changed files
with
1,294 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...y_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
import React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
import { AlertsCard } from './alerts_card'; | ||
import { TestProviders } from '../../../../../common/mock'; | ||
|
||
const props = { | ||
setComplete: jest.fn(), | ||
checkComplete: jest.fn(), | ||
isCardComplete: jest.fn(), | ||
setExpandedCardId: jest.fn(), | ||
}; | ||
|
||
describe('AlertsCard', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('description should be in the document', () => { | ||
const { getByTestId } = render( | ||
<TestProviders> | ||
<AlertsCard {...props} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(getByTestId('alertsCardDescription')).toBeInTheDocument(); | ||
}); | ||
|
||
it('card callout should be rendered if integrations cards is not complete', () => { | ||
props.isCardComplete.mockReturnValueOnce(false); | ||
|
||
const { getByText } = render( | ||
<TestProviders> | ||
<AlertsCard {...props} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(getByText('To view alerts add integrations first.')).toBeInTheDocument(); | ||
}); | ||
|
||
it('card button should be disabled if integrations cards is not complete', () => { | ||
props.isCardComplete.mockReturnValueOnce(false); | ||
|
||
const { getByTestId } = render( | ||
<TestProviders> | ||
<AlertsCard {...props} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(getByTestId('alertsCardButton').querySelector('button')).toBeDisabled(); | ||
}); | ||
}); |
82 changes: 82 additions & 0 deletions
82
...curity_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React, { useCallback, useMemo } from 'react'; | ||
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; | ||
import { SecurityPageName } from '@kbn/security-solution-navigation'; | ||
import { SecuritySolutionLinkButton } from '../../../../../common/components/links'; | ||
import { OnboardingCardId } from '../../../../constants'; | ||
import type { OnboardingCardComponent } from '../../../../types'; | ||
import { OnboardingCardContentImagePanel } from '../common/card_content_image_panel'; | ||
import { CardCallOut } from '../common/card_callout'; | ||
import alertsImageSrc from './images/alerts.png'; | ||
import * as i18n from './translations'; | ||
|
||
export const AlertsCard: OnboardingCardComponent = ({ | ||
isCardComplete, | ||
setExpandedCardId, | ||
setComplete, | ||
}) => { | ||
const isIntegrationsCardComplete = useMemo( | ||
() => isCardComplete(OnboardingCardId.integrations), | ||
[isCardComplete] | ||
); | ||
|
||
const expandIntegrationsCard = useCallback(() => { | ||
setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); | ||
}, [setExpandedCardId]); | ||
|
||
return ( | ||
<OnboardingCardContentImagePanel imageSrc={alertsImageSrc} imageAlt={i18n.ALERTS_CARD_TITLE}> | ||
<EuiFlexGroup | ||
direction="column" | ||
gutterSize="xl" | ||
justifyContent="flexStart" | ||
alignItems="flexStart" | ||
> | ||
<EuiFlexItem grow={false}> | ||
<EuiText data-test-subj="alertsCardDescription" size="s" color="subdued"> | ||
{i18n.ALERTS_CARD_DESCRIPTION} | ||
</EuiText> | ||
{!isIntegrationsCardComplete && ( | ||
<> | ||
<EuiSpacer size="m" /> | ||
<CardCallOut | ||
color="primary" | ||
icon="iInCircle" | ||
text={i18n.ALERTS_CARD_CALLOUT_INTEGRATIONS_TEXT} | ||
action={ | ||
<EuiLink onClick={expandIntegrationsCard}> | ||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="center"> | ||
<EuiFlexItem>{i18n.ALERTS_CARD_CALLOUT_INTEGRATIONS_BUTTON}</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiIcon type="arrowRight" color="primary" size="s" /> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiLink> | ||
} | ||
/> | ||
</> | ||
)} | ||
</EuiFlexItem> | ||
<EuiFlexItem data-test-subj="alertsCardButton" grow={false}> | ||
<SecuritySolutionLinkButton | ||
onClick={() => setComplete(true)} | ||
deepLinkId={SecurityPageName.alerts} | ||
fill | ||
isDisabled={!isIntegrationsCardComplete} | ||
> | ||
{i18n.ALERTS_CARD_VIEW_ALERTS_BUTTON} | ||
</SecuritySolutionLinkButton> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</OnboardingCardContentImagePanel> | ||
); | ||
}; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default AlertsCard; |
Binary file added
BIN
+65.9 KB
...ion/public/onboarding/components/onboarding_body/cards/alerts/images/alerts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+3.21 KB
...ublic/onboarding/components/onboarding_body/cards/alerts/images/alerts_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions
19
...gins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
import type { OnboardingCardConfig } from '../../../../types'; | ||
import { OnboardingCardId } from '../../../../constants'; | ||
import { ALERTS_CARD_TITLE } from './translations'; | ||
import alertsIcon from './images/alerts_icon.png'; | ||
|
||
export const alertsCardConfig: OnboardingCardConfig = { | ||
id: OnboardingCardId.alerts, | ||
title: ALERTS_CARD_TITLE, | ||
icon: alertsIcon, | ||
Component: React.lazy(() => import('./alerts_card')), | ||
}; |
44 changes: 44 additions & 0 deletions
44
...curity_solution/public/onboarding/components/onboarding_body/cards/alerts/translations.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { i18n } from '@kbn/i18n'; | ||
|
||
export const ALERTS_CARD_TITLE = i18n.translate( | ||
'xpack.securitySolution.onboarding.alertsCard.title', | ||
{ | ||
defaultMessage: 'View alerts', | ||
} | ||
); | ||
|
||
export const ALERTS_CARD_DESCRIPTION = i18n.translate( | ||
'xpack.securitySolution.onboarding.alertsCard.description', | ||
{ | ||
defaultMessage: | ||
'Visualize, sort, filter, and investigate alerts from across your infrastructure. Examine individual alerts of interest, and discover general patterns in alert volume and severity.', | ||
} | ||
); | ||
|
||
export const ALERTS_CARD_CALLOUT_INTEGRATIONS_TEXT = i18n.translate( | ||
'xpack.securitySolution.onboarding.alertsCard.calloutIntegrationsText', | ||
{ | ||
defaultMessage: 'To view alerts add integrations first.', | ||
} | ||
); | ||
|
||
export const ALERTS_CARD_CALLOUT_INTEGRATIONS_BUTTON = i18n.translate( | ||
'xpack.securitySolution.onboarding.alertsCard.calloutIntegrationsButton', | ||
{ | ||
defaultMessage: 'Add integrations step', | ||
} | ||
); | ||
|
||
export const ALERTS_CARD_VIEW_ALERTS_BUTTON = i18n.translate( | ||
'xpack.securitySolution.onboarding.alertsCard.viewAlertsButton', | ||
{ | ||
defaultMessage: 'View alerts', | ||
} | ||
); |
77 changes: 77 additions & 0 deletions
77
..._solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_card.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React, { useCallback, useMemo } from 'react'; | ||
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiText } from '@elastic/eui'; | ||
import { css } from '@emotion/css'; | ||
import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; | ||
import { OnboardingCardId } from '../../../../constants'; | ||
import type { OnboardingCardComponent } from '../../../../types'; | ||
import * as i18n from './translations'; | ||
import { OnboardingCardContentPanel } from '../common/card_content_panel'; | ||
import { ConnectorCards } from './components/connectors/connector_cards'; | ||
import { CardCallOut } from '../common/card_callout'; | ||
|
||
export const AssistantCard: OnboardingCardComponent = ({ | ||
isCardComplete, | ||
setExpandedCardId, | ||
checkCompleteMetadata, | ||
checkComplete, | ||
}) => { | ||
const isIntegrationsCardComplete = useMemo( | ||
() => isCardComplete(OnboardingCardId.integrations), | ||
[isCardComplete] | ||
); | ||
|
||
const expandIntegrationsCard = useCallback(() => { | ||
setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); | ||
}, [setExpandedCardId]); | ||
|
||
const aiConnectors = checkCompleteMetadata?.connectors as AIConnector[]; | ||
|
||
return ( | ||
<OnboardingCardContentPanel style={{ paddingTop: 0 }}> | ||
<EuiFlexGroup direction="column"> | ||
<EuiFlexItem grow={false}> | ||
<EuiText size="s" color="subdued"> | ||
{i18n.ASSISTANT_CARD_DESCRIPTION} | ||
</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
{isIntegrationsCardComplete ? ( | ||
<ConnectorCards connectors={aiConnectors} onConnectorSaved={checkComplete} /> | ||
) : ( | ||
<EuiFlexItem | ||
className={css` | ||
width: 45%; | ||
`} | ||
> | ||
<CardCallOut | ||
color="primary" | ||
icon="iInCircle" | ||
text={i18n.ASSISTANT_CARD_CALLOUT_INTEGRATIONS_TEXT} | ||
action={ | ||
<EuiLink onClick={expandIntegrationsCard}> | ||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="center"> | ||
<EuiFlexItem>{i18n.ASSISTANT_CARD_CALLOUT_INTEGRATIONS_BUTTON}</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiIcon type="arrowRight" color="primary" size="s" /> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiLink> | ||
} | ||
/> | ||
</EuiFlexItem> | ||
)} | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</OnboardingCardContentPanel> | ||
); | ||
}; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default AssistantCard; |
39 changes: 39 additions & 0 deletions
39
.../public/onboarding/components/onboarding_body/cards/assistant/assistant_check_complete.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { loadAllActions as loadConnectors } from '@kbn/triggers-actions-ui-plugin/public/common/constants'; | ||
import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; | ||
import { i18n } from '@kbn/i18n'; | ||
import type { OnboardingCardCheckComplete } from '../../../../types'; | ||
import { AllowedActionTypeIds } from './constants'; | ||
|
||
export const checkAssistantCardComplete: OnboardingCardCheckComplete = async ({ http }) => { | ||
const allConnectors = await loadConnectors({ http }); | ||
|
||
const aiConnectors = allConnectors.reduce((acc: AIConnector[], connector) => { | ||
if (!connector.isMissingSecrets && AllowedActionTypeIds.includes(connector.actionTypeId)) { | ||
acc.push(connector); | ||
} | ||
return acc; | ||
}, []); | ||
|
||
const completeBadgeText = i18n.translate( | ||
'xpack.securitySolution.onboarding.assistantCard.badge.completeText', | ||
{ | ||
defaultMessage: '{count} AI {count, plural, one {connector} other {connectors}} added', | ||
values: { count: aiConnectors.length }, | ||
} | ||
); | ||
|
||
return { | ||
isComplete: aiConnectors.length > 0, | ||
completeBadgeText, | ||
metadata: { | ||
connectors: aiConnectors, | ||
}, | ||
}; | ||
}; |
Oops, something went wrong.