mirror of
https://github.com/elastic/kibana.git
synced 2025-04-19 23:39:42 -04:00
fix current field candidates list
This commit is contained in:
parent
26cd1a53df
commit
632b711ca1
4 changed files with 59 additions and 43 deletions
|
@ -9,14 +9,16 @@ import { httpServiceMock } from '@kbn/core/public/mocks';
|
|||
|
||||
import type { FetchFieldCandidatesResponse } from '../queries/fetch_field_candidates';
|
||||
|
||||
import { fetchFieldCandidates } from './log_rate_analysis_field_candidates_slice';
|
||||
import { fetchFieldCandidates, getDefaultState } from './log_rate_analysis_field_candidates_slice';
|
||||
|
||||
const mockHttp = httpServiceMock.createStartContract();
|
||||
|
||||
describe('fetchFieldCandidates', () => {
|
||||
it('dispatches field candidates', async () => {
|
||||
const mockDispatch = jest.fn();
|
||||
const mockGetState = jest.fn();
|
||||
const mockGetState = jest.fn().mockReturnValue({
|
||||
logRateAnalysisFieldCandidates: getDefaultState(),
|
||||
});
|
||||
|
||||
const mockResponse: FetchFieldCandidatesResponse = {
|
||||
isECS: false,
|
||||
|
@ -60,7 +62,12 @@ describe('fetchFieldCandidates', () => {
|
|||
payload: {
|
||||
fieldSelectionMessage:
|
||||
'2 out of 5 fields were preselected for the analysis. Use the "Fields" dropdown to adjust the selection.',
|
||||
fieldFilterSkippedItems: [
|
||||
initialFieldFilterSkippedItems: [
|
||||
'another-keyword-field',
|
||||
'another-text-field',
|
||||
'yet-another-text-field',
|
||||
],
|
||||
currentFieldFilterSkippedItems: [
|
||||
'another-keyword-field',
|
||||
'another-text-field',
|
||||
'yet-another-text-field',
|
||||
|
|
|
@ -90,10 +90,14 @@ export const fetchFieldCandidates = createAsyncThunk(
|
|||
...selectedKeywordFieldCandidates,
|
||||
...selectedTextFieldCandidates,
|
||||
];
|
||||
const fieldFilterSkippedItems = fieldFilterUniqueItems.filter(
|
||||
const initialFieldFilterSkippedItems = fieldFilterUniqueItems.filter(
|
||||
(d) => !fieldFilterUniqueSelectedItems.includes(d)
|
||||
);
|
||||
|
||||
const currentFieldFilterSkippedItems = (
|
||||
thunkApi.getState() as { logRateAnalysisFieldCandidates: FieldCandidatesState }
|
||||
).logRateAnalysisFieldCandidates.currentFieldFilterSkippedItems;
|
||||
|
||||
thunkApi.dispatch(
|
||||
setAllFieldCandidates({
|
||||
fieldSelectionMessage: getFieldSelectionMessage(
|
||||
|
@ -102,7 +106,13 @@ export const fetchFieldCandidates = createAsyncThunk(
|
|||
fieldFilterUniqueSelectedItems.length
|
||||
),
|
||||
fieldFilterUniqueItems,
|
||||
fieldFilterSkippedItems,
|
||||
initialFieldFilterSkippedItems,
|
||||
// If the currentFieldFilterSkippedItems is null, we're on the first load,
|
||||
// only then we set the current skipped fields to the initial skipped fields.
|
||||
currentFieldFilterSkippedItems:
|
||||
currentFieldFilterSkippedItems === null && initialFieldFilterSkippedItems.length > 0
|
||||
? initialFieldFilterSkippedItems
|
||||
: currentFieldFilterSkippedItems,
|
||||
keywordFieldCandidates,
|
||||
textFieldCandidates,
|
||||
selectedKeywordFieldCandidates,
|
||||
|
@ -116,18 +126,20 @@ export interface FieldCandidatesState {
|
|||
isLoading: boolean;
|
||||
fieldSelectionMessage?: string;
|
||||
fieldFilterUniqueItems: string[];
|
||||
fieldFilterSkippedItems: string[];
|
||||
initialFieldFilterSkippedItems: string[];
|
||||
currentFieldFilterSkippedItems: string[] | null;
|
||||
keywordFieldCandidates: string[];
|
||||
textFieldCandidates: string[];
|
||||
selectedKeywordFieldCandidates: string[];
|
||||
selectedTextFieldCandidates: string[];
|
||||
}
|
||||
|
||||
function getDefaultState(): FieldCandidatesState {
|
||||
export function getDefaultState(): FieldCandidatesState {
|
||||
return {
|
||||
isLoading: false,
|
||||
fieldFilterUniqueItems: [],
|
||||
fieldFilterSkippedItems: [],
|
||||
initialFieldFilterSkippedItems: [],
|
||||
currentFieldFilterSkippedItems: null,
|
||||
keywordFieldCandidates: [],
|
||||
textFieldCandidates: [],
|
||||
selectedKeywordFieldCandidates: [],
|
||||
|
@ -145,6 +157,12 @@ export const logRateAnalysisFieldCandidatesSlice = createSlice({
|
|||
) => {
|
||||
return { ...state, ...action.payload };
|
||||
},
|
||||
setCurrentFieldFilterSkippedItems: (
|
||||
state: FieldCandidatesState,
|
||||
action: PayloadAction<string[]>
|
||||
) => {
|
||||
return { ...state, currentFieldFilterSkippedItems: action.payload };
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(fetchFieldCandidates.pending, (state) => {
|
||||
|
@ -157,4 +175,5 @@ export const logRateAnalysisFieldCandidatesSlice = createSlice({
|
|||
});
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { setAllFieldCandidates } = logRateAnalysisFieldCandidatesSlice.actions;
|
||||
export const { setAllFieldCandidates, setCurrentFieldFilterSkippedItems } =
|
||||
logRateAnalysisFieldCandidatesSlice.actions;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import type { FC } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
|
||||
|
@ -23,6 +23,7 @@ import {
|
|||
setSkippedColumns,
|
||||
type LogRateAnalysisResultsTableColumnName,
|
||||
} from '@kbn/aiops-log-rate-analysis/state/log_rate_analysis_table_slice';
|
||||
import { setCurrentFieldFilterSkippedItems } from '@kbn/aiops-log-rate-analysis/state/log_rate_analysis_field_candidates_slice';
|
||||
|
||||
import { ItemFilterPopover as FieldFilterPopover } from './item_filter_popover';
|
||||
import { ItemFilterPopover as ColumnFilterPopover } from './item_filter_popover';
|
||||
|
@ -82,13 +83,11 @@ const resultsGroupedOnId = 'aiopsLogRateAnalysisGroupingOn';
|
|||
export interface LogRateAnalysisOptionsProps {
|
||||
foundGroups: boolean;
|
||||
growFirstItem?: boolean;
|
||||
onFieldsFilterChange: (skippedFieldsUpdate: string[]) => void;
|
||||
}
|
||||
|
||||
export const LogRateAnalysisOptions: FC<LogRateAnalysisOptionsProps> = ({
|
||||
foundGroups,
|
||||
growFirstItem = false,
|
||||
onFieldsFilterChange,
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
@ -96,20 +95,11 @@ export const LogRateAnalysisOptions: FC<LogRateAnalysisOptionsProps> = ({
|
|||
const { isRunning } = useAppSelector((s) => s.logRateAnalysisStream);
|
||||
const fieldCandidates = useAppSelector((s) => s.logRateAnalysisFieldCandidates);
|
||||
const { skippedColumns } = useAppSelector((s) => s.logRateAnalysisTable);
|
||||
const { fieldFilterUniqueItems, fieldFilterSkippedItems } = fieldCandidates;
|
||||
const { fieldFilterUniqueItems, initialFieldFilterSkippedItems } = fieldCandidates;
|
||||
const fieldFilterButtonDisabled =
|
||||
isRunning || fieldCandidates.isLoading || fieldFilterUniqueItems.length === 0;
|
||||
const toggleIdSelected = groupResults ? resultsGroupedOnId : resultsGroupedOffId;
|
||||
|
||||
// null is used as the uninitialized state to identify the first load.
|
||||
const [skippedFields, setSkippedFields] = useState<string[] | null>(null);
|
||||
|
||||
// Set skipped fields only on first load, otherwise we'd overwrite the user's selection.
|
||||
useEffect(() => {
|
||||
if (skippedFields === null && fieldFilterSkippedItems.length > 0)
|
||||
setSkippedFields(fieldFilterSkippedItems);
|
||||
}, [fieldFilterSkippedItems, skippedFields]);
|
||||
|
||||
const onGroupResultsToggle = (optionId: string) => {
|
||||
dispatch(setGroupResults(optionId === resultsGroupedOnId));
|
||||
// When toggling the group switch, clear all row selections
|
||||
|
@ -120,9 +110,8 @@ export const LogRateAnalysisOptions: FC<LogRateAnalysisOptionsProps> = ({
|
|||
dispatch(setSkippedColumns(columns));
|
||||
};
|
||||
|
||||
const onFieldsFilterChangeHandler = (skippedFieldsUpdate: string[]) => {
|
||||
setSkippedFields(skippedFieldsUpdate);
|
||||
onFieldsFilterChange(skippedFieldsUpdate);
|
||||
const onFieldsFilterChange = (skippedFieldsUpdate: string[]) => {
|
||||
dispatch(setCurrentFieldFilterSkippedItems(skippedFieldsUpdate));
|
||||
};
|
||||
|
||||
// Disable the grouping switch toggle only if no groups were found,
|
||||
|
@ -173,8 +162,8 @@ export const LogRateAnalysisOptions: FC<LogRateAnalysisOptionsProps> = ({
|
|||
popoverButtonTitle={fieldsButton}
|
||||
selectedItemLimit={1}
|
||||
uniqueItemNames={fieldFilterUniqueItems}
|
||||
initialSkippedItems={fieldFilterSkippedItems}
|
||||
onChange={onFieldsFilterChangeHandler}
|
||||
initialSkippedItems={initialFieldFilterSkippedItems}
|
||||
onChange={onFieldsFilterChange}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -135,21 +135,27 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
setEmbeddableOptionsVisible((s) => !s);
|
||||
};
|
||||
|
||||
const onFieldsFilterChange = (skippedFieldsUpdate: string[]) => {
|
||||
const { currentFieldFilterSkippedItems, keywordFieldCandidates, textFieldCandidates } =
|
||||
fieldCandidates;
|
||||
|
||||
useEffect(() => {
|
||||
if (currentFieldFilterSkippedItems === null) return;
|
||||
|
||||
dispatch(resetResults());
|
||||
setOverrides({
|
||||
loaded: 0,
|
||||
remainingKeywordFieldCandidates: keywordFieldCandidates.filter(
|
||||
(d) => !skippedFieldsUpdate.includes(d)
|
||||
(d) => !currentFieldFilterSkippedItems.includes(d)
|
||||
),
|
||||
remainingTextFieldCandidates: textFieldCandidates.filter(
|
||||
(d) => !skippedFieldsUpdate.includes(d)
|
||||
(d) => !currentFieldFilterSkippedItems.includes(d)
|
||||
),
|
||||
regroupOnly: false,
|
||||
});
|
||||
startHandler(true, false);
|
||||
};
|
||||
const { fieldFilterSkippedItems, keywordFieldCandidates, textFieldCandidates } = fieldCandidates;
|
||||
// custom check to trigger on currentFieldFilterSkippedItems change
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentFieldFilterSkippedItems]);
|
||||
|
||||
function cancelHandler() {
|
||||
abortCtrl.current.abort();
|
||||
|
@ -209,10 +215,12 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
dispatch(resetResults());
|
||||
setOverrides({
|
||||
remainingKeywordFieldCandidates: keywordFieldCandidates.filter(
|
||||
(d) => fieldFilterSkippedItems !== null && fieldFilterSkippedItems.includes(d)
|
||||
(d) =>
|
||||
currentFieldFilterSkippedItems === null || !currentFieldFilterSkippedItems.includes(d)
|
||||
),
|
||||
remainingTextFieldCandidates: textFieldCandidates.filter(
|
||||
(d) => fieldFilterSkippedItems !== null && fieldFilterSkippedItems.includes(d)
|
||||
(d) =>
|
||||
currentFieldFilterSkippedItems === null || !currentFieldFilterSkippedItems.includes(d)
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -325,10 +333,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
>
|
||||
<>
|
||||
{embeddingOrigin !== AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD && (
|
||||
<LogRateAnalysisOptions
|
||||
foundGroups={foundGroups}
|
||||
onFieldsFilterChange={onFieldsFilterChange}
|
||||
/>
|
||||
<LogRateAnalysisOptions foundGroups={foundGroups} />
|
||||
)}
|
||||
{embeddingOrigin === AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD && (
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -354,11 +359,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s">
|
||||
<LogRateAnalysisOptions
|
||||
foundGroups={foundGroups}
|
||||
growFirstItem={true}
|
||||
onFieldsFilterChange={onFieldsFilterChange}
|
||||
/>
|
||||
<LogRateAnalysisOptions foundGroups={foundGroups} growFirstItem={true} />
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue