[AI4DSOC][Attack discovery] Followup to Attack discovery alerts (#218906) (#218964)

## Summary

These changes are follow-up to
https://github.com/elastic/kibana/pull/218906 and fix:
* The issue with displaying two connectors on AD scheduling create and
update views
(https://github.com/elastic/kibana/pull/218906#discussion_r2055893288)
* Removes redundant use of `stats` property in AD scheduling components
(https://github.com/elastic/kibana/pull/218906#discussion_r2055879265)
* Removes redundant dot in the string translation path
(https://github.com/elastic/kibana/pull/218906#discussion_r2055740976)

## NOTES

The feature is hidden behind the feature flag (in `kibana.dev.yml`):

```
feature_flags.overrides:
  securitySolution.assistantAttackDiscoverySchedulingEnabled: true
```
This commit is contained in:
Ievgen Sorokopud 2025-04-23 20:40:52 +02:00 committed by GitHub
parent 4b56543b1d
commit f00e51aefc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 15 additions and 28 deletions

View file

@ -43,7 +43,7 @@ export const VISIBILITY = i18n.translate(
);
export const VISIBLE_TO_YOUR_TEAM = i18n.translate(
'xpack.securitySolution.attackDiscovery.results.attackDiscoveryPanel.panelHeader.badges.sharedBadge..visibleToYourTeamLabel',
'xpack.securitySolution.attackDiscovery.results.attackDiscoveryPanel.panelHeader.badges.sharedBadge.visibleToYourTeamLabel',
{
defaultMessage: 'Visible to your team',
}

View file

@ -81,7 +81,7 @@ describe('useScheduleView', () => {
isLoading: false,
} as unknown as jest.Mocked<ReturnType<typeof useFindAttackDiscoverySchedules>>);
const { result } = renderHook(() => useScheduleView(null));
const { result } = renderHook(() => useScheduleView());
render(<TestProviders>{result.current.scheduleView}</TestProviders>);
@ -94,7 +94,7 @@ describe('useScheduleView', () => {
isLoading: false,
} as unknown as jest.Mocked<ReturnType<typeof useFindAttackDiscoverySchedules>>);
const { result } = renderHook(() => useScheduleView(null));
const { result } = renderHook(() => useScheduleView());
render(<TestProviders>{result.current.actionButtons}</TestProviders>);
@ -102,7 +102,7 @@ describe('useScheduleView', () => {
});
it('should return the `attack discovery schedules table` if there are existing schedules', () => {
const { result } = renderHook(() => useScheduleView(null));
const { result } = renderHook(() => useScheduleView());
render(<TestProviders>{result.current.scheduleView}</TestProviders>);
@ -110,7 +110,7 @@ describe('useScheduleView', () => {
});
it('should return `create new schedule` action button if there are existing schedules', () => {
const { result } = renderHook(() => useScheduleView(null));
const { result } = renderHook(() => useScheduleView());
render(<TestProviders>{result.current.actionButtons}</TestProviders>);
@ -118,7 +118,7 @@ describe('useScheduleView', () => {
});
it('should show create schedule flyout on `create new schedule` action button click', async () => {
const { result } = renderHook(() => useScheduleView(null));
const { result } = renderHook(() => useScheduleView());
render(<TestProviders>{result.current.actionButtons}</TestProviders>);

View file

@ -15,7 +15,6 @@ import {
} from '@elastic/eui';
import { ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG } from '@kbn/elastic-assistant-common';
import type { AttackDiscoveryStats } from '@kbn/elastic-assistant-common';
import React, { useCallback, useMemo, useState } from 'react';
import * as i18n from './translations';
@ -30,7 +29,7 @@ export interface UseScheduleView {
actionButtons: React.ReactNode;
}
export const useScheduleView = (stats: AttackDiscoveryStats | null): UseScheduleView => {
export const useScheduleView = (): UseScheduleView => {
const {
services: { featureFlags },
} = useKibana();
@ -60,12 +59,12 @@ export const useScheduleView = (stats: AttackDiscoveryStats | null): UseSchedule
<EuiSkeletonText />
</>
}
loadedContent={!total ? <EmptyPage stats={stats} /> : <SchedulesTable />}
loadedContent={!total ? <EmptyPage /> : <SchedulesTable />}
/>
{showFlyout && <CreateFlyout stats={stats} onClose={onClose} />}
{showFlyout && <CreateFlyout onClose={onClose} />}
</>
);
}, [isDataLoading, onClose, showFlyout, stats, total]);
}, [isDataLoading, onClose, showFlyout, total]);
const actionButtons = useMemo(() => {
return total ? (

View file

@ -66,7 +66,7 @@ export const useTabsView = ({
showConnectorSelector: true,
stats,
});
const { scheduleView, actionButtons: scheduleTabButtons } = useScheduleView(stats);
const { scheduleView, actionButtons: scheduleTabButtons } = useScheduleView();
const settingsTab: EuiTabbedContentTab = useMemo(
() => ({

View file

@ -51,7 +51,6 @@ const defaultProps = {
connectorId: undefined,
onConnectorIdSelected: jest.fn(),
onClose: jest.fn(),
stats: null,
};
const renderComponent = async () => {

View file

@ -16,7 +16,6 @@ import {
useGeneratedHtmlId,
} from '@elastic/eui';
import { useAssistantContext, useLoadConnectors } from '@kbn/elastic-assistant';
import type { AttackDiscoveryStats } from '@kbn/elastic-assistant-common';
import { useKibana } from '../../../../../common/lib/kibana';
import { useSourcererDataView } from '../../../../../sourcerer/containers';
@ -30,10 +29,9 @@ import { convertFormDataInBaseSchedule } from '../utils/convert_form_data';
interface Props {
onClose: () => void;
stats: AttackDiscoveryStats | null;
}
export const CreateFlyout: React.FC<Props> = React.memo(({ onClose, stats }) => {
export const CreateFlyout: React.FC<Props> = React.memo(({ onClose }) => {
const flyoutTitleId = useGeneratedHtmlId({
prefix: 'attackDiscoveryScheduleCreateFlyoutTitle',
});
@ -87,7 +85,6 @@ export const CreateFlyout: React.FC<Props> = React.memo(({ onClose, stats }) =>
isLoading: isLoadingConnectors || isLoadingQuery,
onSave: onCreateSchedule,
saveButtonTitle: i18n.SCHEDULE_CREATE_BUTTON_TITLE,
stats,
});
return (

View file

@ -127,7 +127,6 @@ export const DetailsFlyout: React.FC<Props> = React.memo(({ scheduleId, onClose
isLoading,
onSave: onUpdateSchedule,
saveButtonTitle: i18n.SCHEDULE_SAVE_BUTTON_TITLE,
stats: null,
});
const scheduleDetails = useMemo(() => {

View file

@ -92,7 +92,7 @@ export const EditForm: React.FC<FormProps> = React.memo((props) => {
onConnectorIdSelected,
onSettingsChanged,
settings,
showConnectorSelector: true,
showConnectorSelector: false,
stats: null,
});

View file

@ -18,7 +18,6 @@ import {
import { css } from '@emotion/react';
import { DEFAULT_ATTACK_DISCOVERY_MAX_ALERTS } from '@kbn/elastic-assistant';
import type { AttackDiscoveryStats } from '@kbn/elastic-assistant-common';
import { DEFAULT_END, DEFAULT_START } from '@kbn/elastic-assistant-common';
import * as i18n from './translations';
import type { AttackDiscoveryScheduleSchema } from './types';
@ -50,7 +49,6 @@ export interface UseEditFormProps {
initialValue?: AttackDiscoveryScheduleSchema;
onSave?: (scheduleData: AttackDiscoveryScheduleSchema) => void;
saveButtonTitle?: string;
stats: AttackDiscoveryStats | null;
}
export const useEditForm = (props: UseEditFormProps): UseEditForm => {

View file

@ -16,7 +16,6 @@ import {
EuiPanel,
EuiText,
} from '@elastic/eui';
import type { AttackDiscoveryStats } from '@kbn/elastic-assistant-common';
import { css } from '@emotion/react';
import * as i18n from './translations';
@ -24,11 +23,7 @@ import * as i18n from './translations';
import ScheduleIconSVG from '../icons/schedule.svg';
import { CreateFlyout } from '../create_flyout';
interface Props {
stats: AttackDiscoveryStats | null;
}
export const EmptyPage: React.FC<Props> = React.memo(({ stats }) => {
export const EmptyPage: React.FC = React.memo(() => {
// showing / hiding the flyout:
const [showFlyout, setShowFlyout] = useState<boolean>(false);
const openFlyout = useCallback(() => setShowFlyout(true), []);
@ -83,7 +78,7 @@ export const EmptyPage: React.FC<Props> = React.memo(({ stats }) => {
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
{showFlyout && <CreateFlyout onClose={onClose} stats={stats} />}
{showFlyout && <CreateFlyout onClose={onClose} />}
</>
);
});