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

[8.0] Fix success message to show correct language based on timelin… (#123258) #123320

Merged
merged 1 commit into from
Jan 19, 2022
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 @@ -180,9 +180,9 @@ const FlyoutHeaderPanelComponent: React.FC<FlyoutHeaderPanelProps> = ({ timeline
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
<EuiToolTip content={i18n.CLOSE_TIMELINE}>
<EuiToolTip content={i18n.CLOSE_TIMELINE_OR_TEMPLATE(timelineType === 'default')}>
<EuiButtonIcon
aria-label={i18n.CLOSE_TIMELINE}
aria-label={i18n.CLOSE_TIMELINE_OR_TEMPLATE(timelineType === 'default')}
data-test-subj="close-timeline"
iconType="cross"
onClick={handleClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

import { i18n } from '@kbn/i18n';

export const CLOSE_TIMELINE = i18n.translate(
'xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel',
{
defaultMessage: 'Close timeline',
}
);
export const CLOSE_TIMELINE_OR_TEMPLATE = (isTimeline: boolean) =>
i18n.translate('xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel', {
defaultMessage: 'Close {isTimeline, select, true {timeline} false {template}}',
values: {
isTimeline,
},
});

export const UNSAVED = i18n.translate('xpack.securitySolution.timeline.properties.unsavedLabel', {
defaultMessage: 'Unsaved',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ import React from 'react';

import AddToTimelineButton, { ADD_TO_TIMELINE_KEYBOARD_SHORTCUT } from './add_to_timeline';
import { DataProvider, IS_OPERATOR } from '../../../../common/types';
import { useDeepEqualSelector } from '../../../hooks/use_selector';
import { TestProviders } from '../../../mock';
import * as i18n from './translations';

const mockAddSuccess = jest.fn();
jest.mock('../../../hooks/use_app_toasts', () => ({
useAppToasts: () => ({
addSuccess: mockAddSuccess,
}),
}));

jest.mock('../../../hooks/use_selector');

const mockDispatch = jest.fn();
jest.mock('react-redux', () => {
const originalModule = jest.requireActual('react-redux');
Expand Down Expand Up @@ -72,6 +82,7 @@ const providerB: DataProvider = {
describe('add to timeline', () => {
beforeEach(() => {
jest.resetAllMocks();
(useDeepEqualSelector as jest.Mock).mockReturnValue({ timelineType: 'default' });
});

const field = 'user.name';
Expand Down Expand Up @@ -369,4 +380,32 @@ describe('add to timeline', () => {
});
});
});

describe('it shows the appropriate text based on timeline type', () => {
test('Add success is called with "timeline" if timeline type is timeline', () => {
render(
<TestProviders>
<AddToTimelineButton dataProvider={providerA} field={field} ownFocus={false} />
</TestProviders>
);

fireEvent.click(screen.getByRole('button'));

expect(mockAddSuccess).toBeCalledWith('Added a to timeline');
});

test('Add success is called with "template" if timeline type is template', () => {
(useDeepEqualSelector as jest.Mock).mockReturnValue({ timelineType: 'template' });

render(
<TestProviders>
<AddToTimelineButton dataProvider={providerA} field={field} ownFocus={false} />
</TestProviders>
);

fireEvent.click(screen.getByRole('button'));

expect(mockAddSuccess).toBeCalledWith('Added a to template');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import React, { useCallback, useEffect, useMemo } from 'react';
import { EuiContextMenuItem, EuiButtonEmpty, EuiButtonIcon, EuiToolTip } from '@elastic/eui';
import { DraggableId } from 'react-beautiful-dnd';
import { useDispatch } from 'react-redux';

import { isEmpty } from 'lodash';

import { stopPropagationAndPreventDefault } from '../../../../common/utils/accessibility';
import { DataProvider, TimelineId } from '../../../../common/types';
import { useDeepEqualSelector } from '../../../hooks/use_selector';
import { tGridSelectors } from '../../../types';
import { TooltipWithKeyboardShortcut } from '../../tooltip_with_keyboard_shortcut';
import { getAdditionalScreenReaderOnlyContext } from '../utils';
import { useAddToTimeline } from '../../../hooks/use_add_to_timeline';
Expand Down Expand Up @@ -67,6 +69,12 @@ const AddToTimelineButton: React.FC<AddToTimelineButtonProps> = React.memo(
const dispatch = useDispatch();
const { addSuccess } = useAppToasts();
const startDragToTimeline = useGetHandleStartDragToTimeline({ draggableId, field });
const getTGrid = tGridSelectors.getTGridByIdSelector();

const { timelineType } = useDeepEqualSelector((state) => {
return getTGrid(state, TimelineId.active);
});

const handleStartDragToTimeline = useCallback(() => {
if (draggableId != null) {
startDragToTimeline();
Expand All @@ -80,15 +88,25 @@ const AddToTimelineButton: React.FC<AddToTimelineButtonProps> = React.memo(
dataProvider: provider,
})
);
addSuccess(i18n.ADDED_TO_TIMELINE_MESSAGE(provider.name));
addSuccess(
i18n.ADDED_TO_TIMELINE_OR_TEMPLATE_MESSAGE(provider.name, timelineType === 'default')
);
}
});
}

if (onClick != null) {
onClick();
}
}, [addSuccess, onClick, dataProvider, dispatch, draggableId, startDragToTimeline]);
}, [
addSuccess,
dataProvider,
dispatch,
draggableId,
onClick,
startDragToTimeline,
timelineType,
]);

useEffect(() => {
if (!ownFocus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const ADD_TO_TIMELINE = i18n.translate('xpack.timelines.hoverActions.addT
defaultMessage: 'Add to timeline investigation',
});

export const ADDED_TO_TIMELINE_MESSAGE = (fieldOrValue: string) =>
export const ADDED_TO_TIMELINE_OR_TEMPLATE_MESSAGE = (fieldOrValue: string, isTimeline: boolean) =>
i18n.translate('xpack.timelines.hoverActions.addToTimeline.addedFieldMessage', {
values: { fieldOrValue },
defaultMessage: `Added {fieldOrValue} to timeline`,
values: { fieldOrValue, isTimeline },
defaultMessage: `Added {fieldOrValue} to {isTimeline, select, true {timeline} false {template}}`,
});
1 change: 1 addition & 0 deletions x-pack/plugins/timelines/public/mock/global_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const mockGlobalState: TimelineState = {
queryFields: [],
selectAll: false,
title: 'Events',
timelineType: 'default',
},
},
};
1 change: 1 addition & 0 deletions x-pack/plugins/timelines/public/mock/mock_timeline_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1588,4 +1588,5 @@ export const mockTgridModel: TGridModel = {
],
title: 'Test rule',
version: '1',
timelineType: 'default',
};
1 change: 1 addition & 0 deletions x-pack/plugins/timelines/public/store/t_grid/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export interface TGridModel extends TGridModelSettings {
/** Events selected on this timeline -- eventId to TimelineNonEcsData[] mapping of data required for bulk actions **/
selectedEventIds: Record<string, TimelineNonEcsData[]>;
savedObjectId: string | null;
timelineType: 'default' | 'template';
version: string | null;
initialized?: boolean;
}
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -23844,7 +23844,6 @@
"xpack.securitySolution.timeline.failSearchDescription": "検索を実行できませんでした",
"xpack.securitySolution.timeline.fieldTooltip": "フィールド",
"xpack.securitySolution.timeline.file.fromOriginalPathDescription": "元のパスから",
"xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel": "タイムラインを閉じる",
"xpack.securitySolution.timeline.flyout.pane.removeColumnButtonLabel": "列を削除",
"xpack.securitySolution.timeline.flyout.pane.timelinePropertiesAriaLabel": "タイムラインのプロパティ",
"xpack.securitySolution.timeline.flyoutTimelineTemplateLabel": "タイムラインテンプレート",
Expand Down Expand Up @@ -25228,7 +25227,6 @@
"xpack.timelines.footer.rowsPerPageLabel": "ページごとの行:{rowsPerPage}",
"xpack.timelines.footer.totalCountOfEvents": "イベント",
"xpack.timelines.hoverActions.addToTimeline": "タイムライン調査に追加",
"xpack.timelines.hoverActions.addToTimeline.addedFieldMessage": "{fieldOrValue}をタイムラインに追加しました",
"xpack.timelines.hoverActions.columnToggleLabel": "表の{field}列を切り替える",
"xpack.timelines.hoverActions.fieldLabel": "フィールド",
"xpack.timelines.hoverActions.filterIn": "フィルタリング",
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -24241,7 +24241,6 @@
"xpack.securitySolution.timeline.failSearchDescription": "无法运行搜索",
"xpack.securitySolution.timeline.fieldTooltip": "字段",
"xpack.securitySolution.timeline.file.fromOriginalPathDescription": "从其原始路径",
"xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel": "关闭时间线",
"xpack.securitySolution.timeline.flyout.pane.removeColumnButtonLabel": "移除列",
"xpack.securitySolution.timeline.flyout.pane.timelinePropertiesAriaLabel": "时间线属性",
"xpack.securitySolution.timeline.flyoutTimelineTemplateLabel": "时间线模板",
Expand Down Expand Up @@ -25661,7 +25660,6 @@
"xpack.timelines.footer.rowsPerPageLabel": "每页行数:{rowsPerPage}",
"xpack.timelines.footer.totalCountOfEvents": "事件",
"xpack.timelines.hoverActions.addToTimeline": "添加到时间线调查",
"xpack.timelines.hoverActions.addToTimeline.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线",
"xpack.timelines.hoverActions.columnToggleLabel": "在表中切换 {field} 列",
"xpack.timelines.hoverActions.fieldLabel": "字段",
"xpack.timelines.hoverActions.filterIn": "筛选",
Expand Down