Skip to content

Commit

Permalink
fix current field candidates list
Browse files Browse the repository at this point in the history
  • Loading branch information
walterra committed Oct 11, 2024
1 parent 26cd1a5 commit 632b711
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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,
Expand All @@ -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: [],
Expand All @@ -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) => {
Expand All @@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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';
Expand Down Expand Up @@ -82,34 +83,23 @@ 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();

const { groupResults } = useAppSelector((s) => s.logRateAnalysis);
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
Expand All @@ -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,
Expand Down Expand Up @@ -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}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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)
),
});
}
Expand Down Expand Up @@ -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}>
Expand All @@ -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>
</>
)}
Expand Down

0 comments on commit 632b711

Please sign in to comment.