[ML] Explain Log Rate Spikes: Fix loading behavior. (#137873) (#137996)

- Fixes API messages and loading state to always finish with 100% except when a user cancels the request.
- Fix to never apply loading={true} to the analysis table because it disables hovering events. To indicate loading we have the overall progress bar anyway.
- When the analysis returns no results, instead of an empty table and just the "no data" message, this now hides the table and displays an EuiEmptyPrompt.

(cherry picked from commit cd7578a26e)

Co-authored-by: Walter Rafelsberger <walter@elastic.co>
This commit is contained in:
Kibana Machine 2022-08-03 11:52:43 -04:00 committed by GitHub
parent f085a9d39a
commit 468e8050e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 28 deletions

View file

@ -7,10 +7,13 @@
import React, { useEffect, FC } from 'react';
import { EuiEmptyPrompt } from '@elastic/eui';
import type { DataView } from '@kbn/data-views-plugin/public';
import { ProgressControls } from '@kbn/aiops-components';
import { useFetchStream } from '@kbn/aiops-utils';
import type { WindowParameters } from '@kbn/aiops-utils';
import { FormattedMessage } from '@kbn/i18n-react';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { Query } from '@kbn/es-query';
@ -85,6 +88,8 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
start();
}
const showSpikeAnalysisTable = data?.changePoints.length > 0;
return (
<>
<ProgressControls
@ -94,7 +99,28 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
onRefresh={startHandler}
onCancel={cancel}
/>
{data?.changePoints ? (
{!isRunning && !showSpikeAnalysisTable && (
<EuiEmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.aiops.explainLogRateSpikesPage.noResultsPromptTitle"
defaultMessage="The analysis did not return any results."
/>
</h2>
}
titleSize="xs"
body={
<p>
<FormattedMessage
id="xpack.aiops.explainLogRateSpikesPage.noResultsPromptBody"
defaultMessage="Try to adjust the baseline and deviation time ranges and rerun the analysis. If you still get no results, there might be no statistically significant entities contributing to this spike in log rates."
/>
</p>
}
/>
)}
{showSpikeAnalysisTable && (
<SpikeAnalysisTable
changePoints={data.changePoints}
loading={isRunning}
@ -103,7 +129,7 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
onSelectedChangePoint={onSelectedChangePoint}
selectedChangePoint={selectedChangePoint}
/>
) : null}
)}
</>
);
};

View file

@ -29,9 +29,6 @@ import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transa
const NARROW_COLUMN_WIDTH = '120px';
const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50];
const noDataText = i18n.translate('xpack.aiops.correlations.correlationsTable.noDataText', {
defaultMessage: 'No data',
});
const DEFAULT_SORT_FIELD = 'pValue';
const DEFAULT_SORT_DIRECTION = 'asc';
@ -206,15 +203,21 @@ export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
};
}, [pageIndex, pageSize, sortField, sortDirection, changePoints]);
// Don't pass on the `loading` state to the table itself because
// it disables hovering events. Because the mini histograms take a while
// to load, hovering would not update the main chart. Instead,
// the loading state is shown by the progress bar on the outer component level.
// The outer component also will display a prompt when no data was returned
// running the analysis and will hide this table.
return (
<EuiBasicTable
compressed
columns={columns}
items={pageOfItems}
noItemsMessage={noDataText}
onChange={onChange}
pagination={pagination}
loading={loading}
loading={false}
error={error}
sorting={sorting as EuiTableSortingType<ChangePoint>}
rowProps={(changePoint) => {

View file

@ -75,6 +75,23 @@ export const defineExplainLogRateSpikesRoute = (
logger
);
function endWithUpdatedLoadingState() {
push(
updateLoadingStateAction({
ccsWarning: false,
loaded: 1,
loadingState: i18n.translate(
'xpack.aiops.explainLogRateSpikes.loadingState.doneMessage',
{
defaultMessage: 'Done.',
}
),
})
);
end();
}
// Async IIFE to run the analysis while not blocking returning `responseWithHeaders`.
(async () => {
push(resetAction());
@ -100,11 +117,7 @@ export const defineExplainLogRateSpikesRoute = (
return;
}
if (fieldCandidates.length > 0) {
loaded += LOADED_FIELD_CANDIDATES;
} else {
loaded = 1;
}
loaded += LOADED_FIELD_CANDIDATES;
push(
updateLoadingStateAction({
@ -123,7 +136,9 @@ export const defineExplainLogRateSpikesRoute = (
})
);
if (shouldStop || fieldCandidates.length === 0) {
if (fieldCandidates.length === 0) {
endWithUpdatedLoadingState();
} else if (shouldStop) {
end();
return;
}
@ -179,7 +194,7 @@ export const defineExplainLogRateSpikesRoute = (
}
if (changePoints?.length === 0) {
end();
endWithUpdatedLoadingState();
return;
}
@ -274,20 +289,7 @@ export const defineExplainLogRateSpikesRoute = (
});
}
push(
updateLoadingStateAction({
ccsWarning: false,
loaded: 1,
loadingState: i18n.translate(
'xpack.aiops.explainLogRateSpikes.loadingState.doneMessage',
{
defaultMessage: 'Done.',
}
),
})
);
end();
endWithUpdatedLoadingState();
})();
return response.ok(responseWithHeaders);