Skip to content

Commit

Permalink
[UnifiedFieldList] Lazy load some modules
Browse files Browse the repository at this point in the history
  • Loading branch information
jughosta committed Dec 16, 2022
1 parent 4327b66 commit 57c3335
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/plugins/unified_field_list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const { fieldListFiltersProps, fieldListGroupedProps } = useGroupedFields({

## Utils

* `getFieldIconProps(field)` - gets icon's props to use with `<FieldIcon {...getFieldIconProps(field)} />` component

* `getFieldIconType(field)` - gets icon's type for the field

* `getFieldTypeName(field)` - gets a field type label to show to the user
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@
import React from 'react';
import { shallow } from 'enzyme';
import { stubLogstashDataView as dataView } from '@kbn/data-views-plugin/common/data_view.stub';
import { FieldIcon } from './field_icon';
import { getFieldType } from '../../utils/field_types';
import FieldIcon from './field_icon';
import { getFieldIconProps } from './get_field_icon_props';

const dateField = dataView.getFieldByName('@timestamp')!;
const scriptedField = dataView.getFieldByName('script date')!;

describe('UnifiedFieldList <FieldIcon />', () => {
test('renders properly', () => {
const component = shallow(<FieldIcon type={getFieldType(dateField)} />);
const component = shallow(<FieldIcon {...getFieldIconProps(dateField)} />);
expect(component).toMatchSnapshot();
});

test('renders properly scripted fields', () => {
const component = shallow(<FieldIcon {...getFieldIconProps(scriptedField)} />);
expect(component).toMatchSnapshot();
});

test('accepts additional props', () => {
const component = shallow(<FieldIcon type={getFieldType(dateField)} fill="none" />);
const component = shallow(<FieldIcon {...getFieldIconProps(dateField)} fill="none" />);
expect(component).toMatchSnapshot();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@

import React from 'react';
import { FieldIcon as KbnFieldIcon, FieldIconProps as KbnFieldIconProps } from '@kbn/react-field';
import { type DataViewField } from '@kbn/data-views-plugin/common';
import { type FieldListItem } from '../../types';
import { getFieldIconType, getFieldTypeName } from '../../utils/field_types';
import { getFieldTypeName } from '../../utils/field_types';

export type FieldIconProps = KbnFieldIconProps;

export const FieldIcon: React.FC<FieldIconProps> = ({ type, ...rest }) => {
const InnerFieldIcon: React.FC<FieldIconProps> = ({ type, ...rest }) => {
return <KbnFieldIcon type={normalizeFieldType(type)} label={getFieldTypeName(type)} {...rest} />;
};

export function getFieldIconProps<T extends FieldListItem = DataViewField>(
field: T
): FieldIconProps {
return {
type: getFieldIconType(field),
scripted: field.scripted,
};
}
export type GenericFieldIcon = typeof InnerFieldIcon;
const FieldIcon = React.memo(InnerFieldIcon) as GenericFieldIcon;

// Necessary for React.lazy
// eslint-disable-next-line import/no-default-export
export default FieldIcon;

function normalizeFieldType(type: string) {
if (type === 'histogram') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { type DataViewField } from '@kbn/data-views-plugin/common';
import { FieldListItem } from '../../types';
import { getFieldIconType } from '../../utils/field_types';
import { type FieldIconProps } from './field_icon';

export function getFieldIconProps<T extends FieldListItem = DataViewField>(
field: T
): FieldIconProps {
return {
type: getFieldIconType(field),
scripted: field.scripted,
};
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { Fragment } from 'react';
import { type DataViewField } from '@kbn/data-views-plugin/common';
import type { FieldIconProps, GenericFieldIcon } from './field_icon';
import { type FieldListItem } from '../../types';

const Fallback = () => <Fragment />;

const LazyFieldIcon = React.lazy(() => import('./field_icon')) as GenericFieldIcon;

function WrappedFieldIcon<T extends FieldListItem = DataViewField>(props: FieldIconProps) {
return (
<React.Suspense fallback={<Fallback />}>
<LazyFieldIcon {...props} />
</React.Suspense>
);
}

export const FieldIcon = WrappedFieldIcon;
export type { FieldIconProps };
export { getFieldIconProps } from './get_field_icon_props';
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const containerStyle = css`
height: 100%;
`;

/**
* A top level wrapper props
* @public
*/
export interface FieldListProps {
'data-test-subj'?: string;
isProcessing: boolean;
Expand All @@ -24,6 +28,17 @@ export interface FieldListProps {
className?: string;
}

/**
* A top level wrapper for field list components (filters and field list groups)
* @param dataTestSubject
* @param isProcessing
* @param prepend
* @param append
* @param className
* @param children
* @public
* @constructor
*/
export const FieldList: React.FC<FieldListProps> = ({
'data-test-subj': dataTestSubject = 'fieldList',
isProcessing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { FieldNameSearch, type FieldNameSearchProps } from './field_name_search'
import { FieldTypeFilter, type FieldTypeFilterProps } from './field_type_filter';
import { type FieldListItem } from '../../types';

/**
* Props for FieldListFilters component
*/
export interface FieldListFiltersProps<T extends FieldListItem> {
'data-test-subj'?: string;
docLinks: FieldTypeFilterProps<T>['docLinks'];
Expand All @@ -25,7 +28,23 @@ export interface FieldListFiltersProps<T extends FieldListItem> {
onChangeNameFilter: FieldNameSearchProps['onChange'];
}

export function FieldListFilters<T extends FieldListItem = DataViewField>({
/**
* Field list filters which include search by field name and filtering by field type.
* Use in combination with `useGroupedFields` hook. Or for more control - `useFieldFilters()` hook.
* @param dataTestSubject
* @param docLinks
* @param selectedFieldTypes
* @param allFields
* @param getCustomFieldType
* @param onSupportedFieldFilter
* @param onChangeFieldTypes
* @param nameFilter
* @param screenReaderDescriptionId
* @param onChangeNameFilter
* @public
* @constructor
*/
function InnerFieldListFilters<T extends FieldListItem = DataViewField>({
'data-test-subj': dataTestSubject = 'fieldListFilters',
docLinks,
selectedFieldTypes,
Expand Down Expand Up @@ -59,3 +78,10 @@ export function FieldListFilters<T extends FieldListItem = DataViewField>({
/>
);
}

export type GenericFieldListFilters = typeof InnerFieldListFilters;
const FieldListFilters = React.memo(InnerFieldListFilters) as GenericFieldListFilters;

// Necessary for React.lazy
// eslint-disable-next-line import/no-default-export
export default FieldListFilters;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFieldSearch, type EuiFieldSearchProps } from '@elastic/eui';

/**
* Props for FieldNameSearch component
*/
export interface FieldNameSearchProps {
'data-test-subj': string;
append?: EuiFieldSearchProps['append'];
Expand All @@ -18,6 +21,15 @@ export interface FieldNameSearchProps {
onChange: (nameFilter: string) => unknown;
}

/**
* Search input for fields list
* @param dataTestSubject
* @param append
* @param nameFilter
* @param screenReaderDescriptionId
* @param onChange
* @constructor
*/
export const FieldNameSearch: React.FC<FieldNameSearchProps> = ({
'data-test-subj': dataTestSubject,
append,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ const filterButtonStyle = css`
}
`;

/**
* Props for FieldTypeFilter component
*/
export interface FieldTypeFilterProps<T extends FieldListItem> {
'data-test-subj': string;
docLinks: CoreStart['docLinks'];
Expand All @@ -63,6 +66,17 @@ export interface FieldTypeFilterProps<T extends FieldListItem> {
onChange: (fieldTypes: FieldTypeKnown[]) => unknown;
}

/**
* A popover with field type filters
* @param dataTestSubject
* @param docLinks
* @param allFields
* @param getCustomFieldType
* @param selectedFieldTypes
* @param onSupportedFieldFilter
* @param onChange
* @constructor
*/
export function FieldTypeFilter<T extends FieldListItem = DataViewField>({
'data-test-subj': dataTestSubject,
docLinks,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { Fragment } from 'react';
import { type DataViewField } from '@kbn/data-views-plugin/common';
import type { FieldListFiltersProps, GenericFieldListFilters } from './field_list_filters';
import { type FieldListItem } from '../../types';

const Fallback = () => <Fragment />;

const LazyFieldListFilters = React.lazy(
() => import('./field_list_filters')
) as GenericFieldListFilters;

function WrappedFieldListFilters<T extends FieldListItem = DataViewField>(
props: FieldListFiltersProps<T>
) {
return (
<React.Suspense fallback={<Fallback />}>
<LazyFieldListFilters<T> {...props} />
</React.Suspense>
);
}

export const FieldListFilters = WrappedFieldListFilters;
export type { FieldListFiltersProps };
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ const unknownInfo: ExistingFieldsInfo = {
const globalMap$ = new BehaviorSubject<ExistingFieldsByDataViewMap>(initialData); // for syncing between hooks
let lastFetchId: string = ''; // persist last fetch id to skip older requests/responses if any

/**
* Fetches info whether a field contains data or it's empty.
* Can be used in combination with `useQuerySubscriber` hook for gathering the required params.
* @param params
* @public
*/
export const useExistingFieldsFetcher = (
params: ExistingFieldsFetcherParams
): ExistingFieldsFetcher => {
Expand Down
14 changes: 14 additions & 0 deletions src/plugins/unified_field_list/public/hooks/use_field_filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { getFieldIconType } from '../utils/field_types';

const htmlId = htmlIdGenerator('fieldList');

/**
* Input params for useFieldFilters hook
*/
export interface FieldFiltersParams<T extends FieldListItem> {
allFields: T[] | null;
getCustomFieldType?: GetCustomFieldType<T>;
Expand All @@ -25,12 +28,23 @@ export interface FieldFiltersParams<T extends FieldListItem> {
};
}

/**
* Output of useFieldFilters hook
*/
export interface FieldFiltersResult<T extends FieldListItem> {
fieldSearchHighlight: string;
fieldListFiltersProps: FieldListFiltersProps<T>;
onFilterField?: (field: T) => boolean;
}

/**
* A hook for managing field search and filters state
* @param allFields
* @param getCustomFieldType
* @param onSupportedFieldFilter
* @param services
* @public
*/
export function useFieldFilters<T extends FieldListItem = DataViewField>({
allFields,
getCustomFieldType,
Expand Down

0 comments on commit 57c3335

Please sign in to comment.