Skip to content

Commit

Permalink
[Rules migration] Add possibility to navigate to a specific migration (
Browse files Browse the repository at this point in the history
  • Loading branch information
e40pud committed Nov 25, 2024
1 parent 845aa8c commit b924f32
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import React from 'react';
import { Routes, Route } from '@kbn/shared-ux-router';

import type { SecuritySubPluginRoutes } from '../app/types';
import { SIEM_MIGRATIONS_RULES_PATH, SecurityPageName } from '../../common/constants';
Expand All @@ -17,7 +18,9 @@ export const RulesRoutes = () => {
return (
<PluginTemplateWrapper>
<SecurityRoutePageWrapper pageName={SecurityPageName.siemMigrationsRules}>
<RulesPage />
<Routes>
<Route path={`${SIEM_MIGRATIONS_RULES_PATH}/:migrationId?`} component={RulesPage} />
</Routes>
</SecurityRoutePageWrapper>
</PluginTemplateWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import * as i18n from './translations';

const NoSelectedMigrationsComponent = () => {
return (
<EuiFlexGroup
alignItems="center"
gutterSize="s"
responsive={false}
direction="column"
wrap={true}
>
<EuiFlexItem grow={false}>
<EuiEmptyPrompt
title={<h2>{i18n.NO_SELECTED_MIGRATIONS}</h2>}
titleSize="s"
body={i18n.NO_SELECTED_MIGRATIONS_BODY}
data-test-subj="noMigrationsAvailable"
/>
</EuiFlexItem>
</EuiFlexGroup>
);
};

export const NoSelectedMigrations = React.memo(NoSelectedMigrationsComponent);
NoSelectedMigrations.displayName = 'NoSelectedMigrations';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 NO_SELECTED_MIGRATIONS = i18n.translate(
'xpack.securitySolution.siemMigrations.rules.noSelectedMigrationsTitle',
{
defaultMessage: 'Select migration',
}
);

export const NO_SELECTED_MIGRATIONS_BODY = i18n.translate(
'xpack.securitySolution.siemMigrations.rules.noSelectedMigrationsBodyTitle',
{
defaultMessage: 'There is no selected migration',
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import * as i18n from './translations';

const UnknownMigrationComponent = () => {
return (
<EuiFlexGroup
alignItems="center"
gutterSize="s"
responsive={false}
direction="column"
wrap={true}
>
<EuiFlexItem grow={false}>
<EuiEmptyPrompt
title={<h2>{i18n.UNKNOWN_MIGRATION}</h2>}
titleSize="s"
body={i18n.UNKNOWN_MIGRATION_BODY}
data-test-subj="noMigrationsAvailable"
/>
</EuiFlexItem>
</EuiFlexGroup>
);
};

export const UnknownMigration = React.memo(UnknownMigrationComponent);
UnknownMigration.displayName = 'UnknownMigration';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 UNKNOWN_MIGRATION = i18n.translate(
'xpack.securitySolution.siemMigrations.rules.unknownMigrationTitle',
{
defaultMessage: 'Unknown migration',
}
);

export const UNKNOWN_MIGRATION_BODY = i18n.translate(
'xpack.securitySolution.siemMigrations.rules.unknownMigrationBodyTitle',
{
defaultMessage: 'Selected migration is unknown. Please select one of the available migraitons',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
* 2.0.
*/

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useMemo } from 'react';

import { EuiSkeletonLoading, EuiSkeletonText, EuiSkeletonTitle } from '@elastic/eui';
import type { RouteComponentProps } from 'react-router-dom';
import { useNavigation } from '../../../common/lib/kibana';
import type { RuleMigration } from '../../../../common/siem_migrations/model/rule_migration.gen';
import { SecurityPageName } from '../../../app/types';
import { HeaderPage } from '../../../common/components/header_page';
Expand All @@ -22,8 +24,18 @@ import { HeaderButtons } from '../components/header_buttons';
import { useGetRuleMigrationsStatsAllQuery } from '../api/hooks/use_get_rule_migrations_stats_all';
import { useRulePreviewFlyout } from '../hooks/use_rule_preview_flyout';
import { NoMigrations } from '../components/no_migrations';
import { NoSelectedMigrations } from '../components/no_selected_migrations';
import { UnknownMigration } from '../components/unknown_migration';

type RulesMigrationPageProps = RouteComponentProps<{ migrationId?: string }>;

const RulesPageComponent: React.FC<RulesMigrationPageProps> = ({
match: {
params: { migrationId },
},
}) => {
const { navigateTo } = useNavigation();

const RulesPageComponent: React.FC = () => {
const { data: ruleMigrationsStatsAll, isLoading: isLoadingMigrationsStats } =
useGetRuleMigrationsStatsAllQuery();

Expand All @@ -36,21 +48,10 @@ const RulesPageComponent: React.FC = () => {
.map((migration) => migration.migration_id);
}, [isLoadingMigrationsStats, ruleMigrationsStatsAll]);

const [selectedMigrationId, setSelectedMigrationId] = useState<string | undefined>();
const onMigrationIdChange = (selectedId?: string) => {
setSelectedMigrationId(selectedId);
navigateTo({ deepLinkId: SecurityPageName.siemMigrationsRules, path: selectedId });
};

useEffect(() => {
if (!migrationsIds.length) {
return;
}
const index = migrationsIds.findIndex((id) => id === selectedMigrationId);
if (index === -1) {
setSelectedMigrationId(migrationsIds[0]);
}
}, [migrationsIds, selectedMigrationId]);

const ruleActionsFactory = useCallback(
(ruleMigration: RuleMigration, closeRulePreview: () => void) => {
// TODO: Add flyout action buttons
Expand All @@ -63,6 +64,19 @@ const RulesPageComponent: React.FC = () => {
ruleActionsFactory,
});

const content = useMemo(() => {
if (!migrationsIds.length) {
return <NoMigrations />;
}
if (!migrationId) {
return <NoSelectedMigrations />;
}
if (migrationsIds.includes(migrationId)) {
return <RulesTable migrationId={migrationId} openRulePreview={openRulePreview} />;
}
return <UnknownMigration />;
}, [migrationId, migrationsIds, openRulePreview]);

return (
<>
<NeedAdminForUpdateRulesCallOut />
Expand All @@ -72,7 +86,7 @@ const RulesPageComponent: React.FC = () => {
<HeaderPage title={i18n.PAGE_TITLE}>
<HeaderButtons
migrationsIds={migrationsIds}
selectedMigrationId={selectedMigrationId}
selectedMigrationId={migrationId}
onMigrationIdChange={onMigrationIdChange}
/>
</HeaderPage>
Expand All @@ -84,13 +98,7 @@ const RulesPageComponent: React.FC = () => {
<EuiSkeletonText />
</>
}
loadedContent={
selectedMigrationId ? (
<RulesTable migrationId={selectedMigrationId} openRulePreview={openRulePreview} />
) : (
<NoMigrations />
)
}
loadedContent={content}
/>
{rulePreviewFlyout}
</SecuritySolutionPageWrapper>
Expand Down

0 comments on commit b924f32

Please sign in to comment.