mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Security Solution]: Add banner to promote prebuilt rule customization in ESS (#213750)
**Resolves: https://github.com/elastic/kibana/issues/205594** ## Summary **Changes:** - Adds a banner to promote prebuilt rule customization in ESS. Link currently leads to a 404 page since the blog post is not yet published. (Serverless banner to be added later, after April 1, when the blog post is published). Banner is dismissible. It's state is stored in localStorage. <img width="1006" alt="Schermafbeelding 2025-03-11 om 12 25 45" src="https://github.com/user-attachments/assets/41d83db9-4bc4-433e-a7e2-c5ef1049a20c" /> - A couple unrelated small changes: - Fixes spelling of singular/plural for "require" in the upgrade flyout - Fixes horizontal line misalignment in upgrade flyout. It was caused by an incorrect `css` function import: `import { css } from '@emotion/css';` instead of `import { css } from '@emotion/react';` <img width="653" alt="Schermafbeelding 2025-03-10 om 12 12 33" src="https://github.com/user-attachments/assets/ab5f3b9e-73b2-4938-bda2-401eece5407d" /> <img width="676" alt="Schermafbeelding 2025-03-10 om 12 13 17" src="https://github.com/user-attachments/assets/37bbff65-326f-415c-aab8-c9c661ef14ce" /> <img width="1966" alt="Schermafbeelding 2025-03-10 om 12 26 05" src="https://github.com/user-attachments/assets/16ac2b9e-13ba-45d8-adcd-c9fb74f8db6e" /> <img width="1966" alt="Schermafbeelding 2025-03-10 om 12 24 54" src="https://github.com/user-attachments/assets/c53e7642-26f5-490f-b1bc-6f3961aef71a" />
This commit is contained in:
parent
aa850d4b9f
commit
122c7e12e6
8 changed files with 139 additions and 2 deletions
|
@ -449,6 +449,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: {
|
||||
|
|
|
@ -313,6 +313,7 @@ export interface DocLinks {
|
|||
readonly manageDetectionRules: string;
|
||||
readonly createDetectionRules: string;
|
||||
readonly updatePrebuiltDetectionRules: string;
|
||||
readonly prebuiltRuleCustomizationPromoBlog: string;
|
||||
readonly createEsqlRuleType: string;
|
||||
readonly ruleUiAdvancedParams: string;
|
||||
readonly entityAnalytics: {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 }}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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',
|
||||
}
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue