[Discover] Add data view changed warning after alert rule created (#134674)

* [Discover] add data view changed warn

* [Discover] add functional test

* [Discover] update snapshot

* [Discover] adjust comment

* [Discover] apply suggestions
This commit is contained in:
Dmitry Tomashevich 2022-07-04 13:59:21 +03:00 committed by GitHub
parent f1564ba339
commit 8e607ccdbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 5 deletions

View file

@ -6,6 +6,7 @@ exports[`AddFilter should ignore strings with just spaces 1`] = `
grow={10} grow={10}
> >
<EuiFieldText <EuiFieldText
data-test-subj="fieldFilterInput"
fullWidth={true} fullWidth={true}
onChange={[Function]} onChange={[Function]}
placeholder="field filter, accepts wildcards (e.g., \`user*\` to filter fields starting with 'user')" placeholder="field filter, accepts wildcards (e.g., \`user*\` to filter fields starting with 'user')"
@ -14,6 +15,7 @@ exports[`AddFilter should ignore strings with just spaces 1`] = `
</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem> <EuiFlexItem>
<EuiButton <EuiButton
data-test-subj="addFieldFilterButton"
isDisabled={true} isDisabled={true}
onClick={[Function]} onClick={[Function]}
> >
@ -33,6 +35,7 @@ exports[`AddFilter should render normally 1`] = `
grow={10} grow={10}
> >
<EuiFieldText <EuiFieldText
data-test-subj="fieldFilterInput"
fullWidth={true} fullWidth={true}
onChange={[Function]} onChange={[Function]}
placeholder="field filter, accepts wildcards (e.g., \`user*\` to filter fields starting with 'user')" placeholder="field filter, accepts wildcards (e.g., \`user*\` to filter fields starting with 'user')"
@ -41,6 +44,7 @@ exports[`AddFilter should render normally 1`] = `
</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem> <EuiFlexItem>
<EuiButton <EuiButton
data-test-subj="addFieldFilterButton"
isDisabled={true} isDisabled={true}
onClick={[Function]} onClick={[Function]}
> >

View file

@ -38,12 +38,17 @@ export const AddFilter = ({ onAddFilter }: AddFilterProps) => {
<EuiFieldText <EuiFieldText
fullWidth fullWidth
value={filter} value={filter}
data-test-subj="fieldFilterInput"
onChange={(e) => setFilter(e.target.value.trim())} onChange={(e) => setFilter(e.target.value.trim())}
placeholder={sourcePlaceholder} placeholder={sourcePlaceholder}
/> />
</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem> <EuiFlexItem>
<EuiButton isDisabled={filter.length === 0} onClick={onAddButtonClick}> <EuiButton
data-test-subj="addFieldFilterButton"
isDisabled={filter.length === 0}
onClick={onAddButtonClick}
>
<FormattedMessage <FormattedMessage
id="indexPatternManagement.editIndexPattern.source.addButtonLabel" id="indexPatternManagement.editIndexPattern.source.addButtonLabel"
defaultMessage="Add" defaultMessage="Add"

View file

@ -69,6 +69,7 @@ export function ViewAlertRoute() {
displayRuleChangedWarn, displayRuleChangedWarn,
displayPossibleDocsDiffInfoAlert, displayPossibleDocsDiffInfoAlert,
showDataViewFetchError, showDataViewFetchError,
showDataViewUpdatedWarning,
} = getAlertUtils(toastNotifications, core, data); } = getAlertUtils(toastNotifications, core, data);
const navigateToResults = async () => { const navigateToResults = async () => {
@ -79,9 +80,12 @@ export function ViewAlertRoute() {
} }
const calculatedChecksum = getCurrentChecksum(fetchedAlert.params); const calculatedChecksum = getCurrentChecksum(fetchedAlert.params);
// rule params changed
if (openActualAlert && calculatedChecksum !== queryParams.checksum) { if (openActualAlert && calculatedChecksum !== queryParams.checksum) {
displayRuleChangedWarn(); displayRuleChangedWarn();
} else if (openActualAlert && calculatedChecksum === queryParams.checksum) { }
// documents might be updated or deleted
else if (openActualAlert && calculatedChecksum === queryParams.checksum) {
displayPossibleDocsDiffInfoAlert(); displayPossibleDocsDiffInfoAlert();
} }
@ -93,12 +97,24 @@ export function ViewAlertRoute() {
const dataView = fetchedSearchSource.getField('index'); const dataView = fetchedSearchSource.getField('index');
const timeFieldName = dataView?.timeFieldName; const timeFieldName = dataView?.timeFieldName;
// data view fetch error
if (!dataView || !timeFieldName) { if (!dataView || !timeFieldName) {
showDataViewFetchError(fetchedAlert.id); showDataViewFetchError(fetchedAlert.id);
history.push(DISCOVER_MAIN_ROUTE); history.push(DISCOVER_MAIN_ROUTE);
return; return;
} }
const dataViewSavedObject = await core.savedObjects.client.get('index-pattern', dataView.id!);
const alertUpdatedAt = fetchedAlert.updatedAt;
const dataViewUpdatedAt = dataViewSavedObject.updatedAt!;
// data view updated after the last update of the alert rule
if (
openActualAlert &&
new Date(dataViewUpdatedAt).valueOf() > new Date(alertUpdatedAt).valueOf()
) {
showDataViewUpdatedWarning();
}
const timeRange = openActualAlert const timeRange = openActualAlert
? { from: queryParams.from, to: queryParams.to } ? { from: queryParams.from, to: queryParams.to }
: buildTimeRangeFilter(dataView, fetchedAlert, timeFieldName); : buildTimeRangeFilter(dataView, fetchedAlert, timeFieldName);

View file

@ -106,11 +106,26 @@ export const getAlertUtils = (
} }
}; };
const showDataViewUpdatedWarning = async () => {
const warnTitle = i18n.translate('discover.viewAlert.dataViewChangedWarnTitle', {
defaultMessage: 'Data View has changed',
});
const warnDescription = i18n.translate('discover.viewAlert.dataViewChangedWarnDescription', {
defaultMessage: `Data view has been updated after the last update of the alert rule.`,
});
toastNotifications.addWarning({
title: warnTitle,
text: toMountPoint(<MarkdownSimple>{warnDescription}</MarkdownSimple>),
});
};
return { return {
fetchAlert,
fetchSearchSource,
displayRuleChangedWarn, displayRuleChangedWarn,
displayPossibleDocsDiffInfoAlert, displayPossibleDocsDiffInfoAlert,
showDataViewFetchError, showDataViewFetchError,
fetchAlert, showDataViewUpdatedWarning,
fetchSearchSource,
}; };
}; };

