import React , { Fragment , FC , useContext , useEffect , useState } from 'react' ; import { EuiSpacer } from '@elastic/eui' ; import { FormattedMessage } from '@kbn/i18n-react' ; import { JobCreatorContext } from '../../../job_creator_context' ; import { PopulationJobCreator } from '../../../../../common/job_creator' ; import { Results , ModelItem , Anomaly } from '../../../../../common/results_loader' ; import { LineChartData } from '../../../../../common/chart_loader' ; import { Field , AggFieldPair } from '../../../../../../../../../common/types/fields' ; import { getChartSettings , defaultChartSettings } from '../../../charts/common/settings' ; import { ChartGrid } from './chart_grid' ; import { getToastNotificationService } from '../../../../../../../services/toast_notification_service' ; type DetectorFieldValues = Record < number , string [ ] > ; export const PopulationDetectorsSummary = ( ) => { const { jobCreator : jc , chartLoader , resultsLoader , chartInterval , } = useContext ( JobCreatorContext ) ; const jobCreator = jc as PopulationJobCreator ; const [ aggFieldPairList , setAggFieldPairList ] = useState < AggFieldPair [ ] > ( jobCreator . aggFieldPairs ) ; const [ lineChartsData , setLineChartsData ] = useState < LineChartData > ( { } ) ; const [ loadingData , setLoadingData ] = useState ( false ) ; const [ modelData , setModelData ] = useState < Record < number , ModelItem [ ] > > ( [ ] ) ; const [ anomalyData , setAnomalyData ] = useState < Record < number , Anomaly [ ] > > ( [ ] ) ; const [ chartSettings , setChartSettings ] = useState ( defaultChartSettings ) ; const [ fieldValuesPerDetector , setFieldValuesPerDetector ] = useState < DetectorFieldValues > ( { } ) ; function setResultsWrapper ( results ) { setModelData ( results . model ) ; setAnomalyData ( results . anomalies ) ; } useEffect ( ( ) => { const subscription = resultsLoader . subscribeToResults ( setResultsWrapper ) ; return ( ) => { subscription . unsubscribe ( ) ; } ; } , [ ] ) ; useEffect ( ( ) => { if ( allDataReady ( ) ) { loadCharts ( ) ; } } , [ JSON . stringify ( fieldValuesPerDetector ) , jobCreator . populationField ] ) ; useEffect ( ( ) => { loadFieldExamples ( ) ; } , [ jobCreator . populationField ] ) ; async function loadCharts ( ) { if ( allDataReady ( ) ) { setLoadingData ( true ) ; try { const cs = getChartSettings ( jobCreator , chartInterval ) ; setChartSettings ( cs ) ; const resp = await chartLoader . loadPopulationCharts ( jobCreator . start , jobCreator . end , aggFieldPairList , jobCreator . populationField , cs . intervalMs , jobCreator . runtimeMappings , jobCreator . datafeedConfig . indices_options ) ; setLineChartsData ( resp ) ; } catch ( error ) { getToastNotificationService ( ) . displayErrorToast ( error ) ; setLineChartsData ( { } ) ; } setLoadingData ( false ) ; } } async function loadFieldExamples ( ) { const promises = [ ] ; aggFieldPairList . forEach ( ( af , i ) => { if ( af . by !== undefined && af . by . field !== null ) { promises . push ( ( async ( index , field ) => { return { index , fields : await chartLoader . loadFieldExampleValues ( field , jobCreator . runtimeMappings , jobCreator . datafeedConfig . indices_options ) , } ; } ) ( i , af . by . field ) ) ; } } ) ; const results = await Promise . all ( promises ) ; const fieldValues = results . reduce ( ( p , c ) => { p [ c . index ] = c . fields ; return p ; } , { } ) as DetectorFieldValues ; const newPairs = aggFieldPairList . map ( ( pair , i ) => ( { ... pair , ... ( pair . by === undefined || pair . by . field === null ? { } : { by : { ... pair . by , value : fieldValues [ i ] [ 0 ] , } , } ) , } ) ) ; setAggFieldPairList ( [ ... newPairs ] ) ; setFieldValuesPerDetector ( fieldValues ) ; } function allDataReady ( ) { let ready = aggFieldPairList . length > 0 ; aggFieldPairList . forEach ( ( af ) => { if ( af . by !== undefined && af . by . field !== null ) { ready = ready && af . by . value !== null ; } } ) ; return ready ; } return ( < Fragment > { jobCreator . populationField !== null && ( < Fragment > < FormattedMessage id = "xpack.ml.newJob.wizard.pickFieldsStep.populationView.splitFieldTitle" defaultMessage = "Population split by {field}" values = { { field : jobCreator . populationField . name } } /> < EuiSpacer / > < ChartGrid aggFieldPairList = { jobCreator . aggFieldPairs } chartSettings = { chartSettings } splitField = { jobCreator . populationField } lineChartsData = { lineChartsData } modelData = { modelData } anomalyData = { anomalyData } jobType = { jobCreator . type } fieldValuesPerDetector = { fieldValuesPerDetector } loading = { loadingData } / > < /Fragment>)} < /Fragment>); } ;