[SecuritySolution] Rename timeline-saving-related components (#166740)

## Summary

This PR prepares further work on the timeline-saving-related components.
As a first step we're only renaming the components to make it easier to
reason about their function.

> `SaveTimelineButton` -> `EditTimelineButton`:

We might have a dedicated `save` button more prominently in the UI in
the near future. The former "save" button actually opened up a modal
with the `edit` form. In cypress tests, the component was already
referred to as the `edit` button.

> `TimelineTitleAndDescription` -> `EditTimelineModal`:

The original name did not make it clear that it's actually a form in a
modal.

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Jan Monschke 2023-09-21 15:57:48 +02:00 committed by GitHub
parent d7369d9bde
commit 1e3f438531
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 103 additions and 121 deletions

View file

@ -35,7 +35,7 @@ import { AddToFavoritesButton } from '../../timeline/properties/helpers';
import type { TimerangeInput } from '../../../../../common/search_strategy';
import { AddToCaseButton } from '../add_to_case_button';
import { AddTimelineButton } from '../add_timeline_button';
import { SaveTimelineButton } from '../../timeline/header/save_timeline_button';
import { EditTimelineButton } from '../../timeline/header/edit_timeline_button';
import { useGetUserCasesPermissions, useKibana } from '../../../../common/lib/kibana';
import { InspectButton } from '../../../../common/components/inspect';
import { useTimelineKpis } from '../../../containers/kpis';
@ -421,14 +421,14 @@ const FlyoutHeaderComponent: React.FC<FlyoutHeaderProps> = ({ timelineId }) => {
<EuiFlexGroup data-test-subj="properties-left" direction="column" gutterSize="none">
<RowFlexItem>
<TimelineName timelineId={timelineId} />
<SaveTimelineButton timelineId={timelineId} initialFocus="title" />
<EditTimelineButton timelineId={timelineId} initialFocus="title" />
<TimelineStatusInfoContainer>
<TimelineStatusInfo timelineId={timelineId} />
</TimelineStatusInfoContainer>
</RowFlexItem>
<RowFlexItem>
<TimelineDescription timelineId={timelineId} />
<SaveTimelineButton timelineId={timelineId} initialFocus="description" />
<EditTimelineButton timelineId={timelineId} initialFocus="description" />
</RowFlexItem>
</EuiFlexGroup>
</EuiFlexItem>

View file

@ -30,7 +30,7 @@ import { NOTE_CONTENT_CLASS_NAME } from '../../timeline/body/helpers';
import * as i18n from './translations';
import { TimelineTabs } from '../../../../../common/types/timeline';
import { useDeepEqualSelector } from '../../../../common/hooks/use_selector';
import { SaveTimelineButton } from '../../timeline/header/save_timeline_button';
import { EditTimelineButton } from '../../timeline/header/edit_timeline_button';
import { SourcererScopeName } from '../../../../common/store/sourcerer/model';
import { useSourcererDataView } from '../../../../common/containers/sourcerer';
import { useKibana } from '../../../../common/lib/kibana';
@ -226,7 +226,7 @@ export const NotePreviews = React.memo<NotePreviewsProps>(
size="l"
/>
),
actions: <SaveTimelineButton timelineId={timelineId} initialFocus="description" />,
actions: <EditTimelineButton timelineId={timelineId} initialFocus="description" />,
},
]
: [],

View file

