Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ declare const ValidateJob: FC<{
mlJobService: any;
embedded?: boolean;
setIsValid?: (valid: boolean) => void;
idFilterList?: string[];
}>;
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ class ValidateJob extends Component {
const isCurrentJobConfig = (this.props.isCurrentJobConfig !== true) ? false : true;
const isDisabled = (this.props.isDisabled !== true) ? false : true;
const embedded = (this.props.embedded === true);
const idFilterList = this.props.idFilterList || [];

return (
<Fragment>
Expand Down Expand Up @@ -271,9 +272,11 @@ class ValidateJob extends Component {
values={{ title: this.state.title }}
/>}
>
{this.state.data.messages.map(
(m, i) => <Callout key={`${m.id}_${i}`} message={m} />
)}
{
this.state.data.messages
.filter(m => idFilterList.includes(m.id) === false)
.map((m, i) => <Callout key={`${m.id}_${i}`} message={m} />)
}
<EuiText>
<FormattedMessage
id="xpack.ml.validateJob.modal.jobValidationDescriptionText"
Expand Down Expand Up @@ -303,9 +306,11 @@ class ValidateJob extends Component {
}
{embedded === true &&
<div>
{this.state.data.messages.map(
(m, i) => <Callout key={`${m.id}_${i}`} message={m} />
)}
{
this.state.data.messages
.filter(m => idFilterList.includes(m.id) === false)
.map((m, i) => <Callout key={`${m.id}_${i}`} message={m} />)
}
</div>
}
</Fragment>
Expand All @@ -322,6 +327,7 @@ ValidateJob.propTypes = {
mlJobService: PropTypes.object.isRequired,
embedded: PropTypes.bool,
setIsValid: PropTypes.func,
idFilterList: PropTypes.array,
};

export { ValidateJob };
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ChartSettings } from '../../../charts/common/settings';
import { LineChartData } from '../../../../../common/chart_loader';
import { ModelItem, Anomaly } from '../../../../../common/results_loader';
import { JOB_TYPE } from '../../../../../common/job_creator/util/constants';
import { SplitCards } from '../split_cards';
import { SplitCards, useAnimateSplit } from '../split_cards';
import { DetectorTitle } from '../detector_title';
import { AnomalyChart, CHART_TYPE } from '../../../charts/anomaly_chart';

Expand All @@ -26,6 +26,7 @@ interface ChartGridProps {
anomalyData: Record<number, Anomaly[]>;
deleteDetector?: (index: number) => void;
jobType: JOB_TYPE;
animate?: boolean;
}

export const ChartGrid: FC<ChartGridProps> = ({
Expand All @@ -39,12 +40,15 @@ export const ChartGrid: FC<ChartGridProps> = ({
deleteDetector,
jobType,
}) => {
const animateSplit = useAnimateSplit();

return (
<SplitCards
fieldValues={fieldValues}
splitField={splitField}
numberOfDetectors={aggFieldPairList.length}
jobType={jobType}
animate={animateSplit}
>
<EuiFlexGrid columns={chartSettings.cols}>
{aggFieldPairList.map((af, i) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { newJobCapsService } from '../../../../../../../services/new_job_capabil
import { AggFieldPair } from '../../../../../../../../common/types/fields';
import { defaultChartSettings, ChartSettings } from '../../../charts/common/settings';
import { MetricSelector } from './metric_selector';
import { JobProgress } from '../job_progress';
import { ChartGrid } from './chart_grid';

interface Props {
Expand Down Expand Up @@ -48,7 +47,7 @@ export const MultiMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {
const [anomalyData, setAnomalyData] = useState<Record<number, Anomaly[]>>([]);
const [start, setStart] = useState(jobCreator.start);
const [end, setEnd] = useState(jobCreator.end);
const [progress, setProgress] = useState(resultsLoader.progress);

const [chartSettings, setChartSettings] = useState(defaultChartSettings);
const [splitField, setSplitField] = useState(jobCreator.splitField);
const [fieldValues, setFieldValues] = useState<string[]>([]);
Expand Down Expand Up @@ -82,7 +81,6 @@ export const MultiMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {

useEffect(() => {
// subscribe to progress and results
jobCreator.subscribeToProgress(setProgress);
const subscription = resultsLoader.subscribeToResults(setResultsWrapper);
return () => {
subscription.unsubscribe();
Expand Down Expand Up @@ -190,9 +188,6 @@ export const MultiMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {
removeOptions={aggFieldPairList}
/>
)}
{isActive === false && (
<Fragment>{lineChartsData && <JobProgress progress={progress} />}</Fragment>
)}
</Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ import { MultiMetricSettings } from './settings';

interface Props {
isActive: boolean;
setCanProceed: (proceed: boolean) => void;
setCanProceed?: (proceed: boolean) => void;
}

export const MultiMetricView: FC<Props> = ({ isActive, setCanProceed }) => {
const [metricsValid, setMetricValid] = useState(false);
const [settingsValid, setSettingsValid] = useState(false);

useEffect(() => {
setCanProceed(metricsValid && settingsValid);
if (typeof setCanProceed === 'function') {
setCanProceed(metricsValid && settingsValid);
}
}, [metricsValid, settingsValid]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ChartSettings } from '../../../charts/common/settings';
import { LineChartData } from '../../../../../common/chart_loader';
import { ModelItem, Anomaly } from '../../../../../common/results_loader';
import { JOB_TYPE } from '../../../../../common/job_creator/util/constants';
import { SplitCards } from '../split_cards';
import { SplitCards, useAnimateSplit } from '../split_cards';
import { DetectorTitle } from '../detector_title';
import { ByFieldSelector } from '../split_field';
import { AnomalyChart, CHART_TYPE } from '../../../charts/anomaly_chart';
Expand Down Expand Up @@ -42,6 +42,8 @@ export const ChartGrid: FC<ChartGridProps> = ({
jobType,
fieldValuesPerDetector,
}) => {
const animateSplit = useAnimateSplit();

return (
<EuiFlexGrid columns={chartSettings.cols}>
{aggFieldPairList.map((af, i) => (
Expand All @@ -67,6 +69,7 @@ export const ChartGrid: FC<ChartGridProps> = ({
splitField={splitField}
numberOfDetectors={aggFieldPairList.length}
jobType={jobType}
animate={animateSplit}
>
<AnomalyChart
chartType={CHART_TYPE.SCATTER}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { newJobCapsService } from '../../../../../../../services/new_job_capabil
import { Field, AggFieldPair } from '../../../../../../../../common/types/fields';
import { defaultChartSettings, ChartSettings } from '../../../charts/common/settings';
import { MetricSelector } from './metric_selector';
import { JobProgress } from '../job_progress';
import { SplitFieldSelector } from '../split_field';
import { MlTimeBuckets } from '../../../../../../../util/ml_time_buckets';
import { ChartGrid } from './chart_grid';
Expand Down Expand Up @@ -53,7 +52,6 @@ export const PopulationDetectors: FC<Props> = ({ isActive, setIsValid }) => {
const [anomalyData, setAnomalyData] = useState<Record<number, Anomaly[]>>([]);
const [start, setStart] = useState(jobCreator.start);
const [end, setEnd] = useState(jobCreator.end);
const [progress, setProgress] = useState(resultsLoader.progress);
const [chartSettings, setChartSettings] = useState(defaultChartSettings);
const [splitField, setSplitField] = useState(jobCreator.splitField);
const [fieldValuesPerDetector, setFieldValuesPerDetector] = useState<DetectorFieldValues>({});
Expand Down Expand Up @@ -90,7 +88,6 @@ export const PopulationDetectors: FC<Props> = ({ isActive, setIsValid }) => {

useEffect(() => {
// subscribe to progress and results
jobCreator.subscribeToProgress(setProgress);
const subscription = resultsLoader.subscribeToResults(setResultsWrapper);
return () => {
subscription.unsubscribe();
Expand Down Expand Up @@ -262,9 +259,6 @@ export const PopulationDetectors: FC<Props> = ({ isActive, setIsValid }) => {
removeOptions={[]}
/>
)}
{isActive === false && (
<Fragment>{lineChartsData && <JobProgress progress={progress} />}</Fragment>
)}
</Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ import { PopulationSettings } from './settings';

interface Props {
isActive: boolean;
setCanProceed: (proceed: boolean) => void;
setCanProceed?: (proceed: boolean) => void;
}

export const PopulationView: FC<Props> = ({ isActive, setCanProceed }) => {
const [metricsValid, setMetricValid] = useState(false);
const [settingsValid, setSettingsValid] = useState(false);

useEffect(() => {
setCanProceed(metricsValid && settingsValid);
if (typeof setCanProceed === 'function') {
setCanProceed(metricsValid && settingsValid);
}
}, [metricsValid, settingsValid]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { AggSelect, DropDownLabel, DropDownProps, createLabel } from '../agg_sel
import { newJobCapsService } from '../../../../../../../services/new_job_capabilities_service';
import { AggFieldPair } from '../../../../../../../../common/types/fields';
import { AnomalyChart, CHART_TYPE } from '../../../charts/anomaly_chart';
import { JobProgress } from '../job_progress';

interface Props {
isActive: boolean;
Expand Down Expand Up @@ -50,7 +49,6 @@ export const SingleMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {
const [anomalyData, setAnomalyData] = useState<Anomaly[]>([]);
const [start, setStart] = useState(jobCreator.start);
const [end, setEnd] = useState(jobCreator.end);
const [progress, setProgress] = useState(resultsLoader.progress);

function detectorChangeHandler(selectedOptionsIn: DropDownLabel[]) {
setSelectedOptions(selectedOptionsIn);
Expand All @@ -77,7 +75,6 @@ export const SingleMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {

useEffect(() => {
// subscribe to progress and results
jobCreator.subscribeToProgress(setProgress);
const subscription = resultsLoader.subscribeToResults(setResultsWrapper);
return () => {
subscription.unsubscribe();
Expand Down Expand Up @@ -137,7 +134,6 @@ export const SingleMetricDetectors: FC<Props> = ({ isActive, setIsValid }) => {
height="300px"
width="100%"
/>
{isActive === false && <JobProgress progress={progress} />}
</Fragment>
)}
</Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ import { SingleMetricSettings } from './settings';

interface Props {
isActive: boolean;
setCanProceed: (proceed: boolean) => void;
setCanProceed?: (proceed: boolean) => void;
}

export const SingleMetricView: FC<Props> = ({ isActive, setCanProceed }) => {
const [metricsValid, setMetricValid] = useState(false);
const [settingsValid, setSettingsValid] = useState(false);

useEffect(() => {
setCanProceed(metricsValid && settingsValid);
if (typeof setCanProceed === 'function') {
setCanProceed(metricsValid && settingsValid);
}
}, [metricsValid, settingsValid]);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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 { useEffect, useState } from 'react';

export const ANIMATION_SWITCH_DELAY_MS = 1000;

// custom hook to enable the card split animation of the cards 1 second after the component has been rendered
// then switching to a step which contains the cards, the animation shouldn't play, instead
// the cards should be initially rendered in the split state.
// all subsequent changes to the split should be animated.

export function useAnimateSplit() {
const [animateSplit, setAnimateSplit] = useState(false);
useEffect(() => {
setTimeout(() => {
setAnimateSplit(true);
}, ANIMATION_SWITCH_DELAY_MS);
}, []);

return animateSplit;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*/

export { SplitCards } from './split_cards';
export { useAnimateSplit } from './animate_split_hook';
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface Props {
numberOfDetectors: number;
children: JSX.Element;
jobType: JOB_TYPE;
animate?: boolean;
}

interface Panel {
Expand All @@ -24,11 +25,14 @@ interface Panel {
}

export const SplitCards: FC<Props> = memo(
({ fieldValues, splitField, children, numberOfDetectors, jobType }) => {
({ fieldValues, splitField, children, numberOfDetectors, jobType, animate = false }) => {
const panels: Panel[] = [];

function storePanels(panel: HTMLDivElement | null, marginBottom: number) {
if (panel !== null) {
if (animate === false) {
panel.style.marginBottom = `${marginBottom}px`;
}
panels.push({ panel, marginBottom });
}
}
Expand All @@ -42,9 +46,11 @@ export const SplitCards: FC<Props> = memo(
let margin = 5;
const sideMargins = fieldValuesCopy.map((f, i) => (margin += 10 - i)).reverse();

setTimeout(() => {
panels.forEach(p => (p.panel.style.marginBottom = `${p.marginBottom}px`));
}, 100);
if (animate === true) {
setTimeout(() => {
panels.forEach(p => (p.panel.style.marginBottom = `${p.marginBottom}px`));
}, 100);
}

const SPACING = 100;
const SPLIT_HEIGHT_MULTIPLIER = 1.6;
Expand All @@ -59,7 +65,7 @@ export const SplitCards: FC<Props> = memo(
marginBottom: `-${SPACING}px`,
marginLeft: `${sideMargin}px`,
marginRight: `${sideMargin}px`,
transition: 'margin 0.2s',
...(animate ? { transition: 'margin 0.2s' } : {}),
};
return (
<div key={fieldName} ref={ref => storePanels(ref, marginBottom)} style={style}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ export const PickFieldsStep: FC<StepProps> = ({ setCurrentStep, isCurrentStep })

return (
<Fragment>
{jobType === JOB_TYPE.SINGLE_METRIC && (
<SingleMetricView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}
{jobType === JOB_TYPE.MULTI_METRIC && (
<MultiMetricView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}
{jobType === JOB_TYPE.POPULATION && (
<PopulationView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}

{isCurrentStep && (
<WizardNav
previous={() => setCurrentStep(WIZARD_STEPS.TIME_RANGE)}
next={() => setCurrentStep(WIZARD_STEPS.JOB_DETAILS)}
nextActive={nextActive}
/>
<Fragment>
{jobType === JOB_TYPE.SINGLE_METRIC && (
<SingleMetricView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}
{jobType === JOB_TYPE.MULTI_METRIC && (
<MultiMetricView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}
{jobType === JOB_TYPE.POPULATION && (
<PopulationView isActive={isCurrentStep} setCanProceed={setNextActive} />
)}
<WizardNav
previous={() => setCurrentStep(WIZARD_STEPS.TIME_RANGE)}
next={() => setCurrentStep(WIZARD_STEPS.JOB_DETAILS)}
nextActive={nextActive}
/>
</Fragment>
)}
</Fragment>
);
Expand Down
Loading