Skip to content

Commit

Permalink
Ensure disappering datasets get removed from filter
Browse files Browse the repository at this point in the history
  • Loading branch information
weltenwort committed Apr 30, 2020
1 parent 162a9d2 commit d3cf524
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 93 deletions.
22 changes: 22 additions & 0 deletions x-pack/plugins/infra/common/log_analysis/job_parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,25 @@ export const combineDatasetFilters = (
datasets: [...includedDatasets],
};
};

export const filterDatasetFilter = (
datasetFilter: DatasetFilter,
predicate: (dataset: string) => boolean
): DatasetFilter => {
if (datasetFilter.type === 'includeAll') {
return datasetFilter;
} else {
const newDatasets = datasetFilter.datasets.filter(predicate);

if (newDatasets.length > 0) {
return {
type: 'includeSome',
datasets: newDatasets,
};
} else {
return {
type: 'includeAll',
};
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
*/

import { isEqual } from 'lodash';
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { usePrevious } from 'react-use';
import {
combineDatasetFilters,
DatasetFilter,
filterDatasetFilter,
isExampleDataIndex,
} from '../../../../common/log_analysis';
import {
Expand Down Expand Up @@ -45,14 +46,82 @@ export const useAnalysisSetupState = <JobType extends string>({
const [startTime, setStartTime] = useState<number | undefined>(Date.now() - fourWeeksInMs);
const [endTime, setEndTime] = useState<number | undefined>(undefined);

const [validatedIndices, dispatchAvailableIndexAction] = useReducer(
reduceAvailableIndicesState,
const [validatedIndices, setValidatedIndices] = useState<AvailableIndex[]>(
sourceConfiguration.indices.map(indexName => ({
name: indexName,
validity: 'unknown' as const,
}))
);

const updateIndicesWithValidationErrors = useCallback(
(validationErrors: ValidationIndicesError[]) =>
setValidatedIndices(availableIndices =>
availableIndices.map(previousAvailableIndex => {
const indexValiationErrors = validationErrors.filter(
({ index }) => index === previousAvailableIndex.name
);

if (indexValiationErrors.length > 0) {
return {
validity: 'invalid',
name: previousAvailableIndex.name,
errors: indexValiationErrors,
};
} else if (previousAvailableIndex.validity === 'valid') {
return {
...previousAvailableIndex,
validity: 'valid',
errors: [],
};
} else {
return {
validity: 'valid',
name: previousAvailableIndex.name,
isSelected: !isExampleDataIndex(previousAvailableIndex.name),
availableDatasets: [],
datasetFilter: {
type: 'includeAll' as const,
},
};
}
})
),
[]
);

const updateIndicesWithAvailableDatasets = useCallback(
(availableDatasets: Array<{ indexName: string; datasets: string[] }>) =>
setValidatedIndices(availableIndices =>
availableIndices.map(previousAvailableIndex => {
if (previousAvailableIndex.validity !== 'valid') {
return previousAvailableIndex;
}

const availableDatasetsForIndex = availableDatasets.filter(
({ indexName }) => indexName === previousAvailableIndex.name
);
const newAvailableDatasets = availableDatasetsForIndex.flatMap(
({ datasets }) => datasets
);

// filter out datasets that have disappeared if this index' datasets were updated
const newDatasetFilter: DatasetFilter =
availableDatasetsForIndex.length > 0
? filterDatasetFilter(previousAvailableIndex.datasetFilter, dataset =>
newAvailableDatasets.includes(dataset)
)
: previousAvailableIndex.datasetFilter;

return {
...previousAvailableIndex,
availableDatasets: newAvailableDatasets,
datasetFilter: newDatasetFilter,
};
})
),
[]
);

const validIndexNames = useMemo(
() => validatedIndices.filter(index => index.validity === 'valid').map(index => index.name),
[validatedIndices]
Expand All @@ -78,15 +147,6 @@ export const useAnalysisSetupState = <JobType extends string>({
[validatedIndices]
);

const setValidatedIndices = useCallback(
(valueOrFunc: AvailableIndex[] | ((validateIndices: AvailableIndex[]) => AvailableIndex[])) =>
dispatchAvailableIndexAction({
type: 'legacySet',
valueOrFunc,
}),
[]
);

const [validateIndicesRequest, validateIndices] = useTrackedPromise(
{
cancelPreviousOn: 'resolution',
Expand All @@ -97,10 +157,7 @@ export const useAnalysisSetupState = <JobType extends string>({
);
},
onResolve: ({ data: { errors } }) => {
dispatchAvailableIndexAction({
type: 'updateWithValidationErrors',
validationErrors: errors,
});
updateIndicesWithValidationErrors(errors);
},
onReject: () => {
setValidatedIndices([]);
Expand All @@ -125,10 +182,7 @@ export const useAnalysisSetupState = <JobType extends string>({
);
},
onResolve: ({ data: { datasets } }) => {
dispatchAvailableIndexAction({
type: 'updateWithAvailableDatasets',
availableDatasets: datasets,
});
updateIndicesWithAvailableDatasets(datasets);
},
},
[validIndexNames, sourceConfiguration.timestampField, startTime, endTime]
Expand Down Expand Up @@ -208,76 +262,3 @@ export const useAnalysisSetupState = <JobType extends string>({
validationErrors,
};
};

type AvailableIndicesAction =
| {
type: 'legacySet';
valueOrFunc: AvailableIndex[] | ((i: AvailableIndex[]) => AvailableIndex[]);
}
| { type: 'updateWithValidationErrors'; validationErrors: ValidationIndicesError[] }
| { type: 'select'; indexName: string }
| {
type: 'updateWithAvailableDatasets';
availableDatasets: Array<{ indexName: string; datasets: string[] }>;
};

const reduceAvailableIndicesState = (
state: AvailableIndex[],
action: AvailableIndicesAction
): AvailableIndex[] => {
switch (action.type) {
case 'legacySet':
if (typeof action.valueOrFunc === 'function') {
return action.valueOrFunc(state);
} else {
return action.valueOrFunc;
}
case 'updateWithValidationErrors':
return state.map(previousAvailableIndex => {
const indexValiationErrors = action.validationErrors.filter(
({ index }) => index === previousAvailableIndex.name
);

if (indexValiationErrors.length > 0) {
return {
validity: 'invalid',
name: previousAvailableIndex.name,
errors: indexValiationErrors,
};
} else if (previousAvailableIndex.validity === 'valid') {
return {
...previousAvailableIndex,
validity: 'valid',
errors: [],
};
} else {
return {
validity: 'valid',
name: previousAvailableIndex.name,
isSelected: !isExampleDataIndex(previousAvailableIndex.name),
availableDatasets: [],
datasetFilter: {
type: 'includeAll' as const,
},
};
}
});
case 'updateWithAvailableDatasets':
return state.map(previousAvailableIndex => {
if (previousAvailableIndex.validity !== 'valid') {
return previousAvailableIndex;
}

const datasetsForIndex = action.availableDatasets
.filter(({ indexName }) => indexName === previousAvailableIndex.name)
.flatMap(({ datasets }) => datasets);

return {
...previousAvailableIndex,
availableDatasets: datasetsForIndex,
};
});
case 'select':
return state;
}
};

0 comments on commit d3cf524

Please sign in to comment.