Skip to content

Commit

Permalink
Fix success message to show correct language based on timelin… (#123258)
Browse files Browse the repository at this point in the history
* Fix success message to show correct language based on timeline type

* Fix translation problems

Co-authored-by: Kristof-Pierre Cummings <[email protected]>
  • Loading branch information
jamster10 and Kristof-Pierre Cummings authored Jan 18, 2022
1 parent 886ad6f commit 91a35c2
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 18 deletions.
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 @@ -23643,7 +23643,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 @@ -25025,7 +25024,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 @@ -24038,7 +24038,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 @@ -25456,7 +25455,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

0 comments on commit 91a35c2

Please sign in to comment.