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

[SecuritySolution] update sourcer messages #129329

Merged
merged 9 commits into from
Apr 12, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,14 @@ describe('Update available', () => {
expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-callout"]`).first().text()).toEqual(
'This timeline uses a legacy data view selector'
);

expect(
wrapper.find(`[data-test-subj="sourcerer-current-patterns-message"]`).first().text()
).toEqual('The active index patterns in this timeline are: myFakebeat-*');

expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-message"]`).first().text()).toEqual(
"We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view here."
);
});

test('Show Add index pattern in UpdateDefaultDataViewModal', () => {
Expand Down Expand Up @@ -1103,6 +1111,10 @@ describe('Update available for timeline template', () => {
expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-callout"]`).first().text()).toEqual(
'This timeline template uses a legacy data view selector'
);

expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-message"]`).first().text()).toEqual(
"We have preserved your timeline template by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view here."
);
});
});

Expand Down Expand Up @@ -1179,6 +1191,20 @@ describe('Missing index patterns', () => {
expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-callout"]`).first().text()).toEqual(
'This timeline is out of date with the Security Data View'
);

expect(
wrapper.find(`[data-test-subj="sourcerer-current-patterns-message"]`).first().text()
).toEqual('The active index patterns in this timeline are: myFakebeat-*');

expect(
wrapper.find(`[data-test-subj="sourcerer-missing-patterns-callout"]`).first().text()
).toEqual('Security Data View is missing the following index patterns: myFakebeat-*');

expect(
wrapper.find(`[data-test-subj="sourcerer-missing-patterns-message"]`).first().text()
).toEqual(
"We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view here."
);
});

