Skip to content

Commit

Permalink
[Enterprise Search] [Search application] Adding filter by field type …
Browse files Browse the repository at this point in the history
…to Schema Page (#154466)

## Summary
Adding Filter by field type component to Schema page and display callout when showing field conflicts

[thread](https://elastic.slack.com/archives/C02U50QNEAG/p1680627458702419?thread_ts=1680288487.778129&cid=C02U50QNEAG)

### Screen Recording


https://user-images.githubusercontent.com/55930906/230146041-4978335d-ad6e-4594-8e01-4e688a580b5a.mov

#### [Edit] Updated Popover clear all button with eraser


<img width="1712" alt="Popover with clear all button with eraser"
src="https://user-images.githubusercontent.com/55930906/230461760-5161b26a-6d76-4a65-8eab-48b45381683f.png">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
saarikabhasi and kibanamachine authored Apr 10, 2023
1 parent 17ed210 commit 1f8dc16
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,31 @@ import {
EuiBadge,
EuiBasicTable,
EuiBasicTableColumn,
EuiButton,
EuiButtonEmpty,
EuiCallOut,
EuiFilterButton,
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiLink,
EuiPanel,
EuiPopover,
EuiPopoverFooter,
EuiPopoverTitle,
EuiSelectable,
EuiSwitch,
EuiText,
} from '@elastic/eui';

import { ES_FIELD_TYPES } from '@kbn/field-types';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';

import { FieldIcon } from '@kbn/react-field';

import { SchemaField } from '../../../../../common/types/engines';

import { docLinks } from '../../../shared/doc_links';
import { generateEncodedPath } from '../../../shared/encode_path_params';
import { KibanaLogic } from '../../../shared/kibana';
Expand All @@ -36,7 +48,6 @@ import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_temp
import { EngineIndicesLogic } from './engine_indices_logic';

import { EngineViewLogic } from './engine_view_logic';
import { FieldIcon } from './field_icon';

const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaField }) => {
const { navigateToUrl } = useValues(KibanaLogic);
Expand Down Expand Up @@ -147,20 +158,49 @@ export const EngineSchema: React.FC = () => {
const [onlyShowConflicts, setOnlyShowConflicts] = useState<boolean>(false);
const { isLoadingEngineSchema, schemaFields } = useValues(EngineViewLogic);
const { fetchEngineSchema } = useActions(EngineViewLogic);

const [isFilterByPopoverOpen, setIsFilterByPopoverOpen] = useState<boolean>(false);
const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<Record<string, JSX.Element>>(
{}
);
// get all the elasticsearch Field Types
const esFieldTypes = Object.values(ES_FIELD_TYPES).map((fieldDataTypeName) => ({
checked: undefined,
label: fieldDataTypeName.toString(),
}));
const [selectedEsFieldTypes, setSelectedEsFieldTypes] = useState(esFieldTypes);

const toggleOnlyShowConflicts = useCallback(() => {
setOnlyShowConflicts(!onlyShowConflicts);
setItemIdToExpandedRowMap({});
}, [onlyShowConflicts]);

const filteredSchemaFields = useMemo(() => {
// update filteredDataTypes as filter by field types are selected
const filteredDataTypes = useMemo(() => {
const selectedDataTypes = selectedEsFieldTypes
.filter((option) => option.checked === 'on')
.map((option) => option.label);
return selectedDataTypes;
}, [selectedEsFieldTypes]);

// return schema fields may be with conflicts
const schemaFieldsMaybeWithConflicts = useMemo(() => {
if (onlyShowConflicts) return schemaFields.filter((field) => field.type === 'conflict');
return schemaFields;
}, [onlyShowConflicts, schemaFields]);

const filteredSchemaFields = useMemo(() => {
if (filteredDataTypes.length > 0)
return schemaFieldsMaybeWithConflicts.filter((field) =>
field.indices.some((i) => filteredDataTypes.includes(i.type))
);
return schemaFieldsMaybeWithConflicts;
}, [onlyShowConflicts, schemaFields, filteredDataTypes]);

const totalConflictsHiddenByTypeFilters = onlyShowConflicts
? schemaFieldsMaybeWithConflicts.length - filteredSchemaFields.length
: 0;

useEffect(() => {
fetchEngineSchema({ engineName });
}, [engineName]);
Expand Down Expand Up @@ -287,6 +327,21 @@ export const EngineSchema: React.FC = () => {
width: '10%',
},
];
const filterButton = (
<EuiFilterButton
iconType="arrowDown"
iconSide="right"
onClick={() => setIsFilterByPopoverOpen(!isFilterByPopoverOpen)}
numFilters={selectedEsFieldTypes.length}
hasActiveFilters={filteredDataTypes.length > 0}
numActiveFilters={filteredDataTypes.length}
isSelected={isFilterByPopoverOpen}
>
{i18n.translate('xpack.enterpriseSearch.content.engine.schema.filters', {
defaultMessage: 'Field types',
})}
</EuiFilterButton>
);

return (
<EnterpriseSearchEnginesPageTemplate
Expand All @@ -300,28 +355,116 @@ export const EngineSchema: React.FC = () => {
}}
engineName={engineName}
>
<EuiFlexGroup direction="column" gutterSize="l">
<EuiFlexGroup>
<EuiSwitch
label={i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.onlyShowConflicts',
{
defaultMessage: 'Only show conflicts',
}
)}
checked={onlyShowConflicts}
onChange={toggleOnlyShowConflicts}
<>
<EuiFlexGroup direction="column" gutterSize="l">
<EuiFlexGroup>
<EuiSwitch
label={i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.onlyShowConflicts',
{
defaultMessage: 'Only show conflicts',
}
)}
checked={onlyShowConflicts}
onChange={toggleOnlyShowConflicts}
/>
<EuiFlexGroup justifyContent="flexEnd" alignItems="center">
<EuiFlexItem grow={false}>
{i18n.translate('xpack.enterpriseSearch.content.engine.schema.filters.label', {
defaultMessage: 'Filter By',
})}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPopover
button={filterButton}
isOpen={isFilterByPopoverOpen}
closePopover={() => setIsFilterByPopoverOpen(false)}
panelPaddingSize="none"
anchorPosition="downCenter"
>
<EuiSelectable
searchable
searchProps={{
placeholder: i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.filters.searchPlaceholder',
{
defaultMessage: 'Filter list ',
}
),
}}
options={selectedEsFieldTypes}
onChange={(options) => setSelectedEsFieldTypes(options)}
>
{(list, search) => (
<div style={{ width: 300 }}>
<EuiPopoverTitle paddingSize="s">{search}</EuiPopoverTitle>
{list}
</div>
)}
</EuiSelectable>
<EuiPopoverFooter>
<EuiFlexGroup justifyContent="spaceAround">
<EuiButtonEmpty
color="danger"
iconType="eraser"
size="s"
onClick={() => setSelectedEsFieldTypes(esFieldTypes)}
>
{i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.filters.clearAll',
{
defaultMessage: 'Clear all ',
}
)}
</EuiButtonEmpty>
</EuiFlexGroup>
</EuiPopoverFooter>
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>

