Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIEM] Fix draft timeline can be attached to a case #67844

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const StatefulFlyoutHeader = React.memo<Props>(
title,
noteIds,
notesById,
status,
timelineId,
toggleLock,
updateDescription,
Expand All @@ -62,6 +63,7 @@ const StatefulFlyoutHeader = React.memo<Props>(
isFavorite={isFavorite}
title={title}
noteIds={noteIds}
status={status}
timelineId={timelineId}
toggleLock={toggleLock}
updateDescription={updateDescription}
Expand Down Expand Up @@ -94,6 +96,7 @@ const makeMapStateToProps = () => {
kqlQuery,
title = '',
noteIds = emptyNotesId,
status,
} = timeline;

const history = emptyHistory; // TODO: get history from store via selector
Expand All @@ -107,6 +110,7 @@ const makeMapStateToProps = () => {
isFavorite,
isDatepickerLocked: globalInput.linkTo.includes('timeline'),
noteIds,
status,
title,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import styled from 'styled-components';
import { useHistory } from 'react-router-dom';
import { useSelector } from 'react-redux';

import { TimelineStatus } from '../../../../../common/types/timeline';
import { Note } from '../../../../common/lib/note';
import { Notes } from '../../notes';
import { AssociateNote, UpdateNote } from '../../notes/helpers';
Expand Down Expand Up @@ -119,40 +120,44 @@ Name.displayName = 'Name';
interface NewCaseProps {
onClosePopover: () => void;
timelineId: string;
timelineStatus: TimelineStatus;
timelineTitle: string;
}

export const NewCase = React.memo<NewCaseProps>(({ onClosePopover, timelineId, timelineTitle }) => {
const history = useHistory();
const { savedObjectId } = useSelector((state: State) =>
timelineSelectors.selectTimeline(state, timelineId)
);
const handleClick = useCallback(() => {
onClosePopover();
history.push({
pathname: `/${SiemPageName.case}/create`,
state: {
insertTimeline: {
timelineId,
timelineSavedObjectId: savedObjectId,
timelineTitle: timelineTitle.length > 0 ? timelineTitle : i18n.UNTITLED_TIMELINE,
export const NewCase = React.memo<NewCaseProps>(
({ onClosePopover, timelineId, timelineStatus, timelineTitle }) => {
const history = useHistory();
const { savedObjectId } = useSelector((state: State) =>
timelineSelectors.selectTimeline(state, timelineId)
);
const handleClick = useCallback(() => {
onClosePopover();
history.push({
pathname: `/${SiemPageName.case}/create`,
state: {
insertTimeline: {
timelineId,
timelineSavedObjectId: savedObjectId,
timelineTitle: timelineTitle.length > 0 ? timelineTitle : i18n.UNTITLED_TIMELINE,
},
},
},
});
}, [onClosePopover, history, timelineId, timelineTitle]);
});
}, [onClosePopover, history, timelineId, timelineTitle]);

return (
<EuiButtonEmpty
data-test-subj="attach-timeline-case"
color="text"
iconSide="left"
iconType="paperClip"
onClick={handleClick}
>
{i18n.ATTACH_TIMELINE_TO_NEW_CASE}
</EuiButtonEmpty>
);
});
return (
<EuiButtonEmpty
data-test-subj="attach-timeline-case"
color="text"
iconSide="left"
iconType="paperClip"
disabled={timelineStatus === TimelineStatus.draft}
onClick={handleClick}
>
{i18n.ATTACH_TIMELINE_TO_NEW_CASE}
</EuiButtonEmpty>
);
}
);
NewCase.displayName = 'NewCase';

interface NewTimelineProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { mount } from 'enzyme';
import React from 'react';
import { Provider as ReduxStoreProvider } from 'react-redux';

import { TimelineStatus } from '../../../../../common/types/timeline';
import {
mockGlobalState,
apolloClientObservable,
Expand All @@ -25,6 +26,24 @@ jest.mock('../../../../common/components/utils');
width: mockedWidth,
}));

jest.mock('react-redux', () => {
const originalModule = jest.requireActual('react-redux');

return {
...originalModule,
useSelector: jest.fn().mockReturnValue({ savedObjectId: '1' }),
};
});

jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');

return {
...originalModule,
useHistory: jest.fn(),
};
});

