[ML] Fix synching jobs from other spaces (#86086)

* [ML] Fix synching jobs from other spaces

* updating text in delete modal

* updating translations

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
James Gowdy 2020-12-17 09:08:17 +00:00 committed by GitHub
parent b201843e68
commit 2066b3d7ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 175 deletions

View file

@ -17,6 +17,7 @@ import {
EuiButtonEmpty,
EuiButton,
EuiLoadingSpinner,
EuiText,
} from '@elastic/eui';
import { deleteJobs } from '../utils';
@ -103,7 +104,7 @@ export const DeleteJobModal: FC<Props> = ({ setShowFunction, unsetShowFunction,
</div>
</div>
) : (
<>
<EuiText>
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.deleteMultipleJobsDescription"
defaultMessage="Deleting {jobsCount, plural, one {a job} other {multiple jobs}} can be time consuming.
@ -113,7 +114,7 @@ export const DeleteJobModal: FC<Props> = ({ setShowFunction, unsetShowFunction,
jobsCount: jobIds.length,
}}
/>
</>
</EuiText>
)}
</p>
</EuiModalBody>

View file

@ -1,167 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {
EuiConfirmModal,
EuiOverlayMask,
EUI_MODAL_CONFIRM_BUTTON,
EuiLoadingSpinner,
EuiSpacer,
} from '@elastic/eui';
import { deleteJobs } from '../utils';
import { DELETING_JOBS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants/jobs_list';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
export class DeleteJobModal extends Component {
static displayName = 'DeleteJobModal';
static propTypes = {
setShowFunction: PropTypes.func.isRequired,
unsetShowFunction: PropTypes.func.isRequired,
refreshJobs: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.state = {
jobs: [],
isModalVisible: false,
deleting: false,
};
this.refreshJobs = this.props.refreshJobs;
}
componentDidMount() {
if (typeof this.props.setShowFunction === 'function') {
this.props.setShowFunction(this.showModal);
}
}
componentWillUnmount() {
if (typeof this.props.unsetShowFunction === 'function') {
this.props.unsetShowFunction();
}
}
closeModal = () => {
this.setState({ isModalVisible: false });
};
showModal = (jobs) => {
this.setState({
jobs,
isModalVisible: true,
deleting: false,
});
};
deleteJob = () => {
this.setState({ deleting: true });
deleteJobs(this.state.jobs);
setTimeout(() => {
this.closeModal();
this.refreshJobs();
}, DELETING_JOBS_REFRESH_INTERVAL_MS);
};
setEL = (el) => {
if (el) {
this.el = el;
}
};
render() {
let modal;
if (this.state.isModalVisible) {
if (this.el && this.state.deleting === true) {
// work around to disable the modal's buttons if the jobs are being deleted
this.el.confirmButton.style.display = 'none';
this.el.cancelButton.textContent = i18n.translate(
'xpack.ml.jobsList.deleteJobModal.closeButtonLabel',
{
defaultMessage: 'Close',
}
);
}
const title = (
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.deleteJobsTitle"
defaultMessage="Delete {jobsCount, plural, one {{jobId}} other {# jobs}}?"
values={{
jobsCount: this.state.jobs.length,
jobId: this.state.jobs[0].id,
}}
/>
);
modal = (
<EuiOverlayMask>
<EuiConfirmModal
data-test-subj="mlDeleteJobConfirmModal"
ref={this.setEL}
title={title}
onCancel={this.closeModal}
onConfirm={this.deleteJob}
cancelButtonText={
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.deleteButtonLabel"
defaultMessage="Delete"
/>
}
buttonColor="danger"
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
className="eui-textBreakWord"
>
{this.state.deleting === true && (
<div>
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.deletingJobsStatusLabel"
defaultMessage="Deleting jobs"
/>
<EuiSpacer />
<div style={{ textAlign: 'center' }}>
<EuiLoadingSpinner size="l" />
</div>
</div>
)}
{this.state.deleting === false && (
<React.Fragment>
<p>
<FormattedMessage
id="xpack.ml.jobsList.deleteJobModal.deleteMultipleJobsDescription"
defaultMessage="Deleting {jobsCount, plural, one {a job} other {multiple jobs}} can be time consuming.
{jobsCount, plural, one {It} other {They}} will be deleted in the background
and may not disappear from the jobs list instantly."
values={{
jobsCount: this.state.jobs.length,
}}
/>
</p>
</React.Fragment>
)}
</EuiConfirmModal>
</EuiOverlayMask>
);
}
return <div>{modal}</div>;
}
}

View file

@ -114,6 +114,19 @@ export function jobSavedObjectServiceFactory(
await savedObjectsClient.delete(ML_SAVED_OBJECT_TYPE, job.id, { force: true });
}
async function _forceDeleteJob(jobType: JobType, jobId: string, namespace: string) {
const id = savedObjectId({
job_id: jobId,
datafeed_id: null,
type: jobType,
});
await internalSavedObjectsClient.delete(ML_SAVED_OBJECT_TYPE, id, {
namespace,
force: true,
});
}
async function createAnomalyDetectionJob(jobId: string, datafeedId?: string) {
await _createJob('anomaly-detector', jobId, datafeedId);
}
@ -122,6 +135,10 @@ export function jobSavedObjectServiceFactory(
await _deleteJob('anomaly-detector', jobId);
}
async function forceDeleteAnomalyDetectionJob(jobId: string, namespace: string) {
await _forceDeleteJob('anomaly-detector', jobId, namespace);
}
async function createDataFrameAnalyticsJob(jobId: string) {
await _createJob('data-frame-analytics', jobId);
}
@ -130,6 +147,10 @@ export function jobSavedObjectServiceFactory(
await _deleteJob('data-frame-analytics', jobId);
}
async function forceDeleteDataFrameAnalyticsJob(jobId: string, namespace: string) {
await _forceDeleteJob('data-frame-analytics', jobId, namespace);
}
async function bulkCreateJobs(jobs: Array<{ job: JobObject; namespaces: string[] }>) {
return await _bulkCreateJobs(jobs);
}
@ -325,7 +346,9 @@ export function jobSavedObjectServiceFactory(
createAnomalyDetectionJob,
createDataFrameAnalyticsJob,
deleteAnomalyDetectionJob,
forceDeleteAnomalyDetectionJob,
deleteDataFrameAnalyticsJob,
forceDeleteDataFrameAnalyticsJob,
addDatafeed,
deleteDatafeed,
filterJobsForSpace,

View file

@ -94,10 +94,14 @@ export function syncSavedObjectsFactory(
results.savedObjectsDeleted[job.jobId] = { success: true };
} else {
// Delete AD saved objects for jobs which no longer exist
const jobId = job.jobId;
const { jobId, namespaces } = job;
tasks.push(async () => {
try {
await jobSavedObjectService.deleteAnomalyDetectionJob(jobId);
if (namespaces !== undefined && namespaces.length) {
await jobSavedObjectService.forceDeleteAnomalyDetectionJob(jobId, namespaces[0]);
} else {
await jobSavedObjectService.deleteAnomalyDetectionJob(jobId);
}
results.savedObjectsDeleted[job.jobId] = { success: true };
} catch (error) {
results.savedObjectsDeleted[job.jobId] = {
@ -115,10 +119,14 @@ export function syncSavedObjectsFactory(
results.savedObjectsDeleted[job.jobId] = { success: true };
} else {
// Delete DFA saved objects for jobs which no longer exist
const jobId = job.jobId;
const { jobId, namespaces } = job;
tasks.push(async () => {
try {
await jobSavedObjectService.deleteDataFrameAnalyticsJob(jobId);
if (namespaces !== undefined && namespaces.length) {
await jobSavedObjectService.forceDeleteDataFrameAnalyticsJob(jobId, namespaces[0]);
} else {
await jobSavedObjectService.deleteDataFrameAnalyticsJob(jobId);
}
results.savedObjectsDeleted[job.jobId] = { success: true };
} catch (error) {
results.savedObjectsDeleted[job.jobId] = {

View file

@ -12498,7 +12498,6 @@
"xpack.ml.jobsList.deletedActionStatusText": "削除されました",
"xpack.ml.jobsList.deleteJobErrorMessage": "ジョブの削除に失敗しました",
"xpack.ml.jobsList.deleteJobModal.cancelButtonLabel": "キャンセル",
"xpack.ml.jobsList.deleteJobModal.closeButtonLabel": "閉じる",
"xpack.ml.jobsList.deleteJobModal.deleteButtonLabel": "削除",
"xpack.ml.jobsList.deleteJobModal.deleteJobsTitle": "{jobsCount, plural, one {{jobId}} other {# 件のジョブ}}を削除しますか?",
"xpack.ml.jobsList.deleteJobModal.deleteMultipleJobsDescription": "{jobsCount, plural, one {ジョブ} other {複数ジョブ}}の削除には時間がかかる場合があります。{jobsCount, plural, one {} other {}}バックグラウンドで削除され、ジョブリストからすぐに消えない場合があります。",

View file

@ -12512,7 +12512,6 @@
"xpack.ml.jobsList.deletedActionStatusText": "已删除",
"xpack.ml.jobsList.deleteJobErrorMessage": "作业无法删除",
"xpack.ml.jobsList.deleteJobModal.cancelButtonLabel": "取消",
"xpack.ml.jobsList.deleteJobModal.closeButtonLabel": "关闭",
"xpack.ml.jobsList.deleteJobModal.deleteButtonLabel": "删除",
"xpack.ml.jobsList.deleteJobModal.deleteJobsTitle": "删除 {jobsCount, plural, one {{jobId}} other {# 个作业}}",
"xpack.ml.jobsList.deleteJobModal.deleteMultipleJobsDescription": "删除{jobsCount, plural, one {一个作业} other {多个作业}}可能很费时。将在后台删除{jobsCount, plural, one {该作业} other {这些作业}},但删除的作业可能不会从作业列表中立即消失。",