@ -7,15 +7,15 @@
import React from 'react';
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
import type { SaveTimelineComponentProps } from './save_timeline_button';
import { SaveTimelineButton } from './save_timeline_button';
import type { EditTimelineComponentProps } from './edit_timeline_button';
import { EditTimelineButton } from './edit_timeline_button';
import { TestProviders } from '../../../../common/mock';
import { useUserPrivileges } from '../../../../common/components/user_privileges';
const TEST_ID = {
SAVE_TIMELINE_MODAL: 'save-timeline-modal',
SAVE_TIMELINE_BTN: 'save-timeline-button-icon',
SAVE_TIMELINE_TOOLTIP: 'save-timeline-tooltip',
EDIT_TIMELINE_MODAL: 'edit-timeline-modal',
EDIT_TIMELINE_BTN: 'edit-timeline-button-icon',
EDIT_TIMELINE_TOOLTIP: 'edit-timeline-tooltip',
};
jest.mock('react-redux', () => {
@ -36,9 +36,9 @@ const props = {
toolTip: 'tooltip message',
};
const TestSaveTimelineButton = (_props: SaveTimelineComponentProps) => (
const TestEditTimelineButton = (_props: EditTimelineComponentProps) => (
<TestProviders>
<SaveTimelineButton {..._props} />
<EditTimelineButton {..._props} />
</TestProviders>
);
@ -46,21 +46,16 @@ jest.mock('raf', () => {
return jest.fn().mockImplementation((cb) => cb());
});
describe('SaveTimelineButton', () => {
describe('EditTimelineButton', () => {
beforeEach(() => {
jest.clearAllMocks();
});
// skipping this test because popover is not getting visible by RTL gestures.
//
// Raised a bug with eui team: https://github.com/elastic/eui/issues/6065
xit('Show tooltip', async () => {
render(<TestSaveTimelineButton {...props} />);
const saveTimelineIcon = screen.queryAllByTestId(TEST_ID.SAVE_TIMELINE_BTN)[0];
it('Show tooltip', async () => {
render(<TestEditTimelineButton {...props} />);
const editTimelineIcon = screen.queryAllByTestId(TEST_ID.EDIT_TIMELINE_BTN)[0];
fireEvent.mouseOver(saveTimelineIcon);
jest.runAllTimers();
fireEvent.mouseOver(editTimelineIcon);
await waitFor(() => {
expect(screen.getByRole('tooltip')).toBeVisible();
@ -68,9 +63,9 @@ describe('SaveTimelineButton', () => {
});
it('should show a button with pencil icon', () => {
render(<TestSaveTimelineButton {...props} />);
render(<TestEditTimelineButton {...props} />);
expect(screen.getByTestId(TEST_ID.SAVE_TIMELINE_BTN).firstChild).toHaveAttribute(
expect(screen.getByTestId(TEST_ID.EDIT_TIMELINE_BTN).firstChild).toHaveAttribute(
'data-euiicon-type',
'pencil'
);
@ -82,26 +77,26 @@ describe('SaveTimelineButton', () => {
});
render(
<TestProviders>
<SaveTimelineButton {...props} />
<EditTimelineButton {...props} />
</TestProviders>
);
expect(screen.getByTestId(TEST_ID.SAVE_TIMELINE_BTN)).toBeDisabled();
expect(screen.getByTestId(TEST_ID.EDIT_TIMELINE_BTN)).toBeDisabled();
});
it('should not show modal if user does not have write access', async () => {
(useUserPrivileges as jest.Mock).mockReturnValue({
kibanaSecuritySolutionsPrivileges: { crud: false },
});
render(<TestSaveTimelineButton {...props} />);
render(<TestEditTimelineButton {...props} />);
expect(screen.queryByTestId(TEST_ID.SAVE_TIMELINE_MODAL)).not.toBeInTheDocument();
expect(screen.queryByTestId(TEST_ID.EDIT_TIMELINE_MODAL)).not.toBeInTheDocument();
const saveTimelineIcon = screen.getByTestId(TEST_ID.SAVE_TIMELINE_BTN);
const editTimelineIcon = screen.getByTestId(TEST_ID.EDIT_TIMELINE_BTN);
fireEvent.click(saveTimelineIcon);
fireEvent.click(editTimelineIcon);
await waitFor(() => {
expect(screen.queryAllByTestId(TEST_ID.SAVE_TIMELINE_MODAL)).toHaveLength(0);
expect(screen.queryAllByTestId(TEST_ID.EDIT_TIMELINE_MODAL)).toHaveLength(0);
});
});
@ -109,16 +104,16 @@ describe('SaveTimelineButton', () => {
(useUserPrivileges as jest.Mock).mockReturnValue({
kibanaSecuritySolutionsPrivileges: { crud: true },
});
render(<TestSaveTimelineButton {...props} />);
expect(screen.queryByTestId(TEST_ID.SAVE_TIMELINE_MODAL)).not.toBeInTheDocument();
render(<TestEditTimelineButton {...props} />);
expect(screen.queryByTestId(TEST_ID.EDIT_TIMELINE_MODAL)).not.toBeInTheDocument();
const saveTimelineIcon = screen.queryAllByTestId(TEST_ID.SAVE_TIMELINE_BTN)[0];
const editTimelineIcon = screen.queryAllByTestId(TEST_ID.EDIT_TIMELINE_BTN)[0];
fireEvent.click(saveTimelineIcon);
fireEvent.click(editTimelineIcon);
await waitFor(() => {
expect(screen.queryByTestId(TEST_ID.SAVE_TIMELINE_TOOLTIP)).not.toBeInTheDocument();
expect(screen.queryAllByTestId(TEST_ID.SAVE_TIMELINE_MODAL)[0]).toBeVisible();
expect(screen.queryByTestId(TEST_ID.EDIT_TIMELINE_TOOLTIP)).not.toBeInTheDocument();
expect(screen.queryAllByTestId(TEST_ID.EDIT_TIMELINE_MODAL)[0]).toBeVisible();
});
});
});

View file

@ -14,24 +14,24 @@ import { TimelineId } from '../../../../../common/types/timeline';
import { useDeepEqualSelector } from '../../../../common/hooks/use_selector';
import { timelineActions } from '../../../store/timeline';
import { getTimelineSaveModalByIdSelector } from './selectors';
import { TimelineTitleAndDescription } from './title_and_description';
import { EditTimelineModal } from './edit_timeline_modal';
import * as timelineTranslations from './translations';
export interface SaveTimelineComponentProps {
export interface EditTimelineComponentProps {
initialFocus: 'title' | 'description';
timelineId: string;
toolTip?: string;
}
export const SaveTimelineButton = React.memo<SaveTimelineComponentProps>(
export const EditTimelineButton = React.memo<EditTimelineComponentProps>(
({ initialFocus, timelineId, toolTip }) => {
const dispatch = useDispatch();
const getTimelineSaveModal = useMemo(() => getTimelineSaveModalByIdSelector(), []);
const show = useDeepEqualSelector((state) => getTimelineSaveModal(state, timelineId));
const [showSaveTimelineOverlay, setShowSaveTimelineOverlay] = useState<boolean>(false);
const [showEditTimelineOverlay, setShowEditTimelineOverlay] = useState<boolean>(false);
const closeSaveTimeline = useCallback(() => {
setShowSaveTimelineOverlay(false);
const closeEditTimeline = useCallback(() => {
setShowEditTimelineOverlay(false);
if (show) {
dispatch(
timelineActions.toggleModalSaveTimeline({
@ -40,11 +40,11 @@ export const SaveTimelineButton = React.memo<SaveTimelineComponentProps>(
})
);
}
}, [dispatch, setShowSaveTimelineOverlay, show]);
}, [dispatch, setShowEditTimelineOverlay, show]);
const openSaveTimeline = useCallback(() => {
setShowSaveTimelineOverlay(true);
}, [setShowSaveTimelineOverlay]);
const openEditTimeline = useCallback(() => {
setShowEditTimelineOverlay(true);
}, [setShowEditTimelineOverlay]);
// Case: 1
// check if user has crud privileges so that user can be allowed to edit the timeline
@ -60,35 +60,35 @@ export const SaveTimelineButton = React.memo<SaveTimelineComponentProps>(
[toolTip, hasKibanaCrud]
);
const saveTimelineButtonIcon = useMemo(
const editTimelineButtonIcon = useMemo(
() => (
<EuiButtonIcon
aria-label={timelineTranslations.EDIT}
isDisabled={!hasKibanaCrud}
onClick={openSaveTimeline}
onClick={openEditTimeline}
iconType="pencil"
data-test-subj="save-timeline-button-icon"
data-test-subj="edit-timeline-button-icon"
/>
),
[openSaveTimeline, hasKibanaCrud]
[openEditTimeline, hasKibanaCrud]
);
return (initialFocus === 'title' && show) || showSaveTimelineOverlay ? (
return (initialFocus === 'title' && show) || showEditTimelineOverlay ? (
<>
{saveTimelineButtonIcon}
<TimelineTitleAndDescription
closeSaveTimeline={closeSaveTimeline}
{editTimelineButtonIcon}
<EditTimelineModal
closeEditTimeline={closeEditTimeline}
initialFocus={initialFocus}
timelineId={timelineId}
showWarning={initialFocus === 'title' && show}
/>
</>
) : (
<EuiToolTip content={finalTooltipMsg ?? ''} data-test-subj="save-timeline-btn-tooltip">
{saveTimelineButtonIcon}
<EuiToolTip content={finalTooltipMsg ?? ''} data-test-subj="edit-timeline-btn-tooltip">
{editTimelineButtonIcon}
</EuiToolTip>
);
}
);
SaveTimelineButton.displayName = 'SaveTimelineButton';
EditTimelineButton.displayName = 'EditTimelineButton';

View file

@ -11,7 +11,7 @@ import { mount } from 'enzyme';
import { TestProviders } from '../../../../common/mock';
import { useDeepEqualSelector } from '../../../../common/hooks/use_selector';
import { TimelineStatus, TimelineType } from '../../../../../common/api/timeline';
import { TimelineTitleAndDescription } from './title_and_description';
import { EditTimelineModal } from './edit_timeline_modal';
import * as i18n from './translations';
jest.mock('../../../../common/hooks/use_selector', () => ({
@ -30,15 +30,12 @@ jest.mock('react-redux', () => {
};
});
describe('TimelineTitleAndDescription', () => {
describe('EditTimelineModal', () => {
describe('save timeline', () => {
const props = {
initialFocus: 'title' as const,
closeSaveTimeline: jest.fn(),
closeEditTimeline: jest.fn(),
timelineId: 'timeline-1',
onSaveTimeline: jest.fn(),
updateTitle: jest.fn(),
updateDescription: jest.fn(),
};
const mockGetButton = jest.fn().mockReturnValue(<div data-test-subj="mock-discard-button" />);
@ -59,14 +56,14 @@ describe('TimelineTitleAndDescription', () => {
});
test('show process bar while saving', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="progress-bar"]').exists()).toEqual(true);
});
test('Show correct header for save timeline modal', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
test('Show correct header for edit timeline modal', () => {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="modal-header"]').at(1).prop('children')).toEqual(
@ -74,7 +71,7 @@ describe('TimelineTitleAndDescription', () => {
);
});
test('Show correct header for save timeline template modal', () => {
test('Show correct header for edit timeline template modal', () => {
(useDeepEqualSelector as jest.Mock).mockReturnValue({
description: '',
isSaving: true,
@ -82,7 +79,7 @@ describe('TimelineTitleAndDescription', () => {
title: 'my timeline',
timelineType: TimelineType.template,
});
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="modal-header"]').at(1).prop('children')).toEqual(
@ -91,28 +88,28 @@ describe('TimelineTitleAndDescription', () => {
});
test('Show name field', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-timeline-title"]').exists()).toEqual(true);
expect(component.find('[data-test-subj="edit-timeline-title"]').exists()).toEqual(true);
});
test('Show description field', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-timeline-description"]').exists()).toEqual(true);
expect(component.find('[data-test-subj="edit-timeline-description"]').exists()).toEqual(true);
});
test('Show close button', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="close-button"]').exists()).toEqual(true);
});
test('Show saveButton', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-button"]').exists()).toEqual(true);
@ -122,13 +119,8 @@ describe('TimelineTitleAndDescription', () => {
describe('update timeline', () => {
const props = {
initialFocus: 'title' as const,
closeSaveTimeline: jest.fn(),
openSaveTimeline: jest.fn(),
closeEditTimeline: jest.fn(),
timelineId: 'timeline-1',
toggleSaveTimeline: jest.fn(),
onSaveTimeline: jest.fn(),
updateTitle: jest.fn(),
updateDescription: jest.fn(),
};
const mockGetButton = jest.fn().mockReturnValue(<div data-test-subj="mock-discard-button" />);
@ -149,14 +141,14 @@ describe('TimelineTitleAndDescription', () => {
});
test('show process bar while saving', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="progress-bar"]').exists()).toEqual(true);
});
test('Show correct header for save timeline modal', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="modal-header"]').at(1).prop('children')).toEqual(
@ -164,7 +156,7 @@ describe('TimelineTitleAndDescription', () => {
);
});
test('Show correct header for save timeline template modal', () => {
test('Show correct header for edit timeline template modal', () => {
(useDeepEqualSelector as jest.Mock).mockReturnValue({
description: 'xxxx',
isSaving: true,
@ -172,7 +164,7 @@ describe('TimelineTitleAndDescription', () => {
title: 'my timeline',
timelineType: TimelineType.template,
});
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="modal-header"]').at(1).prop('children')).toEqual(
@ -181,21 +173,21 @@ describe('TimelineTitleAndDescription', () => {
});
test('Show name field', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-timeline-title"]').exists()).toEqual(true);
expect(component.find('[data-test-subj="edit-timeline-title"]').exists()).toEqual(true);
});
test('Show description field', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-timeline-description"]').exists()).toEqual(true);
expect(component.find('[data-test-subj="edit-timeline-description"]').exists()).toEqual(true);
});
test('Show saveButton', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-button"]').exists()).toEqual(true);
@ -205,13 +197,8 @@ describe('TimelineTitleAndDescription', () => {
describe('showWarning', () => {
const props = {
initialFocus: 'title' as const,
closeSaveTimeline: jest.fn(),
openSaveTimeline: jest.fn(),
closeEditTimeline: jest.fn(),
timelineId: 'timeline-1',
toggleSaveTimeline: jest.fn(),
onSaveTimeline: jest.fn(),
updateTitle: jest.fn(),
updateDescription: jest.fn(),
showWarning: true,
};
@ -234,14 +221,14 @@ describe('TimelineTitleAndDescription', () => {
});
test('Show EuiCallOut', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="save-timeline-callout"]').exists()).toEqual(true);
expect(component.find('[data-test-subj="edit-timeline-callout"]').exists()).toEqual(true);
});
test('Show discardTimelineButton', () => {
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="close-button"]').at(2).text()).toEqual(
@ -257,7 +244,7 @@ describe('TimelineTitleAndDescription', () => {
title: 'my timeline',
timelineType: TimelineType.template,
});
const component = mount(<TimelineTitleAndDescription {...props} />, {
const component = mount(<EditTimelineModal {...props} />, {
wrappingComponent: TestProviders,
});
expect(component.find('[data-test-subj="close-button"]').at(2).text()).toEqual(
@ -266,7 +253,7 @@ describe('TimelineTitleAndDescription', () => {
});
test('Show saveButton', () => {
const component = mount(<TimelineTitleAndDescription {...props} />);
const component = mount(<EditTimelineModal {...props} />);
expect(component.find('[data-test-subj="save-button"]').at(1).exists()).toEqual(true);
});
});

View file

@ -35,8 +35,8 @@ import { useStartTransaction } from '../../../../common/lib/apm/use_start_transa
import { TIMELINE_ACTIONS } from '../../../../common/lib/apm/user_actions';
const CommonUseField = getUseField({ component: Field });
interface TimelineTitleAndDescriptionProps {
closeSaveTimeline: () => void;
interface EditTimelineModalProps {
closeEditTimeline: () => void;
initialFocus: 'title' | 'description';
timelineId: string;
showWarning?: boolean;
@ -45,8 +45,8 @@ interface TimelineTitleAndDescriptionProps {
// when showWarning equals to true,
// the modal is used as a reminder for users to save / discard
// the unsaved timeline / template
export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptionProps>(
({ closeSaveTimeline, initialFocus, timelineId, showWarning }) => {
export const EditTimelineModal = React.memo<EditTimelineModalProps>(
({ closeEditTimeline, initialFocus, timelineId, showWarning }) => {
const { startTransaction } = useStartTransaction();
const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []);
const {
@ -112,8 +112,8 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
if (showWarning) {
handleCreateNewTimeline();
}
closeSaveTimeline();
}, [closeSaveTimeline, handleCreateNewTimeline, showWarning]);
closeEditTimeline();
}, [closeEditTimeline, handleCreateNewTimeline, showWarning]);
const closeModalText = useMemo(() => {
if (status === TimelineStatus.draft && showWarning) {
@ -157,7 +157,7 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
() => ({
'aria-label': i18n.TIMELINE_TITLE,
autoFocus: initialFocus === 'title',
'data-test-subj': 'save-timeline-title',
'data-test-subj': 'edit-timeline-title',
disabled: isSaving,
spellCheck: true,
placeholder:
@ -172,7 +172,7 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
() => ({
'aria-label': i18n.TIMELINE_DESCRIPTION,
autoFocus: initialFocus === 'description',
'data-test-subj': 'save-timeline-description',
'data-test-subj': 'edit-timeline-description',
disabled: isSaving,
placeholder: commonI18n.DESCRIPTION,
}),
@ -181,15 +181,15 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
useEffect(() => {
if (isSubmitted && !isSaving && prevIsSaving) {
closeSaveTimeline();
closeEditTimeline();
}
}, [isSubmitted, isSaving, prevIsSaving, closeSaveTimeline]);
}, [isSubmitted, isSaving, prevIsSaving, closeEditTimeline]);
return (
<EuiModal
data-test-subj="save-timeline-modal"
data-test-subj="edit-timeline-modal"
maxWidth={NOTES_PANEL_WIDTH}
onClose={closeSaveTimeline}
onClose={closeEditTimeline}
>
{isSaving && (
<EuiProgress size="s" color="primary" position="absolute" data-test-subj="progress-bar" />
@ -203,7 +203,7 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
title={calloutMessage}
color="danger"
iconType="warning"
data-test-subj="save-timeline-callout"
data-test-subj="edit-timeline-callout"
/>
<EuiSpacer size="m" />
</EuiFlexItem>
@ -260,4 +260,4 @@ export const TimelineTitleAndDescription = React.memo<TimelineTitleAndDescriptio
}
);
TimelineTitleAndDescription.displayName = 'TimelineTitleAndDescription';
EditTimelineModal.displayName = 'EditTimelineModal';

View file

@ -177,7 +177,7 @@ export const SAVE_DATA_PROVIDER_BTN = `[data-test-subj="save"]`;
export const TIMELINE_DESCRIPTION = '[data-test-subj="timeline-description"]';
export const TIMELINE_DESCRIPTION_INPUT = '[data-test-subj="save-timeline-description"]';
export const TIMELINE_DESCRIPTION_INPUT = '[data-test-subj="edit-timeline-description"]';
export const TIMELINE_DROPPED_DATA_PROVIDERS = '[data-test-subj="providerContainer"]';
@ -248,7 +248,7 @@ export const TIMELINE_KQLLANGUAGE_BUTTON = '[data-test-subj="kqlLanguageMenuItem
export const TIMELINE_TITLE = '[data-test-subj="timeline-title"]';
export const TIMELINE_TITLE_INPUT = '[data-test-subj="save-timeline-title"]';
export const TIMELINE_TITLE_INPUT = '[data-test-subj="edit-timeline-title"]';
export const TIMESTAMP_HEADER_FIELD = '[data-test-subj="header-text-@timestamp"]';
@ -257,9 +257,9 @@ export const TIMESTAMP_TOGGLE_FIELD =
export const TOGGLE_TIMELINE_EXPAND_EVENT = '[data-test-subj="expand-event"]';
export const TIMELINE_EDIT_MODAL_OPEN_BUTTON = '[data-test-subj="save-timeline-button-icon"]';
export const TIMELINE_EDIT_MODAL_OPEN_BUTTON = '[data-test-subj="edit-timeline-button-icon"]';
export const TIMELINE_SAVE_MODAL = '[data-test-subj="save-timeline-modal"]';
export const TIMELINE_SAVE_MODAL = '[data-test-subj="edit-timeline-modal"]';
export const TIMELINE_EDIT_MODAL_SAVE_BUTTON = '[data-test-subj="save-button"]';
@ -299,9 +299,9 @@ export const TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN =
export const USER_KPI = '[data-test-subj="siem-timeline-user-kpi"]';
export const EDIT_TIMELINE_BTN = '[data-test-subj="save-timeline-button-icon"]';
export const EDIT_TIMELINE_BTN = '[data-test-subj="edit-timeline-button-icon"]';
export const EDIT_TIMELINE_TOOLTIP = '[data-test-subj="save-timeline-btn-tooltip"]';
export const EDIT_TIMELINE_TOOLTIP = '[data-test-subj="edit-timeline-btn-tooltip"]';
export const ALERT_TABLE_SEVERITY_VALUES =
'[data-test-subj="formatted-field-kibana.alert.severity"]';