[9.0] [Security Solution]: Add banner to promote prebuilt rule customization in ESS (#213750) (#213922)

# Backport

This will backport the following commits from `main` to `9.0`:
- [[Security Solution]: Add banner to promote prebuilt rule
customization in ESS
(#213750)](https://github.com/elastic/kibana/pull/213750)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Nikita
Indik","email":"nikita.indik@elastic.co"},"sourceCommit":{"committedDate":"2025-03-11T13:45:30Z","message":"[Security
Solution]: Add banner to promote prebuilt rule customization in ESS
(#213750)\n\n**Resolves:
https://github.com/elastic/kibana/issues/205594**\n\n##
Summary\n\n**Changes:**\n- Adds a banner to promote prebuilt rule
customization in ESS. Link\ncurrently leads to a 404 page since the blog
post is not yet published.\n(Serverless banner to be added later, after
April 1, when the blog post\nis published). Banner is dismissible. It's
state is stored in\nlocalStorage.\n<img width=\"1006\"
alt=\"Scherm­afbeelding 2025-03-11 om 12 25
45\"\nsrc=\"https://github.com/user-attachments/assets/41d83db9-4bc4-433e-a7e2-c5ef1049a20c\"\n/>\n\n\n
- A couple unrelated small changes:\n- Fixes spelling of singular/plural
for \"require\" in the upgrade flyout\n- Fixes horizontal line
misalignment in upgrade flyout. It was caused by\nan incorrect `css`
function import: `import { css } from\n'@emotion/css';` instead of
`import { css } from '@emotion/react';`\n\n<img width=\"653\"
alt=\"Scherm­afbeelding 2025-03-10 om 12 12
33\"\nsrc=\"https://github.com/user-attachments/assets/ab5f3b9e-73b2-4938-bda2-401eece5407d\"\n/>\n<img
width=\"676\" alt=\"Scherm­afbeelding 2025-03-10 om 12 13
17\"\nsrc=\"https://github.com/user-attachments/assets/37bbff65-326f-415c-aab8-c9c661ef14ce\"\n/>\n\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 26
05\"\nsrc=\"https://github.com/user-attachments/assets/16ac2b9e-13ba-45d8-adcd-c9fb74f8db6e\"\n/>\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 24
54\"\nsrc=\"https://github.com/user-attachments/assets/c53e7642-26f5-490f-b1bc-6f3961aef71a\"\n/>","sha":"122c7e12e68bea74ec2c5c25674dd4a89583a64c","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Detections
and Resp","Team: SecuritySolution","Team:Detection Rule
Management","Feature:Prebuilt Detection
Rules","backport:version","v8.18.0","v9.1.0","v8.19.0"],"title":"[Security
Solution]: Add banner to promote prebuilt rule customization in
ESS","number":213750,"url":"https://github.com/elastic/kibana/pull/213750","mergeCommit":{"message":"[Security
Solution]: Add banner to promote prebuilt rule customization in ESS
(#213750)\n\n**Resolves:
https://github.com/elastic/kibana/issues/205594**\n\n##
Summary\n\n**Changes:**\n- Adds a banner to promote prebuilt rule
customization in ESS. Link\ncurrently leads to a 404 page since the blog
post is not yet published.\n(Serverless banner to be added later, after
April 1, when the blog post\nis published). Banner is dismissible. It's
state is stored in\nlocalStorage.\n<img width=\"1006\"
alt=\"Scherm­afbeelding 2025-03-11 om 12 25
45\"\nsrc=\"https://github.com/user-attachments/assets/41d83db9-4bc4-433e-a7e2-c5ef1049a20c\"\n/>\n\n\n
- A couple unrelated small changes:\n- Fixes spelling of singular/plural
for \"require\" in the upgrade flyout\n- Fixes horizontal line
misalignment in upgrade flyout. It was caused by\nan incorrect `css`
function import: `import { css } from\n'@emotion/css';` instead of
`import { css } from '@emotion/react';`\n\n<img width=\"653\"
alt=\"Scherm­afbeelding 2025-03-10 om 12 12
33\"\nsrc=\"https://github.com/user-attachments/assets/ab5f3b9e-73b2-4938-bda2-401eece5407d\"\n/>\n<img
width=\"676\" alt=\"Scherm­afbeelding 2025-03-10 om 12 13
17\"\nsrc=\"https://github.com/user-attachments/assets/37bbff65-326f-415c-aab8-c9c661ef14ce\"\n/>\n\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 26
05\"\nsrc=\"https://github.com/user-attachments/assets/16ac2b9e-13ba-45d8-adcd-c9fb74f8db6e\"\n/>\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 24
54\"\nsrc=\"https://github.com/user-attachments/assets/c53e7642-26f5-490f-b1bc-6f3961aef71a\"\n/>","sha":"122c7e12e68bea74ec2c5c25674dd4a89583a64c"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.18","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/213750","number":213750,"mergeCommit":{"message":"[Security
Solution]: Add banner to promote prebuilt rule customization in ESS
(#213750)\n\n**Resolves:
https://github.com/elastic/kibana/issues/205594**\n\n##
Summary\n\n**Changes:**\n- Adds a banner to promote prebuilt rule
customization in ESS. Link\ncurrently leads to a 404 page since the blog
post is not yet published.\n(Serverless banner to be added later, after
April 1, when the blog post\nis published). Banner is dismissible. It's
state is stored in\nlocalStorage.\n<img width=\"1006\"
alt=\"Scherm­afbeelding 2025-03-11 om 12 25
45\"\nsrc=\"https://github.com/user-attachments/assets/41d83db9-4bc4-433e-a7e2-c5ef1049a20c\"\n/>\n\n\n
- A couple unrelated small changes:\n- Fixes spelling of singular/plural
for \"require\" in the upgrade flyout\n- Fixes horizontal line
misalignment in upgrade flyout. It was caused by\nan incorrect `css`
function import: `import { css } from\n'@emotion/css';` instead of
`import { css } from '@emotion/react';`\n\n<img width=\"653\"
alt=\"Scherm­afbeelding 2025-03-10 om 12 12
33\"\nsrc=\"https://github.com/user-attachments/assets/ab5f3b9e-73b2-4938-bda2-401eece5407d\"\n/>\n<img
width=\"676\" alt=\"Scherm­afbeelding 2025-03-10 om 12 13
17\"\nsrc=\"https://github.com/user-attachments/assets/37bbff65-326f-415c-aab8-c9c661ef14ce\"\n/>\n\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 26
05\"\nsrc=\"https://github.com/user-attachments/assets/16ac2b9e-13ba-45d8-adcd-c9fb74f8db6e\"\n/>\n<img
width=\"1966\" alt=\"Scherm­afbeelding 2025-03-10 om 12 24
54\"\nsrc=\"https://github.com/user-attachments/assets/c53e7642-26f5-490f-b1bc-6f3961aef71a\"\n/>","sha":"122c7e12e68bea74ec2c5c25674dd4a89583a64c"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Nikita Indik <nikita.indik@elastic.co>
This commit is contained in:
Kibana Machine 2025-03-12 02:30:57 +11:00 committed by GitHub
parent 2fef7f5581
commit 52f23ee058
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 139 additions and 2 deletions

View file

@ -448,6 +448,9 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
updatePrebuiltDetectionRules: isServerless
? `${SERVERLESS_DOCS}security-prebuilt-rules-management.html#update-prebuilt-rules`
: `${SECURITY_SOLUTION_DOCS}prebuilt-rules-management.html#update-prebuilt-rules`,
prebuiltRuleCustomizationPromoBlog: isServerless
? '' // URL for Serverless to be added later, once the blog post is published. Issue: https://github.com/elastic/kibana/issues/209000
: `${ELASTIC_WEBSITE_URL}blog/security-prebuilt-rules-editing`,
createEsqlRuleType: `${SECURITY_SOLUTION_DOCS}rules-ui-create.html#create-esql-rule`,
ruleUiAdvancedParams: `${SECURITY_SOLUTION_DOCS}rules-ui-create.html#rule-ui-advanced-params`,
entityAnalytics: {

View file

@ -312,6 +312,7 @@ export interface DocLinks {
readonly manageDetectionRules: string;
readonly createDetectionRules: string;
readonly updatePrebuiltDetectionRules: string;
readonly prebuiltRuleCustomizationPromoBlog: string;
readonly createEsqlRuleType: string;
readonly ruleUiAdvancedParams: string;
readonly entityAnalytics: {

View file

@ -8,7 +8,7 @@
import type { PropsWithChildren } from 'react';
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/css';
import { css } from '@emotion/react';
export function FieldUpgradeSideHeader({ children }: PropsWithChildren<{}>) {
const { euiTheme } = useEuiTheme();

View file

@ -14,7 +14,7 @@ import { useKibana } from '../../../../../../common/lib/kibana/kibana_react';
export const TOTAL_NUM_OF_FIELDS = (count: number) => (
<FormattedMessage
id="xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.totalNumOfFieldsWithUpdates"
defaultMessage="{countValue} {count, plural, one {field} other {fields}} require review"
defaultMessage="{countValue} {count, plural, one {field} other {fields}} {count, plural, one {requires} other {require}} review"
values={{ countValue: <strong>{count}</strong>, count }}
/>
);

View file

@ -36,6 +36,7 @@ import { RulesTableContextProvider } from '../../components/rules_table/rules_ta
import { useInvalidateFetchCoverageOverviewQuery } from '../../../rule_management/api/hooks/use_fetch_coverage_overview_query';
import { HeaderPage } from '../../../../common/components/header_page';
import { RuleUpdateCallouts } from '../../components/rule_update_callouts/rule_update_callouts';
import { BlogPostPrebuiltRuleCustomizationCallout } from '../../../../detections/components/callouts/blog_post_prebuilt_rule_customization_callout';
const RulesPageComponent: React.FC = () => {
const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState();
@ -175,6 +176,7 @@ const RulesPageComponent: React.FC = () => {
kibanaServices={kibanaServices}
categories={[DEFAULT_APP_CATEGORIES.security.id]}
/>
<BlogPostPrebuiltRuleCustomizationCallout />
<AllRules data-test-subj="all-rules" />
</SecuritySolutionPageWrapper>
</RulesTableContextProvider>

View file

@ -0,0 +1,38 @@
/*
* 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 { EuiCallOut, useEuiTheme, type EuiCallOutProps } from '@elastic/eui';
import { css } from '@emotion/react';
interface BackgroundImageCalloutProps extends EuiCallOutProps {
backgroundImage: string;
description: JSX.Element;
}
export function BackgroundImageCallout({
description,
backgroundImage,
...euiCalloutProps
}: BackgroundImageCalloutProps) {
const { euiTheme } = useEuiTheme();
return (
<EuiCallOut
css={css`
padding-left: ${euiTheme.size.xl};
background-image: url(${backgroundImage});
background-repeat: no-repeat;
background-position-x: right;
background-position-y: bottom;
`}
{...euiCalloutProps}
>
{description}
</EuiCallOut>
);
}

View file

@ -0,0 +1,63 @@
/*
* 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 avcBannerBackground from '@kbn/avc-banner/src/avc_banner_background.svg';
import { EuiSpacer, EuiButton } from '@elastic/eui';
import { type CallOutMessage } from '../../../../common/components/callouts';
import { useCallOutStorage } from '../../../../common/components/callouts/use_callout_storage';
import * as i18n from './translations';
import { useKibana } from '../../../../common/lib/kibana';
import { BackgroundImageCallout } from '../background_image_callout';
export function BlogPostPrebuiltRuleCustomizationCallout() {
// URL is currently only available in ESS. So we are only showing this callout in ESS for now.
const blogPostUrl =
useKibana().services.docLinks.links.securitySolution.prebuiltRuleCustomizationPromoBlog;
const calloutMessage: CallOutMessage = useMemo(
() => ({
type: 'success',
id: 'blog-post-elastic-security-prebuilt-rule-customization',
title: i18n.CALLOUT_TITLE,
description: (
<>
{i18n.CALLOUT_DESCRIPTION}
<EuiSpacer size="s" />
<EuiButton size="s" color="success" href={blogPostUrl} target="_blank">
{i18n.CALLOUT_ACTION_BUTTON_LABEL}
</EuiButton>
</>
),
}),
[blogPostUrl]
);
const { isVisible, dismiss } = useCallOutStorage([calloutMessage], 'detections');
const handleDismiss = useCallback(() => {
dismiss(calloutMessage);
}, [dismiss, calloutMessage]);
if (blogPostUrl && isVisible(calloutMessage)) {
return (
<>
<BackgroundImageCallout
backgroundImage={avcBannerBackground}
title={calloutMessage.title}
description={calloutMessage.description}
color={calloutMessage.type}
iconType="cheer"
onDismiss={handleDismiss}
/>
<EuiSpacer size="l" />
</>
);
}
return null;
}

View file

@ -0,0 +1,30 @@
/*
* 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 CALLOUT_TITLE = i18n.translate(
'xpack.securitySolution.detectionEngine.blogPostPrebuiltRuleCustomizationCallout.calloutTitle',
{
defaultMessage: 'Get more value out of Elastic prebuilt rules!',
}
);
export const CALLOUT_DESCRIPTION = i18n.translate(
'xpack.securitySolution.detectionEngine.blogPostPrebuiltRuleCustomizationCallout.calloutDescription',
{
defaultMessage:
'Learn how to customize prebuilt rules and update them with the latest improvements.',
}
);
export const CALLOUT_ACTION_BUTTON_LABEL = i18n.translate(
'xpack.securitySolution.detectionEngine.blogPostPrebuiltRuleCustomizationCallout.calloutButtonLabel',
{
defaultMessage: 'Read the blog',
}
);