Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field Search in Data panel #995

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
abbashus marked this conversation as resolved.
Show resolved Hide resolved
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { i18n } from '@osd/i18n';
import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { setSearchField } from '../../utils/state_management/datasource_slice';
import { useTypedDispatch } from '../../utils/state_management';

export interface Props {
/**
* the input value of the user
*/
value?: string;
}

/**
* Component is Wizard's side bar to search of available fields
* Additionally there's a button displayed that allows the user to show/hide more filter fields
*/
export function FieldSearch({ value }: Props) {
const searchPlaceholder = i18n.translate('wizard.fieldChooser.searchPlaceHolder', {
defaultMessage: 'Search field names',
});

const dispatch = useTypedDispatch();

return (
<React.Fragment>
<EuiFlexGroup responsive={false} gutterSize={'s'}>
<EuiFlexItem>
<EuiFieldSearch
aria-label={searchPlaceholder}
data-test-subj="fieldFilterSearchInput"
compressed
fullWidth
onChange={(event) => dispatch(setSearchField(event.currentTarget.value))}
placeholder={searchPlaceholder}
value={value}
/>
</EuiFlexItem>
</EuiFlexGroup>
</React.Fragment>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';

import {
EuiFormLabel,
EuiFlexItem,
EuiAccordion,
EuiSpacer,
EuiNotificationBadge,
EuiTitle,
} from '@elastic/eui';
import React, { useCallback, useState, useEffect } from 'react';
import { EuiFlexItem, EuiAccordion, EuiSpacer, EuiNotificationBadge, EuiTitle } from '@elastic/eui';
import { FieldSearch } from './field_search';

import {
IndexPatternField,
Expand All @@ -39,7 +32,19 @@ const META_FIELDS: string[] = [

export const FieldSelector = () => {
const indexFields = useTypedSelector((state) => state.dataSource.visualizableFields);
const fields = indexFields?.reduce<IFieldCategories>(
const [filteredFields, setFilteredFields] = useState(indexFields);
abbashus marked this conversation as resolved.
Show resolved Hide resolved
const fieldSearchValue = useTypedSelector((state) => state.dataSource.searchField);

useEffect(() => {
const filteredSubset = indexFields.filter((field) =>
field.displayName.includes(fieldSearchValue)
);

setFilteredFields(filteredSubset);
return;
}, [indexFields, fieldSearchValue]);

const fields = filteredFields?.reduce<IFieldCategories>(
(fieldGroups, currentField) => {
const category = getFieldCategory(currentField);
fieldGroups[category].push(currentField);
Expand All @@ -56,7 +61,9 @@ export const FieldSelector = () => {
return (
<div className="wizFieldSelector">
<div>
<EuiFormLabel>TODO: Search goes here</EuiFormLabel>
<form>
<FieldSearch value={fieldSearchValue} />
</form>
</div>
<div className="wizFieldSelector__fieldGroups">
<FieldGroup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ const ALLOWED_FIELDS: string[] = [OSD_FIELD_TYPES.STRING, OSD_FIELD_TYPES.NUMBER
interface DataSourceState {
indexPattern: IndexPattern | null;
visualizableFields: IndexPatternField[];
searchField: string;
}

const initialState: DataSourceState = {
indexPattern: null,
visualizableFields: [],
searchField: '',
};

export const slice = createSlice({
Expand All @@ -28,14 +30,17 @@ export const slice = createSlice({
state.indexPattern = action.payload;
state.visualizableFields = action.payload.fields.filter(isVisualizable);
},
setSearchField: (state, action: PayloadAction<string>) => {
state.searchField = action.payload;
},
},
});

export const { reducer } = slice;
export const { setIndexPattern } = slice.actions;
export const { setIndexPattern, setSearchField } = slice.actions;

// TODO: Temporary validate function
// Need to identify hopw to get fieldCounts to use the standard filter and group functions
// Need to identify how to get fieldCounts to use the standard filter and group functions
function isVisualizable(field: IndexPatternField): boolean {
const isAggregatable = field.aggregatable === true;
const isNotScripted = !field.scripted;
Expand Down