describe('Properties', () => {
const usersViewing = ['elastic'];

Expand All @@ -50,6 +69,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand All @@ -60,7 +80,45 @@ describe('Properties', () => {
/>
</ReduxStoreProvider>
);

wrapper.find('[data-test-subj="settings-gear"]').at(0).simulate('click');

expect(wrapper.find('[data-test-subj="timeline-properties"]').exists()).toEqual(true);
expect(wrapper.find('button[data-test-subj="attach-timeline-case"]').prop('disabled')).toEqual(
false
);
});

test('renders correctly draft timeline', () => {
const wrapper = mount(
<ReduxStoreProvider store={store}>
<Properties
associateNote={jest.fn()}
createTimeline={jest.fn()}
isDataInTimeline={false}
isDatepickerLocked={false}
isFavorite={false}
title=""
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.draft}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
updateIsFavorite={jest.fn()}
updateTitle={jest.fn()}
updateNote={jest.fn()}
usersViewing={usersViewing}
/>
</ReduxStoreProvider>
);

wrapper.find('[data-test-subj="settings-gear"]').at(0).simulate('click');

expect(wrapper.find('button[data-test-subj="attach-timeline-case"]').prop('disabled')).toEqual(
true
);
});

test('it renders an empty star icon when it is NOT a favorite', () => {
Expand All @@ -76,6 +134,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
patrykkopycinski marked this conversation as resolved.
Show resolved Hide resolved
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -103,6 +162,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -132,6 +192,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -159,6 +220,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -191,6 +253,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -222,6 +285,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -256,6 +320,7 @@ describe('Properties', () => {
description={description}
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -292,6 +357,7 @@ describe('Properties', () => {
description={description}
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -326,6 +392,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -360,6 +427,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -392,6 +460,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -421,6 +490,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -448,6 +518,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

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

import { TimelineStatus } from '../../../../../common/types/timeline';
import { useThrottledResizeObserver } from '../../../../common/components/utils';
import { Note } from '../../../../common/lib/note';
import { InputsModelId } from '../../../../common/store/inputs/constants';
Expand All @@ -31,6 +32,7 @@ interface Props {
isFavorite: boolean;
noteIds: string[];
timelineId: string;
status: TimelineStatus;
title: string;
toggleLock: ToggleLock;
updateDescription: UpdateDescription;
Expand Down Expand Up @@ -62,6 +64,7 @@ export const Properties = React.memo<Props>(
isDatepickerLocked,
isFavorite,
noteIds,
status,
timelineId,
title,
toggleLock,
Expand Down Expand Up @@ -140,6 +143,7 @@ export const Properties = React.memo<Props>(
showNotesFromWidth={width < showNotesThreshold}
showTimelineModal={showTimelineModal}
showUsersView={title.length > 0}
status={status}
timelineId={timelineId}
title={title}
updateDescription={updateDescription}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { InspectButton, InspectButtonContainer } from '../../../../common/compon
import * as i18n from './translations';
import { AssociateNote } from '../../notes/helpers';
import { Note } from '../../../../common/lib/note';
import { TimelineStatus } from '../../../../../common/types/timeline';

export const PropertiesRightStyle = styled(EuiFlexGroup)`
margin-right: 5px;
Expand Down Expand Up @@ -79,6 +80,7 @@ interface Props {
onCloseTimelineModal: () => void;
onOpenTimelineModal: () => void;
showTimelineModal: boolean;
status: TimelineStatus;
title: string;
updateNote: UpdateNote;
}
Expand Down Expand Up @@ -106,6 +108,7 @@ const PropertiesRightComponent: React.FC<Props> = ({
onCloseTimelineModal,
onOpenTimelineModal,
title,
status,
}) => (
<PropertiesRightStyle alignItems="flexStart" data-test-subj="properties-right" gutterSize="s">
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -142,6 +145,7 @@ const PropertiesRightComponent: React.FC<Props> = ({
onClosePopover={onClosePopover}
timelineId={timelineId}
timelineTitle={title}
timelineStatus={status}
/>
</EuiFlexItem>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export const oneTimelineQuery = gql`
updatedBy
version
}
status
title
timelineType
templateTimelineId
Expand Down