[Lens] Reduce lodash footprint (#101029) (#101043)

* [Lens] extract lodash methods

* remove lodash from files that don't use it

Co-authored-by: Marta Bondyra <marta.bondyra@gmail.com>
This commit is contained in:
Kibana Machine 2021-06-02 12:41:56 -04:00 committed by GitHub
parent 0d855a13e1
commit e8968738fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 37 additions and 41 deletions

View file

@ -5,7 +5,7 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash'; import { mapValues } from 'lodash';
import { EditorFrameState } from '../state_management'; import { EditorFrameState } from '../state_management';
import { Datasource, Visualization } from '../../../types'; import { Datasource, Visualization } from '../../../types';
@ -35,7 +35,7 @@ export function removeLayer(opts: RemoveLayerOptions): EditorFrameState {
return { return {
...state, ...state,
datasourceStates: _.mapValues(state.datasourceStates, (datasourceState, datasourceId) => { datasourceStates: mapValues(state.datasourceStates, (datasourceState, datasourceId) => {
const datasource = datasourceMap[datasourceId!]; const datasource = datasourceMap[datasourceId!];
return { return {
...datasourceState, ...datasourceState,

View file

@ -7,7 +7,7 @@
import './suggestion_panel.scss'; import './suggestion_panel.scss';
import _, { camelCase } from 'lodash'; import { camelCase, pick } from 'lodash';
import React, { useState, useEffect, useMemo, useRef } from 'react'; import React, { useState, useEffect, useMemo, useRef } from 'react';
import { FormattedMessage } from '@kbn/i18n/react'; import { FormattedMessage } from '@kbn/i18n/react';
import { import {
@ -442,7 +442,7 @@ function getPreviewExpression(
) { ) {
const datasource = datasources[visualizableState.datasourceId]; const datasource = datasources[visualizableState.datasourceId];
const datasourceState = visualizableState.datasourceState; const datasourceState = visualizableState.datasourceState;
const updatedLayerApis: Record<string, DatasourcePublicAPI> = _.pick( const updatedLayerApis: Record<string, DatasourcePublicAPI> = pick(
frame.datasourceLayers, frame.datasourceLayers,
visualizableState.keptLayerIds visualizableState.keptLayerIds
); );

View file

@ -5,7 +5,7 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash'; import { isEqual, uniqBy } from 'lodash';
import React from 'react'; import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom'; import { render, unmountComponentAtNode } from 'react-dom';
import { import {
@ -23,7 +23,7 @@ import { Subscription } from 'rxjs';
import { toExpression, Ast } from '@kbn/interpreter/common'; import { toExpression, Ast } from '@kbn/interpreter/common';
import { DefaultInspectorAdapters, RenderMode } from 'src/plugins/expressions'; import { DefaultInspectorAdapters, RenderMode } from 'src/plugins/expressions';
import { map, distinctUntilChanged, skip } from 'rxjs/operators'; import { map, distinctUntilChanged, skip } from 'rxjs/operators';
import isEqual from 'fast-deep-equal'; import fastIsEqual from 'fast-deep-equal';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
import { METRIC_TYPE } from '@kbn/analytics'; import { METRIC_TYPE } from '@kbn/analytics';
import { import {
@ -161,7 +161,7 @@ export class Embeddable
input$ input$
.pipe( .pipe(
map((input) => input.enhancements?.dynamicActions), map((input) => input.enhancements?.dynamicActions),
distinctUntilChanged((a, b) => isEqual(a, b)), distinctUntilChanged((a, b) => fastIsEqual(a, b)),
skip(1) skip(1)
) )
.subscribe((input) => { .subscribe((input) => {
@ -195,7 +195,7 @@ export class Embeddable
input$ input$
.pipe( .pipe(
distinctUntilChanged((a, b) => distinctUntilChanged((a, b) =>
isEqual( fastIsEqual(
['attributes' in a && a.attributes, 'savedObjectId' in a && a.savedObjectId], ['attributes' in a && a.attributes, 'savedObjectId' in a && a.savedObjectId],
['attributes' in b && b.attributes, 'savedObjectId' in b && b.savedObjectId] ['attributes' in b && b.attributes, 'savedObjectId' in b && b.savedObjectId]
) )
@ -214,7 +214,7 @@ export class Embeddable
.pipe(map(() => this.getInput())) .pipe(map(() => this.getInput()))
.pipe( .pipe(
distinctUntilChanged((a, b) => distinctUntilChanged((a, b) =>
isEqual( fastIsEqual(
[a.filters, a.query, a.timeRange, a.searchSessionId], [a.filters, a.query, a.timeRange, a.searchSessionId],
[b.filters, b.query, b.timeRange, b.searchSessionId] [b.filters, b.query, b.timeRange, b.searchSessionId]
) )
@ -283,9 +283,9 @@ export class Embeddable
? containerState.filters.filter((filter) => !filter.meta.disabled) ? containerState.filters.filter((filter) => !filter.meta.disabled)
: undefined; : undefined;
if ( if (
!_.isEqual(containerState.timeRange, this.externalSearchContext.timeRange) || !isEqual(containerState.timeRange, this.externalSearchContext.timeRange) ||
!_.isEqual(containerState.query, this.externalSearchContext.query) || !isEqual(containerState.query, this.externalSearchContext.query) ||
!_.isEqual(cleanedFilters, this.externalSearchContext.filters) || !isEqual(cleanedFilters, this.externalSearchContext.filters) ||
this.externalSearchContext.searchSessionId !== containerState.searchSessionId this.externalSearchContext.searchSessionId !== containerState.searchSessionId
) { ) {
this.externalSearchContext = { this.externalSearchContext = {
@ -446,7 +446,7 @@ export class Embeddable
return; return;
} }
const responses = await Promise.allSettled( const responses = await Promise.allSettled(
_.uniqBy( uniqBy(
this.savedVis.references.filter(({ type }) => type === 'index-pattern'), this.savedVis.references.filter(({ type }) => type === 'index-pattern'),
'id' 'id'
).map(({ id }) => this.deps.indexPatternService.get(id)) ).map(({ id }) => this.deps.indexPatternService.get(id))

View file

@ -6,7 +6,6 @@
*/ */
import './dimension_editor.scss'; import './dimension_editor.scss';
import _ from 'lodash';
import React, { useState, useMemo } from 'react'; import React, { useState, useMemo } from 'react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { import {

View file

@ -6,7 +6,7 @@
*/ */
import './field_select.scss'; import './field_select.scss';
import _ from 'lodash'; import { partition } from 'lodash';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { import {
@ -68,7 +68,7 @@ export function FieldSelect({
return !currentOperationType || operationByField[fieldName]!.has(currentOperationType); return !currentOperationType || operationByField[fieldName]!.has(currentOperationType);
} }
const [specialFields, normalFields] = _.partition( const [specialFields, normalFields] = partition(
fields, fields,
(field) => currentIndexPattern.getFieldByName(field)?.type === 'document' (field) => currentIndexPattern.getFieldByName(field)?.type === 'document'
); );
@ -121,11 +121,11 @@ export function FieldSelect({
})); }));
} }
const [metaFields, nonMetaFields] = _.partition( const [metaFields, nonMetaFields] = partition(
normalFields, normalFields,
(field) => currentIndexPattern.getFieldByName(field)?.meta (field) => currentIndexPattern.getFieldByName(field)?.meta
); );
const [availableFields, emptyFields] = _.partition(nonMetaFields, containsData); const [availableFields, emptyFields] = partition(nonMetaFields, containsData);
const constructFieldsOptions = (fieldsArr: string[], label: string) => const constructFieldsOptions = (fieldsArr: string[], label: string) =>
fieldsArr.length > 0 && { fieldsArr.length > 0 && {

View file

@ -5,7 +5,6 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash';
import { DatasourceDimensionDropProps } from '../../types'; import { DatasourceDimensionDropProps } from '../../types';
import { OperationType } from '../indexpattern'; import { OperationType } from '../indexpattern';
import { memoizedGetAvailableOperationsByMetadata } from '../operations'; import { memoizedGetAvailableOperationsByMetadata } from '../operations';

View file

@ -6,7 +6,6 @@
*/ */
import './dimension_editor.scss'; import './dimension_editor.scss';
import _ from 'lodash';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { import {

View file

@ -5,7 +5,6 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash';
import React from 'react'; import React from 'react';
import { render } from 'react-dom'; import { render } from 'react-dom';
import { I18nProvider } from '@kbn/i18n/react'; import { I18nProvider } from '@kbn/i18n/react';

View file

@ -5,7 +5,7 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash'; import { flatten, minBy, pick, mapValues } from 'lodash';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { generateId } from '../id_generator'; import { generateId } from '../id_generator';
import { DatasourceSuggestion, TableChangeType } from '../types'; import { DatasourceSuggestion, TableChangeType } from '../types';
@ -58,9 +58,9 @@ function buildSuggestion({
// It's fairly easy to accidentally introduce a mismatch between // It's fairly easy to accidentally introduce a mismatch between
// columnOrder and columns, so this is a safeguard to ensure the // columnOrder and columns, so this is a safeguard to ensure the
// two match up. // two match up.
const layers = _.mapValues(updatedState.layers, (layer) => ({ const layers = mapValues(updatedState.layers, (layer) => ({
...layer, ...layer,
columns: _.pick(layer.columns, layer.columnOrder) as Record<string, IndexPatternColumn>, columns: pick(layer.columns, layer.columnOrder) as Record<string, IndexPatternColumn>,
})); }));
const columnOrder = layers[layerId].columnOrder; const columnOrder = layers[layerId].columnOrder;
@ -111,7 +111,7 @@ export function getDatasourceSuggestionsForField(
// The field we're suggesting on matches an existing layer. In this case we find the layer with // The field we're suggesting on matches an existing layer. In this case we find the layer with
// the fewest configured columns and try to add the field to this table. If this layer does not // the fewest configured columns and try to add the field to this table. If this layer does not
// contain any layers yet, behave as if there is no layer. // contain any layers yet, behave as if there is no layer.
const mostEmptyLayerId = _.minBy( const mostEmptyLayerId = minBy(
layerIds, layerIds,
(layerId) => state.layers[layerId].columnOrder.length (layerId) => state.layers[layerId].columnOrder.length
) as string; ) as string;
@ -386,7 +386,7 @@ export function getDatasourceSuggestionsFromCurrentState(
]); ]);
} }
return _.flatten( return flatten(
Object.entries(state.layers || {}) Object.entries(state.layers || {})
.filter(([_id, layer]) => layer.columnOrder.length && layer.indexPatternId) .filter(([_id, layer]) => layer.columnOrder.length && layer.indexPatternId)
.map(([layerId, layer]) => { .map(([layerId, layer]) => {
@ -586,7 +586,7 @@ function createSimplifiedTableSuggestions(state: IndexPatternPrivateState, layer
availableReferenceColumns, availableReferenceColumns,
] = getExistingColumnGroups(layer); ] = getExistingColumnGroups(layer);
return _.flatten( return flatten(
availableBucketedColumns.map((_col, index) => { availableBucketedColumns.map((_col, index) => {
// build suggestions with fewer buckets // build suggestions with fewer buckets
const bucketedColumns = availableBucketedColumns.slice(0, index + 1); const bucketedColumns = availableBucketedColumns.slice(0, index + 1);

View file

@ -6,7 +6,7 @@
*/ */
import { HttpHandler } from 'kibana/public'; import { HttpHandler } from 'kibana/public';
import _ from 'lodash'; import { last } from 'lodash';
import { import {
loadInitialState, loadInitialState,
loadIndexPatterns, loadIndexPatterns,
@ -841,7 +841,7 @@ describe('loader', () => {
it('should call once for each index pattern', async () => { it('should call once for each index pattern', async () => {
const setState = jest.fn(); const setState = jest.fn();
const fetchJson = (jest.fn((path: string) => { const fetchJson = (jest.fn((path: string) => {
const indexPatternTitle = _.last(path.split('/')); const indexPatternTitle = last(path.split('/'));
return { return {
indexPatternTitle, indexPatternTitle,
existingFieldNames: ['field_1', 'field_2'].map( existingFieldNames: ['field_1', 'field_2'].map(
@ -891,7 +891,7 @@ describe('loader', () => {
const setState = jest.fn(); const setState = jest.fn();
const showNoDataPopover = jest.fn(); const showNoDataPopover = jest.fn();
const fetchJson = (jest.fn((path: string) => { const fetchJson = (jest.fn((path: string) => {
const indexPatternTitle = _.last(path.split('/')); const indexPatternTitle = last(path.split('/'));
return { return {
indexPatternTitle, indexPatternTitle,
existingFieldNames: existingFieldNames:

View file

@ -5,7 +5,7 @@
* 2.0. * 2.0.
*/ */
import _ from 'lodash'; import { uniq, mapValues } from 'lodash';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { HttpSetup, SavedObjectReference } from 'kibana/public'; import { HttpSetup, SavedObjectReference } from 'kibana/public';
import { InitializationOptions, StateSetter } from '../types'; import { InitializationOptions, StateSetter } from '../types';
@ -227,7 +227,7 @@ export async function loadInitialState({
const state = const state =
persistedState && references ? injectReferences(persistedState, references) : undefined; persistedState && references ? injectReferences(persistedState, references) : undefined;
const requiredPatterns: string[] = _.uniq( const requiredPatterns: string[] = uniq(
state state
? Object.values(state.layers) ? Object.values(state.layers)
.map((l) => l.indexPatternId) .map((l) => l.indexPatternId)
@ -312,7 +312,7 @@ export async function changeIndexPattern({
setState((s) => ({ setState((s) => ({
...s, ...s,
layers: isSingleEmptyLayer(state.layers) layers: isSingleEmptyLayer(state.layers)
? _.mapValues(state.layers, (layer) => updateLayerIndexPattern(layer, indexPatterns[id])) ? mapValues(state.layers, (layer) => updateLayerIndexPattern(layer, indexPatterns[id]))
: state.layers, : state.layers,
indexPatterns: { indexPatterns: {
...s.indexPatterns, ...s.indexPatterns,

View file

@ -5,7 +5,7 @@
* 2.0. * 2.0.
*/ */
import _, { partition } from 'lodash'; import { partition, mapValues, pickBy } from 'lodash';
import { getSortScoreByPriority } from './operations'; import { getSortScoreByPriority } from './operations';
import type { OperationMetadata, VisualizationDimensionGroupConfig } from '../../types'; import type { OperationMetadata, VisualizationDimensionGroupConfig } from '../../types';
import { import {
@ -1071,7 +1071,7 @@ export function getColumnOrder(layer: IndexPatternLayer): string[] {
} }
}); });
const [aggregations, metrics] = _.partition(entries, ([, col]) => col.isBucketed); const [aggregations, metrics] = partition(entries, ([, col]) => col.isBucketed);
return aggregations.map(([id]) => id).concat(metrics.map(([id]) => id)); return aggregations.map(([id]) => id).concat(metrics.map(([id]) => id));
} }
@ -1110,10 +1110,10 @@ export function updateLayerIndexPattern(
layer: IndexPatternLayer, layer: IndexPatternLayer,
newIndexPattern: IndexPattern newIndexPattern: IndexPattern
): IndexPatternLayer { ): IndexPatternLayer {
const keptColumns: IndexPatternLayer['columns'] = _.pickBy(layer.columns, (column) => { const keptColumns: IndexPatternLayer['columns'] = pickBy(layer.columns, (column) => {
return isColumnTransferable(column, newIndexPattern, layer); return isColumnTransferable(column, newIndexPattern, layer);
}); });
const newColumns: IndexPatternLayer['columns'] = _.mapValues(keptColumns, (column) => { const newColumns: IndexPatternLayer['columns'] = mapValues(keptColumns, (column) => {
const operationDefinition = operationDefinitionMap[column.operationType]; const operationDefinition = operationDefinitionMap[column.operationType];
return operationDefinition.transfer return operationDefinition.transfer
? operationDefinition.transfer(column, newIndexPattern) ? operationDefinition.transfer(column, newIndexPattern)

View file

@ -6,7 +6,7 @@
*/ */
import React from 'react'; import React from 'react';
import _ from 'lodash'; import { throttle } from 'lodash';
import { EuiResizeObserver } from '@elastic/eui'; import { EuiResizeObserver } from '@elastic/eui';
interface Props extends React.HTMLAttributes<HTMLDivElement> { interface Props extends React.HTMLAttributes<HTMLDivElement> {
@ -26,7 +26,7 @@ export class AutoScale extends React.Component<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.scale = _.throttle(() => { this.scale = throttle(() => {
const scale = computeScale(this.parent, this.child, this.props.minScale); const scale = computeScale(this.parent, this.child, this.props.minScale);
// Prevent an infinite render loop // Prevent an infinite render loop

View file

@ -6,7 +6,7 @@
*/ */
import { delay, finalize, switchMap, tap } from 'rxjs/operators'; import { delay, finalize, switchMap, tap } from 'rxjs/operators';
import _, { debounce } from 'lodash'; import { debounce, isEqual } from 'lodash';
import { Dispatch, MiddlewareAPI, PayloadAction } from '@reduxjs/toolkit'; import { Dispatch, MiddlewareAPI, PayloadAction } from '@reduxjs/toolkit';
import { trackUiEvent } from '../lens_ui_telemetry'; import { trackUiEvent } from '../lens_ui_telemetry';
@ -44,7 +44,7 @@ function subscribeToExternalContext(
const dispatchFromExternal = (searchSessionId = search.session.start()) => { const dispatchFromExternal = (searchSessionId = search.session.start()) => {
const globalFilters = filterManager.getFilters(); const globalFilters = filterManager.getFilters();
const filters = _.isEqual(getState().app.filters, globalFilters) const filters = isEqual(getState().app.filters, globalFilters)
? null ? null
: { filters: globalFilters }; : { filters: globalFilters };
dispatch( dispatch(