Skip to content

Commit

Permalink
Refactor and memoize top navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
kertal committed Feb 4, 2021
1 parent 30e976e commit 583781c
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 47 deletions.

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

52 changes: 5 additions & 47 deletions src/plugins/discover/public/application/components/discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import './discover.scss';
import React, { useState, useRef, useMemo, useCallback } from 'react';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import {
EuiButtonEmpty,
EuiButtonIcon,
Expand All @@ -32,7 +32,7 @@ import { LoadingSpinner } from './loading_spinner/loading_spinner';
import { DocTableLegacy } from '../angular/doc_table/create_doc_table_react';
import { SkipBottomButton } from './skip_bottom_button';
import { esFilters, IndexPatternField, search } from '../../../../data/public';
import { DiscoverSidebarResponsive } from './sidebar/discover_sidebar_responsive';
import { DiscoverSidebarResponsive } from './sidebar';
import { DiscoverProps } from './types';
import { getDisplayedColumns } from '../helpers/columns';
import { SortPairArr } from '../angular/doc_table/lib/get_sort';
Expand All @@ -41,54 +41,12 @@ import { popularizeField } from '../helpers/popularize_field';
import { getStateColumnActions } from '../angular/doc_table/actions/columns';
import { DocViewFilterFn } from '../doc_views/doc_views_types';
import { DiscoverGrid } from './discover_grid/discover_grid';
import { DiscoverTopNav } from './discover_topnav';

const DocTableLegacyMemoized = React.memo(DocTableLegacy);
const SidebarMemoized = React.memo(DiscoverSidebarResponsive);
const DataGridMemoized = React.memo(DiscoverGrid);

const TopNavWrapper = ({
topNavMenu,
indexPattern,
updateQuery,
state,
opts,
}: Pick<DiscoverProps, 'topNavMenu' | 'indexPattern' | 'updateQuery' | 'state' | 'opts'>) => {
const showDatePicker = useMemo(() => indexPattern.isTimeBased(), [indexPattern]);
const { TopNavMenu } = opts.services.navigation.ui;

const updateSavedQueryId = (newSavedQueryId: string | undefined) => {
const { appStateContainer, setAppState } = opts.stateContainer;
if (newSavedQueryId) {
setAppState({ savedQuery: newSavedQueryId });
} else {
// remove savedQueryId from state
const newState = {
...appStateContainer.getState(),
};
delete newState.savedQuery;
appStateContainer.set(newState);
}
};
return (
<TopNavMenu
appName="discover"
config={topNavMenu}
indexPatterns={[indexPattern]}
onQuerySubmit={updateQuery}
onSavedQueryIdChange={updateSavedQueryId}
query={state.query}
setMenuMountPoint={opts.setHeaderActionMenu}
savedQueryId={state.savedQuery}
screenTitle={opts.savedSearch.title}
showDatePicker={showDatePicker}
showSaveQuery={!!opts.services.capabilities.discover.saveQuery}
showSearchBar={true}
useDefaultBehaviors={true}
/>
);
};

const TopNav = React.memo(TopNavWrapper);
const TopNavMemoized = React.memo(DiscoverTopNav);

export function Discover({
fetch,
Expand Down Expand Up @@ -224,7 +182,7 @@ export function Discover({
return (
<I18nProvider>
<EuiPage className="dscPage" data-fetch-counter={fetchCounter}>
<TopNav
<TopNavMemoized
indexPattern={indexPattern}
opts={opts}
state={state}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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 from 'react';
import { shallowWithIntl } from '@kbn/test/jest';
import { inspectorPluginMock } from '../../../../inspector/public/mocks';
import { indexPatternMock } from '../../__mocks__/index_pattern';
import { getTopNavLinks } from './top_nav/get_top_nav_links';
import { DiscoverServices } from '../../build_services';
import { GetStateReturn } from '../angular/discover_state';
import { savedSearchMock } from '../../__mocks__/saved_search';
import { dataPluginMock } from '../../../../data/public/mocks';
import { createFilterManagerMock } from '../../../../data/public/query/filter_manager/filter_manager.mock';
import { uiSettingsMock as mockUiSettings } from '../../__mocks__/ui_settings';
import { IndexPatternAttributes } from '../../../../data/common/index_patterns';
import { SavedObject } from '../../../../../core/types';
import { navigationPluginMock } from '../../../../navigation/public/mocks';
import { DiscoverTopNav } from './discover_topnav';

function getProps() {
const state = ({} as unknown) as GetStateReturn;
const services = ({
navigation: navigationPluginMock.createStartContract(),
capabilities: {
discover: {
save: true,
},
},
uiSettings: mockUiSettings,
} as unknown) as DiscoverServices;
const indexPattern = indexPatternMock;
return {
indexPattern: indexPatternMock,
opts: {
config: mockUiSettings,
data: dataPluginMock.createStartContract(),
filterManager: createFilterManagerMock(),
indexPatternList: (indexPattern as unknown) as Array<SavedObject<IndexPatternAttributes>>,
sampleSize: 10,
savedSearch: savedSearchMock,
setHeaderActionMenu: jest.fn(),
timefield: indexPattern.timeFieldName || '',
setAppState: jest.fn(),
services,
stateContainer: {} as GetStateReturn,
},
topNavMenu: getTopNavLinks({
getFieldCounts: jest.fn(),
indexPattern,
inspectorAdapters: inspectorPluginMock,
navigateTo: jest.fn(),
savedSearch: savedSearchMock,
services,
state,
}),
state,
updateQuery: jest.fn(),
};
}

describe('Discover topnav component', () => {
test('renders correctly', () => {
const component = shallowWithIntl(<DiscoverTopNav {...getProps()} />);
expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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, { useMemo } from 'react';
import { DiscoverProps } from './types';

export const DiscoverTopNav = ({
topNavMenu,
indexPattern,
updateQuery,
state,
opts,
}: Pick<DiscoverProps, 'topNavMenu' | 'indexPattern' | 'updateQuery' | 'state' | 'opts'>) => {
const showDatePicker = useMemo(() => indexPattern.isTimeBased(), [indexPattern]);
const { TopNavMenu } = opts.services.navigation.ui;

const updateSavedQueryId = (newSavedQueryId: string | undefined) => {
const { appStateContainer, setAppState } = opts.stateContainer;
if (newSavedQueryId) {
setAppState({ savedQuery: newSavedQueryId });
} else {
// remove savedQueryId from state
const newState = {
...appStateContainer.getState(),
};
delete newState.savedQuery;
appStateContainer.set(newState);
}
};
return (
<TopNavMenu
appName="discover"
config={topNavMenu}
indexPatterns={[indexPattern]}
onQuerySubmit={updateQuery}
onSavedQueryIdChange={updateSavedQueryId}
query={state.query}
setMenuMountPoint={opts.setHeaderActionMenu}
savedQueryId={state.savedQuery}
screenTitle={opts.savedSearch.title}
showDatePicker={showDatePicker}
showSaveQuery={!!opts.services.capabilities.discover.saveQuery}
showSearchBar={true}
useDefaultBehaviors={true}
/>
);
};

0 comments on commit 583781c

Please sign in to comment.