diff --git a/x-pack/plugins/ml/common/util/job_utils.ts b/x-pack/plugins/ml/common/util/job_utils.ts index 6063511879448..4f4d9851c4957 100644 --- a/x-pack/plugins/ml/common/util/job_utils.ts +++ b/x-pack/plugins/ml/common/util/job_utils.ts @@ -49,6 +49,22 @@ export function calculateDatafeedFrequencyDefaultSeconds(bucketSpanSeconds: numb return freq; } +export function hasRuntimeMappings(job: CombinedJob): boolean { + const hasDatafeed = + typeof job.datafeed_config === 'object' && Object.keys(job.datafeed_config).length > 0; + if (hasDatafeed) { + const runtimeMappings = + typeof job.datafeed_config.runtime_mappings === 'object' + ? Object.keys(job.datafeed_config.runtime_mappings) + : undefined; + + if (Array.isArray(runtimeMappings) && runtimeMappings.length > 0) { + return true; + } + } + return false; +} + export function isTimeSeriesViewJob(job: CombinedJob): boolean { return getSingleMetricViewerJobErrorMessage(job) === undefined; } @@ -94,10 +110,10 @@ export function isSourceDataChartableForDetector(job: CombinedJob, detectorIndex scriptFields.indexOf(dtr.over_field_name!) === -1; } - // We cannot plot the source data for some specific aggregation configurations const hasDatafeed = typeof job.datafeed_config === 'object' && Object.keys(job.datafeed_config).length > 0; if (hasDatafeed) { + // We cannot plot the source data for some specific aggregation configurations const aggs = getDatafeedAggregations(job.datafeed_config); if (aggs !== undefined) { const aggBucketsName = getAggregationBucketsName(aggs); @@ -110,6 +126,11 @@ export function isSourceDataChartableForDetector(job: CombinedJob, detectorIndex } } } + + // We also cannot plot the source data if they datafeed uses any field defined by runtime_mappings + if (hasRuntimeMappings(job)) { + return false; + } } } @@ -149,6 +170,12 @@ export function isModelPlotChartableForDetector(job: Job, detectorIndex: number) // Returns a reason to indicate why the job configuration is not supported // if the result is undefined, that means the single metric job should be viewable export function getSingleMetricViewerJobErrorMessage(job: CombinedJob): string | undefined { + // if job has runtime mappings with no model plot + if (hasRuntimeMappings(job) && !job.model_plot_config?.enabled) { + return i18n.translate('xpack.ml.timeSeriesJob.jobWithRunTimeMessage', { + defaultMessage: 'the datafeed contains runtime fields and model plot is disabled', + }); + } // only allow jobs with at least one detector whose function corresponds to // an ES aggregation which can be viewed in the single metric view and which // doesn't use a scripted field which can be very difficult or impossible to