function loadForJobId(jobId) { // Validation that the ID is for a time series job must already have been performed. // Check if the job was created since the page was first loaded. let jobPickerSelectedJob = _.find($scope.jobs, { 'id': jobId }); if (jobPickerSelectedJob === undefined) { const newJobs = []; _.each(mlJobService.jobs, (job) => { if (isTimeSeriesViewJob(job) === true) { const bucketSpan = parseInterval(job.analysis_config.bucket_span); newJobs.push({ id: job.job_id, selected: false, bucketSpanSeconds: bucketSpan.asSeconds() }); } }); $scope.jobs = newJobs; jobPickerSelectedJob = _.find(newJobs, { 'id': jobId }); } $scope.selectedJob = mlJobService.getJob(jobId); $scope.jobPickerSelections = [jobPickerSelectedJob]; // Read the detector index and entities out of the AppState. const jobDetectors = $scope.selectedJob.analysis_config.detectors; const viewableDetectors = []; _.each(jobDetectors, (dtr, index) => { if (isTimeSeriesViewDetector($scope.selectedJob, index)) { viewableDetectors.push({ index: '' + index, detector_description: dtr.detector_description }); } }); $scope.detectors = viewableDetectors; // Check the supplied index is valid. const appStateDtrIdx = $scope.appState.mlTimeSeriesExplorer.detectorIndex; let detectorIndex = appStateDtrIdx !== undefined ? appStateDtrIdx : +(viewableDetectors[0].index); if (_.find(viewableDetectors, { 'index': '' + detectorIndex }) === undefined) { const warningText = i18n.translate('xpack.ml.timeSeriesExplorer.requestedDetectorIndexNotValidWarningMessage', { defaultMessage: 'Requested detector index {detectorIndex} is not valid for job {jobId}', values: { detectorIndex, jobId: $scope.selectedJob.job_id } }); toastNotifications.addWarning(warningText); detectorIndex = +(viewableDetectors[0].index); $scope.appState.mlTimeSeriesExplorer.detectorIndex = detectorIndex; $scope.appState.save(); } // Store the detector index as a string so it can be used as ng-model in a select control. $scope.detectorId = '' + detectorIndex; updateControlsForDetector(); // Populate the map of jobs / detectors / field formatters for the selected IDs and refresh. mlFieldFormatService.populateFormats([jobId], getIndexPatterns()) .catch((err) => { console.log('Error populating field formats:', err); }) // Load the data - if the FieldFormats failed to populate // the default formatting will be used for metric values. .then(() => { $scope.refresh(); }); }
function ( $scope, $route, timefilter) { timefilter.disableTimeRangeSelector(); // remove time picker from top of page timefilter.disableAutoRefreshSelector(); // remove time picker from top of page $scope.indexPatterns = getIndexPatterns(); $scope.withIndexPatternUrl = function (pattern) { if (!pattern) { return; } return '#/jobs/new_job/step/job_type?index=' + encodeURIComponent(pattern.id); }; $scope.withSavedSearchUrl = function (savedSearch) { if (!savedSearch) { return; } return '#/jobs/new_job/step/job_type?savedSearchId=' + encodeURIComponent(savedSearch.id); }; });
$scope.setSelectedJobs = function (selectedIds, keepSwimlaneSelection = false) { let previousSelected = 0; if ($scope.selectedJobs !== null) { previousSelected = $scope.selectedJobs.length; } // Check for any new jobs created since the page was first loaded, // and whether any of the jobs have influencers configured (in which // case the Top Influencers section will be hidden). let recreateJobs = false; let hasInfluencers = false; selectedIds.forEach((id) => { if (recreateJobs === false && _.find($scope.jobs, { id }) === undefined) { recreateJobs = true; } const job = mlJobService.getJob(id); let influencers = []; if (job !== undefined) { influencers = job.analysis_config.influencers || []; } hasInfluencers = hasInfluencers || influencers.length > 0; }); if (recreateJobs === true) { $scope.jobs = createJobs(mlJobService.jobs); } $scope.noInfluencersConfigured = !hasInfluencers; // update the jobs' selected flag $scope.selectedJobs = []; _.each($scope.jobs, (job) => { job.selected = (_.indexOf(selectedIds, job.id) !== -1); if (job.selected) { $scope.selectedJobs.push(job); } }); // Clear viewBy from the state if we are moving from single // to multi selection, or vice-versa. $scope.appState.fetch(); if ((previousSelected <= 1 && $scope.selectedJobs.length > 1) || ($scope.selectedJobs.length === 1 && previousSelected > 1)) { delete $scope.appState.mlExplorerSwimlane.viewBy; } $scope.appState.save(); // Populate the map of jobs / detectors / field formatters for the selected IDs. mlFieldFormatService.populateFormats(selectedIds, getIndexPatterns()) .catch((err) => { console.log('Error populating field formats:', err); }) .then(() => { // Load the data - if the FieldFormats failed to populate // the default formatting will be used for metric values. loadOverallData(); if (keepSwimlaneSelection === false) { clearSelectedAnomalies(); } else { restoreCellDataFromAppState(); updateExplorer(); } $scope.$applyAsync(); }); };