View file

@ -31,6 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const queryBar = getService('queryBar'); const queryBar = getService('queryBar');
const security = getService('security'); const security = getService('security');
const filterBar = getService('filterBar'); const filterBar = getService('filterBar');
const find = getService('find');
const SOURCE_DATA_INDEX = 'search-source-alert'; const SOURCE_DATA_INDEX = 'search-source-alert';
const OUTPUT_DATA_INDEX = 'search-source-alert-output'; const OUTPUT_DATA_INDEX = 'search-source-alert-output';
@ -171,6 +172,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
return { message, title }; return { message, title };
}; };
const getErrorToastTitle = async () => {
const toastList = await testSubjects.find('globalToastList');
const title = await (
await toastList.findByCssSelector('.euiToast--danger > .euiToastHeader')
).getVisibleText();
return title;
};
const openOutputIndex = async () => { const openOutputIndex = async () => {
await PageObjects.common.navigateToApp('discover'); await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.header.waitUntilLoadingHasFinished();
@ -327,6 +336,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
); );
}); });
it('should display warning about recently updated data view', async () => {
await PageObjects.common.navigateToUrlWithBrowserHistory(
'management',
`/kibana/dataViews/dataView/${sourceDataViewId}`,
undefined
);
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('tab-sourceFilters');
await testSubjects.click('fieldFilterInput');
await PageObjects.common.sleep(15000);
const input = await find.activeElement();
await input.type('message');
await testSubjects.click('addFieldFilterButton');
await openOutputIndex();
await navigateToResults();
await openOutputIndex();
await navigateToResults();
const { message, title } = await getLastToast();
expect(await dataGrid.getDocCount()).to.be(1);
expect(title).to.be.equal('Data View has changed');
expect(message).to.be.equal(
'Data view has been updated after the last update of the alert rule.'
);
});
it('should display not found index error', async () => { it('should display not found index error', async () => {
await openOutputIndex(); await openOutputIndex();
const link = await getResultsLink(); const link = await getResultsLink();
@ -340,7 +382,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await navigateToDiscover(link); await navigateToDiscover(link);
const { title } = await getLastToast(); const title = await getErrorToastTitle();
expect(title).to.be.equal( expect(title).to.be.equal(
'No matching indices found: No indices match "search-source-alert"' 'No matching indices found: No indices match "search-source-alert"'
); );

View file

@ -128,6 +128,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
stackAlerts: ['all'], stackAlerts: ['all'],
discover: ['all'], discover: ['all'],
advancedSettings: ['all'], advancedSettings: ['all'],
indexPatterns: ['all'],
}, },
spaces: ['*'], spaces: ['*'],
}, },