test('Show UpdateDefaultDataViewModal CallOut for timeline template', () => {
Expand All @@ -1201,5 +1227,19 @@ describe('Missing index patterns', () => {
expect(wrapper.find(`[data-test-subj="sourcerer-deprecated-callout"]`).first().text()).toEqual(
'This timeline template is out of date with the Security Data View'
);

expect(
wrapper.find(`[data-test-subj="sourcerer-current-patterns-message"]`).first().text()
).toEqual('The active index patterns in this timeline template are: myFakebeat-*');

expect(
wrapper.find(`[data-test-subj="sourcerer-missing-patterns-callout"]`).first().text()
).toEqual('Security Data View is missing the following index patterns: myFakebeat-*');

expect(
wrapper.find(`[data-test-subj="sourcerer-missing-patterns-message"]`).first().text()
).toEqual(
"We have preserved your timeline template by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view here."
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
import { FormattedMessage } from '@kbn/i18n-react';
import {
EuiCallOut,
EuiLink,
EuiText,
EuiTextColor,
EuiSpacer,
EuiFlexGroup,
EuiFlexItem,
EuiButton,
EuiToolTip,
EuiIcon,
} from '@elastic/eui';
import React, { useMemo } from 'react';
import * as i18n from './translations';
Expand All @@ -26,6 +24,12 @@ import { TimelineId, TimelineType } from '../../../../common/types';
import { timelineSelectors } from '../../../timelines/store/timeline';
import { useDeepEqualSelector } from '../../hooks/use_selector';
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
import {
BadCurrentPatternsMessage,
CurrentPatternsMessage,
DeprecatedMessage,
MissingPatternsMessage,
} from './utils';

interface Props {
activePatterns?: string[];
Expand Down Expand Up @@ -116,66 +120,33 @@ export const TemporarySourcererComp = React.memo<Props>(
<EuiTextColor color="subdued">
<p>
{activePatterns && activePatterns.length > 0 ? (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.currentPatterns"
defaultMessage="The active index patterns in this timeline are{tooltip}: {callout}"
values={{
tooltip:
deadPatterns.length > 0 ? (
<EuiToolTip
content={
<FormattedMessage
id="xpack.securitySolution.indexPatterns.noMatchData"
defaultMessage="The following index patterns are saved to this timeline but do not match any data streams, indices, or index aliases: {aliases}"
values={{
aliases: selectedPatterns
.filter((p) => !activePatterns.includes(p))
.join(', '),
}}
/>
}
>
<EuiIcon type="questionInCircle" title={i18n.INACTIVE_PATTERNS} />
</EuiToolTip>
) : null,
callout: <Blockquote>{activePatterns.join(', ')}</Blockquote>,
}}
<CurrentPatternsMessage
timelineType={timelineType}
activePatterns={activePatterns}
deadPatterns={deadPatterns}
selectedPatterns={selectedPatterns}
/>
) : (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.currentPatternsBad"
defaultMessage="The current index patterns in this timeline are: {callout}"
values={{
callout: <Blockquote>{selectedPatterns.join(', ')}</Blockquote>,
}}
<BadCurrentPatternsMessage
timelineType={timelineType}
selectedPatterns={selectedPatterns}
/>
)}

{isModified === 'deprecated' && (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.toggleToNewSourcerer"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
<DeprecatedMessage timelineType={timelineType} onReset={onReset} />
)}
{isModified === 'missingPatterns' && (
<>
<FormattedMessage
data-test-subj="sourcerer-missing-patterns-callout"
id="xpack.securitySolution.indexPatterns.missingPatterns.callout"
defaultMessage="Security Data View is missing the following index patterns: {callout}"
values={{
callout: <Blockquote>{missingPatterns.join(', ')}</Blockquote>,
}}
/>
<FormattedMessage
id="xpack.securitySolution.indexPatterns.missingPatterns.description"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
<MissingPatternsMessage timelineType={timelineType} onReset={onReset} />
</>
)}
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FormattedMessage doesn’t accept its props to be variables (The build will fail and complain about this), so I created components to return messages by timeline type.

* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { EuiIcon, EuiLink, EuiToolTip } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { useMemo } from 'react';
import { TimelineType } from '../../../../common/types';
import { Blockquote } from './helpers';
import * as i18n from './translations';

export const CurrentPatternsMessage = ({
activePatterns,
deadPatterns,
selectedPatterns,
timelineType,
}: {
activePatterns: string[];
deadPatterns: string[];
selectedPatterns: string[];
timelineType: TimelineType;
}) => {
const tooltip = useMemo(
() =>
deadPatterns.length > 0 ? (
<EuiToolTip
content={
<NoMatchDataMessage
activePatterns={activePatterns}
selectedPatterns={selectedPatterns}
timelineType={timelineType}
/>
}
>
<EuiIcon type="questionInCircle" title={i18n.INACTIVE_PATTERNS} />
</EuiToolTip>
) : null,
[activePatterns, deadPatterns.length, selectedPatterns, timelineType]
);

if (timelineType === TimelineType.template) {
return (
<FormattedMessage
data-test-subj="sourcerer-current-patterns-message"
id="xpack.securitySolution.indexPatterns.timelineTemplate.currentPatterns"
defaultMessage="The active index patterns in this timeline template are{tooltip}: {callout}"
values={{
tooltip,
callout: <Blockquote>{activePatterns.join(', ')}</Blockquote>,
}}
/>
);
}

return (
<FormattedMessage
data-test-subj="sourcerer-current-patterns-message"
id="xpack.securitySolution.indexPatterns.timeline.currentPatterns"
defaultMessage="The active index patterns in this timeline are{tooltip}: {callout}"
values={{
tooltip,
callout: <Blockquote>{activePatterns.join(', ')}</Blockquote>,
}}
/>
);
};

export const NoMatchDataMessage = ({
activePatterns,
selectedPatterns,
timelineType,
}: {
activePatterns: string[];
selectedPatterns: string[];
timelineType: TimelineType;
}) => {
const aliases = useMemo(
() => selectedPatterns.filter((p) => !activePatterns.includes(p)).join(', '),
[activePatterns, selectedPatterns]
);
if (timelineType === TimelineType.template) {
return (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.timelineTemplate.noMatchData"
defaultMessage="The following index patterns are saved to this timeline template but do not match any data streams, indices, or index aliases: {aliases}"
values={{
aliases,
}}
/>
);
}

return (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.timeline.noMatchData"
defaultMessage="The following index patterns are saved to this timeline but do not match any data streams, indices, or index aliases: {aliases}"
values={{
aliases,
}}
/>
);
};

export const BadCurrentPatternsMessage = ({
timelineType,
selectedPatterns,
}: {
timelineType: TimelineType;
selectedPatterns: string[];
}) => {
const callout = useMemo(
() => <Blockquote>{selectedPatterns.join(', ')}</Blockquote>,
[selectedPatterns]
);

if (timelineType === TimelineType.template) {
return (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.timelineTemplate.currentPatternsBad"
defaultMessage="The current index patterns in this timeline template are: {callout}"
values={{
callout,
}}
/>
);
}
return (
<FormattedMessage
id="xpack.securitySolution.indexPatterns.timeline.currentPatternsBad"
defaultMessage="The current index patterns in this timeline are: {callout}"
values={{
callout,
}}
/>
);
};

export const DeprecatedMessage = ({
onReset,
timelineType,
}: {
onReset: () => void;
timelineType: TimelineType;
}) => {
if (timelineType === TimelineType.template) {
return (
<FormattedMessage
data-test-subj="sourcerer-deprecated-message"
id="xpack.securitySolution.indexPatterns.timelineTemplate.toggleToNewSourcerer"
defaultMessage="We have preserved your timeline template by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
);
}
return (
<FormattedMessage
data-test-subj="sourcerer-deprecated-message"
id="xpack.securitySolution.indexPatterns.timeline.toggleToNewSourcerer"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
);
};

export const MissingPatternsMessage = ({
onReset,
timelineType,
}: {
timelineType: TimelineType;
onReset: () => void;
}) => {
if (timelineType === TimelineType.template) {
return (
<FormattedMessage
data-test-subj="sourcerer-missing-patterns-message"
id="xpack.securitySolution.indexPatterns.missingPatterns.timelineTemplate.description"
defaultMessage="We have preserved your timeline template by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
);
}
return (
<FormattedMessage
data-test-subj="sourcerer-missing-patterns-message"
id="xpack.securitySolution.indexPatterns.missingPatterns.timeline.description"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
);
};
Loading