"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.JobDetails = void 0; var _react = _interopRequireWildcard(require("react")); var _useDebounce = _interopRequireDefault(require("react-use/lib/useDebounce")); var _eui = require("@elastic/eui"); var _i18n = require("@kbn/i18n"); var _i18nReact = require("@kbn/i18n-react"); var _mlErrorUtils = require("@kbn/ml-error-utils"); var _new_job = require("../../../../common/constants/new_job"); var _job_utils = require("../../../../common/util/job_utils"); var _validation = require("../../../../common/constants/validation"); var _util = require("../../../application/jobs/new_job/common/job_validator/util"); var _locator = require("../../../../common/constants/locator"); var _context = require("../lens/context"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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. */ var STATE; (function (STATE) { STATE[STATE["DEFAULT"] = 0] = "DEFAULT"; STATE[STATE["VALIDATING"] = 1] = "VALIDATING"; STATE[STATE["SAVING"] = 2] = "SAVING"; STATE[STATE["SAVE_SUCCESS"] = 3] = "SAVE_SUCCESS"; STATE[STATE["SAVE_FAILED"] = 4] = "SAVE_FAILED"; })(STATE || (STATE = {})); const JobDetails = ({ children, createADJobInWizard, createADJob, layer, layerIndex, embeddable, incomingCreateError }) => { var _layer$jobType; const { services: { share, application, mlServices: { mlApiServices } } } = (0, _context.useMlFromLensKibanaContext)(); const [jobId, setJobId] = (0, _react.useState)(''); const [startJob, setStartJob] = (0, _react.useState)(true); const [runInRealTime, setRunInRealTime] = (0, _react.useState)(true); const [bucketSpan, setBucketSpan] = (0, _react.useState)(_new_job.DEFAULT_BUCKET_SPAN); const [jobIdValidationError, setJobIdValidationError] = (0, _react.useState)(''); const [bucketSpanValidationError, setBucketSpanValidationError] = (0, _react.useState)(''); const [state, setState] = (0, _react.useState)(STATE.DEFAULT); const [createError, setCreateError] = (0, _react.useState)(null); const jobType = (_layer$jobType = layer === null || layer === void 0 ? void 0 : layer.jobType) !== null && _layer$jobType !== void 0 ? _layer$jobType : _new_job.JOB_TYPE.GEO; async function createJob() { if (jobId === undefined || jobId === '') { return; } setState(STATE.SAVING); setCreateError(null); const result = await createADJob({ jobId, bucketSpan, embeddable, startJob, runInRealTime }); const error = checkForCreationErrors(result); if (error === null) { setState(STATE.SAVE_SUCCESS); } else { setState(STATE.SAVE_FAILED); setCreateError(error); } } const viewResults = (0, _react.useCallback)(async type => { const { timeRange } = embeddable.getInput(); const locator = share.url.locators.get(_locator.ML_APP_LOCATOR); if (locator) { const page = startJob ? type === _new_job.JOB_TYPE.MULTI_METRIC || type === _new_job.JOB_TYPE.GEO ? _locator.ML_PAGES.ANOMALY_EXPLORER : _locator.ML_PAGES.SINGLE_METRIC_VIEWER : _locator.ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; const pageState = startJob ? { jobIds: [jobId], timeRange } : { jobId }; const url = await locator.getUrl({ page, pageState }); application.navigateToUrl(url); } }, [jobId, embeddable, share, application, startJob]); function setStartJobWrapper(start) { setStartJob(start); setRunInRealTime(start && runInRealTime); } (0, _useDebounce.default)(function validateJobId() { if (jobId === undefined || jobId === '') { return; } setJobIdValidationError(''); setBucketSpanValidationError(''); const validationResults = (0, _job_utils.basicJobValidation)({ job_id: jobId, analysis_config: { detectors: [], bucket_span: bucketSpan } }, undefined, { max_model_memory_limit: '', effective_max_model_memory_limit: '' }, true); if (validationResults.contains('job_id_invalid')) { setJobIdValidationError(_i18n.i18n.translate('xpack.ml.newJob.wizard.validateJob.jobNameAllowedCharactersDescription', { defaultMessage: 'Job ID can contain lowercase alphanumeric (a-z and 0-9), hyphens or underscores; ' + 'must start and end with an alphanumeric character' })); } else if (validationResults.contains('job_id_invalid_max_length')) { setJobIdValidationError(_i18n.i18n.translate('xpack.ml.newJob.wizard.validateJob.jobIdInvalidMaxLengthErrorMessage', { defaultMessage: 'Job ID must be no more than {maxLength, plural, one {# character} other {# characters}} long.', values: { maxLength: _validation.JOB_ID_MAX_LENGTH } })); } else { mlApiServices.jobs.jobsExist([jobId]).then(resp => { if (resp[jobId].exists) { setJobIdValidationError(_i18n.i18n.translate('xpack.ml.newJob.wizard.validateJob.jobNameAlreadyExists', { defaultMessage: 'Job ID already exists. A job ID cannot be the same as an existing job or group.' })); } }).catch(error => { // eslint-disable-next-line no-console console.error('Could not validate whether job ID exists'); }); } if (validationResults.contains('bucket_span_invalid')) { setBucketSpanValidationError((0, _util.invalidTimeIntervalMessage)(bucketSpan)); } setState(STATE.DEFAULT); }, 500, [jobId, bucketSpan]); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, state !== STATE.SAVE_SUCCESS && state !== STATE.SAVING || incomingCreateError ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children !== null && children !== void 0 ? children : null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(_eui.EuiForm, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { label: _i18n.i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobId.title', { defaultMessage: 'Job ID' }), error: jobIdValidationError, isInvalid: jobIdValidationError !== '' }, /*#__PURE__*/_react.default.createElement(_eui.EuiFieldText, { "data-test-subj": `mlLensLayerJobIdInput_${layerIndex}`, value: jobId, onChange: e => { setJobId(e.target.value); setState(STATE.VALIDATING); } })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" }), /*#__PURE__*/_react.default.createElement(_eui.EuiAccordion, { "data-test-subj": `mlLensLayerAdditionalSettingsButton_${layerIndex}`, id: "additional-section", buttonContent: _i18n.i18n.translate('xpack.ml.embeddables.lensLayerFlyout.createJobCallout.additionalSettings.title', { defaultMessage: 'Additional settings' }) }, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" }), /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { label: _i18n.i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.bucketSpan.placeholder', { defaultMessage: 'Bucket span' }), error: bucketSpanValidationError, isInvalid: bucketSpanValidationError !== '' }, /*#__PURE__*/_react.default.createElement(_eui.EuiFieldText, { "data-test-subj": `mlLensLayerBucketSpanInput_${layerIndex}`, value: bucketSpan, onChange: e => { setBucketSpan(e.target.value); setState(STATE.VALIDATING); } })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" }), /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, null, /*#__PURE__*/_react.default.createElement(_eui.EuiCheckbox, { id: "startJob", "data-test-subj": `mlLensLayerStartJobCheckbox_${layerIndex}`, checked: startJob, onChange: e => setStartJobWrapper(e.target.checked), label: _i18n.i18n.translate('xpack.ml.embeddables.lensLayerFlyout.createJobCallout.additionalSettings.start', { defaultMessage: 'Start the job after saving' }) })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" }), /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, null, /*#__PURE__*/_react.default.createElement(_eui.EuiCheckbox, { id: "realTime", disabled: startJob === false, "data-test-subj": `mlLensLayerRealTimeCheckbox_${layerIndex}`, checked: runInRealTime, onChange: e => setRunInRealTime(e.target.checked), label: _i18n.i18n.translate('xpack.ml.embeddables.lensLayerFlyout.createJobCallout.additionalSettings.realTime', { defaultMessage: 'Leave the job running for new data' }) })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiButton, { disabled: state === STATE.VALIDATING || jobId === '' || jobIdValidationError !== '' || bucketSpanValidationError !== '', onClick: createJob.bind(null, layerIndex), size: "s", "data-test-subj": `mlLensLayerCreateJobButton_${layerIndex}` }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.lensLayerFlyout.createJobButton.saving", defaultMessage: "Create job" }))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiButtonEmpty, { onClick: createADJobInWizard.bind(null, layerIndex), size: "s", iconType: "popout", iconSide: "right", "data-test-subj": `mlLensLayerCreateWithWizardButton_${layerIndex}` }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.lensLayerFlyout.createJobButton", defaultMessage: "Create job using wizard" }))))) : null, state === STATE.SAVE_SUCCESS ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { gutterSize: "s", "data-test-subj": `mlLensLayerCompatible.jobCreated.success_${layerIndex}` }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, /*#__PURE__*/_react.default.createElement(_eui.EuiIcon, { type: "checkInCircleFilled", color: "success" }))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.flyout.flyoutAdditionalSettings.saveSuccess", defaultMessage: "Job created" })))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" }), /*#__PURE__*/_react.default.createElement(_eui.EuiButtonEmpty, { onClick: viewResults.bind(null, jobType), flush: "left", "data-test-subj": `mlLensLayerResultsButton_${layerIndex}` }, startJob === false ? /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.flyoutAdditionalSettings.saveSuccess.resultsLink.jobList", defaultMessage: "View in job management page" }) : jobType === _new_job.JOB_TYPE.MULTI_METRIC || jobType === _new_job.JOB_TYPE.GEO ? /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.flyoutAdditionalSettings.saveSuccess.resultsLink.multiMetric", defaultMessage: "View results in Anomaly Explorer" }) : /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.flyoutAdditionalSettings.saveSuccess.resultsLink.singleMetric", defaultMessage: "View results in Single Metric Viewer" }))) : null, state === STATE.SAVING && incomingCreateError === undefined ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.embeddables.flyoutAdditionalSettings.creatingJob", defaultMessage: "Creating job" })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, null)))) : null, state === STATE.SAVE_FAILED && createError !== null ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, null), /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, { color: "danger", title: createError.text }, createError.errorText)) : null, incomingCreateError ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, null), /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, { color: "danger", title: incomingCreateError.text }, incomingCreateError.errorText)) : null); }; exports.JobDetails = JobDetails; const checkForCreationErrors = result => { if (result.jobCreated.error) { return { text: _i18n.i18n.translate('xpack.ml.embeddables.flyoutAdditionalSettings.jobCreateError.jobCreated', { defaultMessage: 'Job could not be created.' }), errorText: (0, _mlErrorUtils.extractErrorMessage)(result.jobCreated.error) }; } else if (result.datafeedCreated.error) { return { text: _i18n.i18n.translate('xpack.ml.embeddables.flyoutAdditionalSettings.jobCreateError.datafeedCreated', { defaultMessage: 'Job created but datafeed could not be created.' }), errorText: (0, _mlErrorUtils.extractErrorMessage)(result.datafeedCreated.error) }; } else if (result.jobOpened.error) { return { text: _i18n.i18n.translate('xpack.ml.embeddables.flyoutAdditionalSettings.jobCreateError.jobOpened', { defaultMessage: 'Job and datafeed created but the job could not be opened.' }), errorText: (0, _mlErrorUtils.extractErrorMessage)(result.jobOpened.error) }; } else if (result.datafeedStarted.error) { return { text: _i18n.i18n.translate('xpack.ml.embeddables.flyoutAdditionalSettings.jobCreateError.datafeedStarted', { defaultMessage: 'Job and datafeed created but the datafeed could not be started.' }), errorText: (0, _mlErrorUtils.extractErrorMessage)(result.datafeedStarted.error) }; } else { return null; } };