Skip to content

Commit

Permalink
Improve multi field code
Browse files Browse the repository at this point in the history
  • Loading branch information
kertal committed Dec 21, 2023
1 parent 30dfec6 commit f747c2e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,14 @@ function getCommonFieldItemButtonProps({
};
}

export interface FieldListMultiField {
field: DataViewField;
isSelected: boolean;
}

interface MultiFieldsProps {
stateService: UnifiedFieldListSidebarContainerStateService;
multiFields: NonNullable<UnifiedFieldListItemProps['multiFields']>;
multiFields: NonNullable<FieldListMultiField[]>;
toggleDisplay: (field: DataViewField) => void;
alwaysShowActionButton: boolean;
size: FieldItemButtonProps<DataViewField>['size'];
Expand Down Expand Up @@ -163,9 +168,9 @@ export interface UnifiedFieldListItemProps {
*/
trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void;
/**
* Multi fields for the current field
* Get multi fields for the given field
*/
multiFields?: Array<{ field: DataViewField; isSelected: boolean }>;
getMultiFields?: (field: DataViewField) => FieldListMultiField[] | undefined;
/**
* Callback to edit a field from data view
* @param fieldName name of the field to edit
Expand Down Expand Up @@ -212,7 +217,7 @@ function UnifiedFieldListItemComponent({
isEmpty,
isSelected,
trackUiMetric,
multiFields,
getMultiFields,
onEditField,
onDeleteField,
workspaceSelectedFieldNames,
Expand Down Expand Up @@ -253,8 +258,6 @@ function UnifiedFieldListItemComponent({
[onAddFieldToWorkspace, onRemoveFieldFromWorkspace, closePopover]
);

const rawMultiFields = useMemo(() => multiFields?.map((f) => f.field), [multiFields]);

const customPopoverHeaderProps: Partial<FieldPopoverHeaderProps> = useMemo(() => {
const dataTestSubjPrefix =
stateService.creationOptions.dataTestSubj?.fieldListItemPopoverHeaderDataTestSubjPrefix;
Expand All @@ -275,6 +278,9 @@ function UnifiedFieldListItemComponent({
}, [field.name, stateService.creationOptions]);

const renderPopover = () => {
const multiFields = getMultiFields?.(field);
const rawMultiFields = multiFields?.map((f) => f.field);

return (
<>
<UnifiedFieldListItemStats
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ToolbarButton } from '@kbn/shared-ux-button-toolbar';
import { DataViewField } from '@kbn/data-views-plugin/common';
import { getDataViewFieldSubtypeMulti } from '@kbn/es-query/src/utils';
import { FIELDS_LIMIT_SETTING, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
import { FieldListMultiField } from '../unified_field_list_item/field_list_item';
import { FieldList } from '../../components/field_list';
import { FieldListFilters } from '../../components/field_list_filters';
import { FieldListGrouped, type FieldListGroupedProps } from '../../components/field_list_grouped';
Expand Down Expand Up @@ -170,9 +171,6 @@ export const UnifiedFieldListSidebarComponent: React.FC<UnifiedFieldListSidebarP
const [selectedFieldsState, setSelectedFieldsState] = useState<SelectedFieldsResult>(
INITIAL_SELECTED_FIELDS_RESULT
);
const [multiFieldsMap, setMultiFieldsMap] = useState<
Map<string, Array<{ field: DataViewField; isSelected: boolean }>> | undefined
>(undefined);

useEffect(() => {
const result = getSelectedFields({
Expand Down Expand Up @@ -230,27 +228,28 @@ export const UnifiedFieldListSidebarComponent: React.FC<UnifiedFieldListSidebarP
},
});

useEffect(() => {
const useMultiFields = useMemo(() => {
if (
searchMode !== 'documents' ||
!useNewFieldsApi ||
stateService.creationOptions.disableMultiFieldsGroupingByParent
) {
setMultiFieldsMap(undefined); // we don't have to calculate multifields in this case
return false;
} else {
setMultiFieldsMap(
calculateMultiFields(allFieldsModified, selectedFieldsState.selectedFieldsMap)
);
return true;
}
}, [
stateService.creationOptions.disableMultiFieldsGroupingByParent,
selectedFieldsState.selectedFieldsMap,
allFieldsModified,
useNewFieldsApi,
setMultiFieldsMap,
searchMode,
]);

const getMultiFieldsByField = useCallback(
(field: DataViewField) =>
getMultiFieldsByParent(field, allFieldsModified, selectedFieldsState.selectedFieldsMap),
[allFieldsModified, selectedFieldsState.selectedFieldsMap]
);

const renderFieldItem: FieldListGroupedProps<DataViewField>['renderFieldItem'] = useCallback(
({ field, groupName, groupIndex, itemIndex, fieldSearchHighlight }) => (
<li key={`field${field.name}`} data-attr-field={field.name}>
Expand All @@ -267,7 +266,7 @@ export const UnifiedFieldListSidebarComponent: React.FC<UnifiedFieldListSidebarP
onRemoveFieldFromWorkspace={onRemoveFieldFromWorkspace}
onAddFilter={onAddFilter}
trackUiMetric={trackUiMetric}
multiFields={multiFieldsMap?.get(field.name)} // ideally we better calculate multifields when they are requested first from the popover
getMultiFields={useMultiFields ? getMultiFieldsByField : undefined}
onEditField={onEditField}
onDeleteField={onDeleteField}
workspaceSelectedFieldNames={workspaceSelectedFieldNames}
Expand All @@ -292,7 +291,8 @@ export const UnifiedFieldListSidebarComponent: React.FC<UnifiedFieldListSidebarP
onRemoveFieldFromWorkspace,
onAddFilter,
trackUiMetric,
multiFieldsMap,
useMultiFields,
getMultiFieldsByField,
onEditField,
onDeleteField,
workspaceSelectedFieldNames,
Expand Down Expand Up @@ -438,27 +438,26 @@ export const UnifiedFieldListSidebar = memo(UnifiedFieldListSidebarComponent);
// eslint-disable-next-line import/no-default-export
export default UnifiedFieldListSidebar;

function calculateMultiFields(
export function getMultiFieldsByParent(
parentField: DataViewField,
allFields: DataViewField[] | null,
selectedFieldsMap: SelectedFieldsResult['selectedFieldsMap'] | undefined
) {
if (!allFields) {
if (!allFields || !parentField) {
return undefined;
}
const map = new Map<string, Array<{ field: DataViewField; isSelected: boolean }>>();
const result: FieldListMultiField[] = [];
allFields.forEach((field) => {
const subTypeMulti = getDataViewFieldSubtypeMulti(field);
const parent = subTypeMulti?.multi.parent;
if (!parent) {
if (!parent || parent !== parentField.name) {
return;
}
const multiField = {
field,
isSelected: Boolean(selectedFieldsMap?.[field.name]),
};
const value = map.get(parent) ?? [];
value.push(multiField);
map.set(parent, value);
result.push(multiField);
});
return map;
return result.length ? result : undefined;
}

0 comments on commit f747c2e

Please sign in to comment.