From 835141857a1b3d55a6cbf42ca2a67fea50347ead Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Thu, 23 Jan 2025 18:45:01 +0100 Subject: [PATCH] [Rules migration] UI updates (#207789) ## Summary [Internal link](https://github.com/elastic/security-team/issues/10820) to the feature details This PR includes next improvements and fixes ### Improvements 1. Updated copies 2. Added `Last updated` label in Translation Rule details flyout Screenshot 2025-01-22 at 14 15 24 copy 3. Added rule installation information callout in Translation Rule details flyout Screenshot 2025-01-22 at 14 15 24 4. Added horizontal line underneath the Translation Rules header > [!NOTE] > This feature needs `siemMigrationsEnabled` experimental flag enabled to work. --- .../public/siem_migrations/links.ts | 3 +- .../components/rule_details_flyout/index.tsx | 4 +- .../tabs/translation/callout.tsx | 58 ++++++++++++------- .../tabs/translation/index.tsx | 17 +++++- .../tabs/translation/translations.ts | 23 ++++++++ .../rule_details_flyout/translations.ts | 7 +++ .../rule_details_flyout/updated_by/index.tsx | 54 +++++++++++++++++ .../updated_by/translations.ts | 15 +++++ .../siem_migrations/rules/pages/index.tsx | 2 +- .../rules/pages/page_title/index.tsx | 2 +- 10 files changed, 158 insertions(+), 27 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/index.tsx create mode 100644 x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/translations.ts diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 29d374713cf17..ede76286696cf 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -19,7 +19,8 @@ export const siemMigrationsLinks: LinkItem = { id: SecurityPageName.siemMigrationsRules, title: SIEM_MIGRATIONS_RULES, description: i18n.translate('xpack.securitySolution.appLinks.siemMigrationsRulesDescription', { - defaultMessage: 'SIEM Rule Migrations.', + defaultMessage: + 'Our generative AI powered SIEM migration tool automates some of the most time consuming migrations tasks and processed.', }), landingIcon: SiemMigrationsIcon, path: SIEM_MIGRATIONS_RULES_PATH, diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/index.tsx index 353b42a5f1337..bd03f05a40bba 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/index.tsx @@ -48,6 +48,7 @@ import { isMigrationCustomRule, } from '../../../../../common/siem_migrations/rules/utils'; import { useUpdateMigrationRules } from '../../logic/use_update_migration_rules'; +import { UpdatedByLabel } from './updated_by'; /* * Fixes tabs to the top and allows the content to scroll. @@ -244,7 +245,8 @@ export const MigrationRuleDetailsFlyout: React.FC - + + { - switch (translationResult) { - case RuleMigrationTranslationResultEnum.full: + switch (mode) { + case 'mapped': + return { + title: i18n.CALLOUT_MAPPED_TRANSLATED_RULE_TITLE, + icon: 'checkInCircleFilled', + color: 'success', + }; + case 'full': return { title: i18n.CALLOUT_TRANSLATED_RULE_TITLE, icon: 'checkInCircleFilled', color: 'success', }; - case RuleMigrationTranslationResultEnum.partial: + case 'partial': return { title: i18n.CALLOUT_PARTIALLY_TRANSLATED_RULE_TITLE, message: i18n.CALLOUT_PARTIALLY_TRANSLATED_RULE_DESCRIPTION, icon: 'warningFilled', color: 'warning', }; - case RuleMigrationTranslationResultEnum.untranslatable: + case 'untranslatable': return { title: i18n.CALLOUT_NOT_TRANSLATED_RULE_TITLE, message: i18n.CALLOUT_NOT_TRANSLATED_RULE_DESCRIPTION, @@ -43,23 +51,29 @@ const getCallOutInfo = ( }; export interface TranslationCallOutProps { - translationResult: RuleMigrationTranslationResult; + ruleMigration: RuleMigration; } -export const TranslationCallOut: FC = React.memo( - ({ translationResult }) => { - const { title, message, icon, color } = getCallOutInfo(translationResult); - - return ( - - {message} - - ); +export const TranslationCallOut: FC = React.memo(({ ruleMigration }) => { + if (!ruleMigration.translation_result) { + return null; } -); + + const mode = ruleMigration.elastic_rule?.prebuilt_rule_id + ? 'mapped' + : ruleMigration.translation_result; + const { title, message, icon, color } = getCallOutInfo(mode); + + return ( + + {message} + + ); +}); TranslationCallOut.displayName = 'TranslationCallOut'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/index.tsx index 182fb3c9fc048..c38bb9f4eded0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/index.tsx @@ -9,6 +9,7 @@ import React, { useMemo } from 'react'; import { EuiAccordion, EuiBadge, + EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer, @@ -18,6 +19,7 @@ import { } from '@elastic/eui'; import { css } from '@emotion/css'; import { FormattedMessage } from '@kbn/i18n-react'; +import { RuleTranslationResult } from '../../../../../../../common/siem_migrations/constants'; import type { RuleResponse } from '../../../../../../../common/api/detection_engine'; import type { RuleMigration } from '../../../../../../../common/siem_migrations/model/rule_migration.gen'; import { TranslationTabHeader } from './header'; @@ -78,7 +80,7 @@ export const TranslationTab: React.FC = React.memo( {ruleMigration.translation_result && !isInstalled && ( <> - + )} @@ -131,6 +133,19 @@ export const TranslationTab: React.FC = React.memo( + {ruleMigration.translation_result === RuleTranslationResult.FULL && ( + <> + + + {i18n.CALLOUT_TRANSLATED_RULE_INFO_DESCRIPTION} + + + )} ); } diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/translations.ts index 925c94d05ec12..1978a2ded474b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/tabs/translation/translations.ts @@ -85,6 +85,14 @@ export const CALLOUT_TRANSLATED_RULE_TITLE = i18n.translate( } ); +export const CALLOUT_MAPPED_TRANSLATED_RULE_TITLE = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.translationDetails.translationTab.mappedTranslatedRuleCalloutTitle', + { + defaultMessage: + 'This rule was mapped to an Elastic authored rule. Click Install & enable rule to complete migration. You can fine-tune it later.', + } +); + export const CALLOUT_PARTIALLY_TRANSLATED_RULE_TITLE = i18n.translate( 'xpack.securitySolution.siemMigrations.rules.translationDetails.translationTab.partiallyTranslatedRuleCalloutTitle', { @@ -114,3 +122,18 @@ export const CALLOUT_NOT_TRANSLATED_RULE_DESCRIPTION = i18n.translate( 'This might be caused by feature differences between SIEM products. If possible, update the rule manually.', } ); + +export const CALLOUT_TRANSLATED_RULE_INFO_TITLE = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.translationDetails.translationTab.partiallyTranslatedRuleCalloutTitle', + { + defaultMessage: 'Translation successful. Install the rule to customize it.', + } +); + +export const CALLOUT_TRANSLATED_RULE_INFO_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.translationDetails.translationTab.partiallyTranslatedRuleCalloutDescription', + { + defaultMessage: + 'After you install the rule, you can modify or update it with full access to all features.', + } +); diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/translations.ts index fe52d358b162a..bee423022ea09 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/translations.ts @@ -41,3 +41,10 @@ export const CLOSE_BUTTON_LABEL = i18n.translate( defaultMessage: 'Close', } ); + +export const LAST_UPDATED_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.translationDetails.lastUpdatedLabel', + { + defaultMessage: 'Last updated', + } +); diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/index.tsx new file mode 100644 index 0000000000000..6b615ee32deeb --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/index.tsx @@ -0,0 +1,54 @@ +/* + * 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, { useMemo } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiText } from '@elastic/eui'; + +import { FormattedDate } from '../../../../../common/components/formatted_date'; +import { useBulkGetUserProfiles } from '../../../../../common/components/user_profiles/use_bulk_get_user_profiles'; +import type { RuleMigration } from '../../../../../../common/siem_migrations/model/rule_migration.gen'; + +import * as i18n from './translations'; + +interface UpdatedByLabelProps { + ruleMigration: RuleMigration; +} + +export const UpdatedByLabel: React.FC = React.memo( + ({ ruleMigration }: UpdatedByLabelProps) => { + const userProfileId = useMemo( + () => new Set([ruleMigration.updated_by ?? ruleMigration.created_by]), + [ruleMigration.created_by, ruleMigration.updated_by] + ); + const { isLoading: isLoadingUserProfiles, data: userProfiles } = useBulkGetUserProfiles({ + uids: userProfileId, + }); + + if (isLoadingUserProfiles || !userProfiles?.length) { + return null; + } + + const userProfile = userProfiles[0]; + const updatedBy = userProfile.user.full_name ?? userProfile.user.username; + const updatedAt = ruleMigration.updated_at ?? ruleMigration['@timestamp']; + return ( + + {i18n.LAST_UPDATED_LABEL}, + by: updatedBy, + date: , + }} + /> + + ); + } +); +UpdatedByLabel.displayName = 'UpdatedByLabel'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/translations.ts new file mode 100644 index 0000000000000..62a117a2987f2 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/rule_details_flyout/updated_by/translations.ts @@ -0,0 +1,15 @@ +/* + * 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 LAST_UPDATED_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.translationDetails.lastUpdated.label', + { + defaultMessage: 'Last updated', + } +); diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx index c31048bf08bcf..4b3ea822c4fd6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx @@ -135,7 +135,7 @@ export const MigrationRulesPage: React.FC = React.memo( - + {