<EuiBasicTable
items={filteredSchemaFields}
columns={columns}
loading={isLoadingEngineSchema}
itemId="name"
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
isExpandable
/>
{totalConflictsHiddenByTypeFilters > 0 && (
<EuiCallOut
title={
<FormattedMessage
id="xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.title"
defaultMessage="There are {totalConflictsHiddenByTypeFilters, number} more {totalConflictsHiddenByTypeFilters, plural, one {conflict} other {conflicts}} not displayed here"
values={{ totalConflictsHiddenByTypeFilters }}
/>
}
color="danger"
iconType="iInCircle"
>
<p>
{i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.subTitle',
{
defaultMessage:
'In order to see all field conflicts you must clear your field filters',
}
)}
</p>
<EuiButton fill color="danger" onClick={() => setSelectedEsFieldTypes(esFieldTypes)}>
{i18n.translate(
'xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.clearFilters',
{
defaultMessage: 'Clear filters ',
}
)}
</EuiButton>
</EuiCallOut>
)}
</EuiFlexGroup>
<EuiBasicTable
items={filteredSchemaFields}
columns={columns}
loading={isLoadingEngineSchema}
itemId="name"
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
isExpandable
/>
</EuiFlexGroup>
</>
</EnterpriseSearchEnginesPageTemplate>
);
};
1 change: 1 addition & 0 deletions x-pack/plugins/enterprise_search/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@
"@kbn/datemath",
"@kbn/expressions-plugin",
"@kbn/react-field",
"@kbn/field-types",
]
}

0 comments on commit 1f8dc16

Please sign in to comment.