mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Security Solution][Notes] - ensures that notes are always sorted from newest to oldest in expandable flyout notes tab (#188400)
This commit is contained in:
parent
80ea21792f
commit
d58de3dc31
3 changed files with 91 additions and 3 deletions
|
@ -37,7 +37,7 @@ import {
|
|||
selectDeleteNotesStatus,
|
||||
selectFetchNotesByDocumentIdsError,
|
||||
selectFetchNotesByDocumentIdsStatus,
|
||||
selectNotesByDocumentId,
|
||||
selectSortedNotesByDocumentId,
|
||||
} from '../../../../notes/store/notes.slice';
|
||||
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
|
||||
import { useUserPrivileges } from '../../../../common/components/user_privileges';
|
||||
|
@ -90,7 +90,12 @@ export const NotesList = memo(({ eventId }: NotesListProps) => {
|
|||
const fetchStatus = useSelector((state: State) => selectFetchNotesByDocumentIdsStatus(state));
|
||||
const fetchError = useSelector((state: State) => selectFetchNotesByDocumentIdsError(state));
|
||||
|
||||
const notes: Note[] = useSelector((state: State) => selectNotesByDocumentId(state, eventId));
|
||||
const notes: Note[] = useSelector((state: State) =>
|
||||
selectSortedNotesByDocumentId(state, {
|
||||
documentId: eventId,
|
||||
sort: { field: 'created', direction: 'desc' },
|
||||
})
|
||||
);
|
||||
|
||||
const createStatus = useSelector((state: State) => selectCreateNoteStatus(state));
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import {
|
|||
userSelectedRow,
|
||||
userSelectedRowForDeletion,
|
||||
userSortedNotes,
|
||||
selectSortedNotesByDocumentId,
|
||||
} from './notes.slice';
|
||||
import type { NotesState } from './notes.slice';
|
||||
import { mockGlobalState } from '../../common/mock';
|
||||
|
@ -515,6 +516,63 @@ describe('notesSlice', () => {
|
|||
expect(selectNotesByDocumentId(mockGlobalState, 'wrong-document-id')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should return all notes sorted dor an existing document id', () => {
|
||||
const oldestNote = {
|
||||
eventId: '1', // should be a valid id based on mockTimelineData
|
||||
noteId: '1',
|
||||
note: 'note-1',
|
||||
timelineId: 'timeline-1',
|
||||
created: 1663882629000,
|
||||
createdBy: 'elastic',
|
||||
updated: 1663882629000,
|
||||
updatedBy: 'elastic',
|
||||
version: 'version',
|
||||
};
|
||||
const newestNote = {
|
||||
...oldestNote,
|
||||
noteId: '2',
|
||||
created: 1663882689000,
|
||||
};
|
||||
|
||||
const state = {
|
||||
...mockGlobalState,
|
||||
notes: {
|
||||
...mockGlobalState.notes,
|
||||
entities: {
|
||||
'1': oldestNote,
|
||||
'2': newestNote,
|
||||
},
|
||||
ids: ['1', '2'],
|
||||
},
|
||||
};
|
||||
|
||||
const ascResult = selectSortedNotesByDocumentId(state, {
|
||||
documentId: '1',
|
||||
sort: { field: 'created', direction: 'asc' },
|
||||
});
|
||||
expect(ascResult[0]).toEqual(oldestNote);
|
||||
expect(ascResult[1]).toEqual(newestNote);
|
||||
|
||||
const descResult = selectSortedNotesByDocumentId(state, {
|
||||
documentId: '1',
|
||||
sort: { field: 'created', direction: 'desc' },
|
||||
});
|
||||
expect(descResult[0]).toEqual(newestNote);
|
||||
expect(descResult[1]).toEqual(oldestNote);
|
||||
});
|
||||
|
||||
it('should also return no notes if document id does not exist', () => {
|
||||
expect(
|
||||
selectSortedNotesByDocumentId(mockGlobalState, {
|
||||
documentId: 'wrong-document-id',
|
||||
sort: {
|
||||
field: 'created',
|
||||
direction: 'desc',
|
||||
},
|
||||
})
|
||||
).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should select notes pagination', () => {
|
||||
const state = {
|
||||
...mockGlobalState,
|
||||
|
|
|
@ -276,10 +276,35 @@ export const selectFetchNotesError = (state: State) => state.notes.error.fetchNo
|
|||
export const selectFetchNotesStatus = (state: State) => state.notes.status.fetchNotes;
|
||||
|
||||
export const selectNotesByDocumentId = createSelector(
|
||||
[selectAllNotes, (state, documentId) => documentId],
|
||||
[selectAllNotes, (state: State, documentId: string) => documentId],
|
||||
(notes, documentId) => notes.filter((note) => note.eventId === documentId)
|
||||
);
|
||||
|
||||
export const selectSortedNotesByDocumentId = createSelector(
|
||||
[
|
||||
selectAllNotes,
|
||||
(
|
||||
state: State,
|
||||
{
|
||||
documentId,
|
||||
sort,
|
||||
}: { documentId: string; sort: { field: keyof Note; direction: 'asc' | 'desc' } }
|
||||
) => ({ documentId, sort }),
|
||||
],
|
||||
(notes, { documentId, sort }) => {
|
||||
const { field, direction } = sort;
|
||||
return notes
|
||||
.filter((note: Note) => note.eventId === documentId)
|
||||
.sort((first: Note, second: Note) => {
|
||||
const a = first[field];
|
||||
const b = second[field];
|
||||
if (a == null) return 1;
|
||||
if (b == null) return -1;
|
||||
return direction === 'asc' ? (a > b ? 1 : -1) : a > b ? -1 : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export const {
|
||||
userSelectedPage,
|
||||
userSelectedPerPage,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue