Skip to content

Commit

Permalink
[8.x] [SecuritySolution][Notes] - no note message uses alert/event de…
Browse files Browse the repository at this point in the history
…pending of which type of document is visualized in the flyout (#195960) (#195980)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[SecuritySolution][Notes] - no note message uses alert/event
depending of which type of document is visualized in the flyout
(#195960)](#195960)

<!--- Backport version: 9.4.3 -->

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

<!--BACKPORT [{"author":{"name":"Philippe
Oberti","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-11T19:04:23Z","message":"[SecuritySolution][Notes]
- no note message uses alert/event depending of which type of document
is visualized in the flyout
(#195960)","sha":"cf20d641cf84a88be6d0131011576ee3c47dca58","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["backport","release_note:skip","v9.0.0","Team:Threat
Hunting:Investigations","v8.16.0"],"title":"[SecuritySolution][Notes] -
no note message uses alert/event depending of which type of document is
visualized in the
flyout","number":195960,"url":"https://github.com/elastic/kibana/pull/195960","mergeCommit":{"message":"[SecuritySolution][Notes]
- no note message uses alert/event depending of which type of document
is visualized in the flyout
(#195960)","sha":"cf20d641cf84a88be6d0131011576ee3c47dca58"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/195960","number":195960,"mergeCommit":{"message":"[SecuritySolution][Notes]
- no note message uses alert/event depending of which type of document
is visualized in the flyout
(#195960)","sha":"cf20d641cf84a88be6d0131011576ee3c47dca58"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Philippe Oberti <[email protected]>
  • Loading branch information
kibanamachine and PhilippeOberti authored Oct 11, 2024
1 parent 644692a commit ce62f5b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import { useWhichFlyout } from '../../shared/hooks/use_which_flyout';
import { Flyouts } from '../../shared/constants/flyouts';
import { TimelineId } from '../../../../../common/types';
import { ReqStatus } from '../../../../notes';
import { useBasicDataFromDetailsData } from '../../shared/hooks/use_basic_data_from_details_data';

jest.mock('../../shared/hooks/use_which_flyout');
jest.mock('../../shared/hooks/use_basic_data_from_details_data');

jest.mock('../../../../common/components/user_privileges');
const useUserPrivilegesMock = useUserPrivileges as jest.Mock;
Expand All @@ -47,7 +49,9 @@ jest.mock('react-redux', () => {

const panelContextValue = {
eventId: 'event id',
dataFormattedForFieldBrowser: [],
} as unknown as DocumentDetailsContext;

const mockGlobalStateWithSavedTimeline = {
...mockGlobalState,
timeline: {
Expand Down Expand Up @@ -80,6 +84,7 @@ describe('NotesDetails', () => {
kibanaSecuritySolutionsPrivileges: { crud: true },
});
(useWhichFlyout as jest.Mock).mockReturnValue(Flyouts.timeline);
(useBasicDataFromDetailsData as jest.Mock).mockReturnValue({ isAlert: true });
});

it('should fetch notes for the document id', () => {
Expand Down Expand Up @@ -110,7 +115,30 @@ describe('NotesDetails', () => {
expect(getByTestId(NOTES_LOADING_TEST_ID)).toBeInTheDocument();
});

it('should render no data message if no notes are present', () => {
it('should render no data message for alerts if no notes are present', () => {
const store = createMockStore({
...mockGlobalStateWithSavedTimeline,
notes: {
...mockGlobalStateWithSavedTimeline.notes,
status: {
...mockGlobalStateWithSavedTimeline.notes.status,
fetchNotesByDocumentIds: ReqStatus.Succeeded,
},
},
});

const { getByText } = render(
<TestProviders store={store}>
<DocumentDetailsContext.Provider value={panelContextValue}>
<NotesDetails />
</DocumentDetailsContext.Provider>
</TestProviders>
);

expect(getByText(NO_NOTES(true))).toBeInTheDocument();
});

it('should render no data message for events if no notes are present', () => {
const store = createMockStore({
...mockGlobalStateWithSavedTimeline,
notes: {
Expand All @@ -121,6 +149,7 @@ describe('NotesDetails', () => {
},
},
});
(useBasicDataFromDetailsData as jest.Mock).mockReturnValue({ isAlert: false });

const { getByText } = render(
<TestProviders store={store}>
Expand All @@ -130,7 +159,7 @@ describe('NotesDetails', () => {
</TestProviders>
);

expect(getByText(NO_NOTES)).toBeInTheDocument();
expect(getByText(NO_NOTES(false))).toBeInTheDocument();
});

it('should render error toast if fetching notes fails', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingElastic, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useBasicDataFromDetailsData } from '../../shared/hooks/use_basic_data_from_details_data';
import { Flyouts } from '../../shared/constants/flyouts';
import { timelineSelectors } from '../../../../timelines/store';
import { TimelineId } from '../../../../../common/types';
Expand Down Expand Up @@ -37,9 +38,11 @@ export const FETCH_NOTES_ERROR = i18n.translate(
defaultMessage: 'Error fetching notes',
}
);
export const NO_NOTES = i18n.translate('xpack.securitySolution.flyout.left.notes.noNotesLabel', {
defaultMessage: 'No notes have been created for this document',
});
export const NO_NOTES = (isAlert: boolean) =>
i18n.translate('xpack.securitySolution.flyout.left.notes.noNotesLabel', {
defaultMessage: 'No notes have been created for this {value}',
values: { value: isAlert ? 'alert' : 'event' },
});

/**
* List all the notes for a document id and allows to create new notes associated with that document.
Expand All @@ -48,7 +51,7 @@ export const NO_NOTES = i18n.translate('xpack.securitySolution.flyout.left.notes
export const NotesDetails = memo(() => {
const { addError: addErrorToast } = useAppToasts();
const dispatch = useDispatch();
const { eventId } = useDocumentDetailsContext();
const { eventId, dataFormattedForFieldBrowser } = useDocumentDetailsContext();
const { kibanaSecuritySolutionsPrivileges } = useUserPrivileges();
const canCreateNotes = kibanaSecuritySolutionsPrivileges.crud;

Expand Down Expand Up @@ -105,17 +108,25 @@ export const NotesDetails = memo(() => {
}
}, [addErrorToast, fetchError, fetchStatus]);

const { isAlert } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser);
const noNotesMessage = useMemo(
() => (
<EuiFlexGroup justifyContent="center">
<EuiFlexItem grow={false}>
<p>{NO_NOTES(isAlert)}</p>
</EuiFlexItem>
</EuiFlexGroup>
),
[isAlert]
);

return (
<>
{fetchStatus === ReqStatus.Loading && (
<EuiLoadingElastic data-test-subj={NOTES_LOADING_TEST_ID} size="xxl" />
)}
{fetchStatus === ReqStatus.Succeeded && notes.length === 0 ? (
<EuiFlexGroup justifyContent="center">
<EuiFlexItem grow={false}>
<p>{NO_NOTES}</p>
</EuiFlexItem>
</EuiFlexGroup>
<>{noNotesMessage}</>
) : (
<NotesList notes={notes} options={{ hideFlyoutIcon: true }} />
)}
Expand Down

0 comments on commit ce62f5b

Please sign in to comment.