mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] Display info when no datafeed preview results are found (#155650)
When an empty list is returned from the datafeed preview endpoint, it now displays a callout informing the user that there were no results. Closes https://github.com/elastic/kibana/issues/153306  Also rewrites the datafeed preview component in typescript.
This commit is contained in:
parent
8de71325a3
commit
ab039e63f3
3 changed files with 104 additions and 112 deletions
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* 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 PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { EuiSpacer, EuiCallOut, EuiLoadingSpinner } from '@elastic/eui';
|
||||
|
||||
import { ml } from '../../../../services/ml_api_service';
|
||||
import { checkPermission } from '../../../../capabilities/check_capabilities';
|
||||
import { ML_DATA_PREVIEW_COUNT } from '../../../../../../common/util/job_utils';
|
||||
import { MLJobEditor } from '../ml_job_editor';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
export class DatafeedPreviewPane extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
previewJson: '',
|
||||
loading: true,
|
||||
canPreviewDatafeed: true,
|
||||
};
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const { previewJson, loading, canPreviewDatafeed } = this.state;
|
||||
|
||||
if (canPreviewDatafeed === false) {
|
||||
return (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.noPermissionToViewDatafeedPreviewTitle"
|
||||
defaultMessage="You do not have permission to view the datafeed preview"
|
||||
/>
|
||||
}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.pleaseContactYourAdministratorLabel"
|
||||
defaultMessage="Please contact your administrator"
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
} else if (loading === true) {
|
||||
return <EuiLoadingSpinner size="xl" />;
|
||||
} else {
|
||||
return <MLJobEditor value={previewJson} readOnly={true} />;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const canPreviewDatafeed =
|
||||
checkPermission('canPreviewDatafeed') && this.props.job.datafeed_config !== undefined;
|
||||
this.setState({ canPreviewDatafeed });
|
||||
|
||||
updateDatafeedPreview(this.props.job, canPreviewDatafeed)
|
||||
.then((previewJson) => {
|
||||
this.setState({ previewJson, loading: false });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Datafeed preview could not be loaded', error);
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
{this.renderContent()}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
DatafeedPreviewPane.propTypes = {
|
||||
job: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
function updateDatafeedPreview(job, canPreviewDatafeed) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (canPreviewDatafeed) {
|
||||
ml.jobs
|
||||
.datafeedPreview(job.datafeed_config.datafeed_id)
|
||||
.then((resp) => {
|
||||
if (Array.isArray(resp)) {
|
||||
resolve(JSON.stringify(resp.slice(0, ML_DATA_PREVIEW_COUNT), null, 2));
|
||||
} else {
|
||||
resolve('');
|
||||
console.log('Datafeed preview could not be loaded', resp);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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 React, { FC, useEffect, useState } from 'react';
|
||||
import { EuiCallOut, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { ML_DATA_PREVIEW_COUNT } from '../../../../../../common/util/job_utils';
|
||||
import { useMlApiContext } from '../../../../contexts/kibana';
|
||||
import { usePermissionCheck } from '../../../../capabilities/check_capabilities';
|
||||
import { CombinedJob } from '../../../../../shared';
|
||||
import { MLJobEditor } from '../ml_job_editor';
|
||||
|
||||
interface Props {
|
||||
job: CombinedJob;
|
||||
}
|
||||
|
||||
export const DatafeedPreviewPane: FC<Props> = ({ job }) => {
|
||||
const {
|
||||
jobs: { datafeedPreview },
|
||||
} = useMlApiContext();
|
||||
|
||||
const canPreviewDatafeed = usePermissionCheck('canPreviewDatafeed');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [previewJson, setPreviewJson] = useState<string | null>('');
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
datafeedPreview(job.datafeed_config.datafeed_id).then((resp) => {
|
||||
if (Array.isArray(resp)) {
|
||||
if (resp.length === 0) {
|
||||
setPreviewJson(null);
|
||||
} else {
|
||||
setPreviewJson(JSON.stringify(resp.slice(0, ML_DATA_PREVIEW_COUNT), null, 2));
|
||||
}
|
||||
} else {
|
||||
setPreviewJson('');
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
});
|
||||
}, [datafeedPreview, job]);
|
||||
|
||||
if (canPreviewDatafeed === false) {
|
||||
return <InsufficientPermissions />;
|
||||
}
|
||||
|
||||
return loading ? (
|
||||
<EuiLoadingSpinner size="xl" />
|
||||
) : (
|
||||
<>
|
||||
{previewJson === null ? (
|
||||
<EmptyResults />
|
||||
) : (
|
||||
<MLJobEditor value={previewJson} readOnly={true} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const InsufficientPermissions: FC = () => (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.noPermissionToViewDatafeedPreviewTitle"
|
||||
defaultMessage="You do not have permission to view the datafeed preview"
|
||||
/>
|
||||
}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.pleaseContactYourAdministratorLabel"
|
||||
defaultMessage="Please contact your administrator"
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
|
||||
const EmptyResults: FC = () => (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.noResults.title"
|
||||
defaultMessage="No results"
|
||||
/>
|
||||
}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.jobsList.jobDetails.noResults.text"
|
||||
defaultMessage="Note: Datafeed preview does not return results from frozen tiers."
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
|
@ -368,8 +368,7 @@ export const jobsApiProvider = (httpService: HttpService) => ({
|
|||
) {
|
||||
const body = JSON.stringify({ jobId, snapshotId, replay, end, calendarEvents });
|
||||
return httpService.http<{
|
||||
total: number;
|
||||
categories: Array<{ count?: number; category: Category }>;
|
||||
success: boolean;
|
||||
}>({
|
||||
path: `${ML_BASE_PATH}/jobs/revert_model_snapshot`,
|
||||
method: 'POST',
|
||||
|
@ -379,10 +378,7 @@ export const jobsApiProvider = (httpService: HttpService) => ({
|
|||
|
||||
datafeedPreview(datafeedId?: string, job?: Job, datafeed?: Datafeed) {
|
||||
const body = JSON.stringify({ datafeedId, job, datafeed });
|
||||
return httpService.http<{
|
||||
total: number;
|
||||
categories: Array<{ count?: number; category: Category }>;
|
||||
}>({
|
||||
return httpService.http<unknown[]>({
|
||||
path: `${ML_BASE_PATH}/jobs/datafeed_preview`,
|
||||
method: 'POST',
|
||||
body,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue